From 3c3daa889c2a313af5c36459e3c845fe11a11603 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 20 Sep 2017 17:43:44 +0100 Subject: [PATCH 001/355] ATLAS-103 Adapt accumulate_boundary_nodes to use mesh.polygon --- src/atlas/mesh/PartitionPolygon.cc | 21 ++++++++++++--------- src/atlas/mesh/actions/BuildHalo.cc | 21 +++++++++++++++------ src/atlas/mesh/detail/Polygon.cc | 1 - src/atlas/mesh/detail/Polygon.h | 4 ++++ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/atlas/mesh/PartitionPolygon.cc b/src/atlas/mesh/PartitionPolygon.cc index 7878e409c..80e2c3de7 100644 --- a/src/atlas/mesh/PartitionPolygon.cc +++ b/src/atlas/mesh/PartitionPolygon.cc @@ -27,14 +27,11 @@ namespace atlas { namespace mesh { - -PartitionPolygon::PartitionPolygon(const detail::MeshImpl& mesh, size_t halo) : - mesh_(mesh), - halo_(halo) { - +namespace { +detail::Polygon::edge_set_t compute_edges(const detail::MeshImpl& mesh, size_t halo) { // extract partition boundary edges by always attempting first to` // remove a reversed edge from a neighbouring element, if any - edge_set_t edges; + detail::Polygon::edge_set_t edges; for (size_t t = 0; t < mesh.cells().nb_types(); ++t) { const Elements& elements = mesh.cells().elements(t); @@ -47,7 +44,7 @@ PartitionPolygon::PartitionPolygon(const detail::MeshImpl& mesh, size_t halo) : for (size_t j = 0; j < elements.size(); ++j) { if (field_patch(j) == 0 && field_halo(j) <= halo ) { for (size_t k = 0; k < nb_nodes; ++k) { - edge_t edge(size_t(conn(j, k)), size_t(conn(j, (k+1) % nb_nodes))); + detail::Polygon::edge_t edge( conn(j,k), conn(j, (k+1) % nb_nodes)); if (!edges.erase(edge.reverse())) { edges.insert(edge); } @@ -55,8 +52,14 @@ PartitionPolygon::PartitionPolygon(const detail::MeshImpl& mesh, size_t halo) : } } } + return edges; +} +} - ASSERT(operator+=(detail::Polygon(edges))); +PartitionPolygon::PartitionPolygon(const detail::MeshImpl& mesh, size_t halo) : + detail::Polygon( compute_edges(mesh,halo) ), + mesh_(mesh), + halo_(halo) { } @@ -104,7 +107,7 @@ void PartitionPolygon::outputPythonScript(const eckit::PathName& filepath) const "\n" "" "\n" "fig = plt.figure()" "\n" "ax = fig.add_subplot(111,aspect='equal')" - "\n" ""; + "\n" ""; } f << "\n" "verts_" << r << " = ["; for (idx_t i : static_cast(*this)) { diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index ce3017929..6fc90ec65 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -112,7 +112,7 @@ void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) } -void accumulate_partition_bdry_nodes( Mesh& mesh, std::vector& bdry_nodes ) +void accumulate_partition_bdry_nodes_old( Mesh& mesh, std::vector& bdry_nodes ) { std::set bdry_nodes_set; @@ -143,13 +143,22 @@ void accumulate_partition_bdry_nodes( Mesh& mesh, std::vector& bdry_nodes ) bdry_nodes = std::vector( bdry_nodes_set.begin(), bdry_nodes_set.end()); } + +void accumulate_partition_bdry_nodes( Mesh& mesh, size_t halo, std::vector& bdry_nodes ) +{ +#ifdef OLD + accumulate_partition_bdry_nodes_old(mesh,bdry_nodes); +#else + const Mesh::Polygon& polygon = mesh.polygon(halo); + bdry_nodes = std::vector( polygon.begin(), polygon.end() ); +#endif +} + template< typename Predicate > std::vector filter_nodes(std::vector nodes, const Predicate& predicate ) { std::vector filtered; filtered.reserve(nodes.size()); - for( size_t jnode=0; jnode& bdry_nodes = helper.bdry_nodes; // 2) Communicate uid of these boundary nodes to other partitions @@ -842,7 +851,7 @@ 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.bdry_nodes); + accumulate_partition_bdry_nodes(helper.mesh,helper.halo,helper.bdry_nodes); std::vector bdry_nodes = filter_nodes(helper.bdry_nodes,periodic_points); diff --git a/src/atlas/mesh/detail/Polygon.cc b/src/atlas/mesh/detail/Polygon.cc index f108dfd05..08215401c 100644 --- a/src/atlas/mesh/detail/Polygon.cc +++ b/src/atlas/mesh/detail/Polygon.cc @@ -29,7 +29,6 @@ Polygon::Polygon() { 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) { diff --git a/src/atlas/mesh/detail/Polygon.h b/src/atlas/mesh/detail/Polygon.h index d52c4b7e0..f2e980341 100644 --- a/src/atlas/mesh/detail/Polygon.h +++ b/src/atlas/mesh/detail/Polygon.h @@ -75,6 +75,10 @@ class Polygon : public std::vector { return s; } +protected: + + void construct( const edge_set_t& ); + }; //------------------------------------------------------------------------------------------------------ From e6c3b3829a7abefcbcd1eb6ddb559755775492e0 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 21 Sep 2017 09:34:39 +0100 Subject: [PATCH 002/355] ATLAS-103 Work on negative scaling of BuildHalo --- src/atlas/mesh/actions/BuildHalo.cc | 90 ++++++- src/atlas/util/Unique.h | 9 +- src/tests/mesh/test_halo.cc | 363 +++++++++++++++++++++++++++- 3 files changed, 448 insertions(+), 14 deletions(-) diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 6fc90ec65..2ecae5ef0 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -43,6 +43,13 @@ #include "atlas/mesh/actions/BuildXYZField.h" #endif +#define ATLAS_103 +// #define ATLAS_103_SORT + +#ifndef ATLAS_103 +#warning ATLAS-103 proposed solution deactivated +#endif + using atlas::mesh::detail::accumulate_facets; using atlas::mesh::detail::PeriodicTransform; using atlas::util::UniqueLonLat; @@ -63,9 +70,6 @@ class BuildHaloHelper; void increase_halo( Mesh& mesh ); void increase_halo_interior( BuildHaloHelper& ); - - - class EastWest: public PeriodicTransform { public: @@ -146,12 +150,18 @@ void accumulate_partition_bdry_nodes_old( Mesh& mesh, std::vector& bdry_nod void accumulate_partition_bdry_nodes( Mesh& mesh, size_t halo, std::vector& bdry_nodes ) { -#ifdef OLD +#ifndef ATLAS_103 + /* deprecated */ accumulate_partition_bdry_nodes_old(mesh,bdry_nodes); #else const Mesh::Polygon& polygon = mesh.polygon(halo); bdry_nodes = std::vector( polygon.begin(), polygon.end() ); #endif + +#ifdef ATLAS_103_SORT + /* not required */ + std::sort(bdry_nodes.begin(),bdry_nodes.end()); +#endif } template< typename Predicate > @@ -373,7 +383,7 @@ class BuildHaloHelper comm.allToAll(send.node_part, recv.node_part); comm.allToAll(send.node_ridx, recv.node_ridx); comm.allToAll(send.node_flags, recv.node_flags); - comm.allToAll(send.node_xy, recv.node_xy); + comm.allToAll(send.node_xy, recv.node_xy); comm.allToAll(send.elem_glb_idx, recv.elem_glb_idx); comm.allToAll(send.elem_nodes_id, recv.elem_nodes_id); comm.allToAll(send.elem_part, recv.elem_part); @@ -746,6 +756,53 @@ class BuildHaloHelper }; + +namespace { +void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, const bool& periodic = false ) { +#ifndef ATLAS_103 + /* deprecated */ + parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); +#else + Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); + if( periodic ) { + // add own rank to neighbours to allow periodicity with self (pole caps) + size_t rank = parallel::mpi::comm().rank(); + neighbours.insert( std::upper_bound( neighbours.begin(), neighbours.end(), rank ), rank ); + } + + const size_t mpi_size = parallel::mpi::comm().size(); + const int counts_tag = 0; + const int buffer_tag = 1; + + int sendcnt = send.size(); + for( size_t to : neighbours ) { + parallel::mpi::comm().send(sendcnt,to,counts_tag); + } + recv.counts.assign(0,mpi_size); + for( size_t from : neighbours ) { + parallel::mpi::comm().receive(recv.counts[from],from,counts_tag); + } + for( size_t to : neighbours ) { + parallel::mpi::comm().send(send.data(),send.size(),to,buffer_tag); + } + recv.displs[0] = 0; + recv.cnt = recv.counts[0]; + for(size_t jpart = 1; jpart < mpi_size; ++jpart) { + recv.displs[jpart] = recv.displs[jpart-1] + recv.counts[jpart-1]; + recv.cnt += recv.counts[jpart]; + } + recv.buffer.resize(recv.cnt); + + for( size_t from : neighbours ) { + parallel::mpi::comm().receive(recv.buffer.data()+recv.displs[from],recv.counts[from],from,buffer_tag); + } +#endif +} +} + + + + void increase_halo_interior( BuildHaloHelper& helper ) { helper.update(); @@ -774,10 +831,18 @@ void increase_halo_interior( BuildHaloHelper& helper ) size_t size = parallel::mpi::comm().size(); atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(size); - parallel::mpi::comm().allGatherv(send_bdry_nodes_uid.begin(), send_bdry_nodes_uid.end(), recv_bdry_nodes_uid_from_parts); + gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts ); +#ifndef ATLAS_103 + /* deprecated */ for (size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) +#else + const Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); + Log::info() << helper.mesh.partitionGraph() << std::endl; + for (size_t jpart : neighbours) +#endif { + // 3) Find elements and nodes completing these elements in // other tasks that have my nodes through its UID @@ -868,10 +933,19 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri size_t size = parallel::mpi::comm().size(); atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(size); + + gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts, /* periodic = */ true ); - parallel::mpi::comm().allGatherv(send_bdry_nodes_uid.begin(), send_bdry_nodes_uid.end(), recv_bdry_nodes_uid_from_parts); - +#ifndef ATLAS_103 + /* deprecated */ for (size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) +#else + Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); + // add own rank to neighbours to allow periodicity with self (pole caps) + size_t rank = parallel::mpi::comm().rank(); + neighbours.insert( std::upper_bound( neighbours.begin(), neighbours.end(), rank ), rank ); + for (size_t jpart : neighbours) +#endif { // 3) Find elements and nodes completing these elements in // other tasks that have my nodes through its UID diff --git a/src/atlas/util/Unique.h b/src/atlas/util/Unique.h index f54a92a66..94b504425 100644 --- a/src/atlas/util/Unique.h +++ b/src/atlas/util/Unique.h @@ -21,6 +21,7 @@ #include "atlas/util/CoordinateEnums.h" #include "atlas/util/MicroDeg.h" #include "atlas/array/ArrayView.h" +#include "atlas/array/LocalView.h" #include "atlas/array/IndexView.h" #include "atlas/array/MakeView.h" @@ -45,7 +46,7 @@ namespace util { /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits uidx_t unique_lonlat( const double& lon, const double& lat ); uidx_t unique_lonlat( const double lonlat[] ); - uidx_t unique_lonlat( const array::ArrayView& lonlat ); + uidx_t unique_lonlat( const array::LocalView& lonlat ); /// @brief Compute unique positive index from lon-lat coordinates in degrees. /// coordinates are stored in order: @@ -152,9 +153,9 @@ inline uidx_t unique_lonlat( const double lonlat[] ) { return detail::uniqueT( microdeg(lonlat[LON]), microdeg(lonlat[LAT]) ); } -// inline uidx_t unique_lonlat( const array::ArrayView& lonlat ) { -// return detail::uniqueT( microdeg(lonlat[LON]), microdeg(lonlat[LAT]) ); -// } +inline uidx_t unique_lonlat( const array::LocalView& lonlat ) { + return unique_lonlat( lonlat.data() ); +} inline uidx_t unique_lonlat( const double elem_lonlat[], size_t npts ) diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index 2dfc34afa..5eb069605 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -27,6 +27,8 @@ #include "atlas/mesh/actions/BuildEdges.h" #include "atlas/mesh/actions/BuildDualMesh.h" #include "atlas/util/CoordinateEnums.h" +#include "atlas/util/MicroDeg.h" +#include "atlas/util/Unique.h" #include "atlas/mesh/IsGhostNode.h" #include "eckit/types/FloatCompare.h" @@ -122,11 +124,368 @@ CASE( "test_t63" ) mesh::actions::renumber_nodes_glb_idx(m.nodes()); std::stringstream filename; filename << "T63_halo.msh"; - Gmsh(filename.str()).write(m); + Gmsh(filename.str(),util::Config("ghost",true)).write(m); // EXPECT( eckit::types::is_approximately_equal( test::dual_volume(m), 2.*M_PI*M_PI, 1e-6 )); -// Nodes& nodes = m.nodes(); + auto lonlat = array::make_view( m.nodes().lonlat() ); + + std::vector check; + switch( parallel::mpi::comm().rank() ) { + case 0: check = { + 607990293346953216, + 607990293382953216, + 607990293418953216, + 607990293454953216, + 607990293490953216, + 607990293526953216, + 607990293562953216, + 607990293598953216, + 607990293634953216, + 607990293670953216, + 644481443595331584, + 644481443625331584, + 644481443655331584, + 644481443685331584, + 644481443715331584, + 644481443745331584, + 644481443775331584, + 644481443805331584, + 644481443835331584, + 644481443865331584, + 644481443895331584, + 644481443925331584, + 681187136050079744, + 681187136075794030, + 681187136101508315, + 681187136127222601, + 681187136152936887, + 681187136178651173, + 607990293706953216, + 644481443955331584, + 681187136204365458, + 681187136230079744, + 681187136255794030, + 681187136281508315, + 681187136307222601, + 681187136332936887, + 681187136358651173, + 681187136384365458, + 681187136410079744, + 717939789677242368, + 717939789699742368, + 717939789722242368, + 717939789744742368, + 717939789767242368, + 717939789789742368, + 717939789812242368, + 754708008265885696, + 754708008288385696, + 754708008310885696, + 754708008333385696, + 754708008355885696, + 754708008378385696, + 754708008400885696, + 717939789834742368, + 717939789857242368, + 717939789879742368, + 717939789902242368, + 754708008423385696, + 717939789924742368, + 717939789947242368, + 717939789969742368, + 717939789992242368, + 717939790014742368, + 717939790037242368, + 607990293310953217, + 644481443565331585, + 681187136024365459, + 717939789654742369, + 754708008243385697, + 607990293742953216, + 644481443985331584, + 681187136435794030, + 717939790059742368 + }; + break; + case 1: + check = { + 717939789677242368, + 717939789699742368, + 717939789722242368, + 717939789744742368, + 717939789767242368, + 717939789789742368, + 754708008265885696, + 754708008288385696, + 754708008310885696, + 754708008333385696, + 754708008355885696, + 754708008378385696, + 791480219026630656, + 791480219049130656, + 791480219071630656, + 791480219094130656, + 791480219116630656, + 828248437615273984, + 828248437637773984, + 828248437660273984, + 828248437682773984, + 828248437705273984, + 865001091242436608, + 865001091268150894, + 865001091293865179, + 865001091319579465, + 865001091345293751, + 717939789812242368, + 754708008400885696, + 791480219139130656, + 828248437727773984, + 681187136050079744, + 681187136075794030, + 681187136101508315, + 681187136127222601, + 681187136152936887, + 681187136178651173, + 681187136204365458, + 717939789834742368, + 754708008423385696, + 791480219161630656, + 791480219184130656, + 828248437750273984, + 865001091371008037, + 901706783697184768, + 901706783727184768, + 901706783757184768, + 901706783787184768, + 901706783817184768, + 717939789654742369, + 754708008243385697, + 791480219004130657, + 828248437592773985, + 865001091216722323 + }; + break; + case 2: + check = { + 681187136204365458, + 681187136230079744, + 681187136255794030, + 717939789812242368, + 717939789834742368, + 717939789857242368, + 717939789879742368, + 717939789902242368, + 754708008400885696, + 754708008423385696, + 754708008445885696, + 754708008468385696, + 754708008490885696, + 791480219139130656, + 791480219161630656, + 791480219184130656, + 791480219206630656, + 791480219229130656, + 828248437727773984, + 828248437750273984, + 828248437772773984, + 828248437795273984, + 828248437817773984, + 865001091371008037, + 865001091396722322, + 865001091422436608, + 865001091448150894, + 681187136281508315, + 717939789924742368, + 754708008378385696, + 754708008513385696, + 791480219116630656, + 791480219251630656, + 828248437705273984, + 828248437840273984, + 865001091345293751, + 644481443745331584, + 644481443775331584, + 644481443805331584, + 644481443835331584, + 681187136178651173, + 681187136307222601, + 717939789789742368, + 717939789767242368, + 754708008333385696, + 754708008355885696, + 791480219094130656, + 828248437682773984, + 865001091319579465, + 717939789947242368, + 754708008535885696, + 791480219274130656, + 791480219296630656, + 828248437862773984, + 865001091473865179, + 901706783787184768, + 901706783817184768, + 901706783847184768, + 901706783877184768, + 901706783907184768 + }; + break; + case 3: + check = { + 681187136281508315, + 681187136307222601, + 681187136332936887, + 681187136358651173, + 681187136384365458, + 717939789924742368, + 717939789947242368, + 717939789969742368, + 717939789992242368, + 717939790014742368, + 754708008513385696, + 754708008535885696, + 754708008558385696, + 754708008580885696, + 754708008603385696, + 791480219251630656, + 791480219274130656, + 791480219296630656, + 791480219319130656, + 791480219341630656, + 791480219364130656, + 828248437840273984, + 828248437862773984, + 828248437885273984, + 828248437907773984, + 828248437930273984, + 828248437952773984, + 681187136410079744, + 717939789902242368, + 717939790037242368, + 754708008490885696, + 754708008625885696, + 791480219229130656, + 791480219386630656, + 828248437817773984, + 828248437975273984, + 644481443805331584, + 644481443835331584, + 644481443865331584, + 644481443895331584, + 644481443925331584, + 644481443955331584, + 681187136255794030, + 717939789879742368, + 754708008445885696, + 754708008468385696, + 791480219206630656, + 828248437795273984, + 865001091422436608, + 865001091448150894, + 865001091473865179, + 865001091499579465, + 865001091525293751, + 865001091551008037, + 865001091576722322, + 865001091602436608, + 681187136435794030, + 717939790059742368, + 754708008648385696, + 791480219409130656, + 828248437997773984 + }; + break; + case 4: + check = { + 865001091473865179, + 865001091499579465, + 865001091525293751, + 865001091551008037, + 865001091576722322, + 901706783697184768, + 901706783727184768, + 901706783757184768, + 901706783787184768, + 901706783817184768, + 901706783847184768, + 901706783877184768, + 901706783907184768, + 901706783937184768, + 901706783967184768, + 901706783997184768, + 901706784027184768, + 938197933945563136, + 938197933981563136, + 938197934017563136, + 938197934053563136, + 938197934089563136, + 938197934125563136, + 938197934161563136, + 938197934197563136, + 938197934233563136, + 938197934269563136, + 828248437840273984, + 828248437862773984, + 828248437885273984, + 828248437907773984, + 828248437930273984, + 828248437952773984, + 828248437975273984, + 865001091242436608, + 865001091268150894, + 865001091293865179, + 865001091319579465, + 865001091345293751, + 865001091371008037, + 865001091396722322, + 865001091422436608, + 865001091448150894, + 865001091602436608, + 901706784057184768, + 938197934305563136, + 828248437615273984, + 828248437637773984, + 828248437660273984, + 828248437682773984, + 828248437705273984, + 828248437727773984, + 828248437750273984, + 828248437772773984, + 828248437795273984, + 828248437817773984, + 791480219229130656, + 791480219251630656, + 791480219274130656, + 791480219296630656, + 791480219319130656, + 791480219341630656, + 791480219364130656, + 791480219386630656, + 828248437592773985, + 865001091216722323, + 901706783667184769, + 938197933909563137, + 791480219409130656, + 828248437997773984, + 865001091628150894, + 901706784087184768, + 938197934341563136 + }; + break; + default: + check.clear(); + } + std::vector uid(m.nodes().size()); + for( size_t j=0; j dual_volumes ( nodes.field( "dual_volumes" ) ); // array::array::ArrayView dual_normals ( edges.field( "dual_normals" ) ); From 433184b46b3d306ee6bf14f231c0baba4354c67b Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 21 Sep 2017 11:52:07 +0100 Subject: [PATCH 003/355] ATLAS-103 Use iSend/iReceive to avoid deadlock with certain MPI implementations --- src/atlas/mesh/actions/BuildHalo.cc | 33 ++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 2ecae5ef0..19cad26b4 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -769,22 +769,33 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector size_t rank = parallel::mpi::comm().rank(); neighbours.insert( std::upper_bound( neighbours.begin(), neighbours.end(), rank ), rank ); } - + const size_t mpi_size = parallel::mpi::comm().size(); const int counts_tag = 0; const int buffer_tag = 1; - + + std::vector counts_requests; counts_requests.reserve(neighbours.size()); + std::vector buffer_requests; buffer_requests.reserve(neighbours.size()); + int sendcnt = send.size(); for( size_t to : neighbours ) { - parallel::mpi::comm().send(sendcnt,to,counts_tag); + parallel::mpi::comm().iSend( sendcnt, to, counts_tag ); } + recv.counts.assign(0,mpi_size); + for( size_t from : neighbours ) { - parallel::mpi::comm().receive(recv.counts[from],from,counts_tag); + counts_requests.push_back( parallel::mpi::comm().iReceive( recv.counts[from], from, counts_tag ) ); } + for( size_t to : neighbours ) { - parallel::mpi::comm().send(send.data(),send.size(),to,buffer_tag); + parallel::mpi::comm().iSend(send.data(),send.size(),to, buffer_tag ); } + + for( auto request : counts_requests ) { + parallel::mpi::comm().wait( request ); + } + recv.displs[0] = 0; recv.cnt = recv.counts[0]; for(size_t jpart = 1; jpart < mpi_size; ++jpart) { @@ -794,7 +805,13 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector recv.buffer.resize(recv.cnt); for( size_t from : neighbours ) { - parallel::mpi::comm().receive(recv.buffer.data()+recv.displs[from],recv.counts[from],from,buffer_tag); + buffer_requests.push_back( + parallel::mpi::comm().iReceive( recv.buffer.data()+recv.displs[from], + recv.counts[from], from, buffer_tag) ); + } + + for( auto request : buffer_requests ) { + parallel::mpi::comm().wait( request ); } #endif } @@ -842,7 +859,7 @@ void increase_halo_interior( BuildHaloHelper& helper ) for (size_t jpart : neighbours) #endif { - + // 3) Find elements and nodes completing these elements in // other tasks that have my nodes through its UID @@ -933,7 +950,7 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri size_t size = parallel::mpi::comm().size(); atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(size); - + gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts, /* periodic = */ true ); #ifndef ATLAS_103 From ce56f7a5a6cbf6047d243224881e9746aa5a7f77 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 21 Sep 2017 14:39:13 +0100 Subject: [PATCH 004/355] ATLAS-103 Remove verbose output --- src/atlas/mesh/actions/BuildHalo.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 19cad26b4..9599c2cf8 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -855,7 +855,6 @@ void increase_halo_interior( BuildHaloHelper& helper ) for (size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) #else const Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); - Log::info() << helper.mesh.partitionGraph() << std::endl; for (size_t jpart : neighbours) #endif { From 00f3864ca88d38e9395afe7c37ea2a73443555de Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 21 Sep 2017 14:40:14 +0100 Subject: [PATCH 005/355] ATLAS-103 Create benchmark to assess improvements --- src/sandbox/CMakeLists.txt | 2 +- .../benchmark_build_halo/CMakeLists.txt | 15 ++ .../atlas-benchmark-build-halo.cc | 173 ++++++++++++++++++ 3 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 src/sandbox/benchmark_build_halo/CMakeLists.txt create mode 100644 src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc diff --git a/src/sandbox/CMakeLists.txt b/src/sandbox/CMakeLists.txt index 1d35b17ab..efac7b331 100644 --- a/src/sandbox/CMakeLists.txt +++ b/src/sandbox/CMakeLists.txt @@ -14,4 +14,4 @@ add_subdirectory( example_fortran ) add_subdirectory( interpolation ) add_subdirectory( interpolation-fortran ) add_subdirectory( grid_distribution ) - +add_subdirectory( benchmark_build_halo ) diff --git a/src/sandbox/benchmark_build_halo/CMakeLists.txt b/src/sandbox/benchmark_build_halo/CMakeLists.txt new file mode 100644 index 000000000..19ae13519 --- /dev/null +++ b/src/sandbox/benchmark_build_halo/CMakeLists.txt @@ -0,0 +1,15 @@ +# (C) Copyright 1996-2017 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. + +ecbuild_add_executable( + TARGET atlas-benchmark-build-halo + SOURCES atlas-benchmark-build-halo.cc + LIBS atlas + NOINSTALL +) + diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc new file mode 100644 index 000000000..53b2c6411 --- /dev/null +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -0,0 +1,173 @@ +/* + * (C) Copyright 1996-2017 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 +#include +#include +#include + +#include "eckit/exception/Exceptions.h" +#include "eckit/filesystem/PathName.h" +#include "eckit/log/Timer.h" + +#include "atlas/grid.h" +#include "atlas/meshgenerator.h" +#include "atlas/mesh.h" +#include "atlas/runtime/AtlasTool.h" +#include "atlas/runtime/Log.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/util/Config.h" +#include "atlas/output/detail/GmshIO.h" +#include "atlas/mesh/actions/BuildHalo.h" + +//------------------------------------------------------------------------------ + +using namespace atlas; +using namespace atlas::grid; +using atlas::util::Config; +using eckit::PathName; + +struct TimerStats +{ + TimerStats(const std::string& _name = "timer") + { + max = -1; + min = -1; + avg = 0; + cnt = 0; + name = _name; + } + void update(eckit::Timer& timer) + { + double t = timer.elapsed(); + 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); + ++cnt; + } + std::string str() + { + std::stringstream stream; + stream << name << ": min, max, avg -- " << min << ", " << max << ", " << avg; + return stream.str(); + } + std::string name; + double max; + double min; + double avg; + int cnt; +}; + +//------------------------------------------------------------------------------ + +class Tool : public AtlasTool { + + virtual void execute(const Args& args); + virtual std::string briefDescription() { + return "Tool to generate a python script that plots the grid-distribution of a given grid"; + } + virtual std::string usage() { + return name() + " (--grid.name=name|--grid.json=path) [OPTION]... OUTPUT [--help]"; + } + +public: + + Tool(int argc,char **argv); + +private: + + std::string key; + PathName path_in; + PathName path_out; + +}; + +//----------------------------------------------------------------------------- + +Tool::Tool(int argc,char **argv): AtlasTool(argc,argv) +{ + add_option( new SimpleOption("grid.name","Grid unique identifier\n" + +indent()+" Example values: N80, F40, O24, L32") ); + add_option( new SimpleOption("grid.json","Grid described by json file") ); + add_option( new SimpleOption("halo","Number of halos") ); +} + +//----------------------------------------------------------------------------- + +void Tool::execute(const Args& args) +{ + key = ""; + args.get("grid.name",key); + + std::string path_in_str = ""; + if( args.get("grid.json",path_in_str) ) path_in = path_in_str; + + StructuredGrid grid; + if( key.size() ) + { + try{ grid = Grid(key); } + catch( eckit::BadParameter& e ){} + } + else if( path_in.path().size() ) + { + Log::info() << "Creating grid from file " << path_in << std::endl; + Log::debug() << Config(path_in) << std::endl; + try{ grid = Grid( Config(path_in) ); } + catch( eckit::BadParameter& e ){} + } + else + { + Log::error() << "No grid specified." << std::endl; + } + + if( !grid ) return; + + Log::debug() << "Domain: " << grid.domain() << std::endl; + Log::debug() << "Periodic: " << grid.periodic() << std::endl; + + MeshGenerator meshgenerator("structured"); + + size_t halo = args.getLong("halo",1); + + size_t iterations = 10; + parallel::mpi::comm().barrier(); + TimerStats timer_stats; + for( size_t i=0; i Date: Fri, 22 Sep 2017 18:04:06 +0000 Subject: [PATCH 006/355] ATLAS-132 Add Timer configurable with using mpi barriers --- src/atlas/library/Library.cc | 62 ++++++++---- src/atlas/library/Library.h | 16 +++ src/atlas/runtime/Timer.h | 184 +++++++++++++++++++++++++++++++++++ 3 files changed, 245 insertions(+), 17 deletions(-) create mode 100644 src/atlas/runtime/Timer.h diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 416232f30..c8cced586 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -22,8 +22,10 @@ #endif #include "eckit/runtime/Main.h" +#include "eckit/log/Log.h" #include "eckit/filesystem/PathName.h" #include "eckit/filesystem/LocalPathName.h" +#include "eckit/utils/Translator.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" @@ -38,6 +40,25 @@ using eckit::LocalPathName; namespace atlas { + +//---------------------------------------------------------------------------------------------------------------------- + +namespace { + std::string str(bool v) { + return v ? "ON" : "OFF"; + } + + 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); + } + return ss.str(); + } +} + //---------------------------------------------------------------------------------------------------------------------- static Library libatlas; @@ -75,8 +96,13 @@ void Library::initialise(int argc, char **argv) { } void Library::initialise(const eckit::Parametrisation& config) { - std::ostream& out = Log::debug(); + // Timer configuration + config.get("timer.barriers",timer_.barriers_); + timer_.channel_ = &Log::debug(); + + // Summary + std::ostream& out = Log::debug(); out << "Executable [" << Main::instance().name() << "]\n"; out << " \n"; out << " current dir [" << PathName(LocalPathName::cwd()).fullName() << "]\n"; @@ -86,12 +112,24 @@ void Library::initialise(const eckit::Parametrisation& config) { out << " size [" << parallel::mpi::comm().size() << "] \n"; out << " rank [" << parallel::mpi::comm().rank() << "] \n"; out << " \n"; + out << " TIMERS\n"; + out << " barrier [" << str(timer().barriers()) << "] \n"; + out << " \n"; out << atlas::Library::instance().info(); out << std::flush; } void Library::initialise() { - initialise( util::NoConfig() ); + util::Config timer_config; + + if (::getenv("ATLAS_TIMER_BARRIERS")) { + bool var = eckit::Translator()(::getenv("ATLAS_TIMER_BARRIERS")); + timer_config.set("barriers",var); + } + + util::Config config; + config.set("timer",timer_config); + initialise( config ); } void Library::finalise() { @@ -111,22 +149,12 @@ void Library::finalise() { Log::flush(); } -//---------------------------------------------------------------------------------------------------------------------- - -namespace { - std::string str(bool v) { - return v ? "ON" : "OFF"; - } +bool Library::Timer::barriers() const { + return barriers_; +} - 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); - } - return ss.str(); - } +std::ostream& Library::Timer::channel() const { + return *channel_; } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/library/Library.h b/src/atlas/library/Library.h index ae05e6734..3b97e8b54 100644 --- a/src/atlas/library/Library.h +++ b/src/atlas/library/Library.h @@ -10,6 +10,8 @@ #pragma once +#include +#include #include "eckit/system/Library.h" namespace eckit { @@ -43,10 +45,24 @@ class Library : public eckit::system::Library { }; Info info() const { return Info(); } + class Timer { + public: + bool barriers() const; + std::ostream& channel() const; + private: + friend class Library; + bool barriers_{false}; + std::ostream* channel_; + }; + + const Timer& timer() const { return timer_; } + protected: virtual const void* addr() const override; + Timer timer_; + }; typedef Library Atlas; diff --git a/src/atlas/runtime/Timer.h b/src/atlas/runtime/Timer.h new file mode 100644 index 000000000..a2e0eda32 --- /dev/null +++ b/src/atlas/runtime/Timer.h @@ -0,0 +1,184 @@ +/* + * (C) Copyright 1996-2017 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 "eckit/log/Timer.h" +#include "atlas/library/Library.h" +#include "atlas/runtime/Log.h" +#include "atlas/parallel/mpi/mpi.h" + +namespace atlas { + +template< typename TimerTraits > +class TimerT { +public: + using Barriers = typename TimerTraits::Barriers; + using Log = typename TimerTraits::Log; + +private: + + TimerT(const std::string& msg, std::ostream* _out) : + out_(_out), + finished_(false), + msg_(msg) { + timer_.stop(); + out() << msg << " ..." << std::endl; + barrier(); + timer_.start(); + } + +public: + + TimerT(const std::string& msg, std::ostream& out) : + TimerT(msg,&out){ + } + + TimerT(const std::string& msg) : + TimerT(msg,nullptr) { + } + + TimerT() : + TimerT(std::string(),&empty_channel()) { + } + + ~TimerT() { + finish(); + } + + static eckit::Channel& empty_channel() { + static eckit::Channel channel; + return channel; + } + + std::ostream& out() const { + if( out_ ) + return *out_; + else + return Log::channel(); + } + + void barrier() const { + Barriers::execute(); + } + + bool finished() const { return finished_; } + + void finish() { + if( not finished_ ) { + barrier(); + timer_.stop(); + out() << msg_ << " ... done : " << timer_.elapsed() << " seconds" << std::endl; + finished_ = true; + } + } + + double elapsed() const { return timer_.elapsed(); } + +private: + mutable eckit::Timer timer_; + std::ostream* out_{nullptr}; + bool finished_; + std::string msg_; +}; + + +namespace { + +class TimerBarriers { +private: + class State { + private: + State() { + barriers_ = atlas::Library::instance().timer().barriers(); + } + bool barriers_; + public: + static State& instance() { + static State state; + return state; + } + operator bool() const { return barriers_; } + void set(bool state) { barriers_ = state; } + }; + + bool previous_state_; + +public: + TimerBarriers(bool state) : + previous_state_( State::instance() ) { + State::instance().set(state); + } + ~TimerBarriers() { + State::instance().set(previous_state_); + } + static void execute() { + if( State::instance() ) { + parallel::mpi::comm().barrier(); + } + } +}; + +class TimerLog { +private: + class State { + private: + std::ostream* channel_; + + State() { + channel_ = &atlas::Library::instance().timer().channel(); + } + + public: + + static eckit::Channel& empty_channel() { + static eckit::Channel channel; + return channel; + } + + static State& instance() { + static State channel; + return channel; + } + + operator std::ostream&() { return *channel_; } + operator std::ostream*() { return channel_; } + + void set(std::ostream& channel ) { channel_ = &channel; } + }; + + std::ostream* previous_state_; + +public: + TimerLog(bool state) : + previous_state_( State::instance() ) { + if( state == false ) + State::instance().set( State::empty_channel() ); + } + TimerLog(std::ostream& channel) : + previous_state_( State::instance() ) { + State::instance().set( channel ); + } + ~TimerLog() { + State::instance().set( *previous_state_ ); + } + static std::ostream& channel() { return State::instance(); } +}; + +struct TimerTraits { + using Barriers = TimerBarriers; + using Log = TimerLog; +}; + +} + +using Timer = TimerT< TimerTraits >; + +} // namespace atlas From 6d0a76f924402eee85210d1ea7ed89f9811fcd4e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 22 Sep 2017 18:04:46 +0000 Subject: [PATCH 007/355] ATLAS-132 Timer hunting for ATLAS-103 --- src/apps/atlas-benchmark.cc | 51 ++- src/atlas/functionspace/EdgeColumns.cc | 18 +- src/atlas/functionspace/NodeColumns.cc | 19 +- src/atlas/mesh/actions/BuildDualMesh.cc | 360 +----------------- src/atlas/mesh/actions/BuildHalo.cc | 20 + src/atlas/mesh/actions/BuildParallelFields.cc | 16 + src/atlas/parallel/GatherScatter.cc | 16 +- .../benchmark_build_halo/CMakeLists.txt | 2 +- 8 files changed, 120 insertions(+), 382 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index f323a5aa8..630c40512 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -51,6 +51,7 @@ #include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildPeriodicBoundaries.h" #include "atlas/runtime/AtlasTool.h" +#include "atlas/runtime/Timer.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/output/Gmsh.h" #include "atlas/parallel/Checksum.h" @@ -58,6 +59,9 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/omp/omp.h" +#define ATLAS_TIME(msg) \ + for( atlas::Timer itimer##__LINE__(msg); not itimer##__LINE__.finished(); itimer##__LINE__.finish() ) + //---------------------------------------------------------------------------------------------------------------------- using std::unique_ptr; @@ -84,8 +88,6 @@ using namespace atlas::mesh::actions; using namespace atlas::functionspace; using namespace atlas::meshgenerator; using atlas::AtlasTool; -using eckit::Timer; - namespace { void usage(const std::string& tool) { @@ -129,6 +131,8 @@ struct TimerStats int cnt; }; +//---------------------------------------------------------------------------------------------------------------------- + class AtlasBenchmark: public AtlasTool { virtual void execute(const Args& args); @@ -188,6 +192,8 @@ class AtlasBenchmark: public AtlasTool { void AtlasBenchmark::execute(const Args& args) { + Timer::Log set_channel( Log::info() ); + nlev = 137; args.get("nlev",nlev); gridname = "N64"; @@ -224,7 +230,7 @@ void AtlasBenchmark::execute(const Args& args) Log::info() << "Timings:" << endl; - setup(); + ATLAS_TIME("setup") { setup(); } Log::info() << " Executing " << niter << " iterations: \n"; if( progress ) @@ -277,24 +283,18 @@ void AtlasBenchmark::execute(const Args& args) void AtlasBenchmark::setup() { - Timer timer( "setup", Log::debug()); - - StructuredGrid grid = Grid(gridname); - mesh = MeshGenerator( "structured" ).generate(grid); - size_t halo = 1; - build_nodes_parallel_fields(mesh.nodes()); - build_periodic_boundaries(mesh); - build_halo(mesh,1); - renumber_nodes_glb_idx(mesh.nodes()); - build_edges(mesh); - build_pole_edges(mesh); - build_edges_parallel_fields(mesh); - build_median_dual_mesh(mesh); - build_node_to_edge_connectivity(mesh); + StructuredGrid grid; + ATLAS_TIME( "Create grid" ) { grid = Grid(gridname); } + ATLAS_TIME( "Create mesh" ) { mesh = MeshGenerator( "structured" ).generate(grid); } - nodes_fs = functionspace::NodeColumns(mesh,option::halo(halo)); + ATLAS_TIME( "Create node_fs") { nodes_fs = functionspace::NodeColumns(mesh,option::halo(halo)); } + ATLAS_TIME( "build_edges" ) { build_edges(mesh); } + ATLAS_TIME( "build_pole_edges" ) { build_pole_edges(mesh); } + ATLAS_TIME( "build_edges_parallel_fiels" ) { build_edges_parallel_fields(mesh); } + ATLAS_TIME( "build_median_dual_mesh" ) { build_median_dual_mesh(mesh); } + ATLAS_TIME( "build_node_to_edge_connectivity" ) { build_node_to_edge_connectivity(mesh); } scalar_field = nodes_fs.createField( option::name("field") | option::levels(nlev) ); grad_field = nodes_fs.createField( option::name("grad") | option::levels(nlev) | option::variables(3) ); @@ -366,17 +366,13 @@ void AtlasBenchmark::setup() { is_ghost.push_back( Topology::check(flags(jnode),Topology::GHOST) ); } - - - Log::info() << " setup: " << timer.elapsed() << endl; - } //---------------------------------------------------------------------------------------------------------------------- void AtlasBenchmark::iteration() { - Timer t("iteration", Log::debug()); + Timer t("iteration"); unique_ptr avgS_arr( array::Array::create(nedges,nlev,2ul) ); const auto& node2edge = mesh.nodes().edge_connectivity(); @@ -458,12 +454,11 @@ void AtlasBenchmark::iteration() } // halo-exchange - parallel::mpi::comm().barrier(); - Timer halo("halo-exchange", Log::debug()); + Timer halo("halo-exchange"); nodes_fs.halo_exchange().execute(grad); - parallel::mpi::comm().barrier(); - t.stop(); - halo.stop(); + halo.finish(); + + t.finish(); if( iter >= exclude ) { diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 322a4abc9..12c897c6e 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -27,6 +27,7 @@ #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/Checksum.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" #include "atlas/array/MakeView.h" #ifdef ATLAS_HAVE_FORTRAN @@ -171,6 +172,8 @@ EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo &halo) : void EdgeColumns::constructor() { + Timer scope_timer("EdgeColumns()"); + nb_edges_ = mesh().edges().size(); gather_scatter_.reset(new parallel::GatherScatter()); @@ -181,22 +184,31 @@ void EdgeColumns::constructor() const Field& remote_index = edges().remote_index(); const Field& global_index = edges().global_index(); - halo_exchange_->setup( + { + Timer t( "Setup halo_exchange" ); + halo_exchange_->setup( array::make_view(partition).data(), array::make_view(remote_index).data(),REMOTE_IDX_BASE, nb_edges_); + } - gather_scatter_->setup( + { + Timer t( "Setup gather_scatter" ); + gather_scatter_->setup( array::make_view(partition).data(), array::make_view(remote_index).data(),REMOTE_IDX_BASE, array::make_view(global_index).data(), nb_edges_); + } - checksum_->setup( + { + Timer t( "Setup checksum" ); + checksum_->setup( array::make_view(partition).data(), array::make_view(remote_index).data(),REMOTE_IDX_BASE, array::make_view(global_index).data(), nb_edges_); + } nb_edges_global_ = gather_scatter_->glb_dof(); } diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index ea11cc5f4..d0d1bad61 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -30,6 +30,7 @@ #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" #undef atlas_omp_critical_ordered #define atlas_omp_critical_ordered atlas_omp_critical #include "atlas/array/ArrayView.h" @@ -100,6 +101,7 @@ NodeColumns::NodeColumns( Mesh& mesh, const eckit::Configuration & config ) : nb_levels_( config.getInt("levels",0) ), nb_nodes_(nodes_.size()), nb_nodes_global_(0) { + Timer scope_timer(__FUNCTION__); constructor(); } @@ -130,13 +132,18 @@ void NodeColumns::constructor() } } - Field& part = mesh_.nodes().partition(); - Field& ridx = mesh_.nodes().remote_index(); - halo_exchange_->setup( array::make_view(part).data(), - array::make_view(ridx).data(), - REMOTE_IDX_BASE,nb_nodes_); + { + Timer t( "HaloExchange" ); + Field& part = mesh_.nodes().partition(); + Field& ridx = mesh_.nodes().remote_index(); + halo_exchange_->setup( array::make_view(part).data(), + array::make_view(ridx).data(), + REMOTE_IDX_BASE,nb_nodes_); + } { + Timer t( "GatherScatter"); + // Create new gather_scatter gather_scatter_.reset( new parallel::GatherScatter() ); @@ -163,6 +170,8 @@ void NodeColumns::constructor() } { + Timer t( "Checksum" ); + // Create new checksum checksum_.reset( new parallel::Checksum() ); diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index 5f811db89..94219e9cd 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -29,6 +29,7 @@ #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" #include "atlas/runtime/ErrorHandling.h" +#include "atlas/runtime/Timer.h" #include "atlas/parallel/Checksum.h" using atlas::functionspace::NodeColumns; @@ -42,6 +43,8 @@ namespace { void global_bounding_box( const mesh::Nodes& nodes, double min[2], double max[2] ) { + Timer scope_timer(__FUNCTION__); + array::ArrayView xy = array::make_view( nodes.xy() ); const int nb_nodes = nodes.size(); min[XX] = std::numeric_limits::max(); @@ -96,13 +99,12 @@ void add_median_dual_volume_contribution_poles( const mesh::HybridElements& edges, const mesh::Nodes& nodes, array::Array& array_dual_volumes ); -void build_dual_normals_old( Mesh& mesh ); void build_dual_normals( Mesh& mesh ); -void build_skewness(Mesh& mesh ); void make_dual_normals_outward( Mesh& mesh ); void build_median_dual_mesh( Mesh& mesh ) { + Timer scope_timer(__FUNCTION__); mesh::Nodes& nodes = mesh.nodes(); mesh::HybridElements& edges = mesh.edges(); @@ -131,10 +133,16 @@ void build_median_dual_mesh( Mesh& mesh ) array::make_view(alpha).assign(0.5); functionspace::NodeColumns nodes_fs(mesh, Halo(mesh)); - nodes_fs.haloExchange(nodes.field( "dual_volumes" )); + { + Timer t("halo-exchange dual_volumes"); + nodes_fs.haloExchange(nodes.field( "dual_volumes" )); + } functionspace::EdgeColumns edges_fs(mesh, Halo(mesh)); - edges_fs.haloExchange(edges.field( "dual_normals" )); + { + Timer t("halo-exchange dual_normals"); + edges_fs.haloExchange(edges.field( "dual_normals" )); + } make_dual_normals_outward(mesh); } @@ -171,6 +179,8 @@ void add_median_dual_volume_contribution_cells( const mesh::Nodes& nodes, array::Array& array_dual_volumes ) { + Timer scope_timer(__FUNCTION__); + array::ArrayView dual_volumes = array::make_view ( array_dual_volumes ); const array::ArrayView xy = array::make_view( nodes.xy() ); @@ -217,6 +227,8 @@ void add_median_dual_volume_contribution_poles( const mesh::Nodes& nodes, array::Array& array_dual_volumes ) { + Timer scope_timer(__FUNCTION__); + array::ArrayView dual_volumes = array::make_view( array_dual_volumes ); const array::ArrayView xy = array::make_view( nodes.xy() ); const array::ArrayView edge_centroids = array::make_view( edges.field("centroids_xy") ); @@ -272,6 +284,8 @@ void add_median_dual_volume_contribution_poles( void build_dual_normals( Mesh& mesh ) { + Timer scope_timer(__FUNCTION__); + array::ArrayView elem_centroids = array::make_view( mesh.cells().field("centroids_xy") ); mesh::Nodes& nodes = mesh.nodes(); @@ -373,6 +387,7 @@ void build_dual_normals( Mesh& mesh ) void make_dual_normals_outward( Mesh& mesh ) { + Timer scope_timer(__FUNCTION__); mesh::Nodes& nodes = mesh.nodes(); array::ArrayView node_xy = array::make_view( nodes.xy() ); @@ -451,343 +466,6 @@ void build_centroid_dual_mesh( Mesh& mesh ) // This requires code below which has not been ported yet } -#if TO_BE_PORTED_TO_ATLAS_V_0_6 - -void build_dual_normals( Mesh& mesh ) -{ - - std::vector< array::ArrayView > elem_centroids( mesh.nb_function_spaces() ); - for (size_t func_space_idx = 0; func_space_idx < mesh.nb_function_spaces(); ++func_space_idx) - { - deprecated::FunctionSpace& func_space = mesh.function_space(func_space_idx); - if( func_space.has_field("centroids") ) - elem_centroids[func_space_idx] = array::ArrayView( func_space.field("centroids") ); - } - - mesh::Nodes& nodes = mesh.nodes(); - array::ArrayView node_xy( nodes.xy() ); - double min[2], max[2]; - global_bounding_box( nodes, min, max ); - double tol = 1.e-6; - - double xl, yl, xr, yr; - deprecated::FunctionSpace& edges = mesh.function_space("edges"); - array::IndexView edge_to_elem ( edges.field("to_elem" ) ); - array::IndexView edge_nodes ( edges.field("nodes" ) ); - array::ArrayView edge_centroids( edges.field("centroids") ); - array::ArrayView dual_normals ( edges.create_field("dual_normals",2) ); - int nb_edges = edges.shape(0); - - std::map > node_to_bdry_edge; - for(int edge=0; edge= 0 && edge_to_elem(edge,3) < 0) - { - node_to_bdry_edge[ edge_nodes(edge,0) ].push_back(edge); - node_to_bdry_edge[ edge_nodes(edge,1) ].push_back(edge); - } - } - - for (int edge=0; edge& bdry_edges = node_to_bdry_edge[node]; - double x[2]; - int cnt=0; - for (size_t jedge = 0; jedge < bdry_edges.size(); ++jedge) - { - int bdry_edge = bdry_edges[jedge]; - if ( std::abs(edge_centroids(bdry_edge,YY)-max[YY]) 0.) - dual_normals(edge,YY) = std::abs(x[1]-x[0]); - - //std::cout << "pole dual_normal = " << dual_normals(YY,edge) << std::endl; - break; - } - } - } - else - { - int left_func_space_idx = edge_to_elem(edge,0); - int left_elem = edge_to_elem(edge,1); - int right_func_space_idx = edge_to_elem(edge,2); - int right_elem = edge_to_elem(edge,3); - xl = elem_centroids[left_func_space_idx](left_elem,XX); - yl = elem_centroids[left_func_space_idx](left_elem,YY); - if( right_elem < 0 ) - { - xr = edge_centroids(edge,XX); - yr = edge_centroids(edge,YY);; - if ( std::abs(yr-max[YY])& dual_volumes ) -{ - mesh::Nodes& nodes = mesh.nodes(); - deprecated::FunctionSpace& edges = mesh.function_space("edges"); - array::ArrayView node_glb_idx ( nodes.field("glb_idx" ) ); - array::ArrayView edge_centroids( edges.field("centroids" ) ); - array::IndexView edge_nodes ( edges.field("nodes" ) ); - array::ArrayView edge_glb_idx ( edges.field("glb_idx" ) ); - array::IndexView edge_to_elem ( edges.field("to_elem" ) ); - array::ArrayView node_xy ( nodes.xy() ); - std::vector< array::ArrayView > elem_centroids(mesh.nb_function_spaces()); - for(size_t f = 0; f < mesh.nb_function_spaces(); ++f) - { - deprecated::FunctionSpace& elements = mesh.function_space(f); - if( elements.metadata().get("type") == Entity::ELEMS ) - { - elem_centroids[f] = array::ArrayView( elements.field("centroids") ); - } - } - double tol = 1.e-6; - double min[2], max[2]; - global_bounding_box( nodes, min, max ); - - int nb_edges = edges.shape(0); - - // special ordering for bit-identical results - std::vector ordering(nb_edges); - for (int edge=0; edge= 0 && edge_to_elem(edge,2) >= 0 ) - { - double x0 = elem_centroids[edge_to_elem(edge,0)](edge_to_elem(edge,1),XX); - double y0 = elem_centroids[edge_to_elem(edge,0)](edge_to_elem(edge,1),YY); - double x1 = elem_centroids[edge_to_elem(edge,2)](edge_to_elem(edge,3),XX); - double y1 = elem_centroids[edge_to_elem(edge,2)](edge_to_elem(edge,3),YY); - for( int jnode=0; jnode<2; ++jnode ) - { - int node = edge_nodes(edge,jnode); - double x2 = node_xy( node, XX ); - double y2 = node_xy( node, YY ); - double triag_area = std::abs( x0*(y1-y2)+x1*(y2-y0)+x2*(y0-y1) )*0.5; - dual_volumes(node) += triag_area; - } - } - else if ( edge_to_elem(edge,0) >= 0 && edge_to_elem(edge,2) < 0 ) - { - // This is a boundary edge - double x0 = elem_centroids[edge_to_elem(edge,0)](edge_to_elem(edge,1),XX); - double y0 = elem_centroids[edge_to_elem(edge,0)](edge_to_elem(edge,1),YY); - double x1 = x0; - double y1 = 0; - double y_edge = edge_centroids(edge,YY); - if ( std::abs(y_edge-max[YY]) xy ( nodes.xy() ); - array::ArrayView dual_volumes ( nodes.add( field::Field::create( "dual_volumes", array::make_shape(nodes.size(),1) ) ) ); - - deprecated::FunctionSpace& quads = mesh.function_space( "quads" ); - deprecated::FunctionSpace& triags = mesh.function_space( "triags" ); - deprecated::FunctionSpace& edges = mesh.function_space( "edges" ); - - build_centroids(quads, xy); - build_centroids(triags, xy); - build_centroids(edges, xy); - - add_centroid_dual_volume_contribution( mesh, dual_volumes ); - - build_dual_normals_old( mesh ); - - build_skewness( mesh ); - - functionspace::NodeColumns nodes_fs(mesh,Halo(mesh)); - nodes_fs.haloExchange(nodes.field("dual_volumes")); - - array::ArrayView dual_normals ( edges.field( "dual_normals" ) ); - edges.parallelise(); - edges.halo_exchange().execute(dual_normals); -} - - - -void build_centroids( deprecated::FunctionSpace& func_space, array::ArrayView& xy) -{ - if( !func_space.has_field("centroids") ) - { - int nb_elems = func_space.shape(0); - array::IndexView elem_nodes( func_space.field( "nodes" ) ); - int nb_nodes_per_elem = elem_nodes.shape(1); - array::ArrayView elem_centroids( func_space.create_field( "centroids", 2 ) ); - for (size_t e=0; e(nb_nodes_per_elem); - elem_centroids(e,YY) /= static_cast(nb_nodes_per_elem); - } - } -} - -void build_skewness( Mesh& mesh ) -{ - std::vector< array::ArrayView > elem_centroids( mesh.nb_function_spaces() ); - for (size_t func_space_idx = 0; func_space_idx < mesh.nb_function_spaces(); ++func_space_idx) - { - deprecated::FunctionSpace& func_space = mesh.function_space(func_space_idx); - if( func_space.has_field("centroids") ) - elem_centroids[func_space_idx] = array::ArrayView( func_space.field("centroids") ); - } - - mesh::Nodes& nodes = mesh.nodes(); - array::ArrayView node_xy( nodes.xy() ); - double min[2], max[2]; - global_bounding_box( nodes, min, max ); - double tol = 1.e-6; - - double x1, y1, x2, y2, xc1, yc1, xc2, yc2, xi, yi; - deprecated::FunctionSpace& edges = mesh.function_space("edges"); - array::IndexView edge_to_elem ( edges.field("to_elem" ) ); - array::IndexView edge_nodes ( edges.field("nodes" ) ); - array::ArrayView edge_centroids( edges.field("centroids") ); - array::ArrayView skewness ( edges.create_field("skewness",1) ); - array::ArrayView alpha ( edges.create_field("alpha",1) ); - int nb_edges = edges.shape(0); - - // special ordering for bit-identical results - std::vector ordering(nb_edges); - for (int edge=0; edge > Node2Elem; void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) { + Timer t(__FUNCTION__); + const mesh::Nodes& nodes = mesh.nodes(); node2elem.resize(nodes.size()); @@ -118,6 +121,8 @@ void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) void accumulate_partition_bdry_nodes_old( Mesh& mesh, std::vector& bdry_nodes ) { + Timer t(__FUNCTION__); + std::set bdry_nodes_set; std::vector< idx_t > facet_nodes; @@ -154,6 +159,7 @@ void accumulate_partition_bdry_nodes( Mesh& mesh, size_t halo, std::vector& /* deprecated */ accumulate_partition_bdry_nodes_old(mesh,bdry_nodes); #else + Timer t(__FUNCTION__); const Mesh::Polygon& polygon = mesh.polygon(halo); bdry_nodes = std::vector( polygon.begin(), polygon.end() ); #endif @@ -214,6 +220,7 @@ class Notification typedef std::map Uid2Node; void build_lookup_uid2node( Mesh& mesh, Uid2Node& uid2node ) { + Timer t(__FUNCTION__); Notification notes; mesh::Nodes& nodes = mesh.nodes(); array::ArrayView xy = array::make_view ( nodes.xy() ); @@ -249,6 +256,7 @@ void accumulate_elements( const Mesh& mesh, std::vector& found_elements, std::set< uid_t >& new_nodes_uid ) { + Timer t(__FUNCTION__); const mesh::HybridElements::Connectivity &elem_nodes = mesh.cells().node_connectivity(); const array::ArrayView elem_part = array::make_view( mesh.cells().partition() ); @@ -377,6 +385,7 @@ class BuildHaloHelper static void all_to_all(Buffers& send, Buffers& recv) { + Timer t("all_to_all"); const eckit::mpi::Comm& comm = parallel::mpi::comm(); comm.allToAll(send.node_glb_idx, recv.node_glb_idx); @@ -513,6 +522,8 @@ class BuildHaloHelper template< typename NodeContainer, typename ElementContainer > void fill_sendbuffer(Buffers& buf,const NodeContainer& nodes_uid, const ElementContainer& elems, const PeriodicTransform& transform, int newflags, const int p) { + Timer t(__FUNCTION__); + int nb_nodes = nodes_uid.size(); buf.node_glb_idx[p].resize(nb_nodes); buf.node_part [p].resize(nb_nodes); @@ -586,6 +597,8 @@ class BuildHaloHelper void add_nodes(Buffers& buf) { + Timer t(__FUNCTION__); + mesh::Nodes& nodes = mesh.nodes(); int nb_nodes = nodes.size(); @@ -670,6 +683,8 @@ class BuildHaloHelper void add_elements(Buffers& buf) { + Timer t(__FUNCTION__); + // Elements might be duplicated from different Tasks. We need to identify unique entries std::set elem_uid; int nb_elems = mesh.cells().size(); @@ -761,8 +776,11 @@ namespace { void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, const bool& periodic = false ) { #ifndef ATLAS_103 /* deprecated */ + Timer t("gather_bdry_nodes old way"); + parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); #else + Timer t(__FUNCTION__); Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); if( periodic ) { // add own rank to neighbours to allow periodicity with self (pole caps) @@ -994,6 +1012,8 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri void build_halo(Mesh& mesh, int nb_elems ) { + Timer scope_timer(__FUNCTION__); + int halo = 0; mesh.metadata().get("halo",halo); if( halo == nb_elems ) diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index c6951e024..f3697fefb 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -25,6 +25,7 @@ #include "atlas/array.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/ErrorHandling.h" +#include "atlas/runtime/Timer.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/GatherScatter.h" @@ -90,6 +91,7 @@ struct Node void build_parallel_fields( Mesh& mesh ) { + Timer scope_timer(__FUNCTION__); build_nodes_parallel_fields( mesh.nodes() ); } @@ -97,6 +99,7 @@ void build_parallel_fields( Mesh& mesh ) void build_nodes_parallel_fields( mesh::Nodes& nodes ) { + Timer scope_timer(__FUNCTION__); bool parallel = false; nodes.metadata().get("parallel",parallel); if( ! parallel ) @@ -112,6 +115,7 @@ void build_nodes_parallel_fields( mesh::Nodes& nodes ) void build_edges_parallel_fields( Mesh& mesh ) { + Timer scope_timer(__FUNCTION__); build_edges_partition ( mesh ); build_edges_remote_idx( mesh ); build_edges_global_idx( mesh ); @@ -121,6 +125,8 @@ void build_edges_parallel_fields( Mesh& mesh ) Field& build_nodes_global_idx( mesh::Nodes& nodes ) { + Timer scope_timer(__FUNCTION__); + array::ArrayView glb_idx = array::make_view( nodes.global_index() ); UniqueLonLat compute_uid(nodes); @@ -135,6 +141,8 @@ Field& build_nodes_global_idx( mesh::Nodes& nodes ) void renumber_nodes_glb_idx( mesh::Nodes& nodes ) { + Timer scope_timer(__FUNCTION__); + // TODO: ATLAS-14: fix renumbering of EAST periodic boundary points // --> Those specific periodic points at the EAST boundary are not checked for uid, // and could receive different gidx for different tasks @@ -224,6 +232,7 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) Field& build_nodes_remote_idx( mesh::Nodes& nodes ) { + Timer scope_timer(__FUNCTION__); size_t mypart = parallel::mpi::comm().rank(); size_t nparts = parallel::mpi::comm().size(); @@ -323,6 +332,7 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) Field& build_nodes_partition( mesh::Nodes& nodes ) { + Timer scope_timer(__FUNCTION__); return nodes.partition(); } @@ -330,6 +340,8 @@ Field& build_nodes_partition( mesh::Nodes& nodes ) Field& build_edges_partition( Mesh& mesh ) { + Timer scope_timer(__FUNCTION__); + const mesh::Nodes& nodes = mesh.nodes(); UniqueLonLat compute_uid(mesh); @@ -600,6 +612,8 @@ Field& build_edges_partition( Mesh& mesh ) Field& build_edges_remote_idx( Mesh& mesh ) { + Timer scope_timer(__FUNCTION__); + const mesh::Nodes& nodes = mesh.nodes(); UniqueLonLat compute_uid(mesh); @@ -753,6 +767,8 @@ Field& build_edges_remote_idx( Mesh& mesh ) Field& build_edges_global_idx( Mesh& mesh ) { + Timer scope_timer(__FUNCTION__); + UniqueLonLat compute_uid(mesh); int nparts = parallel::mpi::comm().size(); diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index d036f70f1..7332e6631 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -15,6 +15,7 @@ #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" #include "atlas/parallel/GatherScatter.h" namespace atlas { @@ -115,7 +116,9 @@ void GatherScatter::setup( const int part[], } } - parallel::mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); + { + Timer t( Here() ); parallel::mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); + } glbcnt_ = std::accumulate(glbcounts_.begin(),glbcounts_.end(),0); @@ -126,8 +129,11 @@ void GatherScatter::setup( const int part[], } std::vector recvnodes(glbcnt_); - parallel::mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, - recvnodes.data(), glbcounts_.data(), glbdispls_.data()); + { + Timer t( Here() ); + parallel::mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, + recvnodes.data(), glbcounts_.data(), glbdispls_.data()); + } // Load recvnodes in sorting structure size_t nb_recv_nodes = glbcnt_/nvar; @@ -142,9 +148,11 @@ void GatherScatter::setup( const int part[], recvnodes.clear(); // Sort on "g" member, and remove duplicates + { + Timer t("sorting"); std::sort(node_sort.begin(), node_sort.end()); node_sort.erase( std::unique( node_sort.begin(), node_sort.end() ), node_sort.end() ); - + } glbcounts_.assign(nproc,0); glbdispls_.assign(nproc,0); for( size_t n=0; n Date: Wed, 27 Sep 2017 15:14:25 +0100 Subject: [PATCH 008/355] ATLAS-132 Fix for timing --- src/apps/atlas-benchmark.cc | 10 +- src/atlas/library/Library.cc | 2 + src/atlas/mesh/actions/BuildHalo.cc | 7 + src/atlas/runtime/Timer.h | 219 ++++++++++++++++------------ 4 files changed, 139 insertions(+), 99 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 630c40512..d2eb51a02 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -60,7 +60,7 @@ #include "atlas/parallel/omp/omp.h" #define ATLAS_TIME(msg) \ - for( atlas::Timer itimer##__LINE__(msg); not itimer##__LINE__.finished(); itimer##__LINE__.finish() ) + for( atlas::Timer itimer##__LINE__(msg); itimer##__LINE__.running(); itimer##__LINE__.stop() ) //---------------------------------------------------------------------------------------------------------------------- @@ -121,7 +121,7 @@ struct TimerStats string str() { stringstream stream; - stream << name << ": min, max, avg -- " << min << ", " << max << ", " << avg; + stream << name << ": min, max, avg -- " << fixed << setprecision(5) << min << ", " << fixed << setprecision(5) << max << ", " << fixed << setprecision(5) << avg; return stream.str(); } string name; @@ -283,6 +283,8 @@ void AtlasBenchmark::execute(const Args& args) void AtlasBenchmark::setup() { + Timer::Log set_channel( Log::debug() ); + size_t halo = 1; StructuredGrid grid; @@ -456,9 +458,9 @@ void AtlasBenchmark::iteration() // halo-exchange Timer halo("halo-exchange"); nodes_fs.halo_exchange().execute(grad); - halo.finish(); + halo.stop(); - t.finish(); + t.stop(); if( iter >= exclude ) { diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index c8cced586..a94151ceb 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -33,6 +33,7 @@ #include "atlas/library/Library.h" #include "atlas/library/version.h" #include "atlas/library/git_sha1.h" +#include "atlas/runtime/Timer.h" using eckit::PathName; using eckit::Main; @@ -63,6 +64,7 @@ namespace { static Library libatlas; + Library::Library() : eckit::system::Library( std::string("atlas") ) {} Library& Library::instance() { diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 8b767430b..4a1f02ac5 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -385,6 +385,7 @@ class BuildHaloHelper static void all_to_all(Buffers& send, Buffers& recv) { + Timer t("all_to_all"); const eckit::mpi::Comm& comm = parallel::mpi::comm(); @@ -868,6 +869,8 @@ void increase_halo_interior( BuildHaloHelper& helper ) gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts ); + Timer::Barrier timer_barriers(false); + #ifndef ATLAS_103 /* deprecated */ for (size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) @@ -895,6 +898,8 @@ void increase_halo_interior( BuildHaloHelper& helper ) helper.fill_sendbuffer(sendmesh, found_bdry_nodes_uid, found_bdry_elems, jpart); } + timer_barriers.restore(); + // 5) Now communicate all buffers helper.all_to_all(sendmesh, recvmesh); @@ -970,6 +975,8 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts, /* periodic = */ true ); + Timer::Barrier set_barrier(false); + #ifndef ATLAS_103 /* deprecated */ for (size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) diff --git a/src/atlas/runtime/Timer.h b/src/atlas/runtime/Timer.h index a2e0eda32..540f55fc5 100644 --- a/src/atlas/runtime/Timer.h +++ b/src/atlas/runtime/Timer.h @@ -20,109 +20,137 @@ namespace atlas { template< typename TimerTraits > class TimerT { public: - using Barriers = typename TimerTraits::Barriers; - using Log = typename TimerTraits::Log; + using Barrier = typename TimerTraits::Barrier; + using Log = typename TimerTraits::Log; -private: +public: - TimerT(const std::string& msg, std::ostream* _out) : - out_(_out), - finished_(false), - msg_(msg) { - timer_.stop(); - out() << msg << " ..." << std::endl; - barrier(); - timer_.start(); - } + TimerT(const std::string& msg, std::ostream& out = Log::channel() ); -public: + TimerT(); - TimerT(const std::string& msg, std::ostream& out) : - TimerT(msg,&out){ - } + ~TimerT(); - TimerT(const std::string& msg) : - TimerT(msg,nullptr) { - } - - TimerT() : - TimerT(std::string(),&empty_channel()) { - } + bool running() const; - ~TimerT() { - finish(); - } + void start(); - static eckit::Channel& empty_channel() { - static eckit::Channel channel; - return channel; - } + void stop(); - std::ostream& out() const { - if( out_ ) - return *out_; - else - return Log::channel(); - } + double elapsed() const; - void barrier() const { - Barriers::execute(); - } - - bool finished() const { return finished_; } - - void finish() { - if( not finished_ ) { - barrier(); - timer_.stop(); - out() << msg_ << " ... done : " << timer_.elapsed() << " seconds" << std::endl; - finished_ = true; - } - } - - double elapsed() const { return timer_.elapsed(); } +private: + + void barrier() const; + + static eckit::Channel& empty_channel(); private: - mutable eckit::Timer timer_; - std::ostream* out_{nullptr}; - bool finished_; - std::string msg_; + mutable eckit::Timer timer_; + std::ostream& out_; + std::string msg_; + bool barrier_; }; +// Definitions + +template< typename TimerTraits > +inline TimerT::TimerT(const std::string& msg, std::ostream& out ) : + out_(out), + msg_(msg), + barrier_(Barrier::state()) { + start(); +} + +template< typename TimerTraits > +inline TimerT::TimerT() : + TimerT(std::string(), empty_channel() ) { +} + +template< typename TimerTraits > +inline TimerT::~TimerT() { + stop(); +} + +template< typename TimerTraits > +inline void TimerT::barrier() const { + Barrier::execute(); +} + +template< typename TimerTraits > +inline bool TimerT::running() const { + return timer_.running(); +} + +template< typename TimerTraits > +inline void TimerT::start() { + timer_.stop(); + out_ << msg_ << " ..." << std::endl; + barrier(); + timer_.start(); +} + +template< typename TimerTraits > +inline void TimerT::stop() { + if( running() ) { + barrier(); + timer_.stop(); + out_ << msg_ << " ... done : " << timer_.elapsed() << " seconds" << std::endl; + } +} + +template< typename TimerTraits > +inline double TimerT::elapsed() const { + return timer_.elapsed(); +} + +template< typename TimerTraits > +inline eckit::Channel& TimerT::empty_channel() { + static eckit::Channel channel; + return channel; +} -namespace { -class TimerBarriers { +class TimerBarrier { private: class State { private: - State() { + State() { barriers_ = atlas::Library::instance().timer().barriers(); - } - bool barriers_; + } + bool barriers_; public: - static State& instance() { - static State state; - return state; + State(State const&) = delete; + void operator=(State const&) = delete; + static State& instance() { + static State state; + return state; + } + operator bool() const { + return barriers_; + } + void set( bool state ) { + barriers_ = state; } - operator bool() const { return barriers_; } - void set(bool state) { barriers_ = state; } }; bool previous_state_; public: - TimerBarriers(bool state) : + TimerBarrier(bool state) : previous_state_( State::instance() ) { - State::instance().set(state); + State::instance().set(state); } - ~TimerBarriers() { - State::instance().set(previous_state_); + ~TimerBarrier() { + restore(); } + void restore() { + State::instance().set( previous_state_ ); + } + static bool state() { return State::instance(); } static void execute() { - if( State::instance() ) { - parallel::mpi::comm().barrier(); - } + if( state() ) + parallel::mpi::comm().barrier(); } }; @@ -130,55 +158,56 @@ class TimerLog { private: class State { private: - std::ostream* channel_; + std::ostream* channel_; - State() { + State() { channel_ = &atlas::Library::instance().timer().channel(); } public: - static eckit::Channel& empty_channel() { - static eckit::Channel channel; + static eckit::Channel& empty_channel() { + static eckit::Channel channel; return channel; - } + } - static State& instance() { - static State channel; - return channel; + static State& instance() { + static State channel; + return channel; } - operator std::ostream&() { return *channel_; } - operator std::ostream*() { return channel_; } - - void set(std::ostream& channel ) { channel_ = &channel; } + operator std::ostream&() { return *channel_; } + operator std::ostream*() { return channel_; } + + void set( std::ostream& channel ) { channel_ = &channel; } + void set( bool state ) { if( state == false ) channel_ = &empty_channel(); } }; std::ostream* previous_state_; public: - TimerLog(bool state) : + TimerLog( bool state ) : previous_state_( State::instance() ) { - if( state == false ) - State::instance().set( State::empty_channel() ); + State::instance().set( state ); } - TimerLog(std::ostream& channel) : + TimerLog( std::ostream& channel ) : previous_state_( State::instance() ) { State::instance().set( channel ); } ~TimerLog() { - State::instance().set( *previous_state_ ); + State::instance().set( *previous_state_ ); } static std::ostream& channel() { return State::instance(); } }; struct TimerTraits { - using Barriers = TimerBarriers; - using Log = TimerLog; + using Barrier = TimerBarrier; + using Log = TimerLog; }; -} - -using Timer = TimerT< TimerTraits >; +class Timer : public TimerT< TimerTraits > { +public: + using TimerT::TimerT; +}; } // namespace atlas From 74e098b8c493460ed4548dafd1561f88723664b3 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 21 Sep 2017 16:14:18 +0000 Subject: [PATCH 009/355] Fix compilation with ENABLE_TRANS=OFF --- src/atlas_f/trans/atlas_Trans_module.F90 | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index c0663aba6..1df071795 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -205,42 +205,72 @@ function handle( this ) use atlas_trans_c_binding integer :: handle class(atlas_Trans) :: this +#ifdef ATLAS_HAVE_TRANS handle = atlas__Trans__handle (this%c_ptr()) +#else + THROW_ERROR + handle = 0 +#endif end function function truncation( this ) use atlas_trans_c_binding integer :: truncation class(atlas_Trans) :: this +#ifdef ATLAS_HAVE_TRANS truncation = atlas__Trans__truncation (this%c_ptr()) +#else + THROW_ERROR + truncation = 0 +#endif end function function nb_spectral_coefficients( this ) use atlas_trans_c_binding integer :: nb_spectral_coefficients class(atlas_Trans) :: this +#ifdef ATLAS_HAVE_TRANS nb_spectral_coefficients = atlas__Trans__nspec2 (this%c_ptr()) +#else + THROW_ERROR + nb_spectral_coefficients = 0 +#endif end function function nb_spectral_coefficients_global( this ) use atlas_trans_c_binding integer :: nb_spectral_coefficients_global class(atlas_Trans) :: this +#ifdef ATLAS_HAVE_TRANS nb_spectral_coefficients_global = atlas__Trans__nspec2g (this%c_ptr()) +#else + THROW_ERROR + nb_spectral_coefficients_global = 0 +#endif end function function nb_gridpoints( this ) use atlas_trans_c_binding integer :: nb_gridpoints class(atlas_Trans) :: this +#ifdef ATLAS_HAVE_TRANS nb_gridpoints = atlas__Trans__ngptot (this%c_ptr()) +#else + THROW_ERROR + nb_gridpoints = 0 +#endif end function function nb_gridpoints_global( this ) use atlas_trans_c_binding integer :: nb_gridpoints_global class(atlas_Trans) :: this +#ifdef ATLAS_HAVE_TRANS nb_gridpoints_global = atlas__Trans__ngptotg (this%c_ptr()) +#else + THROW_ERROR + nb_gridpoints_global = 0 +#endif end function function grid( this ) @@ -248,8 +278,13 @@ function grid( this ) use atlas_grid_module class(atlas_Trans) :: this type(atlas_StructuredGrid) :: grid +#ifdef ATLAS_HAVE_TRANS grid = atlas_StructuredGrid( atlas__Trans__grid(this%c_ptr()) ) call grid%return() +#else + THROW_ERROR + call grid%return() +#endif end function subroutine dirtrans_fieldset_nodes(this, gp, gpfields, sp, spfields, parameters) From 38a124119d2356b7aac42b0b604962e065c2e335 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Mon, 25 Sep 2017 12:07:56 +0100 Subject: [PATCH 010/355] ATLAS-105: remove unused code --- src/atlas/CMakeLists.txt | 4 - src/atlas/interpolation/element/Quad2D.cc | 59 -------------- src/atlas/interpolation/element/Quad2D.h | 68 ----------------- src/atlas/interpolation/element/Triag2D.cc | 89 ---------------------- src/atlas/interpolation/element/Triag2D.h | 78 ------------------- src/atlas/util/Earth.cc | 20 ----- src/atlas/util/Earth.h | 6 -- src/tests/util/test_earth.cc | 17 ----- 8 files changed, 341 deletions(-) delete mode 100644 src/atlas/interpolation/element/Quad2D.cc delete mode 100644 src/atlas/interpolation/element/Quad2D.h delete mode 100644 src/atlas/interpolation/element/Triag2D.cc delete mode 100644 src/atlas/interpolation/element/Triag2D.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 2e6f67cea..2cf1219d8 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -320,12 +320,8 @@ interpolation/Vector2D.h interpolation/Vector3D.h interpolation/element/Quad3D.cc interpolation/element/Quad3D.h -interpolation/element/Quad2D.cc -interpolation/element/Quad2D.h interpolation/element/Triag3D.cc interpolation/element/Triag3D.h -interpolation/element/Triag2D.cc -interpolation/element/Triag2D.h interpolation/method/FiniteElement.cc interpolation/method/FiniteElement.h interpolation/method/Intersect.cc diff --git a/src/atlas/interpolation/element/Quad2D.cc b/src/atlas/interpolation/element/Quad2D.cc deleted file mode 100644 index e148adeab..000000000 --- a/src/atlas/interpolation/element/Quad2D.cc +++ /dev/null @@ -1,59 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 "eckit/exception/Exceptions.h" - -#include "atlas/runtime/Log.h" -#include "atlas/interpolation/element/Quad2D.h" -#include "atlas/interpolation/element/Triag2D.h" - -namespace atlas { -namespace interpolation { -namespace element { - -//---------------------------------------------------------------------------------------------------------------------- - -method::Intersect Quad2D::intersects(const Vector2D& p, double edgeEpsilon, double epsilon) const { - method::Intersect isect; // intersection is false - - Triag2D T013(v00, v10, v01); - isect = T013.intersects(p, edgeEpsilon, epsilon); - if(isect) - return isect; - - Triag2D T231(v11, v01, v10); - isect = T231.intersects(p, edgeEpsilon, epsilon); - if(isect) { - isect.u = 1 - isect.u; - isect.v = 1 - isect.v; - return isect; - } - - return isect.fail(); -} - -bool Quad2D::validate() const { - NOTIMP; -} - -double Quad2D::area() const { - Triag2D T013(v00, v10, v01); - Triag2D T231(v11, v01, v10); - - return T013.area() + T231.area(); -} - -//---------------------------------------------------------------------------------------------------------------------- - -} // namespace element -} // namespace interpolation -} // namespace atlas diff --git a/src/atlas/interpolation/element/Quad2D.h b/src/atlas/interpolation/element/Quad2D.h deleted file mode 100644 index 9c5223282..000000000 --- a/src/atlas/interpolation/element/Quad2D.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (C) Copyright 1996-2017 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. - */ - -#ifndef atlas_interpolation_element_Quad2D_h -#define atlas_interpolation_element_Quad2D_h - -#include - -#include "atlas/interpolation/Vector2D.h" -#include "atlas/interpolation/method/Intersect.h" - -namespace atlas { -namespace interpolation { -namespace element { - -//---------------------------------------------------------------------------------------------------------------------- - -class Quad2D { -public: - - Quad2D(const double* x0, const double* x1, const double* x2, const double* x3) { - v00 = Vector2D::Map(x0); - v10 = Vector2D::Map(x1); - v11 = Vector2D::Map(x2); - v01 = Vector2D::Map(x3); - } - - method::Intersect intersects( - const Vector2D& p, - double edgeEpsilon = 5 * std::numeric_limits::epsilon(), - double epsilon = 5 * std::numeric_limits::epsilon() ) const; - - bool validate() const; - - double area() const; - - void print(std::ostream& s) const { - s << "Quad2D[v00=" << v00 << ",v10=" << v10 << ",v11=" << v11 << ",v01=" << v01 << "]"; - } - - friend std::ostream& operator<<(std::ostream& s, const Quad2D& p) { - p.print(s); - return s; - } - -private: // members - Vector2D v00; // aka v0 - Vector2D v10; // aka v1 - Vector2D v11; // aka v2 - Vector2D v01; // aka v3 - -}; - -//---------------------------------------------------------------------------------------------------------------------- - -} // namespace element -} // namespace interpolation -} // namespace atlas - - -#endif diff --git a/src/atlas/interpolation/element/Triag2D.cc b/src/atlas/interpolation/element/Triag2D.cc deleted file mode 100644 index da1459162..000000000 --- a/src/atlas/interpolation/element/Triag2D.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 "eckit/exception/Exceptions.h" - -#include "atlas/interpolation/element/Triag2D.h" -#include "atlas/interpolation/method/Intersect.h" -#include "atlas/interpolation/method/Ray.h" - -//---------------------------------------------------------------------------------------------------------------------- - -namespace { - - -static double dot_sign( - const double& Ax, const double& Ay, - const double& Bx, const double& By, - const double& Cx, const double& Cy ) { - return (Ax - Cx) * (By - Cy) - - (Bx - Cx) * (Ay - Cy); -} - -/// Point-in-triangle test -/// @note "dot product" test, equivalent to half-plane check -/// @see http://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle -static bool point_in_triangle( - const double& Ax, const double& Ay, - const double& Bx, const double& By, - const double& Cx, const double& Cy, - const double& Px, const double& Py ) { - - // Compute signs of dot products - const bool - b1 = dot_sign(Px, Py, Ax, Ay, Bx, By) < 0, - b2 = dot_sign(Px, Py, Bx, By, Cx, Cy) < 0, - b3 = dot_sign(Px, Py, Cx, Cy, Ax, Ay) < 0; - - // Check if point is in triangle - // - check for b1 && b2 && b3 only works for triangles ordered counter-clockwise - // - check for b1==b2 && b2==b3 works for both, equivalent to "all points on the same side" - return (b1 == b2) && (b2 == b3); -} - -} - -namespace atlas { -namespace interpolation { -namespace element { - -method::Intersect Triag2D::intersects(const Vector2D& p, double edgeEpsilon, double epsilon) const { - method::Intersect is; - if( point_in_triangle(v0[0],v0[1],v1[0],v1[1],v2[0],v2[1],p[0],p[1]) ) { - enum { XX=0, YY=1 }; - const double x0 = v0[XX]; - const double x1 = v1[XX]; - const double x2 = v2[XX]; - const double y0 = v0[YY]; - const double y1 = v1[YY]; - const double y2 = v2[YY]; - const double J = (x1 - x0) * (y2 - y0) - (x2 - x0) * (y1 - y0); - - is.u = 1./J * ( (y2 - y0)*p[XX] + (x0 - x2)*p[YY] - x0*y2 + x2*y0 ); - is.v = 1./J * ( (y0 - y1)*p[XX] + (x1 - x0)*p[YY] + x0*y1 - x1*y0 ); - is.success(); - } - return is; -} - -double Triag2D::area() const -{ - NOTIMP; -} - -//---------------------------------------------------------------------------------------------------------------------- - -} // namespace element -} // namespace interpolation -} // namespace atlas - diff --git a/src/atlas/interpolation/element/Triag2D.h b/src/atlas/interpolation/element/Triag2D.h deleted file mode 100644 index 0efc081a2..000000000 --- a/src/atlas/interpolation/element/Triag2D.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * (C) Copyright 1996-2017 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. - */ - -#ifndef atlas_interpolation_element_Triag2D_h -#define atlas_interpolation_element_Triag2D_h - -#include - -#include "atlas/interpolation/Vector2D.h" -#include "atlas/interpolation/method/Intersect.h" - -namespace atlas { -namespace interpolation { -namespace method { -struct Ray; -} -namespace element { - -//---------------------------------------------------------------------------------------------------------------------- - -class Triag2D { - -public: // types - - Triag2D(const Vector2D& x0, const Vector2D& x1, const Vector2D& x2): - v0(x0), - v1(x1), - v2(x2) { - } - - Triag2D(const double* x0, const double* x1, const double* x2) { - v0 = Vector2D::Map(x0); - v1 = Vector2D::Map(x1); - v2 = Vector2D::Map(x2); - } - - method::Intersect intersects( - const Vector2D& p, - double edgeEpsilon = 5 * std::numeric_limits::epsilon(), - double epsilon = 5 * std::numeric_limits::epsilon() ) const; - - double area() const; - - void print(std::ostream& s) const { - s << "Triag2D[" - << "v0=(" << v0[0] << ", " << v0[1] - << "), v1=(" << v1[0] << ", " << v1[1] - << "), v2=(" << v2[0] << ", " << v2[1] << ")]"; - } - - friend std::ostream& operator<<(std::ostream& s, const Triag2D& p) { - p.print(s); - return s; - } - -private: // members - - Vector2D v0; - Vector2D v1; - Vector2D v2; - -}; - -//---------------------------------------------------------------------------------------------------------------------- - -} // namespace element -} // namespace interpolation -} // namespace atlas - - -#endif diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index 19717b603..3798d4b5c 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -39,21 +39,6 @@ static inline double between_m180_and_p180(double a) { //------------------------------------------------------------------------------------------------------ -double Sphere::azimuth(const PointLonLat& u, const PointLonLat& v, const PointLonLat& w) { - using namespace std; - - // Solve spherical triangle using law of cosines (cosine rule for sides), see: - // https://en.wikipedia.org/wiki/Spherical_law_of_cosines - const double - a = distanceInMeters(u, v, 1.), - b = distanceInMeters(u, w, 1.), - c = distanceInMeters(v, w, 1.), - cos_C = - (cos(a) * cos(b) - cos(c)) / (sin(a) * sin(b)); - - return acos( min(1., max( -1., cos_C ))); -} - - double Sphere::centralAngle(const PointLonLat& p1, const PointLonLat& p2) { using namespace std; @@ -200,11 +185,6 @@ PointLonLat Sphere::convertCartesianToSpherical(const PointXYZ& p, const double& //------------------------------------------------------------------------------------------------------ -double Earth::azimuth(const PointLonLat& source, const PointLonLat& target, const PointLonLat& reference) { - return Sphere::azimuth(source, target, reference); -} - - double Earth::centralAngle(const PointLonLat& p1, const PointLonLat& p2) { return Sphere::centralAngle(p1, p2); } diff --git a/src/atlas/util/Earth.h b/src/atlas/util/Earth.h index df0e83999..54bf4909e 100644 --- a/src/atlas/util/Earth.h +++ b/src/atlas/util/Earth.h @@ -26,9 +26,6 @@ namespace util { struct Sphere { - // Azimuth at source point directed to target point, in respect to reference point, in radians - static double azimuth(const PointLonLat& source, const PointLonLat& target, const PointLonLat& reference); - // Great-circle central angle between two points, in radians static double centralAngle(const PointLonLat&, const PointLonLat&); static double centralAngle(const PointXYZ&, const PointXYZ&, const double& radius); @@ -61,9 +58,6 @@ struct Earth static constexpr double areaInSqMeters() { return 4. * M_PI * radiusInMeters() * radiusInMeters(); } static constexpr double areaInSqKm() { return 4. * M_PI * radiusInKm() * radiusInKm(); } - // Azimuth at source point directed to target point, in respect to reference point, in radians - static double azimuth(const PointLonLat& source, const PointLonLat& target, const PointLonLat& reference); - // Great-circle central angle between two points, in radians static double centralAngle(const PointLonLat&, const PointLonLat&); static double centralAngle(const PointXYZ&, const PointXYZ&, const double& radius = radiusInMeters()); diff --git a/src/tests/util/test_earth.cc b/src/tests/util/test_earth.cc index 39dc91600..ac2a48ce6 100644 --- a/src/tests/util/test_earth.cc +++ b/src/tests/util/test_earth.cc @@ -177,23 +177,6 @@ CASE( "test_earth_lon_315" ) EXPECT(PointXYZ::equal(p2[0], p2[1])); } -CASE( "test_earth_azimuth" ) -{ - const PointLonLat - u( 0., 0.), - v(90., 0.), - w( 0., 90.); - - const double - a = Earth::azimuth(w, u, v), - b = Earth::azimuth(v, w, u), - c = Earth::azimuth(u, v, w); - - EXPECT( eckit::types::is_approximately_equal( a, M_PI_2 ) ); - EXPECT( eckit::types::is_approximately_equal( b, M_PI_2 ) ); - EXPECT( eckit::types::is_approximately_equal( c, M_PI_2 ) ); -} - CASE( "test_earth_great_circle_latitude_given_longitude" ) { // latitude at Valparaíso-Shanghai mid-point From 79103bf00e83b16194a0db80847499741df8d9d2 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Mon, 25 Sep 2017 12:20:50 +0100 Subject: [PATCH 011/355] ATLAS-105: remove unused code --- src/atlas/interpolation/method/FiniteElement.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/atlas/interpolation/method/FiniteElement.cc b/src/atlas/interpolation/method/FiniteElement.cc index ef2841366..9ac30f9ff 100644 --- a/src/atlas/interpolation/method/FiniteElement.cc +++ b/src/atlas/interpolation/method/FiniteElement.cc @@ -18,9 +18,7 @@ #include "eckit/geometry/Point3.h" #include "atlas/interpolation/element/Quad3D.h" -#include "atlas/interpolation/element/Quad2D.h" #include "atlas/interpolation/element/Triag3D.h" -#include "atlas/interpolation/element/Triag2D.h" #include "atlas/interpolation/method/Ray.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/PointCloud.h" From 3d9a88464d1d101ad053f0b60230dbb29d11c525 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 25 Sep 2017 14:48:06 +0000 Subject: [PATCH 012/355] Fix warnings: "No newline at end of file" --- src/atlas/functionspace/PointCloud.cc | 2 +- src/atlas/functionspace/Spectral.cc | 2 ++ src/tests/functionspace/test_pointcloud.cc | 2 +- src/tests/functionspace/test_structuredcolumns.cc | 2 +- src/tests/grid/test_domain.cc | 2 +- src/tests/grid/test_field.cc | 2 +- src/tests/grid/test_grid_ptr.cc | 2 +- src/tests/grid/test_grids.cc | 2 +- src/tests/grid/test_rotation.cc | 2 +- src/tests/grid/test_state.cc | 2 +- src/tests/interpolation/test_interpolation_finite_element.cc | 2 +- src/tests/io/test_gmsh.cc | 2 +- src/tests/io/test_pointcloud_io.cc | 2 +- src/tests/mesh/test_accumulate_facets.cc | 2 +- src/tests/mesh/test_connectivity.cc | 2 +- src/tests/mesh/test_elements.cc | 2 +- src/tests/mesh/test_rgg.cc | 2 +- src/tests/util/test_flags.cc | 2 +- src/tests/util/test_footprint.cc | 2 +- src/tests/util/test_indexview.cc | 2 +- src/tests/util/test_metadata.cc | 2 +- 21 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/atlas/functionspace/PointCloud.cc b/src/atlas/functionspace/PointCloud.cc index dc7f179e1..fd6b7dad9 100644 --- a/src/atlas/functionspace/PointCloud.cc +++ b/src/atlas/functionspace/PointCloud.cc @@ -76,4 +76,4 @@ PointCloud::PointCloud( const std::vector& points ) : } -} \ No newline at end of file +} diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index e5e692661..ad36d1012 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -103,8 +103,10 @@ Spectral::Spectral( trans::Trans& trans, const eckit::Configuration& config ) : Spectral::~Spectral() { +#ifdef ATLAS_HAVE_TRANS if( delete_trans_ ) delete trans_; +#endif } size_t Spectral::footprint() const { diff --git a/src/tests/functionspace/test_pointcloud.cc b/src/tests/functionspace/test_pointcloud.cc index 468ae1042..276e8dce0 100644 --- a/src/tests/functionspace/test_pointcloud.cc +++ b/src/tests/functionspace/test_pointcloud.cc @@ -58,4 +58,4 @@ CASE( "test_functionspace_PointCloud" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/functionspace/test_structuredcolumns.cc b/src/tests/functionspace/test_structuredcolumns.cc index 59e138337..f91e77120 100644 --- a/src/tests/functionspace/test_structuredcolumns.cc +++ b/src/tests/functionspace/test_structuredcolumns.cc @@ -211,4 +211,4 @@ CASE( "test_functionspace_StructuredColumns_halo" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/grid/test_domain.cc b/src/tests/grid/test_domain.cc index 10acb970c..b3b345a64 100644 --- a/src/tests/grid/test_domain.cc +++ b/src/tests/grid/test_domain.cc @@ -126,4 +126,4 @@ CASE( "test_domain_global_from_zonalband" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/grid/test_field.cc b/src/tests/grid/test_field.cc index 33f596968..a9018afe1 100644 --- a/src/tests/grid/test_field.cc +++ b/src/tests/grid/test_field.cc @@ -159,4 +159,4 @@ CASE( "test_wrap_rawdata_direct" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/grid/test_grid_ptr.cc b/src/tests/grid/test_grid_ptr.cc index 4d5441ce8..ecc7728f6 100644 --- a/src/tests/grid/test_grid_ptr.cc +++ b/src/tests/grid/test_grid_ptr.cc @@ -211,4 +211,4 @@ CASE( "test_iterator" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/grid/test_grids.cc b/src/tests/grid/test_grids.cc index 2619d7c47..a78075988 100644 --- a/src/tests/grid/test_grids.cc +++ b/src/tests/grid/test_grids.cc @@ -159,4 +159,4 @@ CASE( "test_reducedgaussian" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/grid/test_rotation.cc b/src/tests/grid/test_rotation.cc index 2d4c33b43..6b10547cc 100644 --- a/src/tests/grid/test_rotation.cc +++ b/src/tests/grid/test_rotation.cc @@ -242,4 +242,4 @@ CASE( "test_rotation_angle_only" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/grid/test_state.cc b/src/tests/grid/test_state.cc index 94816de38..569bfd1ce 100644 --- a/src/tests/grid/test_state.cc +++ b/src/tests/grid/test_state.cc @@ -218,4 +218,4 @@ CASE( "state_create" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/interpolation/test_interpolation_finite_element.cc b/src/tests/interpolation/test_interpolation_finite_element.cc index c1af4a15a..983ecd54c 100644 --- a/src/tests/interpolation/test_interpolation_finite_element.cc +++ b/src/tests/interpolation/test_interpolation_finite_element.cc @@ -101,4 +101,4 @@ CASE( "test_interpolation_finite_element" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/io/test_gmsh.cc b/src/tests/io/test_gmsh.cc index 2ae66822c..aaffaf812 100644 --- a/src/tests/io/test_gmsh.cc +++ b/src/tests/io/test_gmsh.cc @@ -43,4 +43,4 @@ CASE( "test_gmsh_output" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/io/test_pointcloud_io.cc b/src/tests/io/test_pointcloud_io.cc index b901b1891..a9367807f 100644 --- a/src/tests/io/test_pointcloud_io.cc +++ b/src/tests/io/test_pointcloud_io.cc @@ -458,4 +458,4 @@ CASE( "write_read_write_field" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/mesh/test_accumulate_facets.cc b/src/tests/mesh/test_accumulate_facets.cc index 2030564e5..9cd2bc648 100644 --- a/src/tests/mesh/test_accumulate_facets.cc +++ b/src/tests/mesh/test_accumulate_facets.cc @@ -863,4 +863,4 @@ CASE( "test_build_edges_triangles_only" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/mesh/test_connectivity.cc b/src/tests/mesh/test_connectivity.cc index c37ad7510..a0968d951 100644 --- a/src/tests/mesh/test_connectivity.cc +++ b/src/tests/mesh/test_connectivity.cc @@ -566,4 +566,4 @@ CASE("test_multi_block_connectivity_insert") { int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/mesh/test_elements.cc b/src/tests/mesh/test_elements.cc index f4cac540e..aa663e4fa 100644 --- a/src/tests/mesh/test_elements.cc +++ b/src/tests/mesh/test_elements.cc @@ -476,4 +476,4 @@ CASE( "cells_add_add" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/mesh/test_rgg.cc b/src/tests/mesh/test_rgg.cc index 615c09288..0e165bb85 100644 --- a/src/tests/mesh/test_rgg.cc +++ b/src/tests/mesh/test_rgg.cc @@ -515,4 +515,4 @@ CASE( "test_meshgen_ghost_at_end" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/util/test_flags.cc b/src/tests/util/test_flags.cc index 149d0036d..1956bac0e 100644 --- a/src/tests/util/test_flags.cc +++ b/src/tests/util/test_flags.cc @@ -53,4 +53,4 @@ CASE( "test_Flags" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/util/test_footprint.cc b/src/tests/util/test_footprint.cc index ac2255ff6..dbfd7d42f 100644 --- a/src/tests/util/test_footprint.cc +++ b/src/tests/util/test_footprint.cc @@ -75,4 +75,4 @@ CASE( "test_broadcast_to_self" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index 166b53819..335538f71 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -292,4 +292,4 @@ CASE( "test_indexview_3d" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} diff --git a/src/tests/util/test_metadata.cc b/src/tests/util/test_metadata.cc index 76223dc84..64f6b5788 100644 --- a/src/tests/util/test_metadata.cc +++ b/src/tests/util/test_metadata.cc @@ -77,4 +77,4 @@ CASE( "test_broadcast_to_other" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} From 3761178838e8423f0a28e11e1b265712e9c0ceb9 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 2 Oct 2017 11:19:57 +0100 Subject: [PATCH 013/355] Version 0.12.1 --- VERSION.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.cmake b/VERSION.cmake index 77e783ccd..503ddde3a 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.12.0" ) +set ( ${PROJECT_NAME}_VERSION_STR "0.12.1" ) From b2aff13142acb7145b327797f312bba24f7d4cb7 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 2 Oct 2017 16:21:53 +0100 Subject: [PATCH 014/355] Denote version with develop --- VERSION.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.cmake b/VERSION.cmake index 503ddde3a..1b1e3cf37 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.12.1" ) +set ( ${PROJECT_NAME}_VERSION_STR "0.12.1-develop" ) From 6cd9e56eacebeb9b7f7414fb1652b92890a5bf02 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 4 Oct 2017 16:34:48 +0100 Subject: [PATCH 015/355] Atlas-133 : Improved performance of native arrays --- src/atlas/CMakeLists.txt | 1 + src/atlas/array/ArrayUtil.cc | 24 ++++++++++ src/atlas/array/ArrayUtil.h | 13 +++++ src/atlas/array/LocalView.cc | 6 +-- src/atlas/array/LocalView.h | 49 +++++++++---------- src/atlas/array/native/NativeArrayView.cc | 2 + src/atlas/array/native/NativeArrayView.h | 58 ++++++++++++----------- src/atlas/array/native/NativeIndexView.h | 50 +++++++++---------- 8 files changed, 121 insertions(+), 82 deletions(-) create mode 100644 src/atlas/array/ArrayUtil.cc diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 2cf1219d8..5902b0d87 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -354,6 +354,7 @@ array/ArrayShape.h array/ArraySpec.cc array/ArraySpec.h array/ArrayStrides.h +array/ArrayUtil.cc array/ArrayUtil.h array/ArrayView.h array/DataType.h diff --git a/src/atlas/array/ArrayUtil.cc b/src/atlas/array/ArrayUtil.cc new file mode 100644 index 000000000..769c33024 --- /dev/null +++ b/src/atlas/array/ArrayUtil.cc @@ -0,0 +1,24 @@ +/* + * (C) Copyright 1996-2016 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 "eckit/exception/Exceptions.h" +#include "atlas/array/ArrayUtil.h" + +namespace atlas { +namespace array { + +void throw_OutOfRange( const std::string& class_name, char idx_str, int idx, int max ) { + std::ostringstream msg; msg << class_name << " index " << idx << " out of bounds: " << idx << " >= " << max; + throw eckit::OutOfRange(msg.str(),Here()); +} + +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArrayUtil.h b/src/atlas/array/ArrayUtil.h index 3acea2912..c8fed843a 100644 --- a/src/atlas/array/ArrayUtil.h +++ b/src/atlas/array/ArrayUtil.h @@ -42,6 +42,19 @@ class ArrayDataStore virtual void* voidDataStore() = 0; }; +template < int Dim > +static constexpr char array_dim() { + return + Dim == 0 ? 'i' :( + Dim == 1 ? 'j' :( + Dim == 2 ? 'k' :( + Dim == 3 ? 'l' :( + Dim == 4 ? 'm' :( + '*'))))); +} + +void throw_OutOfRange( const std::string& class_name, char idx_str, int idx, int max ); + //------------------------------------------------------------------------------------------------------ } // namespace array diff --git a/src/atlas/array/LocalView.cc b/src/atlas/array/LocalView.cc index ae7b5d433..58be6202a 100644 --- a/src/atlas/array/LocalView.cc +++ b/src/atlas/array/LocalView.cc @@ -8,8 +8,9 @@ * does it submit to any jurisdiction. */ -#include "atlas/array/LocalView.h" +#include #include "eckit/exception/Exceptions.h" +#include "atlas/array/LocalView.h" //------------------------------------------------------------------------------------------------------ @@ -41,9 +42,6 @@ os << "]"; } -template -static char array_dim(); - //------------------------------------------------------------------------------------------------------ } // namespace array diff --git a/src/atlas/array/LocalView.h b/src/atlas/array/LocalView.h index 9397a0275..6758b03dd 100644 --- a/src/atlas/array/LocalView.h +++ b/src/atlas/array/LocalView.h @@ -42,10 +42,8 @@ #include #include -#include #include "atlas/library/config.h" #include "atlas/array/ArrayUtil.h" -#include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------------------------------ @@ -152,21 +150,26 @@ class LocalView { // -- Private methods - template < typename... Ints > - constexpr int index_part(int dim, int idx, Ints... next_idx) const { - return dim < Rank ? idx*strides_[dim] + index_part( dim+1, next_idx..., idx ) : 0 ; + template < int Dim, typename Int, typename... Ints > + constexpr int index_part(Int idx, Ints... next_idx) const { + return idx*strides_[Dim] + index_part( next_idx... ); + } + + template < int Dim, typename Int > + constexpr int index_part(Int last_idx) const { + return last_idx*strides_[Dim]; } template < typename... Ints > constexpr int index(Ints... idx) const { - return index_part(0, idx...); + return index_part<0>(idx...); } #ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING template < typename... Ints > void check_bounds(Ints... idx) const { - ASSERT( sizeof...(idx) == Rank ); - return check_bounds_part(0, idx...); + static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>(idx...); } #else template < typename... Ints > @@ -175,29 +178,23 @@ class LocalView { template < typename... Ints > void check_bounds_force(Ints... idx) const { - ASSERT( sizeof...(idx) == Rank ); - return check_bounds_part(0, idx...); + static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>(idx...); } - template < typename... Ints > - void check_bounds_part(int dim, int idx, Ints... next_idx) const { - if( dim < Rank ) { - if( size_t(idx) >= shape_[dim] ) { - std::ostringstream msg; msg << "ArrayView index " << array_dim(dim) << " out of bounds: " << idx << " >= " << shape_[dim]; - throw eckit::OutOfRange(msg.str(),Here()); - } - check_bounds_part( dim+1, next_idx..., idx ); + template < int Dim, typename Int, typename... Ints > + void check_bounds_part(Int idx, Ints... next_idx) const { + if( size_t(idx) >= shape_[Dim] ) { + throw_OutOfRange( "LocalView", array_dim(), idx, shape_[Dim] ); } + check_bounds_part( next_idx... ); } - static constexpr char array_dim(size_t dim) { - return - dim == 0 ? 'i' :( - dim == 1 ? 'j' :( - dim == 2 ? 'k' :( - dim == 3 ? 'l' :( - dim == 4 ? 'm' :( - '*'))))); + template < int Dim, typename Int > + void check_bounds_part(Int last_idx) const { + if( size_t(last_idx) >= shape_[Dim] ) { + throw_OutOfRange( "LocalView", array_dim(), last_idx, shape_[Dim] ); + } } private: diff --git a/src/atlas/array/native/NativeArrayView.cc b/src/atlas/array/native/NativeArrayView.cc index 152601986..88dc5559b 100644 --- a/src/atlas/array/native/NativeArrayView.cc +++ b/src/atlas/array/native/NativeArrayView.cc @@ -8,6 +8,8 @@ * does it submit to any jurisdiction. */ +#include +#include "eckit/exception/Exceptions.h" #include "atlas/array/ArrayView.h" //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 16fd2d0db..b64089477 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -50,12 +50,11 @@ #include #include -#include #include +#include #include "atlas/library/config.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/LocalView.h" -#include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------------------------------ @@ -134,12 +133,16 @@ template class ArrayView { } const Slice at(size_t i) const { - if( i>= shape(0) ) throw eckit::OutOfRange(i,shape(0),Here()); + if( i>= shape(0) ) { + throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); + } return Slicer(*this).apply(i); } Slice at(size_t i) { - if( i>= shape(0) ) throw eckit::OutOfRange(i,shape(0),Here()); + if( i>= shape(0) ) { + throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); + } return Slicer(*this).apply(i); } @@ -173,21 +176,26 @@ template class ArrayView { // -- Private methods - template < typename... Ints > - constexpr int index_part(int dim, int idx, Ints... next_idx) const { - return dim < Rank ? idx*strides_[dim] + index_part( dim+1, next_idx..., idx ) : 0 ; + template < int Dim, typename Int, typename... Ints > + constexpr int index_part(Int idx, Ints... next_idx) const { + return idx*strides_[Dim] + index_part( next_idx... ); + } + + template < int Dim, typename Int > + constexpr int index_part(Int last_idx) const { + return last_idx*strides_[Dim]; } template < typename... Ints > constexpr int index(Ints... idx) const { - return index_part(0, idx...); + return index_part<0>(idx...); } #ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING template < typename... Ints > void check_bounds(Ints... idx) const { - ASSERT( sizeof...(idx) == Rank ); - return check_bounds_part(0, idx...); + static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>(idx...); } #else template < typename... Ints > @@ -196,29 +204,23 @@ template class ArrayView { template < typename... Ints > void check_bounds_force(Ints... idx) const { - ASSERT( sizeof...(idx) == Rank ); - return check_bounds_part(0, idx...); + static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>(idx...); } - template < typename... Ints > - void check_bounds_part(int dim, int idx, Ints... next_idx) const { - if( dim < Rank ) { - if( size_t(idx) >= shape_[dim] ) { - std::ostringstream msg; msg << "ArrayView index " << array_dim(dim) << " out of bounds: " << idx << " >= " << shape_[dim]; - throw eckit::OutOfRange(msg.str(),Here()); - } - check_bounds_part( dim+1, next_idx..., idx ); + template < int Dim, typename Int, typename... Ints > + void check_bounds_part(Int idx, Ints... next_idx) const { + if( size_t(idx) >= shape_[Dim] ) { + throw_OutOfRange( "ArrayView", array_dim(), idx, shape_[Dim] ); } + check_bounds_part( next_idx... ); } - static constexpr char array_dim(size_t dim) { - return - dim == 0 ? 'i' :( - dim == 1 ? 'j' :( - dim == 2 ? 'k' :( - dim == 3 ? 'l' :( - dim == 4 ? 'm' :( - '*'))))); + template < int Dim, typename Int > + void check_bounds_part(Int last_idx) const { + if( size_t(last_idx) >= shape_[Dim] ) { + throw_OutOfRange( "ArrayView", array_dim(), last_idx, shape_[Dim] ); + } } // -- Type definitions diff --git a/src/atlas/array/native/NativeIndexView.h b/src/atlas/array/native/NativeIndexView.h index f76c3037a..8bf3a00e7 100644 --- a/src/atlas/array/native/NativeIndexView.h +++ b/src/atlas/array/native/NativeIndexView.h @@ -37,7 +37,6 @@ #include -#include "eckit/exception/Exceptions.h" #include "atlas/array/ArrayUtil.h" #include "atlas/library/config.h" @@ -73,6 +72,7 @@ class FortranIndex private: Value* idx_; }; + } @@ -103,8 +103,8 @@ class IndexView { public: IndexView( Value* data, const size_t shape[Rank] ); - - + + // -- Access methods template < typename... Idx > @@ -122,21 +122,26 @@ class IndexView { // -- Private methods - template < typename... Ints > - constexpr int index_part(int dim, int idx, Ints... next_idx) const { - return dim < Rank ? idx*strides_[dim] + index_part( dim+1, next_idx..., idx ) : 0 ; + template < int Dim, typename Int, typename... Ints > + constexpr int index_part(Int idx, Ints... next_idx) const { + return idx*strides_[Dim] + index_part( next_idx... ); + } + + template < int Dim, typename Int > + constexpr int index_part(Int last_idx) const { + return last_idx*strides_[Dim]; } template < typename... Ints > constexpr int index(Ints... idx) const { - return index_part(0, idx...); + return index_part<0>(idx...); } #ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING template < typename... Ints > void check_bounds(Ints... idx) const { - ASSERT( sizeof...(idx) == Rank ); - return check_bounds_part(0, idx...); + static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>(idx...); } #else template < typename... Ints > @@ -145,26 +150,23 @@ class IndexView { template < typename... Ints > void check_bounds_force(Ints... idx) const { - ASSERT( sizeof...(idx) == Rank ); - return check_bounds_part(0, idx...); + static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>(idx...); } - template < typename... Ints > - void check_bounds_part(int dim, int idx, Ints... next_idx) const { - if( dim < Rank ) { - if( size_t(idx) >= shape_[dim] ) { - std::ostringstream msg; msg << "ArrayView index " << array_dim(dim) << " out of bounds: " << idx << " >= " << shape_[dim]; - throw eckit::OutOfRange(msg.str(),Here()); - } - check_bounds_part( dim+1, next_idx..., idx ); + template < int Dim, typename Int, typename... Ints > + void check_bounds_part(Int idx, Ints... next_idx) const { + if( size_t(idx) >= shape_[Dim] ) { + throw_OutOfRange( "IndexView", array_dim(), idx, shape_[Dim] ); } + check_bounds_part( next_idx... ); } - static constexpr char array_dim(size_t dim) { - return - dim == 0 ? 'i' :( - dim == 1 ? 'j' :( - '*')); + template < int Dim, typename Int > + void check_bounds_part(Int last_idx) const { + if( size_t(last_idx) >= shape_[Dim] ) { + throw_OutOfRange( "IndexView", array_dim(), last_idx, shape_[Dim] ); + } } size_t size() const { return shape_[0]; } From 1a8317e3a795cbfec0aaec4b20f72e3b42f07437 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 28 Sep 2017 13:50:30 +0100 Subject: [PATCH 016/355] ATLAS-103 Improvements to BuildHalo --- src/atlas/mesh/actions/BuildHalo.cc | 179 ++++++---- src/atlas/mesh/actions/BuildHalo.h | 17 +- .../meshgenerator/StructuredMeshGenerator.cc | 9 + src/sandbox/CMakeLists.txt | 1 + src/sandbox/benchmark_sorting/CMakeLists.txt | 15 + .../atlas-benchmark-sorting.cc | 325 ++++++++++++++++++ 6 files changed, 486 insertions(+), 60 deletions(-) create mode 100644 src/sandbox/benchmark_sorting/CMakeLists.txt create mode 100644 src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 4a1f02ac5..f0d639939 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -38,13 +38,14 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/mpi/Buffer.h" +//#define DEBUG_OUTPUT #ifdef DEBUG_OUTPUT #include "atlas/output/Gmsh.h" #include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildXYZField.h" #endif -#define ATLAS_103 +// #define ATLAS_103 // #define ATLAS_103_SORT #ifndef ATLAS_103 @@ -74,20 +75,18 @@ void increase_halo_interior( BuildHaloHelper& ); class EastWest: public PeriodicTransform { public: - EastWest() - { - x_translation_ = -360.; - } + EastWest() { + x_translation_ = -360.; + } }; class WestEast: public PeriodicTransform { public: - WestEast() - { - x_translation_ = 360.; - } + WestEast() { + x_translation_ = 360.; + } }; typedef std::vector< std::vector > Node2Elem; @@ -99,8 +98,10 @@ void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) const mesh::Nodes& nodes = mesh.nodes(); node2elem.resize(nodes.size()); - for( size_t jnode=0; jnode patched = array::make_view( mesh.cells().field("patch") ); @@ -127,6 +128,10 @@ void accumulate_partition_bdry_nodes_old( Mesh& mesh, std::vector& bdry_nod std::vector< idx_t > facet_nodes; std::vector< idx_t > connectivity_facet_to_elem; + + facet_nodes.reserve(mesh.nodes().size()*4); + connectivity_facet_to_elem.reserve(facet_nodes.capacity()*2); + size_t nb_facets(0); size_t nb_inner_facets(0); idx_t missing_value; @@ -382,7 +387,6 @@ class BuildHaloHelper } }; - static void all_to_all(Buffers& send, Buffers& recv) { @@ -401,8 +405,13 @@ class BuildHaloHelper comm.allToAll(send.elem_nodes_displs, recv.elem_nodes_displs); } + struct Status { + std::vector new_periodic_ghost_points; + } status; + public: + BuildHalo& builder_; Mesh& mesh; array::ArrayView xy; array::ArrayView lonlat; @@ -423,7 +432,8 @@ class BuildHaloHelper public: - BuildHaloHelper( Mesh& _mesh ): + BuildHaloHelper( BuildHalo& builder, Mesh& _mesh ): + builder_( builder ), mesh(_mesh), xy ( array::make_view ( mesh.nodes().xy() ) ), lonlat ( array::make_view ( mesh.nodes().lonlat() ) ), @@ -596,7 +606,7 @@ class BuildHaloHelper } - void add_nodes(Buffers& buf) + void add_nodes(Buffers& buf, bool periodic ) { Timer t(__FUNCTION__); @@ -604,11 +614,29 @@ class BuildHaloHelper int nb_nodes = nodes.size(); // Nodes might be duplicated from different Tasks. We need to identify unique entries - std::set node_uid; - for( int jnode=0; jnode node_uid(nb_nodes); + std::set new_node_uid; { - node_uid.insert( compute_uid(jnode) ); + Timer scoped("compute node_uid"); + for( int jnode=0; jnode bool + { + std::vector::iterator it = std::lower_bound( node_uid.begin(), node_uid.end(), uid ); + bool not_found = ( it == node_uid.end() || uid < *it ); + if( not_found ) { + bool inserted = new_node_uid.insert( uid ).second; + return not inserted; + } else { + return true; + } + }; + + + std::vector< std::vector > rfn_idx(parallel::mpi::comm().size()); for(size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) { @@ -621,8 +649,7 @@ class BuildHaloHelper for(size_t n = 0; n < buf.node_glb_idx[jpart].size(); ++n) { double crd[] = { buf.node_xy[jpart][n*2+XX], buf.node_xy[jpart][n*2+YY] }; - bool inserted = node_uid.insert( util::unique_lonlat(crd) ).second; - if( inserted ) { + if( not node_already_exists( util::unique_lonlat(crd) ) ) { rfn_idx[jpart].push_back(n); } } @@ -661,39 +688,57 @@ class BuildHaloHelper PointLonLat pll = mesh.projection().lonlat(pxy); lonlat (loc_idx,XX) = pll.lon(); lonlat (loc_idx,YY) = pll.lat(); - uid_t uid = compute_uid(loc_idx); + + if( periodic ) + status.new_periodic_ghost_points.push_back( loc_idx ); // make sure new node was not already there - Uid2Node::iterator found = uid2node.find(uid); - if( found != uid2node.end() ) { - int other = found->second; - std::stringstream msg; - msg << "New node with uid " << uid << ":\n" << glb_idx(loc_idx) - << "("<second; + std::stringstream msg; + msg << "New node with uid " << uid << ":\n" << glb_idx(loc_idx) + << "("< elem_uid; int nb_elems = mesh.cells().size(); - - for( int jelem=0; jelem elem_uid; + std::vector elem_uid(nb_elems); + std::set new_elem_uid; { - elem_uid.insert( compute_uid(elem_nodes->row(jelem)) ); + Timer scoped("compute elem_uid"); + for( int jelem=0; jelemrow(jelem)); + } + std::sort( elem_uid.begin(), elem_uid.end() ); } + auto element_already_exists = [&elem_uid,&new_elem_uid]( uid_t uid ) -> bool { + std::vector::iterator it = std::lower_bound( elem_uid.begin(), elem_uid.end(), uid ); + bool not_found = ( it == elem_uid.end() || uid < *it ); + if( not_found ) { + bool inserted = new_elem_uid.insert( uid ).second; + return not inserted; + } else { + return true; + } + }; std::vector< std::vector > received_new_elems(parallel::mpi::comm().size()); for(size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) @@ -706,9 +751,7 @@ class BuildHaloHelper { for(size_t e = 0; e < buf.elem_glb_idx[jpart].size(); ++e) { - bool inserted = elem_uid.insert( buf.elem_glb_idx[jpart][e] ).second; - if( inserted ) - { + if( element_already_exists( buf.elem_glb_idx[jpart][e]) == false ) { received_new_elems[jpart].push_back(e); } } @@ -762,9 +805,9 @@ class BuildHaloHelper } } - void add_buffers(Buffers& buf) + void add_buffers(Buffers& buf, bool periodic = false ) { - add_nodes(buf); + add_nodes(buf, periodic ); add_elements(buf); update(); } @@ -774,7 +817,7 @@ class BuildHaloHelper namespace { -void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, const bool& periodic = false ) { +void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, bool periodic = false ) { #ifndef ATLAS_103 /* deprecated */ Timer t("gather_bdry_nodes old way"); @@ -945,8 +988,11 @@ class PeriodicPoints { void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& periodic_points, const PeriodicTransform& transform, int newflags) { helper.update(); - build_lookup_node2elem(helper.mesh,helper.node_to_elem); - build_lookup_uid2node(helper.mesh,helper.uid2node); + //if (helper.node_to_elem.size() == 0 ) !!! NOT ALLOWED !!! (atlas_test_halo will fail) + build_lookup_node2elem(helper.mesh,helper.node_to_elem); + + //if( helper.uid2node.size() == 0 ) !!! NOT ALLOWED !!! (atlas_test_halo will fail) + build_lookup_uid2node(helper.mesh,helper.uid2node); // All buffers needed to move elements and nodes BuildHaloHelper::Buffers sendmesh(helper.mesh); @@ -1013,16 +1059,17 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri #ifdef DEBUG_OUTPUT Log::debug() << "recv: \n" << recvmesh << std::endl; #endif - helper.add_buffers(recvmesh); + helper.add_buffers(recvmesh, /* periodic = */ true ); } -void build_halo(Mesh& mesh, int nb_elems ) +void BuildHalo::operator () ( int nb_elems ) { Timer scope_timer(__FUNCTION__); int halo = 0; - mesh.metadata().get("halo",halo); + mesh_.metadata().get("halo",halo); + if( halo == nb_elems ) return; @@ -1032,31 +1079,45 @@ void build_halo(Mesh& mesh, int nb_elems ) for(int jhalo=halo ; jhalo() << "Increase halo " << jhalo+1 << std::endl; - size_t nb_nodes_before_halo_increase = mesh.nodes().size(); + size_t nb_nodes_before_halo_increase = mesh_.nodes().size(); - BuildHaloHelper helper(mesh); + BuildHaloHelper helper(*this,mesh_); - increase_halo_interior( helper ); + { + Timer scope_timer( "increase_halo_interior" ); + increase_halo_interior( helper ); + } - PeriodicPoints westpts(mesh,Topology::PERIODIC|Topology::WEST,nb_nodes_before_halo_increase); + PeriodicPoints westpts(mesh_,Topology::PERIODIC|Topology::WEST,nb_nodes_before_halo_increase); #ifdef DEBUG_OUTPUT Log::debug() << " periodic west : " << westpts << std::endl; #endif - increase_halo_periodic( helper, westpts, WestEast(), Topology::PERIODIC|Topology::WEST|Topology::GHOST ); + { + Timer scope_timer( "increase_halo_periodic West" ); + increase_halo_periodic( helper, westpts, WestEast(), Topology::PERIODIC|Topology::WEST|Topology::GHOST ); + } - PeriodicPoints eastpts(mesh,Topology::PERIODIC|Topology::EAST,nb_nodes_before_halo_increase); + PeriodicPoints eastpts(mesh_,Topology::PERIODIC|Topology::EAST,nb_nodes_before_halo_increase); #ifdef DEBUG_OUTPUT Log::debug() << " periodic east : " << eastpts << std::endl; #endif + { + Timer scope_timer( "increase_halo_periodic East" ); + increase_halo_periodic( helper, eastpts, EastWest(), Topology::PERIODIC|Topology::EAST|Topology::GHOST ); + } - increase_halo_periodic( helper, eastpts, EastWest(), Topology::PERIODIC|Topology::EAST|Topology::GHOST ); + mesh_.nodes().global_index().metadata().set("complete",false); + + for( gidx_t p : helper.status.new_periodic_ghost_points ) { + periodic_local_index_.push_back( p ); + } std::stringstream ss; ss << "nb_nodes_including_halo["< periodic_local_index_; + +private: + Mesh& mesh_; +}; + + /// @brief Enlarge each partition of the mesh with a halo of elements /// @param [inout] mesh The mesh to enlarge /// @param [in] nb_elems Size of the halo /// @author Willem Deconinck /// @date June 2014 -void build_halo( Mesh& mesh, int nb_elems ); +inline void build_halo( Mesh& mesh, int nb_elems ) { + BuildHalo f(mesh); + f( nb_elems ); +} // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index c99ac396c..5001aade7 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -914,6 +914,7 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons } } } + int max_glb_idx = n; mesh.nodes().resize(nnodes); @@ -1116,6 +1117,14 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons ++jnode; } + nodes.global_index().metadata().set("complete",true); + nodes.global_index().metadata().set("min",1); + nodes.global_index().metadata().set("max",max_glb_idx); + + + // Now handle elements + // ------------------- + mesh.cells().add( new mesh::temporary::Quadrilateral(), nquads ); mesh.cells().add( new mesh::temporary::Triangle(), ntriags ); diff --git a/src/sandbox/CMakeLists.txt b/src/sandbox/CMakeLists.txt index efac7b331..b8502a142 100644 --- a/src/sandbox/CMakeLists.txt +++ b/src/sandbox/CMakeLists.txt @@ -15,3 +15,4 @@ add_subdirectory( interpolation ) add_subdirectory( interpolation-fortran ) add_subdirectory( grid_distribution ) add_subdirectory( benchmark_build_halo ) +add_subdirectory( benchmark_sorting ) diff --git a/src/sandbox/benchmark_sorting/CMakeLists.txt b/src/sandbox/benchmark_sorting/CMakeLists.txt new file mode 100644 index 000000000..8754839c3 --- /dev/null +++ b/src/sandbox/benchmark_sorting/CMakeLists.txt @@ -0,0 +1,15 @@ +# (C) Copyright 1996-2017 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. + +ecbuild_add_executable( + TARGET atlas-benchmark-sorting + SOURCES atlas-benchmark-sorting.cc + LIBS atlas +# NOINSTALL +) + diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc new file mode 100644 index 000000000..c9e0c87a6 --- /dev/null +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -0,0 +1,325 @@ +/* + * (C) Copyright 1996-2017 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 +#include +#include +#include + +#include "eckit/exception/Exceptions.h" +#include "eckit/filesystem/PathName.h" + +#include "atlas/grid.h" +#include "atlas/meshgenerator.h" +#include "atlas/mesh.h" +#include "atlas/runtime/AtlasTool.h" +#include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/util/Config.h" +#include "atlas/output/detail/GmshIO.h" +#include "atlas/mesh/actions/BuildHalo.h" +#include "atlas/mesh/actions/BuildParallelFields.h" +#include "atlas/mesh/actions/BuildPeriodicBoundaries.h" + + +#include "atlas/field/Field.h" +#include "atlas/util/CoordinateEnums.h" +#include "atlas/util/Unique.h" +#include "atlas/array.h" + +using Topology = atlas::mesh::Nodes::Topology; +using atlas::util::UniqueLonLat; + +//------------------------------------------------------------------------------ + +using namespace atlas; +using namespace atlas::grid; +using atlas::util::Config; +using eckit::PathName; + +//------------------------------------------------------------------------------ +namespace atlas { + +struct TimerStats +{ + TimerStats(const std::string& _name = "timer") + { + max = -1; + min = -1; + avg = 0; + cnt = 0; + name = _name; + } + void update(Timer& timer) + { + double t = timer.elapsed(); + 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); + ++cnt; + } + std::string str() + { + std::stringstream stream; + stream << name << ": min, max, avg -- " << std::fixed << std::setprecision(5) << min << ", " << std::fixed << std::setprecision(5) << max << ", " << std::fixed << std::setprecision(5) << avg; + return stream.str(); + } + std::string name; + double max; + double min; + double avg; + int cnt; +}; + +struct Node +{ + Node(gidx_t gid, int idx) + { + g = gid; + i = idx; + } + gidx_t g; + gidx_t i; + bool operator < (const Node& other) const + { + return ( g Those specific periodic points at the EAST boundary are not checked for uid, +// and could receive different gidx for different tasks + + UniqueLonLat compute_uid(nodes); + + // unused // int mypart = parallel::mpi::comm().rank(); + int nparts = parallel::mpi::comm().size(); + size_t root = 0; + + array::ArrayView nodes_glb_idx = array::make_view ( nodes.global_index() ); + //nodes_glb_idx.dump( Log::info() ); + Log::info() << std::endl; + Log::info() << "min = " << nodes.global_index().metadata().getLong("min") << std::endl; + Log::info() << "max = " << nodes.global_index().metadata().getLong("max") << std::endl; + Log::info() << "complete = " << nodes.global_index().metadata().getBool("complete") << std::endl; + gidx_t glb_idx_max = 0; + + std::vector points_to_edit; + + if( do_all ) { + points_to_edit.resize(nodes_glb_idx.size()); + for( size_t i=0; i glb_idx(points_to_edit.size()); + for( size_t i=0; i recvcounts(parallel::mpi::comm().size()); + std::vector recvdispls(parallel::mpi::comm().size()); + + parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + + recvdispls[0]=0; + for (int jpart=1; jpart glb_idx_gathered( glb_nb_nodes ); + parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); + + + // 2) Sort all global indices, and renumber from 1 to glb_nb_edges + std::vector node_sort; node_sort.reserve(glb_nb_nodes); + for( size_t jnode=0; jnode("grid","Grid unique identifier\n" + +indent()+" Example values: N80, F40, O24, L32") ); + add_option( new SimpleOption("halo","size of halo" ) ); + add_option( new SimpleOption("do-all","Renumber all points" ) ); +} + +//----------------------------------------------------------------------------- + +void Tool::execute(const Args& args) +{ + key = ""; + args.get("grid",key); + + std::string path_in_str = ""; + if( args.get("grid",path_in_str) ) path_in = path_in_str; + + StructuredGrid grid; + if( key.size() ) + { + try{ grid = Grid(key); } + catch( eckit::BadParameter& e ){} + } + else + { + Log::error() << "No grid specified." << std::endl; + } + + if( !grid ) return; + + Log::debug() << "Domain: " << grid.domain() << std::endl; + Log::debug() << "Periodic: " << grid.periodic() << std::endl; + + MeshGenerator meshgenerator("structured"); + + size_t halo = args.getLong("halo",0); + bool do_all = args.getBool("do-all",false); + + ATLAS_DEBUG_VAR( do_all ); + + size_t iterations = 1; + TimerStats timer_stats; + parallel::mpi::comm().barrier(); + Mesh mesh = meshgenerator.generate(grid); + + + atlas::mesh::actions::build_periodic_boundaries(mesh); + + Log::info() << "building halo" << std::endl; + atlas::mesh::actions::BuildHalo build_halo(mesh); + build_halo(halo); + + Timer::Barrier set_barrier(true); + Timer::Log set_channel( Log::info() ); + for( size_t i=0; i Date: Wed, 4 Oct 2017 18:04:32 +0100 Subject: [PATCH 017/355] ATLAS-103 Change partitioner to EqualRegions --- src/atlas/grid/Partitioner.cc | 8 +++++++- src/atlas/grid/Partitioner.h | 2 +- .../grid/detail/partitioner/EqualRegionsPartitioner.cc | 5 +++++ src/atlas/grid/detail/partitioner/TransPartitioner.cc | 3 +++ src/atlas/meshgenerator/StructuredMeshGenerator.cc | 7 ++++++- src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc | 5 ++++- 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/atlas/grid/Partitioner.cc b/src/atlas/grid/Partitioner.cc index 99e257af2..4247953ec 100644 --- a/src/atlas/grid/Partitioner.cc +++ b/src/atlas/grid/Partitioner.cc @@ -11,6 +11,7 @@ #include "atlas/grid/Partitioner.h" #include "atlas/grid/detail/partitioner/Partitioner.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Timer.h" namespace atlas { namespace grid { @@ -48,8 +49,13 @@ Partitioner::Partitioner( const Config& config ): partitioner_( partitioner_from_config(config) ) { } +void Partitioner::partition(const Grid &grid, int part[]) const { + Timer t(__FUNCTION__); + partitioner_->partition(grid,part); +} + MatchingMeshPartitioner::MatchingMeshPartitioner() : - Partitioner() { + Partitioner() { } grid::detail::partitioner::Partitioner* matching_mesh_partititioner( const Mesh& mesh, const Partitioner::Config& config ) { diff --git a/src/atlas/grid/Partitioner.h b/src/atlas/grid/Partitioner.h index 4a1a52930..239d7203c 100644 --- a/src/atlas/grid/Partitioner.h +++ b/src/atlas/grid/Partitioner.h @@ -43,7 +43,7 @@ class Partitioner { operator bool() const { return partitioner_; } - void partition( const Grid& grid, int part[] ) const { partitioner_->partition(grid,part); } + void partition( const Grid& grid, int part[] ) const; Distribution partition( const Grid& grid ) const { return Distribution(grid,*this); } diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index eaa2e6926..f38219b18 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -17,6 +17,7 @@ #include "atlas/grid/Grid.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" #include "atlas/util/MicroDeg.h" +#include "atlas/runtime/Timer.h" using atlas::util::microdeg; @@ -428,6 +429,10 @@ bool compare_WE_NS(const EqualRegionsPartitioner::NodeInt& node1, const EqualReg } void EqualRegionsPartitioner::partition( int nb_nodes, NodeInt nodes[], int part[] ) const { + + Timer t("EqualRegionsPartitioner::partition"); + + // std::clock_t init, final; // init=std::clock(); // std::cout << "partition start (" << nb_nodes << " points)" << std::endl; diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index 9f3237762..fdf4219f1 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -15,6 +15,7 @@ #include "atlas/trans/Trans.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/array.h" +#include "atlas/runtime/Timer.h" namespace atlas { namespace grid { @@ -46,6 +47,8 @@ TransPartitioner::~TransPartitioner() { void TransPartitioner::partition(const Grid& grid, int part[]) const { + Timer timer("TransPartitioner::partition"); + StructuredGrid g(grid); if( not g ) throw eckit::BadCast("Grid is not a grid::Structured type. Cannot partition using IFS trans",Here()); diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 5001aade7..3d3bd31e8 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -31,6 +31,7 @@ #include "atlas/field/Field.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" @@ -189,6 +190,8 @@ void StructuredMeshGenerator::hash(Hash& h) const void StructuredMeshGenerator::generate(const Grid& grid, const grid::Distribution& distribution, Mesh& mesh ) const { + Timer t(__FUNCTION__); + const grid::StructuredGrid rg = grid::StructuredGrid(grid); if( !rg ) throw eckit::BadCast("Grid could not be cast to a Structured",Here()); @@ -232,6 +235,8 @@ void StructuredMeshGenerator::generate(const Grid& grid, const grid::Distributio void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, const std::vector& parts, int mypart, Region& region) const { + Timer t(__FUNCTION__); + double max_angle = options.get("angle"); bool triangulate_quads = options.get("triangulate"); bool three_dimensional = options.get("3d"); @@ -799,7 +804,7 @@ struct GhostNode { void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, const std::vector& parts, const Region& region, Mesh& mesh) const { - + Timer t(__FUNCTION__); ASSERT(!mesh.generated()); diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index c9e0c87a6..6d63e6c59 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -146,6 +146,7 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha ATLAS_DEBUG_VAR( points_to_edit ); + ATLAS_DEBUG_VAR( points_to_edit.size() ); Timer total_timer("distrubuted_sort"); @@ -258,6 +259,8 @@ Tool::Tool(int argc,char **argv): AtlasTool(argc,argv) void Tool::execute(const Args& args) { + Timer t("main"); + key = ""; args.get("grid",key); @@ -280,7 +283,7 @@ void Tool::execute(const Args& args) Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; - MeshGenerator meshgenerator("structured"); + MeshGenerator meshgenerator("structured", Config("partitioner","equal_regions") ); size_t halo = args.getLong("halo",0); bool do_all = args.getBool("do-all",false); From 841ffe66aafb02a0f8080e1e47d017e0752de3f5 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 5 Oct 2017 12:20:54 +0100 Subject: [PATCH 018/355] ATLAS-132 First attempt at creating a timer macro --- src/apps/atlas-benchmark.cc | 25 +- src/apps/atlas-numerics-nabla.F90 | 46 +-- src/atlas/functionspace/EdgeColumns.cc | 28 +- src/atlas/functionspace/NodeColumns.cc | 17 +- src/atlas/functionspace/StructuredColumns.cc | 60 +--- src/atlas/grid/Partitioner.cc | 2 +- .../partitioner/EqualRegionsPartitioner.cc | 2 +- .../detail/partitioner/TransPartitioner.cc | 2 +- .../interpolation/method/FiniteElement.cc | 3 +- .../method/KNearestNeighbours.cc | 4 +- .../method/KNearestNeighboursBase.cc | 6 +- src/atlas/interpolation/method/Method.cc | 5 +- .../interpolation/method/NearestNeighbour.cc | 4 +- src/atlas/interpolation/method/PointSet.h | 4 +- src/atlas/library/Library.cc | 10 +- src/atlas/library/config.h | 2 + src/atlas/mesh/actions/BuildConvexHull3D.cc | 10 +- src/atlas/mesh/actions/BuildDualMesh.cc | 16 +- src/atlas/mesh/actions/BuildHalo.cc | 42 +-- src/atlas/mesh/actions/BuildParallelFields.cc | 20 +- .../meshgenerator/StructuredMeshGenerator.cc | 6 +- src/atlas/parallel/GatherScatter.cc | 7 +- src/atlas/parallel/omp/omp.cc | 2 +- src/atlas/runtime/Timer.h | 335 +++++++++++++++++- .../atlas-benchmark-build-halo.cc | 16 +- .../atlas-benchmark-sorting.cc | 82 ++--- src/sandbox/interpolation/PartitionedMesh.cc | 6 +- src/tests/numerics/fctest_fvm_nabla.F90 | 46 +-- 28 files changed, 513 insertions(+), 295 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index d2eb51a02..1485c7c03 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -59,9 +59,6 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/omp/omp.h" -#define ATLAS_TIME(msg) \ - for( atlas::Timer itimer##__LINE__(msg); itimer##__LINE__.running(); itimer##__LINE__.stop() ) - //---------------------------------------------------------------------------------------------------------------------- using std::unique_ptr; @@ -230,7 +227,7 @@ void AtlasBenchmark::execute(const Args& args) Log::info() << "Timings:" << endl; - ATLAS_TIME("setup") { setup(); } + ATLAS_TIME_SCOPE("setup") { setup(); } Log::info() << " Executing " << niter << " iterations: \n"; if( progress ) @@ -288,15 +285,15 @@ void AtlasBenchmark::setup() size_t halo = 1; StructuredGrid grid; - ATLAS_TIME( "Create grid" ) { grid = Grid(gridname); } - ATLAS_TIME( "Create mesh" ) { mesh = MeshGenerator( "structured" ).generate(grid); } + ATLAS_TIME_SCOPE( "Create grid" ) { grid = Grid(gridname); } + ATLAS_TIME_SCOPE( "Create mesh" ) { mesh = MeshGenerator( "structured" ).generate(grid); } - ATLAS_TIME( "Create node_fs") { nodes_fs = functionspace::NodeColumns(mesh,option::halo(halo)); } - ATLAS_TIME( "build_edges" ) { build_edges(mesh); } - ATLAS_TIME( "build_pole_edges" ) { build_pole_edges(mesh); } - ATLAS_TIME( "build_edges_parallel_fiels" ) { build_edges_parallel_fields(mesh); } - ATLAS_TIME( "build_median_dual_mesh" ) { build_median_dual_mesh(mesh); } - ATLAS_TIME( "build_node_to_edge_connectivity" ) { build_node_to_edge_connectivity(mesh); } + ATLAS_TIME_SCOPE( "Create node_fs") { nodes_fs = functionspace::NodeColumns(mesh,option::halo(halo)); } + ATLAS_TIME_SCOPE( "build_edges" ) { build_edges(mesh); } + ATLAS_TIME_SCOPE( "build_pole_edges" ) { build_pole_edges(mesh); } + ATLAS_TIME_SCOPE( "build_edges_parallel_fiels" ) { build_edges_parallel_fields(mesh); } + ATLAS_TIME_SCOPE( "build_median_dual_mesh" ) { build_median_dual_mesh(mesh); } + ATLAS_TIME_SCOPE( "build_node_to_edge_connectivity" ) { build_node_to_edge_connectivity(mesh); } scalar_field = nodes_fs.createField( option::name("field") | option::levels(nlev) ); grad_field = nodes_fs.createField( option::name("grad") | option::levels(nlev) | option::variables(3) ); @@ -374,7 +371,7 @@ void AtlasBenchmark::setup() void AtlasBenchmark::iteration() { - Timer t("iteration"); + Timer t( Here() ); unique_ptr avgS_arr( array::Array::create(nedges,nlev,2ul) ); const auto& node2edge = mesh.nodes().edge_connectivity(); @@ -456,7 +453,7 @@ void AtlasBenchmark::iteration() } // halo-exchange - Timer halo("halo-exchange"); + Timer halo( Here(), "halo-exchange"); nodes_fs.halo_exchange().execute(grad); halo.stop(); diff --git a/src/apps/atlas-numerics-nabla.F90 b/src/apps/atlas-numerics-nabla.F90 index fce75dd74..7d75fd620 100644 --- a/src/apps/atlas-numerics-nabla.F90 +++ b/src/apps/atlas-numerics-nabla.F90 @@ -44,23 +44,23 @@ module atlas_nabla_program_module real(JPRB), parameter :: RPI = 2.0_JPRB*asin(1.0_JPRB) real(JPRB) :: RA - type :: Timer_type + type :: timer_type private integer*8 :: clck_counts_start, clck_counts_stop, clck_rate integer*8 :: counted = 0 logical :: paused = .True. contains - procedure, public :: start => Timer_start - procedure, public :: pause => Timer_pause - procedure, public :: resume => Timer_resume - procedure, public :: elapsed => Timer_elapsed - end type Timer_type + procedure, public :: start => timer_start + procedure, public :: pause => timer_pause + procedure, public :: resume => timer_resume + procedure, public :: elapsed => timer_elapsed + end type timer_type contains - function Timer_elapsed(self) result(time) + function timer_elapsed(self) result(time) use, intrinsic :: iso_c_binding, only : c_double - class(Timer_type), intent(inout) :: self + class(timer_type), intent(inout) :: self real(c_double) :: time if (.not. self%paused) then call system_clock ( self%clck_counts_stop, self%clck_rate ) @@ -70,27 +70,27 @@ function Timer_elapsed(self) result(time) else time = 0. end if - end function Timer_elapsed + end function timer_elapsed - subroutine Timer_start(self) - class(Timer_type), intent(inout) :: self + subroutine timer_start(self) + class(timer_type), intent(inout) :: self call system_clock ( self%clck_counts_start, self%clck_rate ) self%paused = .False. self%counted = 0 - end subroutine Timer_start + end subroutine timer_start - subroutine Timer_pause(self) - class(Timer_type), intent(inout) :: self + subroutine timer_pause(self) + class(timer_type), intent(inout) :: self call system_clock ( self%clck_counts_stop, self%clck_rate ) self%counted = self%counted + self%clck_counts_stop - self%clck_counts_start self%paused = .True. - end subroutine Timer_pause + end subroutine timer_pause - subroutine Timer_resume(self) - class(Timer_type), intent(inout) :: self + subroutine timer_resume(self) + class(timer_type), intent(inout) :: self call system_clock ( self%clck_counts_start, self%clck_rate ) self%paused = .False. - end subroutine Timer_resume + end subroutine timer_resume SUBROUTINE FV_GRADIENT(PVAR,PGRAD) @@ -289,7 +289,7 @@ subroutine finalize() subroutine run() use fckit_mpi_module -type(Timer_type) :: timer +type(timer_type) :: ATLAS_TIME(); type(fckit_mpi_comm) :: mpi integer :: jiter, jouter real(c_double) :: timing_cpp, timing_f90, timing @@ -306,9 +306,9 @@ subroutine run() ! Compute the gradient timing = 1.e10 do jiter = 1,niter - call timer%start() + call ATLAS_TIME();%start() call nabla%gradient(varfield,gradfield) - timing = min(timing,timer%elapsed()) + timing = min(timing,ATLAS_TIME();%elapsed()) enddo timing_cpp = timing write(msg,*) "timing_cpp = ", timing_cpp @@ -320,9 +320,9 @@ subroutine run() ! Compute the gradient with Fortran routine above timing = 1.e10 do jiter = 1,niter - call timer%start() + call ATLAS_TIME();%start() call FV_GRADIENT(var,grad) - timing = min(timing,timer%elapsed()) + timing = min(timing,ATLAS_TIME();%elapsed()) enddo timing_f90 = timing write(msg,*) "timing_f90 = ", timing_f90 diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 12c897c6e..24119fde8 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -135,8 +135,8 @@ EdgeColumns::EdgeColumns( const Mesh& mesh, const eckit::Configuration ¶ms ) params.get("halo",halo); ASSERT( mesh_halo == halo ); - - + + constructor(); } @@ -150,9 +150,9 @@ EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo &halo, const eckit: size_t mesh_halo_size_; mesh.metadata().get("halo",mesh_halo_size_); ASSERT( mesh_halo_size_ == halo.size() ); - + nb_levels_ = config_levels(params); - + constructor(); } @@ -172,7 +172,7 @@ EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo &halo) : void EdgeColumns::constructor() { - Timer scope_timer("EdgeColumns()"); + ATLAS_TIME("EdgeColumns()"); nb_edges_ = mesh().edges().size(); @@ -184,16 +184,16 @@ void EdgeColumns::constructor() const Field& remote_index = edges().remote_index(); const Field& global_index = edges().global_index(); + ATLAS_TIME_SCOPE("Setup halo_exchange") { - Timer t( "Setup halo_exchange" ); halo_exchange_->setup( array::make_view(partition).data(), array::make_view(remote_index).data(),REMOTE_IDX_BASE, nb_edges_); } + ATLAS_TIME_SCOPE("Setup gather_scatter") { - Timer t( "Setup gather_scatter" ); gather_scatter_->setup( array::make_view(partition).data(), array::make_view(remote_index).data(),REMOTE_IDX_BASE, @@ -201,8 +201,8 @@ void EdgeColumns::constructor() nb_edges_); } + ATLAS_TIME_SCOPE("Setup checksum") { - Timer t( "Setup checksum" ); checksum_->setup( array::make_view(partition).data(), array::make_view(remote_index).data(),REMOTE_IDX_BASE, @@ -240,10 +240,10 @@ Field EdgeColumns::createField(const eckit::Configuration& options) const } Field EdgeColumns::createField( - const Field& other, + const Field& other, const eckit::Configuration& config ) const { - return createField( + return createField( option::datatype ( other.datatype() ) | option::levels ( other.levels() ) | option::variables( other.variables() ) | @@ -767,7 +767,7 @@ EdgeColumns::EdgeColumns( const FunctionSpace& functionspace ) : functionspace_( dynamic_cast< const detail::EdgeColumns* >( get() ) ) { } -EdgeColumns::EdgeColumns( +EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo& halo, const eckit::Configuration& config ) : @@ -775,19 +775,19 @@ EdgeColumns::EdgeColumns( functionspace_( dynamic_cast< const detail::EdgeColumns* >( get() ) ) { } -EdgeColumns::EdgeColumns( +EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo& halo) : FunctionSpace( new detail::EdgeColumns(mesh,halo) ), functionspace_( dynamic_cast< const detail::EdgeColumns* >( get() ) ) { } -EdgeColumns::EdgeColumns( +EdgeColumns::EdgeColumns( const Mesh& mesh) : FunctionSpace( new detail::EdgeColumns(mesh) ), functionspace_( dynamic_cast< const detail::EdgeColumns* >( get() ) ) { } - + size_t EdgeColumns::nb_edges() const { return functionspace_->nb_edges(); } diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index d0d1bad61..09210e407 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -101,7 +101,7 @@ NodeColumns::NodeColumns( Mesh& mesh, const eckit::Configuration & config ) : nb_levels_( config.getInt("levels",0) ), nb_nodes_(nodes_.size()), nb_nodes_global_(0) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); constructor(); } @@ -132,8 +132,8 @@ void NodeColumns::constructor() } } + ATLAS_TIME_SCOPE("HaloExchange") { - Timer t( "HaloExchange" ); Field& part = mesh_.nodes().partition(); Field& ridx = mesh_.nodes().remote_index(); halo_exchange_->setup( array::make_view(part).data(), @@ -141,9 +141,8 @@ void NodeColumns::constructor() REMOTE_IDX_BASE,nb_nodes_); } + ATLAS_TIME_SCOPE("GatherScatter") { - Timer t( "GatherScatter"); - // Create new gather_scatter gather_scatter_.reset( new parallel::GatherScatter() ); @@ -169,8 +168,8 @@ void NodeColumns::constructor() mask.data(),nb_nodes_); } + ATLAS_TIME_SCOPE("Checksum") { - Timer t( "Checksum" ); // Create new checksum checksum_.reset( new parallel::Checksum() ); @@ -260,7 +259,7 @@ void NodeColumns::set_field_metadata(const eckit::Configuration& config, Field& } } field.metadata().set("global",global); - + size_t levels(nb_levels_); config.get("levels",levels); field.set_levels(levels); @@ -319,10 +318,10 @@ Field NodeColumns::createField( } Field NodeColumns::createField( - const Field& other, + const Field& other, const eckit::Configuration& config ) const { - return createField( + return createField( option::datatype ( other.datatype() ) | option::levels ( other.levels() ) | option::variables( other.variables() ) | @@ -1824,7 +1823,7 @@ void mean_and_standard_deviation( const NodeColumns& fs, const Field& field, T& option::name("sqr_diff") | option::datatype(field.datatype()) | option::levels( field.levels() ) ); - + array::LocalView squared_diff = make_leveled_scalar_view( squared_diff_field ); array::LocalView values = make_leveled_scalar_view( field ); diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 8741a3b32..ca208f97e 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -22,6 +22,7 @@ #include "atlas/util/CoordinateEnums.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Debug.h" +#include "atlas/runtime/Timer.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/Checksum.h" @@ -192,39 +193,6 @@ size_t StructuredColumns::config_size(const eckit::Configuration& config) const return size; } - -class DebugTimer -{ -public: - DebugTimer(const std::string& msg): timer(msg+" done",Log::debug()), once_(true) { - Log::debug() << msg << std::endl; - } - bool once() const { return once_; } - void done() { once_=false; } - eckit::Timer timer; -private: - bool once_; -}; - - -class Timer -{ -public: - Timer(const std::string& msg): timer(msg+" done",Log::info()), once_(true) { - Log::info() << msg << std::endl; - } - bool once() const { return once_; } - void done() { once_=false; } - eckit::Timer timer; -private: - bool once_; -}; - -#define ATLAS_DEBUG_SCOPE_TIMER(msg) \ - for( DebugTimer dtimer##__LINE__(Here().asString() + " " + msg); dtimer##__LINE__.once(); dtimer##__LINE__.done() ) -#define ATLAS_SCOPE_TIMER(msg) \ - for( Timer itimer##__LINE__(msg); itimer##__LINE__.once(); itimer##__LINE__.done() ) - // ---------------------------------------------------------------------------- // Constructor // ---------------------------------------------------------------------------- @@ -236,8 +204,8 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& grid_(grid), nb_levels_(0) { + ATLAS_TIME( "Generating StructuredColumns..." ); nb_levels_ = config_levels(config); - Timer timer( "Generating StructuredColumns..." ); if ( not grid_ ) { throw eckit::BadCast("Grid is not a grid::Structured type", Here()); @@ -258,7 +226,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& } grid::Distribution distribution; - ATLAS_DEBUG_SCOPE_TIMER( "Partitioning grid ..." ) { + ATLAS_TIME_SCOPE( "Partitioning grid ..." ) { distribution = grid::Distribution(grid,partitioner); } @@ -383,12 +351,12 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& }; if( atlas::Library::instance().debug() ) { - ATLAS_DEBUG_SCOPE_TIMER("Load imbalance") { + ATLAS_TIME_SCOPE("Load imbalance") { comm.barrier(); } } - ATLAS_DEBUG_SCOPE_TIMER( "Compute mapping ..." ) + ATLAS_TIME_SCOPE( "Compute mapping ..." ) { idx_t imin = std::numeric_limits::max(); idx_t imax = -std::numeric_limits::max(); @@ -465,13 +433,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& } } - if( atlas::Library::instance().debug() ) { - ATLAS_DEBUG_SCOPE_TIMER("Load imbalance") { - comm.barrier(); - } - } - - ATLAS_DEBUG_SCOPE_TIMER("Parallelisation ...") + ATLAS_TIME_SCOPE("Parallelisation ...") { auto build_partition_graph = [this]() -> std::unique_ptr { @@ -500,12 +462,12 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& }; std::unique_ptr graph_ptr; - ATLAS_DEBUG_SCOPE_TIMER( "Building partition graph..." ) { + ATLAS_TIME_SCOPE( "Building partition graph..." ) { graph_ptr = build_partition_graph(); } const Mesh::PartitionGraph& graph = *graph_ptr; - ATLAS_DEBUG_SCOPE_TIMER( "Setup parallel fields..." ) + ATLAS_TIME_SCOPE( "Setup parallel fields..." ) { auto p = array::make_view< int, 1 >( partition() ); auto g = array::make_view< gidx_t, 1 >( global_index() ); @@ -599,19 +561,19 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& } } - ATLAS_DEBUG_SCOPE_TIMER( "Setup gather_scatter..." ) + ATLAS_TIME_SCOPE( "Setup gather_scatter..." ) { gather_scatter_ = new parallel::GatherScatter(); gather_scatter_->setup(part.data(), remote_idx.data(), 0, global_idx.data(), size_owned_ ); } - ATLAS_DEBUG_SCOPE_TIMER( "Setup checksum..." ) + ATLAS_TIME_SCOPE( "Setup checksum..." ) { checksum_ = new parallel::Checksum(); checksum_->setup(part.data(), remote_idx.data(), 0, global_idx.data(), size_owned_ ); } - ATLAS_DEBUG_SCOPE_TIMER( "Setup halo exchange..." ) + ATLAS_TIME_SCOPE( "Setup halo exchange..." ) { halo_exchange_ = new parallel::HaloExchange(); halo_exchange_->setup(part.data(),remote_idx.data(),0,size_halo_); diff --git a/src/atlas/grid/Partitioner.cc b/src/atlas/grid/Partitioner.cc index 4247953ec..a422105d8 100644 --- a/src/atlas/grid/Partitioner.cc +++ b/src/atlas/grid/Partitioner.cc @@ -50,7 +50,7 @@ Partitioner::Partitioner( const Config& config ): } void Partitioner::partition(const Grid &grid, int part[]) const { - Timer t(__FUNCTION__); + ATLAS_TIME(); partitioner_->partition(grid,part); } diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index f38219b18..50dc4bae3 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -430,7 +430,7 @@ bool compare_WE_NS(const EqualRegionsPartitioner::NodeInt& node1, const EqualReg void EqualRegionsPartitioner::partition( int nb_nodes, NodeInt nodes[], int part[] ) const { - Timer t("EqualRegionsPartitioner::partition"); + ATLAS_TIME( "EqualRegionsPartitioner::partition" ); // std::clock_t init, final; diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index fdf4219f1..65e5797ac 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -47,7 +47,7 @@ TransPartitioner::~TransPartitioner() { void TransPartitioner::partition(const Grid& grid, int part[]) const { - Timer timer("TransPartitioner::partition"); + ATLAS_TIME( "TransPartitioner::partition" ); StructuredGrid g(grid); if( not g ) diff --git a/src/atlas/interpolation/method/FiniteElement.cc b/src/atlas/interpolation/method/FiniteElement.cc index 9ac30f9ff..c9e348d40 100644 --- a/src/atlas/interpolation/method/FiniteElement.cc +++ b/src/atlas/interpolation/method/FiniteElement.cc @@ -27,6 +27,7 @@ #include "atlas/mesh/ElementType.h" #include "atlas/mesh/Nodes.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" #include "atlas/util/Point.h" @@ -55,7 +56,7 @@ static const double parametricEpsilon = 1e-15; } // (anonymous namespace) void FiniteElement::setup(const FunctionSpace& source, const FunctionSpace& target) { - eckit::TraceTimer tim("atlas::interpolation::method::FiniteElement::setup()"); + ATLAS_TIME( "atlas::interpolation::method::FiniteElement::setup()" ); if( functionspace::NodeColumns tgt = target ) { diff --git a/src/atlas/interpolation/method/KNearestNeighbours.cc b/src/atlas/interpolation/method/KNearestNeighbours.cc index 68f406b70..f4c478268 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.cc +++ b/src/atlas/interpolation/method/KNearestNeighbours.cc @@ -16,6 +16,7 @@ #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" #include "atlas/functionspace/NodeColumns.h" @@ -65,9 +66,10 @@ void KNearestNeighbours::setup(const FunctionSpace& source, const FunctionSpace& std::vector< Triplet > weights_triplets; weights_triplets.reserve(out_npts * k_); { + Timer timer(Here(),"atlas::interpolation::method::NearestNeighbour::setup()"); + std::vector weights; - eckit::TraceTimer timer("atlas::interpolation::method::NearestNeighbour::setup()"); for (size_t ip = 0; ip < out_npts; ++ip) { if (ip && (ip % 1000 == 0)) { diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.cc b/src/atlas/interpolation/method/KNearestNeighboursBase.cc index f5503624b..e46aa84e9 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.cc +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.cc @@ -11,13 +11,13 @@ #include "atlas/interpolation/method/KNearestNeighboursBase.h" -#include "eckit/log/Timer.h" +#include "eckit/config/Resource.h" +#include "eckit/eckit_version.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/mesh/Nodes.h" #include "atlas/library/Library.h" -#include "eckit/config/Resource.h" +#include "atlas/runtime/Timer.h" -#include "eckit/eckit_version.h" #ifdef ECKIT_VERSION_INT #undef ECKIT_VERSION_INT diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index a0dbe8f38..43cc74a30 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -22,6 +22,7 @@ #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" namespace atlas { namespace interpolation { @@ -83,7 +84,7 @@ Method* MethodFactory::build(const std::string& name, const Method::Config& conf void Method::execute(const FieldSet& fieldsSource, FieldSet& fieldsTarget) const { - eckit::TraceTimer tim("atlas::interpolation::method::Method::execute()"); + ATLAS_TIME( "atlas::interpolation::method::Method::execute()" ); const size_t N = fieldsSource.size(); ASSERT(N == fieldsTarget.size()); @@ -103,7 +104,7 @@ void Method::execute(const FieldSet& fieldsSource, FieldSet& fieldsTarget) const void Method::execute(const Field& fieldSource, Field& fieldTarget) const { - eckit::TraceTimer tim("atlas::interpolation::method::Method::execute()"); + ATLAS_TIME( "atlas::interpolation::method::Method::execute()" ); eckit::linalg::Vector v_src(const_cast< Field& >(fieldSource).data(), fieldSource.shape(0)), diff --git a/src/atlas/interpolation/method/NearestNeighbour.cc b/src/atlas/interpolation/method/NearestNeighbour.cc index 8459a6e66..4b4f000bd 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.cc +++ b/src/atlas/interpolation/method/NearestNeighbour.cc @@ -12,10 +12,10 @@ #include "atlas/interpolation/method/NearestNeighbour.h" #include "eckit/log/Plural.h" -#include "eckit/log/Timer.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" #include "atlas/functionspace/NodeColumns.h" namespace atlas { @@ -58,7 +58,7 @@ void NearestNeighbour::setup(const FunctionSpace& source, const FunctionSpace& t std::vector< Triplet > weights_triplets; weights_triplets.reserve(out_npts); { - eckit::TraceTimer timer("atlas::interpolation::method::NearestNeighbour::setup()"); + Timer timer( Here(), "atlas::interpolation::method::NearestNeighbour::setup()" ); for (size_t ip = 0; ip < out_npts; ++ip) { if (ip && (ip % 1000 == 0)) { diff --git a/src/atlas/interpolation/method/PointSet.h b/src/atlas/interpolation/method/PointSet.h index 6dd3718b4..2ddfe6afa 100644 --- a/src/atlas/interpolation/method/PointSet.h +++ b/src/atlas/interpolation/method/PointSet.h @@ -19,11 +19,11 @@ #include #include -#include "eckit/log/Timer.h" #include "eckit/types/FloatCompare.h" #include "eckit/config/Resource.h" #include "atlas/interpolation/method/PointIndex3.h" +#include "atlas/runtime/Timer.h" #include "atlas/mesh/Mesh.h" #include "eckit/eckit_version.h" @@ -61,7 +61,7 @@ class PointSet { template < typename POINT_T > void list_unique_points( std::vector< POINT_T >& opts ) { - eckit::Timer t("Finding unique points"); + ATLAS_TIME( "Finding unique points" ); ASSERT( opts.empty() ); diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index a94151ceb..99f5a8594 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -99,7 +99,7 @@ void Library::initialise(int argc, char **argv) { void Library::initialise(const eckit::Parametrisation& config) { - // Timer configuration + // ATLAS_TIME(); configuration config.get("timer.barriers",timer_.barriers_); timer_.channel_ = &Log::debug(); @@ -114,8 +114,8 @@ void Library::initialise(const eckit::Parametrisation& config) { out << " size [" << parallel::mpi::comm().size() << "] \n"; out << " rank [" << parallel::mpi::comm().rank() << "] \n"; out << " \n"; - out << " TIMERS\n"; - out << " barrier [" << str(timer().barriers()) << "] \n"; + out << " ATLAS_TIME();S\n"; + out << " barrier [" << str(timer_.barriers()) << "] \n"; out << " \n"; out << atlas::Library::instance().info(); out << std::flush; @@ -124,8 +124,8 @@ void Library::initialise(const eckit::Parametrisation& config) { void Library::initialise() { util::Config timer_config; - if (::getenv("ATLAS_TIMER_BARRIERS")) { - bool var = eckit::Translator()(::getenv("ATLAS_TIMER_BARRIERS")); + if (::getenv("ATLAS_TIME_BARRIERS")) { + bool var = eckit::Translator()(::getenv("ATLAS_TIME_BARRIERS")); timer_config.set("barriers",var); } diff --git a/src/atlas/library/config.h b/src/atlas/library/config.h index 48a1e9afe..5988ca2b2 100644 --- a/src/atlas/library/config.h +++ b/src/atlas/library/config.h @@ -3,6 +3,8 @@ #include "atlas/atlas_ecbuild_config.h" #include "atlas/library/defines.h" +#define ATLAS_HAVE_TIMINGS 1 + namespace atlas { /// @typedef gidx_t diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.cc b/src/atlas/mesh/actions/BuildConvexHull3D.cc index 021d6a533..f9128b83d 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.cc +++ b/src/atlas/mesh/actions/BuildConvexHull3D.cc @@ -12,7 +12,6 @@ #include #include #include -#include "eckit/log/Timer.h" #include "eckit/log/BigNum.h" #include "eckit/memory/ScopedPtr.h" @@ -42,6 +41,7 @@ const Point_3 origin = Point_3(CGAL::ORIGIN); #endif #include "atlas/grid/Grid.h" +#include "atlas/runtime/Timer.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/HybridElements.h" @@ -69,7 +69,7 @@ namespace actions { static Polyhedron_3* create_convex_hull_from_points( const std::vector< Point3 >& pts ) { - Timer t("Convex hull"); + ATLAS_TIME(); Polyhedron_3* poly = new Polyhedron_3(); @@ -88,9 +88,9 @@ static Polyhedron_3* create_convex_hull_from_points( const std::vector< Point3 > static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, PointSet& points ) { - bool ensure_outward_normals = true; + ATLAS_TIME(); - Timer t ("Creating atlas data structure"); + bool ensure_outward_normals = true; mesh::Nodes& nodes = mesh.nodes(); @@ -193,7 +193,7 @@ void BuildConvexHull3D::operator()( Mesh& mesh ) const if( mesh.cells().size() ) return; - Timer t ("grid tesselation"); + ATLAS_TIME(); // remove duplicate points diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index 94219e9cd..683a648af 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -43,7 +43,7 @@ namespace { void global_bounding_box( const mesh::Nodes& nodes, double min[2], double max[2] ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); array::ArrayView xy = array::make_view( nodes.xy() ); const int nb_nodes = nodes.size(); @@ -104,7 +104,7 @@ void make_dual_normals_outward( Mesh& mesh ); void build_median_dual_mesh( Mesh& mesh ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); mesh::Nodes& nodes = mesh.nodes(); mesh::HybridElements& edges = mesh.edges(); @@ -134,13 +134,13 @@ void build_median_dual_mesh( Mesh& mesh ) functionspace::NodeColumns nodes_fs(mesh, Halo(mesh)); { - Timer t("halo-exchange dual_volumes"); + ATLAS_TIME("halo-exchange dual_volumes"); nodes_fs.haloExchange(nodes.field( "dual_volumes" )); } functionspace::EdgeColumns edges_fs(mesh, Halo(mesh)); { - Timer t("halo-exchange dual_normals"); + ATLAS_TIME( "halo-exchange dual_normals" ); edges_fs.haloExchange(edges.field( "dual_normals" )); } @@ -179,7 +179,7 @@ void add_median_dual_volume_contribution_cells( const mesh::Nodes& nodes, array::Array& array_dual_volumes ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); array::ArrayView dual_volumes = array::make_view ( array_dual_volumes ); @@ -227,7 +227,7 @@ void add_median_dual_volume_contribution_poles( const mesh::Nodes& nodes, array::Array& array_dual_volumes ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); array::ArrayView dual_volumes = array::make_view( array_dual_volumes ); const array::ArrayView xy = array::make_view( nodes.xy() ); @@ -284,7 +284,7 @@ void add_median_dual_volume_contribution_poles( void build_dual_normals( Mesh& mesh ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); array::ArrayView elem_centroids = array::make_view( mesh.cells().field("centroids_xy") ); @@ -387,7 +387,7 @@ void build_dual_normals( Mesh& mesh ) void make_dual_normals_outward( Mesh& mesh ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); mesh::Nodes& nodes = mesh.nodes(); array::ArrayView node_xy = array::make_view( nodes.xy() ); diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index f0d639939..ade382ddc 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -13,7 +13,6 @@ #include #include -#include "eckit/log/Timer.h" #include "atlas/library/config.h" #include "atlas/runtime/Log.h" #include "atlas/mesh/Mesh.h" @@ -93,7 +92,7 @@ typedef std::vector< std::vector > Node2Elem; void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) { - Timer t(__FUNCTION__); + ATLAS_TIME(); const mesh::Nodes& nodes = mesh.nodes(); @@ -122,7 +121,7 @@ void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) void accumulate_partition_bdry_nodes_old( Mesh& mesh, std::vector& bdry_nodes ) { - Timer t(__FUNCTION__); + ATLAS_TIME(); std::set bdry_nodes_set; @@ -164,7 +163,7 @@ void accumulate_partition_bdry_nodes( Mesh& mesh, size_t halo, std::vector& /* deprecated */ accumulate_partition_bdry_nodes_old(mesh,bdry_nodes); #else - Timer t(__FUNCTION__); + ATLAS_TIME(); const Mesh::Polygon& polygon = mesh.polygon(halo); bdry_nodes = std::vector( polygon.begin(), polygon.end() ); #endif @@ -225,7 +224,7 @@ class Notification typedef std::map Uid2Node; void build_lookup_uid2node( Mesh& mesh, Uid2Node& uid2node ) { - Timer t(__FUNCTION__); + ATLAS_TIME(); Notification notes; mesh::Nodes& nodes = mesh.nodes(); array::ArrayView xy = array::make_view ( nodes.xy() ); @@ -261,7 +260,7 @@ void accumulate_elements( const Mesh& mesh, std::vector& found_elements, std::set< uid_t >& new_nodes_uid ) { - Timer t(__FUNCTION__); + ATLAS_TIME(); const mesh::HybridElements::Connectivity &elem_nodes = mesh.cells().node_connectivity(); const array::ArrayView elem_part = array::make_view( mesh.cells().partition() ); @@ -390,7 +389,7 @@ class BuildHaloHelper static void all_to_all(Buffers& send, Buffers& recv) { - Timer t("all_to_all"); + ATLAS_TIME( "all_to_all" ); const eckit::mpi::Comm& comm = parallel::mpi::comm(); comm.allToAll(send.node_glb_idx, recv.node_glb_idx); @@ -533,7 +532,7 @@ class BuildHaloHelper template< typename NodeContainer, typename ElementContainer > void fill_sendbuffer(Buffers& buf,const NodeContainer& nodes_uid, const ElementContainer& elems, const PeriodicTransform& transform, int newflags, const int p) { - Timer t(__FUNCTION__); + ATLAS_TIME(); int nb_nodes = nodes_uid.size(); buf.node_glb_idx[p].resize(nb_nodes); @@ -608,7 +607,7 @@ class BuildHaloHelper void add_nodes(Buffers& buf, bool periodic ) { - Timer t(__FUNCTION__); + ATLAS_TIME(); mesh::Nodes& nodes = mesh.nodes(); int nb_nodes = nodes.size(); @@ -617,7 +616,7 @@ class BuildHaloHelper std::vector node_uid(nb_nodes); std::set new_node_uid; { - Timer scoped("compute node_uid"); + ATLAS_TIME( "compute node_uid" ); for( int jnode=0; jnode elem_uid(nb_elems); std::set new_elem_uid; { - Timer scoped("compute elem_uid"); + ATLAS_TIME( "compute elem_uid" ); for( int jelem=0; jelemrow(jelem)); } @@ -820,11 +819,11 @@ namespace { void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, bool periodic = false ) { #ifndef ATLAS_103 /* deprecated */ - Timer t("gather_bdry_nodes old way"); + ATLAS_TIME( "gather_bdry_nodes old way" ); parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); #else - Timer t(__FUNCTION__); + ATLAS_TIME(); Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); if( periodic ) { // add own rank to neighbours to allow periodicity with self (pole caps) @@ -1065,16 +1064,15 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri void BuildHalo::operator () ( int nb_elems ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME( "BuildHalo" ); int halo = 0; mesh_.metadata().get("halo",halo); if( halo == nb_elems ) return; - - Log::debug() << "Increasing mesh halo..." << std::endl; - eckit::TraceTimer timer("Increasing mesh halo... done"); + + ATLAS_TIME( "Increasing mesh halo" ); for(int jhalo=halo ; jhalo() << " periodic west : " << westpts << std::endl; #endif - { - Timer scope_timer( "increase_halo_periodic West" ); + ATLAS_TIME_SCOPE( "increase_halo_periodic West" ) { increase_halo_periodic( helper, westpts, WestEast(), Topology::PERIODIC|Topology::WEST|Topology::GHOST ); } @@ -1103,8 +1100,7 @@ void BuildHalo::operator () ( int nb_elems ) #ifdef DEBUG_OUTPUT Log::debug() << " periodic east : " << eastpts << std::endl; #endif - { - Timer scope_timer( "increase_halo_periodic East" ); + ATLAS_TIME_SCOPE( "increase_halo_periodic East" ) { increase_halo_periodic( helper, eastpts, EastWest(), Topology::PERIODIC|Topology::EAST|Topology::GHOST ); } diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index f3697fefb..ce1eb037e 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -91,7 +91,7 @@ struct Node void build_parallel_fields( Mesh& mesh ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); build_nodes_parallel_fields( mesh.nodes() ); } @@ -99,7 +99,7 @@ void build_parallel_fields( Mesh& mesh ) void build_nodes_parallel_fields( mesh::Nodes& nodes ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); bool parallel = false; nodes.metadata().get("parallel",parallel); if( ! parallel ) @@ -115,7 +115,7 @@ void build_nodes_parallel_fields( mesh::Nodes& nodes ) void build_edges_parallel_fields( Mesh& mesh ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); build_edges_partition ( mesh ); build_edges_remote_idx( mesh ); build_edges_global_idx( mesh ); @@ -125,7 +125,7 @@ void build_edges_parallel_fields( Mesh& mesh ) Field& build_nodes_global_idx( mesh::Nodes& nodes ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); array::ArrayView glb_idx = array::make_view( nodes.global_index() ); @@ -141,7 +141,7 @@ Field& build_nodes_global_idx( mesh::Nodes& nodes ) void renumber_nodes_glb_idx( mesh::Nodes& nodes ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); // TODO: ATLAS-14: fix renumbering of EAST periodic boundary points // --> Those specific periodic points at the EAST boundary are not checked for uid, @@ -232,7 +232,7 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) Field& build_nodes_remote_idx( mesh::Nodes& nodes ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); size_t mypart = parallel::mpi::comm().rank(); size_t nparts = parallel::mpi::comm().size(); @@ -332,7 +332,7 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) Field& build_nodes_partition( mesh::Nodes& nodes ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); return nodes.partition(); } @@ -340,7 +340,7 @@ Field& build_nodes_partition( mesh::Nodes& nodes ) Field& build_edges_partition( Mesh& mesh ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); const mesh::Nodes& nodes = mesh.nodes(); @@ -612,7 +612,7 @@ Field& build_edges_partition( Mesh& mesh ) Field& build_edges_remote_idx( Mesh& mesh ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); const mesh::Nodes& nodes = mesh.nodes(); UniqueLonLat compute_uid(mesh); @@ -767,7 +767,7 @@ Field& build_edges_remote_idx( Mesh& mesh ) Field& build_edges_global_idx( Mesh& mesh ) { - Timer scope_timer(__FUNCTION__); + ATLAS_TIME(); UniqueLonLat compute_uid(mesh); diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 3d3bd31e8..ed2df9545 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -190,7 +190,7 @@ void StructuredMeshGenerator::hash(Hash& h) const void StructuredMeshGenerator::generate(const Grid& grid, const grid::Distribution& distribution, Mesh& mesh ) const { - Timer t(__FUNCTION__); + ATLAS_TIME(); const grid::StructuredGrid rg = grid::StructuredGrid(grid); if( !rg ) @@ -235,7 +235,7 @@ void StructuredMeshGenerator::generate(const Grid& grid, const grid::Distributio void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, const std::vector& parts, int mypart, Region& region) const { - Timer t(__FUNCTION__); + ATLAS_TIME(); double max_angle = options.get("angle"); bool triangulate_quads = options.get("triangulate"); @@ -804,7 +804,7 @@ struct GhostNode { void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, const std::vector& parts, const Region& region, Mesh& mesh) const { - Timer t(__FUNCTION__); + ATLAS_TIME(); ASSERT(!mesh.generated()); diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index 7332e6631..baf10fbe2 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -116,8 +116,9 @@ void GatherScatter::setup( const int part[], } } + ATLAS_TIME_SCOPE("allGather[ counts ]") { - Timer t( Here() ); parallel::mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); + parallel::mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); } glbcnt_ = std::accumulate(glbcounts_.begin(),glbcounts_.end(),0); @@ -129,8 +130,8 @@ void GatherScatter::setup( const int part[], } std::vector recvnodes(glbcnt_); + ATLAS_TIME_SCOPE("allGatherv [glb nodes]") { - Timer t( Here() ); parallel::mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, recvnodes.data(), glbcounts_.data(), glbdispls_.data()); } @@ -148,8 +149,8 @@ void GatherScatter::setup( const int part[], recvnodes.clear(); // Sort on "g" member, and remove duplicates + ATLAS_TIME_SCOPE("sorting") { - Timer t("sorting"); std::sort(node_sort.begin(), node_sort.end()); node_sort.erase( std::unique( node_sort.begin(), node_sort.end() ), node_sort.end() ); } diff --git a/src/atlas/parallel/omp/omp.cc b/src/atlas/parallel/omp/omp.cc index b8e6938b7..7534591a9 100644 --- a/src/atlas/parallel/omp/omp.cc +++ b/src/atlas/parallel/omp/omp.cc @@ -259,7 +259,7 @@ double omp_get_wtime(void) { throw eckit::NotImplemented("omp_get_wtime()\n" "This function does not provide a working" - "wallclock timer. Replace it with a version" + "wallclock ATLAS_TIME();. Replace it with a version" "customized for the target machine", Here() ); return 0.0; } diff --git a/src/atlas/runtime/Timer.h b/src/atlas/runtime/Timer.h index 540f55fc5..15b524245 100644 --- a/src/atlas/runtime/Timer.h +++ b/src/atlas/runtime/Timer.h @@ -10,24 +10,86 @@ #pragma once +#include +#include +#include #include "eckit/log/Timer.h" +#include "eckit/log/Statistics.h" #include "atlas/library/Library.h" +#include "atlas/library/config.h" #include "atlas/runtime/Log.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/util/Config.h" + +#if ATLAS_HAVE_TIMINGS +#define ATLAS_TIME(...) ATLAS_TIME_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) +#define ATLAS_TIME_SCOPE(...) ATLAS_TIME_SCOPE_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) +#else +#define ATLAS_TIME(...) +#define ATLAS_TIME_SCOPE(...) +#endif + +#define __ATLAS__REVERSE 5, 4, 3, 2, 1, 0 +#define __ATLAS__ARGN(_1, _2, _3, _4, _5, N, ...) N +#define __ATLAS__NARG_(dummy, ...) __ATLAS__ARGN(__VA_ARGS__) +#define __ATLAS__NARG(...) __ATLAS__NARG_(dummy, ##__VA_ARGS__, __ATLAS__REVERSE) +#define __ATLAS__SPLICE(a,b) __ATLAS__SPLICE_1(a,b) +#define __ATLAS__SPLICE_1(a,b) __ATLAS__SPLICE_2(a,b) +#define __ATLAS__SPLICE_2(a,b) a##b + +#define ATLAS_TIME_SCOPE_(N, ...) __ATLAS__SPLICE( ATLAS_TIME_SCOPE_, N)(__VA_ARGS__) +#define ATLAS_TIME_SCOPE_0() \ + for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here());\ + __ATLAS__SPLICE( timer, __LINE__ ) .running(); \ + __ATLAS__SPLICE( timer, __LINE__ ) .stop() ) +#define ATLAS_TIME_SCOPE_1(title) \ + for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),title);\ + __ATLAS__SPLICE( timer, __LINE__ ) .running(); \ + __ATLAS__SPLICE( timer, __LINE__ ) .stop() ) + +#define ATLAS_TIME_(N, ...) __ATLAS__SPLICE( ATLAS_TIME_, N)(__VA_ARGS__) +#define ATLAS_TIME_0() ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here()); +#define ATLAS_TIME_1(title) ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),title); + namespace atlas { +class CallStack: public std::list< eckit::CodeLocation > { +private: + using Base = std::list< eckit::CodeLocation >; +public: + using Base::Base; + + void print(std::ostream& out) const { + const_iterator it = begin(); + out << "\nstack:\n"; + for( size_t i=0; ifile() << " +"<< it->line() << '\n'; + } + out << "\n"; + out << std::flush; + } + + friend std::ostream& operator<< ( std::ostream& out, const CallStack& p ) { + p.print(out); + return out; + } + +}; + template< typename TimerTraits > class TimerT { public: - using Barrier = typename TimerTraits::Barrier; - using Log = typename TimerTraits::Log; - + using Barrier = typename TimerTraits::Barrier; + using Log = typename TimerTraits::Log; + using Report = typename TimerTraits::Report; + using Nest = typename TimerTraits::Nest; + using CodeLocation = eckit::CodeLocation; + using ReportIdentifier = typename Report::Identifier; public: - TimerT(const std::string& msg, std::ostream& out = Log::channel() ); - - TimerT(); + TimerT( const CodeLocation&, const std::string& msg, std::ostream& out = Log::channel() ); + TimerT( const CodeLocation&, std::ostream& out = Log::channel() ); ~TimerT(); @@ -43,28 +105,37 @@ class TimerT { void barrier() const; - static eckit::Channel& empty_channel(); + void updateTimings() const; + + void registerTimer(); private: mutable eckit::Timer timer_; + CodeLocation loc_; std::ostream& out_; std::string msg_; - bool barrier_; + ReportIdentifier id_; + Nest nest_; }; // Definitions template< typename TimerTraits > -inline TimerT::TimerT(const std::string& msg, std::ostream& out ) : +inline TimerT::TimerT( const CodeLocation& loc, const std::string& msg, std::ostream& out ) : + loc_(loc), out_(out), msg_(msg), - barrier_(Barrier::state()) { + nest_(loc) { start(); } template< typename TimerTraits > -inline TimerT::TimerT() : - TimerT(std::string(), empty_channel() ) { +inline TimerT::TimerT( const CodeLocation& loc, std::ostream& out ) : + loc_(loc), + out_(out), + msg_( loc_ ? loc_.func() : "" ), + nest_(loc_) { + start(); } template< typename TimerTraits > @@ -77,6 +148,16 @@ inline void TimerT::barrier() const { Barrier::execute(); } +template< typename TimerTraits > +inline void TimerT::registerTimer() { + id_ = Report::add( nest_, msg_ ); +} + +template< typename TimerTraits > +inline void TimerT::updateTimings() const { + Report::update( id_, timer_ ); +} + template< typename TimerTraits > inline bool TimerT::running() const { return timer_.running(); @@ -85,6 +166,7 @@ inline bool TimerT::running() const { template< typename TimerTraits > inline void TimerT::start() { timer_.stop(); + registerTimer(); out_ << msg_ << " ..." << std::endl; barrier(); timer_.start(); @@ -95,6 +177,7 @@ inline void TimerT::stop() { if( running() ) { barrier(); timer_.stop(); + updateTimings(); out_ << msg_ << " ... done : " << timer_.elapsed() << " seconds" << std::endl; } } @@ -104,12 +187,6 @@ inline double TimerT::elapsed() const { return timer_.elapsed(); } -template< typename TimerTraits > -inline eckit::Channel& TimerT::empty_channel() { - static eckit::Channel channel; - return channel; -} - class TimerBarrier { private: @@ -154,6 +231,48 @@ class TimerBarrier { } }; + + +class TimerNest { +private: + class State { + private: + State() {} + CallStack stack_; + public: + State(State const&) = delete; + void operator=(State const&) = delete; + static State& instance() { + static State state; + return state; + } + operator CallStack() const { + return stack_; + } + CallStack& push( const eckit::CodeLocation& loc ) { + stack_.push_front(loc); + return stack_; + } + CallStack& pop() { + stack_.pop_front(); + return stack_; + } + }; + + long depth_; + CallStack stack_; + +public: + TimerNest( const eckit::CodeLocation& loc ) : + stack_( State::instance().push( loc ) ) { + } + ~TimerNest() { + State::instance().pop(); + } + operator long() const { return stack_.size(); } + operator CallStack() const { return stack_; } +}; + class TimerLog { private: class State { @@ -200,9 +319,189 @@ class TimerLog { static std::ostream& channel() { return State::instance(); } }; +class TimerReport { + using Timing = eckit::Timing; +private: + class Registry { + private: + + std::vector counts_; + std::vector tot_timings_; + std::vector min_timings_; + std::vector max_timings_; + std::vector titles_; + std::vector locations_; + std::vector nest_; + std::vector stack_; + std::map index_; + + Registry() { + } + + public: + + static Registry& instance() { + static Registry registry; + return registry; + } + + size_t add( const CallStack& stack, const std::string& title ) { + std::stringstream ss; ss << stack; + std::string key = ss.str(); + auto it = index_.find( key ); + if( it == index_.end() ) { + size_t idx = size(); + index_[key] = idx; + counts_.emplace_back( 0 ); + tot_timings_.emplace_back( 0 ); + min_timings_.emplace_back( 0 ); + max_timings_.emplace_back( 0 ); + titles_.emplace_back( title ); + locations_.emplace_back( stack.front() ); + nest_.emplace_back( stack.size() ); + stack_.emplace_back( stack ); + return idx; + } + else { + return it->second; + } + } + + void update( size_t idx, eckit::Timer& timer ) { + double time = timer.elapsed(); + counts_[idx] += 1; + tot_timings_[idx] += time; + min_timings_[idx] = counts_[idx] == 1 ? time : std::min( time, min_timings_[idx] ); + max_timings_[idx] = counts_[idx] == 1 ? time : std::max( time, max_timings_[idx] ); + } + + size_t size() const { return counts_.size(); } + + void report( std::ostream& out, const eckit::Configuration& config ) { + long indent = config.getLong("indent",4); + long max_nest = config.getLong("depth",0); + long decimals = config.getLong("decimals",5); + + auto digits_before_decimal = [](double x) -> int { + return std::floor(std::log10(std::trunc( std::max(1.,x)) ) )+1; + }; + auto digits = [](long x) -> long { + return std::floor(std::log10( std::max(1l,x) ) )+1l; + }; + + size_t max_title_length(0); + long max_count(0); + double max_seconds(0); + for( size_t j=0; j std::string { + std::stringstream out; + char unit = 's'; + if( std::floor(x) >= 60 ) { + x/=60.; + unit = 'm'; + } + out << std::right + << std::fixed + << std::setprecision(decimals) + << std::setw(max_digits_before_decimal+decimals+1) + << x << unit; + return out.str(); + }; + + + for( size_t j=0; j { diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc index 53b2c6411..fbe14d8e9 100644 --- a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -39,9 +39,9 @@ using namespace atlas::grid; using atlas::util::Config; using eckit::PathName; -struct TimerStats +struct ATLAS_TIME();Stats { - TimerStats(const std::string& _name = "timer") + ATLAS_TIME();Stats(const std::string& _name = "ATLAS_TIME();") { max = -1; min = -1; @@ -49,7 +49,7 @@ struct TimerStats cnt = 0; name = _name; } - void update(eckit::Timer& timer) + void update(eckit::ATLAS_TIME();& ATLAS_TIME();) { double t = timer.elapsed(); if( min < 0 ) min = t; @@ -145,19 +145,19 @@ void Tool::execute(const Args& args) size_t iterations = 10; parallel::mpi::comm().barrier(); - TimerStats timer_stats; + ATLAS_TIME();Stats timer_stats; for( size_t i=0; i Those specific periodic points at the EAST boundary are not checked for uid, // and could receive different gidx for different tasks @@ -148,7 +113,7 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha ATLAS_DEBUG_VAR( points_to_edit ); ATLAS_DEBUG_VAR( points_to_edit.size() ); - Timer total_timer("distrubuted_sort"); + ATLAS_TIME( "distributed_sort" ); /* * Sorting following gidx will define global order of @@ -184,8 +149,7 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha node_sort.push_back( Node(glb_idx_gathered[jnode],jnode) ); } - { - Timer total_timer("local_sort"); + ATLAS_TIME_SCOPE( "local_sort" ) { std::sort(node_sort.begin(), node_sort.end()); } @@ -259,7 +223,7 @@ Tool::Tool(int argc,char **argv): AtlasTool(argc,argv) void Tool::execute(const Args& args) { - Timer t("main"); + Timer t( Here(), "main"); key = ""; args.get("grid",key); @@ -290,33 +254,27 @@ void Tool::execute(const Args& args) ATLAS_DEBUG_VAR( do_all ); - size_t iterations = 1; - TimerStats timer_stats; + size_t iterations = 5; parallel::mpi::comm().barrier(); - Mesh mesh = meshgenerator.generate(grid); + + for( size_t j=0; j<7; ++j ) { + ATLAS_TIME("outer_iteration"); + Mesh mesh = meshgenerator.generate(grid); + atlas::mesh::actions::build_periodic_boundaries(mesh); - atlas::mesh::actions::build_periodic_boundaries(mesh); + Log::info() << "building halo" << std::endl; + atlas::mesh::actions::BuildHalo build_halo(mesh); + build_halo(halo); - Log::info() << "building halo" << std::endl; - atlas::mesh::actions::BuildHalo build_halo(mesh); - build_halo(halo); - - Timer::Barrier set_barrier(true); - Timer::Log set_channel( Log::info() ); - for( size_t i=0; i tim("PartitionedMesh::partition()"); + ATLAS_TIME( "PartitionedMesh::partition()" ); partitioner_ = Partitioner(optionPartitioner_); @@ -63,7 +63,7 @@ void PartitionedMesh::partition(const Grid& grid) { void PartitionedMesh::partition(const Grid& grid, const PartitionedMesh& other) { - eckit::TraceTimer tim("PartitionedMesh::partition(other)"); + ATLAS_TIME( "PartitionedMesh::partition(other)" ); partitioner_ = grid::MatchingMeshPartitioner(other.mesh_, util::Config("type", optionPartitioner_)); diff --git a/src/tests/numerics/fctest_fvm_nabla.F90 b/src/tests/numerics/fctest_fvm_nabla.F90 index 9a6e74632..9a5638292 100644 --- a/src/tests/numerics/fctest_fvm_nabla.F90 +++ b/src/tests/numerics/fctest_fvm_nabla.F90 @@ -43,17 +43,17 @@ module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture - type :: Timer_type + type :: timer_type private integer*8 :: clck_counts_start, clck_counts_stop, clck_rate integer*8 :: counted = 0 logical :: paused = .True. contains - procedure, public :: start => Timer_start - procedure, public :: pause => Timer_pause - procedure, public :: resume => Timer_resume - procedure, public :: elapsed => Timer_elapsed - end type Timer_type + procedure, public :: start => timer_start + procedure, public :: pause => timer_pause + procedure, public :: resume => timer_resume + procedure, public :: elapsed => timer_elapsed + end type timer_type @@ -61,9 +61,9 @@ module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture contains - function Timer_elapsed(self) result(time) + function timer_elapsed(self) result(time) use, intrinsic :: iso_c_binding, only : c_double - class(Timer_type), intent(inout) :: self + class(timer_type), intent(inout) :: self real(c_double) :: time if (.not. self%paused) then call system_clock ( self%clck_counts_stop, self%clck_rate ) @@ -73,27 +73,27 @@ function Timer_elapsed(self) result(time) else time = 0. end if - end function Timer_elapsed + end function timer_elapsed - subroutine Timer_start(self) - class(Timer_type), intent(inout) :: self + subroutine timer_start(self) + class(timer_type), intent(inout) :: self call system_clock ( self%clck_counts_start, self%clck_rate ) self%paused = .False. self%counted = 0 - end subroutine Timer_start + end subroutine timer_start - subroutine Timer_pause(self) - class(Timer_type), intent(inout) :: self + subroutine timer_pause(self) + class(timer_type), intent(inout) :: self call system_clock ( self%clck_counts_stop, self%clck_rate ) self%counted = self%counted + self%clck_counts_stop - self%clck_counts_start self%paused = .True. - end subroutine Timer_pause + end subroutine timer_pause - subroutine Timer_resume(self) - class(Timer_type), intent(inout) :: self + subroutine timer_resume(self) + class(timer_type), intent(inout) :: self call system_clock ( self%clck_counts_start, self%clck_rate ) self%paused = .False. - end subroutine Timer_resume + end subroutine timer_resume subroutine rotated_flow_magnitude( fvm, field, beta, radius ) @@ -363,7 +363,7 @@ end module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture ! ----------------------------------------------------------------------------- TEST( test_nabla ) -type(Timer_type) :: timer +type(timer_type) :: ATLAS_TIME(); integer :: jiter, niter real(c_double) :: norm_native real(c_double) :: norm_fortran @@ -374,11 +374,11 @@ end module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture niter = 5 ! Compute the gradient -call timer%start() +call ATLAS_TIME();%start() do jiter = 1,niter call nabla%gradient(varfield,gradfield) enddo -write(0,*) "time elapsed: ", timer%elapsed() +write(0,*) "time elapsed: ", ATLAS_TIME();%elapsed() call node_columns%mean(gradfield,norm_native) write(0,*) "mean : ", norm_native @@ -387,11 +387,11 @@ end module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture write(0,*) "" ! Compute the gradient with Fortran routine above -call timer%start() +call ATLAS_TIME();%start() do jiter = 1,niter CALL FV_GRADIENT(var,grad) enddo -write(0,*) "time elapsed: ", timer%elapsed() +write(0,*) "time elapsed: ", ATLAS_TIME();%elapsed() call node_columns%mean(gradfield,norm_fortran) write(0,*) "mean : ", norm_fortran From 00ce998e125a9808e7a51551169e40475b20fda4 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 6 Oct 2017 11:37:09 +0100 Subject: [PATCH 019/355] ATLAS-132 More template black magic to support gcc --- src/atlas/runtime/Timer.h | 66 +++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/src/atlas/runtime/Timer.h b/src/atlas/runtime/Timer.h index 15b524245..1f524263f 100644 --- a/src/atlas/runtime/Timer.h +++ b/src/atlas/runtime/Timer.h @@ -21,22 +21,47 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/util/Config.h" -#if ATLAS_HAVE_TIMINGS -#define ATLAS_TIME(...) ATLAS_TIME_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) -#define ATLAS_TIME_SCOPE(...) ATLAS_TIME_SCOPE_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) -#else -#define ATLAS_TIME(...) -#define ATLAS_TIME_SCOPE(...) -#endif +//----------------------------------------------------------------------------------------------------------- #define __ATLAS__REVERSE 5, 4, 3, 2, 1, 0 #define __ATLAS__ARGN(_1, _2, _3, _4, _5, N, ...) N -#define __ATLAS__NARG_(dummy, ...) __ATLAS__ARGN(__VA_ARGS__) -#define __ATLAS__NARG(...) __ATLAS__NARG_(dummy, ##__VA_ARGS__, __ATLAS__REVERSE) +#define __ATLAS__NARG__(dummy, ...) __ATLAS__ARGN(__VA_ARGS__) +#define __ATLAS__NARG_(...) __ATLAS__NARG__(dummy, ##__VA_ARGS__, __ATLAS__REVERSE) #define __ATLAS__SPLICE(a,b) __ATLAS__SPLICE_1(a,b) #define __ATLAS__SPLICE_1(a,b) __ATLAS__SPLICE_2(a,b) #define __ATLAS__SPLICE_2(a,b) a##b + +#define __ATLAS__ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15 +#define __ATLAS__HAS_COMMA(...) __ATLAS__ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) +#define __ATLAS__TRIGGER_PARENTHESIS(...) , +#define __ATLAS__ISEMPTY(...) \ +__ATLAS__ISEMPTY_( \ + /* test if there is just one argument, eventually an empty one */ \ + __ATLAS__HAS_COMMA(__VA_ARGS__), \ + /* test if _TRIGGER_PARENTHESIS_ together with the argument adds a comma */ \ + __ATLAS__HAS_COMMA(__ATLAS__TRIGGER_PARENTHESIS __VA_ARGS__), \ + /* test if the argument together with a parenthesis adds a comma */ \ + __ATLAS__HAS_COMMA(__VA_ARGS__ (/*empty*/)), \ + /* test if placing it between __ATLAS__TRIGGER_PARENTHESIS and the parenthesis adds a comma */ \ + __ATLAS__HAS_COMMA(__ATLAS__TRIGGER_PARENTHESIS __VA_ARGS__ (/*empty*/)) \ +) + +#define __ATLAS__PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4 +#define __ATLAS__ISEMPTY_(_0, _1, _2, _3) __ATLAS__HAS_COMMA(__ATLAS__PASTE5(__ATLAS__IS_EMPTY_CASE_, _0, _1, _2, _3)) +#define __ATLAS__IS_EMPTY_CASE_0001 , + +#define __ATLAS__CALL_NARG_1(...) 0 +#define __ATLAS__CALL_NARG_0 __ATLAS__NARG_ +#define __ATLAS__NARG(...) __ATLAS__SPLICE( __ATLAS__CALL_NARG_, __ATLAS__ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) + +//----------------------------------------------------------------------------------------------------------- + +#if ATLAS_HAVE_TIMINGS + +#define ATLAS_TIME(...) ATLAS_TIME_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) +#define ATLAS_TIME_SCOPE(...) ATLAS_TIME_SCOPE_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) + #define ATLAS_TIME_SCOPE_(N, ...) __ATLAS__SPLICE( ATLAS_TIME_SCOPE_, N)(__VA_ARGS__) #define ATLAS_TIME_SCOPE_0() \ for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here());\ @@ -51,6 +76,13 @@ #define ATLAS_TIME_0() ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here()); #define ATLAS_TIME_1(title) ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),title); +#else + +#define ATLAS_TIME(...) +#define ATLAS_TIME_SCOPE(...) + +#endif + namespace atlas { @@ -381,11 +413,11 @@ class TimerReport { long indent = config.getLong("indent",4); long max_nest = config.getLong("depth",0); long decimals = config.getLong("decimals",5); - - auto digits_before_decimal = [](double x) -> int { + + auto digits_before_decimal = [](double x) -> int { return std::floor(std::log10(std::trunc( std::max(1.,x)) ) )+1; }; - auto digits = [](long x) -> long { + auto digits = [](long x) -> long { return std::floor(std::log10( std::max(1l,x) ) )+1l; }; @@ -402,22 +434,22 @@ class TimerReport { } size_t max_count_length = digits(max_count); size_t max_digits_before_decimal = digits_before_decimal(max_seconds); - - auto print_time = [max_digits_before_decimal,decimals](double x) -> std::string { + + auto print_time = [max_digits_before_decimal,decimals](double x) -> std::string { std::stringstream out; char unit = 's'; if( std::floor(x) >= 60 ) { x/=60.; unit = 'm'; } - out << std::right + out << std::right << std::fixed << std::setprecision(decimals) << std::setw(max_digits_before_decimal+decimals+1) << x << unit; return out.str(); }; - + for( size_t j=0; j Date: Fri, 6 Oct 2017 15:47:33 +0100 Subject: [PATCH 020/355] ATLAS-132 Fix compilation Fortran --- src/apps/atlas-numerics-nabla.F90 | 10 +++++----- src/tests/numerics/fctest_fvm_nabla.F90 | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/apps/atlas-numerics-nabla.F90 b/src/apps/atlas-numerics-nabla.F90 index 7d75fd620..5b6dcdcc0 100644 --- a/src/apps/atlas-numerics-nabla.F90 +++ b/src/apps/atlas-numerics-nabla.F90 @@ -289,7 +289,7 @@ subroutine finalize() subroutine run() use fckit_mpi_module -type(timer_type) :: ATLAS_TIME(); +type(timer_type) :: timer; type(fckit_mpi_comm) :: mpi integer :: jiter, jouter real(c_double) :: timing_cpp, timing_f90, timing @@ -306,9 +306,9 @@ subroutine run() ! Compute the gradient timing = 1.e10 do jiter = 1,niter - call ATLAS_TIME();%start() + call timer%start() call nabla%gradient(varfield,gradfield) - timing = min(timing,ATLAS_TIME();%elapsed()) + timing = min(timing,timer%elapsed()) enddo timing_cpp = timing write(msg,*) "timing_cpp = ", timing_cpp @@ -320,9 +320,9 @@ subroutine run() ! Compute the gradient with Fortran routine above timing = 1.e10 do jiter = 1,niter - call ATLAS_TIME();%start() + call timer%start() call FV_GRADIENT(var,grad) - timing = min(timing,ATLAS_TIME();%elapsed()) + timing = min(timing,timer%elapsed()) enddo timing_f90 = timing write(msg,*) "timing_f90 = ", timing_f90 diff --git a/src/tests/numerics/fctest_fvm_nabla.F90 b/src/tests/numerics/fctest_fvm_nabla.F90 index 9a5638292..ec058386f 100644 --- a/src/tests/numerics/fctest_fvm_nabla.F90 +++ b/src/tests/numerics/fctest_fvm_nabla.F90 @@ -363,7 +363,7 @@ end module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture ! ----------------------------------------------------------------------------- TEST( test_nabla ) -type(timer_type) :: ATLAS_TIME(); +type(timer_type) :: timer; integer :: jiter, niter real(c_double) :: norm_native real(c_double) :: norm_fortran @@ -374,11 +374,11 @@ end module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture niter = 5 ! Compute the gradient -call ATLAS_TIME();%start() +call timer%start() do jiter = 1,niter call nabla%gradient(varfield,gradfield) enddo -write(0,*) "time elapsed: ", ATLAS_TIME();%elapsed() +write(0,*) "time elapsed: ", timer%elapsed() call node_columns%mean(gradfield,norm_native) write(0,*) "mean : ", norm_native @@ -387,11 +387,11 @@ end module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture write(0,*) "" ! Compute the gradient with Fortran routine above -call ATLAS_TIME();%start() +call timer%start() do jiter = 1,niter CALL FV_GRADIENT(var,grad) enddo -write(0,*) "time elapsed: ", ATLAS_TIME();%elapsed() +write(0,*) "time elapsed: ", timer%elapsed() call node_columns%mean(gradfield,norm_fortran) write(0,*) "mean : ", norm_fortran From b9340c3014da6350b03f0c759d0842e17442a97a Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 6 Oct 2017 15:48:11 +0100 Subject: [PATCH 021/355] ATLAS-132 Cleaning up --- src/apps/atlas-benchmark.cc | 4 +- src/atlas/CMakeLists.txt | 13 + src/atlas/mesh/actions/BuildHalo.cc | 6 +- src/atlas/runtime/Timer.h | 560 ++---------------- src/atlas/runtime/timer/TimerBarriers.cc | 22 + src/atlas/runtime/timer/TimerBarriers.h | 68 +++ src/atlas/runtime/timer/TimerLogging.cc | 23 + src/atlas/runtime/timer/TimerLogging.h | 73 +++ src/atlas/runtime/timer/TimerNesting.cc | 22 + src/atlas/runtime/timer/TimerNesting.h | 67 +++ src/atlas/runtime/timer/TimerT.h | 166 ++++++ src/atlas/runtime/timer/Timings.cc | 219 +++++++ src/atlas/runtime/timer/Timings.h | 43 ++ src/atlas/util/detail/BlackMagic.h | 52 ++ src/atlas/util/detail/CallStack.cc | 22 + src/atlas/util/detail/CallStack.h | 36 ++ .../atlas-benchmark-build-halo.cc | 46 +- .../atlas-benchmark-sorting.cc | 10 +- 18 files changed, 899 insertions(+), 553 deletions(-) create mode 100644 src/atlas/runtime/timer/TimerBarriers.cc create mode 100644 src/atlas/runtime/timer/TimerBarriers.h create mode 100644 src/atlas/runtime/timer/TimerLogging.cc create mode 100644 src/atlas/runtime/timer/TimerLogging.h create mode 100644 src/atlas/runtime/timer/TimerNesting.cc create mode 100644 src/atlas/runtime/timer/TimerNesting.h create mode 100644 src/atlas/runtime/timer/TimerT.h create mode 100644 src/atlas/runtime/timer/Timings.cc create mode 100644 src/atlas/runtime/timer/Timings.h create mode 100644 src/atlas/util/detail/BlackMagic.h create mode 100644 src/atlas/util/detail/CallStack.cc create mode 100644 src/atlas/util/detail/CallStack.h diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 1485c7c03..b92c282ed 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -189,7 +189,7 @@ class AtlasBenchmark: public AtlasTool { void AtlasBenchmark::execute(const Args& args) { - Timer::Log set_channel( Log::info() ); + Timer::Logging set_channel( Log::info() ); nlev = 137; args.get("nlev",nlev); @@ -280,7 +280,7 @@ void AtlasBenchmark::execute(const Args& args) void AtlasBenchmark::setup() { - Timer::Log set_channel( Log::debug() ); + Timer::Logging set_channel( Log::debug() ); size_t halo = 1; diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 5902b0d87..f4508c95c 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -33,6 +33,16 @@ runtime/ErrorHandling.cc runtime/AtlasTool.h runtime/AtlasTool.cc runtime/Log.h +runtime/Timer.h +runtime/timer/TimerT.h +runtime/timer/TimerNesting.cc +runtime/timer/TimerNesting.h +runtime/timer/TimerBarriers.cc +runtime/timer/TimerBarriers.h +runtime/timer/TimerLogging.cc +runtime/timer/TimerLogging.h +runtime/timer/Timings.h +runtime/timer/Timings.cc parallel/mpi/mpi.cc parallel/mpi/mpi.h parallel/omp/omp.cc @@ -422,6 +432,9 @@ util/Metadata.cc util/Metadata.h util/Rotation.cc util/Rotation.h +util/detail/CallStack.h +util/detail/CallStack.cc +util/detail/BlackMagic.h ) list( APPEND atlas_internals_srcs diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index ade382ddc..77d5b5027 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -911,7 +911,7 @@ void increase_halo_interior( BuildHaloHelper& helper ) gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts ); - Timer::Barrier timer_barriers(false); + Timer::Barriers timer_barriers(false); #ifndef ATLAS_103 /* deprecated */ @@ -1020,7 +1020,7 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts, /* periodic = */ true ); - Timer::Barrier set_barrier(false); + Timer::Barriers set_barrier(false); #ifndef ATLAS_103 /* deprecated */ @@ -1071,7 +1071,7 @@ void BuildHalo::operator () ( int nb_elems ) if( halo == nb_elems ) return; - + ATLAS_TIME( "Increasing mesh halo" ); for(int jhalo=halo ; jhalo -#include -#include -#include "eckit/log/Timer.h" -#include "eckit/log/Statistics.h" -#include "atlas/library/Library.h" #include "atlas/library/config.h" -#include "atlas/runtime/Log.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/util/Config.h" +#include "atlas/runtime/timer/TimerT.h" +#include "atlas/runtime/timer/TimerBarriers.h" +#include "atlas/runtime/timer/TimerLogging.h" +#include "atlas/runtime/timer/Timings.h" +#include "atlas/runtime/timer/TimerNesting.h" //----------------------------------------------------------------------------------------------------------- -#define __ATLAS__REVERSE 5, 4, 3, 2, 1, 0 -#define __ATLAS__ARGN(_1, _2, _3, _4, _5, N, ...) N -#define __ATLAS__NARG__(dummy, ...) __ATLAS__ARGN(__VA_ARGS__) -#define __ATLAS__NARG_(...) __ATLAS__NARG__(dummy, ##__VA_ARGS__, __ATLAS__REVERSE) -#define __ATLAS__SPLICE(a,b) __ATLAS__SPLICE_1(a,b) -#define __ATLAS__SPLICE_1(a,b) __ATLAS__SPLICE_2(a,b) -#define __ATLAS__SPLICE_2(a,b) a##b +/// Create scoped timer objects +/// +/// Example: +/// +/// void foo() { +/// ATLAS_TIME(); +/// // timer "foo" starts +/// +/// /* interesting computations ... */ +/// +/// ATLAS_TIME_SCOPE("bar") { +/// // timer "bar" starts +/// +/// /* interesting computations ... */ +/// +/// // timer "bar" ends +/// } +/// +/// // timer "foo" ends +/// } +/// +/// Example 2: +/// +/// void foo() { +/// ATLAS_TIME("custom"); +/// // timer "custom" starts +/// +/// /* interesting computations ... */ +/// +/// // timer "custom" ends +/// } +/// +#define ATLAS_TIME(...) +#define ATLAS_TIME_SCOPE(...) + +//----------------------------------------------------------------------------------------------------------- +namespace atlas { + +struct TimerTraits { + using Barriers = runtime::timer::TimerBarriers; + using Logging = runtime::timer::TimerLogging; + using Timings = runtime::timer::Timings; + using Nesting = runtime::timer::TimerNesting; +}; -#define __ATLAS__ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15 -#define __ATLAS__HAS_COMMA(...) __ATLAS__ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) -#define __ATLAS__TRIGGER_PARENTHESIS(...) , -#define __ATLAS__ISEMPTY(...) \ -__ATLAS__ISEMPTY_( \ - /* test if there is just one argument, eventually an empty one */ \ - __ATLAS__HAS_COMMA(__VA_ARGS__), \ - /* test if _TRIGGER_PARENTHESIS_ together with the argument adds a comma */ \ - __ATLAS__HAS_COMMA(__ATLAS__TRIGGER_PARENTHESIS __VA_ARGS__), \ - /* test if the argument together with a parenthesis adds a comma */ \ - __ATLAS__HAS_COMMA(__VA_ARGS__ (/*empty*/)), \ - /* test if placing it between __ATLAS__TRIGGER_PARENTHESIS and the parenthesis adds a comma */ \ - __ATLAS__HAS_COMMA(__ATLAS__TRIGGER_PARENTHESIS __VA_ARGS__ (/*empty*/)) \ -) +class Timer : public runtime::timer::TimerT< TimerTraits > { + using Base = runtime::timer::TimerT< TimerTraits >; +public: + using Base::Base; +}; -#define __ATLAS__PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4 -#define __ATLAS__ISEMPTY_(_0, _1, _2, _3) __ATLAS__HAS_COMMA(__ATLAS__PASTE5(__ATLAS__IS_EMPTY_CASE_, _0, _1, _2, _3)) -#define __ATLAS__IS_EMPTY_CASE_0001 , +} // namespace atlas -#define __ATLAS__CALL_NARG_1(...) 0 -#define __ATLAS__CALL_NARG_0 __ATLAS__NARG_ -#define __ATLAS__NARG(...) __ATLAS__SPLICE( __ATLAS__CALL_NARG_, __ATLAS__ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) //----------------------------------------------------------------------------------------------------------- #if ATLAS_HAVE_TIMINGS +#include "atlas/util/detail/BlackMagic.h" + +#undef ATLAS_TIME +#undef ATLAS_TIME_SCOPE #define ATLAS_TIME(...) ATLAS_TIME_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) #define ATLAS_TIME_SCOPE(...) ATLAS_TIME_SCOPE_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) @@ -76,469 +99,6 @@ __ATLAS__ISEMPTY_( #define ATLAS_TIME_0() ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here()); #define ATLAS_TIME_1(title) ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),title); -#else - -#define ATLAS_TIME(...) -#define ATLAS_TIME_SCOPE(...) - #endif - -namespace atlas { - -class CallStack: public std::list< eckit::CodeLocation > { -private: - using Base = std::list< eckit::CodeLocation >; -public: - using Base::Base; - - void print(std::ostream& out) const { - const_iterator it = begin(); - out << "\nstack:\n"; - for( size_t i=0; ifile() << " +"<< it->line() << '\n'; - } - out << "\n"; - out << std::flush; - } - - friend std::ostream& operator<< ( std::ostream& out, const CallStack& p ) { - p.print(out); - return out; - } - -}; - -template< typename TimerTraits > -class TimerT { -public: - using Barrier = typename TimerTraits::Barrier; - using Log = typename TimerTraits::Log; - using Report = typename TimerTraits::Report; - using Nest = typename TimerTraits::Nest; - using CodeLocation = eckit::CodeLocation; - using ReportIdentifier = typename Report::Identifier; -public: - - TimerT( const CodeLocation&, const std::string& msg, std::ostream& out = Log::channel() ); - TimerT( const CodeLocation&, std::ostream& out = Log::channel() ); - - ~TimerT(); - - bool running() const; - - void start(); - - void stop(); - - double elapsed() const; - -private: - - void barrier() const; - - void updateTimings() const; - - void registerTimer(); - -private: - mutable eckit::Timer timer_; - CodeLocation loc_; - std::ostream& out_; - std::string msg_; - ReportIdentifier id_; - Nest nest_; -}; - -// Definitions - -template< typename TimerTraits > -inline TimerT::TimerT( const CodeLocation& loc, const std::string& msg, std::ostream& out ) : - loc_(loc), - out_(out), - msg_(msg), - nest_(loc) { - start(); -} - -template< typename TimerTraits > -inline TimerT::TimerT( const CodeLocation& loc, std::ostream& out ) : - loc_(loc), - out_(out), - msg_( loc_ ? loc_.func() : "" ), - nest_(loc_) { - start(); -} - -template< typename TimerTraits > -inline TimerT::~TimerT() { - stop(); -} - -template< typename TimerTraits > -inline void TimerT::barrier() const { - Barrier::execute(); -} - -template< typename TimerTraits > -inline void TimerT::registerTimer() { - id_ = Report::add( nest_, msg_ ); -} - -template< typename TimerTraits > -inline void TimerT::updateTimings() const { - Report::update( id_, timer_ ); -} - -template< typename TimerTraits > -inline bool TimerT::running() const { - return timer_.running(); -} - -template< typename TimerTraits > -inline void TimerT::start() { - timer_.stop(); - registerTimer(); - out_ << msg_ << " ..." << std::endl; - barrier(); - timer_.start(); -} - -template< typename TimerTraits > -inline void TimerT::stop() { - if( running() ) { - barrier(); - timer_.stop(); - updateTimings(); - out_ << msg_ << " ... done : " << timer_.elapsed() << " seconds" << std::endl; - } -} - -template< typename TimerTraits > -inline double TimerT::elapsed() const { - return timer_.elapsed(); -} - - -class TimerBarrier { -private: - class State { - private: - State() { - barriers_ = atlas::Library::instance().timer().barriers(); - } - bool barriers_; - public: - State(State const&) = delete; - void operator=(State const&) = delete; - static State& instance() { - static State state; - return state; - } - operator bool() const { - return barriers_; - } - void set( bool state ) { - barriers_ = state; - } - }; - - bool previous_state_; - -public: - TimerBarrier(bool state) : - previous_state_( State::instance() ) { - State::instance().set(state); - } - ~TimerBarrier() { - restore(); - } - void restore() { - State::instance().set( previous_state_ ); - } - static bool state() { return State::instance(); } - static void execute() { - if( state() ) - parallel::mpi::comm().barrier(); - } -}; - - - -class TimerNest { -private: - class State { - private: - State() {} - CallStack stack_; - public: - State(State const&) = delete; - void operator=(State const&) = delete; - static State& instance() { - static State state; - return state; - } - operator CallStack() const { - return stack_; - } - CallStack& push( const eckit::CodeLocation& loc ) { - stack_.push_front(loc); - return stack_; - } - CallStack& pop() { - stack_.pop_front(); - return stack_; - } - }; - - long depth_; - CallStack stack_; - -public: - TimerNest( const eckit::CodeLocation& loc ) : - stack_( State::instance().push( loc ) ) { - } - ~TimerNest() { - State::instance().pop(); - } - operator long() const { return stack_.size(); } - operator CallStack() const { return stack_; } -}; - -class TimerLog { -private: - class State { - private: - std::ostream* channel_; - - State() { - channel_ = &atlas::Library::instance().timer().channel(); - } - - public: - - static eckit::Channel& empty_channel() { - static eckit::Channel channel; - return channel; - } - - static State& instance() { - static State channel; - return channel; - } - - operator std::ostream&() { return *channel_; } - operator std::ostream*() { return channel_; } - - void set( std::ostream& channel ) { channel_ = &channel; } - void set( bool state ) { if( state == false ) channel_ = &empty_channel(); } - }; - - std::ostream* previous_state_; - -public: - TimerLog( bool state ) : - previous_state_( State::instance() ) { - State::instance().set( state ); - } - TimerLog( std::ostream& channel ) : - previous_state_( State::instance() ) { - State::instance().set( channel ); - } - ~TimerLog() { - State::instance().set( *previous_state_ ); - } - static std::ostream& channel() { return State::instance(); } -}; - -class TimerReport { - using Timing = eckit::Timing; -private: - class Registry { - private: - - std::vector counts_; - std::vector tot_timings_; - std::vector min_timings_; - std::vector max_timings_; - std::vector titles_; - std::vector locations_; - std::vector nest_; - std::vector stack_; - std::map index_; - - Registry() { - } - - public: - - static Registry& instance() { - static Registry registry; - return registry; - } - - size_t add( const CallStack& stack, const std::string& title ) { - std::stringstream ss; ss << stack; - std::string key = ss.str(); - auto it = index_.find( key ); - if( it == index_.end() ) { - size_t idx = size(); - index_[key] = idx; - counts_.emplace_back( 0 ); - tot_timings_.emplace_back( 0 ); - min_timings_.emplace_back( 0 ); - max_timings_.emplace_back( 0 ); - titles_.emplace_back( title ); - locations_.emplace_back( stack.front() ); - nest_.emplace_back( stack.size() ); - stack_.emplace_back( stack ); - return idx; - } - else { - return it->second; - } - } - - void update( size_t idx, eckit::Timer& timer ) { - double time = timer.elapsed(); - counts_[idx] += 1; - tot_timings_[idx] += time; - min_timings_[idx] = counts_[idx] == 1 ? time : std::min( time, min_timings_[idx] ); - max_timings_[idx] = counts_[idx] == 1 ? time : std::max( time, max_timings_[idx] ); - } - - size_t size() const { return counts_.size(); } - - void report( std::ostream& out, const eckit::Configuration& config ) { - long indent = config.getLong("indent",4); - long max_nest = config.getLong("depth",0); - long decimals = config.getLong("decimals",5); - - auto digits_before_decimal = [](double x) -> int { - return std::floor(std::log10(std::trunc( std::max(1.,x)) ) )+1; - }; - auto digits = [](long x) -> long { - return std::floor(std::log10( std::max(1l,x) ) )+1l; - }; - - size_t max_title_length(0); - long max_count(0); - double max_seconds(0); - for( size_t j=0; j std::string { - std::stringstream out; - char unit = 's'; - if( std::floor(x) >= 60 ) { - x/=60.; - unit = 'm'; - } - out << std::right - << std::fixed - << std::setprecision(decimals) - << std::setw(max_digits_before_decimal+decimals+1) - << x << unit; - return out.str(); - }; - - - for( size_t j=0; j { -public: - using TimerT::TimerT; -}; - -} // namespace atlas +//----------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/runtime/timer/TimerBarriers.cc b/src/atlas/runtime/timer/TimerBarriers.cc new file mode 100644 index 000000000..36a352f21 --- /dev/null +++ b/src/atlas/runtime/timer/TimerBarriers.cc @@ -0,0 +1,22 @@ +/* + * (C) Copyright 1996-2017 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 "TimerBarriers.h" + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + +} // namespace timer +} // namespace runtime +} // namespace atlas + diff --git a/src/atlas/runtime/timer/TimerBarriers.h b/src/atlas/runtime/timer/TimerBarriers.h new file mode 100644 index 000000000..7e3bd67ec --- /dev/null +++ b/src/atlas/runtime/timer/TimerBarriers.h @@ -0,0 +1,68 @@ +/* + * (C) Copyright 1996-2017 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/library/Library.h" +#include "atlas/parallel/mpi/mpi.h" + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + +class TimerBarriers { +private: + class State { + private: + State() { + barriers_ = atlas::Library::instance().timer().barriers(); + } + bool barriers_; + public: + State(State const&) = delete; + void operator=(State const&) = delete; + static State& instance() { + static State state; + return state; + } + operator bool() const { + return barriers_; + } + void set( bool state ) { + barriers_ = state; + } + }; + + bool previous_state_; + +public: + TimerBarriers(bool state) : + previous_state_( State::instance() ) { + State::instance().set(state); + } + ~TimerBarriers() { + restore(); + } + void restore() { + State::instance().set( previous_state_ ); + } + static bool state() { return State::instance(); } + static void execute() { + if( state() ) + parallel::mpi::comm().barrier(); + } +}; + +} // namespace timer +} // namespace runtime +} // namespace atlas + diff --git a/src/atlas/runtime/timer/TimerLogging.cc b/src/atlas/runtime/timer/TimerLogging.cc new file mode 100644 index 000000000..b243fd648 --- /dev/null +++ b/src/atlas/runtime/timer/TimerLogging.cc @@ -0,0 +1,23 @@ +/* + * (C) Copyright 1996-2017 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 "TimerLogging.h" + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + + +} // namespace timer +} // namespace runtime +} // namespace atlas + diff --git a/src/atlas/runtime/timer/TimerLogging.h b/src/atlas/runtime/timer/TimerLogging.h new file mode 100644 index 000000000..44f786b99 --- /dev/null +++ b/src/atlas/runtime/timer/TimerLogging.h @@ -0,0 +1,73 @@ +/* + * (C) Copyright 1996-2017 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 +#include "eckit/log/Channel.h" +#include "atlas/library/Library.h" + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + + +class TimerLogging { +private: + class State { + private: + std::ostream* channel_; + + State() { + channel_ = &atlas::Library::instance().timer().channel(); + } + + public: + + static eckit::Channel& empty_channel() { + static eckit::Channel channel; + return channel; + } + + static State& instance() { + static State channel; + return channel; + } + + operator std::ostream&() { return *channel_; } + operator std::ostream*() { return channel_; } + + void set( std::ostream& channel ) { channel_ = &channel; } + void set( bool state ) { if( state == false ) channel_ = &empty_channel(); } + }; + + std::ostream* previous_state_; + +public: + TimerLogging( bool state ) : + previous_state_( State::instance() ) { + State::instance().set( state ); + } + TimerLogging( std::ostream& channel ) : + previous_state_( State::instance() ) { + State::instance().set( channel ); + } + ~TimerLogging() { + State::instance().set( *previous_state_ ); + } + static std::ostream& channel() { return State::instance(); } +}; + +} // namespace timer +} // namespace runtime +} // namespace atlas + diff --git a/src/atlas/runtime/timer/TimerNesting.cc b/src/atlas/runtime/timer/TimerNesting.cc new file mode 100644 index 000000000..713cc7b1b --- /dev/null +++ b/src/atlas/runtime/timer/TimerNesting.cc @@ -0,0 +1,22 @@ +/* + * (C) Copyright 1996-2017 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 "TimerNesting.h" + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + +} // namespace timer +} // namespace runtime +} // namespace atlas + diff --git a/src/atlas/runtime/timer/TimerNesting.h b/src/atlas/runtime/timer/TimerNesting.h new file mode 100644 index 000000000..7b7ba9d54 --- /dev/null +++ b/src/atlas/runtime/timer/TimerNesting.h @@ -0,0 +1,67 @@ +/* + * (C) Copyright 1996-2017 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/util/detail/CallStack.h" + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + + +class TimerNesting { +private: + using CallStack = util::detail::CallStack; + class State { + private: + State() {} + CallStack stack_; + public: + State(State const&) = delete; + void operator=(State const&) = delete; + static State& instance() { + static State state; + return state; + } + operator CallStack() const { + return stack_; + } + CallStack& push( const eckit::CodeLocation& loc ) { + stack_.push_front(loc); + return stack_; + } + CallStack& pop() { + stack_.pop_front(); + return stack_; + } + }; + + long depth_; + CallStack stack_; + +public: + TimerNesting( const eckit::CodeLocation& loc ) : + stack_( State::instance().push( loc ) ) { + } + ~TimerNesting() { + State::instance().pop(); + } + operator long() const { return stack_.size(); } + operator CallStack() const { return stack_; } +}; + + +} // namespace timer +} // namespace runtime +} // namespace atlas + diff --git a/src/atlas/runtime/timer/TimerT.h b/src/atlas/runtime/timer/TimerT.h new file mode 100644 index 000000000..ab148b1d8 --- /dev/null +++ b/src/atlas/runtime/timer/TimerT.h @@ -0,0 +1,166 @@ +/* + * (C) Copyright 1996-2017 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 +#include +#include "eckit/log/Timer.h" + +//----------------------------------------------------------------------------------------------------------- + +namespace eckit { + class CodeLocation; + class Configuration; +} + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + +//----------------------------------------------------------------------------------------------------------- + +template< typename TimerTraits > +class TimerT { +public: + using Barriers = typename TimerTraits::Barriers; + using Logging = typename TimerTraits::Logging; + +public: // static methods + + static std::string report(); + static std::string report( const eckit::Configuration& config ); + +public: + + TimerT( const eckit::CodeLocation&, const std::string& msg, std::ostream& out = Logging::channel() ); + TimerT( const eckit::CodeLocation&, std::ostream& out = Logging::channel() ); + + ~TimerT(); + + bool running() const; + + void start(); + + void stop(); + + double elapsed() const; + +private: // types + + using Nesting = typename TimerTraits::Nesting; + using Timings = typename TimerTraits::Timings; + using Identifier = typename Timings::Identifier; + +private: // member functions + + void barrier() const; + + void updateTimings() const; + + void registerTimer(); + +private: // member data + + mutable eckit::Timer timer_; + eckit::CodeLocation loc_; + std::ostream& out_; + std::string msg_; + Identifier id_; + Nesting nesting_; +}; + +//----------------------------------------------------------------------------------------------------------- +// Definitions + +template< typename TimerTraits > +inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& msg, std::ostream& out ) : + loc_(loc), + out_(out), + msg_(msg), + nesting_(loc) { + start(); +} + +template< typename TimerTraits > +inline TimerT::TimerT( const eckit::CodeLocation& loc, std::ostream& out ) : + loc_(loc), + out_(out), + msg_( loc_ ? loc_.func() : "" ), + nesting_(loc_) { + start(); +} + +template< typename TimerTraits > +inline TimerT::~TimerT() { + stop(); +} + +template< typename TimerTraits > +inline void TimerT::barrier() const { + Barriers::execute(); +} + +template< typename TimerTraits > +inline void TimerT::registerTimer() { + id_ = Timings::add( nesting_, msg_ ); +} + +template< typename TimerTraits > +inline void TimerT::updateTimings() const { + Timings::update( id_, timer_.elapsed() ); +} + +template< typename TimerTraits > +inline bool TimerT::running() const { + return timer_.running(); +} + +template< typename TimerTraits > +inline void TimerT::start() { + timer_.stop(); + registerTimer(); + out_ << msg_ << " ..." << std::endl; + barrier(); + timer_.start(); +} + +template< typename TimerTraits > +inline void TimerT::stop() { + if( running() ) { + barrier(); + timer_.stop(); + updateTimings(); + out_ << msg_ << " ... done : " << timer_.elapsed() << "s" << std::endl; + } +} + +template< typename TimerTraits > +inline double TimerT::elapsed() const { + return timer_.elapsed(); +} + +template< typename TimerTraits > +inline std::string TimerT::report() { + return Timings::report(); +} + +template< typename TimerTraits > +inline std::string TimerT::report( const eckit::Configuration& config ) { + return Timings::report(config); +} + +//----------------------------------------------------------------------------------------------------------- + +} // timer +} // runtime +} // atlas diff --git a/src/atlas/runtime/timer/Timings.cc b/src/atlas/runtime/timer/Timings.cc new file mode 100644 index 000000000..ca52989f0 --- /dev/null +++ b/src/atlas/runtime/timer/Timings.cc @@ -0,0 +1,219 @@ +/* + * (C) Copyright 1996-2017 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 "Timings.h" +#include "eckit/config/Configuration.h" +#include "atlas/util/detail/CallStack.h" +#include "atlas/util/Config.h" + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + +class TimingsRegistry { + + using CallStack = Timings::CallStack; + +private: + + std::vector counts_; + std::vector tot_timings_; + std::vector min_timings_; + std::vector max_timings_; + std::vector titles_; + std::vector locations_; + std::vector nest_; + std::vector stack_; + std::map index_; + + TimingsRegistry() { + } + +public: + + static TimingsRegistry& instance() { + static TimingsRegistry registry; + return registry; + } + + size_t add( const CallStack& stack, const std::string& title ); + + void update( size_t idx, double seconds ); + + size_t size() const; + + void report( std::ostream& out, const eckit::Configuration& config ); +private: + std::string prefix( long indent, long nest ) const; + std::string filter_filepath( const std::string& filepath ) const; + + +}; + +size_t TimingsRegistry::add( const CallStack& stack, const std::string& title ) { + std::stringstream ss; ss << stack; + std::string key = ss.str(); + auto it = index_.find( key ); + if( it == index_.end() ) { + size_t idx = size(); + index_[key] = idx; + counts_.emplace_back( 0 ); + tot_timings_.emplace_back( 0 ); + min_timings_.emplace_back( 0 ); + max_timings_.emplace_back( 0 ); + titles_.emplace_back( title ); + locations_.emplace_back( stack.front() ); + nest_.emplace_back( stack.size() ); + stack_.emplace_back( stack ); + return idx; + } + else { + return it->second; + } +} + +void TimingsRegistry::update( size_t idx, double seconds ) { + counts_[idx] += 1; + tot_timings_[idx] += seconds; + min_timings_[idx] = counts_[idx] == 1 ? seconds : std::min( seconds, min_timings_[idx] ); + max_timings_[idx] = counts_[idx] == 1 ? seconds : std::max( seconds, max_timings_[idx] ); +} + +size_t TimingsRegistry::size() const { return counts_.size(); } + +void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& config ) { + long indent = config.getLong("indent",4); + long max_nest = config.getLong("depth",0); + long decimals = config.getLong("decimals",5); + + auto digits_before_decimal = [](double x) -> int { + return std::floor(std::log10(std::trunc( std::max(1.,x)) ) )+1; + }; + auto digits = [](long x) -> long { + return std::floor(std::log10( std::max(1l,x) ) )+1l; + }; + + size_t max_title_length(0); + long max_count(0); + double max_seconds(0); + for( size_t j=0; j std::string { + std::stringstream out; + char unit = 's'; + if( std::floor(x) >= 60 ) { + x/=60.; + unit = 'm'; + } + out << std::right + << std::fixed + << std::setprecision(decimals) + << std::setw(max_digits_before_decimal+decimals+1) + << x << unit; + return out.str(); + }; + + + for( size_t j=0; j + +#include "CallStack.h" + +namespace atlas { +namespace util { +namespace detail { + +void CallStack::print(std::ostream& out) const { + const_iterator it = begin(); + out << "\nstack:\n"; + for( size_t i=0; ifile() << " +"<< it->line() << '\n'; + } + out << "\n"; + out << std::flush; +} + +} // namespace detail +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/detail/CallStack.h b/src/atlas/util/detail/CallStack.h new file mode 100644 index 000000000..74a366daf --- /dev/null +++ b/src/atlas/util/detail/CallStack.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include "eckit/log/CodeLocation.h" + +namespace atlas { +namespace util { +namespace detail { + +/// @class CallStack +/// Instances of CallStack can keep track of nested eckit::CodeLocations +class CallStack: public std::list< eckit::CodeLocation > { +private: + + using Base = std::list< eckit::CodeLocation >; + +public: + + // Enable constructors from base class + using Base::Base; + +private: + + void print(std::ostream& out) const; + + friend std::ostream& operator<< ( std::ostream& out, const CallStack& p ) { + p.print(out); + return out; + } + +}; + +} // namespace detail +} // namespace util +} // namespace atlas diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc index fbe14d8e9..2e1a4d0b5 100644 --- a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -20,13 +20,13 @@ #include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" -#include "eckit/log/Timer.h" #include "atlas/grid.h" #include "atlas/meshgenerator.h" #include "atlas/mesh.h" #include "atlas/runtime/AtlasTool.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Timer.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/util/Config.h" #include "atlas/output/detail/GmshIO.h" @@ -39,39 +39,6 @@ using namespace atlas::grid; using atlas::util::Config; using eckit::PathName; -struct ATLAS_TIME();Stats -{ - ATLAS_TIME();Stats(const std::string& _name = "ATLAS_TIME();") - { - max = -1; - min = -1; - avg = 0; - cnt = 0; - name = _name; - } - void update(eckit::ATLAS_TIME();& ATLAS_TIME();) - { - double t = timer.elapsed(); - 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); - ++cnt; - } - std::string str() - { - std::stringstream stream; - stream << name << ": min, max, avg -- " << min << ", " << max << ", " << avg; - return stream.str(); - } - std::string name; - double max; - double min; - double avg; - int cnt; -}; - //------------------------------------------------------------------------------ class Tool : public AtlasTool { @@ -145,22 +112,13 @@ void Tool::execute(const Args& args) size_t iterations = 10; parallel::mpi::comm().barrier(); - ATLAS_TIME();Stats timer_stats; for( size_t i=0; i Date: Mon, 9 Oct 2017 14:49:20 +0100 Subject: [PATCH 022/355] ATLAS-132 Timers with labels, barriers for MPI only --- src/apps/atlas-benchmark.cc | 32 ++- src/atlas/functionspace/NodeColumns.cc | 77 ++++-- src/atlas/library/Library.cc | 10 +- src/atlas/mesh/actions/BuildDualMesh.cc | 9 +- src/atlas/mesh/actions/BuildEdges.cc | 45 +--- src/atlas/mesh/actions/BuildHalo.cc | 13 +- src/atlas/mesh/actions/BuildParallelFields.cc | 62 ++++- .../mesh/actions/BuildPeriodicBoundaries.cc | 24 +- .../mesh/actions/WriteLoadBalanceReport.cc | 9 +- src/atlas/meshgenerator/MeshGenerator.cc | 5 +- src/atlas/parallel/GatherScatter.cc | 9 +- src/atlas/parallel/GatherScatter.h | 10 +- src/atlas/parallel/HaloExchange.cc | 17 +- src/atlas/parallel/HaloExchange.h | 46 +++- src/atlas/parallel/mpi/Statistics.h | 100 ++++++++ src/atlas/parallel/mpi/mpi.h | 1 + src/atlas/runtime/AtlasTool.h | 4 +- src/atlas/runtime/Timer.h | 17 +- src/atlas/runtime/timer/StopWatch.h | 45 ++++ src/atlas/runtime/timer/TimerBarriers.cc | 78 ++++++ src/atlas/runtime/timer/TimerBarriers.h | 64 ++--- src/atlas/runtime/timer/TimerLogging.cc | 53 ++++ src/atlas/runtime/timer/TimerLogging.h | 58 ++--- src/atlas/runtime/timer/TimerNesting.cc | 47 ++++ src/atlas/runtime/timer/TimerNesting.h | 44 +--- src/atlas/runtime/timer/TimerT.h | 85 ++++-- src/atlas/runtime/timer/Timings.cc | 241 +++++++++++++++--- src/atlas/runtime/timer/Timings.h | 6 +- src/atlas/util/Config.h | 10 + src/atlas/util/Metadata.cc | 22 +- .../atlas-benchmark-build-halo.cc | 1 - .../atlas-benchmark-sorting.cc | 26 +- src/tests/mesh/test_distmesh.cc | 6 +- src/tests/mesh/test_halo.cc | 7 +- 34 files changed, 953 insertions(+), 330 deletions(-) create mode 100644 src/atlas/parallel/mpi/Statistics.h create mode 100644 src/atlas/runtime/timer/StopWatch.h diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index b92c282ed..05bc11624 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -145,6 +145,7 @@ class AtlasBenchmark: public AtlasTool { add_option( new SimpleOption("progress","Show progress bar instead of intermediate timings") ); add_option( new SimpleOption("output","Write output in gmsh format") ); add_option( new SimpleOption("exclude","Exclude number of iterations in statistics (default=1)") ); + add_option( new SimpleOption("details","Show detailed timers (default=false)") ); } void setup(); @@ -189,7 +190,8 @@ class AtlasBenchmark: public AtlasTool { void AtlasBenchmark::execute(const Args& args) { - Timer::Logging set_channel( Log::info() ); + Timer timer( Here(),"atlas-benchmark"); + // Timer::Logging set_channel( Log::info() ); nlev = 137; args.get("nlev",nlev); @@ -225,9 +227,10 @@ void AtlasBenchmark::execute(const Args& args) Log::info() << " OpenMP threads per MPI task: " << omp_get_max_threads() << endl; Log::info() << endl; + Log::info() << "Timings:" << endl; - ATLAS_TIME_SCOPE("setup") { setup(); } + ATLAS_TIME_SCOPE("setup",{"atlas-benchmark-setup"}) { setup(); } Log::info() << " Executing " << niter << " iterations: \n"; if( progress ) @@ -255,6 +258,7 @@ void AtlasBenchmark::execute(const Args& args) } iteration(); } + timer.stop(); Log::info() << "Iteration timer Statistics:\n" @@ -267,6 +271,15 @@ void AtlasBenchmark::execute(const Args& args) << " avg: " << setprecision(5) << fixed << haloexchange_timer.avg << " ( "<< setprecision(2) << haloexchange_timer.avg/iteration_timer.avg*100. << "% )" << endl; + util::Config report_config; + report_config.set("indent",4); + 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; Log::info() << "Results:" << endl; @@ -280,8 +293,6 @@ void AtlasBenchmark::execute(const Args& args) void AtlasBenchmark::setup() { - Timer::Logging set_channel( Log::debug() ); - size_t halo = 1; StructuredGrid grid; @@ -372,7 +383,7 @@ void AtlasBenchmark::setup() void AtlasBenchmark::iteration() { Timer t( Here() ); - + Timer compute( Here(), "compute" ); unique_ptr avgS_arr( array::Array::create(nedges,nlev,2ul) ); const auto& node2edge = mesh.nodes().edge_connectivity(); const auto& edge2node = mesh.edges().node_connectivity(); @@ -451,6 +462,7 @@ void AtlasBenchmark::iteration() if( nlev == 1 ) grad(jnode,0,ZZ) = 0.; } + compute.stop(); // halo-exchange Timer halo( Here(), "halo-exchange"); @@ -509,10 +521,12 @@ double AtlasBenchmark::result() } } } - - parallel::mpi::comm().allReduceInPlace(maxval, eckit::mpi::max()); - parallel::mpi::comm().allReduceInPlace(minval, eckit::mpi::min()); - parallel::mpi::comm().allReduceInPlace(norm, eckit::mpi::sum()); + { + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + parallel::mpi::comm().allReduceInPlace(maxval, eckit::mpi::max()); + parallel::mpi::comm().allReduceInPlace(minval, eckit::mpi::min()); + parallel::mpi::comm().allReduceInPlace(norm, eckit::mpi::sum()); + } norm = std::sqrt(norm); diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 09210e407..efc56be3a 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -582,7 +582,10 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, size_t& local_sum += arr(n,l); } } - parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); + { + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); + } N = fs.nb_nodes_global() * arr.shape(1); } @@ -658,7 +661,10 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& re } } - parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); + { + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); + } N = fs.nb_nodes_global() * arr.shape(1); } @@ -758,7 +764,10 @@ void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& s } } } - parallel::mpi::comm().allReduceInPlace(sum_per_level.data(), sum.size(), eckit::mpi::sum()); + { + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + parallel::mpi::comm().allReduceInPlace(sum_per_level.data(), sum.size(), eckit::mpi::sum()); + } N = fs.nb_nodes_global(); } @@ -790,7 +799,11 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs , const Field& fie fs.gather(field,global); result = std::accumulate(array::make_storageview(global).data(), array::make_storageview(global).data()+global.size(),0.); - parallel::mpi::comm().broadcast(&result, 1, root); + + { + parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + parallel::mpi::comm().broadcast(&result, 1, root); + } N = fs.nb_nodes_global(); } @@ -875,7 +888,10 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& fiel } } size_t root = global.metadata().get("owner"); - parallel::mpi::comm().broadcast(result,root); + { + parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + parallel::mpi::comm().broadcast(result,root); + } N = fs.nb_nodes_global(); } @@ -983,7 +999,10 @@ void dispatch_order_independent_sum_per_level( const NodeColumns& fs, const Fiel } } } - parallel::mpi::comm().broadcast( array::make_storageview(sumfield).data(),sumfield.size(),root); + { + parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + parallel::mpi::comm().broadcast( array::make_storageview(sumfield).data(),sumfield.size(),root); + } N = fs.nb_nodes_global(); } @@ -1032,7 +1051,10 @@ void dispatch_minimum( const NodeColumns& fs, const Field& field, std::vector } } - parallel::mpi::comm().allReduce(local_minimum, min, eckit::mpi::min()); + { + parallel::mpi::comm().allReduce(local_minimum, min, eckit::mpi::min()); + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + } } template< typename T > @@ -1099,7 +1121,10 @@ void dispatch_maximum( const NodeColumns& fs, const Field& field, std::vector } } } - parallel::mpi::comm().allReduce(local_maximum, max, eckit::mpi::max()); + { + parallel::mpi::comm().allReduce(local_maximum, max, eckit::mpi::max()); + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + } } template< typename T > @@ -1204,7 +1229,10 @@ void dispatch_minimum_per_level( const NodeColumns& fs, const Field& field, Fiel } } } - parallel::mpi::comm().allReduceInPlace(min.data(),min_field.size(),eckit::mpi::min()); + { + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + parallel::mpi::comm().allReduceInPlace(min.data(),min_field.size(),eckit::mpi::min()); + } } void minimum_per_level( const NodeColumns& fs, const Field& field, Field& min ) @@ -1274,7 +1302,10 @@ void dispatch_maximum_per_level( const NodeColumns& fs, const Field& field, Fiel } } } - parallel::mpi::comm().allReduceInPlace(max.data(),max_field.size(),eckit::mpi::max()); + { + parallel::mpi::comm().allReduceInPlace(max.data(),max_field.size(),eckit::mpi::max()); + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + } } void maximum_per_level( const NodeColumns& fs, const Field& field, Field& max ) @@ -1349,9 +1380,12 @@ void dispatch_minimum_and_location( const NodeColumns& fs, const Field& field, s min_and_gidx_loc[j] = std::make_pair(local_minimum[j],glb_idx); min_and_level_loc[j] = std::make_pair(local_minimum[j],loc_level[j]); } - - parallel::mpi::comm().allReduce(min_and_gidx_loc, min_and_gidx_glb, eckit::mpi::minloc()); - parallel::mpi::comm().allReduce(min_and_level_loc,min_and_level_glb,eckit::mpi::minloc()); + + { + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + parallel::mpi::comm().allReduce(min_and_gidx_loc, min_and_gidx_glb, eckit::mpi::minloc()); + parallel::mpi::comm().allReduce(min_and_level_loc,min_and_level_glb,eckit::mpi::minloc()); + } for( size_t j=0; j(); @@ -114,8 +114,8 @@ void Library::initialise(const eckit::Parametrisation& config) { out << " size [" << parallel::mpi::comm().size() << "] \n"; out << " rank [" << parallel::mpi::comm().rank() << "] \n"; out << " \n"; - out << " ATLAS_TIME();S\n"; - out << " barrier [" << str(timer_.barriers()) << "] \n"; + out << " Timer\n"; + out << " barriers [" << str(timer_.barriers()) << "] \n"; out << " \n"; out << atlas::Library::instance().info(); out << std::flush; @@ -124,8 +124,8 @@ void Library::initialise(const eckit::Parametrisation& config) { void Library::initialise() { util::Config timer_config; - if (::getenv("ATLAS_TIME_BARRIERS")) { - bool var = eckit::Translator()(::getenv("ATLAS_TIME_BARRIERS")); + if (::getenv("ATLAS_TIMER_BARRIERS")) { + bool var = eckit::Translator()(::getenv("ATLAS_TIMER_BARRIERS")); timer_config.set("barriers",var); } diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index 683a648af..a37c39ae0 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -59,9 +59,12 @@ void global_bounding_box( const mesh::Nodes& nodes, double min[2], double max[2] max[XX] = std::max( max[XX], xy(node,XX) ); max[YY] = std::max( max[YY], xy(node,YY) ); } - - parallel::mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); - parallel::mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); + + { + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + parallel::mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); + parallel::mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); + } } struct Node diff --git a/src/atlas/mesh/actions/BuildEdges.cc b/src/atlas/mesh/actions/BuildEdges.cc index 6da02da83..61f4c4798 100644 --- a/src/atlas/mesh/actions/BuildEdges.cc +++ b/src/atlas/mesh/actions/BuildEdges.cc @@ -212,8 +212,11 @@ void accumulate_pole_edges( mesh::Nodes& nodes, std::vector& pole_edge_no max[YY] = std::max( max[YY], xy(node,YY) ); } - parallel::mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); - parallel::mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); + { + parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + parallel::mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); + parallel::mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); + } double tol = 1e-6; @@ -368,44 +371,6 @@ void build_edges( Mesh& mesh ) edge_to_elem_data[edge*2+0] = e2; edge_to_elem_data[edge*2+1] = e1; } - // if( e2 == cell_nodes.missing_value() || - // compute_uid(cell_nodes.row(e1)) > compute_uid(cell_nodes.row(e2)) ) - // { - // // BOOST_CHECK_EQUAL( edge_to_cell_check[2*jedge+0] , edge_cell_connectivity(jedge,0) ); - // // BOOST_CHECK_EQUAL( edge_to_cell_check[2*jedge+1] , edge_cell_connectivity(jedge,1) ); - // } - // else - // { - // edge_to_elem_data[edge*2+0] = e2; - // edge_to_elem_data[edge*2+1] = e1; - // - // // BOOST_CHECK_EQUAL( edge_to_cell_check[2*jedge+0] , edge_cell_connectivity(jedge,1) ); - // // BOOST_CHECK_EQUAL( edge_to_cell_check[2*jedge+1] , edge_cell_connectivity(jedge,0) ); - // } - - - // if( e1 == cell_nodes.missing_value() && e2 != cell_nodes.missing_value() ) - // { - // edge_to_elem_data[edge*2+0] = e2; - // edge_to_elem_data[edge*2+1] = e1; - // } - // else if( (e1 != cell_nodes.missing_value() && e2 != cell_nodes.missing_value() ) && - // (compute_uid(cell_nodes.row(e1)) > compute_uid(cell_nodes.row(e2)) ) ) - // { - // // Swap order to ensure bit-reproducibility - // edge_to_elem_data[edge*2+0] = e2; - // edge_to_elem_data[edge*2+1] = e1; - // } - - // if( e2 != cell_nodes.missing_value() ) - // { - // // Swap order to ensure bit-reproducibility - // if( compute_uid(cell_nodes.row(e1)) > compute_uid(cell_nodes.row(e2)) ) - // { - // edge_to_elem_data[edge*2+0] = e2; - // edge_to_elem_data[edge*2+1] = e1; - // } - // } } mesh.edges().cell_connectivity().add( nb_edges, 2, edge_to_elem_data.data() ); diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 77d5b5027..29606439f 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -44,7 +44,7 @@ #include "atlas/mesh/actions/BuildXYZField.h" #endif -// #define ATLAS_103 +#define ATLAS_103 // #define ATLAS_103_SORT #ifndef ATLAS_103 @@ -820,8 +820,10 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector #ifndef ATLAS_103 /* deprecated */ ATLAS_TIME( "gather_bdry_nodes old way" ); - - parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); + { + parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); + parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); + } #else ATLAS_TIME(); Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); @@ -911,7 +913,6 @@ void increase_halo_interior( BuildHaloHelper& helper ) gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts ); - Timer::Barriers timer_barriers(false); #ifndef ATLAS_103 /* deprecated */ @@ -940,8 +941,6 @@ void increase_halo_interior( BuildHaloHelper& helper ) helper.fill_sendbuffer(sendmesh, found_bdry_nodes_uid, found_bdry_elems, jpart); } - timer_barriers.restore(); - // 5) Now communicate all buffers helper.all_to_all(sendmesh, recvmesh); @@ -1020,8 +1019,6 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts, /* periodic = */ true ); - Timer::Barriers set_barrier(false); - #ifndef ATLAS_103 /* deprecated */ for (size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index ce1eb037e..e850ab45c 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -181,7 +181,10 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + { + parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + } recvdispls[0]=0; for (int jpart=1; jpart glb_id_arr( glb_nb_nodes ); array::ArrayView glb_id = array::make_view(glb_id_arr); - parallel::mpi::comm().gatherv(loc_id.data(), loc_id.size(), glb_id.data(), recvcounts.data(), recvdispls.data(), root); + { + parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + parallel::mpi::comm().gatherv(loc_id.data(), loc_id.size(), glb_id.data(), recvcounts.data(), recvdispls.data(), root); + } // 2) Sort all global indices, and renumber from 1 to glb_nb_edges std::vector node_sort; node_sort.reserve(glb_nb_nodes); for( size_t jnode=0; jnode > send_found( parallel::mpi::comm().size() ); std::vector< std::vector > recv_found( parallel::mpi::comm().size() ); @@ -312,7 +323,10 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) } } - parallel::mpi::comm().allToAll(send_found, recv_found); + { + parallel::mpi::Statistics stats( Here(), "allToAll", parallel::mpi::Collective::ALLTOALL ); + parallel::mpi::comm().allToAll(send_found, recv_found); + } for( size_t jpart=0; jpart > send_found( parallel::mpi::comm().size() ); std::vector< std::vector > recv_found( parallel::mpi::comm().size() ); @@ -750,7 +773,10 @@ Field& build_edges_remote_idx( Mesh& mesh ) } } } - parallel::mpi::comm().allToAll(send_found, recv_found); + { + parallel::mpi::Statistics stats( Here(), "allToAll", parallel::mpi::Collective::ALLTOALL ); + parallel::mpi::comm().allToAll(send_found, recv_found); + } for( size_t jpart=0; jpart& recv_edge = recv_found[jpart]; @@ -829,7 +855,10 @@ Field& build_edges_global_idx( Mesh& mesh ) std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - parallel::mpi::comm().gather(nb_edges, recvcounts, root); + { + parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + parallel::mpi::comm().gather(nb_edges, recvcounts, root); + } recvdispls[0]=0; for (int jpart=1; jpart glb_edge_id_arr(glb_nb_edges); array::ArrayView glb_edge_id = array::make_view(glb_edge_id_arr); - parallel::mpi::comm().gatherv(loc_edge_id.data(), loc_edge_id.size(), glb_edge_id.data(), recvcounts.data(), recvdispls.data(), root); + { + parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + parallel::mpi::comm().gatherv(loc_edge_id.data(), loc_edge_id.size(), glb_edge_id.data(), recvcounts.data(), recvdispls.data(), root); + } // 2) Sort all global indices, and renumber from 1 to glb_nb_edges std::vector edge_sort; edge_sort.reserve(glb_nb_edges); for( size_t jedge=0; jedge recvcounts( parallel::mpi::comm().size() ); - parallel::mpi::comm().allGather(sendcnt, recvcounts.begin(), recvcounts.end()); + { + parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); + parallel::mpi::comm().allGather(sendcnt, recvcounts.begin(), recvcounts.end()); + } std::vector recvdispls( parallel::mpi::comm().size() ); recvdispls[0] = 0; @@ -114,7 +118,10 @@ void build_periodic_boundaries( Mesh& mesh ) } std::vector recvbuf(recvcnt); - parallel::mpi::comm().allGatherv(slave_nodes.begin(), slave_nodes.end(), recvbuf.begin(), recvcounts.data(), recvdispls.data()); + { + parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); + parallel::mpi::comm().allGatherv(slave_nodes.begin(), slave_nodes.end(), recvbuf.begin(), recvcounts.data(), recvdispls.data()); + } PeriodicTransform transform; for( size_t jproc=0; jproc elem_counts( parallel::mpi::comm().size() ); std::vector elem_displs( parallel::mpi::comm().size() ); - parallel::mpi::comm().allGather(loc_nb_elems, elem_counts.begin(), elem_counts.end()); + { + parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); + parallel::mpi::comm().allGather(loc_nb_elems, elem_counts.begin(), elem_counts.end()); + } elem_displs.at(0) = 0; for(size_t jpart = 1; jpart < parallel::mpi::comm().size(); ++jpart) diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index baf10fbe2..c9e777705 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -17,6 +17,7 @@ #include "atlas/runtime/Log.h" #include "atlas/runtime/Timer.h" #include "atlas/parallel/GatherScatter.h" +#include "atlas/parallel/mpi/Statistics.h" namespace atlas { namespace parallel { @@ -116,8 +117,8 @@ void GatherScatter::setup( const int part[], } } - ATLAS_TIME_SCOPE("allGather[ counts ]") { + parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); parallel::mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); } @@ -130,8 +131,8 @@ void GatherScatter::setup( const int part[], } std::vector recvnodes(glbcnt_); - ATLAS_TIME_SCOPE("allGatherv [glb nodes]") { + parallel::mpi::Statistics stats( Here(), "allGatherv", parallel::mpi::Collective::ALLGATHER ); parallel::mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, recvnodes.data(), glbcounts_.data(), glbdispls_.data()); } @@ -151,8 +152,8 @@ void GatherScatter::setup( const int part[], // Sort on "g" member, and remove duplicates ATLAS_TIME_SCOPE("sorting") { - std::sort(node_sort.begin(), node_sort.end()); - node_sort.erase( std::unique( node_sort.begin(), node_sort.end() ), node_sort.end() ); + std::sort(node_sort.begin(), node_sort.end()); + node_sort.erase( std::unique( node_sort.begin(), node_sort.end() ), node_sort.end() ); } glbcounts_.assign(nproc,0); glbdispls_.assign(nproc,0); diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index b82c3c617..56cea5659 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -276,7 +276,10 @@ void GatherScatter::gather( parallel::Field lfields[], /// Gather - parallel::mpi::comm().gatherv(loc_buffer, glb_buffer, glb_counts, glb_displs, root); + { + parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + parallel::mpi::comm().gatherv(loc_buffer, glb_buffer, glb_counts, glb_displs, root); + } /// Unpack if( myproc == root ) @@ -335,7 +338,10 @@ void GatherScatter::scatter( parallel::Field gfields[], /// Scatter - parallel::mpi::comm().scatterv(glb_buffer.begin(), glb_buffer.end(), glb_counts, glb_displs, loc_buffer.begin(), loc_buffer.end(), root); + { + parallel::mpi::Statistics stats( Here(), "scatter", parallel::mpi::Collective::SCATTER ); + parallel::mpi::comm().scatterv(glb_buffer.begin(), glb_buffer.end(), glb_counts, glb_displs, loc_buffer.begin(), loc_buffer.end(), root); + } /// Unpack unpack_recv_buffer(locmap_,loc_buffer.data(),lfields[jfield]); diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 190f9b173..76be750f9 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -16,6 +16,7 @@ #include #include #include "atlas/parallel/HaloExchange.h" +#include "atlas/parallel/mpi/Statistics.h" namespace atlas { namespace parallel { @@ -64,6 +65,8 @@ void HaloExchange::setup( const int part[], const int remote_idx[], const int base, const size_t parsize ) { + ATLAS_TIME("HaloExchange::setup"); + parsize_ = parsize; sendcounts_.resize(nproc); sendcounts_.assign(nproc,0); recvcounts_.resize(nproc); recvcounts_.assign(nproc,0); @@ -87,8 +90,10 @@ void HaloExchange::setup( const int part[], /* Find the amount of nodes this proc has to send to each other proc */ - - parallel::mpi::comm().allToAll(recvcounts_, sendcounts_); + { + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLTOALL ) + parallel::mpi::comm().allToAll(recvcounts_, sendcounts_); + } sendcnt_ = std::accumulate(sendcounts_.begin(),sendcounts_.end(),0); // std::cout << myproc << ": sendcnt = " << sendcnt_ << std::endl; @@ -126,9 +131,11 @@ void HaloExchange::setup( const int part[], */ std::vector recv_requests(sendcnt_); - - parallel::mpi::comm().allToAllv(send_requests.data(), recvcounts_.data(), recvdispls_.data(), - recv_requests.data(), sendcounts_.data(), senddispls_.data()); + { + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLTOALL ) + parallel::mpi::comm().allToAllv(send_requests.data(), recvcounts_.data(), recvdispls_.data(), + recv_requests.data(), sendcounts_.data(), senddispls_.data()); + } /* What needs to be sent to other procs is asked by remote_idx, which is local here diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 15da05589..38b1ba7f6 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -22,6 +22,7 @@ #include "eckit/memory/Owned.h" #include "eckit/exception/Exceptions.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/parallel/mpi/Statistics.h" #include "atlas/array/ArrayView.h" #include "atlas/runtime/Log.h" @@ -117,6 +118,8 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const throw eckit::SeriousBug("HaloExchange was not setup",Here()); } + ATLAS_TIME("HaloExchange",{"halo-exchange"}); + int tag=1; size_t var_size = std::accumulate(var_shape,var_shape+var_rank,1,std::multiplies()); int send_size = sendcnt_ * var_size; @@ -140,13 +143,15 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const recv_displs[jproc] = recvdispls_[jproc]*var_size; } - - /// Let MPI know what we like to receive - for(int jproc=0; jproc < nproc; ++jproc) + ATLAS_MPI_STATS( parallel::mpi::Collective::IRECEIVE ) { - if(recv_counts[jproc] > 0) + /// Let MPI know what we like to receive + for(int jproc=0; jproc < nproc; ++jproc) { - recv_req[jproc] = parallel::mpi::comm().iReceive(&recv_buffer[recv_displs[jproc]], recv_counts[jproc], jproc, tag); + if(recv_counts[jproc] > 0) + { + recv_req[jproc] = parallel::mpi::comm().iReceive(&recv_buffer[recv_displs[jproc]], recv_counts[jproc], jproc, tag); + } } } @@ -154,20 +159,28 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const pack_send_buffer(field,var_strides,var_shape,var_rank,send_buffer.data()); /// Send - for(int jproc=0; jproc < nproc; ++jproc) + ATLAS_MPI_STATS( parallel::mpi::Collective::ISEND ) { - if(send_counts[jproc] > 0) + for(int jproc=0; jproc < nproc; ++jproc) { - send_req[jproc] = parallel::mpi::comm().iSend(&send_buffer[send_displs[jproc]], send_counts[jproc], jproc, tag); + if(send_counts[jproc] > 0) + { + send_req[jproc] = parallel::mpi::comm().iSend( + &send_buffer[send_displs[jproc]], + send_counts[jproc], jproc, tag); + } } } /// Wait for receiving to finish - for (int jproc=0; jproc < nproc; ++jproc) + ATLAS_MPI_STATS( parallel::mpi::Collective::WAIT, "mpi-wait receive" ) { - if( recvcounts_[jproc] > 0) + for (int jproc=0; jproc < nproc; ++jproc) { - parallel::mpi::comm().wait(recv_req[jproc]); + if( recvcounts_[jproc] > 0) + { + parallel::mpi::comm().wait(recv_req[jproc]); + } } } @@ -175,11 +188,14 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const unpack_recv_buffer(recv_buffer.data(),field,var_strides,var_shape,var_rank); /// Wait for sending to finish - for (int jproc=0; jproc < nproc; ++jproc) + ATLAS_MPI_STATS( parallel::mpi::Collective::WAIT, "mpi-wait send" ) { - if( sendcounts_[jproc] > 0) + for (int jproc=0; jproc < nproc; ++jproc) { - parallel::mpi::comm().wait(send_req[jproc]); + if( sendcounts_[jproc] > 0) + { + parallel::mpi::comm().wait(send_req[jproc]); + } } } } @@ -191,6 +207,7 @@ void HaloExchange::pack_send_buffer( const DATA_TYPE field[], size_t var_rank, DATA_TYPE send_buffer[] ) const { + ATLAS_TIME(); size_t ibuf = 0; size_t send_stride = var_strides[0]*var_shape[0]; @@ -266,6 +283,7 @@ void HaloExchange::unpack_recv_buffer( const DATA_TYPE recv_buffer[], const size_t var_shape[], size_t var_rank ) const { + ATLAS_TIME(); // bool field_changed = false; // DATA_TYPE tmp; size_t ibuf = 0; diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h new file mode 100644 index 000000000..71742a33c --- /dev/null +++ b/src/atlas/parallel/mpi/Statistics.h @@ -0,0 +1,100 @@ +/* + * (C) Copyright 1996-2017 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 +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Timer.h" + +#if ATLAS_HAVE_TIMINGS + +#include "atlas/util/detail/BlackMagic.h" + +#undef ATLAS_MPI_STATS +#define ATLAS_MPI_STATS(...) ATLAS_MPI_STATS_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) + +#define ATLAS_MPI_STATS_(N, ...) __ATLAS__SPLICE( ATLAS_MPI_STATS_, N)(__VA_ARGS__) +#define ATLAS_MPI_STATS_1(Collective) \ + for( ::atlas::parallel::mpi::Statistics __ATLAS__SPLICE( stats, __LINE__ ) \ + /*args=*/(Here(), ::atlas::parallel::mpi::name(Collective), Collective);\ + __ATLAS__SPLICE( stats, __LINE__ ) .running(); \ + __ATLAS__SPLICE( stats, __LINE__ ) .stop() ) +#define ATLAS_MPI_STATS_2(Collective,title) \ + for( ::atlas::parallel::mpi::Statistics __ATLAS__SPLICE( stats, __LINE__ ) \ + /*args=*/(Here(), title, Collective);\ + __ATLAS__SPLICE( stats, __LINE__ ) .running(); \ + __ATLAS__SPLICE( stats, __LINE__ ) .stop() ) + +#endif + + +namespace atlas { +namespace parallel { +namespace mpi { + +struct CollectiveTimerTraits { + using Barriers = runtime::timer::TimerBarriers; + using Logging = runtime::timer::TimerNoLogging; + using Timings = runtime::timer::Timings; + using Nesting = runtime::timer::TimerNesting; +}; + + +enum class Collective { + BROADCAST, + ALLREDUCE, + ALLGATHER, + ALLTOALL, + REDUCE, + GATHER, + SCATTER, + BARRIER, + SENDRECEIVE, + ISEND, + IRECEIVE, + WAIT, + _COUNT_ +}; + +static const std::string& name(Collective c) { + static std::array(Collective::_COUNT_)> names { + "mpi-broadcast", + "mpi-allreduce", + "mpi-allgather", + "mpi-alltoall", + "mpi-reduce", + "mpi-gather", + "mpi-scatter", + "mpi-barrier", + "mpi-sendreceive", + "mpi-isend", + "mpi-ireceive", + "mpi-wait" + }; + return names[ static_cast(c) ]; +} + +class Statistics : public runtime::timer::TimerT< CollectiveTimerTraits > { + using Base = runtime::timer::TimerT< CollectiveTimerTraits >; +public: + Statistics( const eckit::CodeLocation& loc, const std::string& msg, Collective c ) : + Base( loc, msg, make_labels(c), Logging::channel() ) { + + } +private: + static std::vector make_labels( Collective c) { + return {"mpi", name(c)}; + } +}; + +} // namespace mpi +} // namespace parallel +} // namespace atlas diff --git a/src/atlas/parallel/mpi/mpi.h b/src/atlas/parallel/mpi/mpi.h index cc13d8732..daf65b8aa 100644 --- a/src/atlas/parallel/mpi/mpi.h +++ b/src/atlas/parallel/mpi/mpi.h @@ -11,6 +11,7 @@ #pragma once #include "eckit/mpi/Comm.h" +#include "atlas/parallel/mpi/Statistics.h" namespace atlas { namespace parallel { diff --git a/src/atlas/runtime/AtlasTool.h b/src/atlas/runtime/AtlasTool.h index fc4cca9d5..c0f406e37 100644 --- a/src/atlas/runtime/AtlasTool.h +++ b/src/atlas/runtime/AtlasTool.h @@ -13,13 +13,13 @@ #include #include -#include "atlas/library/Library.h" -#include "atlas/runtime/Log.h" #include "eckit/runtime/Tool.h" #include "eckit/option/CmdArgs.h" #include "eckit/option/SimpleOption.h" #include "eckit/option/VectorOption.h" #include "eckit/option/Separator.h" +#include "atlas/library/Library.h" +#include "atlas/runtime/Log.h" #include "atlas/parallel/mpi/mpi.h" //-------------------------------------------------------------------------------- diff --git a/src/atlas/runtime/Timer.h b/src/atlas/runtime/Timer.h index d44d2abef..f387332f5 100644 --- a/src/atlas/runtime/Timer.h +++ b/src/atlas/runtime/Timer.h @@ -59,7 +59,7 @@ namespace atlas { struct TimerTraits { - using Barriers = runtime::timer::TimerBarriers; + using Barriers = runtime::timer::TimerNoBarriers; using Logging = runtime::timer::TimerLogging; using Timings = runtime::timer::Timings; using Nesting = runtime::timer::TimerNesting; @@ -90,14 +90,19 @@ class Timer : public runtime::timer::TimerT< TimerTraits > { for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here());\ __ATLAS__SPLICE( timer, __LINE__ ) .running(); \ __ATLAS__SPLICE( timer, __LINE__ ) .stop() ) -#define ATLAS_TIME_SCOPE_1(title) \ - for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),title);\ +#define ATLAS_TIME_SCOPE_1(arg1) \ + for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),arg1);\ + __ATLAS__SPLICE( timer, __LINE__ ) .running(); \ + __ATLAS__SPLICE( timer, __LINE__ ) .stop() ) +#define ATLAS_TIME_SCOPE_2(arg1,arg2) \ + for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),arg1,arg2);\ __ATLAS__SPLICE( timer, __LINE__ ) .running(); \ __ATLAS__SPLICE( timer, __LINE__ ) .stop() ) -#define ATLAS_TIME_(N, ...) __ATLAS__SPLICE( ATLAS_TIME_, N)(__VA_ARGS__) -#define ATLAS_TIME_0() ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here()); -#define ATLAS_TIME_1(title) ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),title); +#define ATLAS_TIME_(N, ...) __ATLAS__SPLICE( ATLAS_TIME_, N)(__VA_ARGS__) +#define ATLAS_TIME_0() ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here()); +#define ATLAS_TIME_1(arg1) ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),arg1); +#define ATLAS_TIME_2(arg1,arg2) ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),arg1,arg2); #endif diff --git a/src/atlas/runtime/timer/StopWatch.h b/src/atlas/runtime/timer/StopWatch.h new file mode 100644 index 000000000..5cd5e0764 --- /dev/null +++ b/src/atlas/runtime/timer/StopWatch.h @@ -0,0 +1,45 @@ +/* + * (C) Copyright 1996-2017 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 + +namespace atlas { +namespace runtime { +namespace timer { + +//----------------------------------------------------------------------------------------------------------- + +class StopWatch { +private: + std::chrono::duration elapsed_{0}; + std::chrono::steady_clock::time_point start_; +public: + void start() { + start_ = std::chrono::steady_clock::now(); + } + void stop() { + elapsed_ += (std::chrono::steady_clock::now() - start_); + } + void reset() { + elapsed_ = std::chrono::seconds::zero(); + start_ = std::chrono::steady_clock::now(); + } + double elapsed() const { + return elapsed_.count(); + } +}; + +//----------------------------------------------------------------------------------------------------------- + +} // timer +} // runtime +} // atlas diff --git a/src/atlas/runtime/timer/TimerBarriers.cc b/src/atlas/runtime/timer/TimerBarriers.cc index 36a352f21..28dae8213 100644 --- a/src/atlas/runtime/timer/TimerBarriers.cc +++ b/src/atlas/runtime/timer/TimerBarriers.cc @@ -8,7 +8,12 @@ * does it submit to any jurisdiction. */ +#include #include "TimerBarriers.h" +#include "atlas/library/Library.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/timer/StopWatch.h" + //----------------------------------------------------------------------------------------------------------- @@ -16,6 +21,79 @@ namespace atlas { namespace runtime { namespace timer { +class TimerBarriersState { +private: + TimerBarriersState() { + barriers_ = atlas::Library::instance().timer().barriers(); + } + bool barriers_; + StopWatch stopwatch_; +public: + TimerBarriersState(TimerBarriersState const&) = delete; + void operator=(TimerBarriersState const&) = delete; + static TimerBarriersState& instance() { + static TimerBarriersState state; + return state; + } + operator bool() const { + return barriers_; + } + void set( bool state ) { + barriers_ = state; + } + StopWatch& stopwatch() { return stopwatch_; } + + 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; + } + return out.str(); + } +}; + +TimerBarriers::TimerBarriers(bool state) : + previous_state_( TimerBarriersState::instance() ) { + TimerBarriersState::instance().set(state); +} + +TimerBarriers::~TimerBarriers() { + restore(); +} + +void TimerBarriers::restore() { + TimerBarriersState::instance().set( previous_state_ ); +} + +bool TimerBarriers::state() { + return TimerBarriersState::instance(); +} + +void TimerBarriers::execute() { + if( state() ) { + TimerBarriersState::instance().stopwatch().start(); + parallel::mpi::comm().barrier(); + TimerBarriersState::instance().stopwatch().stop(); + } +} + +double TimerBarriers::time() { + return TimerBarriersState::instance().stopwatch().elapsed(); +} + +double TimerNoBarriers::time() { + return TimerBarriersState::instance().stopwatch().elapsed(); +} + +std::string TimerBarriers::report() { + return TimerBarriersState::instance().report(); +} + +std::string TimerNoBarriers::report() { + return TimerBarriersState::instance().report(); +} + } // namespace timer } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/TimerBarriers.h b/src/atlas/runtime/timer/TimerBarriers.h index 7e3bd67ec..3ffeef104 100644 --- a/src/atlas/runtime/timer/TimerBarriers.h +++ b/src/atlas/runtime/timer/TimerBarriers.h @@ -9,9 +9,7 @@ */ #pragma once - -#include "atlas/library/Library.h" -#include "atlas/parallel/mpi/mpi.h" +#include //----------------------------------------------------------------------------------------------------------- @@ -19,47 +17,31 @@ namespace atlas { namespace runtime { namespace timer { +class TimerNoBarriers { +public: + TimerNoBarriers(bool state) {} + void restore() {} + +public: // static methods + static bool state() { return false; } + static void execute() {} + static double time(); + static std::string report(); +}; + class TimerBarriers { +public: + TimerBarriers(bool state); + ~TimerBarriers(); + void restore(); + +public: // static methods + static bool state(); + static void execute(); + static double time(); + static std::string report(); private: - class State { - private: - State() { - barriers_ = atlas::Library::instance().timer().barriers(); - } - bool barriers_; - public: - State(State const&) = delete; - void operator=(State const&) = delete; - static State& instance() { - static State state; - return state; - } - operator bool() const { - return barriers_; - } - void set( bool state ) { - barriers_ = state; - } - }; - bool previous_state_; - -public: - TimerBarriers(bool state) : - previous_state_( State::instance() ) { - State::instance().set(state); - } - ~TimerBarriers() { - restore(); - } - void restore() { - State::instance().set( previous_state_ ); - } - static bool state() { return State::instance(); } - static void execute() { - if( state() ) - parallel::mpi::comm().barrier(); - } }; } // namespace timer diff --git a/src/atlas/runtime/timer/TimerLogging.cc b/src/atlas/runtime/timer/TimerLogging.cc index b243fd648..3861b1fa0 100644 --- a/src/atlas/runtime/timer/TimerLogging.cc +++ b/src/atlas/runtime/timer/TimerLogging.cc @@ -10,12 +10,65 @@ #include "TimerLogging.h" +#include +#include "eckit/log/Channel.h" +#include "atlas/library/Library.h" + //----------------------------------------------------------------------------------------------------------- namespace atlas { namespace runtime { namespace timer { +class TimerLoggingState { +private: + std::ostream* channel_; + + TimerLoggingState() { + channel_ = &atlas::Library::instance().timer().channel(); + } + +public: + + static eckit::Channel& empty_channel() { + static eckit::Channel channel; + return channel; + } + + static TimerLoggingState& instance() { + static TimerLoggingState channel; + return channel; + } + + operator std::ostream&() { return *channel_; } + operator std::ostream*() { return channel_; } + + void set( std::ostream& channel ) { channel_ = &channel; } + void set( bool state ) { if( state == false ) channel_ = &empty_channel(); } +}; + +TimerLogging::TimerLogging( bool state ) : + previous_state_( TimerLoggingState::instance() ) { + TimerLoggingState::instance().set( state ); +} + +TimerLogging::TimerLogging( std::ostream& channel ) : + previous_state_( TimerLoggingState::instance() ) { + TimerLoggingState::instance().set( channel ); +} + +TimerLogging::~TimerLogging() { + TimerLoggingState::instance().set( *previous_state_ ); +} + +std::ostream& TimerLogging::channel() { + return TimerLoggingState::instance(); +} + +std::ostream& TimerNoLogging::channel() { + return TimerLoggingState::empty_channel(); +} + } // namespace timer } // namespace runtime diff --git a/src/atlas/runtime/timer/TimerLogging.h b/src/atlas/runtime/timer/TimerLogging.h index 44f786b99..1abc1a906 100644 --- a/src/atlas/runtime/timer/TimerLogging.h +++ b/src/atlas/runtime/timer/TimerLogging.h @@ -10,9 +10,7 @@ #pragma once -#include -#include "eckit/log/Channel.h" -#include "atlas/library/Library.h" +#include //----------------------------------------------------------------------------------------------------------- @@ -20,51 +18,33 @@ namespace atlas { namespace runtime { namespace timer { +class TimerNoLogging { +public: -class TimerLogging { -private: - class State { - private: - std::ostream* channel_; + TimerNoLogging( bool state ); - State() { - channel_ = &atlas::Library::instance().timer().channel(); - } + TimerNoLogging( std::ostream& channel ); - public: +public: // static method + static std::ostream& channel(); - static eckit::Channel& empty_channel() { - static eckit::Channel channel; - return channel; - } +}; - static State& instance() { - static State channel; - return channel; - } +class TimerLogging { +public: - operator std::ostream&() { return *channel_; } - operator std::ostream*() { return channel_; } + TimerLogging( bool state ); - void set( std::ostream& channel ) { channel_ = &channel; } - void set( bool state ) { if( state == false ) channel_ = &empty_channel(); } - }; + TimerLogging( std::ostream& channel ); + + ~TimerLogging(); - std::ostream* previous_state_; +public: // static method + static std::ostream& channel(); + +private: + std::ostream* previous_state_; -public: - TimerLogging( bool state ) : - previous_state_( State::instance() ) { - State::instance().set( state ); - } - TimerLogging( std::ostream& channel ) : - previous_state_( State::instance() ) { - State::instance().set( channel ); - } - ~TimerLogging() { - State::instance().set( *previous_state_ ); - } - static std::ostream& channel() { return State::instance(); } }; } // namespace timer diff --git a/src/atlas/runtime/timer/TimerNesting.cc b/src/atlas/runtime/timer/TimerNesting.cc index 713cc7b1b..cea077671 100644 --- a/src/atlas/runtime/timer/TimerNesting.cc +++ b/src/atlas/runtime/timer/TimerNesting.cc @@ -15,6 +15,53 @@ namespace atlas { namespace runtime { namespace timer { + + +class TimerNestingState { + using CallStack = util::detail::CallStack; +private: + TimerNestingState() {} + CallStack stack_; +public: + TimerNestingState(TimerNestingState const&) = delete; + void operator=(TimerNestingState const&) = delete; + static TimerNestingState& instance() { + static TimerNestingState state; + return state; + } + operator CallStack() const { + return stack_; + } + CallStack& push( const eckit::CodeLocation& loc ) { + stack_.push_front(loc); + return stack_; + } + void pop() { + stack_.pop_front(); + } +}; + +TimerNesting::TimerNesting( const eckit::CodeLocation& loc ) : + loc_(loc), + stack_( TimerNestingState::instance().push( loc ) ) { +} + +TimerNesting::~TimerNesting() { + if( running_ ) + stop(); +} + +void TimerNesting::stop() { + if( running_ ) + TimerNestingState::instance().pop(); + running_ = false; +} + +void TimerNesting::start() { + if( not running_ ) + TimerNestingState::instance().push( loc_ ); + running_ = true; +} } // namespace timer } // namespace runtime diff --git a/src/atlas/runtime/timer/TimerNesting.h b/src/atlas/runtime/timer/TimerNesting.h index 7b7ba9d54..53c4af1f5 100644 --- a/src/atlas/runtime/timer/TimerNesting.h +++ b/src/atlas/runtime/timer/TimerNesting.h @@ -20,44 +20,18 @@ namespace timer { class TimerNesting { -private: - using CallStack = util::detail::CallStack; - class State { - private: - State() {} - CallStack stack_; - public: - State(State const&) = delete; - void operator=(State const&) = delete; - static State& instance() { - static State state; - return state; - } - operator CallStack() const { - return stack_; - } - CallStack& push( const eckit::CodeLocation& loc ) { - stack_.push_front(loc); - return stack_; - } - CallStack& pop() { - stack_.pop_front(); - return stack_; - } - }; - - long depth_; - CallStack stack_; - public: - TimerNesting( const eckit::CodeLocation& loc ) : - stack_( State::instance().push( loc ) ) { - } - ~TimerNesting() { - State::instance().pop(); - } + using CallStack = util::detail::CallStack; + TimerNesting( const eckit::CodeLocation& ); + ~TimerNesting(); operator long() const { return stack_.size(); } operator CallStack() const { return stack_; } + void stop(); + void start(); +private: + CallStack stack_; + eckit::CodeLocation loc_; + bool running_{true}; }; diff --git a/src/atlas/runtime/timer/TimerT.h b/src/atlas/runtime/timer/TimerT.h index ab148b1d8..5158c916a 100644 --- a/src/atlas/runtime/timer/TimerT.h +++ b/src/atlas/runtime/timer/TimerT.h @@ -12,7 +12,9 @@ #include #include -#include "eckit/log/Timer.h" +#include +#include +#include "atlas/runtime/timer/StopWatch.h" //----------------------------------------------------------------------------------------------------------- @@ -34,6 +36,7 @@ class TimerT { public: using Barriers = typename TimerTraits::Barriers; using Logging = typename TimerTraits::Logging; + using Labels = std::vector; public: // static methods @@ -42,9 +45,12 @@ class TimerT { public: - TimerT( const eckit::CodeLocation&, const std::string& msg, std::ostream& out = Logging::channel() ); + TimerT( const eckit::CodeLocation&, const std::string& title, std::ostream& out = Logging::channel() ); TimerT( const eckit::CodeLocation&, std::ostream& out = Logging::channel() ); + TimerT( const eckit::CodeLocation&, const std::string& title, const Labels&, std::ostream& out = Logging::channel() ); + TimerT( const eckit::CodeLocation&, const Labels&, std::ostream& out = Logging::channel() ); + ~TimerT(); bool running() const; @@ -53,6 +59,10 @@ class TimerT { void stop(); + void pause(); + + void resume(); + double elapsed() const; private: // types @@ -71,22 +81,24 @@ class TimerT { private: // member data - mutable eckit::Timer timer_; + bool running_{true}; + StopWatch stopwatch_; eckit::CodeLocation loc_; std::ostream& out_; - std::string msg_; + std::string title_; Identifier id_; Nesting nesting_; + Labels labels_; }; //----------------------------------------------------------------------------------------------------------- // Definitions template< typename TimerTraits > -inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& msg, std::ostream& out ) : +inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& title, std::ostream& out ) : loc_(loc), out_(out), - msg_(msg), + title_(title), nesting_(loc) { start(); } @@ -95,11 +107,31 @@ template< typename TimerTraits > inline TimerT::TimerT( const eckit::CodeLocation& loc, std::ostream& out ) : loc_(loc), out_(out), - msg_( loc_ ? loc_.func() : "" ), + title_( loc_ ? loc_.func() : ""), nesting_(loc_) { start(); } +template< typename TimerTraits > +inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& title, const Labels& labels, std::ostream& out ) : + loc_(loc), + out_(out), + title_(title), + nesting_(loc), + labels_(labels) { + start(); +} + +template< typename TimerTraits > +inline TimerT::TimerT( const eckit::CodeLocation& loc, const Labels& labels, std::ostream& out ) : + loc_(loc), + out_(out), + title_( loc_ ? loc_.func() : "" ), + nesting_(loc_), + labels_(labels) { + start(); +} + template< typename TimerTraits > inline TimerT::~TimerT() { stop(); @@ -112,51 +144,68 @@ inline void TimerT::barrier() const { template< typename TimerTraits > inline void TimerT::registerTimer() { - id_ = Timings::add( nesting_, msg_ ); + id_ = Timings::add( nesting_, title_ + (Barriers::state() ? " [b]" : ""), labels_ ); } template< typename TimerTraits > inline void TimerT::updateTimings() const { - Timings::update( id_, timer_.elapsed() ); + Timings::update( id_, stopwatch_.elapsed() ); } template< typename TimerTraits > inline bool TimerT::running() const { - return timer_.running(); + return running_; } template< typename TimerTraits > inline void TimerT::start() { - timer_.stop(); registerTimer(); - out_ << msg_ << " ..." << std::endl; + out_ << title_ << " ..." << std::endl; barrier(); - timer_.start(); + stopwatch_.start(); } template< typename TimerTraits > inline void TimerT::stop() { if( running() ) { barrier(); - timer_.stop(); + stopwatch_.stop(); + nesting_.stop(); updateTimings(); - out_ << msg_ << " ... done : " << timer_.elapsed() << "s" << std::endl; + out_ << title_ << " ... done : " << stopwatch_.elapsed() << "s" << std::endl; + running_ = false; + } +} + +template< typename TimerTraits > +inline void TimerT::pause() { + if( running() ) { + barrier(); + stopwatch_.stop(); + nesting_.stop(); } } +template< typename TimerTraits > +inline void TimerT::resume() { + barrier(); + nesting_.start(); + stopwatch_.start(); +} + template< typename TimerTraits > inline double TimerT::elapsed() const { - return timer_.elapsed(); + return stopwatch_.elapsed(); } template< typename TimerTraits > inline std::string TimerT::report() { - return Timings::report(); + return Timings::report() + Barriers::report(); } template< typename TimerTraits > inline std::string TimerT::report( const eckit::Configuration& config ) { - return Timings::report(config); + return Timings::report(config) + Barriers::report(); } //----------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/runtime/timer/Timings.cc b/src/atlas/runtime/timer/Timings.cc index ca52989f0..0e2807389 100644 --- a/src/atlas/runtime/timer/Timings.cc +++ b/src/atlas/runtime/timer/Timings.cc @@ -11,11 +11,14 @@ #include #include #include +#include #include "Timings.h" #include "eckit/config/Configuration.h" +#include "eckit/filesystem/PathName.h" #include "atlas/util/detail/CallStack.h" #include "atlas/util/Config.h" +#include "atlas/runtime/Debug.h" //----------------------------------------------------------------------------------------------------------- @@ -38,6 +41,8 @@ class TimingsRegistry { std::vector nest_; std::vector stack_; std::map index_; + + std::map > labels_; TimingsRegistry() { } @@ -49,7 +54,7 @@ class TimingsRegistry { return registry; } - size_t add( const CallStack& stack, const std::string& title ); + size_t add( const CallStack& stack, const std::string& title, const Timings::Labels& ); void update( size_t idx, double seconds ); @@ -57,13 +62,13 @@ class TimingsRegistry { void report( std::ostream& out, const eckit::Configuration& config ); private: - std::string prefix( long indent, long nest ) const; + std::string filter_filepath( const std::string& filepath ) const; }; -size_t TimingsRegistry::add( const CallStack& stack, const std::string& title ) { +size_t TimingsRegistry::add( const CallStack& stack, const std::string& title, const Timings::Labels& labels ) { std::stringstream ss; ss << stack; std::string key = ss.str(); auto it = index_.find( key ); @@ -78,6 +83,11 @@ size_t TimingsRegistry::add( const CallStack& stack, const std::string& title ) locations_.emplace_back( stack.front() ); nest_.emplace_back( stack.size() ); stack_.emplace_back( stack ); + + for( const auto& label: labels ) { + labels_[label].emplace_back(idx); + } + return idx; } else { @@ -95,9 +105,22 @@ void TimingsRegistry::update( size_t idx, double seconds ) { size_t TimingsRegistry::size() const { return counts_.size(); } void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& config ) { - long indent = config.getLong("indent",4); - long max_nest = config.getLong("depth",0); + long indent = config.getLong("indent",2); + long depth = config.getLong("depth",0); long decimals = config.getLong("decimals",5); + bool header = config.getBool("header",true); + std::vector excluded_labels_vector = config.getStringVector("exclude",std::vector()); + std::vector include_back; + + for( auto& label : excluded_labels_vector ) { + size_t found = label.find("/*"); + if (found!=std::string::npos) { + label.erase(found,2); + include_back.push_back(label); + } + } + + std::set excluded_labels(excluded_labels_vector.begin(),excluded_labels_vector.end()); auto digits_before_decimal = [](double x) -> int { return std::floor(std::log10(std::trunc( std::max(1.,x)) ) )+1; @@ -105,19 +128,71 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con auto digits = [](long x) -> long { return std::floor(std::log10( std::max(1l,x) ) )+1l; }; + + std::vector excluded_timers_vector; + for( auto label: labels_ ) { + auto name = label.first; + if( excluded_labels.count(name) ) { + auto timers = label.second; + for( size_t j : timers ) { + excluded_timers_vector.push_back(j); + } + } + } + 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; + return excluded_timers.count(i); + }; + + std::vector excluded_nest_stored(size()); + long excluded_nest=size(); + for( size_t j=0; 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]); + } + excluded_nest_stored[j] = excluded_nest; + } + 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); + } + } + + + size_t max_title_length(0); + size_t max_location_length(0); + size_t max_nest(0); long max_count(0); double max_seconds(0); for( size_t j=0; j std::string { @@ -135,8 +210,87 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con return out.str(); }; + auto print_line = [](size_t length) -> std::string { + std::stringstream ss; + for( size_t i=0; i std::string { + std::stringstream ss; + ss << print_line(max_title_length + digits(size()) + 3) + << sep << print_line(max_count_length) + << sep << print_line(max_digits_before_decimal+decimals+2) + << sep << print_line(max_digits_before_decimal+decimals+2) + << sep << print_line(max_digits_before_decimal+decimals+2) + << sep << print_line(max_digits_before_decimal+decimals+2) + << sep << print_line(max_location_length); + return ss.str(); + }; + + std::string sept("─┬─"); + std::string seph("─┼─"); + std::string sep (" │ "); + std::string sepf("─┴─"); + + + out << print_horizontal( sept ) << std::endl; + out << std::left << std::setw(max_title_length + digits(size()) + 3) << "Timers" + << sep << std::setw(max_count_length) << "cnt" + << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "tot" + << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "avg" + << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "min" + << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "max" + << sep << "location" + << std::endl; + out << print_horizontal( seph ) << std::endl; + + + std::vector prefix_(size()); + if( indent ) { + std::vector active(max_nest,false); + for( long j=long(size())-1; j>=0; --j ) { + const auto& nest = nest_[j]; + + const CallStack& this_stack = stack_[j]; + const CallStack& next_stack = (j==size()-1) ? this_stack : stack_[j+1]; + + auto this_it = this_stack.rbegin(); + 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->asString() == next_it->asString() ) { + active[i] = active[i] or false; + } else { + active[i] = true; + } + } + for( size_t i=nest; i +#include + //----------------------------------------------------------------------------------------------------------- namespace eckit { class Configuration; } @@ -23,10 +26,11 @@ class Timings { public: using CallStack = util::detail::CallStack; using Identifier = size_t; + using Labels = std::vector; public: // static methods - static Identifier add( const CallStack& stack, const std::string& title ); + static Identifier add( const CallStack& stack, const std::string& title, const Labels& ); static void update( const Identifier& id, double seconds ); diff --git a/src/atlas/util/Config.h b/src/atlas/util/Config.h index 116dcb0f5..64006580d 100644 --- a/src/atlas/util/Config.h +++ b/src/atlas/util/Config.h @@ -12,6 +12,7 @@ #define atlas_Config_h #include +#include #include "eckit/config/Parametrisation.h" #include "atlas/util/Metadata.h" #include "eckit/utils/Hash.h" @@ -52,6 +53,8 @@ class Config: public eckit::LocalConfiguration { template Config operator()(const std::string& name, const ValueT& value); + Config operator()(const std::string& name, const std::initializer_list& value); + // Overload operators to merge two Config objects. Config operator|(const Config& other) const; @@ -87,6 +90,13 @@ inline Config Config::operator()(const std::string& name, const ValueT& value) return *this; } +inline Config Config::operator()(const std::string& name, const std::initializer_list& value) +{ + set(name, std::vector(value.begin(),value.end())); + return *this; +} + + // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index 5b5cb7821..25b4cd201 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -72,13 +72,19 @@ void Metadata::broadcast(Metadata& dest, const size_t root) buffer = s.str(); buffer_size = buffer.size(); } - - atlas::parallel::mpi::comm().broadcast(buffer_size,root); + + { + parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + atlas::parallel::mpi::comm().broadcast(buffer_size,root); + } if( atlas::parallel::mpi::comm().rank() != root ) { buffer.resize(buffer_size); } - atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); + { + parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); + } if( not (&dest==this && atlas::parallel::mpi::comm().rank() == root ) ) { @@ -110,12 +116,18 @@ void Metadata::broadcast(Metadata& dest, const size_t root) const buffer_size = buffer.size(); } - atlas::parallel::mpi::comm().broadcast(buffer_size,root); + { + parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + atlas::parallel::mpi::comm().broadcast(buffer_size,root); + } if( atlas::parallel::mpi::comm().rank() != root ) { buffer.resize(buffer_size); } - atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); + { + parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); + } // Fill in dest { diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc index 2e1a4d0b5..a0b76c5e3 100644 --- a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -111,7 +111,6 @@ void Tool::execute(const Args& args) size_t halo = args.getLong("halo",1); size_t iterations = 10; - parallel::mpi::comm().barrier(); for( size_t i=0; i recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + { + parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + } recvdispls[0]=0; for (int jpart=1; jpart glb_idx_gathered( glb_nb_nodes ); - parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); + { + parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); + } // 2) Sort all global indices, and renumber from 1 to glb_nb_edges @@ -170,8 +176,10 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha } // 3) Scatter renumbered back - - parallel::mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); + { + parallel::mpi::Statistics stats( Here(), "scatter", parallel::mpi::Collective::SCATTER ); + parallel::mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); + } for( int jnode=0; jnode Date: Mon, 9 Oct 2017 16:01:38 +0100 Subject: [PATCH 023/355] ATLAS-132 MPI STATS optional through definitions --- src/apps/atlas-benchmark.cc | 3 +- src/atlas/functionspace/NodeColumns.cc | 57 ++++++------------- src/atlas/mesh/actions/BuildDualMesh.cc | 5 +- src/atlas/mesh/actions/BuildEdges.cc | 3 +- src/atlas/mesh/actions/BuildHalo.cc | 4 +- src/atlas/mesh/actions/BuildParallelFields.cc | 53 ++++++----------- .../mesh/actions/BuildPeriodicBoundaries.cc | 12 ++-- .../mesh/actions/WriteLoadBalanceReport.cc | 2 +- src/atlas/meshgenerator/MeshGenerator.cc | 8 +-- src/atlas/parallel/GatherScatter.cc | 8 +-- src/atlas/parallel/GatherScatter.h | 8 +-- src/atlas/parallel/HaloExchange.cc | 2 +- src/atlas/parallel/HaloExchange.h | 2 +- src/atlas/parallel/mpi/Statistics.h | 25 ++++---- src/atlas/util/Metadata.cc | 20 +++---- .../atlas-benchmark-sorting.cc | 12 +--- src/tests/mesh/test_distmesh.cc | 4 +- src/tests/mesh/test_halo.cc | 10 ++-- 18 files changed, 78 insertions(+), 160 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 05bc11624..41ae02603 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -521,8 +521,7 @@ double AtlasBenchmark::result() } } } - { - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(maxval, eckit::mpi::max()); parallel::mpi::comm().allReduceInPlace(minval, eckit::mpi::min()); parallel::mpi::comm().allReduceInPlace(norm, eckit::mpi::sum()); diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index efc56be3a..9badbe6fc 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -582,10 +582,9 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, size_t& local_sum += arr(n,l); } } - { - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); - } + N = fs.nb_nodes_global() * arr.shape(1); } @@ -661,10 +660,8 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& re } } - { - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); - } N = fs.nb_nodes_global() * arr.shape(1); } @@ -764,10 +761,8 @@ void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& s } } } - { - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) parallel::mpi::comm().allReduceInPlace(sum_per_level.data(), sum.size(), eckit::mpi::sum()); - } N = fs.nb_nodes_global(); } @@ -800,10 +795,8 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs , const Field& fie result = std::accumulate(array::make_storageview(global).data(), array::make_storageview(global).data()+global.size(),0.); - { - parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) parallel::mpi::comm().broadcast(&result, 1, root); - } N = fs.nb_nodes_global(); } @@ -888,10 +881,8 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& fiel } } size_t root = global.metadata().get("owner"); - { - parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) parallel::mpi::comm().broadcast(result,root); - } N = fs.nb_nodes_global(); } @@ -999,10 +990,8 @@ void dispatch_order_independent_sum_per_level( const NodeColumns& fs, const Fiel } } } - { - parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) parallel::mpi::comm().broadcast( array::make_storageview(sumfield).data(),sumfield.size(),root); - } N = fs.nb_nodes_global(); } @@ -1051,10 +1040,8 @@ void dispatch_minimum( const NodeColumns& fs, const Field& field, std::vector } } - { + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) parallel::mpi::comm().allReduce(local_minimum, min, eckit::mpi::min()); - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); - } } template< typename T > @@ -1121,10 +1108,8 @@ void dispatch_maximum( const NodeColumns& fs, const Field& field, std::vector } } } - { + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) parallel::mpi::comm().allReduce(local_maximum, max, eckit::mpi::max()); - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); - } } template< typename T > @@ -1229,10 +1214,8 @@ void dispatch_minimum_per_level( const NodeColumns& fs, const Field& field, Fiel } } } - { - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) parallel::mpi::comm().allReduceInPlace(min.data(),min_field.size(),eckit::mpi::min()); - } } void minimum_per_level( const NodeColumns& fs, const Field& field, Field& min ) @@ -1302,10 +1285,8 @@ void dispatch_maximum_per_level( const NodeColumns& fs, const Field& field, Fiel } } } - { + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) parallel::mpi::comm().allReduceInPlace(max.data(),max_field.size(),eckit::mpi::max()); - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); - } } void maximum_per_level( const NodeColumns& fs, const Field& field, Field& max ) @@ -1380,9 +1361,8 @@ void dispatch_minimum_and_location( const NodeColumns& fs, const Field& field, s min_and_gidx_loc[j] = std::make_pair(local_minimum[j],glb_idx); min_and_level_loc[j] = std::make_pair(local_minimum[j],loc_level[j]); } - - { - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) { parallel::mpi::comm().allReduce(min_and_gidx_loc, min_and_gidx_glb, eckit::mpi::minloc()); parallel::mpi::comm().allReduce(min_and_level_loc,min_and_level_glb,eckit::mpi::minloc()); } @@ -1488,8 +1468,7 @@ void dispatch_maximum_and_location( const NodeColumns& fs, const Field& field, s max_and_level_loc[j] = std::make_pair(local_maximum[j],loc_level[j]); } - { - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) { parallel::mpi::comm().allReduce(max_and_gidx_loc, max_and_gidx_glb, eckit::mpi::maxloc()); parallel::mpi::comm().allReduce(max_and_level_loc,max_and_level_glb,eckit::mpi::maxloc()); } @@ -1666,10 +1645,8 @@ void dispatch_minimum_and_location_per_level( const NodeColumns& fs, const Field } } - { - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) parallel::mpi::comm().allReduce(min_and_gidx_loc,min_and_gidx_glb,eckit::mpi::minloc()); - } atlas_omp_parallel_for( size_t l=0; l& pole_edge_no max[YY] = std::max( max[YY], xy(node,YY) ); } - { - parallel::mpi::Statistics stats( Here(), "allReduce", parallel::mpi::Collective::ALLREDUCE ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); parallel::mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); } diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 29606439f..389cce2b4 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -821,8 +821,8 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector /* deprecated */ ATLAS_TIME( "gather_bdry_nodes old way" ); { - parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); - parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) + parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); } #else ATLAS_TIME(); diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index e850ab45c..341b08dea 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -181,10 +181,8 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - { - parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) parallel::mpi::comm().gather(nb_nodes, recvcounts, root); - } recvdispls[0]=0; for (int jpart=1; jpart glb_id_arr( glb_nb_nodes ); array::ArrayView glb_id = array::make_view(glb_id_arr); - { - parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) parallel::mpi::comm().gatherv(loc_id.data(), loc_id.size(), glb_id.data(), recvcounts.data(), recvdispls.data(), root); - } + // 2) Sort all global indices, and renumber from 1 to glb_nb_edges std::vector node_sort; node_sort.reserve(glb_nb_nodes); for( size_t jnode=0; jnode > send_found( parallel::mpi::comm().size() ); std::vector< std::vector > recv_found( parallel::mpi::comm().size() ); @@ -323,10 +316,8 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) } } - { - parallel::mpi::Statistics stats( Here(), "allToAll", parallel::mpi::Collective::ALLTOALL ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLTOALL ) parallel::mpi::comm().allToAll(send_found, recv_found); - } for( size_t jpart=0; jpart > send_found( parallel::mpi::comm().size() ); std::vector< std::vector > recv_found( parallel::mpi::comm().size() ); @@ -773,10 +759,10 @@ Field& build_edges_remote_idx( Mesh& mesh ) } } } - { - parallel::mpi::Statistics stats( Here(), "allToAll", parallel::mpi::Collective::ALLTOALL ); + + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLTOALL ) parallel::mpi::comm().allToAll(send_found, recv_found); - } + for( size_t jpart=0; jpart& recv_edge = recv_found[jpart]; @@ -855,10 +841,8 @@ Field& build_edges_global_idx( Mesh& mesh ) std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - { - parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) parallel::mpi::comm().gather(nb_edges, recvcounts, root); - } recvdispls[0]=0; for (int jpart=1; jpart glb_edge_id_arr(glb_nb_edges); array::ArrayView glb_edge_id = array::make_view(glb_edge_id_arr); - { - parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) parallel::mpi::comm().gatherv(loc_edge_id.data(), loc_edge_id.size(), glb_edge_id.data(), recvcounts.data(), recvdispls.data(), root); - } + // 2) Sort all global indices, and renumber from 1 to glb_nb_edges std::vector edge_sort; edge_sort.reserve(glb_nb_edges); for( size_t jedge=0; jedge recvcounts( parallel::mpi::comm().size() ); - { - parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) parallel::mpi::comm().allGather(sendcnt, recvcounts.begin(), recvcounts.end()); - } std::vector recvdispls( parallel::mpi::comm().size() ); recvdispls[0] = 0; @@ -118,10 +116,8 @@ void build_periodic_boundaries( Mesh& mesh ) } std::vector recvbuf(recvcnt); - { - parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) parallel::mpi::comm().allGatherv(slave_nodes.begin(), slave_nodes.end(), recvbuf.begin(), recvcounts.data(), recvdispls.data()); - } PeriodicTransform transform; for( size_t jproc=0; jproc elem_counts( parallel::mpi::comm().size() ); std::vector elem_displs( parallel::mpi::comm().size() ); - { - parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) parallel::mpi::comm().allGather(loc_nb_elems, elem_counts.begin(), elem_counts.end()); - } elem_displs.at(0) = 0; for(size_t jpart = 1; jpart < parallel::mpi::comm().size(); ++jpart) @@ -306,7 +304,7 @@ MeshGenerator::MeshGenerator(const std::string &key, const eckit::Parametrisatio meshgenerator_( meshgenerator::MeshGeneratorFactory::build(key,params) ) { } -void MeshGenerator::hash(eckit::Hash& h) const { +void MeshGenerator::hash(eckit::Hash& h) const { return meshgenerator_->hash(h); } @@ -323,7 +321,7 @@ Mesh MeshGenerator::operator()( const Grid& g, const grid::Distribution& d ) con } Mesh MeshGenerator::operator()( const Grid& g ) const { - return meshgenerator_->operator()(g); + return meshgenerator_->operator()(g); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index c9e777705..4d5da1ca6 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -117,10 +117,8 @@ void GatherScatter::setup( const int part[], } } - { - parallel::mpi::Statistics stats( Here(), "allGather", parallel::mpi::Collective::ALLGATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) parallel::mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); - } glbcnt_ = std::accumulate(glbcounts_.begin(),glbcounts_.end(),0); @@ -131,11 +129,9 @@ void GatherScatter::setup( const int part[], } std::vector recvnodes(glbcnt_); - { - parallel::mpi::Statistics stats( Here(), "allGatherv", parallel::mpi::Collective::ALLGATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) parallel::mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, recvnodes.data(), glbcounts_.data(), glbdispls_.data()); - } // Load recvnodes in sorting structure size_t nb_recv_nodes = glbcnt_/nvar; diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index 56cea5659..aaf354778 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -276,10 +276,8 @@ void GatherScatter::gather( parallel::Field lfields[], /// Gather - { - parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) parallel::mpi::comm().gatherv(loc_buffer, glb_buffer, glb_counts, glb_displs, root); - } /// Unpack if( myproc == root ) @@ -338,10 +336,8 @@ void GatherScatter::scatter( parallel::Field gfields[], /// Scatter - { - parallel::mpi::Statistics stats( Here(), "scatter", parallel::mpi::Collective::SCATTER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::SCATTER ) parallel::mpi::comm().scatterv(glb_buffer.begin(), glb_buffer.end(), glb_counts, glb_displs, loc_buffer.begin(), loc_buffer.end(), root); - } /// Unpack unpack_recv_buffer(locmap_,loc_buffer.data(),lfields[jfield]); diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 76be750f9..29bd48c57 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -66,7 +66,7 @@ void HaloExchange::setup( const int part[], const size_t parsize ) { ATLAS_TIME("HaloExchange::setup"); - + parsize_ = parsize; sendcounts_.resize(nproc); sendcounts_.assign(nproc,0); recvcounts_.resize(nproc); recvcounts_.assign(nproc,0); diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 38b1ba7f6..351bccf52 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -166,7 +166,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const if(send_counts[jproc] > 0) { send_req[jproc] = parallel::mpi::comm().iSend( - &send_buffer[send_displs[jproc]], + &send_buffer[send_displs[jproc]], send_counts[jproc], jproc, tag); } } diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 71742a33c..225bce733 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -14,25 +14,18 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Timer.h" +#define ATLAS_MPI_STATS(...) + #if ATLAS_HAVE_TIMINGS #include "atlas/util/detail/BlackMagic.h" #undef ATLAS_MPI_STATS -#define ATLAS_MPI_STATS(...) ATLAS_MPI_STATS_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) - -#define ATLAS_MPI_STATS_(N, ...) __ATLAS__SPLICE( ATLAS_MPI_STATS_, N)(__VA_ARGS__) -#define ATLAS_MPI_STATS_1(Collective) \ +#define ATLAS_MPI_STATS(...) \ for( ::atlas::parallel::mpi::Statistics __ATLAS__SPLICE( stats, __LINE__ ) \ - /*args=*/(Here(), ::atlas::parallel::mpi::name(Collective), Collective);\ + /*args=*/(Here(), __VA_ARGS__ );\ __ATLAS__SPLICE( stats, __LINE__ ) .running(); \ __ATLAS__SPLICE( stats, __LINE__ ) .stop() ) -#define ATLAS_MPI_STATS_2(Collective,title) \ - for( ::atlas::parallel::mpi::Statistics __ATLAS__SPLICE( stats, __LINE__ ) \ - /*args=*/(Here(), title, Collective);\ - __ATLAS__SPLICE( stats, __LINE__ ) .running(); \ - __ATLAS__SPLICE( stats, __LINE__ ) .stop() ) - #endif @@ -49,7 +42,7 @@ struct CollectiveTimerTraits { enum class Collective { - BROADCAST, + BROADCAST, ALLREDUCE, ALLGATHER, ALLTOALL, @@ -85,9 +78,11 @@ static const std::string& name(Collective c) { class Statistics : public runtime::timer::TimerT< CollectiveTimerTraits > { using Base = runtime::timer::TimerT< CollectiveTimerTraits >; public: - Statistics( const eckit::CodeLocation& loc, const std::string& msg, Collective c ) : - Base( loc, msg, make_labels(c), Logging::channel() ) { - + Statistics( const eckit::CodeLocation& loc, Collective c ) : + Base( loc, name(c), make_labels(c), Logging::channel() ) { + } + Statistics( const eckit::CodeLocation& loc, Collective c, const std::string& title ) : + Base( loc, title, make_labels(c), Logging::channel() ) { } private: static std::vector make_labels( Collective c) { diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index 25b4cd201..f06878650 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -72,19 +72,16 @@ void Metadata::broadcast(Metadata& dest, const size_t root) buffer = s.str(); buffer_size = buffer.size(); } - - { - parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + + ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) atlas::parallel::mpi::comm().broadcast(buffer_size,root); - } + if( atlas::parallel::mpi::comm().rank() != root ) { buffer.resize(buffer_size); } - { - parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); - } if( not (&dest==this && atlas::parallel::mpi::comm().rank() == root ) ) { @@ -116,18 +113,15 @@ void Metadata::broadcast(Metadata& dest, const size_t root) const buffer_size = buffer.size(); } - { - parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) atlas::parallel::mpi::comm().broadcast(buffer_size,root); - } + if( atlas::parallel::mpi::comm().rank() != root ) { buffer.resize(buffer_size); } - { - parallel::mpi::Statistics stats( Here(), "broadcast", parallel::mpi::Collective::BROADCAST ); + ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); - } // Fill in dest { diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index 84fc5531c..9a6aca532 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -129,10 +129,8 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - { - parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) parallel::mpi::comm().gather(nb_nodes, recvcounts, root); - } recvdispls[0]=0; for (int jpart=1; jpart glb_idx_gathered( glb_nb_nodes ); - { - parallel::mpi::Statistics stats( Here(), "gather", parallel::mpi::Collective::GATHER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); - } // 2) Sort all global indices, and renumber from 1 to glb_nb_edges @@ -176,10 +172,8 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha } // 3) Scatter renumbered back - { - parallel::mpi::Statistics stats( Here(), "scatter", parallel::mpi::Collective::SCATTER ); + ATLAS_MPI_STATS( parallel::mpi::Collective::SCATTER ) parallel::mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); - } for( int jnode=0; jnode( m.nodes().lonlat() ); - + std::vector check; switch( parallel::mpi::comm().rank() ) { case 0: check = { @@ -511,4 +509,4 @@ CASE( "test_t63" ) int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} From 789c4cd964b6c0d7e870c14f766f9a44b8366277 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 9 Oct 2017 16:33:23 +0100 Subject: [PATCH 024/355] ATLAS-132 Do not require namespace of argument to ATLAS_MPI_STATS --- src/apps/atlas-benchmark.cc | 2 +- src/atlas/functionspace/NodeColumns.cc | 40 +++++++++++------- src/atlas/mesh/actions/BuildDualMesh.cc | 2 +- src/atlas/mesh/actions/BuildEdges.cc | 2 +- src/atlas/mesh/actions/BuildHalo.cc | 3 +- src/atlas/mesh/actions/BuildParallelFields.cc | 42 ++++++++++++------- .../mesh/actions/BuildPeriodicBoundaries.cc | 9 ++-- .../mesh/actions/WriteLoadBalanceReport.cc | 3 +- src/atlas/meshgenerator/MeshGenerator.cc | 3 +- src/atlas/parallel/GatherScatter.cc | 6 ++- src/atlas/parallel/GatherScatter.h | 6 ++- src/atlas/parallel/HaloExchange.cc | 6 +-- src/atlas/parallel/HaloExchange.h | 12 ++---- src/atlas/parallel/mpi/Statistics.h | 30 ++++++++----- src/atlas/util/Metadata.cc | 12 ++++-- src/atlas/util/detail/BlackMagic.h | 2 + .../atlas-benchmark-sorting.cc | 9 ++-- src/tests/mesh/test_distmesh.cc | 3 +- src/tests/mesh/test_halo.cc | 3 +- 19 files changed, 120 insertions(+), 75 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 41ae02603..7dd97c076 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -521,7 +521,7 @@ double AtlasBenchmark::result() } } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) { + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(maxval, eckit::mpi::max()); parallel::mpi::comm().allReduceInPlace(minval, eckit::mpi::min()); parallel::mpi::comm().allReduceInPlace(norm, eckit::mpi::sum()); diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 9badbe6fc..ea000e2df 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -582,8 +582,9 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, size_t& local_sum += arr(n,l); } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); + } N = fs.nb_nodes_global() * arr.shape(1); } @@ -660,8 +661,9 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& re } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); + } N = fs.nb_nodes_global() * arr.shape(1); } @@ -761,8 +763,9 @@ void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& s } } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(sum_per_level.data(), sum.size(), eckit::mpi::sum()); + } N = fs.nb_nodes_global(); } @@ -795,8 +798,9 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs , const Field& fie result = std::accumulate(array::make_storageview(global).data(), array::make_storageview(global).data()+global.size(),0.); - ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) + ATLAS_MPI_STATS( BROADCAST ) { parallel::mpi::comm().broadcast(&result, 1, root); + } N = fs.nb_nodes_global(); } @@ -881,8 +885,9 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& fiel } } size_t root = global.metadata().get("owner"); - ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) + ATLAS_MPI_STATS( BROADCAST ) { parallel::mpi::comm().broadcast(result,root); + } N = fs.nb_nodes_global(); } @@ -990,8 +995,9 @@ void dispatch_order_independent_sum_per_level( const NodeColumns& fs, const Fiel } } } - ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) + ATLAS_MPI_STATS( BROADCAST ) { parallel::mpi::comm().broadcast( array::make_storageview(sumfield).data(),sumfield.size(),root); + } N = fs.nb_nodes_global(); } @@ -1040,8 +1046,9 @@ void dispatch_minimum( const NodeColumns& fs, const Field& field, std::vector } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduce(local_minimum, min, eckit::mpi::min()); + } } template< typename T > @@ -1108,8 +1115,9 @@ void dispatch_maximum( const NodeColumns& fs, const Field& field, std::vector } } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduce(local_maximum, max, eckit::mpi::max()); + } } template< typename T > @@ -1214,8 +1222,9 @@ void dispatch_minimum_per_level( const NodeColumns& fs, const Field& field, Fiel } } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(min.data(),min_field.size(),eckit::mpi::min()); + } } void minimum_per_level( const NodeColumns& fs, const Field& field, Field& min ) @@ -1285,8 +1294,9 @@ void dispatch_maximum_per_level( const NodeColumns& fs, const Field& field, Fiel } } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(max.data(),max_field.size(),eckit::mpi::max()); + } } void maximum_per_level( const NodeColumns& fs, const Field& field, Field& max ) @@ -1362,7 +1372,7 @@ void dispatch_minimum_and_location( const NodeColumns& fs, const Field& field, s min_and_level_loc[j] = std::make_pair(local_minimum[j],loc_level[j]); } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) { + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduce(min_and_gidx_loc, min_and_gidx_glb, eckit::mpi::minloc()); parallel::mpi::comm().allReduce(min_and_level_loc,min_and_level_glb,eckit::mpi::minloc()); } @@ -1468,7 +1478,7 @@ void dispatch_maximum_and_location( const NodeColumns& fs, const Field& field, s max_and_level_loc[j] = std::make_pair(local_maximum[j],loc_level[j]); } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) { + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduce(max_and_gidx_loc, max_and_gidx_glb, eckit::mpi::maxloc()); parallel::mpi::comm().allReduce(max_and_level_loc,max_and_level_glb,eckit::mpi::maxloc()); } @@ -1645,8 +1655,9 @@ void dispatch_minimum_and_location_per_level( const NodeColumns& fs, const Field } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduce(min_and_gidx_loc,min_and_gidx_glb,eckit::mpi::minloc()); + } atlas_omp_parallel_for( size_t l=0; l& pole_edge_no max[YY] = std::max( max[YY], xy(node,YY) ); } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLREDUCE ) { + ATLAS_MPI_STATS( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); parallel::mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); } diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 389cce2b4..7f5527e25 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -821,8 +821,9 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector /* deprecated */ ATLAS_TIME( "gather_bdry_nodes old way" ); { - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) + ATLAS_MPI_STATS( ALLGATHER ) { parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); + } } #else ATLAS_TIME(); diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 341b08dea..94cdbfeeb 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -181,8 +181,9 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) + ATLAS_MPI_STATS( GATHER ) { parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + } recvdispls[0]=0; for (int jpart=1; jpart glb_id_arr( glb_nb_nodes ); array::ArrayView glb_id = array::make_view(glb_id_arr); - ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) + ATLAS_MPI_STATS( GATHER ) { parallel::mpi::comm().gatherv(loc_id.data(), loc_id.size(), glb_id.data(), recvcounts.data(), recvdispls.data(), root); + } // 2) Sort all global indices, and renumber from 1 to glb_nb_edges std::vector node_sort; node_sort.reserve(glb_nb_nodes); @@ -222,8 +224,9 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) } // 3) Scatter renumbered back - ATLAS_MPI_STATS( parallel::mpi::Collective::SCATTER ) + ATLAS_MPI_STATS( SCATTER ) { parallel::mpi::comm().scatterv(glb_id.data(), recvcounts.data(), recvdispls.data(), loc_id.data(), loc_id.size(), root); + } for( int jnode=0; jnode > send_found( parallel::mpi::comm().size() ); std::vector< std::vector > recv_found( parallel::mpi::comm().size() ); @@ -316,8 +320,9 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLTOALL ) + ATLAS_MPI_STATS( ALLTOALL ) { parallel::mpi::comm().allToAll(send_found, recv_found); + } for( size_t jpart=0; jpart > send_found( parallel::mpi::comm().size() ); std::vector< std::vector > recv_found( parallel::mpi::comm().size() ); @@ -760,8 +768,9 @@ Field& build_edges_remote_idx( Mesh& mesh ) } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLTOALL ) + ATLAS_MPI_STATS( ALLTOALL ) { parallel::mpi::comm().allToAll(send_found, recv_found); + } for( size_t jpart=0; jpart recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) + ATLAS_MPI_STATS( GATHER ) { parallel::mpi::comm().gather(nb_edges, recvcounts, root); + } recvdispls[0]=0; for (int jpart=1; jpart glb_edge_id_arr(glb_nb_edges); array::ArrayView glb_edge_id = array::make_view(glb_edge_id_arr); - ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) - parallel::mpi::comm().gatherv(loc_edge_id.data(), loc_edge_id.size(), glb_edge_id.data(), recvcounts.data(), recvdispls.data(), root); + ATLAS_MPI_STATS( GATHER ) { + parallel::mpi::comm().gatherv(loc_edge_id.data(), loc_edge_id.size(), + glb_edge_id.data(), recvcounts.data(), recvdispls.data(), root); + } // 2) Sort all global indices, and renumber from 1 to glb_nb_edges std::vector edge_sort; edge_sort.reserve(glb_nb_edges); @@ -882,8 +894,10 @@ Field& build_edges_global_idx( Mesh& mesh ) } // 3) Scatter renumbered back - ATLAS_MPI_STATS( parallel::mpi::Collective::SCATTER ) - parallel::mpi::comm().scatterv(glb_edge_id.data(), recvcounts.data(), recvdispls.data(), loc_edge_id.data(), loc_edge_id.size(), root); + ATLAS_MPI_STATS( SCATTER ) { + parallel::mpi::comm().scatterv(glb_edge_id.data(), recvcounts.data(), recvdispls.data(), + loc_edge_id.data(), loc_edge_id.size(), root); + } for( int jedge=0; jedge recvcounts( parallel::mpi::comm().size() ); - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) + ATLAS_MPI_STATS( ALLGATHER ) { parallel::mpi::comm().allGather(sendcnt, recvcounts.begin(), recvcounts.end()); + } std::vector recvdispls( parallel::mpi::comm().size() ); recvdispls[0] = 0; @@ -116,8 +117,9 @@ void build_periodic_boundaries( Mesh& mesh ) } std::vector recvbuf(recvcnt); - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) + ATLAS_MPI_STATS( ALLGATHER ) { parallel::mpi::comm().allGatherv(slave_nodes.begin(), slave_nodes.end(), recvbuf.begin(), recvcounts.data(), recvdispls.data()); + } PeriodicTransform transform; for( size_t jproc=0; jproc elem_counts( parallel::mpi::comm().size() ); std::vector elem_displs( parallel::mpi::comm().size() ); - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) + ATLAS_MPI_STATS( ALLGATHER ) { parallel::mpi::comm().allGather(loc_nb_elems, elem_counts.begin(), elem_counts.end()); + } elem_displs.at(0) = 0; for(size_t jpart = 1; jpart < parallel::mpi::comm().size(); ++jpart) diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index 4d5da1ca6..1ec5c3c5c 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -117,8 +117,9 @@ void GatherScatter::setup( const int part[], } } - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) + ATLAS_MPI_STATS( ALLGATHER ) { parallel::mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); + } glbcnt_ = std::accumulate(glbcounts_.begin(),glbcounts_.end(),0); @@ -129,9 +130,10 @@ void GatherScatter::setup( const int part[], } std::vector recvnodes(glbcnt_); - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLGATHER ) + ATLAS_MPI_STATS( ALLGATHER ) { parallel::mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, recvnodes.data(), glbcounts_.data(), glbdispls_.data()); + } // Load recvnodes in sorting structure size_t nb_recv_nodes = glbcnt_/nvar; diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index aaf354778..7cb4045fe 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -276,8 +276,9 @@ void GatherScatter::gather( parallel::Field lfields[], /// Gather - ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) + ATLAS_MPI_STATS( GATHER ) { parallel::mpi::comm().gatherv(loc_buffer, glb_buffer, glb_counts, glb_displs, root); + } /// Unpack if( myproc == root ) @@ -336,8 +337,9 @@ void GatherScatter::scatter( parallel::Field gfields[], /// Scatter - ATLAS_MPI_STATS( parallel::mpi::Collective::SCATTER ) + ATLAS_MPI_STATS( SCATTER ) { parallel::mpi::comm().scatterv(glb_buffer.begin(), glb_buffer.end(), glb_counts, glb_displs, loc_buffer.begin(), loc_buffer.end(), root); + } /// Unpack unpack_recv_buffer(locmap_,loc_buffer.data(),lfields[jfield]); diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 29bd48c57..b968be8e0 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -90,8 +90,7 @@ void HaloExchange::setup( const int part[], /* Find the amount of nodes this proc has to send to each other proc */ - { - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLTOALL ) + ATLAS_MPI_STATS( ALLTOALL ) { parallel::mpi::comm().allToAll(recvcounts_, sendcounts_); } @@ -131,8 +130,7 @@ void HaloExchange::setup( const int part[], */ std::vector recv_requests(sendcnt_); - { - ATLAS_MPI_STATS( parallel::mpi::Collective::ALLTOALL ) + ATLAS_MPI_STATS( ALLTOALL ) { parallel::mpi::comm().allToAllv(send_requests.data(), recvcounts_.data(), recvdispls_.data(), recv_requests.data(), sendcounts_.data(), senddispls_.data()); } diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 351bccf52..7919d9ea7 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -143,8 +143,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const recv_displs[jproc] = recvdispls_[jproc]*var_size; } - ATLAS_MPI_STATS( parallel::mpi::Collective::IRECEIVE ) - { + ATLAS_MPI_STATS( IRECEIVE ) { /// Let MPI know what we like to receive for(int jproc=0; jproc < nproc; ++jproc) { @@ -159,8 +158,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const pack_send_buffer(field,var_strides,var_shape,var_rank,send_buffer.data()); /// Send - ATLAS_MPI_STATS( parallel::mpi::Collective::ISEND ) - { + ATLAS_MPI_STATS( ISEND ) { for(int jproc=0; jproc < nproc; ++jproc) { if(send_counts[jproc] > 0) @@ -173,8 +171,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const } /// Wait for receiving to finish - ATLAS_MPI_STATS( parallel::mpi::Collective::WAIT, "mpi-wait receive" ) - { + ATLAS_MPI_STATS( WAIT, "mpi-wait receive" ) { for (int jproc=0; jproc < nproc; ++jproc) { if( recvcounts_[jproc] > 0) @@ -188,8 +185,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const unpack_recv_buffer(recv_buffer.data(),field,var_strides,var_shape,var_rank); /// Wait for sending to finish - ATLAS_MPI_STATS( parallel::mpi::Collective::WAIT, "mpi-wait send" ) - { + ATLAS_MPI_STATS( WAIT, "mpi-wait send" ) { for (int jproc=0; jproc < nproc; ++jproc) { if( sendcounts_[jproc] > 0) diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 225bce733..181fd5195 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -21,11 +21,19 @@ #include "atlas/util/detail/BlackMagic.h" #undef ATLAS_MPI_STATS -#define ATLAS_MPI_STATS(...) \ +#define ATLAS_MPI_STATS(...) ATLAS_MPI_STATS_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) +#define ATLAS_MPI_STATS_(N, ...) __ATLAS__SPLICE( ATLAS_MPI_STATS_, N)(__VA_ARGS__) +#define ATLAS_MPI_STATS_1( statistics_enum ) \ for( ::atlas::parallel::mpi::Statistics __ATLAS__SPLICE( stats, __LINE__ ) \ - /*args=*/(Here(), __VA_ARGS__ );\ + /*args=*/(Here(), ::atlas::parallel::mpi::StatisticsEnum::__ATLAS_STRINGIFY(statistics_enum) );\ __ATLAS__SPLICE( stats, __LINE__ ) .running(); \ __ATLAS__SPLICE( stats, __LINE__ ) .stop() ) +#define ATLAS_MPI_STATS_2(statistics_enum,title) \ + for( ::atlas::parallel::mpi::Statistics __ATLAS__SPLICE( stats, __LINE__ ) \ + /*args=*/(Here(), ::atlas::parallel::mpi::StatisticsEnum::__ATLAS_STRINGIFY(statistics_enum), title);\ + __ATLAS__SPLICE( stats, __LINE__ ) .running(); \ + __ATLAS__SPLICE( stats, __LINE__ ) .stop() ) + #endif @@ -33,7 +41,7 @@ namespace atlas { namespace parallel { namespace mpi { -struct CollectiveTimerTraits { +struct StatisticsTimerTraits { using Barriers = runtime::timer::TimerBarriers; using Logging = runtime::timer::TimerNoLogging; using Timings = runtime::timer::Timings; @@ -41,7 +49,7 @@ struct CollectiveTimerTraits { }; -enum class Collective { +enum class StatisticsEnum { BROADCAST, ALLREDUCE, ALLGATHER, @@ -57,8 +65,8 @@ enum class Collective { _COUNT_ }; -static const std::string& name(Collective c) { - static std::array(Collective::_COUNT_)> names { +static const std::string& name(StatisticsEnum c) { + static std::array(StatisticsEnum::_COUNT_)> names { "mpi-broadcast", "mpi-allreduce", "mpi-allgather", @@ -75,17 +83,17 @@ static const std::string& name(Collective c) { return names[ static_cast(c) ]; } -class Statistics : public runtime::timer::TimerT< CollectiveTimerTraits > { - using Base = runtime::timer::TimerT< CollectiveTimerTraits >; +class Statistics : public runtime::timer::TimerT< StatisticsTimerTraits > { + using Base = runtime::timer::TimerT< StatisticsTimerTraits >; public: - Statistics( const eckit::CodeLocation& loc, Collective c ) : + Statistics( const eckit::CodeLocation& loc, StatisticsEnum c ) : Base( loc, name(c), make_labels(c), Logging::channel() ) { } - Statistics( const eckit::CodeLocation& loc, Collective c, const std::string& title ) : + Statistics( const eckit::CodeLocation& loc, StatisticsEnum c, const std::string& title ) : Base( loc, title, make_labels(c), Logging::channel() ) { } private: - static std::vector make_labels( Collective c) { + static std::vector make_labels( StatisticsEnum c) { return {"mpi", name(c)}; } }; diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index f06878650..eb0dd00e7 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -73,15 +73,17 @@ void Metadata::broadcast(Metadata& dest, const size_t root) buffer_size = buffer.size(); } - ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) + ATLAS_MPI_STATS( BROADCAST ) { atlas::parallel::mpi::comm().broadcast(buffer_size,root); + } if( atlas::parallel::mpi::comm().rank() != root ) { buffer.resize(buffer_size); } - ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) + ATLAS_MPI_STATS( BROADCAST ) { atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); + } if( not (&dest==this && atlas::parallel::mpi::comm().rank() == root ) ) { @@ -113,15 +115,17 @@ void Metadata::broadcast(Metadata& dest, const size_t root) const buffer_size = buffer.size(); } - ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) + ATLAS_MPI_STATS( BROADCAST ) { atlas::parallel::mpi::comm().broadcast(buffer_size,root); + } if( atlas::parallel::mpi::comm().rank() != root ) { buffer.resize(buffer_size); } - ATLAS_MPI_STATS( parallel::mpi::Collective::BROADCAST ) + ATLAS_MPI_STATS( BROADCAST ) { atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); + } // Fill in dest { diff --git a/src/atlas/util/detail/BlackMagic.h b/src/atlas/util/detail/BlackMagic.h index 53af7214e..a0cd926b8 100644 --- a/src/atlas/util/detail/BlackMagic.h +++ b/src/atlas/util/detail/BlackMagic.h @@ -12,6 +12,8 @@ /// Splice a and b together #define __ATLAS__SPLICE(a,b) +#define __ATLAS_STRINGIFY(a) a + //----------------------------------------------------------------------------------------------------------- // Details diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index 9a6aca532..4df5fe53a 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -129,8 +129,9 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) + ATLAS_MPI_STATS( GATHER ) { parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + } recvdispls[0]=0; for (int jpart=1; jpart glb_idx_gathered( glb_nb_nodes ); - ATLAS_MPI_STATS( parallel::mpi::Collective::GATHER ) + ATLAS_MPI_STATS( GATHER ) { parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); + } // 2) Sort all global indices, and renumber from 1 to glb_nb_edges @@ -172,8 +174,9 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha } // 3) Scatter renumbered back - ATLAS_MPI_STATS( parallel::mpi::Collective::SCATTER ) + ATLAS_MPI_STATS( SCATTER ) { parallel::mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); + } for( int jnode=0; jnode Date: Mon, 9 Oct 2017 18:16:30 +0100 Subject: [PATCH 025/355] ATLAS-132 Make timer callstack lighter --- src/atlas/runtime/timer/TimerNesting.cc | 2 +- src/atlas/runtime/timer/Timings.cc | 54 +++++++++++++------------ src/atlas/util/detail/CallStack.cc | 25 +++++++----- src/atlas/util/detail/CallStack.h | 32 +++++++++------ 4 files changed, 66 insertions(+), 47 deletions(-) diff --git a/src/atlas/runtime/timer/TimerNesting.cc b/src/atlas/runtime/timer/TimerNesting.cc index cea077671..b62ea1c0d 100644 --- a/src/atlas/runtime/timer/TimerNesting.cc +++ b/src/atlas/runtime/timer/TimerNesting.cc @@ -15,7 +15,7 @@ namespace atlas { namespace runtime { namespace timer { - + class TimerNestingState { using CallStack = util::detail::CallStack; diff --git a/src/atlas/runtime/timer/Timings.cc b/src/atlas/runtime/timer/Timings.cc index 0e2807389..569bddaaa 100644 --- a/src/atlas/runtime/timer/Timings.cc +++ b/src/atlas/runtime/timer/Timings.cc @@ -19,6 +19,7 @@ #include "atlas/util/detail/CallStack.h" #include "atlas/util/Config.h" #include "atlas/runtime/Debug.h" +#include "atlas/parallel/mpi/mpi.h" //----------------------------------------------------------------------------------------------------------- @@ -40,8 +41,8 @@ class TimingsRegistry { std::vector locations_; std::vector nest_; std::vector stack_; - std::map index_; - + std::map index_; + std::map > labels_; TimingsRegistry() { @@ -69,8 +70,8 @@ class TimingsRegistry { }; size_t TimingsRegistry::add( const CallStack& stack, const std::string& title, const Timings::Labels& labels ) { - std::stringstream ss; ss << stack; - std::string key = ss.str(); + + size_t key = stack.hash(); auto it = index_.find( key ); if( it == index_.end() ) { size_t idx = size(); @@ -80,10 +81,10 @@ size_t TimingsRegistry::add( const CallStack& stack, const std::string& title, c min_timings_.emplace_back( 0 ); max_timings_.emplace_back( 0 ); titles_.emplace_back( title ); - locations_.emplace_back( stack.front() ); + locations_.emplace_back( stack.loc() ); nest_.emplace_back( stack.size() ); stack_.emplace_back( stack ); - + for( const auto& label: labels ) { labels_[label].emplace_back(idx); } @@ -128,7 +129,7 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con auto digits = [](long x) -> long { return std::floor(std::log10( std::max(1l,x) ) )+1l; }; - + std::vector excluded_timers_vector; for( auto label: labels_ ) { auto name = label.first; @@ -140,14 +141,14 @@ 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; return excluded_timers.count(i); }; - + std::vector excluded_nest_stored(size()); long excluded_nest=size(); for( size_t j=0; jasString() == next_it->asString() ) { + if( *this_it == *next_it ) { active[i] = active[i] or false; } else { active[i] = true; @@ -284,7 +285,7 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con out << "â””"; for( size_t j=1; j +#include #include "CallStack.h" @@ -7,14 +7,21 @@ namespace atlas { namespace util { namespace detail { -void CallStack::print(std::ostream& out) const { - const_iterator it = begin(); - out << "\nstack:\n"; - for( size_t i=0; ifile() << " +"<< it->line() << '\n'; - } - out << "\n"; - out << std::flush; +void CallStack::push_front( const eckit::CodeLocation& loc ) { + stack_.push_front( std::hash{}(loc.asString()) ); + loc_ = loc; +} + +void CallStack::pop_front() { + stack_.pop_front(); +} + +size_t CallStack::hash() const { + if( hash_ ) return hash_; + for( auto h : stack_ ) { + hash_ ^= (h << 1); + } + return hash_; } } // namespace detail diff --git a/src/atlas/util/detail/CallStack.h b/src/atlas/util/detail/CallStack.h index 74a366daf..9e18b16ab 100644 --- a/src/atlas/util/detail/CallStack.h +++ b/src/atlas/util/detail/CallStack.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include "eckit/log/CodeLocation.h" namespace atlas { @@ -10,24 +9,33 @@ namespace detail { /// @class CallStack /// Instances of CallStack can keep track of nested eckit::CodeLocations -class CallStack: public std::list< eckit::CodeLocation > { -private: +class CallStack { - using Base = std::list< eckit::CodeLocation >; +public: + using const_iterator = std::list::const_iterator; + using const_reverse_iterator = std::list::const_reverse_iterator; public: - // Enable constructors from base class - using Base::Base; + void push_front( const eckit::CodeLocation& ); + void pop_front(); -private: + const eckit::CodeLocation& loc() const { return loc_; } + + const_iterator begin() const { return stack_.begin(); } + const_iterator end() const { return stack_.end(); } - void print(std::ostream& out) const; + const_reverse_iterator rbegin() const { return stack_.rbegin(); } + const_reverse_iterator rend() const { return stack_.rend(); } + + size_t hash() const; + size_t size() const { return stack_.size(); } + +private: - friend std::ostream& operator<< ( std::ostream& out, const CallStack& p ) { - p.print(out); - return out; - } + eckit::CodeLocation loc_; + std::list stack_; + mutable size_t hash_{0}; }; From a95a66c64071edc3b771ba82d5da3960f83c6088 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 10 Oct 2017 10:59:07 +0100 Subject: [PATCH 026/355] ATLAS-132 Timers with standard deviation --- src/atlas/runtime/timer/Timings.cc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/atlas/runtime/timer/Timings.cc b/src/atlas/runtime/timer/Timings.cc index 569bddaaa..13bd50373 100644 --- a/src/atlas/runtime/timer/Timings.cc +++ b/src/atlas/runtime/timer/Timings.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include "Timings.h" #include "eckit/config/Configuration.h" @@ -37,6 +38,7 @@ class TimingsRegistry { std::vector tot_timings_; std::vector min_timings_; std::vector max_timings_; + std::vector var_timings_; std::vector titles_; std::vector locations_; std::vector nest_; @@ -78,8 +80,9 @@ size_t TimingsRegistry::add( const CallStack& stack, const std::string& title, c index_[key] = idx; counts_.emplace_back( 0 ); tot_timings_.emplace_back( 0 ); - min_timings_.emplace_back( 0 ); + min_timings_.emplace_back( std::numeric_limits::max() ); max_timings_.emplace_back( 0 ); + var_timings_.emplace_back( 0 ); titles_.emplace_back( title ); locations_.emplace_back( stack.loc() ); nest_.emplace_back( stack.size() ); @@ -97,10 +100,16 @@ size_t TimingsRegistry::add( const CallStack& stack, const std::string& title, c } void TimingsRegistry::update( size_t idx, double seconds ) { - counts_[idx] += 1; + + auto sqr = [](double x) { return x*x; }; + double n = counts_[idx]+1; + double avg_nm1 = tot_timings_[idx] / std::max(n,1.); + double var_nm1 = var_timings_[idx]; + var_timings_[idx] = counts_[idx] == 0 ? 0. : (n-2.)/(n-1.) * var_nm1 + 1./n * sqr(seconds-avg_nm1); + min_timings_[idx] = std::min( seconds, min_timings_[idx] ); + max_timings_[idx] = std::max( seconds, max_timings_[idx] ); tot_timings_[idx] += seconds; - min_timings_[idx] = counts_[idx] == 1 ? seconds : std::min( seconds, min_timings_[idx] ); - max_timings_[idx] = counts_[idx] == 1 ? seconds : std::max( seconds, max_timings_[idx] ); + counts_[idx] += 1; } size_t TimingsRegistry::size() const { return counts_.size(); } @@ -226,6 +235,7 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con << sep << print_line(max_digits_before_decimal+decimals+2) << sep << print_line(max_digits_before_decimal+decimals+2) << sep << print_line(max_digits_before_decimal+decimals+2) + << sep << print_line(max_digits_before_decimal+decimals+2) << sep << print_line(max_location_length); return ss.str(); }; @@ -241,6 +251,7 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con << sep << std::setw(max_count_length) << "cnt" << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "tot" << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "avg" + << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "std" << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "min" << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "max" << sep << "location" @@ -300,6 +311,8 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con auto& title = titles_[j]; auto& loc = locations_[j]; auto& nest = nest_[j]; + auto std = std::sqrt( var_timings_[j] ); + auto avg = tot/double(count); //parallel::mpi::comm().allReduceInPlace(min,eckit::mpi::min()); //parallel::mpi::comm().allReduceInPlace(max,eckit::mpi::max()); @@ -310,7 +323,8 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con << std::left << std::setw(max_title_length-nest*indent) << title << sep << std::string(header ? "" : "count: ") << std::left << std::setw(max_count_length) << count << sep << std::string(header ? "" : "tot: " ) << print_time(tot) - << sep << std::string(header ? "" : "avg: " ) << print_time(tot/double(count)) + << sep << std::string(header ? "" : "avg: " ) << print_time(avg) + << sep << std::string(header ? "" : "std: " ) << print_time(std) << sep << std::string(header ? "" : "min: " ) << print_time(min) << sep << std::string(header ? "" : "max: " ) << print_time(max) << sep << filter_filepath(loc.file()) << " +"< Date: Wed, 11 Oct 2017 15:32:15 +0100 Subject: [PATCH 027/355] ATLAS-132 Rename ATLAS_TIME to ATLAS_TRACE --- src/apps/atlas-benchmark.cc | 34 +++--- src/apps/atlas.cc | 2 +- src/atlas/CMakeLists.txt | 10 +- src/atlas/field/FieldCreatorIFS.cc | 2 +- src/atlas/field/State.cc | 2 +- src/atlas/functionspace/EdgeColumns.cc | 10 +- src/atlas/functionspace/NodeColumns.cc | 38 +++--- src/atlas/functionspace/StructuredColumns.cc | 22 ++-- src/atlas/grid/Partitioner.cc | 4 +- .../partitioner/EqualRegionsPartitioner.cc | 4 +- .../MatchingMeshPartitionerLonLatPolygon.cc | 2 +- ...MatchingMeshPartitionerSphericalPolygon.cc | 2 +- .../grid/detail/partitioner/Partitioner.cc | 4 +- .../detail/partitioner/TransPartitioner.cc | 4 +- .../grid/detail/spacing/gaussian/Latitudes.cc | 2 +- .../interpolation/method/FiniteElement.cc | 14 +-- .../method/KNearestNeighbours.cc | 6 +- .../method/KNearestNeighboursBase.cc | 2 +- src/atlas/interpolation/method/Method.cc | 8 +- .../interpolation/method/NearestNeighbour.cc | 6 +- src/atlas/interpolation/method/PointSet.h | 4 +- src/atlas/library/Library.cc | 80 ++++++++----- src/atlas/library/Library.h | 29 +++-- src/atlas/library/config.h | 2 +- src/atlas/mesh/actions/BuildConvexHull3D.cc | 8 +- src/atlas/mesh/actions/BuildDualMesh.cc | 20 ++-- src/atlas/mesh/actions/BuildEdges.cc | 2 +- src/atlas/mesh/actions/BuildHalo.cc | 50 ++++---- src/atlas/mesh/actions/BuildParallelFields.cc | 46 ++++---- .../mesh/actions/BuildPeriodicBoundaries.cc | 6 +- .../mesh/actions/WriteLoadBalanceReport.cc | 2 +- src/atlas/meshgenerator/MeshGenerator.cc | 6 +- .../meshgenerator/RegularMeshGenerator.cc | 4 +- .../meshgenerator/StructuredMeshGenerator.cc | 8 +- src/atlas/numerics/Nabla.cc | 2 +- src/atlas/numerics/fvm/Nabla.cc | 6 +- src/atlas/output/Gmsh.cc | 2 +- src/atlas/output/Output.cc | 4 +- src/atlas/output/detail/GmshIO.cc | 10 +- src/atlas/parallel/GatherScatter.cc | 8 +- src/atlas/parallel/GatherScatter.h | 4 +- src/atlas/parallel/HaloExchange.cc | 6 +- src/atlas/parallel/HaloExchange.h | 14 +-- src/atlas/parallel/mpi/Statistics.h | 55 ++++----- src/atlas/parallel/omp/omp.cc | 2 +- src/atlas/runtime/Log.h | 26 +++-- src/atlas/runtime/Timer.h | 109 ------------------ src/atlas/runtime/Trace.h | 87 ++++++++++++++ .../detail => runtime/timer}/CallStack.cc | 10 +- .../detail => runtime/timer}/CallStack.h | 15 ++- src/atlas/runtime/timer/StopWatch.h | 50 +++++--- src/atlas/runtime/timer/TimerBarriers.cc | 6 +- src/atlas/runtime/timer/TimerBarriers.h | 4 +- src/atlas/runtime/timer/TimerLogging.cc | 76 ------------ src/atlas/runtime/timer/TimerLogging.h | 53 --------- src/atlas/runtime/timer/TimerNesting.cc | 14 +-- src/atlas/runtime/timer/TimerNesting.h | 5 +- src/atlas/runtime/timer/TimerT.h | 56 ++++----- src/atlas/runtime/timer/TimerTracing.cc | 102 ++++++++++++++++ src/atlas/runtime/timer/TimerTracing.h | 77 +++++++++++++ src/atlas/runtime/timer/Timings.cc | 16 ++- src/atlas/runtime/timer/Timings.h | 11 +- src/atlas/util/Metadata.cc | 8 +- src/atlas/util/detail/BlackMagic.h | 98 +++++++++++----- .../atlas-benchmark-build-halo.cc | 4 +- .../atlas-benchmark-sorting.cc | 24 ++-- src/sandbox/interpolation/PartitionedMesh.cc | 6 +- src/tests/mesh/test_distmesh.cc | 2 +- src/tests/mesh/test_halo.cc | 2 +- 69 files changed, 756 insertions(+), 663 deletions(-) delete mode 100644 src/atlas/runtime/Timer.h create mode 100644 src/atlas/runtime/Trace.h rename src/atlas/{util/detail => runtime/timer}/CallStack.cc (77%) rename src/atlas/{util/detail => runtime/timer}/CallStack.h (80%) delete mode 100644 src/atlas/runtime/timer/TimerLogging.cc delete mode 100644 src/atlas/runtime/timer/TimerLogging.h create mode 100644 src/atlas/runtime/timer/TimerTracing.cc create mode 100644 src/atlas/runtime/timer/TimerTracing.h diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 7dd97c076..5fb5050bc 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -51,7 +51,7 @@ #include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildPeriodicBoundaries.h" #include "atlas/runtime/AtlasTool.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/output/Gmsh.h" #include "atlas/parallel/Checksum.h" @@ -105,7 +105,7 @@ struct TimerStats cnt = 0; name = _name; } - void update(Timer& timer) + void update(Trace& timer) { double t = timer.elapsed(); if( min < 0 ) min = t; @@ -190,7 +190,7 @@ class AtlasBenchmark: public AtlasTool { void AtlasBenchmark::execute(const Args& args) { - Timer timer( Here(),"atlas-benchmark"); + Trace timer( Here(),"atlas-benchmark"); // Timer::Logging set_channel( Log::info() ); nlev = 137; @@ -217,7 +217,7 @@ void AtlasBenchmark::execute(const Args& args) omp_set_num_threads(omp_threads); Log::info() << "atlas-benchmark\n" << endl; - Log::info() << Library::instance().info() << endl; + Log::info() << Library::instance().information() << endl; Log::info() << "Configuration:" << endl; Log::info() << " grid: " << gridname << endl; Log::info() << " nlev: " << nlev << endl; @@ -230,7 +230,7 @@ void AtlasBenchmark::execute(const Args& args) Log::info() << "Timings:" << endl; - ATLAS_TIME_SCOPE("setup",{"atlas-benchmark-setup"}) { setup(); } + ATLAS_TRACE_SCOPE("setup",{"atlas-benchmark-setup"}) { setup(); } Log::info() << " Executing " << niter << " iterations: \n"; if( progress ) @@ -296,15 +296,15 @@ void AtlasBenchmark::setup() size_t halo = 1; StructuredGrid grid; - ATLAS_TIME_SCOPE( "Create grid" ) { grid = Grid(gridname); } - ATLAS_TIME_SCOPE( "Create mesh" ) { mesh = MeshGenerator( "structured" ).generate(grid); } + ATLAS_TRACE_SCOPE( "Create grid" ) { grid = Grid(gridname); } + ATLAS_TRACE_SCOPE( "Create mesh" ) { mesh = MeshGenerator( "structured" ).generate(grid); } - ATLAS_TIME_SCOPE( "Create node_fs") { nodes_fs = functionspace::NodeColumns(mesh,option::halo(halo)); } - ATLAS_TIME_SCOPE( "build_edges" ) { build_edges(mesh); } - ATLAS_TIME_SCOPE( "build_pole_edges" ) { build_pole_edges(mesh); } - ATLAS_TIME_SCOPE( "build_edges_parallel_fiels" ) { build_edges_parallel_fields(mesh); } - ATLAS_TIME_SCOPE( "build_median_dual_mesh" ) { build_median_dual_mesh(mesh); } - ATLAS_TIME_SCOPE( "build_node_to_edge_connectivity" ) { build_node_to_edge_connectivity(mesh); } + ATLAS_TRACE_SCOPE( "Create node_fs") { nodes_fs = functionspace::NodeColumns(mesh,option::halo(halo)); } + ATLAS_TRACE_SCOPE( "build_edges" ) { build_edges(mesh); } + ATLAS_TRACE_SCOPE( "build_pole_edges" ) { build_pole_edges(mesh); } + ATLAS_TRACE_SCOPE( "build_edges_parallel_fiels" ) { build_edges_parallel_fields(mesh); } + ATLAS_TRACE_SCOPE( "build_median_dual_mesh" ) { build_median_dual_mesh(mesh); } + ATLAS_TRACE_SCOPE( "build_node_to_edge_connectivity" ) { build_node_to_edge_connectivity(mesh); } scalar_field = nodes_fs.createField( option::name("field") | option::levels(nlev) ); grad_field = nodes_fs.createField( option::name("grad") | option::levels(nlev) | option::variables(3) ); @@ -382,8 +382,8 @@ void AtlasBenchmark::setup() void AtlasBenchmark::iteration() { - Timer t( Here() ); - Timer compute( Here(), "compute" ); + Trace t( Here() ); + Trace compute( Here(), "compute" ); unique_ptr avgS_arr( array::Array::create(nedges,nlev,2ul) ); const auto& node2edge = mesh.nodes().edge_connectivity(); const auto& edge2node = mesh.edges().node_connectivity(); @@ -465,7 +465,7 @@ void AtlasBenchmark::iteration() compute.stop(); // halo-exchange - Timer halo( Here(), "halo-exchange"); + Trace halo( Here(), "halo-exchange"); nodes_fs.halo_exchange().execute(grad); halo.stop(); @@ -521,7 +521,7 @@ double AtlasBenchmark::result() } } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(maxval, eckit::mpi::max()); parallel::mpi::comm().allReduceInPlace(minval, eckit::mpi::min()); parallel::mpi::comm().allReduceInPlace(norm, eckit::mpi::sum()); diff --git a/src/apps/atlas.cc b/src/apps/atlas.cc index 580185764..41d09efc1 100644 --- a/src/apps/atlas.cc +++ b/src/apps/atlas.cc @@ -43,7 +43,7 @@ void Version::run() } else if( Resource("--info",false) ) { - Log::info() << atlas::Library::instance().info() << std::endl; + Log::info() << atlas::Library::instance().information() << std::endl; return; } else if( Resource("--help",false) ) diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index f4508c95c..f5d48ac6b 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -33,14 +33,16 @@ runtime/ErrorHandling.cc runtime/AtlasTool.h runtime/AtlasTool.cc runtime/Log.h -runtime/Timer.h +runtime/Trace.h +runtime/timer/CallStack.h +runtime/timer/CallStack.cc runtime/timer/TimerT.h runtime/timer/TimerNesting.cc runtime/timer/TimerNesting.h runtime/timer/TimerBarriers.cc runtime/timer/TimerBarriers.h -runtime/timer/TimerLogging.cc -runtime/timer/TimerLogging.h +runtime/timer/TimerTracing.cc +runtime/timer/TimerTracing.h runtime/timer/Timings.h runtime/timer/Timings.cc parallel/mpi/mpi.cc @@ -432,8 +434,6 @@ util/Metadata.cc util/Metadata.h util/Rotation.cc util/Rotation.h -util/detail/CallStack.h -util/detail/CallStack.cc util/detail/BlackMagic.h ) diff --git a/src/atlas/field/FieldCreatorIFS.cc b/src/atlas/field/FieldCreatorIFS.cc index 0b5069d15..87e2dc7fe 100644 --- a/src/atlas/field/FieldCreatorIFS.cc +++ b/src/atlas/field/FieldCreatorIFS.cc @@ -64,7 +64,7 @@ FieldImpl* FieldCreatorIFS::createField( const eckit::Parametrisation& params ) std::string name; params.get("name",name); - Log::debug() << "Creating IFS "<::const_iterator j = m->find(name); - Log::debug() << "Looking for StateGeneratorFactory [" << name << "]" << std::endl; + Log::debug() << "Looking for StateGeneratorFactory [" << name << "]" << std::endl; if (j == m->end()) { Log::error() << "No StateGeneratorFactory for [" << name << "]" << std::endl; diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 24119fde8..be1adc932 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -27,7 +27,7 @@ #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/Checksum.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/array/MakeView.h" #ifdef ATLAS_HAVE_FORTRAN @@ -172,7 +172,7 @@ EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo &halo) : void EdgeColumns::constructor() { - ATLAS_TIME("EdgeColumns()"); + ATLAS_TRACE("EdgeColumns()"); nb_edges_ = mesh().edges().size(); @@ -184,7 +184,7 @@ void EdgeColumns::constructor() const Field& remote_index = edges().remote_index(); const Field& global_index = edges().global_index(); - ATLAS_TIME_SCOPE("Setup halo_exchange") + ATLAS_TRACE_SCOPE("Setup halo_exchange") { halo_exchange_->setup( array::make_view(partition).data(), @@ -192,7 +192,7 @@ void EdgeColumns::constructor() nb_edges_); } - ATLAS_TIME_SCOPE("Setup gather_scatter") + ATLAS_TRACE_SCOPE("Setup gather_scatter") { gather_scatter_->setup( array::make_view(partition).data(), @@ -201,7 +201,7 @@ void EdgeColumns::constructor() nb_edges_); } - ATLAS_TIME_SCOPE("Setup checksum") + ATLAS_TRACE_SCOPE("Setup checksum") { checksum_->setup( array::make_view(partition).data(), diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index ea000e2df..cf3cd37ce 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -30,7 +30,7 @@ #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #undef atlas_omp_critical_ordered #define atlas_omp_critical_ordered atlas_omp_critical #include "atlas/array/ArrayView.h" @@ -101,7 +101,7 @@ NodeColumns::NodeColumns( Mesh& mesh, const eckit::Configuration & config ) : nb_levels_( config.getInt("levels",0) ), nb_nodes_(nodes_.size()), nb_nodes_global_(0) { - ATLAS_TIME(); + ATLAS_TRACE(); constructor(); } @@ -132,7 +132,7 @@ void NodeColumns::constructor() } } - ATLAS_TIME_SCOPE("HaloExchange") + ATLAS_TRACE_SCOPE("HaloExchange") { Field& part = mesh_.nodes().partition(); Field& ridx = mesh_.nodes().remote_index(); @@ -141,7 +141,7 @@ void NodeColumns::constructor() REMOTE_IDX_BASE,nb_nodes_); } - ATLAS_TIME_SCOPE("GatherScatter") + ATLAS_TRACE_SCOPE("GatherScatter") { // Create new gather_scatter gather_scatter_.reset( new parallel::GatherScatter() ); @@ -168,7 +168,7 @@ void NodeColumns::constructor() mask.data(),nb_nodes_); } - ATLAS_TIME_SCOPE("Checksum") + ATLAS_TRACE_SCOPE("Checksum") { // Create new checksum @@ -582,7 +582,7 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, size_t& local_sum += arr(n,l); } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); } @@ -661,7 +661,7 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& re } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); } @@ -763,7 +763,7 @@ void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& s } } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(sum_per_level.data(), sum.size(), eckit::mpi::sum()); } N = fs.nb_nodes_global(); @@ -798,7 +798,7 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs , const Field& fie result = std::accumulate(array::make_storageview(global).data(), array::make_storageview(global).data()+global.size(),0.); - ATLAS_MPI_STATS( BROADCAST ) { + ATLAS_TRACE_MPI( BROADCAST ) { parallel::mpi::comm().broadcast(&result, 1, root); } N = fs.nb_nodes_global(); @@ -885,7 +885,7 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& fiel } } size_t root = global.metadata().get("owner"); - ATLAS_MPI_STATS( BROADCAST ) { + ATLAS_TRACE_MPI( BROADCAST ) { parallel::mpi::comm().broadcast(result,root); } N = fs.nb_nodes_global(); @@ -995,7 +995,7 @@ void dispatch_order_independent_sum_per_level( const NodeColumns& fs, const Fiel } } } - ATLAS_MPI_STATS( BROADCAST ) { + ATLAS_TRACE_MPI( BROADCAST ) { parallel::mpi::comm().broadcast( array::make_storageview(sumfield).data(),sumfield.size(),root); } N = fs.nb_nodes_global(); @@ -1046,7 +1046,7 @@ void dispatch_minimum( const NodeColumns& fs, const Field& field, std::vector } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduce(local_minimum, min, eckit::mpi::min()); } } @@ -1115,7 +1115,7 @@ void dispatch_maximum( const NodeColumns& fs, const Field& field, std::vector } } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduce(local_maximum, max, eckit::mpi::max()); } } @@ -1222,7 +1222,7 @@ void dispatch_minimum_per_level( const NodeColumns& fs, const Field& field, Fiel } } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(min.data(),min_field.size(),eckit::mpi::min()); } } @@ -1294,7 +1294,7 @@ void dispatch_maximum_per_level( const NodeColumns& fs, const Field& field, Fiel } } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(max.data(),max_field.size(),eckit::mpi::max()); } } @@ -1372,7 +1372,7 @@ void dispatch_minimum_and_location( const NodeColumns& fs, const Field& field, s min_and_level_loc[j] = std::make_pair(local_minimum[j],loc_level[j]); } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduce(min_and_gidx_loc, min_and_gidx_glb, eckit::mpi::minloc()); parallel::mpi::comm().allReduce(min_and_level_loc,min_and_level_glb,eckit::mpi::minloc()); } @@ -1478,7 +1478,7 @@ void dispatch_maximum_and_location( const NodeColumns& fs, const Field& field, s max_and_level_loc[j] = std::make_pair(local_maximum[j],loc_level[j]); } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduce(max_and_gidx_loc, max_and_gidx_glb, eckit::mpi::maxloc()); parallel::mpi::comm().allReduce(max_and_level_loc,max_and_level_glb,eckit::mpi::maxloc()); } @@ -1655,7 +1655,7 @@ void dispatch_minimum_and_location_per_level( const NodeColumns& fs, const Field } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduce(min_and_gidx_loc,min_and_gidx_glb,eckit::mpi::minloc()); } @@ -1764,7 +1764,7 @@ void dispatch_maximum_and_location_per_level( const NodeColumns& fs, const Field } } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduce(max_and_gidx_loc,max_and_gidx_glb,eckit::mpi::maxloc()); } diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index ca208f97e..9c2218002 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -22,7 +22,7 @@ #include "atlas/util/CoordinateEnums.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Debug.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/Checksum.h" @@ -204,7 +204,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& grid_(grid), nb_levels_(0) { - ATLAS_TIME( "Generating StructuredColumns..." ); + ATLAS_TRACE( "Generating StructuredColumns..." ); nb_levels_ = config_levels(config); if ( not grid_ ) { @@ -226,7 +226,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& } grid::Distribution distribution; - ATLAS_TIME_SCOPE( "Partitioning grid ..." ) { + ATLAS_TRACE_SCOPE( "Partitioning grid ..." ) { distribution = grid::Distribution(grid,partitioner); } @@ -351,12 +351,12 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& }; if( atlas::Library::instance().debug() ) { - ATLAS_TIME_SCOPE("Load imbalance") { + ATLAS_TRACE_SCOPE("Load imbalance") { comm.barrier(); } } - ATLAS_TIME_SCOPE( "Compute mapping ..." ) + ATLAS_TRACE_SCOPE( "Compute mapping ..." ) { idx_t imin = std::numeric_limits::max(); idx_t imax = -std::numeric_limits::max(); @@ -433,7 +433,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& } } - ATLAS_TIME_SCOPE("Parallelisation ...") + ATLAS_TRACE_SCOPE("Parallelisation ...") { auto build_partition_graph = [this]() -> std::unique_ptr { @@ -462,12 +462,12 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& }; std::unique_ptr graph_ptr; - ATLAS_TIME_SCOPE( "Building partition graph..." ) { + ATLAS_TRACE_SCOPE( "Building partition graph..." ) { graph_ptr = build_partition_graph(); } const Mesh::PartitionGraph& graph = *graph_ptr; - ATLAS_TIME_SCOPE( "Setup parallel fields..." ) + ATLAS_TRACE_SCOPE( "Setup parallel fields..." ) { auto p = array::make_view< int, 1 >( partition() ); auto g = array::make_view< gidx_t, 1 >( global_index() ); @@ -561,19 +561,19 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& } } - ATLAS_TIME_SCOPE( "Setup gather_scatter..." ) + ATLAS_TRACE_SCOPE( "Setup gather_scatter..." ) { gather_scatter_ = new parallel::GatherScatter(); gather_scatter_->setup(part.data(), remote_idx.data(), 0, global_idx.data(), size_owned_ ); } - ATLAS_TIME_SCOPE( "Setup checksum..." ) + ATLAS_TRACE_SCOPE( "Setup checksum..." ) { checksum_ = new parallel::Checksum(); checksum_->setup(part.data(), remote_idx.data(), 0, global_idx.data(), size_owned_ ); } - ATLAS_TIME_SCOPE( "Setup halo exchange..." ) + ATLAS_TRACE_SCOPE( "Setup halo exchange..." ) { halo_exchange_ = new parallel::HaloExchange(); halo_exchange_->setup(part.data(),remote_idx.data(),0,size_halo_); diff --git a/src/atlas/grid/Partitioner.cc b/src/atlas/grid/Partitioner.cc index a422105d8..b8efad014 100644 --- a/src/atlas/grid/Partitioner.cc +++ b/src/atlas/grid/Partitioner.cc @@ -11,7 +11,7 @@ #include "atlas/grid/Partitioner.h" #include "atlas/grid/detail/partitioner/Partitioner.h" #include "atlas/parallel/mpi/mpi.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" namespace atlas { namespace grid { @@ -50,7 +50,7 @@ Partitioner::Partitioner( const Config& config ): } void Partitioner::partition(const Grid &grid, int part[]) const { - ATLAS_TIME(); + ATLAS_TRACE(); partitioner_->partition(grid,part); } diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index 50dc4bae3..920417565 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -17,7 +17,7 @@ #include "atlas/grid/Grid.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" #include "atlas/util/MicroDeg.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" using atlas::util::microdeg; @@ -430,7 +430,7 @@ bool compare_WE_NS(const EqualRegionsPartitioner::NodeInt& node1, const EqualReg void EqualRegionsPartitioner::partition( int nb_nodes, NodeInt nodes[], int part[] ) const { - ATLAS_TIME( "EqualRegionsPartitioner::partition" ); + ATLAS_TRACE( "EqualRegionsPartitioner::partition" ); // std::clock_t init, final; diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc index b647f1858..0f4e34dc1 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc @@ -49,7 +49,7 @@ void MatchingMeshPartitionerLonLatPolygon::partition( const Grid& grid, int part ASSERT( grid.domain().global() ); - Log::debug() << "MatchingMeshPartitionerLonLatPolygon::partition" << std::endl; + Log::debug() << "MatchingMeshPartitionerLonLatPolygon::partition" << std::endl; // FIXME: THIS IS A HACK! the coordinates include North/South Pole (first/last partitions only) bool includesNorthPole = (mpi_rank == 0); diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc index 34829f4bb..dfee3d56a 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc @@ -48,7 +48,7 @@ void MatchingMeshPartitionerSphericalPolygon::partition( const Grid& grid, int p ASSERT( grid.domain().global() ); - Log::debug() << "MatchingMeshPartitionerSphericalPolygon::partition" << std::endl; + Log::debug() << "MatchingMeshPartitionerSphericalPolygon::partition" << std::endl; // FIXME: THIS IS A HACK! the coordinates include North/South Pole (first/last partitions only) bool includesNorthPole = (mpi_rank == 0); diff --git a/src/atlas/grid/detail/partitioner/Partitioner.cc b/src/atlas/grid/detail/partitioner/Partitioner.cc index 2d490a8ca..e5a4071c2 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.cc +++ b/src/atlas/grid/detail/partitioner/Partitioner.cc @@ -140,7 +140,7 @@ Partitioner* PartitionerFactory::build(const std::string& name) { std::map::const_iterator j = m->find(name); - Log::debug() << "Looking for PartitionerFactory [" << name << "]" << '\n'; + Log::debug() << "Looking for PartitionerFactory [" << name << "]" << '\n'; if (j == m->end()) { Log::error() << "No PartitionerFactory for [" << name << "]" << '\n'; @@ -163,7 +163,7 @@ Partitioner* PartitionerFactory::build(const std::string& name, const size_t nb_ std::map::const_iterator j = m->find(name); - Log::debug() << "Looking for PartitionerFactory [" << name << "]" << '\n'; + Log::debug() << "Looking for PartitionerFactory [" << name << "]" << '\n'; if (j == m->end()) { Log::error() << "No PartitionerFactory for [" << name << "]" << '\n'; diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index 65e5797ac..021cb950e 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -15,7 +15,7 @@ #include "atlas/trans/Trans.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/array.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" namespace atlas { namespace grid { @@ -47,7 +47,7 @@ TransPartitioner::~TransPartitioner() { void TransPartitioner::partition(const Grid& grid, int part[]) const { - ATLAS_TIME( "TransPartitioner::partition" ); + ATLAS_TRACE( "TransPartitioner::partition" ); StructuredGrid g(grid); if( not g ) diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc index b0e144c71..5d796bb32 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc @@ -248,7 +248,7 @@ void legpol_quadrature( //----------------------------------------------------------------------------- void compute_gaussian_quadrature_npole_equator(const size_t N, double lats[], double weights[]) { - Log::debug() << "Atlas computing Gaussian latitudes for N " << N << "\n"; + Log::debug() << "Atlas computing Gaussian latitudes for N " << N << "\n"; // Compute first guess for colatitudes in radians double z; diff --git a/src/atlas/interpolation/method/FiniteElement.cc b/src/atlas/interpolation/method/FiniteElement.cc index c9e348d40..5872add5a 100644 --- a/src/atlas/interpolation/method/FiniteElement.cc +++ b/src/atlas/interpolation/method/FiniteElement.cc @@ -27,7 +27,7 @@ #include "atlas/mesh/ElementType.h" #include "atlas/mesh/Nodes.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" #include "atlas/util/Point.h" @@ -56,7 +56,7 @@ static const double parametricEpsilon = 1e-15; } // (anonymous namespace) void FiniteElement::setup(const FunctionSpace& source, const FunctionSpace& target) { - ATLAS_TIME( "atlas::interpolation::method::FiniteElement::setup()" ); + ATLAS_TRACE( "atlas::interpolation::method::FiniteElement::setup()" ); if( functionspace::NodeColumns tgt = target ) { @@ -136,7 +136,7 @@ void FiniteElement::setup(const FunctionSpace& source) { { #if ECKIT_VERSION_INT > 1700 - eckit::ProgressTimer progress("Computing interpolation weights", out_npts, "point", double(5), Log::debug()); + eckit::ProgressTimer progress("Computing interpolation weights", out_npts, "point", double(5), Log::debug()); for ( size_t ip = 0; ip < out_npts; ++ip, ++progress ) { #else for ( size_t ip = 0; ip < out_npts; ++ip ) { @@ -167,14 +167,14 @@ void FiniteElement::setup(const FunctionSpace& source) { if (!success) { failures.push_back(ip); - Log::debug() << "---------------------------------------------------------------------------\n"; + Log::debug() << "---------------------------------------------------------------------------\n"; const PointLonLat pll = util::Earth::convertGeocentricToGeodetic(p); - Log::debug() << "Failed to project point (lon,lat)="<< pll << '\n'; - Log::debug() << failures_log.str(); + Log::debug() << "Failed to project point (lon,lat)="<< pll << '\n'; + Log::debug() << failures_log.str(); } } } - Log::debug() << "Maximum neighbours searched was " << eckit::Plural(max_neighbours, "element") << std::endl; + Log::debug() << "Maximum neighbours searched was " << eckit::Plural(max_neighbours, "element") << std::endl; eckit::mpi::comm().barrier(); diff --git a/src/atlas/interpolation/method/KNearestNeighbours.cc b/src/atlas/interpolation/method/KNearestNeighbours.cc index f4c478268..049f39baf 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.cc +++ b/src/atlas/interpolation/method/KNearestNeighbours.cc @@ -16,7 +16,7 @@ #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/functionspace/NodeColumns.h" @@ -66,7 +66,7 @@ void KNearestNeighbours::setup(const FunctionSpace& source, const FunctionSpace& std::vector< Triplet > weights_triplets; weights_triplets.reserve(out_npts * k_); { - Timer timer(Here(),"atlas::interpolation::method::NearestNeighbour::setup()"); + Trace timer(Here(),"atlas::interpolation::method::NearestNeighbour::setup()"); std::vector weights; @@ -74,7 +74,7 @@ void KNearestNeighbours::setup(const FunctionSpace& source, const FunctionSpace& if (ip && (ip % 1000 == 0)) { double rate = ip / timer.elapsed(); - Log::debug() << eckit::BigNum(ip) << " (at " << rate << " points/s)..." << std::endl; + Log::debug() << eckit::BigNum(ip) << " (at " << rate << " points/s)..." << std::endl; } // find the closest input points to the output point diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.cc b/src/atlas/interpolation/method/KNearestNeighboursBase.cc index e46aa84e9..570e2b90d 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.cc +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.cc @@ -16,7 +16,7 @@ #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/mesh/Nodes.h" #include "atlas/library/Library.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #ifdef ECKIT_VERSION_INT diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index 43cc74a30..19d88842f 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -22,7 +22,7 @@ #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" namespace atlas { namespace interpolation { @@ -84,13 +84,13 @@ Method* MethodFactory::build(const std::string& name, const Method::Config& conf void Method::execute(const FieldSet& fieldsSource, FieldSet& fieldsTarget) const { - ATLAS_TIME( "atlas::interpolation::method::Method::execute()" ); + ATLAS_TRACE( "atlas::interpolation::method::Method::execute()" ); const size_t N = fieldsSource.size(); ASSERT(N == fieldsTarget.size()); for (size_t i = 0; i < fieldsSource.size(); ++i) { - Log::debug() << "Method::execute() on field " << (i+1) << '/' << N << "..." << std::endl; + Log::debug() << "Method::execute() on field " << (i+1) << '/' << N << "..." << std::endl; const Field& src = fieldsSource[i]; Field& tgt = fieldsTarget[i]; @@ -104,7 +104,7 @@ void Method::execute(const FieldSet& fieldsSource, FieldSet& fieldsTarget) const void Method::execute(const Field& fieldSource, Field& fieldTarget) const { - ATLAS_TIME( "atlas::interpolation::method::Method::execute()" ); + ATLAS_TRACE( "atlas::interpolation::method::Method::execute()" ); eckit::linalg::Vector v_src(const_cast< Field& >(fieldSource).data(), fieldSource.shape(0)), diff --git a/src/atlas/interpolation/method/NearestNeighbour.cc b/src/atlas/interpolation/method/NearestNeighbour.cc index 4b4f000bd..3385defda 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.cc +++ b/src/atlas/interpolation/method/NearestNeighbour.cc @@ -15,7 +15,7 @@ #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/functionspace/NodeColumns.h" namespace atlas { @@ -58,12 +58,12 @@ void NearestNeighbour::setup(const FunctionSpace& source, const FunctionSpace& t std::vector< Triplet > weights_triplets; weights_triplets.reserve(out_npts); { - Timer timer( Here(), "atlas::interpolation::method::NearestNeighbour::setup()" ); + Trace timer( Here(), "atlas::interpolation::method::NearestNeighbour::setup()" ); for (size_t ip = 0; ip < out_npts; ++ip) { if (ip && (ip % 1000 == 0)) { double rate = ip / timer.elapsed(); - Log::debug() << eckit::BigNum(ip) << " (at " << rate << " points/s)..." << std::endl; + Log::debug() << eckit::BigNum(ip) << " (at " << rate << " points/s)..." << std::endl; } // find the closest input point to the output point diff --git a/src/atlas/interpolation/method/PointSet.h b/src/atlas/interpolation/method/PointSet.h index 2ddfe6afa..201086bf4 100644 --- a/src/atlas/interpolation/method/PointSet.h +++ b/src/atlas/interpolation/method/PointSet.h @@ -23,7 +23,7 @@ #include "eckit/config/Resource.h" #include "atlas/interpolation/method/PointIndex3.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/mesh/Mesh.h" #include "eckit/eckit_version.h" @@ -61,7 +61,7 @@ class PointSet { template < typename POINT_T > void list_unique_points( std::vector< POINT_T >& opts ) { - ATLAS_TIME( "Finding unique points" ); + ATLAS_TRACE( "Finding unique points" ); ASSERT( opts.empty() ); diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 8d03a5cec..3f6f3b6a5 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -26,6 +26,8 @@ #include "eckit/filesystem/PathName.h" #include "eckit/filesystem/LocalPathName.h" #include "eckit/utils/Translator.h" +#include "eckit/log/PrefixTarget.h" +#include "eckit/log/OStreamTarget.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" @@ -33,7 +35,7 @@ #include "atlas/library/Library.h" #include "atlas/library/version.h" #include "atlas/library/git_sha1.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" using eckit::PathName; using eckit::Main; @@ -88,23 +90,37 @@ void Library::initialise(int argc, char **argv) { Main::initialise(argc, argv); Main::instance().taskID( eckit::mpi::comm("world").rank() ); if( Main::instance().taskID() != 0 ) Log::reset(); - Log::debug() << "Atlas initialised eckit::Main.\n"; + Log::debug() << "Atlas initialised eckit::Main.\n"; if( eckit::mpi::comm("world").size() > 1 ) - Log::debug() << + Log::debug() << "--> Only MPI rank 0 is logging. Please initialise eckit::Main \n" " before to avoid this behaviour.\n"; } initialise(); } +namespace{ + bool getEnv( const std::string& env, bool default_value ) { + if (::getenv( env.c_str() ) ) { + return eckit::Translator()(::getenv( env.c_str() )); + } + return default_value; + } +} void Library::initialise(const eckit::Parametrisation& config) { - // Timer configuration - config.get("timer.barriers",timer_.barriers_); - timer_.channel_ = &Log::debug(); + if( not config.get("trace",info_) ) { + info_ = getEnv("ATLAS_INFO",info_); + } + if( not config.get("trace",trace_) ) { + trace_ = getEnv("ATLAS_TRACE",trace_); + } + if( not config.get("barriers",barriers_) ) { + barriers_ = getEnv("ATLAS_BARRIERS",barriers_); + } // Summary - std::ostream& out = Log::debug(); + std::ostream& out = Log::debug(); out << "Executable [" << Main::instance().name() << "]\n"; out << " \n"; out << " current dir [" << PathName(LocalPathName::cwd()).fullName() << "]\n"; @@ -113,25 +129,17 @@ void Library::initialise(const eckit::Parametrisation& config) { out << " communicator [" << parallel::mpi::comm() << "] \n"; out << " size [" << parallel::mpi::comm().size() << "] \n"; out << " rank [" << parallel::mpi::comm().rank() << "] \n"; + out << " barriers [" << barriers() << "] \n"; out << " \n"; - out << " Timer\n"; - out << " barriers [" << str(timer_.barriers()) << "] \n"; + out << " trace [" << str(trace()) << "] \n"; + out << " debug [" << str(debug()) << "] \n"; out << " \n"; - out << atlas::Library::instance().info(); + out << atlas::Library::instance().information(); out << std::flush; } void Library::initialise() { - util::Config timer_config; - - if (::getenv("ATLAS_TIMER_BARRIERS")) { - bool var = eckit::Translator()(::getenv("ATLAS_TIMER_BARRIERS")); - timer_config.set("barriers",var); - } - - util::Config config; - config.set("timer",timer_config); - initialise( config ); + initialise( util::NoConfig() ); } void Library::finalise() { @@ -147,21 +155,41 @@ void Library::finalise() { } #endif - Log::debug() << "Atlas finalised\n"; + // Make sure that these specialised channels that wrap Log::info() are + // destroyed before Log::info gets destroyed. + // Just in case someone still tries to log, we reset to empty channels. + trace_channel_.reset( new eckit::Channel() ); + + Log::debug() << "Atlas finalised" << std::endl; + Log::flush(); } -bool Library::Timer::barriers() const { - return barriers_; +std::ostream& Library::traceChannel() const { + 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())))); + } else { + trace_channel_.reset( new eckit::Channel() ); + } + return *trace_channel_; } -std::ostream& Library::Timer::channel() const { - return *channel_; +std::ostream& Library::infoChannel() const { + if( info_channel_ ) return *info_channel_; + if( info_ ) { + return eckit::Log::info(); + } else { + info_channel_.reset( new eckit::Channel() ); + } + return *trace_channel_; } + //---------------------------------------------------------------------------------------------------------------------- -void Library::Info::print( std::ostream& out ) const { +void Library::Information::print( std::ostream& out ) const { out << "atlas version (" << atlas::Library::instance().version() << "), " << "git-sha1 "<< atlas::Library::instance().gitsha1(7) << '\n'; out << " \n"; diff --git a/src/atlas/library/Library.h b/src/atlas/library/Library.h index 3b97e8b54..fd048bc46 100644 --- a/src/atlas/library/Library.h +++ b/src/atlas/library/Library.h @@ -12,6 +12,7 @@ #include #include +#include #include "eckit/system/Library.h" namespace eckit { @@ -39,30 +40,26 @@ class Library : public eckit::system::Library { void initialise(); void finalise(); - struct Info { - friend std::ostream& operator<<(std::ostream& s, const Info& i) { i.print(s); return s; } + struct Information { + friend std::ostream& operator<<(std::ostream& s, const Information& i) { i.print(s); return s; } void print(std::ostream&) const; }; - Info info() const { return Info(); } - - class Timer { - public: - bool barriers() const; - std::ostream& channel() const; - private: - friend class Library; - bool barriers_{false}; - std::ostream* channel_; - }; + Information information() const { return Information(); } - const Timer& timer() const { return timer_; } + std::ostream& infoChannel() const; + std::ostream& traceChannel() const; + bool trace() const { return trace_; } + bool barriers() const { return barriers_; } protected: virtual const void* addr() const override; - Timer timer_; - + bool info_{true}; + bool trace_{false}; + bool barriers_{false}; + mutable std::unique_ptr trace_channel_; + mutable std::unique_ptr info_channel_; }; typedef Library Atlas; diff --git a/src/atlas/library/config.h b/src/atlas/library/config.h index 5988ca2b2..6bdcfbe63 100644 --- a/src/atlas/library/config.h +++ b/src/atlas/library/config.h @@ -3,7 +3,7 @@ #include "atlas/atlas_ecbuild_config.h" #include "atlas/library/defines.h" -#define ATLAS_HAVE_TIMINGS 1 +#define ATLAS_HAVE_TRACE 1 namespace atlas { diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.cc b/src/atlas/mesh/actions/BuildConvexHull3D.cc index f9128b83d..95ed76133 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.cc +++ b/src/atlas/mesh/actions/BuildConvexHull3D.cc @@ -41,7 +41,7 @@ const Point_3 origin = Point_3(CGAL::ORIGIN); #endif #include "atlas/grid/Grid.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/HybridElements.h" @@ -69,7 +69,7 @@ namespace actions { static Polyhedron_3* create_convex_hull_from_points( const std::vector< Point3 >& pts ) { - ATLAS_TIME(); + ATLAS_TRACE(); Polyhedron_3* poly = new Polyhedron_3(); @@ -88,7 +88,7 @@ static Polyhedron_3* create_convex_hull_from_points( const std::vector< Point3 > static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, PointSet& points ) { - ATLAS_TIME(); + ATLAS_TRACE(); bool ensure_outward_normals = true; @@ -193,7 +193,7 @@ void BuildConvexHull3D::operator()( Mesh& mesh ) const if( mesh.cells().size() ) return; - ATLAS_TIME(); + ATLAS_TRACE(); // remove duplicate points diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index b8896548a..94e1177a7 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -29,7 +29,7 @@ #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" #include "atlas/runtime/ErrorHandling.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/parallel/Checksum.h" using atlas::functionspace::NodeColumns; @@ -43,7 +43,7 @@ namespace { void global_bounding_box( const mesh::Nodes& nodes, double min[2], double max[2] ) { - ATLAS_TIME(); + ATLAS_TRACE(); array::ArrayView xy = array::make_view( nodes.xy() ); const int nb_nodes = nodes.size(); @@ -60,7 +60,7 @@ void global_bounding_box( const mesh::Nodes& nodes, double min[2], double max[2] max[YY] = std::max( max[YY], xy(node,YY) ); } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); parallel::mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); } @@ -106,7 +106,7 @@ void make_dual_normals_outward( Mesh& mesh ); void build_median_dual_mesh( Mesh& mesh ) { - ATLAS_TIME(); + ATLAS_TRACE(); mesh::Nodes& nodes = mesh.nodes(); mesh::HybridElements& edges = mesh.edges(); @@ -136,13 +136,13 @@ void build_median_dual_mesh( Mesh& mesh ) functionspace::NodeColumns nodes_fs(mesh, Halo(mesh)); { - ATLAS_TIME("halo-exchange dual_volumes"); + ATLAS_TRACE("halo-exchange dual_volumes"); nodes_fs.haloExchange(nodes.field( "dual_volumes" )); } functionspace::EdgeColumns edges_fs(mesh, Halo(mesh)); { - ATLAS_TIME( "halo-exchange dual_normals" ); + ATLAS_TRACE( "halo-exchange dual_normals" ); edges_fs.haloExchange(edges.field( "dual_normals" )); } @@ -181,7 +181,7 @@ void add_median_dual_volume_contribution_cells( const mesh::Nodes& nodes, array::Array& array_dual_volumes ) { - ATLAS_TIME(); + ATLAS_TRACE(); array::ArrayView dual_volumes = array::make_view ( array_dual_volumes ); @@ -229,7 +229,7 @@ void add_median_dual_volume_contribution_poles( const mesh::Nodes& nodes, array::Array& array_dual_volumes ) { - ATLAS_TIME(); + ATLAS_TRACE(); array::ArrayView dual_volumes = array::make_view( array_dual_volumes ); const array::ArrayView xy = array::make_view( nodes.xy() ); @@ -286,7 +286,7 @@ void add_median_dual_volume_contribution_poles( void build_dual_normals( Mesh& mesh ) { - ATLAS_TIME(); + ATLAS_TRACE(); array::ArrayView elem_centroids = array::make_view( mesh.cells().field("centroids_xy") ); @@ -389,7 +389,7 @@ void build_dual_normals( Mesh& mesh ) void make_dual_normals_outward( Mesh& mesh ) { - ATLAS_TIME(); + ATLAS_TRACE(); mesh::Nodes& nodes = mesh.nodes(); array::ArrayView node_xy = array::make_view( nodes.xy() ); diff --git a/src/atlas/mesh/actions/BuildEdges.cc b/src/atlas/mesh/actions/BuildEdges.cc index 071ebcafb..8d862c810 100644 --- a/src/atlas/mesh/actions/BuildEdges.cc +++ b/src/atlas/mesh/actions/BuildEdges.cc @@ -212,7 +212,7 @@ void accumulate_pole_edges( mesh::Nodes& nodes, std::vector& pole_edge_no max[YY] = std::max( max[YY], xy(node,YY) ); } - ATLAS_MPI_STATS( ALLREDUCE ) { + ATLAS_TRACE_MPI( ALLREDUCE ) { parallel::mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); parallel::mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); } diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 7f5527e25..06ce6c410 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -33,7 +33,7 @@ #include "atlas/array.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/mpi/Buffer.h" @@ -92,7 +92,7 @@ typedef std::vector< std::vector > Node2Elem; void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) { - ATLAS_TIME(); + ATLAS_TRACE(); const mesh::Nodes& nodes = mesh.nodes(); @@ -121,7 +121,7 @@ void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) void accumulate_partition_bdry_nodes_old( Mesh& mesh, std::vector& bdry_nodes ) { - ATLAS_TIME(); + ATLAS_TRACE(); std::set bdry_nodes_set; @@ -163,7 +163,7 @@ void accumulate_partition_bdry_nodes( Mesh& mesh, size_t halo, std::vector& /* deprecated */ accumulate_partition_bdry_nodes_old(mesh,bdry_nodes); #else - ATLAS_TIME(); + ATLAS_TRACE(); const Mesh::Polygon& polygon = mesh.polygon(halo); bdry_nodes = std::vector( polygon.begin(), polygon.end() ); #endif @@ -224,7 +224,7 @@ class Notification typedef std::map Uid2Node; void build_lookup_uid2node( Mesh& mesh, Uid2Node& uid2node ) { - ATLAS_TIME(); + ATLAS_TRACE(); Notification notes; mesh::Nodes& nodes = mesh.nodes(); array::ArrayView xy = array::make_view ( nodes.xy() ); @@ -260,7 +260,7 @@ void accumulate_elements( const Mesh& mesh, std::vector& found_elements, std::set< uid_t >& new_nodes_uid ) { - ATLAS_TIME(); + ATLAS_TRACE(); const mesh::HybridElements::Connectivity &elem_nodes = mesh.cells().node_connectivity(); const array::ArrayView elem_part = array::make_view( mesh.cells().partition() ); @@ -389,7 +389,7 @@ class BuildHaloHelper static void all_to_all(Buffers& send, Buffers& recv) { - ATLAS_TIME( "all_to_all" ); + ATLAS_TRACE( "all_to_all" ); const eckit::mpi::Comm& comm = parallel::mpi::comm(); comm.allToAll(send.node_glb_idx, recv.node_glb_idx); @@ -532,7 +532,7 @@ class BuildHaloHelper template< typename NodeContainer, typename ElementContainer > void fill_sendbuffer(Buffers& buf,const NodeContainer& nodes_uid, const ElementContainer& elems, const PeriodicTransform& transform, int newflags, const int p) { - ATLAS_TIME(); + ATLAS_TRACE(); int nb_nodes = nodes_uid.size(); buf.node_glb_idx[p].resize(nb_nodes); @@ -607,7 +607,7 @@ class BuildHaloHelper void add_nodes(Buffers& buf, bool periodic ) { - ATLAS_TIME(); + ATLAS_TRACE(); mesh::Nodes& nodes = mesh.nodes(); int nb_nodes = nodes.size(); @@ -616,7 +616,7 @@ class BuildHaloHelper std::vector node_uid(nb_nodes); std::set new_node_uid; { - ATLAS_TIME( "compute node_uid" ); + ATLAS_TRACE( "compute node_uid" ); for( int jnode=0; jnode elem_uid(nb_elems); std::set new_elem_uid; { - ATLAS_TIME( "compute elem_uid" ); + ATLAS_TRACE( "compute elem_uid" ); for( int jelem=0; jelemrow(jelem)); } @@ -819,14 +819,14 @@ namespace { void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, bool periodic = false ) { #ifndef ATLAS_103 /* deprecated */ - ATLAS_TIME( "gather_bdry_nodes old way" ); + ATLAS_TRACE( "gather_bdry_nodes old way" ); { - ATLAS_MPI_STATS( ALLGATHER ) { + ATLAS_TRACE_MPI( ALLGATHER ) { parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); } } #else - ATLAS_TIME(); + ATLAS_TRACE(); Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); if( periodic ) { // add own rank to neighbours to allow periodicity with self (pole caps) @@ -947,7 +947,7 @@ void increase_halo_interior( BuildHaloHelper& helper ) // 6) Adapt mesh #ifdef DEBUG_OUTPUT - Log::debug() << "recv: \n" << recvmesh << std::endl; + Log::debug() << "recv: \n" << recvmesh << std::endl; #endif helper.add_buffers(recvmesh); } @@ -1054,7 +1054,7 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri // 6) Adapt mesh #ifdef DEBUG_OUTPUT - Log::debug() << "recv: \n" << recvmesh << std::endl; + Log::debug() << "recv: \n" << recvmesh << std::endl; #endif helper.add_buffers(recvmesh, /* periodic = */ true ); @@ -1062,7 +1062,7 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri void BuildHalo::operator () ( int nb_elems ) { - ATLAS_TIME( "BuildHalo" ); + ATLAS_TRACE( "BuildHalo" ); int halo = 0; mesh_.metadata().get("halo",halo); @@ -1070,16 +1070,16 @@ void BuildHalo::operator () ( int nb_elems ) if( halo == nb_elems ) return; - ATLAS_TIME( "Increasing mesh halo" ); + ATLAS_TRACE( "Increasing mesh halo" ); for(int jhalo=halo ; jhalo() << "Increase halo " << jhalo+1 << std::endl; + Log::debug() << "Increase halo " << jhalo+1 << std::endl; size_t nb_nodes_before_halo_increase = mesh_.nodes().size(); BuildHaloHelper helper(*this,mesh_); - ATLAS_TIME_SCOPE( "increase_halo_interior" ) + ATLAS_TRACE_SCOPE( "increase_halo_interior" ) { increase_halo_interior( helper ); } @@ -1087,18 +1087,18 @@ void BuildHalo::operator () ( int nb_elems ) PeriodicPoints westpts(mesh_,Topology::PERIODIC|Topology::WEST,nb_nodes_before_halo_increase); #ifdef DEBUG_OUTPUT - Log::debug() << " periodic west : " << westpts << std::endl; + Log::debug() << " periodic west : " << westpts << std::endl; #endif - ATLAS_TIME_SCOPE( "increase_halo_periodic West" ) { + ATLAS_TRACE_SCOPE( "increase_halo_periodic West" ) { increase_halo_periodic( helper, westpts, WestEast(), Topology::PERIODIC|Topology::WEST|Topology::GHOST ); } PeriodicPoints eastpts(mesh_,Topology::PERIODIC|Topology::EAST,nb_nodes_before_halo_increase); #ifdef DEBUG_OUTPUT - Log::debug() << " periodic east : " << eastpts << std::endl; + Log::debug() << " periodic east : " << eastpts << std::endl; #endif - ATLAS_TIME_SCOPE( "increase_halo_periodic East" ) { + ATLAS_TRACE_SCOPE( "increase_halo_periodic East" ) { increase_halo_periodic( helper, eastpts, EastWest(), Topology::PERIODIC|Topology::EAST|Topology::GHOST ); } diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 94cdbfeeb..5b09a26d2 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -25,7 +25,7 @@ #include "atlas/array.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/ErrorHandling.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/GatherScatter.h" @@ -91,7 +91,7 @@ struct Node void build_parallel_fields( Mesh& mesh ) { - ATLAS_TIME(); + ATLAS_TRACE(); build_nodes_parallel_fields( mesh.nodes() ); } @@ -99,7 +99,7 @@ void build_parallel_fields( Mesh& mesh ) void build_nodes_parallel_fields( mesh::Nodes& nodes ) { - ATLAS_TIME(); + ATLAS_TRACE(); bool parallel = false; nodes.metadata().get("parallel",parallel); if( ! parallel ) @@ -115,7 +115,7 @@ void build_nodes_parallel_fields( mesh::Nodes& nodes ) void build_edges_parallel_fields( Mesh& mesh ) { - ATLAS_TIME(); + ATLAS_TRACE(); build_edges_partition ( mesh ); build_edges_remote_idx( mesh ); build_edges_global_idx( mesh ); @@ -125,7 +125,7 @@ void build_edges_parallel_fields( Mesh& mesh ) Field& build_nodes_global_idx( mesh::Nodes& nodes ) { - ATLAS_TIME(); + ATLAS_TRACE(); array::ArrayView glb_idx = array::make_view( nodes.global_index() ); @@ -141,7 +141,7 @@ Field& build_nodes_global_idx( mesh::Nodes& nodes ) void renumber_nodes_glb_idx( mesh::Nodes& nodes ) { - ATLAS_TIME(); + ATLAS_TRACE(); // TODO: ATLAS-14: fix renumbering of EAST periodic boundary points // --> Those specific periodic points at the EAST boundary are not checked for uid, @@ -181,7 +181,7 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - ATLAS_MPI_STATS( GATHER ) { + ATLAS_TRACE_MPI( GATHER ) { parallel::mpi::comm().gather(nb_nodes, recvcounts, root); } @@ -195,7 +195,7 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) array::ArrayT glb_id_arr( glb_nb_nodes ); array::ArrayView glb_id = array::make_view(glb_id_arr); - ATLAS_MPI_STATS( GATHER ) { + ATLAS_TRACE_MPI( GATHER ) { parallel::mpi::comm().gatherv(loc_id.data(), loc_id.size(), glb_id.data(), recvcounts.data(), recvdispls.data(), root); } @@ -224,7 +224,7 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) } // 3) Scatter renumbered back - ATLAS_MPI_STATS( SCATTER ) { + ATLAS_TRACE_MPI( SCATTER ) { parallel::mpi::comm().scatterv(glb_id.data(), recvcounts.data(), recvdispls.data(), loc_id.data(), loc_id.size(), root); } @@ -238,7 +238,7 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) Field& build_nodes_remote_idx( mesh::Nodes& nodes ) { - ATLAS_TIME(); + ATLAS_TRACE(); size_t mypart = parallel::mpi::comm().rank(); size_t nparts = parallel::mpi::comm().size(); @@ -288,7 +288,7 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) } } - ATLAS_MPI_STATS( ALLTOALL ) { + ATLAS_TRACE_MPI( ALLTOALL ) { parallel::mpi::comm().allToAll(send_needed, recv_needed); } @@ -320,7 +320,7 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) } } - ATLAS_MPI_STATS( ALLTOALL ) { + ATLAS_TRACE_MPI( ALLTOALL ) { parallel::mpi::comm().allToAll(send_found, recv_found); } @@ -342,7 +342,7 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) Field& build_nodes_partition( mesh::Nodes& nodes ) { - ATLAS_TIME(); + ATLAS_TRACE(); return nodes.partition(); } @@ -350,7 +350,7 @@ Field& build_nodes_partition( mesh::Nodes& nodes ) Field& build_edges_partition( Mesh& mesh ) { - ATLAS_TIME(); + ATLAS_TRACE(); const mesh::Nodes& nodes = mesh.nodes(); @@ -533,7 +533,7 @@ Field& build_edges_partition( Mesh& mesh ) } - ATLAS_MPI_STATS( ALLTOALL ) { + ATLAS_TRACE_MPI( ALLTOALL ) { parallel::mpi::comm().allToAll(send_unknown, recv_unknown); } @@ -563,7 +563,7 @@ Field& build_edges_partition( Mesh& mesh ) } } - ATLAS_MPI_STATS( ALLTOALL ) { + ATLAS_TRACE_MPI( ALLTOALL ) { parallel::mpi::comm().allToAll(send_found, recv_found); } @@ -626,7 +626,7 @@ Field& build_edges_partition( Mesh& mesh ) Field& build_edges_remote_idx( Mesh& mesh ) { - ATLAS_TIME(); + ATLAS_TRACE(); const mesh::Nodes& nodes = mesh.nodes(); UniqueLonLat compute_uid(mesh); @@ -728,7 +728,7 @@ Field& build_edges_remote_idx( Mesh& mesh ) varsize=6; #endif - ATLAS_MPI_STATS( ALLTOALL ) { + ATLAS_TRACE_MPI( ALLTOALL ) { parallel::mpi::comm().allToAll(send_needed, recv_needed); } @@ -768,7 +768,7 @@ Field& build_edges_remote_idx( Mesh& mesh ) } } - ATLAS_MPI_STATS( ALLTOALL ) { + ATLAS_TRACE_MPI( ALLTOALL ) { parallel::mpi::comm().allToAll(send_found, recv_found); } @@ -788,7 +788,7 @@ Field& build_edges_remote_idx( Mesh& mesh ) Field& build_edges_global_idx( Mesh& mesh ) { - ATLAS_TIME(); + ATLAS_TRACE(); UniqueLonLat compute_uid(mesh); @@ -850,7 +850,7 @@ Field& build_edges_global_idx( Mesh& mesh ) std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - ATLAS_MPI_STATS( GATHER ) { + ATLAS_TRACE_MPI( GATHER ) { parallel::mpi::comm().gather(nb_edges, recvcounts, root); } @@ -864,7 +864,7 @@ Field& build_edges_global_idx( Mesh& mesh ) array::ArrayT glb_edge_id_arr(glb_nb_edges); array::ArrayView glb_edge_id = array::make_view(glb_edge_id_arr); - ATLAS_MPI_STATS( GATHER ) { + ATLAS_TRACE_MPI( GATHER ) { parallel::mpi::comm().gatherv(loc_edge_id.data(), loc_edge_id.size(), glb_edge_id.data(), recvcounts.data(), recvdispls.data(), root); } @@ -894,7 +894,7 @@ Field& build_edges_global_idx( Mesh& mesh ) } // 3) Scatter renumbered back - ATLAS_MPI_STATS( SCATTER ) { + ATLAS_TRACE_MPI( SCATTER ) { parallel::mpi::comm().scatterv(glb_edge_id.data(), recvcounts.data(), recvdispls.data(), loc_edge_id.data(), loc_edge_id.size(), root); } diff --git a/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc b/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc index b87f6f227..126ce4518 100644 --- a/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc +++ b/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc @@ -103,7 +103,7 @@ void build_periodic_boundaries( Mesh& mesh ) int sendcnt = slave_nodes.size(); std::vector< int > recvcounts( parallel::mpi::comm().size() ); - ATLAS_MPI_STATS( ALLGATHER ) { + ATLAS_TRACE_MPI( ALLGATHER ) { parallel::mpi::comm().allGather(sendcnt, recvcounts.begin(), recvcounts.end()); } @@ -117,7 +117,7 @@ void build_periodic_boundaries( Mesh& mesh ) } std::vector recvbuf(recvcnt); - ATLAS_MPI_STATS( ALLGATHER ) { + ATLAS_TRACE_MPI( ALLGATHER ) { parallel::mpi::comm().allGatherv(slave_nodes.begin(), slave_nodes.end(), recvbuf.begin(), recvcounts.data(), recvdispls.data()); } @@ -183,7 +183,7 @@ void build_periodic_boundaries( Mesh& mesh ) } // Communicate - ATLAS_MPI_STATS( ALLTOALL ) { + ATLAS_TRACE_MPI( ALLTOALL ) { parallel::mpi::comm().allToAll( send_slave_idx, recv_slave_idx ); parallel::mpi::comm().allToAll( send_master_part, recv_master_part ); parallel::mpi::comm().allToAll( send_master_ridx, recv_master_ridx ); diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc index b2ad2e499..1ba9a6d53 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc @@ -76,7 +76,7 @@ void write_load_balance_report( const Mesh& mesh, std::ostream& ofs ) /// @note this could be improved by packing the 3 integers in a vector, and doing only comm() call - ATLAS_MPI_STATS( GATHER ) { + ATLAS_TRACE_MPI( GATHER ) { parallel::mpi::comm().gather(nb_nodes, nb_total_nodes, root); parallel::mpi::comm().gather(nowned, nb_owned_nodes, root); parallel::mpi::comm().gather(nghost, nb_ghost_nodes, root); diff --git a/src/atlas/meshgenerator/MeshGenerator.cc b/src/atlas/meshgenerator/MeshGenerator.cc index 0c47afc2e..641f4f226 100644 --- a/src/atlas/meshgenerator/MeshGenerator.cc +++ b/src/atlas/meshgenerator/MeshGenerator.cc @@ -103,7 +103,7 @@ void MeshGeneratorImpl::generate_global_element_numbering( Mesh& mesh ) const std::vector elem_counts( parallel::mpi::comm().size() ); std::vector elem_displs( parallel::mpi::comm().size() ); - ATLAS_MPI_STATS( ALLGATHER ) { + ATLAS_TRACE_MPI( ALLGATHER ) { parallel::mpi::comm().allGather(loc_nb_elems, elem_counts.begin(), elem_counts.end()); } @@ -174,7 +174,7 @@ const MeshGenerator::Implementation *MeshGeneratorFactory::build(const std::stri std::map::const_iterator j = m->find(name); - Log::debug() << "Looking for MeshGeneratorFactory [" << name << "]" << std::endl; + Log::debug() << "Looking for MeshGeneratorFactory [" << name << "]" << std::endl; if (j == m->end()) { Log::error() << "No MeshGeneratorFactory for [" << name << "]" << std::endl; @@ -197,7 +197,7 @@ const MeshGenerator::Implementation *MeshGeneratorFactory::build(const std::stri std::map::const_iterator j = m->find(name); - Log::debug() << "Looking for MeshGeneratorFactory [" << name << "]" << std::endl; + Log::debug() << "Looking for MeshGeneratorFactory [" << name << "]" << std::endl; if (j == m->end()) { Log::error() << "No MeshGeneratorFactory for [" << name << "]" << std::endl; diff --git a/src/atlas/meshgenerator/RegularMeshGenerator.cc b/src/atlas/meshgenerator/RegularMeshGenerator.cc index 2c484e275..60bd2e081 100644 --- a/src/atlas/meshgenerator/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/RegularMeshGenerator.cc @@ -160,8 +160,8 @@ void RegularMeshGenerator::generate_mesh( bool periodic_x = options.get("periodic_x") or rg.periodic() ; bool periodic_y = options.get("periodic_y"); - Log::debug() << Here() << " periodic_x = " << periodic_x << std::endl; - Log::debug() << Here() << " periodic_y = " << periodic_y << std::endl; + Log::debug() << Here() << " periodic_x = " << periodic_x << std::endl; + Log::debug() << Here() << " periodic_y = " << periodic_y << std::endl; // for asynchronous output #if DEBUG_OUTPUT diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index ed2df9545..f2b4a658d 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -31,7 +31,7 @@ #include "atlas/field/Field.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" @@ -190,7 +190,7 @@ void StructuredMeshGenerator::hash(Hash& h) const void StructuredMeshGenerator::generate(const Grid& grid, const grid::Distribution& distribution, Mesh& mesh ) const { - ATLAS_TIME(); + ATLAS_TRACE(); const grid::StructuredGrid rg = grid::StructuredGrid(grid); if( !rg ) @@ -235,7 +235,7 @@ void StructuredMeshGenerator::generate(const Grid& grid, const grid::Distributio void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, const std::vector& parts, int mypart, Region& region) const { - ATLAS_TIME(); + ATLAS_TRACE(); double max_angle = options.get("angle"); bool triangulate_quads = options.get("triangulate"); @@ -804,7 +804,7 @@ struct GhostNode { void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, const std::vector& parts, const Region& region, Mesh& mesh) const { - ATLAS_TIME(); + ATLAS_TRACE(); ASSERT(!mesh.generated()); diff --git a/src/atlas/numerics/Nabla.cc b/src/atlas/numerics/Nabla.cc index 7d9aa31da..813dde023 100644 --- a/src/atlas/numerics/Nabla.cc +++ b/src/atlas/numerics/Nabla.cc @@ -153,7 +153,7 @@ const NablaImpl* NablaFactory::build(const Method& method, const eckit::Parametr std::map::const_iterator j = m->find(method.name()); - Log::debug() << "Looking for NablaFactory [" << method.name() << "]" << '\n'; + Log::debug() << "Looking for NablaFactory [" << method.name() << "]" << '\n'; if (j == m->end()) { Log::error() << "No NablaFactory for [" << method.name() << "]" << '\n'; diff --git a/src/atlas/numerics/fvm/Nabla.cc b/src/atlas/numerics/fvm/Nabla.cc index 20ef00d41..82a1e6a3c 100644 --- a/src/atlas/numerics/fvm/Nabla.cc +++ b/src/atlas/numerics/fvm/Nabla.cc @@ -41,7 +41,7 @@ Nabla::Nabla(const numerics::Method &method, const eckit::Parametrisation &p) : fvm_ = dynamic_cast(&method); if( ! fvm_ ) throw eckit::BadCast("atlas::numerics::fvm::Nabla needs a atlas::numerics::fvm::Method",Here()); - Log::debug() << "Nabla constructed for method " << fvm_->name() + Log::debug() << "Nabla constructed for method " << fvm_->name() << " with " << fvm_->node_columns().nb_nodes_global() << " nodes total" << std::endl; setup(); @@ -99,7 +99,7 @@ void Nabla::gradient(const Field &field, Field &grad_field) const void Nabla::gradient_of_scalar(const Field& scalar_field, Field& grad_field) const { - Log::debug() << "Compute gradient of scalar field " << scalar_field.name() << " with fvm method" << std::endl; + Log::debug() << "Compute gradient of scalar field " << scalar_field.name() << " with fvm method" << std::endl; const double radius = fvm_->radius(); const double deg2rad = M_PI/180.; @@ -179,7 +179,7 @@ void Nabla::gradient_of_scalar(const Field& scalar_field, Field& grad_field) con void Nabla::gradient_of_vector(const Field &vector_field, Field &grad_field) const { - Log::debug() << "Compute gradient of vector field " << vector_field.name() << " with fvm method" << std::endl; + Log::debug() << "Compute gradient of vector field " << vector_field.name() << " with fvm method" << std::endl; const double radius = fvm_->radius(); const double deg2rad = M_PI/180.; diff --git a/src/atlas/output/Gmsh.cc b/src/atlas/output/Gmsh.cc index 0bec28207..75b4f2b4f 100644 --- a/src/atlas/output/Gmsh.cc +++ b/src/atlas/output/Gmsh.cc @@ -223,7 +223,7 @@ void Gmsh::write( if( c.coordinates == "xyz" and not mesh.nodes().has_field("xyz") ) { - Log::debug() << "Building xyz representation for nodes" << std::endl; + Log::debug() << "Building xyz representation for nodes" << std::endl; mesh::actions::BuildXYZField("xyz")(const_cast(mesh)); } diff --git a/src/atlas/output/Output.cc b/src/atlas/output/Output.cc index 9f4bb478f..0c1d37dbf 100644 --- a/src/atlas/output/Output.cc +++ b/src/atlas/output/Output.cc @@ -146,7 +146,7 @@ const OutputImpl *OutputFactory::build(const std::string &name, Stream& stream) std::map::const_iterator j = m->find(name); - Log::debug() << "Looking for OutputFactory [" << name << "]" << std::endl; + Log::debug() << "Looking for OutputFactory [" << name << "]" << std::endl; if (j == m->end()) { Log::error() << "No OutputFactory for [" << name << "]" << std::endl; @@ -166,7 +166,7 @@ const OutputImpl *OutputFactory::build(const std::string& name, Stream& stream, std::map::const_iterator j = m->find(name); - Log::debug() << "Looking for OutputFactory [" << name << "]" << std::endl; + Log::debug() << "Looking for OutputFactory [" << name << "]" << std::endl; if (j == m->end()) { Log::error() << "No OutputFactory for [" << name << "]" << std::endl; diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index 879064832..1d477ba4b 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -107,7 +107,7 @@ void write_header_binary(std::ostream& out) template< typename DATATYPE > void write_field_nodes(const Metadata& gmsh_options, const functionspace::NodeColumns& function_space, const Field& field, std::ostream& out) { - Log::debug() << "writing field " << field.name() << " defined in NodeColumns..." << std::endl; + Log::debug() << "writing field " << field.name() << " defined in NodeColumns..." << std::endl; bool gather( gmsh_options.get("gather") ); bool binary( !gmsh_options.get("ascii") ); @@ -305,7 +305,7 @@ void write_field_nodes( const Field& field, std::ostream& out) { - Log::debug() << "writing field " << field.name() << "..." << std::endl; + Log::debug() << "writing field " << field.name() << "..." << std::endl; //bool gather(gmsh_options.get("gather")); bool binary(!gmsh_options.get("ascii")); @@ -876,7 +876,7 @@ void GmshIO::write(const Mesh& mesh, const PathName& file_path) const ASSERT(surfdim == 2 || surfdim == 3); - Log::debug() << "writing mesh to gmsh file " << file_path << std::endl; + Log::debug() << "writing mesh to gmsh file " << file_path << std::endl; bool binary = !options.get("ascii"); @@ -1161,7 +1161,7 @@ void GmshIO::write_delegate( for(size_t field_idx = 0; field_idx < fieldset.size(); ++field_idx) { const Field& field = fieldset[field_idx]; - Log::debug() << "writing field " << field.name() + Log::debug() << "writing field " << field.name() << " to gmsh file " << file_path << std::endl; if (field.datatype() == array::DataType::int32()) @@ -1212,7 +1212,7 @@ void GmshIO::write_delegate( for (size_t field_idx = 0; field_idx < fieldset.size(); ++field_idx) { const Field& field = fieldset[field_idx]; - Log::debug() << "writing field " << field.name() + Log::debug() << "writing field " << field.name() << " to gmsh file " << file_path << std::endl; if (field.datatype() == array::DataType::int32()) diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index 1ec5c3c5c..9f7cad986 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -15,7 +15,7 @@ #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/mpi/Statistics.h" @@ -117,7 +117,7 @@ void GatherScatter::setup( const int part[], } } - ATLAS_MPI_STATS( ALLGATHER ) { + ATLAS_TRACE_MPI( ALLGATHER ) { parallel::mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); } @@ -130,7 +130,7 @@ void GatherScatter::setup( const int part[], } std::vector recvnodes(glbcnt_); - ATLAS_MPI_STATS( ALLGATHER ) { + ATLAS_TRACE_MPI( ALLGATHER ) { parallel::mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, recvnodes.data(), glbcounts_.data(), glbdispls_.data()); } @@ -148,7 +148,7 @@ void GatherScatter::setup( const int part[], recvnodes.clear(); // Sort on "g" member, and remove duplicates - ATLAS_TIME_SCOPE("sorting") + ATLAS_TRACE_SCOPE("sorting") { std::sort(node_sort.begin(), node_sort.end()); node_sort.erase( std::unique( node_sort.begin(), node_sort.end() ), node_sort.end() ); diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index 7cb4045fe..c60752033 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -276,7 +276,7 @@ void GatherScatter::gather( parallel::Field lfields[], /// Gather - ATLAS_MPI_STATS( GATHER ) { + ATLAS_TRACE_MPI( GATHER ) { parallel::mpi::comm().gatherv(loc_buffer, glb_buffer, glb_counts, glb_displs, root); } @@ -337,7 +337,7 @@ void GatherScatter::scatter( parallel::Field gfields[], /// Scatter - ATLAS_MPI_STATS( SCATTER ) { + ATLAS_TRACE_MPI( SCATTER ) { parallel::mpi::comm().scatterv(glb_buffer.begin(), glb_buffer.end(), glb_counts, glb_displs, loc_buffer.begin(), loc_buffer.end(), root); } diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index b968be8e0..edbecdbae 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -65,7 +65,7 @@ void HaloExchange::setup( const int part[], const int remote_idx[], const int base, const size_t parsize ) { - ATLAS_TIME("HaloExchange::setup"); + ATLAS_TRACE("HaloExchange::setup"); parsize_ = parsize; sendcounts_.resize(nproc); sendcounts_.assign(nproc,0); @@ -90,7 +90,7 @@ void HaloExchange::setup( const int part[], /* Find the amount of nodes this proc has to send to each other proc */ - ATLAS_MPI_STATS( ALLTOALL ) { + ATLAS_TRACE_MPI( ALLTOALL ) { parallel::mpi::comm().allToAll(recvcounts_, sendcounts_); } @@ -130,7 +130,7 @@ void HaloExchange::setup( const int part[], */ std::vector recv_requests(sendcnt_); - ATLAS_MPI_STATS( ALLTOALL ) { + ATLAS_TRACE_MPI( ALLTOALL ) { parallel::mpi::comm().allToAllv(send_requests.data(), recvcounts_.data(), recvdispls_.data(), recv_requests.data(), sendcounts_.data(), senddispls_.data()); } diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 7919d9ea7..54325e798 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -118,7 +118,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const throw eckit::SeriousBug("HaloExchange was not setup",Here()); } - ATLAS_TIME("HaloExchange",{"halo-exchange"}); + ATLAS_TRACE("HaloExchange",{"halo-exchange"}); int tag=1; size_t var_size = std::accumulate(var_shape,var_shape+var_rank,1,std::multiplies()); @@ -143,7 +143,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const recv_displs[jproc] = recvdispls_[jproc]*var_size; } - ATLAS_MPI_STATS( IRECEIVE ) { + ATLAS_TRACE_MPI( IRECEIVE ) { /// Let MPI know what we like to receive for(int jproc=0; jproc < nproc; ++jproc) { @@ -158,7 +158,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const pack_send_buffer(field,var_strides,var_shape,var_rank,send_buffer.data()); /// Send - ATLAS_MPI_STATS( ISEND ) { + ATLAS_TRACE_MPI( ISEND ) { for(int jproc=0; jproc < nproc; ++jproc) { if(send_counts[jproc] > 0) @@ -171,7 +171,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const } /// Wait for receiving to finish - ATLAS_MPI_STATS( WAIT, "mpi-wait receive" ) { + ATLAS_TRACE_MPI( WAIT, "mpi-wait receive" ) { for (int jproc=0; jproc < nproc; ++jproc) { if( recvcounts_[jproc] > 0) @@ -185,7 +185,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const unpack_recv_buffer(recv_buffer.data(),field,var_strides,var_shape,var_rank); /// Wait for sending to finish - ATLAS_MPI_STATS( WAIT, "mpi-wait send" ) { + ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { for (int jproc=0; jproc < nproc; ++jproc) { if( sendcounts_[jproc] > 0) @@ -203,7 +203,7 @@ void HaloExchange::pack_send_buffer( const DATA_TYPE field[], size_t var_rank, DATA_TYPE send_buffer[] ) const { - ATLAS_TIME(); + ATLAS_TRACE(); size_t ibuf = 0; size_t send_stride = var_strides[0]*var_shape[0]; @@ -279,7 +279,7 @@ void HaloExchange::unpack_recv_buffer( const DATA_TYPE recv_buffer[], const size_t var_shape[], size_t var_rank ) const { - ATLAS_TIME(); + ATLAS_TRACE(); // bool field_changed = false; // DATA_TYPE tmp; size_t ibuf = 0; diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 181fd5195..625eddfc6 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -12,27 +12,18 @@ #include #include "atlas/parallel/mpi/mpi.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" -#define ATLAS_MPI_STATS(...) +#define ATLAS_TRACE_MPI(...) -#if ATLAS_HAVE_TIMINGS +#if ATLAS_HAVE_TRACE #include "atlas/util/detail/BlackMagic.h" -#undef ATLAS_MPI_STATS -#define ATLAS_MPI_STATS(...) ATLAS_MPI_STATS_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) -#define ATLAS_MPI_STATS_(N, ...) __ATLAS__SPLICE( ATLAS_MPI_STATS_, N)(__VA_ARGS__) -#define ATLAS_MPI_STATS_1( statistics_enum ) \ - for( ::atlas::parallel::mpi::Statistics __ATLAS__SPLICE( stats, __LINE__ ) \ - /*args=*/(Here(), ::atlas::parallel::mpi::StatisticsEnum::__ATLAS_STRINGIFY(statistics_enum) );\ - __ATLAS__SPLICE( stats, __LINE__ ) .running(); \ - __ATLAS__SPLICE( stats, __LINE__ ) .stop() ) -#define ATLAS_MPI_STATS_2(statistics_enum,title) \ - for( ::atlas::parallel::mpi::Statistics __ATLAS__SPLICE( stats, __LINE__ ) \ - /*args=*/(Here(), ::atlas::parallel::mpi::StatisticsEnum::__ATLAS_STRINGIFY(statistics_enum), title);\ - __ATLAS__SPLICE( stats, __LINE__ ) .running(); \ - __ATLAS__SPLICE( stats, __LINE__ ) .stop() ) +#undef ATLAS_TRACE_MPI +#define ATLAS_TRACE_MPI(...) ATLAS_TRACE_MPI_( ::atlas::parallel::mpi::Statistics, Here(), ##__VA_ARGS__ ) +#define ATLAS_TRACE_MPI_( Type, loc, enum_var, ... ) \ + __ATLAS_TYPE_SCOPE( Type, loc, ::atlas::parallel::mpi::StatisticsEnum::__ATLAS_STRINGIFY(enum_var), ##__VA_ARGS__ ) #endif @@ -43,9 +34,7 @@ namespace mpi { struct StatisticsTimerTraits { using Barriers = runtime::timer::TimerBarriers; - using Logging = runtime::timer::TimerNoLogging; - using Timings = runtime::timer::Timings; - using Nesting = runtime::timer::TimerNesting; + using Tracing = runtime::timer::TimerTracingNone; }; @@ -67,18 +56,18 @@ enum class StatisticsEnum { static const std::string& name(StatisticsEnum c) { static std::array(StatisticsEnum::_COUNT_)> names { - "mpi-broadcast", - "mpi-allreduce", - "mpi-allgather", - "mpi-alltoall", - "mpi-reduce", - "mpi-gather", - "mpi-scatter", - "mpi-barrier", - "mpi-sendreceive", - "mpi-isend", - "mpi-ireceive", - "mpi-wait" + "mpi.broadcast", + "mpi.allreduce", + "mpi.allgather", + "mpi.alltoall", + "mpi.reduce", + "mpi.gather", + "mpi.scatter", + "mpi.barrier", + "mpi.sendreceive", + "mpi.isend", + "mpi.ireceive", + "mpi.wait" }; return names[ static_cast(c) ]; } @@ -87,10 +76,10 @@ class Statistics : public runtime::timer::TimerT< StatisticsTimerTraits > { using Base = runtime::timer::TimerT< StatisticsTimerTraits >; public: Statistics( const eckit::CodeLocation& loc, StatisticsEnum c ) : - Base( loc, name(c), make_labels(c), Logging::channel() ) { + Base( loc, name(c), make_labels(c) ) { } Statistics( const eckit::CodeLocation& loc, StatisticsEnum c, const std::string& title ) : - Base( loc, title, make_labels(c), Logging::channel() ) { + Base( loc, title, make_labels(c) ) { } private: static std::vector make_labels( StatisticsEnum c) { diff --git a/src/atlas/parallel/omp/omp.cc b/src/atlas/parallel/omp/omp.cc index 7534591a9..d5429741e 100644 --- a/src/atlas/parallel/omp/omp.cc +++ b/src/atlas/parallel/omp/omp.cc @@ -259,7 +259,7 @@ double omp_get_wtime(void) { throw eckit::NotImplemented("omp_get_wtime()\n" "This function does not provide a working" - "wallclock ATLAS_TIME();. Replace it with a version" + "wallclock ATLAS_TRACE();. Replace it with a version" "customized for the target machine", Here() ); return 0.0; } diff --git a/src/atlas/runtime/Log.h b/src/atlas/runtime/Log.h index cd91679ee..3e864b3b6 100644 --- a/src/atlas/runtime/Log.h +++ b/src/atlas/runtime/Log.h @@ -14,25 +14,27 @@ namespace atlas { namespace detail { typedef eckit::Log LogBase; } } namespace atlas { -// Use Log::debug() for debugging that can be switched -// on or off by the boolean environment variable ATLAS_DEBUG - class Log : public detail::LogBase { public: typedef eckit::Channel Channel; + + static std::ostream& info() { return atlas::Library::instance().infoChannel(); } + static std::ostream& trace() { return atlas::Library::instance().traceChannel(); } + static std::ostream& debug() { return atlas::Library::instance().debugChannel(); } #ifndef ATLAS_HAVE_FORTRAN - enum Style { - SIMPLE=0,PREFIX=1,TIMESTAMP=2 - }; - static void addFortranUnit(int unit, Style=PREFIX, const char* prefix="") { /*NOTIMP*/ } - static void setFortranUnit(int unit, Style=PREFIX, const char* prefix="") { /*NOTIMP*/ } - - // Fortran unit numbers - static int output_unit() { return 6; } - static int error_unit() { return 0; } + // Stubs for what fckit::Log provides + enum Style { + SIMPLE=0,PREFIX=1,TIMESTAMP=2 + }; + static void addFortranUnit(int unit, Style=PREFIX, const char* prefix="") { /*NOTIMP*/ } + static void setFortranUnit(int unit, Style=PREFIX, const char* prefix="") { /*NOTIMP*/ } + + // Fortran unit numbers + static int output_unit() { return 6; } + static int error_unit() { return 0; } #endif }; } // namespace atlas diff --git a/src/atlas/runtime/Timer.h b/src/atlas/runtime/Timer.h deleted file mode 100644 index f387332f5..000000000 --- a/src/atlas/runtime/Timer.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * (C) Copyright 1996-2017 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/library/config.h" -#include "atlas/runtime/timer/TimerT.h" -#include "atlas/runtime/timer/TimerBarriers.h" -#include "atlas/runtime/timer/TimerLogging.h" -#include "atlas/runtime/timer/Timings.h" -#include "atlas/runtime/timer/TimerNesting.h" - -//----------------------------------------------------------------------------------------------------------- - -/// Create scoped timer objects -/// -/// Example: -/// -/// void foo() { -/// ATLAS_TIME(); -/// // timer "foo" starts -/// -/// /* interesting computations ... */ -/// -/// ATLAS_TIME_SCOPE("bar") { -/// // timer "bar" starts -/// -/// /* interesting computations ... */ -/// -/// // timer "bar" ends -/// } -/// -/// // timer "foo" ends -/// } -/// -/// Example 2: -/// -/// void foo() { -/// ATLAS_TIME("custom"); -/// // timer "custom" starts -/// -/// /* interesting computations ... */ -/// -/// // timer "custom" ends -/// } -/// -#define ATLAS_TIME(...) -#define ATLAS_TIME_SCOPE(...) - -//----------------------------------------------------------------------------------------------------------- - -namespace atlas { - -struct TimerTraits { - using Barriers = runtime::timer::TimerNoBarriers; - using Logging = runtime::timer::TimerLogging; - using Timings = runtime::timer::Timings; - using Nesting = runtime::timer::TimerNesting; -}; - -class Timer : public runtime::timer::TimerT< TimerTraits > { - using Base = runtime::timer::TimerT< TimerTraits >; -public: - using Base::Base; -}; - -} // namespace atlas - - -//----------------------------------------------------------------------------------------------------------- - -#if ATLAS_HAVE_TIMINGS - -#include "atlas/util/detail/BlackMagic.h" - -#undef ATLAS_TIME -#undef ATLAS_TIME_SCOPE -#define ATLAS_TIME(...) ATLAS_TIME_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) -#define ATLAS_TIME_SCOPE(...) ATLAS_TIME_SCOPE_( __ATLAS__NARG(__VA_ARGS__), ##__VA_ARGS__ ) - -#define ATLAS_TIME_SCOPE_(N, ...) __ATLAS__SPLICE( ATLAS_TIME_SCOPE_, N)(__VA_ARGS__) -#define ATLAS_TIME_SCOPE_0() \ - for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here());\ - __ATLAS__SPLICE( timer, __LINE__ ) .running(); \ - __ATLAS__SPLICE( timer, __LINE__ ) .stop() ) -#define ATLAS_TIME_SCOPE_1(arg1) \ - for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),arg1);\ - __ATLAS__SPLICE( timer, __LINE__ ) .running(); \ - __ATLAS__SPLICE( timer, __LINE__ ) .stop() ) -#define ATLAS_TIME_SCOPE_2(arg1,arg2) \ - for( ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),arg1,arg2);\ - __ATLAS__SPLICE( timer, __LINE__ ) .running(); \ - __ATLAS__SPLICE( timer, __LINE__ ) .stop() ) - -#define ATLAS_TIME_(N, ...) __ATLAS__SPLICE( ATLAS_TIME_, N)(__VA_ARGS__) -#define ATLAS_TIME_0() ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here()); -#define ATLAS_TIME_1(arg1) ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),arg1); -#define ATLAS_TIME_2(arg1,arg2) ::atlas::Timer __ATLAS__SPLICE( timer, __LINE__ ) (Here(),arg1,arg2); - -#endif - -//----------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/runtime/Trace.h b/src/atlas/runtime/Trace.h new file mode 100644 index 000000000..94c71873d --- /dev/null +++ b/src/atlas/runtime/Trace.h @@ -0,0 +1,87 @@ +/* + * (C) Copyright 1996-2017 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/library/config.h" +#include "atlas/runtime/timer/TimerT.h" +#include "atlas/runtime/timer/TimerBarriers.h" +#include "atlas/runtime/timer/TimerTracing.h" + +//----------------------------------------------------------------------------------------------------------- + +/// Create scoped timer objects +/// +/// Example: +/// +/// void foo() { +/// ATLAS_TRACE(); +/// // trace "foo" starts +/// +/// /* interesting computations ... */ +/// +/// ATLAS_TRACE_SCOPE("bar") { +/// // trace "bar" starts +/// +/// /* interesting computations ... */ +/// +/// // trace "bar" ends +/// } +/// +/// // trace "foo" ends +/// } +/// +/// Example 2: +/// +/// void foo() { +/// ATLAS_TRACE("custom"); +/// // trace "custom" starts +/// +/// /* interesting computations ... */ +/// +/// // trace "custom" ends +/// } +/// +#define ATLAS_TRACE(...) +#define ATLAS_TRACE_SCOPE(...) + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { + +struct TraceTraits { + using Barriers = runtime::timer::TimerBarriersNone; + using Tracing = runtime::timer::TimerTracing; +}; + +class Trace : public runtime::timer::TimerT< TraceTraits > { + using Base = runtime::timer::TimerT< TraceTraits >; +public: + using Base::Base; +}; + +} // namespace atlas + + +//----------------------------------------------------------------------------------------------------------- + +#if ATLAS_HAVE_TRACE + +#include "atlas/util/detail/BlackMagic.h" + +#undef ATLAS_TRACE +#undef ATLAS_TRACE_SCOPE + +#define ATLAS_TRACE(...) __ATLAS_TYPE( ::atlas::Trace, Here(), ##__VA_ARGS__ ) +#define ATLAS_TRACE_SCOPE(...) __ATLAS_TYPE_SCOPE( ::atlas::Trace, Here(), ##__VA_ARGS__ ) + +#endif + +//----------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/util/detail/CallStack.cc b/src/atlas/runtime/timer/CallStack.cc similarity index 77% rename from src/atlas/util/detail/CallStack.cc rename to src/atlas/runtime/timer/CallStack.cc index e166cff58..53edb88bb 100644 --- a/src/atlas/util/detail/CallStack.cc +++ b/src/atlas/runtime/timer/CallStack.cc @@ -2,14 +2,14 @@ #include #include "CallStack.h" +#include "eckit/log/CodeLocation.h" namespace atlas { -namespace util { -namespace detail { +namespace runtime { +namespace timer { void CallStack::push_front( const eckit::CodeLocation& loc ) { stack_.push_front( std::hash{}(loc.asString()) ); - loc_ = loc; } void CallStack::pop_front() { @@ -24,6 +24,6 @@ size_t CallStack::hash() const { return hash_; } -} // namespace detail -} // namespace util +} // namespace timer +} // namespace runtime } // namespace atlas diff --git a/src/atlas/util/detail/CallStack.h b/src/atlas/runtime/timer/CallStack.h similarity index 80% rename from src/atlas/util/detail/CallStack.h rename to src/atlas/runtime/timer/CallStack.h index 9e18b16ab..616f2e476 100644 --- a/src/atlas/util/detail/CallStack.h +++ b/src/atlas/runtime/timer/CallStack.h @@ -1,17 +1,19 @@ #pragma once #include -#include "eckit/log/CodeLocation.h" + +namespace eckit { class CodeLocation; } namespace atlas { -namespace util { -namespace detail { +namespace runtime { +namespace timer { /// @class CallStack /// Instances of CallStack can keep track of nested eckit::CodeLocations class CallStack { public: + using const_iterator = std::list::const_iterator; using const_reverse_iterator = std::list::const_reverse_iterator; @@ -20,8 +22,6 @@ class CallStack { void push_front( const eckit::CodeLocation& ); void pop_front(); - const eckit::CodeLocation& loc() const { return loc_; } - const_iterator begin() const { return stack_.begin(); } const_iterator end() const { return stack_.end(); } @@ -33,12 +33,11 @@ class CallStack { private: - eckit::CodeLocation loc_; std::list stack_; mutable size_t hash_{0}; }; -} // namespace detail -} // namespace util +} // namespace timer +} // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/StopWatch.h b/src/atlas/runtime/timer/StopWatch.h index 5cd5e0764..1dc32e9ed 100644 --- a/src/atlas/runtime/timer/StopWatch.h +++ b/src/atlas/runtime/timer/StopWatch.h @@ -19,24 +19,48 @@ namespace timer { //----------------------------------------------------------------------------------------------------------- class StopWatch { +public: + StopWatch(); + StopWatch(double elapsed); + void start(); + void stop(); + void reset(); + double elapsed() const; private: std::chrono::duration elapsed_{0}; std::chrono::steady_clock::time_point start_; -public: - void start() { - start_ = std::chrono::steady_clock::now(); - } - void stop() { + bool running_{false}; +}; + +//----------------------------------------------------------------------------------------------------------- + +inline StopWatch::StopWatch() { +} + +inline StopWatch::StopWatch(double elapsed) : + elapsed_(elapsed) { +} + +inline void StopWatch::start() { + start_ = std::chrono::steady_clock::now(); + running_ = true; +} + +inline void StopWatch::stop() { + if( running_ ) { elapsed_ += (std::chrono::steady_clock::now() - start_); + running_ = false; } - void reset() { - elapsed_ = std::chrono::seconds::zero(); - start_ = std::chrono::steady_clock::now(); - } - double elapsed() const { - return elapsed_.count(); - } -}; +} + +inline void StopWatch::reset() { + elapsed_ = std::chrono::seconds::zero(); + start_ = std::chrono::steady_clock::now(); +} + +inline double StopWatch::elapsed() const { + return elapsed_.count(); +} //----------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/runtime/timer/TimerBarriers.cc b/src/atlas/runtime/timer/TimerBarriers.cc index 28dae8213..660c97f15 100644 --- a/src/atlas/runtime/timer/TimerBarriers.cc +++ b/src/atlas/runtime/timer/TimerBarriers.cc @@ -24,7 +24,7 @@ namespace timer { class TimerBarriersState { private: TimerBarriersState() { - barriers_ = atlas::Library::instance().timer().barriers(); + barriers_ = atlas::Library::instance().barriers(); } bool barriers_; StopWatch stopwatch_; @@ -82,7 +82,7 @@ double TimerBarriers::time() { return TimerBarriersState::instance().stopwatch().elapsed(); } -double TimerNoBarriers::time() { +double TimerBarriersNone::time() { return TimerBarriersState::instance().stopwatch().elapsed(); } @@ -90,7 +90,7 @@ std::string TimerBarriers::report() { return TimerBarriersState::instance().report(); } -std::string TimerNoBarriers::report() { +std::string TimerBarriersNone::report() { return TimerBarriersState::instance().report(); } diff --git a/src/atlas/runtime/timer/TimerBarriers.h b/src/atlas/runtime/timer/TimerBarriers.h index 3ffeef104..741e38c3f 100644 --- a/src/atlas/runtime/timer/TimerBarriers.h +++ b/src/atlas/runtime/timer/TimerBarriers.h @@ -17,9 +17,9 @@ namespace atlas { namespace runtime { namespace timer { -class TimerNoBarriers { +class TimerBarriersNone { public: - TimerNoBarriers(bool state) {} + TimerBarriersNone(bool state) {} void restore() {} public: // static methods diff --git a/src/atlas/runtime/timer/TimerLogging.cc b/src/atlas/runtime/timer/TimerLogging.cc deleted file mode 100644 index 3861b1fa0..000000000 --- a/src/atlas/runtime/timer/TimerLogging.cc +++ /dev/null @@ -1,76 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 "TimerLogging.h" - -#include -#include "eckit/log/Channel.h" -#include "atlas/library/Library.h" - -//----------------------------------------------------------------------------------------------------------- - -namespace atlas { -namespace runtime { -namespace timer { - -class TimerLoggingState { -private: - std::ostream* channel_; - - TimerLoggingState() { - channel_ = &atlas::Library::instance().timer().channel(); - } - -public: - - static eckit::Channel& empty_channel() { - static eckit::Channel channel; - return channel; - } - - static TimerLoggingState& instance() { - static TimerLoggingState channel; - return channel; - } - - operator std::ostream&() { return *channel_; } - operator std::ostream*() { return channel_; } - - void set( std::ostream& channel ) { channel_ = &channel; } - void set( bool state ) { if( state == false ) channel_ = &empty_channel(); } -}; - -TimerLogging::TimerLogging( bool state ) : - previous_state_( TimerLoggingState::instance() ) { - TimerLoggingState::instance().set( state ); -} - -TimerLogging::TimerLogging( std::ostream& channel ) : - previous_state_( TimerLoggingState::instance() ) { - TimerLoggingState::instance().set( channel ); -} - -TimerLogging::~TimerLogging() { - TimerLoggingState::instance().set( *previous_state_ ); -} - -std::ostream& TimerLogging::channel() { - return TimerLoggingState::instance(); -} - -std::ostream& TimerNoLogging::channel() { - return TimerLoggingState::empty_channel(); -} - - -} // namespace timer -} // namespace runtime -} // namespace atlas - diff --git a/src/atlas/runtime/timer/TimerLogging.h b/src/atlas/runtime/timer/TimerLogging.h deleted file mode 100644 index 1abc1a906..000000000 --- a/src/atlas/runtime/timer/TimerLogging.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 - -//----------------------------------------------------------------------------------------------------------- - -namespace atlas { -namespace runtime { -namespace timer { - -class TimerNoLogging { -public: - - TimerNoLogging( bool state ); - - TimerNoLogging( std::ostream& channel ); - -public: // static method - static std::ostream& channel(); - -}; - -class TimerLogging { -public: - - TimerLogging( bool state ); - - TimerLogging( std::ostream& channel ); - - ~TimerLogging(); - -public: // static method - static std::ostream& channel(); - -private: - std::ostream* previous_state_; - -}; - -} // namespace timer -} // namespace runtime -} // namespace atlas - diff --git a/src/atlas/runtime/timer/TimerNesting.cc b/src/atlas/runtime/timer/TimerNesting.cc index b62ea1c0d..ef7a3ae37 100644 --- a/src/atlas/runtime/timer/TimerNesting.cc +++ b/src/atlas/runtime/timer/TimerNesting.cc @@ -18,7 +18,6 @@ namespace timer { class TimerNestingState { - using CallStack = util::detail::CallStack; private: TimerNestingState() {} CallStack stack_; @@ -47,20 +46,21 @@ TimerNesting::TimerNesting( const eckit::CodeLocation& loc ) : } TimerNesting::~TimerNesting() { - if( running_ ) - stop(); + stop(); } void TimerNesting::stop() { - if( running_ ) + if( running_ ) { TimerNestingState::instance().pop(); - running_ = false; + running_ = false; + } } void TimerNesting::start() { - if( not running_ ) + if( not running_ ) { TimerNestingState::instance().push( loc_ ); - running_ = true; + running_ = true; + } } } // namespace timer diff --git a/src/atlas/runtime/timer/TimerNesting.h b/src/atlas/runtime/timer/TimerNesting.h index 53c4af1f5..103b75323 100644 --- a/src/atlas/runtime/timer/TimerNesting.h +++ b/src/atlas/runtime/timer/TimerNesting.h @@ -10,7 +10,8 @@ #pragma once -#include "atlas/util/detail/CallStack.h" +#include "eckit/log/CodeLocation.h" +#include "atlas/runtime/timer/CallStack.h" //----------------------------------------------------------------------------------------------------------- @@ -21,10 +22,8 @@ namespace timer { class TimerNesting { public: - using CallStack = util::detail::CallStack; TimerNesting( const eckit::CodeLocation& ); ~TimerNesting(); - operator long() const { return stack_.size(); } operator CallStack() const { return stack_; } void stop(); void start(); diff --git a/src/atlas/runtime/timer/TimerT.h b/src/atlas/runtime/timer/TimerT.h index 5158c916a..fc53ad506 100644 --- a/src/atlas/runtime/timer/TimerT.h +++ b/src/atlas/runtime/timer/TimerT.h @@ -15,6 +15,8 @@ #include #include #include "atlas/runtime/timer/StopWatch.h" +#include "atlas/runtime/timer/Timings.h" +#include "atlas/runtime/timer/TimerNesting.h" //----------------------------------------------------------------------------------------------------------- @@ -35,7 +37,7 @@ template< typename TimerTraits > class TimerT { public: using Barriers = typename TimerTraits::Barriers; - using Logging = typename TimerTraits::Logging; + using Tracing = typename TimerTraits::Tracing; using Labels = std::vector; public: // static methods @@ -45,11 +47,9 @@ class TimerT { public: - TimerT( const eckit::CodeLocation&, const std::string& title, std::ostream& out = Logging::channel() ); - TimerT( const eckit::CodeLocation&, std::ostream& out = Logging::channel() ); - - TimerT( const eckit::CodeLocation&, const std::string& title, const Labels&, std::ostream& out = Logging::channel() ); - TimerT( const eckit::CodeLocation&, const Labels&, std::ostream& out = Logging::channel() ); + TimerT( const eckit::CodeLocation& ); + TimerT( const eckit::CodeLocation&, const std::string& title ); + TimerT( const eckit::CodeLocation&, const std::string& title, const Labels& ); ~TimerT(); @@ -67,9 +67,9 @@ class TimerT { private: // types - using Nesting = typename TimerTraits::Nesting; - using Timings = typename TimerTraits::Timings; - using Identifier = typename Timings::Identifier; + using Nesting = timer::TimerNesting; + using Timings = timer::Timings; + using Identifier = timer::Timings::Identifier; private: // member functions @@ -84,7 +84,6 @@ class TimerT { bool running_{true}; StopWatch stopwatch_; eckit::CodeLocation loc_; - std::ostream& out_; std::string title_; Identifier id_; Nesting nesting_; @@ -95,43 +94,30 @@ class TimerT { // Definitions template< typename TimerTraits > -inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& title, std::ostream& out ) : +inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& title ) : loc_(loc), - out_(out), title_(title), nesting_(loc) { start(); } template< typename TimerTraits > -inline TimerT::TimerT( const eckit::CodeLocation& loc, std::ostream& out ) : +inline TimerT::TimerT( const eckit::CodeLocation& loc ) : loc_(loc), - out_(out), title_( loc_ ? loc_.func() : ""), nesting_(loc_) { start(); } template< typename TimerTraits > -inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& title, const Labels& labels, std::ostream& out ) : +inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& title, const Labels& labels ) : loc_(loc), - out_(out), title_(title), nesting_(loc), labels_(labels) { start(); } -template< typename TimerTraits > -inline TimerT::TimerT( const eckit::CodeLocation& loc, const Labels& labels, std::ostream& out ) : - loc_(loc), - out_(out), - title_( loc_ ? loc_.func() : "" ), - nesting_(loc_), - labels_(labels) { - start(); -} - template< typename TimerTraits > inline TimerT::~TimerT() { stop(); @@ -144,7 +130,7 @@ inline void TimerT::barrier() const { template< typename TimerTraits > inline void TimerT::registerTimer() { - id_ = Timings::add( nesting_, title_ + (Barriers::state() ? " [b]" : ""), labels_ ); + id_ = Timings::add( loc_, nesting_, title_ + (Barriers::state() ? " [b]" : ""), labels_ ); } template< typename TimerTraits > @@ -160,26 +146,26 @@ inline bool TimerT::running() const { template< typename TimerTraits > inline void TimerT::start() { registerTimer(); - out_ << title_ << " ..." << std::endl; + Tracing::start( title_ ); barrier(); stopwatch_.start(); } template< typename TimerTraits > inline void TimerT::stop() { - if( running() ) { + if( running_ ) { barrier(); stopwatch_.stop(); nesting_.stop(); updateTimings(); - out_ << title_ << " ... done : " << stopwatch_.elapsed() << "s" << std::endl; + Tracing::stop( title_, stopwatch_.elapsed() ); running_ = false; } } template< typename TimerTraits > inline void TimerT::pause() { - if( running() ) { + if( running_ ) { barrier(); stopwatch_.stop(); nesting_.stop(); @@ -188,9 +174,11 @@ inline void TimerT::pause() { template< typename TimerTraits > inline void TimerT::resume() { - barrier(); - nesting_.start(); - stopwatch_.start(); + if( running_ ) { + barrier(); + nesting_.start(); + stopwatch_.start(); + } } template< typename TimerTraits > diff --git a/src/atlas/runtime/timer/TimerTracing.cc b/src/atlas/runtime/timer/TimerTracing.cc new file mode 100644 index 000000000..b261cf26c --- /dev/null +++ b/src/atlas/runtime/timer/TimerTracing.cc @@ -0,0 +1,102 @@ +/* + * (C) Copyright 1996-2017 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 "TimerTracing.h" + +#include +#include "eckit/log/Channel.h" +#include "atlas/library/Library.h" + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + +//----------------------------------------------------------------------------------------------------------- + +class TimerTracingState { +private: + std::ostream* channel_; + + TimerTracingState() { + channel_ = &atlas::Library::instance().traceChannel(); + } + +public: + + static eckit::Channel& empty_channel() { + static eckit::Channel channel; + return channel; + } + + static TimerTracingState& instance() { + static TimerTracingState channel; + return channel; + } + + operator std::ostream&() { return *channel_; } + operator std::ostream*() { return channel_; } + + void set( std::ostream& channel ) { channel_ = &channel; } + void set( bool state ) { if( state == false ) channel_ = &empty_channel(); } +}; + +//----------------------------------------------------------------------------------------------------------- + +TimerTracing::TimerTracing( bool state ) : + previous_state_( TimerTracingState::instance() ) { + TimerTracingState::instance().set( state ); +} + +TimerTracing::TimerTracing( std::ostream& channel ) : + previous_state_( TimerTracingState::instance() ) { + TimerTracingState::instance().set( channel ); +} + +TimerTracing::~TimerTracing() { + TimerTracingState::instance().set( *previous_state_ ); +} + +std::ostream& TimerTracing::channel() { + return TimerTracingState::instance(); +} + +bool TimerTracing::enabled() { + return TimerTracingState::instance(); +} +void TimerTracing::start( const std::string& title ) { + if( enabled() ) + channel() << title << " ..." << std::endl; +} + +void TimerTracing::stop( const std::string& title, double seconds ) { + if( enabled() ) + channel() << title << " ... done : " << seconds << "s" << std::endl; +} +//----------------------------------------------------------------------------------------------------------- + +std::ostream& TimerTracingNone::channel() { + return TimerTracingState::empty_channel(); +} + +//----------------------------------------------------------------------------------------------------------- + +void TimerTracingResult::stop( const std::string& title, double seconds ) { + if( enabled() ) + channel() << title << " : " << seconds << "s" << std::endl; +} + +//----------------------------------------------------------------------------------------------------------- + +} // namespace timer +} // namespace runtime +} // namespace atlas + diff --git a/src/atlas/runtime/timer/TimerTracing.h b/src/atlas/runtime/timer/TimerTracing.h new file mode 100644 index 000000000..0515c4e5a --- /dev/null +++ b/src/atlas/runtime/timer/TimerTracing.h @@ -0,0 +1,77 @@ +/* + * (C) Copyright 1996-2017 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 + +//----------------------------------------------------------------------------------------------------------- + +namespace atlas { +namespace runtime { +namespace timer { + +//----------------------------------------------------------------------------------------------------------- + +// Class used to avoid any printing before and after a timer +class TimerTracingNone { +public: + TimerTracingNone( bool state ); + TimerTracingNone( std::ostream& channel ); + +public: // static methods + static std::ostream& channel(); + static bool enabled(); + static void start( const std::string& ) {} + static void stop( const std::string&, double ) {} +}; + +//----------------------------------------------------------------------------------------------------------- + +// Class used to print message before and after a timer +// Example print: +// timer-name ... +// timer-name ... done : 5s +class TimerTracing { +public: + TimerTracing( bool state ); + TimerTracing( std::ostream& channel ); + virtual ~TimerTracing(); + +public: // static methods + static std::ostream& channel(); + static bool enabled(); + static void start( const std::string& title ); + static void stop( const std::string& title, double seconds ); + +private: + std::ostream* previous_state_; +}; + +//----------------------------------------------------------------------------------------------------------- + +// Class used to print message only upon end of a timer +// Example print: +// timer-name : 5s +class TimerTracingResult : public TimerTracing { +public: + using TimerTracing::TimerTracing; + +public: // static methods + static void start( const std::string& ) {} + static void stop( const std::string& title, double seconds ); +}; + +//----------------------------------------------------------------------------------------------------------- + +} // namespace timer +} // namespace runtime +} // namespace atlas + diff --git a/src/atlas/runtime/timer/Timings.cc b/src/atlas/runtime/timer/Timings.cc index 13bd50373..8e9538590 100644 --- a/src/atlas/runtime/timer/Timings.cc +++ b/src/atlas/runtime/timer/Timings.cc @@ -17,8 +17,8 @@ #include "Timings.h" #include "eckit/config/Configuration.h" #include "eckit/filesystem/PathName.h" -#include "atlas/util/detail/CallStack.h" #include "atlas/util/Config.h" +#include "atlas/runtime/timer/CallStack.h" #include "atlas/runtime/Debug.h" #include "atlas/parallel/mpi/mpi.h" @@ -30,8 +30,6 @@ namespace timer { class TimingsRegistry { - using CallStack = Timings::CallStack; - private: std::vector counts_; @@ -57,7 +55,7 @@ class TimingsRegistry { return registry; } - size_t add( const CallStack& stack, const std::string& title, const Timings::Labels& ); + size_t add( const eckit::CodeLocation&, const CallStack& stack, const std::string& title, const Timings::Labels& ); void update( size_t idx, double seconds ); @@ -71,7 +69,7 @@ class TimingsRegistry { }; -size_t TimingsRegistry::add( const CallStack& stack, const std::string& title, const Timings::Labels& labels ) { +size_t TimingsRegistry::add( const eckit::CodeLocation& loc, const CallStack& stack, const std::string& title, const Timings::Labels& labels ) { size_t key = stack.hash(); auto it = index_.find( key ); @@ -84,7 +82,7 @@ size_t TimingsRegistry::add( const CallStack& stack, const std::string& title, c max_timings_.emplace_back( 0 ); var_timings_.emplace_back( 0 ); titles_.emplace_back( title ); - locations_.emplace_back( stack.loc() ); + locations_.emplace_back( loc ); nest_.emplace_back( stack.size() ); stack_.emplace_back( stack ); @@ -377,8 +375,8 @@ std::string TimingsRegistry::filter_filepath( const std::string& filepath ) cons // return filepath; } -Timings::Identifier Timings::add( const CallStack& stack, const std::string& title, const Labels& labels ) { - return TimingsRegistry::instance().add( stack, title, labels ); +Timings::Identifier Timings::add( const CodeLocation& loc, const CallStack& stack, const std::string& title, const Labels& labels ) { + return TimingsRegistry::instance().add( loc, stack, title, labels ); } void Timings::update( const Identifier& id, double seconds ) { @@ -389,7 +387,7 @@ std::string Timings::report() { return report( util::NoConfig() ); } -std::string Timings::report( const eckit::Configuration& config ) { +std::string Timings::report( const Configuration& config ) { std::stringstream out; TimingsRegistry::instance().report( out, config ); return out.str(); diff --git a/src/atlas/runtime/timer/Timings.h b/src/atlas/runtime/timer/Timings.h index c17a2406c..50c6b3734 100644 --- a/src/atlas/runtime/timer/Timings.h +++ b/src/atlas/runtime/timer/Timings.h @@ -16,27 +16,30 @@ //----------------------------------------------------------------------------------------------------------- namespace eckit { class Configuration; } -namespace atlas { namespace util { namespace detail { class CallStack; } } } +namespace eckit { class CodeLocation; } namespace atlas { namespace runtime { namespace timer { +class CallStack; + class Timings { public: - using CallStack = util::detail::CallStack; + using Configuration = eckit::Configuration; + using CodeLocation = eckit::CodeLocation; using Identifier = size_t; using Labels = std::vector; public: // static methods - static Identifier add( const CallStack& stack, const std::string& title, const Labels& ); + static Identifier add( const CodeLocation&, const CallStack&, const std::string& title, const Labels& ); static void update( const Identifier& id, double seconds ); static std::string report(); - static std::string report( const eckit::Configuration& ); + static std::string report( const Configuration& ); }; diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index eb0dd00e7..9a131921f 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -73,7 +73,7 @@ void Metadata::broadcast(Metadata& dest, const size_t root) buffer_size = buffer.size(); } - ATLAS_MPI_STATS( BROADCAST ) { + ATLAS_TRACE_MPI( BROADCAST ) { atlas::parallel::mpi::comm().broadcast(buffer_size,root); } @@ -81,7 +81,7 @@ void Metadata::broadcast(Metadata& dest, const size_t root) buffer.resize(buffer_size); } - ATLAS_MPI_STATS( BROADCAST ) { + ATLAS_TRACE_MPI( BROADCAST ) { atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); } @@ -115,7 +115,7 @@ void Metadata::broadcast(Metadata& dest, const size_t root) const buffer_size = buffer.size(); } - ATLAS_MPI_STATS( BROADCAST ) { + ATLAS_TRACE_MPI( BROADCAST ) { atlas::parallel::mpi::comm().broadcast(buffer_size,root); } @@ -123,7 +123,7 @@ void Metadata::broadcast(Metadata& dest, const size_t root) const buffer.resize(buffer_size); } - ATLAS_MPI_STATS( BROADCAST ) { + ATLAS_TRACE_MPI( BROADCAST ) { atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); } diff --git a/src/atlas/util/detail/BlackMagic.h b/src/atlas/util/detail/BlackMagic.h index a0cd926b8..7a4de4678 100644 --- a/src/atlas/util/detail/BlackMagic.h +++ b/src/atlas/util/detail/BlackMagic.h @@ -7,48 +7,86 @@ // Public /// Returns the number of passed arguments -#define __ATLAS__NARG(...) +#define __ATLAS_NARG(...) /// Splice a and b together -#define __ATLAS__SPLICE(a,b) +#define __ATLAS_SPLICE(a,b) #define __ATLAS_STRINGIFY(a) a +#define __ATLAS_TYPE( Type, ... ) +#define __ATLAS_TYPE_SCOPE( Type, ... ) + //----------------------------------------------------------------------------------------------------------- // Details // Undefine these, to be redefined further down. -#undef __ATLAS__NARG -#undef __ATLAS__SPLICE - -#define __ATLAS__REVERSE 5, 4, 3, 2, 1, 0 -#define __ATLAS__ARGN(_1, _2, _3, _4, _5, N, ...) N -#define __ATLAS__NARG__(dummy, ...) __ATLAS__ARGN(__VA_ARGS__) -#define __ATLAS__NARG_(...) __ATLAS__NARG__(dummy, ##__VA_ARGS__, __ATLAS__REVERSE) -#define __ATLAS__SPLICE(a,b) __ATLAS__SPLICE_1(a,b) -#define __ATLAS__SPLICE_1(a,b) __ATLAS__SPLICE_2(a,b) -#define __ATLAS__SPLICE_2(a,b) a##b - - -#define __ATLAS__ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15 -#define __ATLAS__HAS_COMMA(...) __ATLAS__ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) -#define __ATLAS__TRIGGER_PARENTHESIS(...) , -#define __ATLAS__ISEMPTY(...) \ -__ATLAS__ISEMPTY_( \ +#undef __ATLAS_NARG +#undef __ATLAS_SPLICE +#undef __ATLAS_TYPE +#undef __ATLAS_TYPE_SCOPE + +#define __ATLAS_REVERSE 5, 4, 3, 2, 1, 0 +#define __ATLAS_ARGN(_1, _2, _3, _4, _5, N, ...) N +#define __ATLAS_NARG__(dummy, ...) __ATLAS_ARGN(__VA_ARGS__) +#define __ATLAS_NARG_(...) __ATLAS_NARG__(dummy, ##__VA_ARGS__, __ATLAS_REVERSE) +#define __ATLAS_SPLICE(a,b) __ATLAS_SPLICE_1(a,b) +#define __ATLAS_SPLICE_1(a,b) __ATLAS_SPLICE_2(a,b) +#define __ATLAS_SPLICE_2(a,b) a##b + + +#define __ATLAS_ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15 +#define __ATLAS_HAS_COMMA(...) __ATLAS_ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) +#define __ATLAS_TRIGGER_PARENTHESIS(...) , +#define __ATLAS_ISEMPTY(...) \ +__ATLAS_ISEMPTY_( \ /* test if there is just one argument, eventually an empty one */ \ - __ATLAS__HAS_COMMA(__VA_ARGS__), \ + __ATLAS_HAS_COMMA(__VA_ARGS__), \ /* test if _TRIGGER_PARENTHESIS_ together with the argument adds a comma */ \ - __ATLAS__HAS_COMMA(__ATLAS__TRIGGER_PARENTHESIS __VA_ARGS__), \ + __ATLAS_HAS_COMMA(__ATLAS_TRIGGER_PARENTHESIS __VA_ARGS__), \ /* test if the argument together with a parenthesis adds a comma */ \ - __ATLAS__HAS_COMMA(__VA_ARGS__ (/*empty*/)), \ - /* test if placing it between __ATLAS__TRIGGER_PARENTHESIS and the parenthesis adds a comma */ \ - __ATLAS__HAS_COMMA(__ATLAS__TRIGGER_PARENTHESIS __VA_ARGS__ (/*empty*/)) \ + __ATLAS_HAS_COMMA(__VA_ARGS__ (/*empty*/)), \ + /* test if placing it between __ATLAS_TRIGGER_PARENTHESIS and the parenthesis adds a comma */ \ + __ATLAS_HAS_COMMA(__ATLAS_TRIGGER_PARENTHESIS __VA_ARGS__ (/*empty*/)) \ ) -#define __ATLAS__PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4 -#define __ATLAS__ISEMPTY_(_0, _1, _2, _3) __ATLAS__HAS_COMMA(__ATLAS__PASTE5(__ATLAS__IS_EMPTY_CASE_, _0, _1, _2, _3)) -#define __ATLAS__IS_EMPTY_CASE_0001 , +#define __ATLAS_PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4 +#define __ATLAS_ISEMPTY_(_0, _1, _2, _3) __ATLAS_HAS_COMMA(__ATLAS_PASTE5(__ATLAS_IS_EMPTY_CASE_, _0, _1, _2, _3)) +#define __ATLAS_IS_EMPTY_CASE_0001 , + +#define __ATLAS_CALL_NARG_1(...) 0 +#define __ATLAS_CALL_NARG_0 __ATLAS_NARG_ +#define __ATLAS_NARG(...) __ATLAS_SPLICE( __ATLAS_CALL_NARG_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) + +#define __ATLAS_TYPE( Type, ... ) __ATLAS_TYPE_( __ATLAS_NARG(__VA_ARGS__), Type, ##__VA_ARGS__ ) +#define __ATLAS_TYPE_SCOPE( Type, ... ) __ATLAS_TYPE_SCOPE_( __ATLAS_NARG(__VA_ARGS__), Type, ##__VA_ARGS__ ) + +#define __ATLAS_TYPE_( N, ... ) __ATLAS_SPLICE( __ATLAS_TYPE_, N )( __VA_ARGS__ ) +#define __ATLAS_TYPE_SCOPE_( N, ... ) __ATLAS_SPLICE( __ATLAS_TYPE_SCOPE_, N )( __VA_ARGS__ ) + +#define __ATLAS_TYPE_0( Type ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) ( ); +#define __ATLAS_TYPE_1( Type, arg1 ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1 ); +#define __ATLAS_TYPE_2( Type, arg1, arg2 ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1, arg2 ); +#define __ATLAS_TYPE_3( Type, arg1, arg2, arg3 ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1, arg2, arg3 ); -#define __ATLAS__CALL_NARG_1(...) 0 -#define __ATLAS__CALL_NARG_0 __ATLAS__NARG_ -#define __ATLAS__NARG(...) __ATLAS__SPLICE( __ATLAS__CALL_NARG_, __ATLAS__ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) +#define __ATLAS_TYPE_SCOPE_0( Type ) \ + for( Type \ + __ATLAS_SPLICE( __variable_, __LINE__ ) ( );\ + __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ + __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) +#define __ATLAS_TYPE_SCOPE_1( Type, arg1 ) \ + for( Type \ + __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1 ); \ + __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ + __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) +#define __ATLAS_TYPE_SCOPE_2( Type , arg1, arg2 ) \ + for( Type \ + __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1, arg2 );\ + __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ + __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) +#define __ATLAS_TYPE_SCOPE_3( Type , arg1, arg2, arg3 ) \ + for( Type \ + __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1, arg2, arg3 );\ + __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ + __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) + diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc index a0b76c5e3..91d54c184 100644 --- a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -26,7 +26,7 @@ #include "atlas/mesh.h" #include "atlas/runtime/AtlasTool.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/util/Config.h" #include "atlas/output/detail/GmshIO.h" @@ -117,7 +117,7 @@ void Tool::execute(const Args& args) mesh::actions::build_halo( mesh, halo ); parallel::mpi::comm().barrier(); } - Log::info() << Timer::report() << std::endl; + Log::info() << Trace::report() << std::endl; } diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index 4df5fe53a..c6df07997 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -26,7 +26,7 @@ #include "atlas/mesh.h" #include "atlas/runtime/AtlasTool.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Timer.h" +#include "atlas/runtime/Trace.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/util/Config.h" #include "atlas/output/detail/GmshIO.h" @@ -73,7 +73,7 @@ struct Node void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_halo, mesh::Nodes& nodes, bool do_all ) { - ATLAS_TIME(); + ATLAS_TRACE(); // TODO: ATLAS-14: fix renumbering of EAST periodic boundary points // --> Those specific periodic points at the EAST boundary are not checked for uid, // and could receive different gidx for different tasks @@ -113,7 +113,7 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha ATLAS_DEBUG_VAR( points_to_edit ); ATLAS_DEBUG_VAR( points_to_edit.size() ); - ATLAS_TIME( "distributed_sort" ); + ATLAS_TRACE( "distributed_sort" ); /* * Sorting following gidx will define global order of @@ -129,7 +129,7 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha std::vector recvcounts(parallel::mpi::comm().size()); std::vector recvdispls(parallel::mpi::comm().size()); - ATLAS_MPI_STATS( GATHER ) { + ATLAS_TRACE_MPI( GATHER ) { parallel::mpi::comm().gather(nb_nodes, recvcounts, root); } @@ -141,7 +141,7 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha int glb_nb_nodes = std::accumulate(recvcounts.begin(),recvcounts.end(),0); std::vector glb_idx_gathered( glb_nb_nodes ); - ATLAS_MPI_STATS( GATHER ) { + ATLAS_TRACE_MPI( GATHER ) { parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); } @@ -153,7 +153,7 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha node_sort.push_back( Node(glb_idx_gathered[jnode],jnode) ); } - ATLAS_TIME_SCOPE( "local_sort" ) { + ATLAS_TRACE_SCOPE( "local_sort" ) { std::sort(node_sort.begin(), node_sort.end()); } @@ -174,7 +174,7 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha } // 3) Scatter renumbered back - ATLAS_MPI_STATS( SCATTER ) { + ATLAS_TRACE_MPI( SCATTER ) { parallel::mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); } @@ -228,7 +228,7 @@ Tool::Tool(int argc,char **argv): AtlasTool(argc,argv) void Tool::execute(const Args& args) { - Timer t( Here(), "main"); + Trace t( Here(), "main"); key = ""; args.get("grid",key); @@ -263,7 +263,7 @@ void Tool::execute(const Args& args) parallel::mpi::comm().barrier(); for( size_t j=0; j<1; ++j ) { - ATLAS_TIME("outer_iteration"); + ATLAS_TRACE("outer_iteration"); Mesh mesh = meshgenerator.generate(grid); atlas::mesh::actions::build_periodic_boundaries(mesh); @@ -272,14 +272,14 @@ void Tool::execute(const Args& args) atlas::mesh::actions::BuildHalo build_halo(mesh); build_halo(halo); - Timer::Barriers set_barrier(true); - Timer::Logging set_channel( Log::info() ); + Trace::Barriers set_barrier(true); + Trace::Tracing set_channel( Log::info() ); for( size_t i=0; i Date: Wed, 11 Oct 2017 16:06:53 +0100 Subject: [PATCH 028/355] ATLAS-132 Move timer to trace --- src/atlas/CMakeLists.txt | 22 ++--- src/atlas/parallel/mpi/Statistics.h | 8 +- src/atlas/runtime/Trace.h | 16 ++-- .../TimerBarriers.cc => trace/Barriers.cc} | 58 ++++++------ .../TimerBarriers.h => trace/Barriers.h} | 14 +-- .../runtime/{timer => trace}/CallStack.cc | 4 +- .../runtime/{timer => trace}/CallStack.h | 4 +- .../TimerTracing.cc => trace/Logging.cc} | 48 +++++----- .../{timer/TimerTracing.h => trace/Logging.h} | 22 ++--- .../TimerNesting.cc => trace/Nesting.cc} | 32 +++---- .../{timer/TimerNesting.h => trace/Nesting.h} | 12 +-- .../runtime/{timer => trace}/StopWatch.h | 4 +- src/atlas/runtime/{timer => trace}/Timings.cc | 6 +- src/atlas/runtime/{timer => trace}/Timings.h | 4 +- .../{timer/TimerT.h => trace/TraceT.h} | 90 +++++++++---------- 15 files changed, 171 insertions(+), 173 deletions(-) rename src/atlas/runtime/{timer/TimerBarriers.cc => trace/Barriers.cc} (53%) rename src/atlas/runtime/{timer/TimerBarriers.h => trace/Barriers.h} (85%) rename src/atlas/runtime/{timer => trace}/CallStack.cc (92%) rename src/atlas/runtime/{timer => trace}/CallStack.h (95%) rename src/atlas/runtime/{timer/TimerTracing.cc => trace/Logging.cc} (65%) rename src/atlas/runtime/{timer/TimerTracing.h => trace/Logging.h} (84%) rename src/atlas/runtime/{timer/TimerNesting.cc => trace/Nesting.cc} (61%) rename src/atlas/runtime/{timer/TimerNesting.h => trace/Nesting.h} (82%) rename src/atlas/runtime/{timer => trace}/StopWatch.h (98%) rename src/atlas/runtime/{timer => trace}/Timings.cc (99%) rename src/atlas/runtime/{timer => trace}/Timings.h (96%) rename src/atlas/runtime/{timer/TimerT.h => trace/TraceT.h} (61%) diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index f5d48ac6b..16404689b 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -34,17 +34,17 @@ runtime/AtlasTool.h runtime/AtlasTool.cc runtime/Log.h runtime/Trace.h -runtime/timer/CallStack.h -runtime/timer/CallStack.cc -runtime/timer/TimerT.h -runtime/timer/TimerNesting.cc -runtime/timer/TimerNesting.h -runtime/timer/TimerBarriers.cc -runtime/timer/TimerBarriers.h -runtime/timer/TimerTracing.cc -runtime/timer/TimerTracing.h -runtime/timer/Timings.h -runtime/timer/Timings.cc +runtime/trace/CallStack.h +runtime/trace/CallStack.cc +runtime/trace/TraceT.h +runtime/trace/Nesting.cc +runtime/trace/Nesting.h +runtime/trace/Barriers.cc +runtime/trace/Barriers.h +runtime/trace/Logging.cc +runtime/trace/Logging.h +runtime/trace/Timings.h +runtime/trace/Timings.cc parallel/mpi/mpi.cc parallel/mpi/mpi.h parallel/omp/omp.cc diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 625eddfc6..962819323 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -33,8 +33,8 @@ namespace parallel { namespace mpi { struct StatisticsTimerTraits { - using Barriers = runtime::timer::TimerBarriers; - using Tracing = runtime::timer::TimerTracingNone; + using Barriers = runtime::trace::Barriers; + using Tracing = runtime::trace::NoLogging; }; @@ -72,8 +72,8 @@ static const std::string& name(StatisticsEnum c) { return names[ static_cast(c) ]; } -class Statistics : public runtime::timer::TimerT< StatisticsTimerTraits > { - using Base = runtime::timer::TimerT< StatisticsTimerTraits >; +class Statistics : public runtime::trace::TraceT< StatisticsTimerTraits > { + using Base = runtime::trace::TraceT< StatisticsTimerTraits >; public: Statistics( const eckit::CodeLocation& loc, StatisticsEnum c ) : Base( loc, name(c), make_labels(c) ) { diff --git a/src/atlas/runtime/Trace.h b/src/atlas/runtime/Trace.h index 94c71873d..0471702b4 100644 --- a/src/atlas/runtime/Trace.h +++ b/src/atlas/runtime/Trace.h @@ -11,13 +11,13 @@ #pragma once #include "atlas/library/config.h" -#include "atlas/runtime/timer/TimerT.h" -#include "atlas/runtime/timer/TimerBarriers.h" -#include "atlas/runtime/timer/TimerTracing.h" +#include "atlas/runtime/trace/TraceT.h" +#include "atlas/runtime/trace/Barriers.h" +#include "atlas/runtime/trace/Logging.h" //----------------------------------------------------------------------------------------------------------- -/// Create scoped timer objects +/// Create scoped trace objects /// /// Example: /// @@ -57,12 +57,12 @@ namespace atlas { struct TraceTraits { - using Barriers = runtime::timer::TimerBarriersNone; - using Tracing = runtime::timer::TimerTracing; + using Barriers = runtime::trace::NoBarriers; + using Tracing = runtime::trace::Logging; }; -class Trace : public runtime::timer::TimerT< TraceTraits > { - using Base = runtime::timer::TimerT< TraceTraits >; +class Trace : public runtime::trace::TraceT< TraceTraits > { + using Base = runtime::trace::TraceT< TraceTraits >; public: using Base::Base; }; diff --git a/src/atlas/runtime/timer/TimerBarriers.cc b/src/atlas/runtime/trace/Barriers.cc similarity index 53% rename from src/atlas/runtime/timer/TimerBarriers.cc rename to src/atlas/runtime/trace/Barriers.cc index 660c97f15..5977bc44a 100644 --- a/src/atlas/runtime/timer/TimerBarriers.cc +++ b/src/atlas/runtime/trace/Barriers.cc @@ -9,30 +9,30 @@ */ #include -#include "TimerBarriers.h" +#include "Barriers.h" #include "atlas/library/Library.h" #include "atlas/parallel/mpi/mpi.h" -#include "atlas/runtime/timer/StopWatch.h" +#include "atlas/runtime/trace/StopWatch.h" //----------------------------------------------------------------------------------------------------------- namespace atlas { namespace runtime { -namespace timer { +namespace trace { -class TimerBarriersState { +class BarriersState { private: - TimerBarriersState() { + BarriersState() { barriers_ = atlas::Library::instance().barriers(); } bool barriers_; StopWatch stopwatch_; public: - TimerBarriersState(TimerBarriersState const&) = delete; - void operator=(TimerBarriersState const&) = delete; - static TimerBarriersState& instance() { - static TimerBarriersState state; + BarriersState(BarriersState const&) = delete; + void operator=(BarriersState const&) = delete; + static BarriersState& instance() { + static BarriersState state; return state; } operator bool() const { @@ -53,48 +53,48 @@ class TimerBarriersState { } }; -TimerBarriers::TimerBarriers(bool state) : - previous_state_( TimerBarriersState::instance() ) { - TimerBarriersState::instance().set(state); +Barriers::Barriers(bool state) : + previous_state_( BarriersState::instance() ) { + BarriersState::instance().set(state); } -TimerBarriers::~TimerBarriers() { +Barriers::~Barriers() { restore(); } -void TimerBarriers::restore() { - TimerBarriersState::instance().set( previous_state_ ); +void Barriers::restore() { + BarriersState::instance().set( previous_state_ ); } -bool TimerBarriers::state() { - return TimerBarriersState::instance(); +bool Barriers::state() { + return BarriersState::instance(); } -void TimerBarriers::execute() { +void Barriers::execute() { if( state() ) { - TimerBarriersState::instance().stopwatch().start(); + BarriersState::instance().stopwatch().start(); parallel::mpi::comm().barrier(); - TimerBarriersState::instance().stopwatch().stop(); + BarriersState::instance().stopwatch().stop(); } } -double TimerBarriers::time() { - return TimerBarriersState::instance().stopwatch().elapsed(); +double Barriers::time() { + return BarriersState::instance().stopwatch().elapsed(); } -double TimerBarriersNone::time() { - return TimerBarriersState::instance().stopwatch().elapsed(); +double NoBarriers::time() { + return BarriersState::instance().stopwatch().elapsed(); } -std::string TimerBarriers::report() { - return TimerBarriersState::instance().report(); +std::string Barriers::report() { + return BarriersState::instance().report(); } -std::string TimerBarriersNone::report() { - return TimerBarriersState::instance().report(); +std::string NoBarriers::report() { + return BarriersState::instance().report(); } -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/TimerBarriers.h b/src/atlas/runtime/trace/Barriers.h similarity index 85% rename from src/atlas/runtime/timer/TimerBarriers.h rename to src/atlas/runtime/trace/Barriers.h index 741e38c3f..009383885 100644 --- a/src/atlas/runtime/timer/TimerBarriers.h +++ b/src/atlas/runtime/trace/Barriers.h @@ -15,11 +15,11 @@ namespace atlas { namespace runtime { -namespace timer { +namespace trace { -class TimerBarriersNone { +class NoBarriers { public: - TimerBarriersNone(bool state) {} + NoBarriers(bool state) {} void restore() {} public: // static methods @@ -29,10 +29,10 @@ class TimerBarriersNone { static std::string report(); }; -class TimerBarriers { +class Barriers { public: - TimerBarriers(bool state); - ~TimerBarriers(); + Barriers(bool state); + ~Barriers(); void restore(); public: // static methods @@ -44,7 +44,7 @@ class TimerBarriers { bool previous_state_; }; -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/CallStack.cc b/src/atlas/runtime/trace/CallStack.cc similarity index 92% rename from src/atlas/runtime/timer/CallStack.cc rename to src/atlas/runtime/trace/CallStack.cc index 53edb88bb..6b39ccc74 100644 --- a/src/atlas/runtime/timer/CallStack.cc +++ b/src/atlas/runtime/trace/CallStack.cc @@ -6,7 +6,7 @@ namespace atlas { namespace runtime { -namespace timer { +namespace trace { void CallStack::push_front( const eckit::CodeLocation& loc ) { stack_.push_front( std::hash{}(loc.asString()) ); @@ -24,6 +24,6 @@ size_t CallStack::hash() const { return hash_; } -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/CallStack.h b/src/atlas/runtime/trace/CallStack.h similarity index 95% rename from src/atlas/runtime/timer/CallStack.h rename to src/atlas/runtime/trace/CallStack.h index 616f2e476..45d3e1064 100644 --- a/src/atlas/runtime/timer/CallStack.h +++ b/src/atlas/runtime/trace/CallStack.h @@ -6,7 +6,7 @@ namespace eckit { class CodeLocation; } namespace atlas { namespace runtime { -namespace timer { +namespace trace { /// @class CallStack /// Instances of CallStack can keep track of nested eckit::CodeLocations @@ -38,6 +38,6 @@ class CallStack { }; -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/TimerTracing.cc b/src/atlas/runtime/trace/Logging.cc similarity index 65% rename from src/atlas/runtime/timer/TimerTracing.cc rename to src/atlas/runtime/trace/Logging.cc index b261cf26c..0944a727a 100644 --- a/src/atlas/runtime/timer/TimerTracing.cc +++ b/src/atlas/runtime/trace/Logging.cc @@ -8,7 +8,7 @@ * does it submit to any jurisdiction. */ -#include "TimerTracing.h" +#include "Logging.h" #include #include "eckit/log/Channel.h" @@ -18,15 +18,15 @@ namespace atlas { namespace runtime { -namespace timer { +namespace trace { //----------------------------------------------------------------------------------------------------------- -class TimerTracingState { +class LoggingState { private: std::ostream* channel_; - TimerTracingState() { + LoggingState() { channel_ = &atlas::Library::instance().traceChannel(); } @@ -37,8 +37,8 @@ class TimerTracingState { return channel; } - static TimerTracingState& instance() { - static TimerTracingState channel; + static LoggingState& instance() { + static LoggingState channel; return channel; } @@ -51,52 +51,52 @@ class TimerTracingState { //----------------------------------------------------------------------------------------------------------- -TimerTracing::TimerTracing( bool state ) : - previous_state_( TimerTracingState::instance() ) { - TimerTracingState::instance().set( state ); +Logging::Logging( bool state ) : + previous_state_( LoggingState::instance() ) { + LoggingState::instance().set( state ); } -TimerTracing::TimerTracing( std::ostream& channel ) : - previous_state_( TimerTracingState::instance() ) { - TimerTracingState::instance().set( channel ); +Logging::Logging( std::ostream& channel ) : + previous_state_( LoggingState::instance() ) { + LoggingState::instance().set( channel ); } -TimerTracing::~TimerTracing() { - TimerTracingState::instance().set( *previous_state_ ); +Logging::~Logging() { + LoggingState::instance().set( *previous_state_ ); } -std::ostream& TimerTracing::channel() { - return TimerTracingState::instance(); +std::ostream& Logging::channel() { + return LoggingState::instance(); } -bool TimerTracing::enabled() { - return TimerTracingState::instance(); +bool Logging::enabled() { + return LoggingState::instance(); } -void TimerTracing::start( const std::string& title ) { +void Logging::start( const std::string& title ) { if( enabled() ) channel() << title << " ..." << std::endl; } -void TimerTracing::stop( const std::string& title, double seconds ) { +void Logging::stop( const std::string& title, double seconds ) { if( enabled() ) channel() << title << " ... done : " << seconds << "s" << std::endl; } //----------------------------------------------------------------------------------------------------------- -std::ostream& TimerTracingNone::channel() { - return TimerTracingState::empty_channel(); +std::ostream& NoLogging::channel() { + return LoggingState::empty_channel(); } //----------------------------------------------------------------------------------------------------------- -void TimerTracingResult::stop( const std::string& title, double seconds ) { +void LoggingResult::stop( const std::string& title, double seconds ) { if( enabled() ) channel() << title << " : " << seconds << "s" << std::endl; } //----------------------------------------------------------------------------------------------------------- -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/TimerTracing.h b/src/atlas/runtime/trace/Logging.h similarity index 84% rename from src/atlas/runtime/timer/TimerTracing.h rename to src/atlas/runtime/trace/Logging.h index 0515c4e5a..1d99fdd3c 100644 --- a/src/atlas/runtime/timer/TimerTracing.h +++ b/src/atlas/runtime/trace/Logging.h @@ -16,15 +16,15 @@ namespace atlas { namespace runtime { -namespace timer { +namespace trace { //----------------------------------------------------------------------------------------------------------- // Class used to avoid any printing before and after a timer -class TimerTracingNone { +class NoLogging { public: - TimerTracingNone( bool state ); - TimerTracingNone( std::ostream& channel ); + NoLogging( bool state ); + NoLogging( std::ostream& channel ); public: // static methods static std::ostream& channel(); @@ -39,11 +39,11 @@ class TimerTracingNone { // Example print: // timer-name ... // timer-name ... done : 5s -class TimerTracing { +class Logging { public: - TimerTracing( bool state ); - TimerTracing( std::ostream& channel ); - virtual ~TimerTracing(); + Logging( bool state ); + Logging( std::ostream& channel ); + virtual ~Logging(); public: // static methods static std::ostream& channel(); @@ -60,9 +60,9 @@ class TimerTracing { // Class used to print message only upon end of a timer // Example print: // timer-name : 5s -class TimerTracingResult : public TimerTracing { +class LoggingResult : public Logging { public: - using TimerTracing::TimerTracing; + using Logging::Logging; public: // static methods static void start( const std::string& ) {} @@ -71,7 +71,7 @@ class TimerTracingResult : public TimerTracing { //----------------------------------------------------------------------------------------------------------- -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/TimerNesting.cc b/src/atlas/runtime/trace/Nesting.cc similarity index 61% rename from src/atlas/runtime/timer/TimerNesting.cc rename to src/atlas/runtime/trace/Nesting.cc index ef7a3ae37..a0e121b23 100644 --- a/src/atlas/runtime/timer/TimerNesting.cc +++ b/src/atlas/runtime/trace/Nesting.cc @@ -8,24 +8,24 @@ * does it submit to any jurisdiction. */ -#include "TimerNesting.h" +#include "Nesting.h" //----------------------------------------------------------------------------------------------------------- namespace atlas { namespace runtime { -namespace timer { +namespace trace { -class TimerNestingState { +class NestingState { private: - TimerNestingState() {} + NestingState() {} CallStack stack_; public: - TimerNestingState(TimerNestingState const&) = delete; - void operator=(TimerNestingState const&) = delete; - static TimerNestingState& instance() { - static TimerNestingState state; + NestingState(NestingState const&) = delete; + void operator=(NestingState const&) = delete; + static NestingState& instance() { + static NestingState state; return state; } operator CallStack() const { @@ -40,30 +40,30 @@ class TimerNestingState { } }; -TimerNesting::TimerNesting( const eckit::CodeLocation& loc ) : +Nesting::Nesting( const eckit::CodeLocation& loc ) : loc_(loc), - stack_( TimerNestingState::instance().push( loc ) ) { + stack_( NestingState::instance().push( loc ) ) { } -TimerNesting::~TimerNesting() { +Nesting::~Nesting() { stop(); } -void TimerNesting::stop() { +void Nesting::stop() { if( running_ ) { - TimerNestingState::instance().pop(); + NestingState::instance().pop(); running_ = false; } } -void TimerNesting::start() { +void Nesting::start() { if( not running_ ) { - TimerNestingState::instance().push( loc_ ); + NestingState::instance().push( loc_ ); running_ = true; } } -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/TimerNesting.h b/src/atlas/runtime/trace/Nesting.h similarity index 82% rename from src/atlas/runtime/timer/TimerNesting.h rename to src/atlas/runtime/trace/Nesting.h index 103b75323..e00d72b13 100644 --- a/src/atlas/runtime/timer/TimerNesting.h +++ b/src/atlas/runtime/trace/Nesting.h @@ -11,19 +11,19 @@ #pragma once #include "eckit/log/CodeLocation.h" -#include "atlas/runtime/timer/CallStack.h" +#include "atlas/runtime/trace/CallStack.h" //----------------------------------------------------------------------------------------------------------- namespace atlas { namespace runtime { -namespace timer { +namespace trace { -class TimerNesting { +class Nesting { public: - TimerNesting( const eckit::CodeLocation& ); - ~TimerNesting(); + Nesting( const eckit::CodeLocation& ); + ~Nesting(); operator CallStack() const { return stack_; } void stop(); void start(); @@ -34,7 +34,7 @@ class TimerNesting { }; -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/StopWatch.h b/src/atlas/runtime/trace/StopWatch.h similarity index 98% rename from src/atlas/runtime/timer/StopWatch.h rename to src/atlas/runtime/trace/StopWatch.h index 1dc32e9ed..9b7c58c6b 100644 --- a/src/atlas/runtime/timer/StopWatch.h +++ b/src/atlas/runtime/trace/StopWatch.h @@ -14,7 +14,7 @@ namespace atlas { namespace runtime { -namespace timer { +namespace trace { //----------------------------------------------------------------------------------------------------------- @@ -64,6 +64,6 @@ inline double StopWatch::elapsed() const { //----------------------------------------------------------------------------------------------------------- -} // timer +} // trace } // runtime } // atlas diff --git a/src/atlas/runtime/timer/Timings.cc b/src/atlas/runtime/trace/Timings.cc similarity index 99% rename from src/atlas/runtime/timer/Timings.cc rename to src/atlas/runtime/trace/Timings.cc index 8e9538590..0de943e32 100644 --- a/src/atlas/runtime/timer/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -18,7 +18,7 @@ #include "eckit/config/Configuration.h" #include "eckit/filesystem/PathName.h" #include "atlas/util/Config.h" -#include "atlas/runtime/timer/CallStack.h" +#include "atlas/runtime/trace/CallStack.h" #include "atlas/runtime/Debug.h" #include "atlas/parallel/mpi/mpi.h" @@ -26,7 +26,7 @@ namespace atlas { namespace runtime { -namespace timer { +namespace trace { class TimingsRegistry { @@ -394,7 +394,7 @@ std::string Timings::report( const Configuration& config ) { } -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/Timings.h b/src/atlas/runtime/trace/Timings.h similarity index 96% rename from src/atlas/runtime/timer/Timings.h rename to src/atlas/runtime/trace/Timings.h index 50c6b3734..651010ecf 100644 --- a/src/atlas/runtime/timer/Timings.h +++ b/src/atlas/runtime/trace/Timings.h @@ -20,7 +20,7 @@ namespace eckit { class CodeLocation; } namespace atlas { namespace runtime { -namespace timer { +namespace trace { class CallStack; @@ -44,7 +44,7 @@ class Timings { }; -} // namespace timer +} // namespace trace } // namespace runtime } // namespace atlas diff --git a/src/atlas/runtime/timer/TimerT.h b/src/atlas/runtime/trace/TraceT.h similarity index 61% rename from src/atlas/runtime/timer/TimerT.h rename to src/atlas/runtime/trace/TraceT.h index fc53ad506..d96c511c6 100644 --- a/src/atlas/runtime/timer/TimerT.h +++ b/src/atlas/runtime/trace/TraceT.h @@ -14,9 +14,9 @@ #include #include #include -#include "atlas/runtime/timer/StopWatch.h" -#include "atlas/runtime/timer/Timings.h" -#include "atlas/runtime/timer/TimerNesting.h" +#include "atlas/runtime/trace/StopWatch.h" +#include "atlas/runtime/trace/Timings.h" +#include "atlas/runtime/trace/Nesting.h" //----------------------------------------------------------------------------------------------------------- @@ -29,15 +29,15 @@ namespace eckit { namespace atlas { namespace runtime { -namespace timer { +namespace trace { //----------------------------------------------------------------------------------------------------------- -template< typename TimerTraits > -class TimerT { +template< typename TraceTraits > +class TraceT { public: - using Barriers = typename TimerTraits::Barriers; - using Tracing = typename TimerTraits::Tracing; + using Barriers = typename TraceTraits::Barriers; + using Tracing = typename TraceTraits::Tracing; using Labels = std::vector; public: // static methods @@ -47,11 +47,11 @@ class TimerT { public: - TimerT( const eckit::CodeLocation& ); - TimerT( const eckit::CodeLocation&, const std::string& title ); - TimerT( const eckit::CodeLocation&, const std::string& title, const Labels& ); + TraceT( const eckit::CodeLocation& ); + TraceT( const eckit::CodeLocation&, const std::string& title ); + TraceT( const eckit::CodeLocation&, const std::string& title, const Labels& ); - ~TimerT(); + ~TraceT(); bool running() const; @@ -67,9 +67,7 @@ class TimerT { private: // types - using Nesting = timer::TimerNesting; - using Timings = timer::Timings; - using Identifier = timer::Timings::Identifier; + using Identifier = Timings::Identifier; private: // member functions @@ -93,24 +91,24 @@ class TimerT { //----------------------------------------------------------------------------------------------------------- // Definitions -template< typename TimerTraits > -inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& title ) : +template< typename TraceTraits > +inline TraceT::TraceT( const eckit::CodeLocation& loc, const std::string& title ) : loc_(loc), title_(title), nesting_(loc) { start(); } -template< typename TimerTraits > -inline TimerT::TimerT( const eckit::CodeLocation& loc ) : +template< typename TraceTraits > +inline TraceT::TraceT( const eckit::CodeLocation& loc ) : loc_(loc), title_( loc_ ? loc_.func() : ""), nesting_(loc_) { start(); } -template< typename TimerTraits > -inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::string& title, const Labels& labels ) : +template< typename TraceTraits > +inline TraceT::TraceT( const eckit::CodeLocation& loc, const std::string& title, const Labels& labels ) : loc_(loc), title_(title), nesting_(loc), @@ -118,41 +116,41 @@ inline TimerT::TimerT( const eckit::CodeLocation& loc, const std::s start(); } -template< typename TimerTraits > -inline TimerT::~TimerT() { +template< typename TraceTraits > +inline TraceT::~TraceT() { stop(); } -template< typename TimerTraits > -inline void TimerT::barrier() const { +template< typename TraceTraits > +inline void TraceT::barrier() const { Barriers::execute(); } -template< typename TimerTraits > -inline void TimerT::registerTimer() { +template< typename TraceTraits > +inline void TraceT::registerTimer() { id_ = Timings::add( loc_, nesting_, title_ + (Barriers::state() ? " [b]" : ""), labels_ ); } -template< typename TimerTraits > -inline void TimerT::updateTimings() const { +template< typename TraceTraits > +inline void TraceT::updateTimings() const { Timings::update( id_, stopwatch_.elapsed() ); } -template< typename TimerTraits > -inline bool TimerT::running() const { +template< typename TraceTraits > +inline bool TraceT::running() const { return running_; } -template< typename TimerTraits > -inline void TimerT::start() { +template< typename TraceTraits > +inline void TraceT::start() { registerTimer(); Tracing::start( title_ ); barrier(); stopwatch_.start(); } -template< typename TimerTraits > -inline void TimerT::stop() { +template< typename TraceTraits > +inline void TraceT::stop() { if( running_ ) { barrier(); stopwatch_.stop(); @@ -163,8 +161,8 @@ inline void TimerT::stop() { } } -template< typename TimerTraits > -inline void TimerT::pause() { +template< typename TraceTraits > +inline void TraceT::pause() { if( running_ ) { barrier(); stopwatch_.stop(); @@ -172,8 +170,8 @@ inline void TimerT::pause() { } } -template< typename TimerTraits > -inline void TimerT::resume() { +template< typename TraceTraits > +inline void TraceT::resume() { if( running_ ) { barrier(); nesting_.start(); @@ -181,23 +179,23 @@ inline void TimerT::resume() { } } -template< typename TimerTraits > -inline double TimerT::elapsed() const { +template< typename TraceTraits > +inline double TraceT::elapsed() const { return stopwatch_.elapsed(); } -template< typename TimerTraits > -inline std::string TimerT::report() { +template< typename TraceTraits > +inline std::string TraceT::report() { return Timings::report() + Barriers::report(); } -template< typename TimerTraits > -inline std::string TimerT::report( const eckit::Configuration& config ) { +template< typename TraceTraits > +inline std::string TraceT::report( const eckit::Configuration& config ) { return Timings::report(config) + Barriers::report(); } //----------------------------------------------------------------------------------------------------------- -} // timer +} // trace } // runtime } // atlas From cfce070c60eec62ba11e5e1f683a3f68588a68bd Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 11 Oct 2017 16:31:53 +0000 Subject: [PATCH 029/355] ATLAS-132 Use unicode numbers instead of rendered --- src/atlas/runtime/trace/Timings.cc | 44 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/atlas/runtime/trace/Timings.cc b/src/atlas/runtime/trace/Timings.cc index 0de943e32..9db28ccc4 100644 --- a/src/atlas/runtime/trace/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -113,6 +113,22 @@ void TimingsRegistry::update( size_t idx, double seconds ) { size_t TimingsRegistry::size() const { return counts_.size(); } void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& config ) { + auto box_horizontal = [](int n) { + std::string s; s.reserve(2*n); + for( size_t i=0; i std::string { - std::stringstream ss; - for( size_t i=0; i std::string { + return box_horizontal(length); }; + auto print_horizontal = [&](const std::string& sep) -> std::string { std::stringstream ss; ss << print_line(max_title_length + digits(size()) + 3) @@ -238,10 +251,10 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con return ss.str(); }; - std::string sept("─┬─"); - std::string seph("─┼─"); - std::string sep (" │ "); - std::string sepf("─┴─"); + std::string sept = box_horizontal(1)+box_T_down+box_horizontal(1); + std::string seph = box_horizontal(1)+box_cross+box_horizontal(1); + std::string sep = std::string(" ") +box_vertical+std::string(" "); + std::string sepf = box_horizontal(1)+box_T_up+box_horizontal(1); out << print_horizontal( sept ) << std::endl; @@ -282,18 +295,18 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con std::stringstream out; for( long i=0; i Date: Wed, 11 Oct 2017 18:39:41 +0100 Subject: [PATCH 030/355] ATLAS-132 Fix gcc blackmagic for ATLAS_TRACE ; ATLAS_TRACE_MPI still to fix (disabled for now) --- src/atlas/parallel/mpi/Statistics.h | 14 +++++------ src/atlas/runtime/Trace.h | 9 ++++++-- src/atlas/util/detail/BlackMagic.h | 36 ++++++++++------------------- 3 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 962819323..1ef0466fd 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -16,16 +16,16 @@ #define ATLAS_TRACE_MPI(...) -#if ATLAS_HAVE_TRACE +//#if ATLAS_HAVE_TRACE -#include "atlas/util/detail/BlackMagic.h" +//#include "atlas/util/detail/BlackMagic.h" -#undef ATLAS_TRACE_MPI -#define ATLAS_TRACE_MPI(...) ATLAS_TRACE_MPI_( ::atlas::parallel::mpi::Statistics, Here(), ##__VA_ARGS__ ) -#define ATLAS_TRACE_MPI_( Type, loc, enum_var, ... ) \ - __ATLAS_TYPE_SCOPE( Type, loc, ::atlas::parallel::mpi::StatisticsEnum::__ATLAS_STRINGIFY(enum_var), ##__VA_ARGS__ ) +//#undef ATLAS_TRACE_MPI +//#define ATLAS_TRACE_MPI(...) ATLAS_TRACE_MPI_( ::atlas::parallel::mpi::Statistics, Here(), ##__VA_ARGS__ ) +//#define ATLAS_TRACE_MPI_( Type, loc, enum_var, ... ) \ +// __ATLAS_TYPE_SCOPE( Type, loc, ::atlas::parallel::mpi::StatisticsEnum::__ATLAS_STRINGIFY(enum_var), ##__VA_ARGS__ ) -#endif +//#endif namespace atlas { diff --git a/src/atlas/runtime/Trace.h b/src/atlas/runtime/Trace.h index 0471702b4..373efd8eb 100644 --- a/src/atlas/runtime/Trace.h +++ b/src/atlas/runtime/Trace.h @@ -79,8 +79,13 @@ class Trace : public runtime::trace::TraceT< TraceTraits > { #undef ATLAS_TRACE #undef ATLAS_TRACE_SCOPE -#define ATLAS_TRACE(...) __ATLAS_TYPE( ::atlas::Trace, Here(), ##__VA_ARGS__ ) -#define ATLAS_TRACE_SCOPE(...) __ATLAS_TYPE_SCOPE( ::atlas::Trace, Here(), ##__VA_ARGS__ ) +#define ATLAS_TRACE(...) __ATLAS_SPLICE( __ATLAS_TRACE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) +#define __ATLAS_TRACE_1(...) __ATLAS_TYPE( ::atlas::Trace, Here() ) +#define __ATLAS_TRACE_0(...) __ATLAS_TYPE( ::atlas::Trace, Here(), __VA_ARGS__ ) + +#define ATLAS_TRACE_SCOPE(...) __ATLAS_SPLICE( __ATLAS_TRACE_SCOPE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) +#define __ATLAS_TRACE_SCOPE_1(...) __ATLAS_TYPE_SCOPE( ::atlas::Trace, Here() ) +#define __ATLAS_TRACE_SCOPE_0(...) __ATLAS_TYPE_SCOPE( ::atlas::Trace, Here(), __VA_ARGS__ ) #endif diff --git a/src/atlas/util/detail/BlackMagic.h b/src/atlas/util/detail/BlackMagic.h index 7a4de4678..5fcac2127 100644 --- a/src/atlas/util/detail/BlackMagic.h +++ b/src/atlas/util/detail/BlackMagic.h @@ -57,36 +57,24 @@ __ATLAS_ISEMPTY_( #define __ATLAS_CALL_NARG_1(...) 0 #define __ATLAS_CALL_NARG_0 __ATLAS_NARG_ #define __ATLAS_NARG(...) __ATLAS_SPLICE( __ATLAS_CALL_NARG_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) - -#define __ATLAS_TYPE( Type, ... ) __ATLAS_TYPE_( __ATLAS_NARG(__VA_ARGS__), Type, ##__VA_ARGS__ ) -#define __ATLAS_TYPE_SCOPE( Type, ... ) __ATLAS_TYPE_SCOPE_( __ATLAS_NARG(__VA_ARGS__), Type, ##__VA_ARGS__ ) -#define __ATLAS_TYPE_( N, ... ) __ATLAS_SPLICE( __ATLAS_TYPE_, N )( __VA_ARGS__ ) -#define __ATLAS_TYPE_SCOPE_( N, ... ) __ATLAS_SPLICE( __ATLAS_TYPE_SCOPE_, N )( __VA_ARGS__ ) -#define __ATLAS_TYPE_0( Type ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) ( ); -#define __ATLAS_TYPE_1( Type, arg1 ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1 ); -#define __ATLAS_TYPE_2( Type, arg1, arg2 ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1, arg2 ); -#define __ATLAS_TYPE_3( Type, arg1, arg2, arg3 ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1, arg2, arg3 ); +#define __ATLAS_ARGS_OR_DUMMY(...) __ATLAS_SPLICE( __ATLAS_ARGS_OR_DUMMY_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) ( __VA_ARGS__) +#define __ATLAS_ARGS_OR_DUMMY_0(...) __VA_ARGS__ +#define __ATLAS_ARGS_OR_DUMMY_1(...) 0 -#define __ATLAS_TYPE_SCOPE_0( Type ) \ - for( Type \ - __ATLAS_SPLICE( __variable_, __LINE__ ) ( );\ - __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ - __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) -#define __ATLAS_TYPE_SCOPE_1( Type, arg1 ) \ - for( Type \ - __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1 ); \ - __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ - __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) -#define __ATLAS_TYPE_SCOPE_2( Type , arg1, arg2 ) \ +#define __ATLAS_TYPE(Type,...) __ATLAS_SPLICE( __ATLAS_TYPE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) ( Type, __ATLAS_ARGS_OR_DUMMY(__VA_ARGS__) ) +#define __ATLAS_TYPE_1( Type, dummy ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) +#define __ATLAS_TYPE_0( Type, ... ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) (__VA_ARGS__) + +#define __ATLAS_TYPE_SCOPE(Type,...) __ATLAS_SPLICE( __ATLAS_TYPE_SCOPE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) ( Type, __ATLAS_ARGS_OR_DUMMY(__VA_ARGS__) ) +#define __ATLAS_TYPE_SCOPE_1( Type, dummy ) \ for( Type \ - __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1, arg2 );\ + __ATLAS_SPLICE( __variable_, __LINE__ );\ __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) -#define __ATLAS_TYPE_SCOPE_3( Type , arg1, arg2, arg3 ) \ +#define __ATLAS_TYPE_SCOPE_0( Type, ... ) \ for( Type \ - __ATLAS_SPLICE( __variable_, __LINE__ ) ( arg1, arg2, arg3 );\ + __ATLAS_SPLICE( __variable_, __LINE__ ) (__VA_ARGS__); \ __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) - From 2104f8c9b4638ccf176b561e3325bb18e8098e65 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 12 Oct 2017 08:43:07 +0100 Subject: [PATCH 031/355] ATLAS-132 Fix ATLAS_TRACE_MPI again --- src/atlas/CMakeLists.txt | 1 - src/atlas/functionspace/StructuredColumns.cc | 1 - .../meshgenerator/RegularMeshGenerator.cc | 1 - src/atlas/parallel/mpi/Statistics.h | 28 +++++++++-------- src/atlas/runtime/Debug.h | 30 ------------------- src/atlas/runtime/Log.h | 15 ++++++---- src/atlas/runtime/Trace.h | 9 ++---- src/atlas/runtime/trace/Timings.cc | 14 ++++----- src/atlas/util/detail/BlackMagic.h | 21 +++++++------ 9 files changed, 43 insertions(+), 77 deletions(-) delete mode 100644 src/atlas/runtime/Debug.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 16404689b..eef61f9f4 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -443,7 +443,6 @@ mesh/detail/AccumulateFacets.cc util/Bitflags.h util/Checksum.h util/Checksum.cc -runtime/Debug.h util/MicroDeg.h mesh/IsGhostNode.h util/LonLatMicroDeg.h diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 9c2218002..d0230b46f 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -21,7 +21,6 @@ #include "atlas/util/Checksum.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/runtime/ErrorHandling.h" -#include "atlas/runtime/Debug.h" #include "atlas/runtime/Trace.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/GatherScatter.h" diff --git a/src/atlas/meshgenerator/RegularMeshGenerator.cc b/src/atlas/meshgenerator/RegularMeshGenerator.cc index 60bd2e081..d21102764 100644 --- a/src/atlas/meshgenerator/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/RegularMeshGenerator.cc @@ -22,7 +22,6 @@ #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" #include "atlas/parallel/mpi/mpi.h" -#include "atlas/runtime/Debug.h" #include "atlas/runtime/Log.h" #define DEBUG_OUTPUT 0 diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 1ef0466fd..b328e38c7 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -16,16 +16,18 @@ #define ATLAS_TRACE_MPI(...) -//#if ATLAS_HAVE_TRACE +#if ATLAS_HAVE_TRACE -//#include "atlas/util/detail/BlackMagic.h" +#include "atlas/util/detail/BlackMagic.h" -//#undef ATLAS_TRACE_MPI -//#define ATLAS_TRACE_MPI(...) ATLAS_TRACE_MPI_( ::atlas::parallel::mpi::Statistics, Here(), ##__VA_ARGS__ ) -//#define ATLAS_TRACE_MPI_( Type, loc, enum_var, ... ) \ -// __ATLAS_TYPE_SCOPE( Type, loc, ::atlas::parallel::mpi::StatisticsEnum::__ATLAS_STRINGIFY(enum_var), ##__VA_ARGS__ ) +#undef ATLAS_TRACE_MPI +#define ATLAS_TRACE_MPI(...) ATLAS_TRACE_MPI_( ::atlas::parallel::mpi::Statistics, 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__) ) -//#endif +#define __ATLAS_TRACE_MPI_ENUM(operation) ::atlas::parallel::mpi::Operation::__ATLAS_STRINGIFY(operation) + +#endif namespace atlas { @@ -38,7 +40,7 @@ struct StatisticsTimerTraits { }; -enum class StatisticsEnum { +enum class Operation { BROADCAST, ALLREDUCE, ALLGATHER, @@ -54,8 +56,8 @@ enum class StatisticsEnum { _COUNT_ }; -static const std::string& name(StatisticsEnum c) { - static std::array(StatisticsEnum::_COUNT_)> names { +static const std::string& name(Operation c) { + static std::array(Operation::_COUNT_)> names { "mpi.broadcast", "mpi.allreduce", "mpi.allgather", @@ -75,14 +77,14 @@ static const std::string& name(StatisticsEnum c) { class Statistics : public runtime::trace::TraceT< StatisticsTimerTraits > { using Base = runtime::trace::TraceT< StatisticsTimerTraits >; public: - Statistics( const eckit::CodeLocation& loc, StatisticsEnum c ) : + Statistics( const eckit::CodeLocation& loc, Operation c ) : Base( loc, name(c), make_labels(c) ) { } - Statistics( const eckit::CodeLocation& loc, StatisticsEnum c, const std::string& title ) : + Statistics( const eckit::CodeLocation& loc, Operation c, const std::string& title ) : Base( loc, title, make_labels(c) ) { } private: - static std::vector make_labels( StatisticsEnum c) { + static std::vector make_labels( Operation c) { return {"mpi", name(c)}; } }; diff --git a/src/atlas/runtime/Debug.h b/src/atlas/runtime/Debug.h deleted file mode 100644 index c6d3e90de..000000000 --- a/src/atlas/runtime/Debug.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 -#include - -#include "atlas/library/config.h" -#include "atlas/runtime/Log.h" -#include "atlas/parallel/mpi/mpi.h" - -/// DEBUG MACRO -#define DEBUG_RANK (parallel::mpi::comm().rank()) -#define DEBUG_HERE() atlas::Log::info() << "["<< DEBUG_RANK << "] DEBUG() @ " << Here() << std::endl; -#define DEBUG(WHAT) atlas::Log::info() << "["<< DEBUG_RANK << "] DEBUG( " << WHAT << " ) @ " << Here() << std::endl; - -/// DEBUG_VAR MACRO -#ifdef DEBUG_VAR - #undef DEBUG_VAR -#endif -#define DEBUG_VAR(VAR) \ - atlas::Log::info() << "["<< DEBUG_RANK << "] DEBUG( " << #VAR << " : " << VAR << " ) @ " << Here() << std::endl; diff --git a/src/atlas/runtime/Log.h b/src/atlas/runtime/Log.h index 3e864b3b6..569dc24fa 100644 --- a/src/atlas/runtime/Log.h +++ b/src/atlas/runtime/Log.h @@ -39,10 +39,13 @@ class Log : public detail::LogBase { }; } // namespace atlas -#define ATLAS_DEBUG(WHAT) do{ atlas::Log::info() << "DEBUG(" << WHAT << ") @ " << Here() << std::endl; } while(0) -#define ATLAS_DEBUG_HERE() do{ atlas::Log::info() << "DEBUG() @ " << Here() << std::endl; } while(0) -#define ATLAS_DEBUG_VAR(VAR) do{ atlas::Log::info() << "DEBUG( " << #VAR << " : " << VAR << " ) @ " << Here() << std::endl; } while(0) +#include "atlas/util/detail/BlackMagic.h" + +#define ATLAS_DEBUG_HERE() do{ ::atlas::Log::info() << "DEBUG() @ " << Here() << std::endl; } while(0) +#define ATLAS_DEBUG_WHAT(WHAT) do{ ::atlas::Log::info() << "DEBUG(" << WHAT << ") @ " << Here() << std::endl; } while(0) +#define ATLAS_DEBUG_VAR(VAR) do{ ::atlas::Log::info() << "DEBUG( " << #VAR << " : " << VAR << " ) @ " << Here() << std::endl; } while(0) + +#define ATLAS_DEBUG(...) __ATLAS_SPLICE( __ATLAS_DEBUG_, __ATLAS_NARGS(__VA_ARGS__) ) (__VA_ARGS__) +#define __ATLAS_DEBUG_0 ATLAS_DEBUG_HERE +#define __ATLAS_DEBUG_1 ATLAS_DEBUG_WHAT -#define ATLAS_DEBUG(WHAT) do{ atlas::Log::info() << "DEBUG(" << WHAT << ") @ " << Here() << std::endl; } while(0) -#define ATLAS_DEBUG_HERE() do{ atlas::Log::info() << "DEBUG() @ " << Here() << std::endl; } while(0) -#define ATLAS_DEBUG_VAR(VAR) do{ atlas::Log::info() << "DEBUG( " << #VAR << " : " << VAR << " ) @ " << Here() << std::endl; } while(0) diff --git a/src/atlas/runtime/Trace.h b/src/atlas/runtime/Trace.h index 373efd8eb..447de8aa9 100644 --- a/src/atlas/runtime/Trace.h +++ b/src/atlas/runtime/Trace.h @@ -79,13 +79,8 @@ class Trace : public runtime::trace::TraceT< TraceTraits > { #undef ATLAS_TRACE #undef ATLAS_TRACE_SCOPE -#define ATLAS_TRACE(...) __ATLAS_SPLICE( __ATLAS_TRACE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) -#define __ATLAS_TRACE_1(...) __ATLAS_TYPE( ::atlas::Trace, Here() ) -#define __ATLAS_TRACE_0(...) __ATLAS_TYPE( ::atlas::Trace, Here(), __VA_ARGS__ ) - -#define ATLAS_TRACE_SCOPE(...) __ATLAS_SPLICE( __ATLAS_TRACE_SCOPE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) -#define __ATLAS_TRACE_SCOPE_1(...) __ATLAS_TYPE_SCOPE( ::atlas::Trace, Here() ) -#define __ATLAS_TRACE_SCOPE_0(...) __ATLAS_TYPE_SCOPE( ::atlas::Trace, Here(), __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/runtime/trace/Timings.cc b/src/atlas/runtime/trace/Timings.cc index 9db28ccc4..9d43d450b 100644 --- a/src/atlas/runtime/trace/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -19,7 +19,6 @@ #include "eckit/filesystem/PathName.h" #include "atlas/util/Config.h" #include "atlas/runtime/trace/CallStack.h" -#include "atlas/runtime/Debug.h" #include "atlas/parallel/mpi/mpi.h" //----------------------------------------------------------------------------------------------------------- @@ -349,10 +348,11 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con std::string sepc = box_horizontal(3); - out << "\n"; - out << print_horizontal(sepc) << std::endl; - out << "Timers accumulated by label" << std::endl; - out << print_horizontal(sepc) << std::endl; + out << std::left << box_horizontal(40) << sept << box_horizontal(5) << sept << box_horizontal(12) << "\n"; + out << std::left << std::setw(40) << "Timers accumulated by label" + << sep << std::left << std::setw(5) << "count" + << sep << "time" << std::endl; + out << std::left << box_horizontal(40) << seph << box_horizontal(5) << seph << box_horizontal(12) << "\n"; for( auto label : labels_ ) { auto name = label.first; auto timers = label.second; @@ -363,11 +363,11 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con count += counts_[j]; } out << std::left << std::setw(40) << name + << sep << std::left << std::setw(5) << count << sep << print_time(tot) - << sep << std::string(header ? "" : "count: ") << std::left << std::setw(max_count_length) << count << std::endl; } - out << print_horizontal(sepc) << std::endl; + out << std::left << box_horizontal(40) << sepf << box_horizontal(5) << sepf << box_horizontal(12) << "\n"; } diff --git a/src/atlas/util/detail/BlackMagic.h b/src/atlas/util/detail/BlackMagic.h index 5fcac2127..651804430 100644 --- a/src/atlas/util/detail/BlackMagic.h +++ b/src/atlas/util/detail/BlackMagic.h @@ -54,10 +54,13 @@ __ATLAS_ISEMPTY_( #define __ATLAS_ISEMPTY_(_0, _1, _2, _3) __ATLAS_HAS_COMMA(__ATLAS_PASTE5(__ATLAS_IS_EMPTY_CASE_, _0, _1, _2, _3)) #define __ATLAS_IS_EMPTY_CASE_0001 , +#define __ATLAS_NARG(...) __ATLAS_SPLICE( __ATLAS_CALL_NARG_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) #define __ATLAS_CALL_NARG_1(...) 0 #define __ATLAS_CALL_NARG_0 __ATLAS_NARG_ -#define __ATLAS_NARG(...) __ATLAS_SPLICE( __ATLAS_CALL_NARG_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) +#define __ATLAS_COMMA_ARGS(...) __ATLAS_SPLICE( __ATLAS_COMMA_ARGS_, __ATLAS_ISEMPTY(__VA_ARGS__) ) (__VA_ARGS__) +#define __ATLAS_COMMA_ARGS_1(...) +#define __ATLAS_COMMA_ARGS_0(...) , __VA_ARGS__ #define __ATLAS_ARGS_OR_DUMMY(...) __ATLAS_SPLICE( __ATLAS_ARGS_OR_DUMMY_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) ( __VA_ARGS__) #define __ATLAS_ARGS_OR_DUMMY_0(...) __VA_ARGS__ @@ -68,13 +71,9 @@ __ATLAS_ISEMPTY_( #define __ATLAS_TYPE_0( Type, ... ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) (__VA_ARGS__) #define __ATLAS_TYPE_SCOPE(Type,...) __ATLAS_SPLICE( __ATLAS_TYPE_SCOPE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) ( Type, __ATLAS_ARGS_OR_DUMMY(__VA_ARGS__) ) -#define __ATLAS_TYPE_SCOPE_1( Type, dummy ) \ - for( Type \ - __ATLAS_SPLICE( __variable_, __LINE__ );\ - __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ - __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) -#define __ATLAS_TYPE_SCOPE_0( Type, ... ) \ - for( Type \ - __ATLAS_SPLICE( __variable_, __LINE__ ) (__VA_ARGS__); \ - __ATLAS_SPLICE( __variable_, __LINE__ ) .running(); \ - __ATLAS_SPLICE( __variable_, __LINE__ ) .stop() ) +#define __ATLAS_TYPE_SCOPE_1( Type, ... ) \ + for( bool __ATLAS_SPLICE( __done_, __LINE__ )=false; __ATLAS_SPLICE( __done_, __LINE__ )!=true; ) \ + for( Type __ATLAS_SPLICE( __variable_, __LINE__ ); __ATLAS_SPLICE( __done_, __LINE__ )!=true; __ATLAS_SPLICE( __done_, __LINE__ )=true ) +#define __ATLAS_TYPE_SCOPE_0( Type, ... ) \ + for( bool __ATLAS_SPLICE( __done_, __LINE__ )=false; __ATLAS_SPLICE( __done_, __LINE__ )!=true; ) \ + for( Type __ATLAS_SPLICE( __variable_, __LINE__ )(__VA_ARGS__); __ATLAS_SPLICE( __done_, __LINE__ )!=true; __ATLAS_SPLICE( __done_, __LINE__ )=true ) From 590b867a2ac405ad05fcd8d577d1d2244f763c25 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 12 Oct 2017 16:50:11 +0100 Subject: [PATCH 032/355] ATLAS-103 Change partitioner to EqualRegions --- src/atlas/mesh/actions/BuildHalo.cc | 2 +- .../atlas-benchmark-build-halo.cc | 23 ++++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 06ce6c410..310e6b69f 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -44,7 +44,7 @@ #include "atlas/mesh/actions/BuildXYZField.h" #endif -#define ATLAS_103 +// #define ATLAS_103 // #define ATLAS_103_SORT #ifndef ATLAS_103 diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc index 91d54c184..97fd6161e 100644 --- a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -48,7 +48,7 @@ class Tool : public AtlasTool { return "Tool to generate a python script that plots the grid-distribution of a given grid"; } virtual std::string usage() { - return name() + " (--grid.name=name|--grid.json=path) [OPTION]... OUTPUT [--help]"; + return name() + " --grid=name [OPTION]... OUTPUT [--help]"; } public: @@ -67,21 +67,21 @@ class Tool : public AtlasTool { Tool::Tool(int argc,char **argv): AtlasTool(argc,argv) { - add_option( new SimpleOption("grid.name","Grid unique identifier\n" + add_option( new SimpleOption("grid","Grid unique identifier\n" +indent()+" Example values: N80, F40, O24, L32") ); - add_option( new SimpleOption("grid.json","Grid described by json file") ); - add_option( new SimpleOption("halo","Number of halos") ); + add_option( new SimpleOption("halo","Number of halos (default=1") ); } //----------------------------------------------------------------------------- void Tool::execute(const Args& args) { + Trace timer(Here(), displayName() ); key = ""; - args.get("grid.name",key); + args.get("grid",key); std::string path_in_str = ""; - if( args.get("grid.json",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() ) @@ -89,24 +89,18 @@ void Tool::execute(const Args& args) try{ grid = Grid(key); } catch( eckit::BadParameter& e ){} } - else if( path_in.path().size() ) - { - Log::info() << "Creating grid from file " << path_in << std::endl; - Log::debug() << Config(path_in) << std::endl; - try{ grid = Grid( Config(path_in) ); } - catch( eckit::BadParameter& e ){} - } else { Log::error() << "No grid specified." << std::endl; } + if( !grid ) return; Log::debug() << "Domain: " << grid.domain() << std::endl; Log::debug() << "Periodic: " << grid.periodic() << std::endl; - MeshGenerator meshgenerator("structured"); + MeshGenerator meshgenerator("structured", util::Config("partitioner","equal_regions")); size_t halo = args.getLong("halo",1); @@ -117,6 +111,7 @@ void Tool::execute(const Args& args) mesh::actions::build_halo( mesh, halo ); parallel::mpi::comm().barrier(); } + timer.stop(); Log::info() << Trace::report() << std::endl; } From 7459ab22f6ecffa69c274960c10019d916c832e0 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 12 Oct 2017 18:04:52 +0100 Subject: [PATCH 033/355] Require eckit 0.18 --- CMakeLists.txt | 8 +------ src/atlas/CMakeLists.txt | 5 ---- .../MatchingMeshPartitionerBruteForce.cc | 18 ++++----------- .../MatchingMeshPartitionerLonLatPolygon.cc | 18 ++++----------- ...MatchingMeshPartitionerSphericalPolygon.cc | 18 ++++----------- .../interpolation/method/FiniteElement.cc | 14 +---------- .../method/KNearestNeighboursBase.cc | 13 ----------- src/atlas/interpolation/method/PointIndex3.cc | 16 ------------- src/atlas/interpolation/method/PointSet.cc | 10 -------- src/atlas/interpolation/method/PointSet.h | 20 +--------------- src/atlas/library/Library.cc | 23 +++---------------- src/atlas/mesh/actions/BuildHalo.cc | 2 +- src/tests/array/CMakeLists.txt | 3 +-- src/tests/functionspace/CMakeLists.txt | 6 ----- src/tests/grid/CMakeLists.txt | 4 ---- src/tests/interpolation/CMakeLists.txt | 4 ---- src/tests/io/CMakeLists.txt | 4 ---- src/tests/mesh/CMakeLists.txt | 4 ---- src/tests/numerics/CMakeLists.txt | 4 ---- src/tests/parallel/CMakeLists.txt | 6 +---- src/tests/trans/CMakeLists.txt | 5 ---- src/tests/util/CMakeLists.txt | 5 ---- 22 files changed, 21 insertions(+), 189 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a20167f0..6584615d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,15 +31,9 @@ ecbuild_declare_project() ### eckit -ecbuild_use_package( PROJECT eckit VERSION 0.17 REQUIRED ) +ecbuild_use_package( PROJECT eckit VERSION 0.18 REQUIRED ) ecbuild_debug( " ECKIT_FEATURES : [${ECKIT_FEATURES}]" ) -set( ECKIT_HAVE_TESTING ON ) -if( ECKIT_VERSION VERSION_LESS 0.18 ) - set( ECKIT_HAVE_TESTING OFF ) - ecbuild_warn("Atlas C++ unit tests are disabled because (eckit version < 0.18)") -endif() - # options & dependencies ecbuild_add_cxx11_flags() diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index eef61f9f4..c12e6dd12 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -507,11 +507,6 @@ if( NOT ATLAS_HAVE_TRANS ) unset( TRANSI_LIBRARIES ) endif() -if( ECKIT_HAVE_MPI AND ATLAS_HAVE_MPI AND EC_OS_NAME MATCHES "macosx" ) - list( APPEND ATLAS_DEFINITIONS BUG_ECKIT_166 ) - link_libraries(${MPI_CXX_LIBRARIES}) -endif() - if( SHORTCUT_COMPILATION ) unset( atlas_grid_srcs ) unset( atlas_mesh_srcs ) diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc index 8f8bbc6bf..2ea0e07d2 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc @@ -14,6 +14,7 @@ #include #include "eckit/geometry/Point2.h" #include "eckit/mpi/Comm.h" +#include "eckit/log/ProgressTimer.h" #include "atlas/array/ArrayView.h" #include "atlas/field/Field.h" #include "atlas/grid/Grid.h" @@ -23,17 +24,6 @@ #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/eckit_version.h" -#undef ECKIT_VERSION_INT -#define ECKIT_VERSION_INT (ECKIT_MAJOR_VERSION * 10000 \ - + ECKIT_MINOR_VERSION * 100 ) -#if ECKIT_VERSION_INT > 1700 -#include "eckit/log/ProgressTimer.h" -#define IF_ECKIT_VERSION_SUPPORTS_IT( args ) args -#else -#define IF_ECKIT_VERSION_SUPPORTS_IT( args ) -#endif - namespace atlas { namespace grid { namespace detail { @@ -120,9 +110,9 @@ void MatchingMeshPartitionerBruteForce::partition(const Grid& grid, int partitio } { - IF_ECKIT_VERSION_SUPPORTS_IT( eckit::ProgressTimer timer("Partitioning target", grid.size(), "point", double(10), atlas::Log::info()); ) - for (size_t i=0; i #include "eckit/config/Resource.h" +#include "eckit/log/ProgressTimer.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/detail/PolygonCoordinates.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" - -#include "eckit/eckit_version.h" -#undef ECKIT_VERSION_INT -#define ECKIT_VERSION_INT (ECKIT_MAJOR_VERSION * 10000 \ - + ECKIT_MINOR_VERSION * 100 ) -#if ECKIT_VERSION_INT > 1700 -#include "eckit/log/ProgressTimer.h" -#define IF_ECKIT_VERSION_SUPPORTS_IT( args ) args -#else -#define IF_ECKIT_VERSION_SUPPORTS_IT( args ) -#endif - namespace atlas { namespace grid { namespace detail { @@ -62,11 +51,12 @@ void MatchingMeshPartitionerLonLatPolygon::partition( const Grid& grid, int part includesSouthPole ); { - IF_ECKIT_VERSION_SUPPORTS_IT( eckit::ProgressTimer timer("Partitioning", grid.size(), "point", double(10), atlas::Log::info()); ) + eckit::ProgressTimer timer("Partitioning", grid.size(), "point", + double(10), atlas::Log::info()); size_t i = 0; for (const PointXY Pxy : grid.xy()) { - IF_ECKIT_VERSION_SUPPORTS_IT( ++timer; ) + ++timer; const PointLonLat P = grid.projection().lonlat(Pxy); partitioning[i++] = poly.containsPointInLonLatGeometry(P) ? mpi_rank : -1; } diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc index dfee3d56a..d95838f34 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc @@ -12,24 +12,13 @@ #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h" #include -#include "eckit/config/Resource.h" +#include "eckit/log/ProgressTimer.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/detail/PolygonCoordinates.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" -#include "eckit/eckit_version.h" -#undef ECKIT_VERSION_INT -#define ECKIT_VERSION_INT (ECKIT_MAJOR_VERSION * 10000 \ - + ECKIT_MINOR_VERSION * 100 ) -#if ECKIT_VERSION_INT > 1700 -#include "eckit/log/ProgressTimer.h" -#define IF_ECKIT_VERSION_SUPPORTS_IT( args ) args -#else -#define IF_ECKIT_VERSION_SUPPORTS_IT( args ) -#endif - namespace atlas { namespace grid { namespace detail { @@ -61,11 +50,12 @@ void MatchingMeshPartitionerSphericalPolygon::partition( const Grid& grid, int p includesSouthPole ); { - IF_ECKIT_VERSION_SUPPORTS_IT( eckit::ProgressTimer timer("Partitioning", grid.size(), "point", double(10), atlas::Log::info()); ) + eckit::ProgressTimer timer("Partitioning", grid.size(), "point", + double(10), atlas::Log::info()); size_t i = 0; for (const PointXY Pxy : grid.xy()) { - IF_ECKIT_VERSION_SUPPORTS_IT( ++timer; ) + ++timer; const PointLonLat P = grid.projection().lonlat(Pxy); partitioning[i++] = poly.containsPointInSphericalGeometry(P) ? mpi_rank : -1; } diff --git a/src/atlas/interpolation/method/FiniteElement.cc b/src/atlas/interpolation/method/FiniteElement.cc index 5872add5a..b93c70fef 100644 --- a/src/atlas/interpolation/method/FiniteElement.cc +++ b/src/atlas/interpolation/method/FiniteElement.cc @@ -14,6 +14,7 @@ #include "eckit/log/Plural.h" #include "eckit/log/Seconds.h" +#include "eckit/log/ProgressTimer.h" #include "eckit/mpi/Comm.h" #include "eckit/geometry/Point3.h" @@ -32,15 +33,6 @@ #include "atlas/util/Earth.h" #include "atlas/util/Point.h" - -#include "eckit/eckit_version.h" -#undef ECKIT_VERSION_INT -#define ECKIT_VERSION_INT (ECKIT_MAJOR_VERSION * 10000 \ - + ECKIT_MINOR_VERSION * 100 ) -#if ECKIT_VERSION_INT > 1700 -#include "eckit/log/ProgressTimer.h" -#endif - namespace atlas { namespace interpolation { namespace method { @@ -135,12 +127,8 @@ void FiniteElement::setup(const FunctionSpace& source) { std::vector failures; { -#if ECKIT_VERSION_INT > 1700 eckit::ProgressTimer progress("Computing interpolation weights", out_npts, "point", double(5), Log::debug()); for ( size_t ip = 0; ip < out_npts; ++ip, ++progress ) { -#else - for ( size_t ip = 0; ip < out_npts; ++ip ) { -#endif if (out_ghosts(ip)) { continue; } diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.cc b/src/atlas/interpolation/method/KNearestNeighboursBase.cc index 570e2b90d..e957bcccc 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.cc +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.cc @@ -12,19 +12,12 @@ #include "atlas/interpolation/method/KNearestNeighboursBase.h" #include "eckit/config/Resource.h" -#include "eckit/eckit_version.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/mesh/Nodes.h" #include "atlas/library/Library.h" #include "atlas/runtime/Trace.h" -#ifdef ECKIT_VERSION_INT -#undef ECKIT_VERSION_INT -#endif -#define ECKIT_VERSION_INT (ECKIT_MAJOR_VERSION * 10000 \ - + ECKIT_MINOR_VERSION * 100 ) - namespace atlas { namespace interpolation { namespace method { @@ -44,10 +37,6 @@ void KNearestNeighboursBase::buildPointSearchTree(Mesh& meshSource) { static bool fastBuildKDTrees = eckit::Resource("$ATLAS_FAST_BUILD_KDTREES", true); -# if ECKIT_VERSION_INT <= 1700 - fastBuildKDTrees = true; -# endif - if (fastBuildKDTrees) { std::vector pidx; pidx.reserve(meshSource.nodes().size()); @@ -57,14 +46,12 @@ void KNearestNeighboursBase::buildPointSearchTree(Mesh& meshSource) { } pTree_->build(pidx.begin(), pidx.end()); } -# if ECKIT_VERSION_INT > 1700 else { for (size_t ip = 0; ip < meshSource.nodes().size(); ++ip) { PointIndex3::Point p(coords[ip].data()); pTree_->insert(PointIndex3::Value(p, ip)); } } -# endif } diff --git a/src/atlas/interpolation/method/PointIndex3.cc b/src/atlas/interpolation/method/PointIndex3.cc index 57e36572d..8eda68ac4 100644 --- a/src/atlas/interpolation/method/PointIndex3.cc +++ b/src/atlas/interpolation/method/PointIndex3.cc @@ -15,13 +15,6 @@ #include "atlas/array/MakeView.h" #include "atlas/mesh/HybridElements.h" #include "eckit/config/Resource.h" -#include "eckit/eckit_version.h" - -#ifdef ECKIT_VERSION_INT -#undef ECKIT_VERSION_INT -#endif -#define ECKIT_VERSION_INT (ECKIT_MAJOR_VERSION * 10000 \ - + ECKIT_MINOR_VERSION * 100 ) namespace atlas { namespace interpolation { @@ -33,11 +26,6 @@ ElemIndex3* create_element_kdtree(const Field& field_centres) { static bool fastBuildKDTrees = eckit::Resource("$ATLAS_FAST_BUILD_KDTREES", true); - // If eckit version <= 0.17 -# if ECKIT_VERSION_INT <= 1700 - fastBuildKDTrees = true; -# endif - ElemIndex3* tree = new ElemIndex3(); const size_t nb_cells = centres.shape(0); @@ -53,9 +41,6 @@ ElemIndex3* create_element_kdtree(const Field& field_centres) { tree->build(p.begin(), p.end()); } - - // If eckit version > 0.17 -# if ECKIT_VERSION_INT > 1700 else { for (size_t j = 0; j < nb_cells; ++j) { tree->insert(ElemIndex3::Value( @@ -63,7 +48,6 @@ ElemIndex3* create_element_kdtree(const Field& field_centres) { ElemIndex3::Payload(j) )); } } -# endif return tree; } diff --git a/src/atlas/interpolation/method/PointSet.cc b/src/atlas/interpolation/method/PointSet.cc index a1253b6cc..c0ec1032b 100644 --- a/src/atlas/interpolation/method/PointSet.cc +++ b/src/atlas/interpolation/method/PointSet.cc @@ -18,10 +18,6 @@ #include "atlas/field/Field.h" #include "eckit/config/Resource.h" -#ifndef ECKIT_VERSION_INT -#error ECKIT_VERSION_INT not defined -#endif - using namespace eckit; namespace atlas { @@ -50,10 +46,6 @@ PointSet::PointSet( Mesh& mesh ) tree_ = new PointIndex3(); -# if ECKIT_VERSION_INT <= 1700 - fastBuildKDTrees = true; -# endif - if (fastBuildKDTrees) { std::vector< PointIndex3::Value > pidx; pidx.reserve(npts_); @@ -64,12 +56,10 @@ PointSet::PointSet( Mesh& mesh ) tree_->build(pidx.begin(), pidx.end()); } -# if ECKIT_VERSION_INT > 1700 else { for ( size_t ip = 0; ip < npts_; ++ip ) tree_->insert( PointIndex3::Value( PointIndex3::Point( coords(ip, 0), coords(ip, 1), coords(ip, 2) ) , ip ) ); } -# endif } size_t PointSet::search_unique( const Point& p, size_t idx, uint32_t n ) diff --git a/src/atlas/interpolation/method/PointSet.h b/src/atlas/interpolation/method/PointSet.h index 201086bf4..3122caa9a 100644 --- a/src/atlas/interpolation/method/PointSet.h +++ b/src/atlas/interpolation/method/PointSet.h @@ -8,8 +8,7 @@ * does it submit to any jurisdiction. */ -#ifndef atlas_interpolation_method_PointSet_h -#define atlas_interpolation_method_PointSet_h +#pragma once #include #include @@ -26,14 +25,6 @@ #include "atlas/runtime/Trace.h" #include "atlas/mesh/Mesh.h" -#include "eckit/eckit_version.h" - -#ifdef ECKIT_VERSION_INT -#undef ECKIT_VERSION_INT -#endif -#define ECKIT_VERSION_INT (ECKIT_MAJOR_VERSION * 10000 \ - + ECKIT_MINOR_VERSION * 100 ) - namespace atlas { namespace interpolation { namespace method { @@ -111,10 +102,6 @@ class PointSet { static bool fastBuildKDTrees = eckit::Resource("$ATLAS_FAST_BUILD_KDTREES", true); tree_ = new PointIndex3(); -# if ECKIT_VERSION_INT <= 1700 - fastBuildKDTrees = true; -# endif - if(fastBuildKDTrees){ std::vector< PointIndex3::Value > pidx; pidx.reserve(npts_); @@ -125,13 +112,11 @@ class PointSet { tree_->build(pidx.begin(), pidx.end()); } -# if ECKIT_VERSION_INT > 1700 else { for( size_t ip = 0; ip < npts_; ++ip ) { tree_->insert(PointIndex3::Value( PointIndex3::Point( ipts[ip] ), ip ) ); } } -# endif } size_t search_unique( const Point& p, size_t idx, uint32_t n ); @@ -162,6 +147,3 @@ class PointSet { } // namespace method } // namespace interpolation } // namespace atlas - -#endif - diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 3f6f3b6a5..b4da407b5 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -12,11 +12,6 @@ #include "atlas/library/config.h" -// Temporary until ECKIT-166 is fixed -#ifdef BUG_ECKIT_166 -#include -#endif - #ifdef ATLAS_HAVE_TRANS #include "transi/version.h" #endif @@ -143,20 +138,8 @@ void Library::initialise() { } void Library::finalise() { -// Temporary until ECKIT-166 is fixed -#ifdef BUG_ECKIT_166 - const bool using_mpi = (::getenv("OMPI_COMM_WORLD_SIZE") || ::getenv("ALPS_APP_PE")); - if( using_mpi ) { - int finalized = 1; - MPI_Finalized(&finalized); - if( not finalized ) { - MPI_Finalize(); - } - } -#endif - - // Make sure that these specialised channels that wrap Log::info() are - // destroyed before Log::info gets destroyed. + // Make sure that these specialised channels that wrap Log::info() are + // destroyed before eckit::Log::info gets destroyed. // Just in case someone still tries to log, we reset to empty channels. trace_channel_.reset( new eckit::Channel() ); @@ -169,7 +152,7 @@ std::ostream& Library::traceChannel() const { 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())))); + new eckit::PrefixTarget("ATLAS_TRACE", new eckit::OStreamTarget(eckit::Log::info())))); } else { trace_channel_.reset( new eckit::Channel() ); } diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 310e6b69f..06ce6c410 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -44,7 +44,7 @@ #include "atlas/mesh/actions/BuildXYZField.h" #endif -// #define ATLAS_103 +#define ATLAS_103 // #define ATLAS_103_SORT #ifndef ATLAS_103 diff --git a/src/tests/array/CMakeLists.txt b/src/tests/array/CMakeLists.txt index fbee273de..2ac6336cc 100644 --- a/src/tests/array/CMakeLists.txt +++ b/src/tests/array/CMakeLists.txt @@ -6,12 +6,11 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -if( ECKIT_HAVE_TESTING ) ecbuild_add_test( TARGET atlas_test_array SOURCES test_array.cc LIBS atlas ) -endif() + #ecbuild_add_test( TARGET atlas_test_table # SOURCES test_table.cc # LIBS atlas diff --git a/src/tests/functionspace/CMakeLists.txt b/src/tests/functionspace/CMakeLists.txt index 9c2eb3e41..c135aa5a9 100644 --- a/src/tests/functionspace/CMakeLists.txt +++ b/src/tests/functionspace/CMakeLists.txt @@ -18,14 +18,11 @@ if( HAVE_FCTEST ) endif() -if( ECKIT_HAVE_TESTING ) - ecbuild_add_test( TARGET atlas_test_functionspace SOURCES test_functionspace.cc LIBS atlas ) - ecbuild_add_test( TARGET atlas_test_structuredcolumns SOURCES test_structuredcolumns.cc LIBS atlas @@ -37,6 +34,3 @@ ecbuild_add_test( TARGET atlas_test_pointcloud SOURCES test_pointcloud.cc LIBS atlas ) - -endif() - diff --git a/src/tests/grid/CMakeLists.txt b/src/tests/grid/CMakeLists.txt index fb3e12ef5..a88466698 100644 --- a/src/tests/grid/CMakeLists.txt +++ b/src/tests/grid/CMakeLists.txt @@ -9,8 +9,6 @@ if( HAVE_FCTEST ) endforeach() endif() -if( ECKIT_HAVE_TESTING ) - foreach(test test_domain test_field @@ -22,5 +20,3 @@ foreach(test ecbuild_add_test( TARGET atlas_${test} SOURCES ${test}.cc LIBS atlas ) endforeach() - -endif() diff --git a/src/tests/interpolation/CMakeLists.txt b/src/tests/interpolation/CMakeLists.txt index 530e50870..d31d3b784 100644 --- a/src/tests/interpolation/CMakeLists.txt +++ b/src/tests/interpolation/CMakeLists.txt @@ -6,8 +6,6 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -if( ECKIT_HAVE_TESTING ) - ecbuild_add_test( TARGET atlas_test_Quad3D CONDITION ECKIT_HAVE_EIGEN SOURCES test_Quad3D.cc @@ -18,5 +16,3 @@ ecbuild_add_test( TARGET atlas_test_interpolation_finite_element SOURCES test_interpolation_finite_element.cc LIBS atlas ) - -endif() diff --git a/src/tests/io/CMakeLists.txt b/src/tests/io/CMakeLists.txt index 96fa24d8b..e6f5148fd 100644 --- a/src/tests/io/CMakeLists.txt +++ b/src/tests/io/CMakeLists.txt @@ -6,8 +6,6 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -if( ECKIT_HAVE_TESTING ) - ecbuild_add_test( TARGET atlas_test_gmsh SOURCES test_gmsh.cc ../TestMeshes.h LIBS atlas @@ -18,8 +16,6 @@ ecbuild_add_test( TARGET atlas_test_pointcloud_io LIBS atlas ) -endif() - if( HAVE_FCTEST ) add_fctest( TARGET atlas_fctest_gmsh diff --git a/src/tests/mesh/CMakeLists.txt b/src/tests/mesh/CMakeLists.txt index 9618eb502..d684e5443 100644 --- a/src/tests/mesh/CMakeLists.txt +++ b/src/tests/mesh/CMakeLists.txt @@ -36,8 +36,6 @@ if( HAVE_FCTEST ) endif() -if( ECKIT_HAVE_TESTING ) - ecbuild_add_test( TARGET atlas_test_parfields MPI 2 CONDITION ECKIT_HAVE_MPI AND TRANSI_HAVE_MPI @@ -73,8 +71,6 @@ foreach( test accumulate_facets connectivity elements ll meshgen3d polygon rgg ) ) endforeach() -endif() - atlas_add_cuda_test( TARGET atlas_test_connectivity_kernel BOOST diff --git a/src/tests/numerics/CMakeLists.txt b/src/tests/numerics/CMakeLists.txt index 7f446b513..b1fbd2911 100644 --- a/src/tests/numerics/CMakeLists.txt +++ b/src/tests/numerics/CMakeLists.txt @@ -6,15 +6,11 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -if( ECKIT_HAVE_TESTING ) - ecbuild_add_test( TARGET atlas_test_fvm_nabla SOURCES test_fvm_nabla.cc LIBS atlas ) -endif() - if( HAVE_FCTEST) add_fctest( TARGET atlas_fctest_fvm_nabla LINKER_LANGUAGE Fortran diff --git a/src/tests/parallel/CMakeLists.txt b/src/tests/parallel/CMakeLists.txt index bd2c0933e..b8e4bf33d 100644 --- a/src/tests/parallel/CMakeLists.txt +++ b/src/tests/parallel/CMakeLists.txt @@ -6,9 +6,7 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -if( ECKIT_HAVE_TESTING ) - - ecbuild_add_test( TARGET atlas_test_haloexchange +ecbuild_add_test( TARGET atlas_test_haloexchange MPI 3 CONDITION ECKIT_HAVE_MPI SOURCES test_haloexchange.cc @@ -21,5 +19,3 @@ ecbuild_add_test( TARGET atlas_test_gather SOURCES test_gather.cc LIBS atlas ) - -endif() diff --git a/src/tests/trans/CMakeLists.txt b/src/tests/trans/CMakeLists.txt index c667d51a5..a969a18f4 100644 --- a/src/tests/trans/CMakeLists.txt +++ b/src/tests/trans/CMakeLists.txt @@ -26,8 +26,6 @@ if( HAVE_FCTEST ) endif() -if( ECKIT_HAVE_TESTING ) - ecbuild_add_test( TARGET atlas_test_trans MPI 4 SOURCES test_trans.cc @@ -46,6 +44,3 @@ ecbuild_add_test( TARGET atlas_test_trans_invtrans_grad CONDITION ATLAS_HAVE_TRANS LIBS atlas ) - -endif() - diff --git a/src/tests/util/CMakeLists.txt b/src/tests/util/CMakeLists.txt index 0fb552c04..c98e0f84e 100644 --- a/src/tests/util/CMakeLists.txt +++ b/src/tests/util/CMakeLists.txt @@ -36,8 +36,6 @@ if( HAVE_FCTEST ) endif() -if( ECKIT_HAVE_TESTING ) - ecbuild_add_test( TARGET atlas_test_flags SOURCES test_flags.cc LIBS atlas @@ -70,6 +68,3 @@ ecbuild_add_test( TARGET atlas_test_earth SOURCES test_earth.cc LIBS atlas ) - -endif() - From 01b3e534b402a7d4e73fc80d3123ad6e325e6ada Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 13 Oct 2017 17:35:13 +0000 Subject: [PATCH 034/355] ATLAS-103 Add some timers --- src/atlas/mesh/actions/BuildHalo.cc | 76 +++++++++++-------- src/atlas/mesh/actions/BuildParallelFields.cc | 42 +++++----- .../atlas-benchmark-build-halo.cc | 1 + src/tests/mesh/test_parfields.cc | 3 +- src/tests/trans/test_trans_invtrans_grad.cc | 3 +- 5 files changed, 69 insertions(+), 56 deletions(-) diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 06ce6c410..63c1fcfca 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -44,7 +44,7 @@ #include "atlas/mesh/actions/BuildXYZField.h" #endif -#define ATLAS_103 +// #define ATLAS_103 // #define ATLAS_103_SORT #ifndef ATLAS_103 @@ -388,20 +388,21 @@ class BuildHaloHelper static void all_to_all(Buffers& send, Buffers& recv) { - - ATLAS_TRACE( "all_to_all" ); + ATLAS_TRACE(); const eckit::mpi::Comm& comm = parallel::mpi::comm(); - comm.allToAll(send.node_glb_idx, recv.node_glb_idx); - comm.allToAll(send.node_part, recv.node_part); - comm.allToAll(send.node_ridx, recv.node_ridx); - comm.allToAll(send.node_flags, recv.node_flags); - comm.allToAll(send.node_xy, recv.node_xy); - comm.allToAll(send.elem_glb_idx, recv.elem_glb_idx); - comm.allToAll(send.elem_nodes_id, recv.elem_nodes_id); - comm.allToAll(send.elem_part, recv.elem_part); - comm.allToAll(send.elem_type, recv.elem_type); - comm.allToAll(send.elem_nodes_displs, recv.elem_nodes_displs); + ATLAS_TRACE_MPI( ALLTOALL ) { + comm.allToAll(send.node_glb_idx, recv.node_glb_idx); + comm.allToAll(send.node_part, recv.node_part); + comm.allToAll(send.node_ridx, recv.node_ridx); + comm.allToAll(send.node_flags, recv.node_flags); + comm.allToAll(send.node_xy, recv.node_xy); + comm.allToAll(send.elem_glb_idx, recv.elem_glb_idx); + comm.allToAll(send.elem_nodes_id, recv.elem_nodes_id); + comm.allToAll(send.elem_part, recv.elem_part); + comm.allToAll(send.elem_type, recv.elem_type); + comm.allToAll(send.elem_nodes_displs, recv.elem_nodes_displs); + } } struct Status { @@ -471,6 +472,8 @@ class BuildHaloHelper template< typename NodeContainer, typename ElementContainer > void fill_sendbuffer(Buffers& buf,const NodeContainer& nodes_uid, const ElementContainer& elems, const int p) { + ATLAS_TRACE(); + int nb_nodes = nodes_uid.size(); buf.node_glb_idx[p].resize(nb_nodes); buf.node_part [p].resize(nb_nodes); @@ -817,12 +820,13 @@ class BuildHaloHelper namespace { void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, bool periodic = false ) { + auto& comm = parallel::mpi::comm(); #ifndef ATLAS_103 /* deprecated */ ATLAS_TRACE( "gather_bdry_nodes old way" ); { ATLAS_TRACE_MPI( ALLGATHER ) { - parallel::mpi::comm().allGatherv(send.begin(), send.end(), recv); + comm.allGatherv(send.begin(), send.end(), recv); } } #else @@ -830,11 +834,11 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); if( periodic ) { // add own rank to neighbours to allow periodicity with self (pole caps) - size_t rank = parallel::mpi::comm().rank(); + size_t rank = comm.rank(); neighbours.insert( std::upper_bound( neighbours.begin(), neighbours.end(), rank ), rank ); } - const size_t mpi_size = parallel::mpi::comm().size(); + const size_t mpi_size = comm.size(); const int counts_tag = 0; const int buffer_tag = 1; @@ -842,22 +846,30 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector std::vector buffer_requests; buffer_requests.reserve(neighbours.size()); int sendcnt = send.size(); - for( size_t to : neighbours ) { - parallel::mpi::comm().iSend( sendcnt, to, counts_tag ); + ATLAS_TRACE_MPI(ISEND) { + for( size_t to : neighbours ) { + count_requests.push_back( comm.iSend( sendcnt, to, counts_tag ) ); + } } recv.counts.assign(0,mpi_size); - for( size_t from : neighbours ) { - counts_requests.push_back( parallel::mpi::comm().iReceive( recv.counts[from], from, counts_tag ) ); + ATLAS_TRACE_MPI(IRECEIVE) { + for( size_t from : neighbours ) { + counts_requests.push_back( comm.iReceive( recv.counts[from], from, counts_tag ) ); + } } - for( size_t to : neighbours ) { - parallel::mpi::comm().iSend(send.data(),send.size(),to, buffer_tag ); + ATLAS_TRACE_MPI(ISEND) { + for( size_t to : neighbours ) { + buffer_requests.push_back( comm.iSend(send.data(),send.size(),to, buffer_tag ) ); + } } - for( auto request : counts_requests ) { - parallel::mpi::comm().wait( request ); + ATLAS_TRACE_MPI(WAIT) { + for( auto request : counts_requests ) { + comm.wait( request ); + } } recv.displs[0] = 0; @@ -868,14 +880,18 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector } recv.buffer.resize(recv.cnt); - for( size_t from : neighbours ) { - buffer_requests.push_back( - parallel::mpi::comm().iReceive( recv.buffer.data()+recv.displs[from], - recv.counts[from], from, buffer_tag) ); + ATLAS_TRACE_MPI( IRECEIVE ) { + for( size_t from : neighbours ) { + buffer_requests.push_back( + comm.iReceive( recv.buffer.data()+recv.displs[from], + recv.counts[from], from, buffer_tag) ); + } } - for( auto request : buffer_requests ) { - parallel::mpi::comm().wait( request ); + ATLAS_TRACE_MPI( WAIT ) { + for( auto request : buffer_requests ) { + comm.wait( request ); + } } #endif } diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 5b09a26d2..fa9fd6a68 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -78,8 +78,7 @@ struct Node } gidx_t g; gidx_t i; - bool operator < (const Node& other) const - { + bool operator < (const Node& other) const { return ( g loc_id_arr( nb_nodes ); array::ArrayView loc_id = array::make_view(loc_id_arr); - for( int jnode=0; jnode node_sort; node_sort.reserve(glb_nb_nodes); - for( size_t jnode=0; jnode recv_node( recv_found[ proc[jpart] ].data(), // array::make_shape(recv_found[ proc[jpart] ].size()/2,2) ); - for( size_t jnode=0; jnode Date: Fri, 13 Oct 2017 18:36:51 +0100 Subject: [PATCH 035/355] ATLAS-103 Avoid calling mpi::comm() too often --- src/atlas/mesh/actions/BuildHalo.cc | 67 ++++++++++++++++------------- 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 63c1fcfca..d8f739b99 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -265,6 +265,7 @@ void accumulate_elements( const Mesh& mesh, const array::ArrayView elem_part = array::make_view( mesh.cells().partition() ); size_t nb_nodes = node_uid.size(); + const size_t mpi_rank = parallel::mpi::comm().rank(); std::set< int > found_elements_set; @@ -284,7 +285,7 @@ void accumulate_elements( const Mesh& mesh, for(size_t jelem = 0; jelem < node2elem[inode].size(); ++jelem) { int e = node2elem[inode][jelem]; - if( size_t(elem_part(e)) == atlas::parallel::mpi::comm().rank() ) + if( size_t(elem_part(e)) == mpi_rank ) { found_elements_set.insert( e ); } @@ -343,24 +344,27 @@ class BuildHaloHelper Buffers(Mesh& mesh) { - node_part.resize(parallel::mpi::comm().size()); - node_ridx.resize(parallel::mpi::comm().size()); - node_flags.resize(parallel::mpi::comm().size()); - node_glb_idx.resize(parallel::mpi::comm().size()); - node_xy.resize(parallel::mpi::comm().size()); - elem_glb_idx.resize(parallel::mpi::comm().size()); - elem_nodes_id.resize(parallel::mpi::comm().size()); - elem_nodes_displs.resize(parallel::mpi::comm().size()); - elem_part.resize(parallel::mpi::comm().size()); - elem_type.resize(parallel::mpi::comm().size()); + const size_t mpi_size = parallel::mpi::comm().size(); + + node_part.resize(mpi_size); + node_ridx.resize(mpi_size); + node_flags.resize(mpi_size); + node_glb_idx.resize(mpi_size); + node_xy.resize(mpi_size); + elem_glb_idx.resize(mpi_size); + elem_nodes_id.resize(mpi_size); + elem_nodes_displs.resize(mpi_size); + elem_part.resize(mpi_size); + elem_type.resize(mpi_size); } void print( std::ostream& os ) const { + const size_t mpi_size = parallel::mpi::comm().size(); os << "Nodes\n" << "-----\n"; size_t n(0); - for( size_t jpart=0; jpart > rfn_idx(parallel::mpi::comm().size()); - for(size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) + std::vector< std::vector > rfn_idx(mpi_size); + for(size_t jpart = 0; jpart < mpi_size; ++jpart) { rfn_idx[jpart].reserve(buf.node_glb_idx[jpart].size()); } int nb_new_nodes=0; - for(size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) + for(size_t jpart = 0; jpart < mpi_size; ++jpart) { for(size_t n = 0; n < buf.node_glb_idx[jpart].size(); ++n) { @@ -674,7 +679,7 @@ class BuildHaloHelper // Add new nodes // ------------- int new_node=0; - for(size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) + for(size_t jpart = 0; jpart < mpi_size; ++jpart) { for(size_t n = 0; n < rfn_idx[jpart].size(); ++n) { @@ -719,6 +724,8 @@ class BuildHaloHelper { ATLAS_TRACE(); + const size_t mpi_size = parallel::mpi::comm().size(); + // Elements might be duplicated from different Tasks. We need to identify unique entries int nb_elems = mesh.cells().size(); // std::set elem_uid; @@ -742,14 +749,14 @@ class BuildHaloHelper } }; - std::vector< std::vector > received_new_elems(parallel::mpi::comm().size()); - for(size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) + std::vector< std::vector > received_new_elems( mpi_size ); + for(size_t jpart = 0; jpart < mpi_size; ++jpart) { received_new_elems[jpart].reserve(buf.elem_glb_idx[jpart].size()); } size_t nb_new_elems(0); - for(size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) + for(size_t jpart = 0; jpart < mpi_size; ++jpart) { for(size_t e = 0; e < buf.elem_glb_idx[jpart].size(); ++e) { @@ -762,10 +769,10 @@ class BuildHaloHelper std::vector< std::vector< std::vector > > elements_of_type( mesh.cells().nb_types(), - std::vector< std::vector >( parallel::mpi::comm().size() ) ); + std::vector< std::vector >( mpi_size ) ); std::vector nb_elements_of_type( mesh.cells().nb_types(), 0 ); - for(size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) + for(size_t jpart = 0; jpart < mpi_size ; ++jpart) { for(size_t jelem = 0; jelem < received_new_elems[jpart].size(); ++jelem) { @@ -791,7 +798,7 @@ class BuildHaloHelper // Copy information in new elements size_t new_elem(0); - for(size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) + for(size_t jpart = 0; jpart < mpi_size ; ++jpart) { for(size_t e = 0; e < elems[jpart].size(); ++e) { @@ -925,15 +932,15 @@ void increase_halo_interior( BuildHaloHelper& helper ) for(size_t jnode = 0; jnode < bdry_nodes.size(); ++jnode) send_bdry_nodes_uid[jnode] = helper.compute_uid(bdry_nodes[jnode]); - size_t size = parallel::mpi::comm().size(); - atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(size); + size_t mpi_size = parallel::mpi::comm().size(); + atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts ); #ifndef ATLAS_103 /* deprecated */ - for (size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) + for (size_t jpart = 0; jpart < mpi_size; ++jpart) #else const Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); for (size_t jpart : neighbours) @@ -1031,14 +1038,14 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri send_bdry_nodes_uid[jnode] = util::unique_lonlat(crd); } - size_t size = parallel::mpi::comm().size(); - atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(size); + size_t mpi_size = parallel::mpi::comm().size(); + atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts, /* periodic = */ true ); #ifndef ATLAS_103 /* deprecated */ - for (size_t jpart = 0; jpart < parallel::mpi::comm().size(); ++jpart) + for (size_t jpart = 0; jpart < mpi_size; ++jpart) #else Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); // add own rank to neighbours to allow periodicity with self (pole caps) From 109365dcfaa6a90daa4a077f2403c8e4e84d2e97 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 16 Oct 2017 10:22:34 +0100 Subject: [PATCH 036/355] atlas-benchmark uses equal_regions partitioner --- src/apps/atlas-benchmark.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 5fb5050bc..b29a234e9 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -297,7 +297,7 @@ void AtlasBenchmark::setup() StructuredGrid grid; ATLAS_TRACE_SCOPE( "Create grid" ) { grid = Grid(gridname); } - ATLAS_TRACE_SCOPE( "Create mesh" ) { mesh = MeshGenerator( "structured" ).generate(grid); } + ATLAS_TRACE_SCOPE( "Create mesh" ) { mesh = MeshGenerator( "structured", util::Config("partitioner","equal_regions") ).generate(grid); } ATLAS_TRACE_SCOPE( "Create node_fs") { nodes_fs = functionspace::NodeColumns(mesh,option::halo(halo)); } ATLAS_TRACE_SCOPE( "build_edges" ) { build_edges(mesh); } From 0154d27459dc9866cbb1d9007c05b07a9f734801 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 25 Oct 2017 10:48:54 +0100 Subject: [PATCH 037/355] Fix gridtools-storage backend (compatible with ESCAPE/gridtools-storage@escape/D1.3) --- src/atlas/array/ArrayLayout.h | 13 +++++---- src/atlas/array/ArrayShape.h | 22 +++++++++----- src/atlas/array/ArraySpec.cc | 4 +-- src/atlas/array/ArrayStrides.h | 16 +++++----- src/atlas/array/ArrayUtil.h | 1 + .../array/gridtools/GridToolsArrayHelpers.h | 29 +++++++++++++++++-- .../array/gridtools/GridToolsArrayView.h | 8 +++-- src/atlas/field/FieldCreatorArraySpec.cc | 2 +- src/atlas/field/detail/FieldImpl.cc | 16 +++++----- src/atlas/mesh/actions/BuildHalo.cc | 10 ++++--- .../meshgenerator/StructuredMeshGenerator.cc | 3 ++ 11 files changed, 85 insertions(+), 39 deletions(-) diff --git a/src/atlas/array/ArrayLayout.h b/src/atlas/array/ArrayLayout.h index c383373af..69662a11d 100644 --- a/src/atlas/array/ArrayLayout.h +++ b/src/atlas/array/ArrayLayout.h @@ -22,13 +22,16 @@ class ArrayLayout : public std::vector { private: using Base = std::vector; public: - using Base::Base; // inherit constructors from std::vector + ArrayLayout() {} + ArrayLayout( std::initializer_list list ) : Base(list) {} + ArrayLayout( Base&& base ) : Base( std::forward(base) ) {} }; -inline ArrayLayout make_layout(size_t size1) { return ArrayLayout(1,size1); } -inline ArrayLayout make_layout(size_t size1, size_t size2) { ArrayLayout v(2); v[0]=size1; v[1]=size2; return v; } -inline ArrayLayout make_layout(size_t size1, size_t size2, size_t size3) { ArrayLayout v(3); v[0]=size1; v[1]=size2; v[2]=size3; return v; } -inline ArrayLayout make_layout(size_t size1, size_t size2, size_t size3, size_t size4) { ArrayLayout v(4); v[0]=size1; v[1]=size2; v[2]=size3; v[3]=size4; return v; } +inline ArrayLayout make_layout(size_t size1) { return ArrayLayout{size1}; } +inline ArrayLayout make_layout(size_t size1, size_t size2) { return ArrayLayout{size1,size2}; } +inline ArrayLayout make_layout(size_t size1, size_t size2, size_t size3) { return ArrayLayout{size1,size2,size3}; } +inline ArrayLayout make_layout(size_t size1, size_t size2, size_t size3, size_t size4) { return ArrayLayout{size1,size2,size3,size4}; } +inline ArrayLayout make_layout(size_t size1, size_t size2, size_t size3, size_t size4, size_t size5) { return ArrayLayout{size1,size2,size3,size4,size5}; } //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/array/ArrayShape.h b/src/atlas/array/ArrayShape.h index c33408202..e181a77bf 100644 --- a/src/atlas/array/ArrayShape.h +++ b/src/atlas/array/ArrayShape.h @@ -18,14 +18,20 @@ namespace atlas { namespace array { -typedef std::vector ArrayShape; - -inline ArrayShape make_shape() { return std::vector(); } -inline ArrayShape make_shape(size_t size1) { return std::vector(1,size1); } -inline ArrayShape make_shape(size_t size1, size_t size2) { std::vector v(2); v[0]=size1; v[1]=size2; return v; } -inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3) { std::vector v(3); v[0]=size1; v[1]=size2; v[2]=size3; return v; } -inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3, size_t size4) { std::vector v(4); v[0]=size1; v[1]=size2; v[2]=size3; v[3]=size4; return v; } -inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3, size_t size4, size_t size5) { std::vector v(4); v[0]=size1; v[1]=size2; v[2]=size3; v[3]=size4; v[4]=size5; return v; } +class ArrayShape : public std::vector { +private: + using Base = std::vector; +public: + ArrayShape() {} + ArrayShape( Base&& base ) : Base( std::forward(base) ) {} + ArrayShape( std::initializer_list list ) : Base(list) {} +}; + +inline ArrayShape make_shape(size_t size1) { return ArrayShape{size1}; } +inline ArrayShape make_shape(size_t size1, size_t size2) { return ArrayShape{size1,size2}; } +inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3) { return ArrayShape{size1,size2,size3}; } +inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3, size_t size4) { return ArrayShape{size1,size2,size3,size4}; } +inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3, size_t size4, size_t size5) { return ArrayShape{size1,size2,size3,size4,size5}; } //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/array/ArraySpec.cc b/src/atlas/array/ArraySpec.cc index fa0cd0cbe..ef30e2b60 100644 --- a/src/atlas/array/ArraySpec.cc +++ b/src/atlas/array/ArraySpec.cc @@ -16,8 +16,8 @@ namespace atlas { namespace array { ArraySpec::ArraySpec(): - size_(0), - rank_(0), + size_(), + rank_(), contiguous_(true), default_layout_(true) { diff --git a/src/atlas/array/ArrayStrides.h b/src/atlas/array/ArrayStrides.h index bc9df9033..cadf42d07 100644 --- a/src/atlas/array/ArrayStrides.h +++ b/src/atlas/array/ArrayStrides.h @@ -12,6 +12,7 @@ #include #include +#include //------------------------------------------------------------------------------------------------------ @@ -22,15 +23,16 @@ class ArrayStrides : public std::vector { private: using Base = std::vector; public: - using Base::Base; // inherit constructors from std::vector + ArrayStrides() {} + ArrayStrides( std::initializer_list list) : Base(list) {} + ArrayStrides( Base&& base ) : Base( std::forward(base) ) {} }; -// typedef std::vector ArrayStrides; - -inline ArrayStrides make_strides(size_t size1) { return ArrayStrides(1,size1); } -inline ArrayStrides make_strides(size_t size1, size_t size2) { ArrayStrides v(2); v[0]=size1; v[1]=size2; return v; } -inline ArrayStrides make_strides(size_t size1, size_t size2, size_t size3) { ArrayStrides v(3); v[0]=size1; v[1]=size2; v[2]=size3; return v; } -inline ArrayStrides make_strides(size_t size1, size_t size2, size_t size3, size_t size4) { ArrayStrides v(4); v[0]=size1; v[1]=size2; v[2]=size3; v[3]=size4; return v; } +inline ArrayStrides make_strides(size_t size1) { return ArrayStrides{size1}; } +inline ArrayStrides make_strides(size_t size1, size_t size2) { return ArrayStrides{size1,size2}; } +inline ArrayStrides make_strides(size_t size1, size_t size2, size_t size3) { return ArrayStrides{size1,size2,size3}; } +inline ArrayStrides make_strides(size_t size1, size_t size2, size_t size3, size_t size4) { return ArrayStrides{size1,size2,size3,size4}; } +inline ArrayStrides make_strides(size_t size1, size_t size2, size_t size3, size_t size4, size_t size5) { return ArrayStrides{size1,size2,size3,size4,size5}; } //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/array/ArrayUtil.h b/src/atlas/array/ArrayUtil.h index c8fed843a..cdeed7bd1 100644 --- a/src/atlas/array/ArrayUtil.h +++ b/src/atlas/array/ArrayUtil.h @@ -10,6 +10,7 @@ #pragma once +#include #include "atlas/array/ArrayShape.h" #include "atlas/array/ArrayStrides.h" #include "atlas/array/ArrayLayout.h" diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index 63602cc66..5d8b1173d 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -197,6 +197,32 @@ struct default_layout_t { } + template < typename UInt > + struct my_apply_gt_integer_sequence { + template < typename Container, template < UInt T > class Lambda, typename... ExtraTypes > + ATLAS_HOST_DEVICE static constexpr Container apply(ExtraTypes const &... args_) { + static_assert((boost::is_same< Container, Container >::value), + "ERROR: apply_gt_integer_sequence only accepts a gt_integer_sequence type. Check the call"); + return Container(args_...); + } + }; + + template < typename UInt, UInt... Indices > + struct my_apply_gt_integer_sequence< ::gridtools::gt_integer_sequence< UInt, Indices... > > { + + /** + @brief duplicated interface for the case in which the container is an aggregator + */ + template < typename Container, + template < UInt T > class Lambda, + typename... ExtraTypes > + ATLAS_HOST_DEVICE static constexpr Container apply(ExtraTypes const &... args_) { + return Container{Lambda< Indices >::apply(args_...)...}; + } + }; + + + template ArraySpec make_spec(DataStore* gt_data_store_ptr, Dims...dims) { static_assert((::gridtools::is_data_store::value), "Internal Error: passing a non GT data store"); @@ -204,8 +230,7 @@ struct default_layout_t { auto storage_info_ptr = gt_data_store_ptr->get_storage_info_ptr(); using Layout = typename DataStore::storage_info_t::Layout; - using seq = - ::gridtools::apply_gt_integer_sequence::type>; + using seq = my_apply_gt_integer_sequence::type>; return ArraySpec( ArrayShape{(unsigned long)dims...}, diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index b5c94e1ea..d34118bed 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -63,12 +63,16 @@ template< typename Value, int Rank > class ArrayView { } const Slice at(size_t i) const { - if( i>= shape(0) ) throw eckit::OutOfRange(i,shape(0),Here()); + if( i>= shape(0) ) { + throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); + } return Slicer(*this).apply(i); } Slice at(size_t i) { - if( i>= shape(0) ) throw eckit::OutOfRange(i,shape(0),Here()); + if( i>= shape(0) ) { + throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); + } return Slicer(*this).apply(i); } diff --git a/src/atlas/field/FieldCreatorArraySpec.cc b/src/atlas/field/FieldCreatorArraySpec.cc index 9881c275c..ac920959f 100644 --- a/src/atlas/field/FieldCreatorArraySpec.cc +++ b/src/atlas/field/FieldCreatorArraySpec.cc @@ -54,7 +54,7 @@ FieldImpl* FieldCreatorArraySpec::createField( const eckit::Parametrisation& par std::string name; params.get("name",name); - return FieldImpl::create(name,datatype,s); + return FieldImpl::create( name,datatype,array::ArrayShape( std::move(s) ) ); } namespace { diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index 9d02eb9f3..6274208cb 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -172,8 +172,8 @@ extern "C" FieldImpl* atlas__Field__wrap_int_specf(const char* name, int data[], int rank, int shapef[], int stridesf[]) { ATLAS_ERROR_HANDLING( - array::ArrayShape shape(rank); - array::ArrayStrides strides(rank); + array::ArrayShape shape; shape.resize(rank); + array::ArrayStrides strides; strides.resize(rank); size_t jf = rank-1; for( int j=0; j patched = array::make_view( mesh.cells().field("patch") ); + auto patched = array::make_view( mesh.cells().field("patch") ); size_t nb_elems = mesh.cells().size(); for (size_t elem=0; elem elem_type_glb_idx = elements.view( mesh.cells().global_index() ); - array::LocalView elem_type_part = elements.view( mesh.cells().partition() ); - array::LocalView elem_type_halo = elements.view( mesh.cells().halo() ); + auto elem_type_glb_idx = elements.view( mesh.cells().global_index() ); + auto elem_type_part = elements.view( mesh.cells().partition() ); + auto elem_type_halo = elements.view( mesh.cells().halo() ); + auto elem_type_patch = elements.view( mesh.cells().field("patch") ); // Copy information in new elements size_t new_elem(0); @@ -806,6 +807,7 @@ class BuildHaloHelper elem_type_glb_idx(new_elems_pos+new_elem) = buf.elem_glb_idx[jpart][jelem]; elem_type_part (new_elems_pos+new_elem) = buf.elem_part[jpart][jelem]; elem_type_halo (new_elems_pos+new_elem) = halo+1; + elem_type_patch (new_elems_pos+new_elem) = 0; for( size_t n=0; n Date: Fri, 12 May 2017 00:41:56 +0200 Subject: [PATCH 038/355] fix the cuda library generation --- CMakeLists.txt | 3 ++- src/atlas/CMakeLists.txt | 30 ++++++++++++++++++++---------- src/atlas/array/Vector.h | 1 + src/atlas/mesh/Nodes.h | 2 ++ 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6584615d0..96d3d7212 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,6 +127,7 @@ ecbuild_add_option( if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11") set( ENABLE_GPU "OFF" CACHE BOOL "Compile with GPU support (CUDA)" ) set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST 1 ) @@ -141,7 +142,7 @@ if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) add_definitions(-D_FORCE_INLINES) # Question to Carlos: Is this needed for nvcc only? set(CUDA_PROPAGATE_HOST_FLAGS ON) - set(CUDA_NVCC_FLAGS "--std=c++11" "--relaxed-constexpr" "${CUDA_NVCC_FLAGS}") + set(CUDA_NVCC_FLAGS "--relaxed-constexpr" "${CUDA_NVCC_FLAGS}") if( NOT ${CUDA_VERSION} VERSION_GREATER "60") message(FATAL_ERROR "CUDA 6.0 or lower does not support C++11 (disabling)") endif() diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index c12e6dd12..d41ece1ca 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -201,7 +201,6 @@ endif() list( APPEND atlas_mesh_srcs mesh.h -mesh/Connectivity.cc mesh/Connectivity.h mesh/ElementType.cc mesh/ElementType.h @@ -264,6 +263,13 @@ mesh/actions/BuildTorusXYZField.h mesh/actions/BuildTorusXYZField.cc ) +if(NOT ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA) +list( APPEND atlas_mesh_srcs +mesh/Connectivity.cc +) +endif() + + list( APPEND atlas_output_srcs output/Output.h output/Output.cc @@ -386,16 +392,22 @@ list( APPEND atlas_array_srcs array/gridtools/GPUClonable.h array/gridtools/GridToolsArray.cc array/gridtools/GridToolsArrayHelpers.h -array/gridtools/GridToolsArrayView.cc array/gridtools/GridToolsArrayView.h array/gridtools/GridToolsDataStore.h -array/gridtools/GridToolsIndexView.cc array/gridtools/GridToolsIndexView.h array/gridtools/GridToolsMakeView.cc array/gridtools/GridToolsMakeView.h array/gridtools/GridToolsStorageView.h array/gridtools/GridToolsTraits.h ) + +if(NOT ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA) +list( APPEND atlas_array_srcs +array/gridtools/GridToolsArrayView.cc +array/gridtools/GridToolsIndexView.cc +) +endif() + else() list( APPEND atlas_array_srcs array/native/NativeArray.cc @@ -536,13 +548,11 @@ list( APPEND source_list ) if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) -## TODO temporary disabled since I get a linking error of the nvcc intermediate step -# use_cuda( source_list -# array/gridtools/GridToolsArrayView.cc -# array/gridtools/GridToolsIndexView.cc -# array/gridtools/GridToolsMakeView.cc -# mesh/Connectivity.cc -# ) + use_cuda( source_list + array/gridtools/GridToolsArrayView.cu + array/gridtools/GridToolsIndexView.cu + mesh/Connectivity.cu + ) endif() ecbuild_add_library( TARGET atlas diff --git a/src/atlas/array/Vector.h b/src/atlas/array/Vector.h index 7b903768f..0a5788640 100644 --- a/src/atlas/array/Vector.h +++ b/src/atlas/array/Vector.h @@ -12,6 +12,7 @@ #include #include +#include #include "atlas/runtime/ErrorHandling.h" #include "atlas/library/config.h" diff --git a/src/atlas/mesh/Nodes.h b/src/atlas/mesh/Nodes.h index f6d8cfd5f..f5bf042b1 100644 --- a/src/atlas/mesh/Nodes.h +++ b/src/atlas/mesh/Nodes.h @@ -98,6 +98,8 @@ class Nodes : public eckit::Owned { const Connectivity& connectivity(const std::string& name) const; Connectivity& connectivity(const std::string& name); + bool has_connectivity(std::string name) const { return connectivities_.count(name); } + size_t size() const { return size_; } // -- Modifiers From 28bc4e34363127f069f2a610058bb4e401dd312e Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Wed, 31 May 2017 10:29:02 +0200 Subject: [PATCH 039/355] adapt to new GT storage restructuring --- CMakeLists.txt | 1 + cmake/Findgridtools_storage.cmake | 4 +-- src/atlas/array/Array.h | 4 +-- src/atlas/array/ArrayUtil.h | 4 +-- src/atlas/array/Table.cc | 8 ++--- src/atlas/array/Table.h | 4 +-- src/atlas/array/Vector.h | 14 +++++--- src/atlas/array/gridtools/GridToolsArray.cc | 4 +-- .../array/gridtools/GridToolsArrayHelpers.h | 25 ++++++--------- .../array/gridtools/GridToolsArrayView.h | 4 +-- .../array/gridtools/GridToolsDataStore.h | 8 ++--- .../array/gridtools/GridToolsIndexView.h | 2 +- .../array/gridtools/GridToolsMakeView.cc | 8 ++--- src/atlas/array/gridtools/GridToolsTraits.h | 11 +++++-- src/atlas/array/native/NativeDataStore.h | 8 ++--- src/atlas/field/Field.cc | 8 ++--- src/atlas/field/Field.h | 4 +-- src/atlas/field/detail/FieldImpl.cc | 4 +-- src/atlas/field/detail/FieldImpl.h | 8 ++--- src/atlas/mesh/Connectivity.cc | 32 +++++++++---------- src/atlas/mesh/Connectivity.h | 12 +++---- src/tests/array/test_array.cc | 11 +++++++ src/tests/mesh/test_connectivity_kernel.cu | 6 ++-- 23 files changed, 105 insertions(+), 89 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96d3d7212..f8e986558 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,7 @@ if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) string(REPLACE "." "" CUDA_VERSION ${CUDA_VERSION}) add_definitions(-D_FORCE_INLINES) # Question to Carlos: Is this needed for nvcc only? + add_definitions(-D_USE_GPU_) set(CUDA_PROPAGATE_HOST_FLAGS ON) set(CUDA_NVCC_FLAGS "--relaxed-constexpr" "${CUDA_NVCC_FLAGS}") diff --git a/cmake/Findgridtools_storage.cmake b/cmake/Findgridtools_storage.cmake index 0d95e777e..8c7870184 100644 --- a/cmake/Findgridtools_storage.cmake +++ b/cmake/Findgridtools_storage.cmake @@ -16,10 +16,10 @@ if( NOT GRIDTOOLS_STORAGE_FOUND ) find_path( GRIDTOOLS_STORAGE_INCLUDE_DIR - NAMES storage-facility.hpp + NAMES storage/storage-facility.hpp PATHS ${CMAKE_INSTALL_PREFIX} - ${GRIDTOOLS_STORAGE_PATH} + "${GRIDTOOLS_STORAGE_PATH}" ENV GRIDTOOLS_STORAGE_PATH PATH_SUFFIXES include ) diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index d8ec840ad..d12127cc9 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -100,9 +100,9 @@ class Array : public eckit::Owned { void syncHostDevice() const { data_store_->syncHostDevice(); } - bool isOnHost() const { return data_store_->isOnHost(); } + bool hostNeedsUpdate() const { return data_store_->hostNeedsUpdate(); } - bool isOnDevice() const { return data_store_->isOnDevice(); } + bool deviceNeedsUpdate() const { return data_store_->deviceNeedsUpdate(); } void reactivateDeviceWriteViews() const { data_store_->reactivateDeviceWriteViews(); } diff --git a/src/atlas/array/ArrayUtil.h b/src/atlas/array/ArrayUtil.h index cdeed7bd1..519c1639f 100644 --- a/src/atlas/array/ArrayUtil.h +++ b/src/atlas/array/ArrayUtil.h @@ -36,8 +36,8 @@ class ArrayDataStore virtual void cloneFromDevice() const = 0; virtual bool valid() const = 0; virtual void syncHostDevice() const = 0; - virtual bool isOnHost() const = 0; - virtual bool isOnDevice() const = 0; + virtual bool hostNeedsUpdate() const = 0; + virtual bool deviceNeedsUpdate() const = 0; virtual void reactivateDeviceWriteViews() const = 0; virtual void reactivateHostWriteViews() const = 0; virtual void* voidDataStore() = 0; diff --git a/src/atlas/array/Table.cc b/src/atlas/array/Table.cc index 242cb2d05..6dec8f1dd 100644 --- a/src/atlas/array/Table.cc +++ b/src/atlas/array/Table.cc @@ -342,17 +342,17 @@ bool Table::valid() const { // ---------------------------------------------------------------------------- -bool Table::isOnHost() const { +bool Table::hostNeedsUpdate() const { bool res=true; - std::for_each( data_.begin(), data_.end(), [&](array::Array* a){ res &= a->isOnHost();} ); + std::for_each( data_.begin(), data_.end(), [&](array::Array* a){ res &= a->hostNeedsUpdate();} ); return res; } // ---------------------------------------------------------------------------- -bool Table::isOnDevice() const { +bool Table::deviceNeedsUpdate() const { bool res=true; - std::for_each( data_.begin(), data_.end(), [&](array::Array* a){ res &= a->isOnDevice();} ); + std::for_each( data_.begin(), data_.end(), [&](array::Array* a){ res &= a->deviceNeedsUpdate();} ); return res; } diff --git a/src/atlas/array/Table.h b/src/atlas/array/Table.h index 6280edace..f633e5643 100644 --- a/src/atlas/array/Table.h +++ b/src/atlas/array/Table.h @@ -114,10 +114,10 @@ class Table : public eckit::Owned { virtual bool valid() const; /// @brief Check if data is present on host - virtual bool isOnHost() const; + virtual bool hostNeedsUpdate() const; /// @brief Check if data is present on device - virtual bool isOnDevice() const; + virtual bool deviceNeedsUpdate() const; /// @brief Print all values unformatted to output stream void dump(std::ostream&) const; diff --git a/src/atlas/array/Vector.h b/src/atlas/array/Vector.h index 0a5788640..666b688d0 100644 --- a/src/atlas/array/Vector.h +++ b/src/atlas/array/Vector.h @@ -12,7 +12,13 @@ #include #include -#include + +#include "atlas/library/config.h" + +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + #include +#endif + #include "atlas/runtime/ErrorHandling.h" #include "atlas/library/config.h" @@ -57,7 +63,7 @@ class Vector { void cloneToDevice() { if(!data_gpu_) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - cudaMalloc((void**)(&data_gpu_), sizeof(T*)*size_); + ::cudaMalloc((void**)(&data_gpu_), sizeof(T*)*size_); T* buff = new T[size_]; @@ -65,7 +71,7 @@ class Vector { data_[i]->cloneToDevice(); buff[i] = data_[i]->gpu_object_ptr(); } - cudaMemcpy(data_gpu_, buff, sizeof(T*)*size_, cudaMemcpyHostToDevice); + ::cudaMemcpy(data_gpu_, buff, sizeof(T*)*size_, cudaMemcpyHostToDevice); delete buff; #else data_gpu_ = data_; @@ -74,7 +80,7 @@ class Vector { } else { assert(size_gpu_ == size_); -#ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA for(size_t i=0; i < size(); ++i) { data_[i]->cloneToDevice(); assert(data_gpu_[i] == data_[i]->gpu_object_ptr()); diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 52ceb0d5d..c799473a7 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -157,7 +157,7 @@ class ArrayT_impl { check_dimension_lengths(array_.shape(), c...); - if(!array_.isOnHost()) { + if(!array_.hostNeedsUpdate()) { array_.cloneFromDevice(); } @@ -330,7 +330,7 @@ size_t ArrayT::footprint() const { //------------------------------------------------------------------------------ template void ArrayT::insert(size_t idx1, size_t size1) { - if(!isOnHost()) { + if(!hostNeedsUpdate()) { cloneFromDevice(); } diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index 5d8b1173d..0091f525e 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -150,45 +150,38 @@ struct default_layout_t { template static gridtools::storage_traits::data_store_t< Value, - gridtools::storage_traits::storage_info_t< + gridtools::storage_traits::custom_layout_storage_info_t< 0, - get_pack_size::type::value, - typename ::gridtools::zero_halo::type::value>::type, - LayoutMap + LayoutMap, + ::gridtools::zero_halo::type::value> > >* create_gt_storage(UInts... dims) { static_assert((sizeof...(dims) > 0), "Error: can not create storages without any dimension"); constexpr static unsigned int rank = get_pack_size::type::value; - typedef gridtools::storage_traits::storage_info_t< + typedef gridtools::storage_traits::custom_layout_storage_info_t< 0, - rank, - typename ::gridtools::zero_halo::type, - LayoutMap + LayoutMap, + ::gridtools::zero_halo > storage_info_ty; typedef gridtools::storage_traits::data_store_t data_store_t; storage_info_ty si(dims...); data_store_t* ds = new data_store_t(si); - ds->allocate(); return ds; } template static gridtools::storage_traits::data_store_t< - Value, gridtools::storage_traits::storage_info_t< - 0, Rank, - typename ::gridtools::zero_halo::type, - typename default_layout_t::type > >* + Value, gridtools::storage_traits::storage_info_t<0, Rank> >* wrap_gt_storage( Value* data, std::array&& shape, std::array&& strides) { static_assert((Rank > 0), "Error: can not create storages without any dimension"); typedef gridtools::storage_traits::storage_info_t< - 0, Rank, typename ::gridtools::zero_halo::type, - typename default_layout_t::type> storage_info_ty; + 0, Rank, ::gridtools::zero_halo > storage_info_ty; typedef gridtools::storage_traits::data_store_t data_store_t; storage_info_ty si(shape, strides); @@ -228,7 +221,7 @@ struct default_layout_t { static_assert((::gridtools::is_data_store::value), "Internal Error: passing a non GT data store"); auto storage_info_ptr = gt_data_store_ptr->get_storage_info_ptr(); - using Layout = typename DataStore::storage_info_t::Layout; + using Layout = typename DataStore::storage_info_t::layout_t; using seq = my_apply_gt_integer_sequence::type>; diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index d34118bed..6dcf209b4 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -29,7 +29,7 @@ template< typename Value, int Rank > class ArrayView { // -- Type definitions using value_type = typename remove_const::type; using Slice = typename std::conditional<(Rank==1), value_type&, LocalView >::type; - using data_view_t = atlas::array::gridtools::data_view_tt; + using data_view_t = gridtools::data_view_tt; public: @@ -39,8 +39,8 @@ template< typename Value, int Rank > class ArrayView { value_type const* data() const { return gt_data_view_.data(); } template < typename... Coords, typename = typename boost::enable_if_c<(sizeof...(Coords) == Rank), int>::type > - value_type& ATLAS_HOST_DEVICE + value_type& operator()(Coords... c) { assert(sizeof...(Coords) == Rank); return gt_data_view_(c...); diff --git a/src/atlas/array/gridtools/GridToolsDataStore.h b/src/atlas/array/gridtools/GridToolsDataStore.h index a7d5b7c50..006a3ed5f 100644 --- a/src/atlas/array/gridtools/GridToolsDataStore.h +++ b/src/atlas/array/gridtools/GridToolsDataStore.h @@ -44,12 +44,12 @@ struct GridToolsDataStore : ArrayDataStore data_store_->sync(); } - bool isOnHost() const { - return data_store_->is_on_host(); + bool hostNeedsUpdate() const { + return data_store_->host_needs_update(); } - bool isOnDevice() const { - return data_store_->is_on_device(); + bool deviceNeedsUpdate() const { + return data_store_->device_needs_update(); } void reactivateDeviceWriteViews() const { diff --git a/src/atlas/array/gridtools/GridToolsIndexView.h b/src/atlas/array/gridtools/GridToolsIndexView.h index 262e07f10..bb7c5aaf5 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.h +++ b/src/atlas/array/gridtools/GridToolsIndexView.h @@ -77,7 +77,7 @@ class IndexView #define FROM_FORTRAN #define TO_FORTRAN #endif - using data_view_t = gridtools::data_view_tt; + using data_view_t = gridtools::data_view_tt; public: diff --git a/src/atlas/array/gridtools/GridToolsMakeView.cc b/src/atlas/array/gridtools/GridToolsMakeView.cc index d3fd080de..d2f4875e8 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.cc +++ b/src/atlas/array/gridtools/GridToolsMakeView.cc @@ -43,7 +43,7 @@ make_gt_host_view(const Array& array) { data_store_t* ds = reinterpret_cast(const_cast(array.storage())); - return ::gridtools::make_host_view(*ds); + return ::gridtools::make_host_view<::gridtools::access_mode::ReadWrite>(*ds); } template @@ -54,9 +54,9 @@ make_gt_device_view(const Array& array) { data_store_t* ds = reinterpret_cast(const_cast(array.storage())); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - return ::gridtools::make_device_view(*ds); + return ::gridtools::make_device_view<::gridtools::access_mode::ReadWrite>(*ds); #else - return ::gridtools::make_host_view(*ds); + return ::gridtools::make_host_view<::gridtools::access_mode::ReadWrite>(*ds); #endif } } @@ -99,7 +99,7 @@ make_host_indexview(const Array& array) { data_store_t* ds = reinterpret_cast(const_cast(array.storage())); - return IndexView(::gridtools::make_host_view(*ds)); + return IndexView(::gridtools::make_host_view<::gridtools::access_mode::ReadWrite>(*ds)); } // -------------------------------------------------------------------------------------------- diff --git a/src/atlas/array/gridtools/GridToolsTraits.h b/src/atlas/array/gridtools/GridToolsTraits.h index 476c9f4ee..272e1c941 100644 --- a/src/atlas/array/gridtools/GridToolsTraits.h +++ b/src/atlas/array/gridtools/GridToolsTraits.h @@ -6,7 +6,8 @@ #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA #define ENABLE_GPU #endif -#include "storage-facility.hpp" +#include "common/generic_metafunctions/all_integrals.hpp" +#include "storage/storage-facility.hpp" #ifdef ENABLE_GPU #undef ENABLE_GPU #endif @@ -28,12 +29,16 @@ using storage_traits = ::gridtools::storage_traits< ::gridtools::enumtype::Host //------------------------------------------------------------------------------ -template +template using data_view_tt = ::gridtools::data_view< gridtools::storage_traits::data_store_t< Value, gridtools::storage_traits::storage_info_t<0, Rank> >, - ReadOnly>; + AccessMode>; + +constexpr ::gridtools::access_mode get_access_mode(bool readonly) { + return readonly ? ::gridtools::access_mode::ReadOnly : ::gridtools::access_mode::ReadWrite; +} //------------------------------------------------------------------------------ diff --git a/src/atlas/array/native/NativeDataStore.h b/src/atlas/array/native/NativeDataStore.h index abf40227a..b714fe273 100644 --- a/src/atlas/array/native/NativeDataStore.h +++ b/src/atlas/array/native/NativeDataStore.h @@ -40,11 +40,11 @@ class DataStore : public ArrayDataStore { void syncHostDevice() const { } - bool isOnHost() const { + bool hostNeedsUpdate() const { return true; } - bool isOnDevice() const { + bool deviceNeedsUpdate() const { return false; } @@ -85,11 +85,11 @@ class WrappedDataStore : public ArrayDataStore { void syncHostDevice() const { } - bool isOnHost() const { + bool hostNeedsUpdate() const { return true; } - bool isOnDevice() const { + bool deviceNeedsUpdate() const { return false; } diff --git a/src/atlas/field/Field.cc b/src/atlas/field/Field.cc index bdb41e36f..0ebc7eda6 100644 --- a/src/atlas/field/Field.cc +++ b/src/atlas/field/Field.cc @@ -265,11 +265,11 @@ void Field::cloneFromDevice() const { void Field::syncHostDevice() const { field_->syncHostDevice(); } -bool Field::isOnHost() const { - return field_->isOnHost(); +bool Field::hostNeedsUpdate() const { + return field_->hostNeedsUpdate(); } -bool Field::isOnDevice() const { - return field_->isOnDevice(); +bool Field::deviceNeedsUpdate() const { + return field_->deviceNeedsUpdate(); } void Field::reactivateDeviceWriteViews() const { field_->reactivateDeviceWriteViews(); diff --git a/src/atlas/field/Field.h b/src/atlas/field/Field.h index 878591851..07e0ba305 100644 --- a/src/atlas/field/Field.h +++ b/src/atlas/field/Field.h @@ -163,8 +163,8 @@ class Field { void cloneToDevice() const; void cloneFromDevice() const; void syncHostDevice() const; - bool isOnHost() const; - bool isOnDevice() const; + bool hostNeedsUpdate() const; + bool deviceNeedsUpdate() const; void reactivateDeviceWriteViews() const; void reactivateHostWriteViews() const; }; diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index 6274208cb..7c1500c12 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -486,12 +486,12 @@ void atlas__Field__device_data_double_specf (FieldImpl* This, double* &data, int int atlas__Field__is_on_host(const FieldImpl* This) { - return This->isOnHost(); + return This->hostNeedsUpdate(); } int atlas__Field__is_on_device(const FieldImpl* This) { - return This->isOnDevice(); + return This->deviceNeedsUpdate(); } void atlas__Field__rename(FieldImpl* This, const char* name) diff --git a/src/atlas/field/detail/FieldImpl.h b/src/atlas/field/detail/FieldImpl.h index 310350657..247c369df 100644 --- a/src/atlas/field/detail/FieldImpl.h +++ b/src/atlas/field/detail/FieldImpl.h @@ -170,11 +170,11 @@ class FieldImpl : public eckit::Owned { void syncHostDevice() const { array_->syncHostDevice(); } - bool isOnHost() const { - return array_->isOnHost(); + bool hostNeedsUpdate() const { + return array_->hostNeedsUpdate(); } - bool isOnDevice() const { - return array_->isOnDevice(); + bool deviceNeedsUpdate() const { + return array_->deviceNeedsUpdate(); } void reactivateDeviceWriteViews() const { array_->reactivateDeviceWriteViews(); diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index 021377638..a21a5a174 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -399,14 +399,14 @@ bool IrregularConnectivityImpl::valid() const { std::for_each(data_.begin(), data_.end(), [&](array::Array* a){ res &= a->valid();}); return res; } -bool IrregularConnectivityImpl::isOnHost() const { +bool IrregularConnectivityImpl::hostNeedsUpdate() const { bool res=true; - std::for_each(data_.begin(), data_.end(), [&](array::Array* a){ res &= a->isOnHost();}); + std::for_each(data_.begin(), data_.end(), [&](array::Array* a){ res &= a->hostNeedsUpdate();}); return res; } -bool IrregularConnectivityImpl::isOnDevice() const { +bool IrregularConnectivityImpl::deviceNeedsUpdate() const { bool res=true; - std::for_each(data_.begin(), data_.end(), [&](array::Array* a){ res &= a->isOnDevice();}); + std::for_each(data_.begin(), data_.end(), [&](array::Array* a){ res &= a->deviceNeedsUpdate();}); return res; } @@ -518,18 +518,18 @@ bool MultiBlockConnectivityImpl::valid() const { block_cols_->valid(); } -bool MultiBlockConnectivityImpl::isOnHost() const { +bool MultiBlockConnectivityImpl::hostNeedsUpdate() const { return - IrregularConnectivityImpl::isOnHost() && - block_displs_->isOnHost() && - block_cols_->isOnHost(); + IrregularConnectivityImpl::hostNeedsUpdate() && + block_displs_->hostNeedsUpdate() && + block_cols_->hostNeedsUpdate(); } -bool MultiBlockConnectivityImpl::isOnDevice() const { +bool MultiBlockConnectivityImpl::deviceNeedsUpdate() const { return - IrregularConnectivityImpl::isOnDevice() && - block_displs_->isOnDevice() && - block_cols_->isOnDevice(); + IrregularConnectivityImpl::deviceNeedsUpdate() && + block_displs_->deviceNeedsUpdate() && + block_cols_->deviceNeedsUpdate(); } //------------------------------------------------------------------------------------------------------ @@ -872,12 +872,12 @@ bool BlockConnectivityImpl::valid() const { return values_->valid(); } -bool BlockConnectivityImpl::isOnHost() const { - return values_->isOnHost(); +bool BlockConnectivityImpl::hostNeedsUpdate() const { + return values_->hostNeedsUpdate(); } -bool BlockConnectivityImpl::isOnDevice() const { - return values_->isOnDevice(); +bool BlockConnectivityImpl::deviceNeedsUpdate() const { + return values_->deviceNeedsUpdate(); } //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 9f85b259e..2ca7b7873 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -264,8 +264,8 @@ class IrregularConnectivityImpl virtual void cloneFromDevice(); virtual void syncHostDevice() const; virtual bool valid() const; - virtual bool isOnHost() const; - virtual bool isOnDevice() const; + virtual bool hostNeedsUpdate() const; + virtual bool deviceNeedsUpdate() const; IrregularConnectivityImpl* gpu_object_ptr() {return gpu_clone_.gpu_object_ptr();} void dump(std::ostream& os) const; @@ -430,8 +430,8 @@ class MultiBlockConnectivityImpl : public IrregularConnectivityImpl virtual void cloneFromDevice(); virtual void syncHostDevice() const; virtual bool valid() const; - virtual bool isOnHost() const; - virtual bool isOnDevice() const; + virtual bool hostNeedsUpdate() const; + virtual bool deviceNeedsUpdate() const; MultiBlockConnectivityImpl* gpu_object_ptr() {return gpu_clone_.gpu_object_ptr();} @@ -553,8 +553,8 @@ class BlockConnectivityImpl { void cloneFromDevice(); void syncHostDevice() const; bool valid() const; - bool isOnHost() const; - bool isOnDevice() const; + bool hostNeedsUpdate() const; + bool deviceNeedsUpdate() const; bool owns() const { return owns_; } BlockConnectivityImpl* gpu_object_ptr() {return gpu_clone_.gpu_object_ptr();} diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index c17344c0b..c7e6f7931 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -37,12 +37,16 @@ CASE("test_array") { } #endif +#warning fix +//#ifndef ATLAS_HAVE_GRIDTOOLS_STORAGE +// GridTools does not support arrays with zero size CASE("test_array_zero_size") { Array* ds = Array::create(0); EXPECT(ds->size() == 0); delete ds; } +//#endif #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE CASE("test_create") { @@ -214,6 +218,13 @@ CASE("test_resize") { delete ds; } + { + Array* ds = Array::create(1); + EXPECT(ds->size() == 1); + ds->resize(2); + delete ds; + } + { Array* ds = Array::create(2, 3, 4); { diff --git a/src/tests/mesh/test_connectivity_kernel.cu b/src/tests/mesh/test_connectivity_kernel.cu index 1cc305269..8b901eca9 100644 --- a/src/tests/mesh/test_connectivity_kernel.cu +++ b/src/tests/mesh/test_connectivity_kernel.cu @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE( test_block_connectivity ) conn.add(2,5, vals2); conn.cloneToDevice(); - BOOST_CHECK( conn.isOnDevice() ); + BOOST_CHECK( !conn.deviceNeedsUpdate() ); kernel_block<<<1,1>>>(conn.gpu_object_ptr(), result); @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE( test_irregular_connectivity ) *result = true; conn.cloneToDevice(); - BOOST_CHECK( conn.isOnDevice() ); + BOOST_CHECK( !conn.deviceNeedsUpdate() ); kernel_irr<<<1,1>>>(conn.gpu_object_ptr(), result); @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE( test_multiblock_connectivity ) *result = true; conn.cloneToDevice(); - BOOST_CHECK( conn.isOnDevice() ); + BOOST_CHECK( !conn.deviceNeedsUpdate() ); kernel_multiblock<<<1,1>>>(conn.gpu_object_ptr(), result); From d597adcf58e831f7bb58bff3617c3de3a54b12ed Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 6 Jun 2017 09:13:14 +0200 Subject: [PATCH 040/355] adapt to new gt storage --- .../array/gridtools/GridToolsArrayHelpers.h | 36 ++++++++++++++----- .../array/gridtools/GridToolsArrayView.cc | 31 ++++++++++------ .../array/gridtools/GridToolsIndexView.h | 5 ++- src/tests/array/test_array.cc | 8 +++++ 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index 0091f525e..319be8150 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -13,6 +13,7 @@ #include #include #include +#include #include "atlas/library/config.h" #include "atlas/array_fwd.h" #include "atlas/array.h" @@ -167,8 +168,14 @@ struct default_layout_t { > storage_info_ty; typedef gridtools::storage_traits::data_store_t data_store_t; - storage_info_ty si(dims...); - data_store_t* ds = new data_store_t(si); + data_store_t* ds; + if(::gridtools::accumulate(::gridtools::multiplies(), dims...) == 0) { + ds = new data_store_t(); + } + else { + storage_info_ty si(dims...); + ds = new data_store_t(si); + } return ds; } @@ -186,9 +193,16 @@ struct default_layout_t { storage_info_ty si(shape, strides); data_store_t* ds = new data_store_t(si, data); + return ds; } + constexpr size_t zero(std::size_t) {return 0;} + + template + ArrayShape make_null_strides(::gridtools::gt_integer_sequence) { + return make_strides(zero(Is)...); + } template < typename UInt > struct my_apply_gt_integer_sequence { @@ -220,21 +234,25 @@ struct default_layout_t { ArraySpec make_spec(DataStore* gt_data_store_ptr, Dims...dims) { static_assert((::gridtools::is_data_store::value), "Internal Error: passing a non GT data store"); - auto storage_info_ptr = gt_data_store_ptr->get_storage_info_ptr(); - using Layout = typename DataStore::storage_info_t::layout_t; + if(gt_data_store_ptr->valid()) { + auto storage_info_ptr = gt_data_store_ptr->get_storage_info_ptr(); + using Layout = typename DataStore::storage_info_t::layout_t; using seq = my_apply_gt_integer_sequence::type>; - return ArraySpec( - ArrayShape{(unsigned long)dims...}, - seq::template apply< + return ArraySpec( + ArrayShape{(unsigned long)dims...}, + seq::template apply< ArrayStrides, get_stride_component::type>::template get_component>( storage_info_ptr), - seq::template apply< + seq::template apply< ArrayLayout, get_layout_map_component::template get_component>() - ); + ); + } + + return ArraySpec( make_shape(dims...), make_null_strides(typename ::gridtools::make_gt_integer_sequence::type())); } //------------------------------------------------------------------------------ diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index bb049c1a8..487239240 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -27,21 +27,30 @@ ArrayView::ArrayView( const ArrayView& other ) : template< typename Value, int Rank > ArrayView::ArrayView(data_view_t data_view, const Array& array) : gt_data_view_(data_view), data_store_orig_(array.data_store()), array_(&array) { - using seq = ::gridtools::apply_gt_integer_sequence::type>; + if(data_view.valid()) { + using seq = ::gridtools::apply_gt_integer_sequence::type>; - constexpr static unsigned int ndims = data_view_t::data_store_t::storage_info_t::ndims; - data_view_t gt_host_view_ = atlas::array::gridtools::make_gt_host_view ( array ); + constexpr static unsigned int ndims = data_view_t::data_store_t::storage_info_t::ndims; + data_view_t gt_host_view_ = atlas::array::gridtools::make_gt_host_view ( array ); - auto stridest = seq::template apply< - std::vector, - atlas::array::gridtools::get_stride_component >::template get_component>( - &(gt_host_view_.storage_info())); - auto shapet = seq::template apply, atlas::array::gridtools::get_shape_component>(&(gt_host_view_.storage_info())); + auto stridest = seq::template apply< + std::vector, + atlas::array::gridtools::get_stride_component >::template get_component>( + &(gt_host_view_.storage_info())); + auto shapet = seq::template apply, atlas::array::gridtools::get_shape_component>(&(gt_host_view_.storage_info())); - std::memcpy(strides_, &(stridest[0]), sizeof(size_t)*Rank); - std::memcpy(shape_, &(shapet[0]), sizeof(size_t)*Rank); + std::memcpy(strides_, &(stridest[0]), sizeof(size_t)*Rank); + std::memcpy(shape_, &(shapet[0]), sizeof(size_t)*Rank); - size_ = gt_host_view_.storage_info().size(); + size_ = gt_host_view_.storage_info().size(); + } + else { + + std::fill_n(shape_, Rank, 0 ); + std::fill_n(strides_, Rank, 0 ); + + size_ = 0; + } } template< typename Value, int Rank > diff --git a/src/atlas/array/gridtools/GridToolsIndexView.h b/src/atlas/array/gridtools/GridToolsIndexView.h index bb7c5aaf5..be2996888 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.h +++ b/src/atlas/array/gridtools/GridToolsIndexView.h @@ -82,7 +82,10 @@ class IndexView public: IndexView(data_view_t data_view) : gt_data_view_(data_view) { - size_ = gt_data_view_.storage_info().size(); + if(data_view.valid()) + size_ = gt_data_view_.storage_info().size(); + else + size_ = 0; } template < typename... Coords > diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index c7e6f7931..69ac08891 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -222,6 +222,13 @@ CASE("test_resize") { Array* ds = Array::create(1); EXPECT(ds->size() == 1); ds->resize(2); + delete ds + } + + { + Array* ds = Array::create(0); + EXPECT(ds->size() == 0); + ds->resize(make_shape(5)); delete ds; } @@ -233,6 +240,7 @@ CASE("test_resize") { hv(1, 2, 2) = 7.5; } ds->resize(3, 4, 5); + atlas::array::ArrayView hv = make_host_view(*ds); EXPECT(ds->spec().shape()[0] == 3); From 2d687306d3684e1b28c4435a37b2c65fe1382d50 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 11 Jul 2017 14:38:53 +0200 Subject: [PATCH 041/355] use some c++11 initializer list to avoid multiple fn overload declarations --- src/atlas/array/ArrayShape.h | 1 + src/atlas/array/ArrayStrides.h | 1 + src/atlas/array/gridtools/GridToolsArrayHelpers.h | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/atlas/array/ArrayShape.h b/src/atlas/array/ArrayShape.h index e181a77bf..ce52a878c 100644 --- a/src/atlas/array/ArrayShape.h +++ b/src/atlas/array/ArrayShape.h @@ -27,6 +27,7 @@ class ArrayShape : public std::vector { ArrayShape( std::initializer_list list ) : Base(list) {} }; +inline ArrayShape make_shape(std::initializer_list sizes) { return ArrayShape(sizes); } inline ArrayShape make_shape(size_t size1) { return ArrayShape{size1}; } inline ArrayShape make_shape(size_t size1, size_t size2) { return ArrayShape{size1,size2}; } inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3) { return ArrayShape{size1,size2,size3}; } diff --git a/src/atlas/array/ArrayStrides.h b/src/atlas/array/ArrayStrides.h index cadf42d07..f4dee3f5b 100644 --- a/src/atlas/array/ArrayStrides.h +++ b/src/atlas/array/ArrayStrides.h @@ -28,6 +28,7 @@ class ArrayStrides : public std::vector { ArrayStrides( Base&& base ) : Base( std::forward(base) ) {} }; +inline ArrayStrides make_strides(std::initializer_list list) { return ArrayStrides(list); } inline ArrayStrides make_strides(size_t size1) { return ArrayStrides{size1}; } inline ArrayStrides make_strides(size_t size1, size_t size2) { return ArrayStrides{size1,size2}; } inline ArrayStrides make_strides(size_t size1, size_t size2, size_t size3) { return ArrayStrides{size1,size2,size3}; } diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index 319be8150..6f7ef08c1 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -201,7 +201,7 @@ struct default_layout_t { template ArrayShape make_null_strides(::gridtools::gt_integer_sequence) { - return make_strides(zero(Is)...); + return make_strides({zero(Is)...}); } template < typename UInt > @@ -252,7 +252,7 @@ struct default_layout_t { ); } - return ArraySpec( make_shape(dims...), make_null_strides(typename ::gridtools::make_gt_integer_sequence::type())); + return ArraySpec( make_shape({dims...}), make_null_strides(typename ::gridtools::make_gt_integer_sequence::type())); } //------------------------------------------------------------------------------ From d91aad48863b5f58b46c74563bfdd32216e63c53 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 11 Jul 2017 14:50:50 +0200 Subject: [PATCH 042/355] add missing files --- src/atlas/array/gridtools/GridToolsArrayView.cu | 1 + src/atlas/array/gridtools/GridToolsIndexView.cu | 1 + src/atlas/mesh/Connectivity.cu | 1 + 3 files changed, 3 insertions(+) create mode 100644 src/atlas/array/gridtools/GridToolsArrayView.cu create mode 100644 src/atlas/array/gridtools/GridToolsIndexView.cu create mode 100644 src/atlas/mesh/Connectivity.cu diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cu b/src/atlas/array/gridtools/GridToolsArrayView.cu new file mode 100644 index 000000000..5441c6fe2 --- /dev/null +++ b/src/atlas/array/gridtools/GridToolsArrayView.cu @@ -0,0 +1 @@ +#include "GridToolsArrayView.cc" diff --git a/src/atlas/array/gridtools/GridToolsIndexView.cu b/src/atlas/array/gridtools/GridToolsIndexView.cu new file mode 100644 index 000000000..5abeea37d --- /dev/null +++ b/src/atlas/array/gridtools/GridToolsIndexView.cu @@ -0,0 +1 @@ +#include "GridToolsIndexView.cc" diff --git a/src/atlas/mesh/Connectivity.cu b/src/atlas/mesh/Connectivity.cu new file mode 100644 index 000000000..a96a08016 --- /dev/null +++ b/src/atlas/mesh/Connectivity.cu @@ -0,0 +1 @@ +#include "Connectivity.cc" From f60ce8d97d87285bf9fbbd45dce9d8b214adccf2 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 28 Aug 2017 20:01:49 +0200 Subject: [PATCH 043/355] change prep flat --- src/atlas/array/gridtools/GridToolsTraits.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsTraits.h b/src/atlas/array/gridtools/GridToolsTraits.h index 272e1c941..ec741d534 100644 --- a/src/atlas/array/gridtools/GridToolsTraits.h +++ b/src/atlas/array/gridtools/GridToolsTraits.h @@ -4,12 +4,12 @@ //------------------------------------------------------------------------------ #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA -#define ENABLE_GPU +#define _USE_GPU_ #endif #include "common/generic_metafunctions/all_integrals.hpp" #include "storage/storage-facility.hpp" -#ifdef ENABLE_GPU -#undef ENABLE_GPU +#ifdef _USE_GPU_ +#undef _USE_GPU_ #endif //------------------------------------------------------------------------------ From 2aa1d7ffdc7bb468949a0f08f876b9a23bec6722 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 29 Aug 2017 15:10:26 +0200 Subject: [PATCH 044/355] fixes --- src/atlas/array/gridtools/GridToolsArrayHelpers.h | 2 +- src/atlas/array/gridtools/GridToolsArrayView.cc | 2 +- src/atlas/array/gridtools/GridToolsIndexView.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index 6f7ef08c1..b59bf4825 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -235,7 +235,7 @@ struct default_layout_t { 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(); + auto storage_info_ptr = gt_data_store_ptr->get_storage_info_ptr().get(); using Layout = typename DataStore::storage_info_t::layout_t; using seq = my_apply_gt_integer_sequence::type>; diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index 487239240..21060f9f5 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -42,7 +42,7 @@ ArrayView::ArrayView(data_view_t data_view, const Array& array) : std::memcpy(strides_, &(stridest[0]), sizeof(size_t)*Rank); std::memcpy(shape_, &(shapet[0]), sizeof(size_t)*Rank); - size_ = gt_host_view_.storage_info().size(); + size_ = gt_host_view_.storage_info().total_length(); } else { diff --git a/src/atlas/array/gridtools/GridToolsIndexView.h b/src/atlas/array/gridtools/GridToolsIndexView.h index be2996888..93dfaf713 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.h +++ b/src/atlas/array/gridtools/GridToolsIndexView.h @@ -83,7 +83,7 @@ class IndexView IndexView(data_view_t data_view) : gt_data_view_(data_view) { if(data_view.valid()) - size_ = gt_data_view_.storage_info().size(); + size_ = gt_data_view_.storage_info().total_length(); else size_ = 0; } From 78114f9bd478e6c00cb4cfba5eb57a10c6efaf54 Mon Sep 17 00:00:00 2001 From: cosunae Date: Tue, 29 Aug 2017 16:16:11 +0200 Subject: [PATCH 045/355] use unaligned dim --- src/atlas/array/gridtools/GridToolsArrayHelpers.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index b59bf4825..e8effa59b 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -138,7 +138,7 @@ struct default_layout_t { template < typename StorageInfoPtr> ATLAS_HOST_DEVICE constexpr static size_t apply(StorageInfoPtr a) { static_assert((::gridtools::is_storage_info::type >::value ), "Error: not a storage_info"); - return a->template dim(); + return a->template unaligned_dim(); } }; From 25a8e1eef080c95a0c01ad0f9a53975bd028a2ae Mon Sep 17 00:00:00 2001 From: cosunae Date: Tue, 29 Aug 2017 16:24:58 +0200 Subject: [PATCH 046/355] avoid host data view --- .../array/gridtools/GridToolsArrayView.cc | 12 ++++++---- src/atlas/field/detail/FieldImpl.cc | 4 ++-- src/atlas/field/detail/FieldImpl.h | 4 ++-- .../autogenerated/atlas_Field_module_fypp.F90 | 24 +++++++++---------- src/atlas_f/field/atlas_Field_module.F90 | 24 +++++++++---------- src/tests/array/test_array.cc | 2 +- src/tests/field/CMakeLists.txt | 4 ++-- src/tests/field/fctest_field.F90 | 6 ++--- src/tests/field/fctest_field_gpu.F90 | 6 ++--- 9 files changed, 45 insertions(+), 41 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index 21060f9f5..fb2438e80 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -31,18 +31,22 @@ ArrayView::ArrayView(data_view_t data_view, const Array& array) : using seq = ::gridtools::apply_gt_integer_sequence::type>; constexpr static unsigned int ndims = data_view_t::data_store_t::storage_info_t::ndims; - data_view_t gt_host_view_ = atlas::array::gridtools::make_gt_host_view ( array ); + + using storage_info_ty = gridtools::storage_traits::storage_info_t<0, ndims>; + using data_store_t = gridtools::storage_traits::data_store_t; + + auto storage_info_ = *((reinterpret_cast(const_cast(array.storage())))->get_storage_info_ptr()); auto stridest = seq::template apply< std::vector, atlas::array::gridtools::get_stride_component >::template get_component>( - &(gt_host_view_.storage_info())); - auto shapet = seq::template apply, atlas::array::gridtools::get_shape_component>(&(gt_host_view_.storage_info())); + &(storage_info_)); + auto shapet = seq::template apply, atlas::array::gridtools::get_shape_component>(&(storage_info_)); std::memcpy(strides_, &(stridest[0]), sizeof(size_t)*Rank); std::memcpy(shape_, &(shapet[0]), sizeof(size_t)*Rank); - size_ = gt_host_view_.storage_info().total_length(); + size_ = storage_info_.total_length(); } else { diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index 7c1500c12..cdce90bb3 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -484,12 +484,12 @@ void atlas__Field__device_data_double_specf (FieldImpl* This, double* &data, int ); } -int atlas__Field__is_on_host(const FieldImpl* This) +int atlas__Field__host_needs_update(const FieldImpl* This) { return This->hostNeedsUpdate(); } -int atlas__Field__is_on_device(const FieldImpl* This) +int atlas__Field__device_needs_update(const FieldImpl* This) { return This->deviceNeedsUpdate(); } diff --git a/src/atlas/field/detail/FieldImpl.h b/src/atlas/field/detail/FieldImpl.h index 247c369df..35b17fe1b 100644 --- a/src/atlas/field/detail/FieldImpl.h +++ b/src/atlas/field/detail/FieldImpl.h @@ -256,8 +256,8 @@ extern "C" void atlas__Field__rename(FieldImpl* This, const char* name); void atlas__Field__set_levels(FieldImpl* This, int levels); void atlas__Field__set_functionspace(FieldImpl* This, const functionspace::FunctionSpaceImpl* functionspace); - int atlas__Field__is_on_host(const FieldImpl* This); - int atlas__Field__is_on_device(const FieldImpl* This); + int atlas__Field__host_needs_update(const FieldImpl* This); + int atlas__Field__device_needs_update(const FieldImpl* This); void atlas__Field__clone_to_device(FieldImpl* This); void atlas__Field__clone_from_device(FieldImpl* This); void atlas__Field__sync_host_device(FieldImpl* This); diff --git a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 index a4844076f..2b33e5381 100644 --- a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 +++ b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 @@ -267,8 +267,8 @@ module atlas_field_module & access_device_data_logical32_r4_shape, & & dummy - procedure, public :: is_on_host - procedure, public :: is_on_device + procedure, public :: host_needs_update + procedure, public :: device_needs_update procedure, public :: clone_to_device procedure, public :: clone_from_device procedure, public :: sync_host_device @@ -3098,27 +3098,27 @@ subroutine set_functionspace(this,functionspace) !------------------------------------------------------------------------------- -function is_on_host(this) +function host_needs_update(this) use atlas_field_c_binding - logical :: is_on_host + logical :: host_needs_update class(atlas_Field), intent(in) :: this - if( atlas__Field__is_on_host(this%c_ptr()) == 1 ) then - is_on_host = .true. + if( atlas__Field__host_needs_update(this%c_ptr()) == 1 ) then + host_needs_update = .true. else - is_on_host = .false. + host_needs_update = .false. endif end function !------------------------------------------------------------------------------- -function is_on_device(this) +function device_needs_update(this) use atlas_field_c_binding - logical :: is_on_device + logical :: device_needs_update class(atlas_Field), intent(in) :: this - if( atlas__Field__is_on_device(this%c_ptr()) == 1 ) then - is_on_device = .true. + if( atlas__Field__device_needs_update(this%c_ptr()) == 1 ) then + device_needs_update = .true. else - is_on_device = .false. + device_needs_update = .false. endif end function diff --git a/src/atlas_f/field/atlas_Field_module.F90 b/src/atlas_f/field/atlas_Field_module.F90 index 6f80fbd40..e1831ddea 100644 --- a/src/atlas_f/field/atlas_Field_module.F90 +++ b/src/atlas_f/field/atlas_Field_module.F90 @@ -102,8 +102,8 @@ module atlas_field_module #:endfor & dummy - procedure, public :: is_on_host - procedure, public :: is_on_device + procedure, public :: host_needs_update + procedure, public :: device_needs_update procedure, public :: clone_to_device procedure, public :: clone_from_device procedure, public :: sync_host_device @@ -642,27 +642,27 @@ subroutine set_functionspace(this,functionspace) !------------------------------------------------------------------------------- -function is_on_host(this) +function host_needs_update(this) use atlas_field_c_binding - logical :: is_on_host + logical :: host_needs_update class(atlas_Field), intent(in) :: this - if( atlas__Field__is_on_host(this%c_ptr()) == 1 ) then - is_on_host = .true. + if( atlas__Field__host_needs_update(this%c_ptr()) == 1 ) then + host_needs_update = .true. else - is_on_host = .false. + host_needs_update = .false. endif end function !------------------------------------------------------------------------------- -function is_on_device(this) +function device_needs_update(this) use atlas_field_c_binding - logical :: is_on_device + logical :: device_needs_update class(atlas_Field), intent(in) :: this - if( atlas__Field__is_on_device(this%c_ptr()) == 1 ) then - is_on_device = .true. + if( atlas__Field__device_needs_update(this%c_ptr()) == 1 ) then + device_needs_update = .true. else - is_on_device = .false. + device_needs_update = .false. endif end function diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 69ac08891..9b78abe4a 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -222,7 +222,7 @@ CASE("test_resize") { Array* ds = Array::create(1); EXPECT(ds->size() == 1); ds->resize(2); - delete ds + delete ds; } { diff --git a/src/tests/field/CMakeLists.txt b/src/tests/field/CMakeLists.txt index 347b66304..2941bf6fa 100644 --- a/src/tests/field/CMakeLists.txt +++ b/src/tests/field/CMakeLists.txt @@ -9,14 +9,14 @@ if( HAVE_FCTEST ) add_fctest( TARGET atlas_fctest_field - CONDITION ATLAS_HAVE_GRIDTOOLS_STORAGE + CONDITION ATLAS_HAVE_GRIDTOOLS_STORAGE AND ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST LINKER_LANGUAGE Fortran SOURCES fctest_field.F90 LIBS atlas_f ) add_fctest( TARGET atlas_fctest_field_gpu - CONDITION ATLAS_HAVE_GRIDTOOLS_STORAGE + CONDITION ATLAS_HAVE_GRIDTOOLS_STORAGE AND ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA LINKER_LANGUAGE Fortran SOURCES fctest_field_gpu.F90 LIBS atlas_f diff --git a/src/tests/field/fctest_field.F90 b/src/tests/field/fctest_field.F90 index 20f8e145f..47de73a67 100644 --- a/src/tests/field/fctest_field.F90 +++ b/src/tests/field/fctest_field.F90 @@ -49,11 +49,11 @@ module fcta_Field_fxt call field%host_data(host) -FCTEST_CHECK( field%is_on_host() ) -FCTEST_CHECK( field%is_on_device() ) +FCTEST_CHECK( .not. field%host_needs_update() ) +FCTEST_CHECK( .not. field%device_needs_update() ) call field%clone_to_device() -FCTEST_CHECK( field%is_on_device() ) +FCTEST_CHECK( .not. field%device_needs_update() ) call field%final() END_TEST diff --git a/src/tests/field/fctest_field_gpu.F90 b/src/tests/field/fctest_field_gpu.F90 index e0d912f0a..2ff51a17b 100644 --- a/src/tests/field/fctest_field_gpu.F90 +++ b/src/tests/field/fctest_field_gpu.F90 @@ -64,8 +64,8 @@ end subroutine test_res field = atlas_Field(kind=atlas_real(8),shape=[10,5]) -FCTEST_CHECK( field%is_on_host() ) -FCTEST_CHECK( field%is_on_device() ) +FCTEST_CHECK( .not. field%host_needs_update() ) +FCTEST_CHECK( field%device_needs_update() ) call field%clone_to_device() call field%host_data(host) @@ -82,7 +82,7 @@ end subroutine test_res !FCTEST_CHECK_EQUAL( val, 3.5_c_float ) -FCTEST_CHECK( field%is_on_device() ) +FCTEST_CHECK( .not. field%device_needs_update() ) call field%final() END_TEST From 7def7282acd553233b58e99f42ed55ae284e8118 Mon Sep 17 00:00:00 2001 From: cosunae Date: Tue, 29 Aug 2017 16:25:08 +0200 Subject: [PATCH 047/355] add assert --- src/atlas/array/gridtools/GridToolsDataStore.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/atlas/array/gridtools/GridToolsDataStore.h b/src/atlas/array/gridtools/GridToolsDataStore.h index 006a3ed5f..c47f52138 100644 --- a/src/atlas/array/gridtools/GridToolsDataStore.h +++ b/src/atlas/array/gridtools/GridToolsDataStore.h @@ -29,6 +29,7 @@ struct GridToolsDataStore : ArrayDataStore } void cloneToDevice() const { + assert(data_store_); data_store_->clone_to_device(); } From 69437fdd9ee156f614cf0a387fc58b9eb97ac021 Mon Sep 17 00:00:00 2001 From: cosunae Date: Tue, 29 Aug 2017 16:26:23 +0200 Subject: [PATCH 048/355] protect define --- src/atlas/array/gridtools/GridToolsTraits.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/atlas/array/gridtools/GridToolsTraits.h b/src/atlas/array/gridtools/GridToolsTraits.h index ec741d534..9079a4c0d 100644 --- a/src/atlas/array/gridtools/GridToolsTraits.h +++ b/src/atlas/array/gridtools/GridToolsTraits.h @@ -4,8 +4,10 @@ //------------------------------------------------------------------------------ #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA +#ifndef _USE_GPU_ #define _USE_GPU_ #endif +#endif #include "common/generic_metafunctions/all_integrals.hpp" #include "storage/storage-facility.hpp" #ifdef _USE_GPU_ From a4b289bf66110b13cfb52adf8f1f935c9113bffa Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 31 Aug 2017 12:28:06 +0200 Subject: [PATCH 049/355] remove protection for zero size storages in GT --- src/tests/array/test_array.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 9b78abe4a..64c7127f1 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -37,16 +37,12 @@ CASE("test_array") { } #endif -#warning fix -//#ifndef ATLAS_HAVE_GRIDTOOLS_STORAGE -// GridTools does not support arrays with zero size CASE("test_array_zero_size") { Array* ds = Array::create(0); EXPECT(ds->size() == 0); delete ds; } -//#endif #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE CASE("test_create") { From 43b4003ca30e09001913338e926b932288c08e9c Mon Sep 17 00:00:00 2001 From: cosunae Date: Fri, 20 Oct 2017 18:56:26 +0200 Subject: [PATCH 050/355] fix; only sync if we have a valid array --- src/atlas/array/gridtools/GridToolsArray.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index c799473a7..c6f3f667a 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -157,9 +157,8 @@ class ArrayT_impl { check_dimension_lengths(array_.shape(), c...); - if(!array_.hostNeedsUpdate()) { - array_.cloneFromDevice(); - } + if(array_.valid()) + array_.syncHostDevice(); Array* resized = Array::create(ArrayShape{(unsigned int)c...}); From e8148c5f0f5d7ed513107368b54359f6dc3f07c7 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 12:48:40 +0200 Subject: [PATCH 051/355] move to SVector --- src/atlas/parallel/HaloExchange.h | 19 ++++++++++--------- src/tests/array/CMakeLists.txt | 12 ++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 54325e798..a2c213807 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -25,6 +25,7 @@ #include "atlas/parallel/mpi/Statistics.h" #include "atlas/array/ArrayView.h" +#include "atlas/array/SVector.h" #include "atlas/runtime/Log.h" namespace atlas { @@ -73,10 +74,10 @@ class HaloExchange: public eckit::Owned { const size_t var_strides[], const size_t var_shape[], size_t var_rank, - DATA_TYPE send_buffer[] ) const; + array::SVector& send_buffer ) const; template< typename DATA_TYPE> - void unpack_recv_buffer(const DATA_TYPE recv_buffer[], + void unpack_recv_buffer(const array::SVector& recv_buffer, DATA_TYPE field[], const size_t var_strides[], const size_t var_shape[], @@ -97,7 +98,7 @@ class HaloExchange: public eckit::Owned { std::vector senddispls_; std::vector recvcounts_; std::vector recvdispls_; - std::vector sendmap_; + array::SVector sendmap_; std::vector recvmap_; int parsize_; @@ -125,8 +126,8 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const int send_size = sendcnt_ * var_size; int recv_size = recvcnt_ * var_size; - std::vector send_buffer(send_size); - std::vector recv_buffer(recv_size); + array::SVector send_buffer(send_size); + array::SVector recv_buffer(recv_size); std::vector send_displs(nproc ); std::vector recv_displs(nproc ); std::vector send_counts(nproc ); @@ -155,7 +156,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const } /// Pack - pack_send_buffer(field,var_strides,var_shape,var_rank,send_buffer.data()); + pack_send_buffer(field,var_strides,var_shape,var_rank,send_buffer); /// Send ATLAS_TRACE_MPI( ISEND ) { @@ -182,7 +183,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const } /// Unpack - unpack_recv_buffer(recv_buffer.data(),field,var_strides,var_shape,var_rank); + unpack_recv_buffer(recv_buffer,field,var_strides,var_shape,var_rank); /// Wait for sending to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { @@ -201,7 +202,7 @@ void HaloExchange::pack_send_buffer( const DATA_TYPE field[], const size_t var_strides[], const size_t var_shape[], size_t var_rank, - DATA_TYPE send_buffer[] ) const + array::SVector& send_buffer ) const { ATLAS_TRACE(); size_t ibuf = 0; @@ -273,7 +274,7 @@ void HaloExchange::pack_send_buffer( const DATA_TYPE field[], } template -void HaloExchange::unpack_recv_buffer( const DATA_TYPE recv_buffer[], +void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buffer, DATA_TYPE field[], const size_t var_strides[], const size_t var_shape[], diff --git a/src/tests/array/CMakeLists.txt b/src/tests/array/CMakeLists.txt index 2ac6336cc..40a0a3eb9 100644 --- a/src/tests/array/CMakeLists.txt +++ b/src/tests/array/CMakeLists.txt @@ -16,6 +16,11 @@ ecbuild_add_test( TARGET atlas_test_array # LIBS atlas #) +ecbuild_add_test( TARGET atlas_test_svector + SOURCES test_svector.cc + LIBS atlas +) + if( CMAKE_BUILD_TYPE MATCHES "DEBUG" ) set ( CMAKE_NVCC_FLAGS "-G" ) endif() @@ -33,3 +38,10 @@ atlas_add_cuda_test( LIBS atlas ) +atlas_add_cuda_test( + TARGET atlas_test_svector_kernel + BOOST + SOURCES test_svector_kernel.cu + LIBS atlas +) + From d0f325b6b2f3c93bd4df91550d14995be7efeca1 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 15:22:44 +0200 Subject: [PATCH 052/355] comment out code --- src/atlas/parallel/HaloExchange.cc | 56 +++++++++++++++--------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index edbecdbae..cbdbe44d0 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -174,43 +174,43 @@ void atlas__HaloExchange__setup (HaloExchange* This, int part[], int remote_idx[ } void atlas__HaloExchange__execute_strided_int (HaloExchange* This, int field[], int var_strides[], int var_extents[], int var_rank) { - std::vector vstrides(var_rank); - std::vector vextents(var_rank); - for(int n = 0; n < var_rank; ++n) { - vstrides[n] = var_strides[n]; - vextents[n] = var_extents[n]; - } - This->execute(field,vstrides.data(),vextents.data(),var_rank); +// std::vector vstrides(var_rank); +// std::vector vextents(var_rank); +// for(int n = 0; n < var_rank; ++n) { +// vstrides[n] = var_strides[n]; +// vextents[n] = var_extents[n]; +// } +// This->execute(field,vstrides.data(),vextents.data(),var_rank); } void atlas__HaloExchange__execute_strided_long (HaloExchange* This, long field[], int var_strides[], int var_extents[], int var_rank) { - std::vector vstrides(var_rank); - std::vector vextents(var_rank); - for(int n = 0; n < var_rank; ++n) { - vstrides[n] = var_strides[n]; - vextents[n] = var_extents[n]; - } - This->execute(field,vstrides.data(),vextents.data(),var_rank); +// std::vector vstrides(var_rank); +// std::vector vextents(var_rank); +// for(int n = 0; n < var_rank; ++n) { +// vstrides[n] = var_strides[n]; +// vextents[n] = var_extents[n]; +// } +// This->execute(field,vstrides.data(),vextents.data(),var_rank); } void atlas__HaloExchange__execute_strided_float (HaloExchange* This, float field[], int var_strides[], int var_extents[], int var_rank) { - std::vector vstrides(var_rank); - std::vector vextents(var_rank); - for(int n = 0; n < var_rank; ++n) { - vstrides[n] = var_strides[n]; - vextents[n] = var_extents[n]; - } - This->execute(field,vstrides.data(),vextents.data(),var_rank); +// std::vector vstrides(var_rank); +// std::vector vextents(var_rank); +// for(int n = 0; n < var_rank; ++n) { +// vstrides[n] = var_strides[n]; +// vextents[n] = var_extents[n]; +// } +// This->execute(field,vstrides.data(),vextents.data(),var_rank); } void atlas__HaloExchange__execute_strided_double (HaloExchange* This, double field[], int var_strides[], int var_extents[], int var_rank) { - std::vector vstrides(var_rank); - std::vector vextents(var_rank); - for(int n = 0; n < var_rank; ++n) { - vstrides[n] = var_strides[n]; - vextents[n] = var_extents[n]; - } - This->execute(field,vstrides.data(),vextents.data(),var_rank); +// std::vector vstrides(var_rank); +// std::vector vextents(var_rank); +// for(int n = 0; n < var_rank; ++n) { +// vstrides[n] = var_strides[n]; +// vextents[n] = var_extents[n]; +// } +// This->execute(field,vstrides.data(),vextents.data(),var_rank); } void atlas__HaloExchange__execute_int (HaloExchange* This, int field[], int nb_vars ) { From 78aae556793e8097838b339f392d84464e687c67 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 15:40:09 +0200 Subject: [PATCH 053/355] pass arrayview --- src/atlas/parallel/HaloExchange.cc | 8 + src/atlas/parallel/HaloExchange.h | 28 ++- src/tests/parallel/test_haloexchange.cc | 280 ++++++++++++------------ 3 files changed, 164 insertions(+), 152 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index cbdbe44d0..edc538677 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -174,6 +174,8 @@ void atlas__HaloExchange__setup (HaloExchange* This, int part[], int remote_idx[ } void atlas__HaloExchange__execute_strided_int (HaloExchange* This, int field[], int var_strides[], int var_extents[], int var_rank) { + throw eckit::AssertionFailed("Call not supported"); + // std::vector vstrides(var_rank); // std::vector vextents(var_rank); // for(int n = 0; n < var_rank; ++n) { @@ -184,6 +186,8 @@ void atlas__HaloExchange__execute_strided_int (HaloExchange* This, int field[], } void atlas__HaloExchange__execute_strided_long (HaloExchange* This, long field[], int var_strides[], int var_extents[], int var_rank) { + throw eckit::AssertionFailed("Call not supported"); + // std::vector vstrides(var_rank); // std::vector vextents(var_rank); // for(int n = 0; n < var_rank; ++n) { @@ -194,6 +198,8 @@ void atlas__HaloExchange__execute_strided_long (HaloExchange* This, long field[] } void atlas__HaloExchange__execute_strided_float (HaloExchange* This, float field[], int var_strides[], int var_extents[], int var_rank) { + throw eckit::AssertionFailed("Call not supported"); + // std::vector vstrides(var_rank); // std::vector vextents(var_rank); // for(int n = 0; n < var_rank; ++n) { @@ -204,6 +210,8 @@ void atlas__HaloExchange__execute_strided_float (HaloExchange* This, float field } void atlas__HaloExchange__execute_strided_double (HaloExchange* This, double field[], int var_strides[], int var_extents[], int var_rank) { + throw eckit::AssertionFailed("Call not supported"); + // std::vector vstrides(var_rank); // std::vector vextents(var_rank); // for(int n = 0; n < var_rank; ++n) { diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index a2c213807..1ed000ac5 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -48,8 +48,8 @@ class HaloExchange: public eckit::Owned { const int remote_idx[], const int base, size_t size ); - template - void execute( DATA_TYPE field[], const size_t var_strides[], const size_t var_shape[], size_t var_rank ) const; + template + void execute( array::ArrayView& field, const size_t var_strides[], const size_t var_shape[], size_t var_rank ) const; template void execute( DATA_TYPE field[], size_t nb_vars ) const; @@ -111,8 +111,8 @@ class HaloExchange: public eckit::Owned { }; -template -void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const size_t var_shape[], size_t var_rank ) const +template +void HaloExchange::execute(array::ArrayView& field, const size_t var_strides[], const size_t var_shape[], size_t var_rank ) const { if( ! is_setup_ ) { @@ -126,6 +126,8 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const int send_size = sendcnt_ * var_size; int recv_size = recvcnt_ * var_size; + DATA_TYPE * data = field.data(); + array::SVector send_buffer(send_size); array::SVector recv_buffer(recv_size); std::vector send_displs(nproc ); @@ -156,7 +158,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const } /// Pack - pack_send_buffer(field,var_strides,var_shape,var_rank,send_buffer); + pack_send_buffer(data,var_strides,var_shape,var_rank,send_buffer); /// Send ATLAS_TRACE_MPI( ISEND ) { @@ -183,7 +185,7 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const } /// Unpack - unpack_recv_buffer(recv_buffer,field,var_strides,var_shape,var_rank); + unpack_recv_buffer(recv_buffer,data,var_strides,var_shape,var_rank); /// Wait for sending to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { @@ -197,8 +199,8 @@ void HaloExchange::execute(DATA_TYPE field[], const size_t var_strides[], const } } -template -void HaloExchange::pack_send_buffer( const DATA_TYPE field[], +template +void HaloExchange::pack_send_buffer( const DATA_TYPE field, const size_t var_strides[], const size_t var_shape[], size_t var_rank, @@ -371,9 +373,11 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf template void HaloExchange::execute( DATA_TYPE field[], size_t nb_vars ) const { - size_t strides[] = {1}; - size_t shape[] = {nb_vars}; - execute( field, strides, shape, 1); + throw eckit::AssertionFailed("Call not supported"); + +// size_t strides[] = {1}; +// size_t shape[] = {nb_vars}; +// execute( field, strides, shape, 1); } @@ -411,7 +415,7 @@ void HaloExchange::execute( array::ArrayView& field ) const if( true ){ std::vector varstrides, varshape; var_info( field, varstrides, varshape ); - execute( field.data(), varstrides.data(), varshape.data(), varstrides.size() ); + execute( field, varstrides.data(), varshape.data(), varstrides.size() ); } else { diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 4cdd220df..a57b2fcc8 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -91,19 +91,19 @@ CASE("test_haloexchange") { SECTION( "test_rank0" ) { - size_t strides[] = {1}; - size_t shape[] = {1}; - f.halo_exchange.execute(f.gidx.data(),strides,shape,1); - - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; - EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } - case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; - EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } - case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; - EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } - } +// size_t strides[] = {1}; +// size_t shape[] = {1}; +// f.halo_exchange.execute(f.gidx.data(),strides,shape,1); + +// switch( parallel::mpi::comm().rank() ) +// { +// case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; +// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } +// case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; +// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } +// case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; +// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } +// } } SECTION( "test_rank1" ) @@ -117,7 +117,7 @@ CASE("test_haloexchange") { size_t strides[] = {1}; size_t shape[] = {2}; - f.halo_exchange.execute(arrv.data(),strides,shape,1); + f.halo_exchange.execute(arrv,strides,shape,1); switch( parallel::mpi::comm().rank() ) { @@ -141,7 +141,7 @@ CASE("test_haloexchange") { size_t strides[] = {2}; size_t shape[] = {1}; - f.halo_exchange.execute(&arrv(0,0),strides,shape,1); + f.halo_exchange.execute(arrv,strides,shape,1); switch( parallel::mpi::comm().rank() ) { @@ -156,26 +156,26 @@ CASE("test_haloexchange") { SECTION( "test_rank1_strided_v2" ) { - array::ArrayT arr(f.N,2); - array::ArrayView arrv = array::make_view(arr); - for( int j=0; j arr(f.N,2); +// array::ArrayView arrv = array::make_view(arr); +// for( int j=0; j arr(f.N,3,2); - array::ArrayView arrv = array::make_view(arr); - for( int p=0; p arr(f.N,3,2); +// array::ArrayView arrv = array::make_view(arr); +// for( int p=0; p arr(f.N,3,2); - array::ArrayView arrv = array::make_view(arr); - for( int p=0; p arr(f.N,3,2); +// array::ArrayView arrv = array::make_view(arr); +// for( int p=0; p Date: Thu, 26 Oct 2017 15:51:43 +0200 Subject: [PATCH 054/355] pass tp pack --- src/atlas/parallel/HaloExchange.h | 36 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 1ed000ac5..cee672e31 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -69,16 +69,16 @@ class HaloExchange: public eckit::Owned { size_t index(size_t i, size_t j, size_t ni, size_t nj) const { return( i + ni*j ); } - template< typename DATA_TYPE> - void pack_send_buffer( const DATA_TYPE field[], + template< typename DATA_TYPE, int RANK> + void pack_send_buffer( const array::ArrayView& field, const size_t var_strides[], const size_t var_shape[], size_t var_rank, array::SVector& send_buffer ) const; - template< typename DATA_TYPE> + template< typename DATA_TYPE, int RANK> void unpack_recv_buffer(const array::SVector& recv_buffer, - DATA_TYPE field[], + array::ArrayView& field, const size_t var_strides[], const size_t var_shape[], size_t var_rank ) const; @@ -126,8 +126,6 @@ void HaloExchange::execute(array::ArrayView& field, const size_ int send_size = sendcnt_ * var_size; int recv_size = recvcnt_ * var_size; - DATA_TYPE * data = field.data(); - array::SVector send_buffer(send_size); array::SVector recv_buffer(recv_size); std::vector send_displs(nproc ); @@ -158,7 +156,7 @@ void HaloExchange::execute(array::ArrayView& field, const size_ } /// Pack - pack_send_buffer(data,var_strides,var_shape,var_rank,send_buffer); + pack_send_buffer(field,var_strides,var_shape,var_rank,send_buffer); /// Send ATLAS_TRACE_MPI( ISEND ) { @@ -185,7 +183,7 @@ void HaloExchange::execute(array::ArrayView& field, const size_ } /// Unpack - unpack_recv_buffer(recv_buffer,data,var_strides,var_shape,var_rank); + unpack_recv_buffer(recv_buffer,field,var_strides,var_shape,var_rank); /// Wait for sending to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { @@ -200,7 +198,7 @@ void HaloExchange::execute(array::ArrayView& field, const size_ } template -void HaloExchange::pack_send_buffer( const DATA_TYPE field, +void HaloExchange::pack_send_buffer( const array::ArrayView& field, const size_t var_strides[], const size_t var_shape[], size_t var_rank, @@ -217,7 +215,7 @@ void HaloExchange::pack_send_buffer( const DATA_TYPE field, { const size_t pp = send_stride*sendmap_[p]; for( size_t i=0; i +template void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buffer, - DATA_TYPE field[], + array::ArrayView& field, const size_t var_strides[], const size_t var_shape[], size_t var_rank ) const @@ -297,7 +295,7 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf for( size_t i=0; i& recv_buf for( size_t j=0; j& recv_buf for( size_t k=0; k& recv_buf for( size_t l=0; l Date: Thu, 26 Oct 2017 16:10:21 +0200 Subject: [PATCH 055/355] add an on device --- src/atlas/functionspace/NodeColumns.cc | 43 ++++++++++++++------------ src/atlas/functionspace/NodeColumns.h | 8 ++--- src/atlas/parallel/HaloExchange.h | 9 ++++++ 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index cf3cd37ce..5aba6fce1 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -329,45 +329,48 @@ Field NodeColumns::createField( } namespace { + +template +array::ArrayView get_field_view(const Field& field, bool on_device) +{ + return on_device ? array::make_device_view(field) : array::make_view(field); +} + template -void dispatch_haloExchange( const Field& field, const parallel::HaloExchange& halo_exchange ) +void dispatch_haloExchange( const Field& field, const parallel::HaloExchange& halo_exchange, bool on_device ) { if ( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange.execute( view ); + halo_exchange.execute( get_field_view(field, on_device) ); } else if( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange.execute( view ); + halo_exchange.execute( get_field_view(field, on_device) ); } else if( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange.execute( view ); + halo_exchange.execute( get_field_view(field, on_device) ); } else if( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange.execute( view ); + halo_exchange.execute( get_field_view(field, on_device) ); } else throw eckit::Exception("datatype not supported",Here()); } } -void NodeColumns::haloExchange( FieldSet& fieldset ) const +void NodeColumns::haloExchange( FieldSet& fieldset, bool on_device ) const { for( size_t f=0; f(field,halo_exchange()); + dispatch_haloExchange<1>(field,halo_exchange(), on_device); break; case 2: - dispatch_haloExchange<2>(field,halo_exchange()); + dispatch_haloExchange<2>(field,halo_exchange(), on_device); break; case 3: - dispatch_haloExchange<3>(field,halo_exchange()); + dispatch_haloExchange<3>(field,halo_exchange(), on_device); break; case 4: - dispatch_haloExchange<4>(field,halo_exchange()); + dispatch_haloExchange<4>(field,halo_exchange(), on_device); break; default: throw eckit::Exception("Rank not supported", Here()); @@ -376,11 +379,11 @@ void NodeColumns::haloExchange( FieldSet& fieldset ) const } } -void NodeColumns::haloExchange( Field& field ) const +void NodeColumns::haloExchange( Field& field, bool on_device ) const { FieldSet fieldset; fieldset.add(field); - haloExchange(fieldset); + haloExchange(fieldset, on_device); } const parallel::HaloExchange& NodeColumns::halo_exchange() const { @@ -2152,12 +2155,12 @@ const mesh::Halo& NodeColumns::halo() const { return functionspace_->halo(); } -void NodeColumns::haloExchange( FieldSet& fieldset ) const { - functionspace_->haloExchange(fieldset); +void NodeColumns::haloExchange( FieldSet& fieldset, bool on_device ) const { + functionspace_->haloExchange(fieldset, on_device); } -void NodeColumns::haloExchange( Field& field ) const { - functionspace_->haloExchange(field); +void NodeColumns::haloExchange( Field& field, bool on_device ) const { + functionspace_->haloExchange(field, on_device); } const parallel::HaloExchange& NodeColumns::halo_exchange() const { diff --git a/src/atlas/functionspace/NodeColumns.h b/src/atlas/functionspace/NodeColumns.h index bd0841570..412fc2876 100644 --- a/src/atlas/functionspace/NodeColumns.h +++ b/src/atlas/functionspace/NodeColumns.h @@ -79,8 +79,8 @@ class NodeColumns : public FunctionSpaceImpl const mesh::Halo& halo() const { return halo_; } - void haloExchange( FieldSet& ) const; - void haloExchange( Field& ) const; + void haloExchange( FieldSet&, bool on_device = false ) const; + void haloExchange( Field&, bool on_device = false ) const; const parallel::HaloExchange& halo_exchange() const; void gather( const FieldSet&, FieldSet& ) const; @@ -450,8 +450,8 @@ class NodeColumns : public FunctionSpace const mesh::Halo& halo() const; - void haloExchange( FieldSet& ) const; - void haloExchange( Field& ) const; + void haloExchange( FieldSet&, bool on_device = false ) const; + void haloExchange( Field&, bool on_device = false ) const; const parallel::HaloExchange& halo_exchange() const; void gather( const FieldSet&, FieldSet& ) const; diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index cee672e31..00aeb7a3d 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -57,6 +57,10 @@ class HaloExchange: public eckit::Owned { template void execute( array::ArrayView& field ) const; + template + void execute( array::ArrayView&& field ) const; + + private: // methods void create_mappings( std::vector& send_map, std::vector& recv_map, size_t nb_vars ) const; @@ -406,6 +410,11 @@ void HaloExchange::var_info( const array::ArrayView& arr, } } +template +void HaloExchange::execute( array::ArrayView&& field ) const +{ + execute(field); +} template void HaloExchange::execute( array::ArrayView& field ) const { From eb3a95e7b77ee687aa25d30bcee40125b5be4960 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 16:16:55 +0200 Subject: [PATCH 056/355] adding tests --- src/tests/array/test_svector.cc | 78 ++++++++++++++++++ src/tests/array/test_svector_kernel.cu | 105 +++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 src/tests/array/test_svector.cc create mode 100644 src/tests/array/test_svector_kernel.cu diff --git a/src/tests/array/test_svector.cc b/src/tests/array/test_svector.cc new file mode 100644 index 000000000..dd99bc4d9 --- /dev/null +++ b/src/tests/array/test_svector.cc @@ -0,0 +1,78 @@ +/* + * (C) Copyright 1996-2016 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 "atlas/library/config.h" +#include "tests/AtlasTestEnvironment.h" +#include "eckit/testing/Test.h" +#include "atlas/array/SVector.h" + +using namespace atlas::array; +using namespace eckit::testing; + +namespace atlas { +namespace test { + +CASE( "test_svector" ) +{ + SVector list_ints(2); + + list_ints[0] = 3; + list_ints[1] = 4; + + EXPECT( list_ints[0] == 3 ); + EXPECT( list_ints[1] == 4 ); + + EXPECT( list_ints.size() == 2); + + list_ints[0]++; + list_ints[1]++; + + EXPECT( list_ints[0] == 4); + EXPECT( list_ints[1] == 5); +} + +CASE( "test_svector_resize" ) +{ + SVector list_ints(2); + + list_ints[0] = 3; + list_ints[1] = 4; + + EXPECT( list_ints[0] == 3 ); + EXPECT( list_ints[1] == 4 ); + + EXPECT( list_ints.size()== 2); + + list_ints.resize(5); + + EXPECT( list_ints.size()== 5); + + list_ints[3] = 5; + list_ints[4] = 6; + + list_ints[3]++; + list_ints[4]++; + + + EXPECT( list_ints[0] == 3 ); + EXPECT( list_ints[1] == 4 ); + EXPECT( list_ints[3] == 6 ); + EXPECT( list_ints[4] == 7 ); + +} + +} // namespace test +} // namespace atlas + +int main(int argc, char **argv) { + atlas::test::AtlasTestEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} + diff --git a/src/tests/array/test_svector_kernel.cu b/src/tests/array/test_svector_kernel.cu new file mode 100644 index 000000000..8c207f930 --- /dev/null +++ b/src/tests/array/test_svector_kernel.cu @@ -0,0 +1,105 @@ +/* + * (C) Copyright 1996-2016 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. + */ + +#define BOOST_TEST_MODULE TestSVectorKernel +#include +#include "ecbuild/boost_test_framework.h" +#include "atlas/array/SVector.h" + +using namespace atlas::array; + +namespace atlas { +namespace test { + +__global__ +void kernel_exe(array::SVector list_ints, int offset, bool* result ) +{ + *result = *result && (list_ints[offset] == 3); + *result = *result && (list_ints[offset+1] == 4); + + + list_ints[offset]++; + list_ints[offset+1]++; +} + +BOOST_AUTO_TEST_CASE( test_svector ) +{ + SVector list_ints(2); + + list_ints[0] = 3; + list_ints[1] = 4; + + BOOST_CHECK_EQUAL( list_ints[0] , 3 ); + BOOST_CHECK_EQUAL( list_ints[1] , 4 ); + + BOOST_CHECK_EQUAL( list_ints.size(), 2); + + bool *result; + cudaError_t err = cudaMallocManaged(&result, sizeof(bool)); + + if(err != cudaSuccess) + throw eckit::AssertionFailed("failed to allocate GPU memory"); + + *result=true; + kernel_exe<<<1,1>>>(list_ints, 0, result); + cudaDeviceSynchronize(); + + err = cudaGetLastError(); + if(err != cudaSuccess) + throw eckit::AssertionFailed("failed to execute kernel"); + + BOOST_CHECK( *result ); + BOOST_CHECK_EQUAL( list_ints[0], 4); + BOOST_CHECK_EQUAL( list_ints[1], 5); + +} + +BOOST_AUTO_TEST_CASE( test_svector_resize ) +{ + SVector list_ints(2); + + list_ints[0] = 3; + list_ints[1] = 4; + + BOOST_CHECK_EQUAL( list_ints[0] , 3 ); + BOOST_CHECK_EQUAL( list_ints[1] , 4 ); + + BOOST_CHECK_EQUAL( list_ints.size(), 2); + + list_ints.resize(5); + + BOOST_CHECK_EQUAL( list_ints.size(), 5); + + bool *result; + cudaError_t err = cudaMallocManaged(&result, sizeof(bool)); + + if(err != cudaSuccess) + throw eckit::AssertionFailed("failed to allocate GPU memory"); + + *result=true; + + list_ints[3] = 3; + list_ints[4] = 4; + + kernel_exe<<<1,1>>>(list_ints, 3, result); + cudaDeviceSynchronize(); + + err = cudaGetLastError(); + if(err != cudaSuccess) + throw eckit::AssertionFailed("failed to execute kernel"); + + BOOST_CHECK( *result ); + BOOST_CHECK_EQUAL( list_ints[3], 4); + BOOST_CHECK_EQUAL( list_ints[4], 5); + +} + +} +} From 239046ac8fe8d4d74c76a9bf5354a256a031cdd0 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 16:23:27 +0200 Subject: [PATCH 057/355] add missing SVector --- src/atlas/array/SVector.h | 113 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/atlas/array/SVector.h diff --git a/src/atlas/array/SVector.h b/src/atlas/array/SVector.h new file mode 100644 index 000000000..ce10f5306 --- /dev/null +++ b/src/atlas/array/SVector.h @@ -0,0 +1,113 @@ +/* +* (C) Copyright 1996-2016 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 +#include + +#include "atlas/library/config.h" + +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA +#include +#endif + +#include "atlas/runtime/ErrorHandling.h" +#include "atlas/library/config.h" + +namespace atlas { +namespace array { + +//------------------------------------------------------------------------------ + +template +class SVector { +public: + SVector() : data_(nullptr), size_(0) {} + SVector(SVector const & other) : data_(other.data_), size_(other.size_){} + + SVector(size_t N) : size_(N) { +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + cudaError_t err = cudaMallocManaged(&data_, N * sizeof(T)); + if(err != cudaSuccess) + throw eckit::AssertionFailed("failed to allocate GPU memory"); +#else + data_ = (T*)malloc(N*sizeof(T)); +#endif + } + ~SVector(){ + delete_managedmem(data_); + } + + void delete_managedmem(T* data) { + if( data ) { +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + cudaError_t err = cudaDeviceSynchronize(); + if(err != cudaSuccess) + throw eckit::AssertionFailed("failed to synchronize memory"); + + err = cudaFree(data); + if(err != cudaSuccess) + throw eckit::AssertionFailed("failed to free GPU memory"); +#else + free(data_); +#endif + data_ = NULL; + } + } + T* data() { return data_; } + + ATLAS_HOST_DEVICE + T& operator()(const size_t idx) { return data_[idx]; } + ATLAS_HOST_DEVICE + T const& operator()(const size_t idx) const { return data_[idx]; } + + ATLAS_HOST_DEVICE + T& operator[](const size_t idx) { return data_[idx]; } + ATLAS_HOST_DEVICE + T const& operator[](const size_t idx) const { return data_[idx]; } + + ATLAS_HOST_DEVICE + size_t size() const { return size_; } + + void resize_impl(size_t N) { + assert(N >= size_); + if (N == size_) return; + + T* d_; +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + cudaError_t err = cudaMallocManaged(&d_, sizeof(T)*N ); + if(err != cudaSuccess) + throw eckit::AssertionFailed("failed to allocate GPU memory"); + +#else + d_ = (T*)malloc(sizeof(T)*N ); +#endif + for(unsigned int c=0; c < size_; ++c) { + d_[c] = data_[c]; + } + delete_managedmem(data_); + data_ = d_; + } + + void resize(size_t N) { + resize_impl(N); + size_ = N; + } + +private: + T* data_; + size_t size_; +}; + +//------------------------------------------------------------------------------ + +} // namespace array +} // namespace atlas From 25e55547e8f8c9bc1873e0d59bd2f24620740c02 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 16:30:20 +0200 Subject: [PATCH 058/355] move test to new testing eckit --- src/atlas/parallel/HaloExchange.h | 4 +++ src/tests/array/test_svector_kernel.cu | 38 ++++++++++++++------------ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 00aeb7a3d..9e5fb0c18 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -215,12 +215,16 @@ void HaloExchange::pack_send_buffer( const array::ArrayView& fi switch( var_rank ) { case 1: +#ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA for(int p=0; p < sendcnt_; ++p) { const size_t pp = send_stride*sendmap_[p]; for( size_t i=0; i -#include "ecbuild/boost_test_framework.h" +#include "atlas/library/config.h" +#include "tests/AtlasTestEnvironment.h" +#include "eckit/testing/Test.h" #include "atlas/array/SVector.h" using namespace atlas::array; +using namespace eckit::testing; + namespace atlas { namespace test { @@ -29,17 +31,17 @@ void kernel_exe(array::SVector list_ints, int offset, bool* result ) list_ints[offset+1]++; } -BOOST_AUTO_TEST_CASE( test_svector ) +CASE( "test_svector" ) { SVector list_ints(2); list_ints[0] = 3; list_ints[1] = 4; - BOOST_CHECK_EQUAL( list_ints[0] , 3 ); - BOOST_CHECK_EQUAL( list_ints[1] , 4 ); + EXPECT( list_ints[0] == 3 ); + EXPECT( list_ints[1] == 4 ); - BOOST_CHECK_EQUAL( list_ints.size(), 2); + EXPECT( list_ints.size() == 2); bool *result; cudaError_t err = cudaMallocManaged(&result, sizeof(bool)); @@ -55,27 +57,27 @@ BOOST_AUTO_TEST_CASE( test_svector ) if(err != cudaSuccess) throw eckit::AssertionFailed("failed to execute kernel"); - BOOST_CHECK( *result ); - BOOST_CHECK_EQUAL( list_ints[0], 4); - BOOST_CHECK_EQUAL( list_ints[1], 5); + EXPECT( *result ); + EXPECT( list_ints[0] == 4); + EXPECT( list_ints[1] == 5); } -BOOST_AUTO_TEST_CASE( test_svector_resize ) +CASE( "test_svector_resize" ) { SVector list_ints(2); list_ints[0] = 3; list_ints[1] = 4; - BOOST_CHECK_EQUAL( list_ints[0] , 3 ); - BOOST_CHECK_EQUAL( list_ints[1] , 4 ); + EXPECT( list_ints[0] == 3 ); + EXPECT( list_ints[1] == 4 ); - BOOST_CHECK_EQUAL( list_ints.size(), 2); + EXPECT( list_ints.size() == 2); list_ints.resize(5); - BOOST_CHECK_EQUAL( list_ints.size(), 5); + EXPECT( list_ints.size() == 5); bool *result; cudaError_t err = cudaMallocManaged(&result, sizeof(bool)); @@ -95,9 +97,9 @@ BOOST_AUTO_TEST_CASE( test_svector_resize ) if(err != cudaSuccess) throw eckit::AssertionFailed("failed to execute kernel"); - BOOST_CHECK( *result ); - BOOST_CHECK_EQUAL( list_ints[3], 4); - BOOST_CHECK_EQUAL( list_ints[4], 5); + EXPECT( *result ); + EXPECT( list_ints[3] == 4); + EXPECT( list_ints[4] == 5); } From 187b19a7d56b3fa37a2e42bff0fe5262427ac82e Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 17:45:16 +0200 Subject: [PATCH 059/355] fix unittest --- src/tests/util/test_array_kernel.cu | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/tests/util/test_array_kernel.cu b/src/tests/util/test_array_kernel.cu index b802ceec8..2cdc8ce38 100644 --- a/src/tests/util/test_array_kernel.cu +++ b/src/tests/util/test_array_kernel.cu @@ -8,9 +8,8 @@ * does it submit to any jurisdiction. */ -#define BOOST_TEST_MODULE TestArrayKernel #include -#include "ecbuild/boost_test_framework.h" +#include "eckit/testing/Test.h" #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "atlas/runtime/Log.h" @@ -27,7 +26,7 @@ void kernel_ex(ArrayView dv) dv(3, 3, 3) += 1; } -BOOST_AUTO_TEST_CASE( test_array ) +CASE( "test_array" ) { Array* ds = Array::create(4ul, 4ul, 4ul); ArrayView hv = make_host_view(*ds); @@ -51,3 +50,8 @@ BOOST_AUTO_TEST_CASE( test_array ) } } + +int main(int argc, char **argv) { + atlas::test::AtlasTestEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} From 8b692374f0ed48728237a212d1da219861e25bec Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 17:46:19 +0200 Subject: [PATCH 060/355] add small kernel --- src/atlas/parallel/HaloExchange.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 9e5fb0c18..13d325b87 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -81,6 +81,12 @@ class HaloExchange: public eckit::Owned { array::SVector& send_buffer ) const; template< typename DATA_TYPE, int RANK> + void pack_send_cuda( const array::ArrayView& field, + const size_t var_strides[], + const size_t var_shape[], + size_t var_rank, + array::SVector& send_buffer ) const; + template< typename DATA_TYPE, int RANK> void unpack_recv_buffer(const array::SVector& recv_buffer, array::ArrayView& field, const size_t var_strides[], @@ -201,6 +207,29 @@ void HaloExchange::execute(array::ArrayView& field, const size_ } } +#ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA +#ifdef __CUDACC__ +__global__ void pack_kernel() { + +} + +template +void HaloExchange::pack_send_cuda( const array::ArrayView& field, + const size_t var_strides[], + const size_t var_shape[], + size_t var_rank, + array::SVector& send_buffer ) const +{ + const unsigned int block_size_x = 32; + const unsigned int block_size_y = 4; + dim3 threads(block_size_x, block_size_y); + dim3 blocks((sendcnt_+block_size_x-1)/block_size_x, (var_shape[0]+block_size_y-1)/block_size_y); + + pack_kernel<<>>(); +} +#endif +#endif + template void HaloExchange::pack_send_buffer( const array::ArrayView& field, const size_t var_strides[], From f5aed849151502d1de9fdb1734c4f86e06c4f172 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 18:03:26 +0200 Subject: [PATCH 061/355] adapt several .cu unittests to latest unittest framework --- src/tests/array/test_array_kernel.cu | 18 ++++++++++------ src/tests/array/test_svector_kernel.cu | 5 +++++ src/tests/array/test_vector_kernel.cu | 30 +++++++++++++++----------- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/tests/array/test_array_kernel.cu b/src/tests/array/test_array_kernel.cu index b802ceec8..62bcf7412 100644 --- a/src/tests/array/test_array_kernel.cu +++ b/src/tests/array/test_array_kernel.cu @@ -8,29 +8,30 @@ * does it submit to any jurisdiction. */ -#define BOOST_TEST_MODULE TestArrayKernel #include -#include "ecbuild/boost_test_framework.h" +#include "tests/AtlasTestEnvironment.h" +#include "eckit/testing/Test.h" #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "atlas/runtime/Log.h" using namespace atlas::array; +using namespace eckit::testing; namespace atlas { namespace test { template __global__ -void kernel_ex(ArrayView dv) +void kernel_ex(array::ArrayView dv) { dv(3, 3, 3) += 1; } -BOOST_AUTO_TEST_CASE( test_array ) +CASE( "test_array" ) { Array* ds = Array::create(4ul, 4ul, 4ul); - ArrayView hv = make_host_view(*ds); + array::ArrayView hv = make_host_view(*ds); hv(3, 3, 3) = 4.5; ds->cloneToDevice(); @@ -44,10 +45,15 @@ BOOST_AUTO_TEST_CASE( test_array ) ds->cloneFromDevice(); ds->reactivateHostWriteViews(); - BOOST_CHECK_EQUAL( hv(3, 3, 3) , 5.5 ); + EXPECT( hv(3, 3, 3) == 5.5 ); delete ds; } } } + +int main(int argc, char **argv) { + atlas::test::AtlasTestEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} diff --git a/src/tests/array/test_svector_kernel.cu b/src/tests/array/test_svector_kernel.cu index 1ad197a14..489701968 100644 --- a/src/tests/array/test_svector_kernel.cu +++ b/src/tests/array/test_svector_kernel.cu @@ -105,3 +105,8 @@ CASE( "test_svector_resize" ) } } + +int main(int argc, char **argv) { + atlas::test::AtlasTestEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} diff --git a/src/tests/array/test_vector_kernel.cu b/src/tests/array/test_vector_kernel.cu index d963be2a5..c0686d0e5 100644 --- a/src/tests/array/test_vector_kernel.cu +++ b/src/tests/array/test_vector_kernel.cu @@ -8,13 +8,14 @@ * does it submit to any jurisdiction. */ -#define BOOST_TEST_MODULE TestArrayKernel #include -#include "ecbuild/boost_test_framework.h" +#include "tests/AtlasTestEnvironment.h" +#include "eckit/testing/Test.h" #include "atlas/array/Vector.h" #include "atlas/array/gridtools/GPUClonable.h" using namespace atlas::array; +using namespace eckit::testing; namespace atlas { namespace test { @@ -42,7 +43,7 @@ void kernel_ex(VectorView* list_ints ) } } -BOOST_AUTO_TEST_CASE( test_resize ) +CASE( "test_resize" ) { Vector list_ints(2); @@ -50,24 +51,24 @@ BOOST_AUTO_TEST_CASE( test_resize ) list_ints_h[0] = new int_gpu(3); list_ints_h[1] = new int_gpu(4); - BOOST_CHECK_EQUAL( list_ints_h[0]->val_ , 3 ); - BOOST_CHECK_EQUAL( list_ints_h[1]->val_ , 4 ); + EXPECT( list_ints_h[0]->val_ == 3 ); + EXPECT( list_ints_h[1]->val_ == 4 ); list_ints.resize(6); - BOOST_CHECK_EQUAL( list_ints_h.is_valid(list_ints) , false ); + EXPECT( list_ints_h.is_valid(list_ints) == false ); VectorView list_ints_h2 = make_host_vector_view(list_ints); - BOOST_CHECK_EQUAL( list_ints_h2[0]->val_ , 3 ); - BOOST_CHECK_EQUAL( list_ints_h2[1]->val_ , 4 ); - BOOST_CHECK_EQUAL( list_ints_h2.size() , 6 ); + EXPECT( list_ints_h2[0]->val_ == 3 ); + EXPECT( list_ints_h2[1]->val_ == 4 ); + EXPECT( list_ints_h2.size() == 6 ); } -BOOST_AUTO_TEST_CASE( test_vector_kernel ) +CASE( "test_vector_kernel" ) { Vector list_ints(4); @@ -91,11 +92,16 @@ BOOST_AUTO_TEST_CASE( test_vector_kernel ) if( cudaPeekAtLastError() != cudaSuccess) std::cout << "ERROR " << std::endl; list_ints.cloneFromDevice(); - BOOST_CHECK_EQUAL( list_ints_h[0]->val_ , 8 ); + EXPECT( list_ints_h[0]->val_ == 8 ); - BOOST_CHECK_THROW( list_ints.resize(6), eckit::AssertionFailed ); + EXPECT_THROWS_AS( list_ints.resize(6), eckit::AssertionFailed ); } } } + +int main(int argc, char **argv) { + atlas::test::AtlasTestEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} From 932bc152635ca9e1e84df62ed7f5464d22192b68 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 18:11:48 +0200 Subject: [PATCH 062/355] compile HaloExchange with nvcc if required --- src/atlas/CMakeLists.txt | 10 +++++++++- src/atlas/parallel/HaloExchange.cu | 11 +++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/atlas/parallel/HaloExchange.cu diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index d41ece1ca..ae2e6e52c 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -430,7 +430,6 @@ parallel/Checksum.cc parallel/Checksum.h parallel/GatherScatter.cc parallel/GatherScatter.h -parallel/HaloExchange.cc parallel/HaloExchange.h parallel/mpi/Buffer.h runtime/ErrorHandling.cc @@ -449,6 +448,14 @@ util/Rotation.h util/detail/BlackMagic.h ) +if(NOT ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA) +list( APPEND atlas_util_srcs +parallel/HaloExchange.cc +) +endif() + + + list( APPEND atlas_internals_srcs mesh/detail/AccumulateFacets.h mesh/detail/AccumulateFacets.cc @@ -552,6 +559,7 @@ if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) array/gridtools/GridToolsArrayView.cu array/gridtools/GridToolsIndexView.cu mesh/Connectivity.cu + parallel/HaloExchange.cu ) endif() diff --git a/src/atlas/parallel/HaloExchange.cu b/src/atlas/parallel/HaloExchange.cu new file mode 100644 index 000000000..2a17dc967 --- /dev/null +++ b/src/atlas/parallel/HaloExchange.cu @@ -0,0 +1,11 @@ +/* + * (C) Copyright 1996-2017 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 "HaloExchange.cc" From 9ba8761d1c4bdc6abcb8aa23ce8e862e7befe91e Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 26 Oct 2017 18:25:46 +0200 Subject: [PATCH 063/355] add a copy ctr test --- src/tests/array/test_array.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 64c7127f1..b4c7cd52f 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -205,6 +205,20 @@ CASE("test_resize_throw") { delete ds; } +CASE("test_copy_ctr") { + Array* ds = Array::create(3, 2); + atlas::array::ArrayView hv = make_host_view(*ds); + hv(2, 1) = 4; + hv(1, 1) = 7; + + atlas::array::ArrayView hv2(hv); + + EXPECT(hv2(2, 1) == 4); + EXPECT(hv2(1, 1) == 7); + + delete ds; +} + CASE("test_resize") { { From 0d393351f4a1ccc636f880ce2903bf1a5361ae73 Mon Sep 17 00:00:00 2001 From: cosunae Date: Thu, 26 Oct 2017 19:28:02 +0200 Subject: [PATCH 064/355] fix bug in nvcc --- src/atlas/runtime/trace/StopWatch.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atlas/runtime/trace/StopWatch.h b/src/atlas/runtime/trace/StopWatch.h index 9b7c58c6b..2522f973e 100644 --- a/src/atlas/runtime/trace/StopWatch.h +++ b/src/atlas/runtime/trace/StopWatch.h @@ -27,14 +27,14 @@ class StopWatch { void reset(); double elapsed() const; private: - std::chrono::duration elapsed_{0}; + std::chrono::duration elapsed_; std::chrono::steady_clock::time_point start_; bool running_{false}; }; //----------------------------------------------------------------------------------------------------------- -inline StopWatch::StopWatch() { +inline StopWatch::StopWatch() : elapsed_(0) { } inline StopWatch::StopWatch(double elapsed) : From 49cb8033de648271bfdb221ae8e3093b4d8d9532 Mon Sep 17 00:00:00 2001 From: cosunae Date: Thu, 26 Oct 2017 20:28:29 +0200 Subject: [PATCH 065/355] fix a device free --- src/atlas/array/SVector.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/atlas/array/SVector.h b/src/atlas/array/SVector.h index ce10f5306..3c3f0dde6 100644 --- a/src/atlas/array/SVector.h +++ b/src/atlas/array/SVector.h @@ -31,6 +31,8 @@ template class SVector { public: SVector() : data_(nullptr), size_(0) {} + + ATLAS_HOST_DEVICE SVector(SVector const & other) : data_(other.data_), size_(other.size_){} SVector(size_t N) : size_(N) { @@ -46,7 +48,7 @@ class SVector { delete_managedmem(data_); } - void delete_managedmem(T* data) { + void delete_managedmem(T*& data) { if( data ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA cudaError_t err = cudaDeviceSynchronize(); @@ -54,8 +56,11 @@ class SVector { throw eckit::AssertionFailed("failed to synchronize memory"); err = cudaFree(data); +// The following throws an invalid device memory +/* if(err != cudaSuccess) throw eckit::AssertionFailed("failed to free GPU memory"); +*/ #else free(data_); #endif From f27b3e8f43171e7d080ef01f060a7851f554bea7 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 27 Oct 2017 09:26:55 +0200 Subject: [PATCH 066/355] adding test to array --- src/tests/array/test_array.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index b4c7cd52f..18d582781 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -219,6 +219,26 @@ CASE("test_copy_ctr") { delete ds; } +#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +CASE("test_copy_gt_ctr") { + Array* ds = Array::create(3, 2); + atlas::array::ArrayView hv = make_host_view(*ds); + hv(2, 1) = 4; + hv(1, 1) = 7; + + atlas::array::ArrayView hv2(hv); + + EXPECT(hv2(2, 1) == 4); + EXPECT(hv2(1, 1) == 7); + + auto dims = hv.data_view().storage_info().dims(); + EXPECT(dims[0] == 3); + EXPECT(dims[1] == 2); + + delete ds; +} +#endif + CASE("test_resize") { { From 64f59f37db962f5e961147dff889fbf2341fa32f Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 27 Oct 2017 11:20:46 +0200 Subject: [PATCH 067/355] add ATLAS_HOST_DEVICE --- src/atlas/array/SVector.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/atlas/array/SVector.h b/src/atlas/array/SVector.h index ce10f5306..f7e63e098 100644 --- a/src/atlas/array/SVector.h +++ b/src/atlas/array/SVector.h @@ -31,6 +31,8 @@ template class SVector { public: SVector() : data_(nullptr), size_(0) {} + + ATLAS_HOST_DEVICE SVector(SVector const & other) : data_(other.data_), size_(other.size_){} SVector(size_t N) : size_(N) { From f9f98878b21340af4a520850f3b8e8eab212cd93 Mon Sep 17 00:00:00 2001 From: cosunae Date: Fri, 27 Oct 2017 11:23:41 +0200 Subject: [PATCH 068/355] add host device --- src/atlas/array/gridtools/GridToolsArrayView.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 6dcf209b4..9c47c13a5 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -33,6 +33,7 @@ template< typename Value, int Rank > class ArrayView { public: + ATLAS_HOST_DEVICE ArrayView( const ArrayView& other ); ArrayView(data_view_t data_view, const Array& array); value_type* data() { return gt_data_view_.data(); } @@ -76,7 +77,7 @@ template< typename Value, int Rank > class ArrayView { return Slicer(*this).apply(i); } - + ATLAS_HOST_DEVICE data_view_t& data_view() { return gt_data_view_;} size_t rank() const { return Rank; } From 112cbb039108d156af6ea9204e6e456839a8b561 Mon Sep 17 00:00:00 2001 From: cosunae Date: Fri, 27 Oct 2017 12:43:44 +0200 Subject: [PATCH 069/355] extent unittest --- src/tests/array/test_array_kernel.cu | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/tests/array/test_array_kernel.cu b/src/tests/array/test_array_kernel.cu index 62bcf7412..b26c3b2da 100644 --- a/src/tests/array/test_array_kernel.cu +++ b/src/tests/array/test_array_kernel.cu @@ -23,21 +23,25 @@ namespace test { template __global__ -void kernel_ex(array::ArrayView dv) +void kernel_ex(ArrayView dv) { - dv(3, 3, 3) += 1; + dv(3, 3, 3) += dv.data_view().template length<0>() * dv.data_view().template length<1>() * dv.data_view().template length<2>(); } CASE( "test_array" ) { - Array* ds = Array::create(4ul, 4ul, 4ul); - array::ArrayView hv = make_host_view(*ds); + constexpr unsigned int dx = 5; + constexpr unsigned int dy = 6; + constexpr unsigned int dz = 7; + + Array* ds = Array::create(dx, dy, dz); + ArrayView hv = make_host_view(*ds); hv(3, 3, 3) = 4.5; ds->cloneToDevice(); auto cv = make_device_view(*ds); - + kernel_ex<<<1,1>>>(cv); cudaDeviceSynchronize(); @@ -45,7 +49,7 @@ CASE( "test_array" ) ds->cloneFromDevice(); ds->reactivateHostWriteViews(); - EXPECT( hv(3, 3, 3) == 5.5 ); + EXPECT( hv(3, 3, 3) == 4.5 + dx*dy*dz ); delete ds; } From 131d5e74b69b612d8b2a7f97f63a19e00cd14793 Mon Sep 17 00:00:00 2001 From: cosunae Date: Fri, 27 Oct 2017 12:46:11 +0200 Subject: [PATCH 070/355] resolve namespace ambiguity --- src/tests/array/test_array_kernel.cu | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/array/test_array_kernel.cu b/src/tests/array/test_array_kernel.cu index b26c3b2da..c63953d9b 100644 --- a/src/tests/array/test_array_kernel.cu +++ b/src/tests/array/test_array_kernel.cu @@ -23,7 +23,7 @@ namespace test { template __global__ -void kernel_ex(ArrayView dv) +void kernel_ex(array::ArrayView dv) { dv(3, 3, 3) += dv.data_view().template length<0>() * dv.data_view().template length<1>() * dv.data_view().template length<2>(); } @@ -35,7 +35,7 @@ CASE( "test_array" ) constexpr unsigned int dz = 7; Array* ds = Array::create(dx, dy, dz); - ArrayView hv = make_host_view(*ds); + array::ArrayView hv = make_host_view(*ds); hv(3, 3, 3) = 4.5; ds->cloneToDevice(); From 7fed63e70f69662ac5a4079d71304fd5c89823e8 Mon Sep 17 00:00:00 2001 From: cosunae Date: Fri, 27 Oct 2017 12:57:24 +0200 Subject: [PATCH 071/355] adding more comprehensive test for array kernel --- src/tests/array/test_array_kernel.cu | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/tests/array/test_array_kernel.cu b/src/tests/array/test_array_kernel.cu index c63953d9b..da836aa9a 100644 --- a/src/tests/array/test_array_kernel.cu +++ b/src/tests/array/test_array_kernel.cu @@ -28,6 +28,19 @@ void kernel_ex(array::ArrayView dv) dv(3, 3, 3) += dv.data_view().template length<0>() * dv.data_view().template length<1>() * dv.data_view().template length<2>(); } +template +__global__ +void loop_kernel_ex(array::ArrayView dv) +{ + for(int i=0; i < dv.data_view().template length<0>(); i++) { + for(int j=0; j < dv.data_view().template length<1>(); j++) { + for(int k=0; k < dv.data_view().template length<2>(); k++) { + dv(i,j,k) += i*10+j*100+k*1000; + } + } + } +} + CASE( "test_array" ) { constexpr unsigned int dx = 5; @@ -54,6 +67,43 @@ CASE( "test_array" ) delete ds; } +CASE( "test_array_loop" ) +{ + constexpr unsigned int dx = 5; + constexpr unsigned int dy = 6; + constexpr unsigned int dz = 7; + + Array* ds = Array::create(dx, dy, dz); + array::ArrayView hv = make_host_view(*ds); + for(int i=0; i < dx; i++) { + for(int j=0; j < dy; j++) { + for(int k=0; k < dz; k++) { + hv(i,j,k) = 0; + } + } + } + + ds->cloneToDevice(); + + auto cv = make_device_view(*ds); + + loop_kernel_ex<<<1,1>>>(cv); + + cudaDeviceSynchronize(); + + ds->cloneFromDevice(); + ds->reactivateHostWriteViews(); + + for(int i=0; i < dx; i++) { + for(int j=0; j < dy; j++) { + for(int k=0; k < dz; k++) { + EXPECT( hv(i,j,k) == i*10+j*100+k*1000 ); + } + } + } + + delete ds; +} } } From 7608919537e39b53bf1e355d2ff90fc72cf3a61a Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 27 Oct 2017 19:21:47 +0200 Subject: [PATCH 072/355] adding const getter --- src/atlas/array/gridtools/GridToolsArrayView.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 6dcf209b4..243471e89 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -78,6 +78,7 @@ template< typename Value, int Rank > class ArrayView { data_view_t& data_view() { return gt_data_view_;} + data_view_t const & data_view() const { return gt_data_view_;} size_t rank() const { return Rank; } size_t size() const { return size_; } From 94f95a4c6ef46e895d614aaad571e45c5a2e353f Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 27 Oct 2017 19:34:22 +0200 Subject: [PATCH 073/355] adding one 1D test and removing non working tests --- src/tests/parallel/test_haloexchange.cc | 88 ++++++++++++++++--------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index a57b2fcc8..7a5415eae 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -106,31 +106,30 @@ CASE("test_haloexchange") { // } } - SECTION( "test_rank1" ) + SECTION( "test_rank0_arrview" ) { - array::ArrayT arr(f.N,2); - array::ArrayView arrv = array::make_view(arr); + size_t strides[] = {1}; + size_t shape[] = {1}; + array::ArrayT arr(f.N); + array::ArrayView arrv = array::make_view(arr); for( int j=0; j arr(f.N,2); array::ArrayView arrv = array::make_view(arr); @@ -139,21 +138,45 @@ CASE("test_haloexchange") { arrv(j,1) = (size_t(f.part[j]) != parallel::mpi::comm().rank() ? 0 : f.gidx[j]*100); } - size_t strides[] = {2}; - size_t shape[] = {1}; + size_t strides[] = {1}; + size_t shape[] = {2}; f.halo_exchange.execute(arrv,strides,shape,1); switch( parallel::mpi::comm().rank() ) { - case 0: { POD arr_c[] = { 90,0, 10,100, 20,200, 30,300, 40,0 }; + case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 1: { POD arr_c[] = { 30,0, 40,400, 50,500, 60,600, 70,0, 80,0}; + case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 2: { POD arr_c[] = { 50,0, 60,0, 70,700, 80,800, 90,900, 10,0, 20,0}; + case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } } } +// SECTION( "test_rank1_strided_v1" ) +// { +// array::ArrayT arr(f.N,2); +// array::ArrayView arrv = array::make_view(arr); +// for( int j=0; j arr(f.N,2); @@ -401,21 +424,22 @@ CASE("test_haloexchange") { SECTION( "test_rank0_ArrayView" ) { - array::ArraySpec spec(array::make_shape(1), array::make_strides(f.N)); - eckit::SharedPtr arr ( array::Array::wrap(f.gidx.data(), spec ) ); - array::ArrayView arrv = array::make_view(*arr); + //TODO FIRST +// array::ArraySpec spec(array::make_shape(1), array::make_strides(f.N)); +// eckit::SharedPtr arr ( array::Array::wrap(f.gidx.data(), spec ) ); +// array::ArrayView arrv = array::make_view(*arr); - f.halo_exchange.execute(arrv); +// f.halo_exchange.execute(arrv); - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; - EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } - case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; - EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } - case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; - EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } - } +// switch( parallel::mpi::comm().rank() ) +// { +// case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; +// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } +// case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; +// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } +// case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; +// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } +// } } From 55d81c4501567ca58e278ff869911764cfbe7b7d Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sat, 28 Oct 2017 01:21:10 +0200 Subject: [PATCH 074/355] working version of pack --- src/atlas/parallel/HaloExchange.h | 153 +++++++++++++++--------- src/tests/parallel/test_haloexchange.cc | 104 ++++++++-------- 2 files changed, 150 insertions(+), 107 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 13d325b87..0b4052d10 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -209,8 +209,18 @@ void HaloExchange::execute(array::ArrayView& field, const size_ #ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA #ifdef __CUDACC__ -__global__ void pack_kernel() { +template +__global__ void pack_kernel(int sendcnt, array::SVector sendmap, + const array::ArrayView field, array::SVector send_buffer) { + + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + + if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; + const size_t buff_idx = field.data_view().template length<1>() * p + i; + + send_buffer[buff_idx] = field.data(p, i); } template @@ -225,11 +235,89 @@ void HaloExchange::pack_send_cuda( const array::ArrayView& fiel dim3 threads(block_size_x, block_size_y); dim3 blocks((sendcnt_+block_size_x-1)/block_size_x, (var_shape[0]+block_size_y-1)/block_size_y); - pack_kernel<<>>(); + pack_kernel<<>>(sendcnt_, sendmap_, field, send_buffer); } #endif #endif +template +struct halo_packer; + +template<> +struct halo_packer<1> +{ + template + static void pack(const unsigned int sendcnt, array::SVector const & sendmap, + const array::ArrayView& field, array::SVector& send_buffer ) + { + size_t ibuf = 0; + for(int p=0; p < sendcnt; ++p) + { + const size_t pp = sendmap[p]; + send_buffer[ibuf++] = field(pp); + } + } +}; + +template<> +struct halo_packer<2> +{ + template + static void pack(const unsigned int sendcnt, array::SVector const & sendmap, const array::ArrayView& field, array::SVector& send_buffer ) + { + size_t ibuf = 0; + + for(int p=0; p < sendcnt; ++p) + { + const size_t pp = sendmap[p]; + for( size_t i=0; i< field.data_view().template length<1>(); ++i ) { + send_buffer[ibuf++] = field(pp, i); + } + } + } +}; + +template<> +struct halo_packer<3> +{ + template + static void pack(const unsigned int sendcnt, array::SVector const & sendmap, const array::ArrayView& field, array::SVector& send_buffer ) + { + size_t ibuf = 0; + for(int p=0; p < sendcnt; ++p) + { + const size_t pp = sendmap[p]; + for( size_t i=0; i< field.data_view().template length<1>(); ++i ) { + for( size_t j=0; j< field.data_view().template length<2>(); ++j ) { + send_buffer[ibuf++] = field(pp, i,j); + } + } + } + } +}; + +template<> +struct halo_packer<4> +{ + template + static void pack(const unsigned int sendcnt, array::SVector const & sendmap, const array::ArrayView& field, array::SVector& send_buffer ) + { + size_t ibuf = 0; + for(int p=0; p < sendcnt; ++p) + { + const size_t pp = sendmap[p]; + for( size_t i=0; i< field.data_view().template length<1>(); ++i ) { + for( size_t j=0; j< field.data_view().template length<2>(); ++j ) { + for( size_t k=0; k< field.data_view().template length<3>(); ++k ) { + + send_buffer[ibuf++] = field(pp,i,j,k); + } + } + } + } + } +}; + template void HaloExchange::pack_send_buffer( const array::ArrayView& field, const size_t var_strides[], @@ -241,69 +329,24 @@ void HaloExchange::pack_send_buffer( const array::ArrayView& fi size_t ibuf = 0; size_t send_stride = var_strides[0]*var_shape[0]; - switch( var_rank ) + switch( RANK ) { case 1: -#ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - for(int p=0; p < sendcnt_; ++p) - { - const size_t pp = send_stride*sendmap_[p]; - for( size_t i=0; i::pack(sendcnt_, sendmap_, field, send_buffer); #endif + std::cout << parallel::mpi::comm().rank() << " END IF " << std::endl; break; case 2: - for(int p=0; p < sendcnt_; ++p) - { - const size_t pp = send_stride*sendmap_[p]; - for( size_t i=0; i::pack(sendcnt_, sendmap_, field, send_buffer); break; case 3: - for(int p=0; p < sendcnt_; ++p) - { - const size_t pp = send_stride*sendmap_[p]; - for( size_t i=0; i::pack(sendcnt_, sendmap_, field, send_buffer); break; case 4: - for(int p=0; p < sendcnt_; ++p) - { - const size_t pp = send_stride*sendmap_[p]; - for( size_t i=0; i::pack(sendcnt_, sendmap_, field, send_buffer); break; default: NOTIMP; diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 7a5415eae..0c86e07bb 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -256,60 +256,60 @@ CASE("test_haloexchange") { } } - SECTION( "test_rank2_l1" ) - { - array::ArrayT arr(f.N,3,2); - array::ArrayView arrv = array::make_view(arr); - for( int p=0; p arr(f.N,3,2); +// array::ArrayView arrv = array::make_view(arr); +// for( int p=0; p Date: Sat, 28 Oct 2017 02:13:16 +0200 Subject: [PATCH 075/355] proviate halo packer --- src/atlas/parallel/HaloExchange.h | 80 ++++++++----------------------- 1 file changed, 19 insertions(+), 61 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 0b4052d10..3f8a915f8 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -240,84 +240,42 @@ void HaloExchange::pack_send_cuda( const array::ArrayView& fiel #endif #endif -template -struct halo_packer; - -template<> -struct halo_packer<1> -{ - template - static void pack(const unsigned int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ) - { - size_t ibuf = 0; - for(int p=0; p < sendcnt; ++p) - { - const size_t pp = sendmap[p]; - send_buffer[ibuf++] = field(pp); - } +template +struct halo_packer_impl { + template + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, + array::SVector& send_buffer, Idx... idxs) { + for( size_t i=0; i< field.data_view().template length(); ++i ) { + halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); + } } }; -template<> -struct halo_packer<2> -{ - template - static void pack(const unsigned int sendcnt, array::SVector const & sendmap, const array::ArrayView& field, array::SVector& send_buffer ) +template +struct halo_packer_impl<0, CurrentDim> { + template + static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, + array::SVector& send_buffer, Idx...idxs) { - size_t ibuf = 0; - - for(int p=0; p < sendcnt; ++p) - { - const size_t pp = sendmap[p]; - for( size_t i=0; i< field.data_view().template length<1>(); ++i ) { - send_buffer[ibuf++] = field(pp, i); - } - } + send_buffer[buf_idx++] = field(node_idx, idxs...); } }; -template<> -struct halo_packer<3> -{ +template +struct halo_packer { template - static void pack(const unsigned int sendcnt, array::SVector const & sendmap, const array::ArrayView& field, array::SVector& send_buffer ) + static void pack(const unsigned int sendcnt, array::SVector const & sendmap, + const array::ArrayView& field, array::SVector& send_buffer ) { size_t ibuf = 0; for(int p=0; p < sendcnt; ++p) { const size_t pp = sendmap[p]; - for( size_t i=0; i< field.data_view().template length<1>(); ++i ) { - for( size_t j=0; j< field.data_view().template length<2>(); ++j ) { - send_buffer[ibuf++] = field(pp, i,j); - } - } + halo_packer_impl::apply(ibuf, pp, field, send_buffer); } } }; -template<> -struct halo_packer<4> -{ - template - static void pack(const unsigned int sendcnt, array::SVector const & sendmap, const array::ArrayView& field, array::SVector& send_buffer ) - { - size_t ibuf = 0; - for(int p=0; p < sendcnt; ++p) - { - const size_t pp = sendmap[p]; - for( size_t i=0; i< field.data_view().template length<1>(); ++i ) { - for( size_t j=0; j< field.data_view().template length<2>(); ++j ) { - for( size_t k=0; k< field.data_view().template length<3>(); ++k ) { - - send_buffer[ibuf++] = field(pp,i,j,k); - } - } - } - } - } -}; - template void HaloExchange::pack_send_buffer( const array::ArrayView& field, const size_t var_strides[], From c8c22f01dc11bff1445b8be943ea2830c8185f04 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sat, 28 Oct 2017 02:14:18 +0200 Subject: [PATCH 076/355] remove switch --- src/atlas/parallel/HaloExchange.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 3f8a915f8..d252d37ba 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -287,28 +287,11 @@ void HaloExchange::pack_send_buffer( const array::ArrayView& fi size_t ibuf = 0; size_t send_stride = var_strides[0]*var_shape[0]; - switch( RANK ) - { - case 1: #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA pack_send_cuda(field, var_strides, var_shape, var_rank, send_buffer); #else halo_packer::pack(sendcnt_, sendmap_, field, send_buffer); #endif - std::cout << parallel::mpi::comm().rank() << " END IF " << std::endl; - break; - case 2: - halo_packer::pack(sendcnt_, sendmap_, field, send_buffer); - break; - case 3: - halo_packer::pack(sendcnt_, sendmap_, field, send_buffer); - break; - case 4: - halo_packer::pack(sendcnt_, sendmap_, field, send_buffer); - break; - default: - NOTIMP; - } } template From 7ad1dd444abae2926e70cf4292b61fb5c93b5f30 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sat, 28 Oct 2017 02:23:10 +0200 Subject: [PATCH 077/355] provide unpacker --- src/atlas/parallel/HaloExchange.h | 120 +++++++++--------------------- 1 file changed, 37 insertions(+), 83 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index d252d37ba..8da47add9 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -109,7 +109,7 @@ class HaloExchange: public eckit::Owned { std::vector recvcounts_; std::vector recvdispls_; array::SVector sendmap_; - std::vector recvmap_; + array::SVector recvmap_; int parsize_; int nproc; @@ -261,6 +261,27 @@ struct halo_packer_impl<0, CurrentDim> { } }; +template +struct halo_unpacker_impl { + template + static void apply(size_t& buf_idx, const size_t node_idx, array::ArrayView& field, + array::SVector const & recv_buffer, Idx... idxs) { + for( size_t i=0; i< field.data_view().template length(); ++i ) { + halo_unpacker_impl::apply(buf_idx, node_idx, field, recv_buffer, idxs..., i); + } + } +}; + +template +struct halo_unpacker_impl<0, CurrentDim> { + template + static void apply(size_t& buf_idx, size_t node_idx, array::ArrayView& field, + array::SVector const & recv_buffer, Idx...idxs) + { + field(node_idx, idxs...) = recv_buffer[buf_idx++]; + } +}; + template struct halo_packer { template @@ -274,6 +295,19 @@ struct halo_packer { halo_packer_impl::apply(ibuf, pp, field, send_buffer); } } + + template + static void unpack(const unsigned int recvcnt, array::SVector const & recvmap, + array::ArrayView& field, array::SVector const & recv_buffer ) + { + size_t ibuf = 0; + for(int p=0; p < recvcnt; ++p) + { + const size_t pp = recvmap[p]; + halo_unpacker_impl::apply(ibuf, pp, field, recv_buffer); + } + } + }; template @@ -302,91 +336,11 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf size_t var_rank ) const { ATLAS_TRACE(); -// bool field_changed = false; -// DATA_TYPE tmp; size_t ibuf = 0; size_t recv_stride = var_strides[0]*var_shape[0]; - switch( var_rank ) - { - case 1: - for(int p=0; p < recvcnt_; ++p) - { - const size_t pp = recv_stride*recvmap_[p]; - for( size_t i=0; i::unpack(recvcnt_, recvmap_, field, recv_buffer); + } template From a5e43d418fc156c4e6fb47b13b719eae203cd8f4 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 29 Oct 2017 02:10:28 +0200 Subject: [PATCH 078/355] adding cuda halo exchange files --- src/atlas/CMakeLists.txt | 14 +++----- src/atlas/parallel/HaloExchange.cu | 11 ------ src/atlas/parallel/HaloExchange.h | 46 ++++---------------------- src/atlas/parallel/HaloExchangeCUDA.cu | 34 +++++++++++++++++++ src/atlas/parallel/HaloExchangeCUDA.h | 42 +++++++++++++++++++++++ 5 files changed, 87 insertions(+), 60 deletions(-) delete mode 100644 src/atlas/parallel/HaloExchange.cu create mode 100644 src/atlas/parallel/HaloExchangeCUDA.cu create mode 100644 src/atlas/parallel/HaloExchangeCUDA.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index ae2e6e52c..035761c5d 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -431,6 +431,7 @@ parallel/Checksum.h parallel/GatherScatter.cc parallel/GatherScatter.h parallel/HaloExchange.h +parallel/HaloExchange.cc parallel/mpi/Buffer.h runtime/ErrorHandling.cc runtime/ErrorHandling.h @@ -448,14 +449,6 @@ util/Rotation.h util/detail/BlackMagic.h ) -if(NOT ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA) -list( APPEND atlas_util_srcs -parallel/HaloExchange.cc -) -endif() - - - list( APPEND atlas_internals_srcs mesh/detail/AccumulateFacets.h mesh/detail/AccumulateFacets.cc @@ -555,11 +548,14 @@ list( APPEND source_list ) if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) + list( APPEND source_list + parallel/HaloExchangeCUDA.h + ) use_cuda( source_list array/gridtools/GridToolsArrayView.cu array/gridtools/GridToolsIndexView.cu mesh/Connectivity.cu - parallel/HaloExchange.cu + parallel/HaloExchangeCUDA.cu ) endif() diff --git a/src/atlas/parallel/HaloExchange.cu b/src/atlas/parallel/HaloExchange.cu deleted file mode 100644 index 2a17dc967..000000000 --- a/src/atlas/parallel/HaloExchange.cu +++ /dev/null @@ -1,11 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 "HaloExchange.cc" diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 8da47add9..40a858142 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -28,6 +28,11 @@ #include "atlas/array/SVector.h" #include "atlas/runtime/Log.h" +#ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA +#include "atlas/parallel/HaloExchangeCUDA.h" +#endif + + namespace atlas { namespace parallel { @@ -81,12 +86,6 @@ class HaloExchange: public eckit::Owned { array::SVector& send_buffer ) const; template< typename DATA_TYPE, int RANK> - void pack_send_cuda( const array::ArrayView& field, - const size_t var_strides[], - const size_t var_shape[], - size_t var_rank, - array::SVector& send_buffer ) const; - template< typename DATA_TYPE, int RANK> void unpack_recv_buffer(const array::SVector& recv_buffer, array::ArrayView& field, const size_t var_strides[], @@ -207,39 +206,6 @@ void HaloExchange::execute(array::ArrayView& field, const size_ } } -#ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA -#ifdef __CUDACC__ -template -__global__ void pack_kernel(int sendcnt, array::SVector sendmap, - const array::ArrayView field, array::SVector send_buffer) { - - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - - if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; - - const size_t buff_idx = field.data_view().template length<1>() * p + i; - - send_buffer[buff_idx] = field.data(p, i); -} - -template -void HaloExchange::pack_send_cuda( const array::ArrayView& field, - const size_t var_strides[], - const size_t var_shape[], - size_t var_rank, - array::SVector& send_buffer ) const -{ - const unsigned int block_size_x = 32; - const unsigned int block_size_y = 4; - dim3 threads(block_size_x, block_size_y); - dim3 blocks((sendcnt_+block_size_x-1)/block_size_x, (var_shape[0]+block_size_y-1)/block_size_y); - - pack_kernel<<>>(sendcnt_, sendmap_, field, send_buffer); -} -#endif -#endif - template struct halo_packer_impl { template @@ -322,7 +288,7 @@ void HaloExchange::pack_send_buffer( const array::ArrayView& fi size_t send_stride = var_strides[0]*var_shape[0]; #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - pack_send_cuda(field, var_strides, var_shape, var_rank, send_buffer); + pack_send_cuda(sendcnt_, sendmap_, field, send_buffer); #else halo_packer::pack(sendcnt_, sendmap_, field, send_buffer); #endif diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu new file mode 100644 index 000000000..961c8392f --- /dev/null +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -0,0 +1,34 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/parallel/HaloExchangeCUDA.h" + +namespace atlas { +namespace parallel { + +#ifdef __CUDACC__ +template +__global__ void pack_kernel(int sendcnt, array::SVector sendmap, + const array::ArrayView field, array::SVector send_buffer) { + + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + + if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; + + const size_t buff_idx = field.data_view().template length<1>() * p + i; + + send_buffer[buff_idx] = field.data(p, i); +} + +#endif + +} // namespace parallel +} // namespace atlas diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h new file mode 100644 index 000000000..ad1ca7ea9 --- /dev/null +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -0,0 +1,42 @@ +#pragma once + +/* + * (C) Copyright 1996-2017 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 "atlas/array/ArrayView.h" +#include "atlas/array/SVector.h" + +namespace atlas { +namespace parallel { + +#ifdef __CUDACC__ +template +__global__ +void pack_kernel(int sendcnt, array::SVector sendmap, + const array::ArrayView field, array::SVector send_buffer); +#endif + +template +void pack_send_cuda( const int sendcnt, array::SVector const & sendmap, + const array::ArrayView& field, array::SVector& send_buffer ) +{ +#ifdef __CUDACC__ + const unsigned int block_size_x = 32; + const unsigned int block_size_y = 4; + dim3 threads(block_size_x, block_size_y); + dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (field.data_view().template length<1>()+block_size_y-1)/block_size_y); + + pack_kernel<<>>(sendcnt, sendmap, field, send_buffer); +#endif +} + + +} // namespace paralllel +} // namespace atlas + From 6359a486af498e92b19685d0af1a278d007f7577 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 29 Oct 2017 02:14:47 +0100 Subject: [PATCH 079/355] create cuda halo exh library --- src/atlas/CMakeLists.txt | 9 +++++++-- src/atlas/array/gridtools/GridToolsArrayView.h | 1 + src/atlas/parallel/HaloExchange.cu | 13 +++++++++++++ src/atlas/parallel/HaloExchangeCUDA.cu | 13 ------------- src/atlas/parallel/HaloExchangeCUDA.h | 15 ++++++++++++--- src/tests/parallel/CMakeLists.txt | 8 ++++++++ 6 files changed, 41 insertions(+), 18 deletions(-) create mode 100644 src/atlas/parallel/HaloExchange.cu diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 035761c5d..a46543033 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -431,7 +431,6 @@ parallel/Checksum.h parallel/GatherScatter.cc parallel/GatherScatter.h parallel/HaloExchange.h -parallel/HaloExchange.cc parallel/mpi/Buffer.h runtime/ErrorHandling.cc runtime/ErrorHandling.h @@ -449,6 +448,12 @@ util/Rotation.h util/detail/BlackMagic.h ) +if( NOT ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) + list( APPEND atlas_util_srcs + parallel/HaloExchange.cc + ) +endif() + list( APPEND atlas_internals_srcs mesh/detail/AccumulateFacets.h mesh/detail/AccumulateFacets.cc @@ -555,7 +560,7 @@ if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) array/gridtools/GridToolsArrayView.cu array/gridtools/GridToolsIndexView.cu mesh/Connectivity.cu - parallel/HaloExchangeCUDA.cu + parallel/HaloExchange.cu ) endif() diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 354bfd469..fadf7f84e 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -79,6 +79,7 @@ template< typename Value, int Rank > class ArrayView { ATLAS_HOST_DEVICE data_view_t& data_view() { return gt_data_view_;} + ATLAS_HOST_DEVICE data_view_t const & data_view() const { return gt_data_view_;} size_t rank() const { return Rank; } diff --git a/src/atlas/parallel/HaloExchange.cu b/src/atlas/parallel/HaloExchange.cu new file mode 100644 index 000000000..bbb9955e6 --- /dev/null +++ b/src/atlas/parallel/HaloExchange.cu @@ -0,0 +1,13 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/parallel/HaloExchange.cc" + diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 961c8392f..952037a37 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -14,19 +14,6 @@ namespace atlas { namespace parallel { #ifdef __CUDACC__ -template -__global__ void pack_kernel(int sendcnt, array::SVector sendmap, - const array::ArrayView field, array::SVector send_buffer) { - - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - - if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; - - const size_t buff_idx = field.data_view().template length<1>() * p + i; - - send_buffer[buff_idx] = field.data(p, i); -} #endif diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index ad1ca7ea9..db72a9c5c 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -17,9 +17,18 @@ namespace parallel { #ifdef __CUDACC__ template -__global__ -void pack_kernel(int sendcnt, array::SVector sendmap, - const array::ArrayView field, array::SVector send_buffer); +__global__ void pack_kernel(int sendcnt, array::SVector sendmap, + const array::ArrayView field, array::SVector send_buffer) { + + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + + if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; + + const size_t buff_idx = field.data_view().template length<1>() * p + i; + + send_buffer[buff_idx] = field(p, i); +} #endif template diff --git a/src/tests/parallel/CMakeLists.txt b/src/tests/parallel/CMakeLists.txt index b8e4bf33d..ab6480e46 100644 --- a/src/tests/parallel/CMakeLists.txt +++ b/src/tests/parallel/CMakeLists.txt @@ -19,3 +19,11 @@ ecbuild_add_test( TARGET atlas_test_gather SOURCES test_gather.cc LIBS atlas ) + +atlas_add_cuda_test( + TARGET atlas_test_haloexchange_kernel + BOOST + SOURCES test_haloexchange_kernel.cu + LIBS atlas +) + From b2a5ae39fd058f7d663b2f4ba2d29820ef32366c Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 29 Oct 2017 02:14:56 +0100 Subject: [PATCH 080/355] create cuda halo exh library --- src/atlas/parallel/HaloExchangeCUDA.cu | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 src/atlas/parallel/HaloExchangeCUDA.cu diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu deleted file mode 100644 index 952037a37..000000000 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ /dev/null @@ -1,21 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 "atlas/parallel/HaloExchangeCUDA.h" - -namespace atlas { -namespace parallel { - -#ifdef __CUDACC__ - -#endif - -} // namespace parallel -} // namespace atlas From 44783684cf08442cb863653dd3e6aa05456e88f5 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 29 Oct 2017 02:25:19 +0100 Subject: [PATCH 081/355] renaming test --- src/tests/parallel/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/parallel/CMakeLists.txt b/src/tests/parallel/CMakeLists.txt index ab6480e46..b4a93be76 100644 --- a/src/tests/parallel/CMakeLists.txt +++ b/src/tests/parallel/CMakeLists.txt @@ -20,10 +20,10 @@ ecbuild_add_test( TARGET atlas_test_gather LIBS atlas ) -atlas_add_cuda_test( - TARGET atlas_test_haloexchange_kernel +ecbuild_add_test( + TARGET atlas_test_haloexchange_gpu BOOST - SOURCES test_haloexchange_kernel.cu + SOURCES test_haloexchange_gpu.cc LIBS atlas ) From 6b6aac6c381b265dbc67bf30bfafaf007f1ecbe2 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 29 Oct 2017 02:25:38 +0100 Subject: [PATCH 082/355] adding gpu test --- src/tests/parallel/test_haloexchange_gpu.cc | 126 ++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/tests/parallel/test_haloexchange_gpu.cc diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc new file mode 100644 index 000000000..85325e7ef --- /dev/null +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -0,0 +1,126 @@ +/* + * (C) Copyright 1996-2017 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 "eckit/memory/SharedPtr.h" + +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/library/config.h" +#include "atlas/array.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/MakeView.h" +#include "atlas/parallel/HaloExchange.h" + + +#include "tests/AtlasTestEnvironment.h" +#include "eckit/testing/Test.h" + +using namespace eckit::testing; + +/// POD: Type to test +typedef double POD; + +namespace atlas { +namespace test { + +//----------------------------------------------------------------------------- + +template +std::vector vec( const T (&list)[N] ) +{ + return std::vector(list,list+N); +} + +struct Fixture { + Fixture() + { + int nnodes_c[] = {5, 6, 7}; nb_nodes = vec(nnodes_c); + N = nb_nodes[parallel::mpi::comm().rank()]; + switch( parallel::mpi::comm().rank() ) + { + case 0: + { + int part_c[] = {2,0,0,0,1}; part = vec(part_c); + int ridx_c[] = {4,1,2,3,1}; ridx = vec(ridx_c); + POD gidx_c[] = {0,1,2,3,0}; gidx = vec(gidx_c); + break; + } + case 1: + { + int part_c[] = {0,1,1,1,2,2}; part = vec(part_c); + int ridx_c[] = {3,1,2,3,2,3}; ridx = vec(ridx_c); + POD gidx_c[] = {0,4,5,6,0,0}; gidx = vec(gidx_c); + break; + } + case 2: + { + int part_c[] = {1,1,2,2,2,0,0}; part = vec(part_c); + int ridx_c[] = {2,3,2,3,4,1,2}; ridx = vec(ridx_c); + POD gidx_c[] = {0,0,7,8,9,0,0}; gidx = vec(gidx_c); + break; + } + } + halo_exchange.setup(part.data(),ridx.data(),0,N); + } + parallel::HaloExchange halo_exchange; + std::vector nb_nodes; + std::vector part; + std::vector ridx; + std::vector gidx; + + int N; +}; + +//----------------------------------------------------------------------------- + +CASE("test_haloexchange_gpu") { + SETUP("Fixture") { + Fixture f; + + SECTION( "test_rank1" ) + { + array::ArrayT arr(f.N,2); + array::ArrayView arrv = array::make_view(arr); + for( int j=0; j Date: Sun, 29 Oct 2017 13:07:22 +0100 Subject: [PATCH 083/355] refurbish API --- .../array/gridtools/GridToolsArrayView.h | 5 ++ src/atlas/parallel/HaloExchange.h | 54 ++++++------------- src/tests/parallel/test_haloexchange.cc | 9 ++-- 3 files changed, 26 insertions(+), 42 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index fadf7f84e..8e39a9bdc 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -77,6 +77,11 @@ template< typename Value, int Rank > class ArrayView { return Slicer(*this).apply(i); } + template + size_t length() const { + return gt_data_view_.template length(); + } + ATLAS_HOST_DEVICE data_view_t& data_view() { return gt_data_view_;} ATLAS_HOST_DEVICE diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 40a858142..d9a8dc794 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -53,9 +53,6 @@ class HaloExchange: public eckit::Owned { const int remote_idx[], const int base, size_t size ); - template - void execute( array::ArrayView& field, const size_t var_strides[], const size_t var_shape[], size_t var_rank ) const; - template void execute( DATA_TYPE field[], size_t nb_vars ) const; @@ -80,17 +77,11 @@ class HaloExchange: public eckit::Owned { template< typename DATA_TYPE, int RANK> void pack_send_buffer( const array::ArrayView& field, - const size_t var_strides[], - const size_t var_shape[], - size_t var_rank, array::SVector& send_buffer ) const; template< typename DATA_TYPE, int RANK> void unpack_recv_buffer(const array::SVector& recv_buffer, - array::ArrayView& field, - const size_t var_strides[], - const size_t var_shape[], - size_t var_rank ) const; + array::ArrayView& field) const; template void var_info( const array::ArrayView& arr, @@ -119,9 +110,18 @@ class HaloExchange: public eckit::Owned { }; +template +constexpr typename boost::enable_if_c< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { + return 1; +} + +template +constexpr typename boost::disable_if_c< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { + return get_var_size(field) * field.template length(); +} template -void HaloExchange::execute(array::ArrayView& field, const size_t var_strides[], const size_t var_shape[], size_t var_rank ) const +void HaloExchange::execute(array::ArrayView& field) const { if( ! is_setup_ ) { @@ -131,7 +131,7 @@ void HaloExchange::execute(array::ArrayView& field, const size_ ATLAS_TRACE("HaloExchange",{"halo-exchange"}); int tag=1; - size_t var_size = std::accumulate(var_shape,var_shape+var_rank,1,std::multiplies()); + size_t var_size = get_var_size<1>(field); int send_size = sendcnt_ * var_size; int recv_size = recvcnt_ * var_size; @@ -165,7 +165,7 @@ void HaloExchange::execute(array::ArrayView& field, const size_ } /// Pack - pack_send_buffer(field,var_strides,var_shape,var_rank,send_buffer); + pack_send_buffer(field,send_buffer); /// Send ATLAS_TRACE_MPI( ISEND ) { @@ -192,7 +192,7 @@ void HaloExchange::execute(array::ArrayView& field, const size_ } /// Unpack - unpack_recv_buffer(recv_buffer,field,var_strides,var_shape,var_rank); + unpack_recv_buffer(recv_buffer,field); /// Wait for sending to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { @@ -278,14 +278,10 @@ struct halo_packer { template void HaloExchange::pack_send_buffer( const array::ArrayView& field, - const size_t var_strides[], - const size_t var_shape[], - size_t var_rank, array::SVector& send_buffer ) const { ATLAS_TRACE(); size_t ibuf = 0; - size_t send_stride = var_strides[0]*var_shape[0]; #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA pack_send_cuda(sendcnt_, sendmap_, field, send_buffer); @@ -296,14 +292,10 @@ void HaloExchange::pack_send_buffer( const array::ArrayView& fi template void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buffer, - array::ArrayView& field, - const size_t var_strides[], - const size_t var_shape[], - size_t var_rank ) const + array::ArrayView& field) const { ATLAS_TRACE(); size_t ibuf = 0; - size_t recv_stride = var_strides[0]*var_shape[0]; halo_packer::unpack(recvcnt_, recvmap_, field, recv_buffer); @@ -352,22 +344,6 @@ void HaloExchange::execute( array::ArrayView&& field ) const { execute(field); } -template -void HaloExchange::execute( array::ArrayView& field ) const -{ - //if( field.shape(0) == parsize_) - if( true ){ - std::vector varstrides, varshape; - var_info( field, varstrides, varshape ); - execute( field, varstrides.data(), varshape.data(), varstrides.size() ); - } - else - { - Log::error() << "Passed field with rank " << RANK << " and shape(0) " << field.shape(0) << std::endl; - Log::error() << "parsize_ = " << parsize_ << std::endl; - NOTIMP; // Need to implement with parallel ranks > 1 - } -} //---------------------------------------------------------------------------------------------------------------------- // C wrapper interfaces to C++ routines diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 0c86e07bb..60be8e69a 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -116,7 +116,8 @@ CASE("test_haloexchange") { arrv(j) = (size_t(f.part[j]) != parallel::mpi::comm().rank() ? 0 : f.gidx[j] ); } - f.halo_exchange.execute(arrv,strides,shape,1); + f.halo_exchange.execute(arrv); +// f.halo_exchange.execute(arrv,strides,shape,1); switch( parallel::mpi::comm().rank() ) { @@ -140,7 +141,8 @@ CASE("test_haloexchange") { size_t strides[] = {1}; size_t shape[] = {2}; - f.halo_exchange.execute(arrv,strides,shape,1); + f.halo_exchange.execute(arrv); +// f.halo_exchange.execute(arrv,strides,shape,1); switch( parallel::mpi::comm().rank() ) { @@ -216,7 +218,8 @@ CASE("test_haloexchange") { size_t strides[] = {2,1}; size_t shape[] = {3,2}; - f.halo_exchange.execute(arrv,strides,shape,2); + f.halo_exchange.execute(arrv); +// f.halo_exchange.execute(arrv,strides,shape,2); switch( parallel::mpi::comm().rank() ) { From 447ad12fbe3b93ea1f3ef6802d1097f524c5fc12 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 29 Oct 2017 20:01:11 +0100 Subject: [PATCH 084/355] fixing the wrap unittest --- src/tests/parallel/test_haloexchange.cc | 29 ++++++++++--------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 60be8e69a..1e095790e 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -139,10 +139,7 @@ CASE("test_haloexchange") { arrv(j,1) = (size_t(f.part[j]) != parallel::mpi::comm().rank() ? 0 : f.gidx[j]*100); } - size_t strides[] = {1}; - size_t shape[] = {2}; f.halo_exchange.execute(arrv); -// f.halo_exchange.execute(arrv,strides,shape,1); switch( parallel::mpi::comm().rank() ) { @@ -427,22 +424,20 @@ CASE("test_haloexchange") { SECTION( "test_rank0_ArrayView" ) { - //TODO FIRST -// array::ArraySpec spec(array::make_shape(1), array::make_strides(f.N)); -// eckit::SharedPtr arr ( array::Array::wrap(f.gidx.data(), spec ) ); -// array::ArrayView arrv = array::make_view(*arr); + eckit::SharedPtr arr ( array::Array::wrap(f.gidx.data(), array::make_shape(f.N) ) ); + array::ArrayView arrv = array::make_view(*arr); -// f.halo_exchange.execute(arrv); + f.halo_exchange.execute(arrv); -// switch( parallel::mpi::comm().rank() ) -// { -// case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; -// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } -// case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; -// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } -// case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; -// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } -// } + switch( parallel::mpi::comm().rank() ) + { + case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; + EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } + case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; + EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } + case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; + EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } + } } From 265e5586d25849a8d66c719fd0a45d4b2cb91b84 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 30 Oct 2017 01:07:17 +0100 Subject: [PATCH 085/355] recover some of the strided version --- src/tests/parallel/test_haloexchange.cc | 201 +++++++++++++----------- 1 file changed, 108 insertions(+), 93 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 1e095790e..3ce69aee7 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -117,7 +117,6 @@ CASE("test_haloexchange") { } f.halo_exchange.execute(arrv); -// f.halo_exchange.execute(arrv,strides,shape,1); switch( parallel::mpi::comm().rank() ) { @@ -152,52 +151,67 @@ CASE("test_haloexchange") { } } -// SECTION( "test_rank1_strided_v1" ) -// { -// array::ArrayT arr(f.N,2); -// array::ArrayView arrv = array::make_view(arr); -// for( int j=0; j arr_t(f.N,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int j=0; j arr ( array::Array::wrap(arrv_t.data(), + array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); + array::ArrayView arrv = array::make_view(*arr); + + f.halo_exchange.execute(arrv); + + switch( parallel::mpi::comm().rank() ) + { + case 0: { POD arr_c[] = { 90,0, 10,100, 20,200, 30,300, 40,0 }; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 1: { POD arr_c[] = { 30,0, 40,400, 50,500, 60,600, 70,0, 80,0}; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 2: { POD arr_c[] = { 50,0, 60,0, 70,700, 80,800, 90,900, 10,0, 20,0}; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + } + } SECTION( "test_rank1_strided_v2" ) { -// array::ArrayT arr(f.N,2); -// array::ArrayView arrv = array::make_view(arr); -// for( int j=0; j arr_t(f.N,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int j=0; j arr ( array::Array::wrap(&(arrv_t(0,1)), + array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); + array::ArrayView arrv = array::make_view(*arr); + + f.halo_exchange.execute(arrv); + + switch( parallel::mpi::comm().rank() ) + { + case 0: { POD arr_c[] = { 0,900, 10,100, 20,200, 30,300, 0,400 }; + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 1: { POD arr_c[] = { 0,300, 40,400, 50,500, 60,600, 0,700, 0,800}; + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 2: { POD arr_c[] = { 0,500, 0,600, 70,700, 80,800, 90,900, 0,100, 0,200}; + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + } } SECTION( "test_rank2" ) @@ -216,7 +230,6 @@ CASE("test_haloexchange") { size_t strides[] = {2,1}; size_t shape[] = {3,2}; f.halo_exchange.execute(arrv); -// f.halo_exchange.execute(arrv,strides,shape,2); switch( parallel::mpi::comm().rank() ) { @@ -256,60 +269,62 @@ CASE("test_haloexchange") { } } -// SECTION( "test_rank2_l1" ) -// { -// array::ArrayT arr(f.N,3,2); -// array::ArrayView arrv = array::make_view(arr); -// for( int p=0; p arr_t(f.N,3,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int p=0; p arr ( array::Array::wrap(arrv_t.data(), + array::ArraySpec{array::make_shape(f.N, 1, 2), array::make_strides(6, 2, 1) } ) ); + array::ArrayView arrv = array::make_view(*arr); -// switch( parallel::mpi::comm().rank() ) -// { -// case 0: -// { -// POD arr_c[] = { -9,9, 0, 0, 0, 0, // halo -// -1,1, -10,10, -100,100, // core -// -2,2, -20,20, -200,200, // core -// -3,3, -30,30, -300,300, // core -// -4,4, 0, 0, 0, 0}; // halo -// EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); -// break; -// } -// case 1: -// { -// POD arr_c[] = { -3,3, 0, 0, 0, 0, // halo -// -4,4, -40,40, -400,400, // core -// -5,5, -50,50, -500,500, // core -// -6,6, -60,60, -600,600, // core -// -7,7, 0, 0, 0, 0, // halo -// -8,8, 0, 0, 0, 0}; // halo -// EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); -// break; -// } -// case 2: -// { -// POD arr_c[] = { -5,5, 0, 0, 0, 0, // halo -// -6,6, 0, 0, 0, 0, // halo -// -7,7, -70,70, -700,700, // core -// -8,8, -80,80, -800,800, // core -// -9,9, -90,90, -900,900, // core -// -1,1, 0, 0, 0, 0, // halo -// -2,2, 0, 0, 0, 0}; // halo -// EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); -// break; -// } -// } -// } + f.halo_exchange.execute(arrv); + + switch( parallel::mpi::comm().rank() ) + { + case 0: + { + POD arr_c[] = { -9,9, 0, 0, 0, 0, // halo + -1,1, -10,10, -100,100, // core + -2,2, -20,20, -200,200, // core + -3,3, -30,30, -300,300, // core + -4,4, 0, 0, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 1: + { + POD arr_c[] = { -3,3, 0, 0, 0, 0, // halo + -4,4, -40,40, -400,400, // core + -5,5, -50,50, -500,500, // core + -6,6, -60,60, -600,600, // core + -7,7, 0, 0, 0, 0, // halo + -8,8, 0, 0, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 2: + { + POD arr_c[] = { -5,5, 0, 0, 0, 0, // halo + -6,6, 0, 0, 0, 0, // halo + -7,7, -70,70, -700,700, // core + -8,8, -80,80, -800,800, // core + -9,9, -90,90, -900,900, // core + -1,1, 0, 0, 0, 0, // halo + -2,2, 0, 0, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + } + } SECTION( "test_rank2_l2_v2" ) { From d5f597c1f352d51af2807fa4778a7fa26cd20e1b Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 30 Oct 2017 01:34:34 +0100 Subject: [PATCH 086/355] recover some of the strided version --- src/tests/parallel/test_haloexchange.cc | 104 ++++++++++++------------ 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 3ce69aee7..0917fd842 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -328,58 +328,62 @@ CASE("test_haloexchange") { SECTION( "test_rank2_l2_v2" ) { -// // Test rank 2 halo-exchange -// array::ArrayT arr(f.N,3,2); -// array::ArrayView arrv = array::make_view(arr); -// for( int p=0; p arr_t(f.N,3,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int p=0; p arr ( array::Array::wrap(&arrv_t(0,1,1), + array::ArraySpec{array::make_shape(f.N, 1, 1), array::make_strides(6, 2, 1) } ) ); + array::ArrayView arrv = array::make_view(*arr); -// switch( parallel::mpi::comm().rank() ) -// { -// case 0: -// { -// POD arr_c[] = { 0,0, 0,90, 0, 0, // halo -// -1,1, -10,10, -100,100, // core -// -2,2, -20,20, -200,200, // core -// -3,3, -30,30, -300,300, // core -// 0,0, 0,40, 0, 0}; // halo -// EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); -// break; -// } -// case 1: -// { -// POD arr_c[] = { 0,0, 0,30, 0, 0, // halo -// -4,4, -40,40, -400,400, // core -// -5,5, -50,50, -500,500, // core -// -6,6, -60,60, -600,600, // core -// 0,0, 0,70, 0, 0, // halo -// 0,0, 0,80, 0, 0}; // halo -// EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); -// break; -// } -// case 2: -// { -// POD arr_c[] = { 0,0, 0,50, 0, 0, // halo -// 0,0, 0,60, 0, 0, // halo -// -7,7, -70,70, -700,700, // core -// -8,8, -80,80, -800,800, // core -// -9,9, -90,90, -900,900, // core -// 0,0, 0,10, 0, 0, // halo -// 0,0, 0,20, 0, 0}; // halo -// EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); -// break; -// } -// } + size_t strides[] = {6,2}; + size_t shape[] = {1,1}; + f.halo_exchange.execute(arrv); + + switch( parallel::mpi::comm().rank() ) + { + case 0: + { + POD arr_c[] = { 0,0, 0,90, 0, 0, // halo + -1,1, -10,10, -100,100, // core + -2,2, -20,20, -200,200, // core + -3,3, -30,30, -300,300, // core + 0,0, 0,40, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 1: + { + POD arr_c[] = { 0,0, 0,30, 0, 0, // halo + -4,4, -40,40, -400,400, // core + -5,5, -50,50, -500,500, // core + -6,6, -60,60, -600,600, // core + 0,0, 0,70, 0, 0, // halo + 0,0, 0,80, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 2: + { + POD arr_c[] = { 0,0, 0,50, 0, 0, // halo + 0,0, 0,60, 0, 0, // halo + -7,7, -70,70, -700,700, // core + -8,8, -80,80, -800,800, // core + -9,9, -90,90, -900,900, // core + 0,0, 0,10, 0, 0, // halo + 0,0, 0,20, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + } } SECTION( "test_rank2_v2" ) From 017f72cf1629246b653257b0d97c5c5db2ac5d56 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 30 Oct 2017 01:44:16 +0100 Subject: [PATCH 087/355] recover some of the strided version --- src/tests/parallel/test_haloexchange.cc | 106 ++++++++++++------------ 1 file changed, 51 insertions(+), 55 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 0917fd842..ca4af9942 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -108,8 +108,6 @@ CASE("test_haloexchange") { SECTION( "test_rank0_arrview" ) { - size_t strides[] = {1}; - size_t shape[] = {1}; array::ArrayT arr(f.N); array::ArrayView arrv = array::make_view(arr); for( int j=0; j arrv = array::make_view(*arr); - size_t strides[] = {6,2}; - size_t shape[] = {1,1}; f.halo_exchange.execute(arrv); switch( parallel::mpi::comm().rank() ) @@ -388,57 +382,59 @@ CASE("test_haloexchange") { SECTION( "test_rank2_v2" ) { -// array::ArrayT arr(f.N,3,2); -// array::ArrayView arrv = array::make_view(arr); -// for( int p=0; p arr_t(f.N,3,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int p=0; p arr ( array::Array::wrap(&arrv_t(0,0,1), + array::ArraySpec{array::make_shape(f.N, 3, 1), array::make_strides(6, 2, 2) } ) ); + array::ArrayView arrv = array::make_view(*arr); -// switch( parallel::mpi::comm().rank() ) -// { -// case 0: -// { -// POD arr_c[] = { 0,9, 0,90, 0,900, // halo -// -1,1, -10,10, -100,100, // core -// -2,2, -20,20, -200,200, // core -// -3,3, -30,30, -300,300, // core -// 0,4, 0,40, 0,400}; // halo -// EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); -// break; -// } -// case 1: -// { -// POD arr_c[] = { 0,3, 0,30, 0,300, // halo -// -4,4, -40,40, -400,400, // core -// -5,5, -50,50, -500,500, // core -// -6,6, -60,60, -600,600, // core -// 0,7, 0,70, 0,700, // halo -// 0,8, 0,80, 0,800}; // halo -// EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); -// break; -// } -// case 2: -// { -// POD arr_c[] = { 0,5, 0,50, 0,500, // halo -// 0,6, 0,60, 0,600, // halo -// -7,7, -70,70, -700,700, // core -// -8,8, -80,80, -800,800, // core -// -9,9, -90,90, -900,900, // core -// 0,1, 0,10, 0,100, // halo -// 0,2, 0,20, 0,200}; // halo -// EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); -// break; -// } -// } + f.halo_exchange.execute(arrv); + + switch( parallel::mpi::comm().rank() ) + { + case 0: + { + POD arr_c[] = { 0,9, 0,90, 0,900, // halo + -1,1, -10,10, -100,100, // core + -2,2, -20,20, -200,200, // core + -3,3, -30,30, -300,300, // core + 0,4, 0,40, 0,400}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 1: + { + POD arr_c[] = { 0,3, 0,30, 0,300, // halo + -4,4, -40,40, -400,400, // core + -5,5, -50,50, -500,500, // core + -6,6, -60,60, -600,600, // core + 0,7, 0,70, 0,700, // halo + 0,8, 0,80, 0,800}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 2: + { + POD arr_c[] = { 0,5, 0,50, 0,500, // halo + 0,6, 0,60, 0,600, // halo + -7,7, -70,70, -700,700, // core + -8,8, -80,80, -800,800, // core + -9,9, -90,90, -900,900, // core + 0,1, 0,10, 0,100, // halo + 0,2, 0,20, 0,200}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + } } SECTION( "test_rank0_ArrayView" ) From fccda473e3c7a0cd441f416e6583c877125f946d Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 30 Oct 2017 11:06:56 +0100 Subject: [PATCH 088/355] exchange a gpu device --- src/tests/parallel/test_haloexchange_gpu.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index 85325e7ef..2b5d159f9 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -90,7 +90,7 @@ CASE("test_haloexchange_gpu") { SECTION( "test_rank1" ) { array::ArrayT arr(f.N,2); - array::ArrayView arrv = array::make_view(arr); + array::ArrayView arrv = array::make_host_view(arr); for( int j=0; j arrvd = array::make_device_view(arr); + + f.halo_exchange.execute(arrvd); switch( parallel::mpi::comm().rank() ) { From 26100578201aaa21f219ae0ec6c29ac21c565475 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 30 Oct 2017 18:01:24 +0000 Subject: [PATCH 089/355] Compatibility with new gridtools_storage module --- CMakeLists.txt | 46 ++++------------- cmake/Findgridtools_storage.cmake | 55 --------------------- src/CMakeLists.txt | 5 -- src/atlas/CMakeLists.txt | 4 ++ src/atlas/array/gridtools/GridToolsTraits.h | 13 +---- src/atlas/library/defines.h.in | 1 - src/tests/CMakeLists.txt | 6 +-- 7 files changed, 16 insertions(+), 114 deletions(-) delete mode 100644 cmake/Findgridtools_storage.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f8e986558..47bee8d8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,44 +127,16 @@ ecbuild_add_option( if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --std=c++11") - set( ENABLE_GPU "OFF" CACHE BOOL "Compile with GPU support (CUDA)" ) - - set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST 1 ) - set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA 0 ) - - if(ENABLE_GPU) - set( CUDA_USE_STATIC_CUDA_RUNTIME OFF ) - find_package(CUDA REQUIRED) - - string(REPLACE "." "" CUDA_VERSION ${CUDA_VERSION}) - - add_definitions(-D_FORCE_INLINES) # Question to Carlos: Is this needed for nvcc only? - add_definitions(-D_USE_GPU_) - - set(CUDA_PROPAGATE_HOST_FLAGS ON) - set(CUDA_NVCC_FLAGS "--relaxed-constexpr" "${CUDA_NVCC_FLAGS}") - if( NOT ${CUDA_VERSION} VERSION_GREATER "60") - message(FATAL_ERROR "CUDA 6.0 or lower does not support C++11 (disabling)") - endif() - - set( CUDA_ARCH "sm_35" CACHE STRING "Compute capability for CUDA" ) - set( CUDA_SEPARABLE_COMPILATION ON) - - include_directories(SYSTEM ${CUDA_INCLUDE_DIRS}) - - set(CUDA_SEPARABLE_COMPILATION ON) - # adding the additional nvcc flags - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" "-arch=${CUDA_ARCH}" "-Xcudafe" "--diag_suppress=dupl_calling_convention") - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" "-Xcudafe" "--diag_suppress=code_is_unreachable" "-Xcudafe") - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" "--diag_suppress=implicit_return_from_non_void_function" "-Xcudafe") - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" "--diag_suppress=calling_convention_not_allowed" "-Xcudafe") - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" "--diag_suppress=conflicting_calling_conventions") - set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}" "-Xcompiler" "-fPIC") + set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST 1 ) + set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA 0 ) + + if( GRIDTOOLS_HAVE_CUDA ) + ecbuild_info( "Gridtools found with CUDA support" ) + set( CUDA_NVCC_FLAGS "--relaxed-constexpr" "${CUDA_NVCC_FLAGS}" ) + set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST 0 ) + set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA 1 ) + endif() - set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST 0 ) - set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA 1 ) - endif() endif() ### Eigen diff --git a/cmake/Findgridtools_storage.cmake b/cmake/Findgridtools_storage.cmake deleted file mode 100644 index 8c7870184..000000000 --- a/cmake/Findgridtools_storage.cmake +++ /dev/null @@ -1,55 +0,0 @@ -# (C) Copyright 1996-2016 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. - -# - Try to find gridtools_storage -# Once done this will define -# GRIDTOOLS_STORAGE_FOUND - True if gridtools_storage found -# GRIDTOOLS_STORAGE_INCLUDE_DIRS - The gridtools_storage include directories -# GRIDTOOLS_STORAGE_LIBRARIES - The libraries needed to use gridtools_storage -# GRIDTOOLS_STORAGE_DEFINITIONS - Compiler switches required for using gridtools_storage - -if( NOT GRIDTOOLS_STORAGE_FOUND ) - - find_path( GRIDTOOLS_STORAGE_INCLUDE_DIR - NAMES storage/storage-facility.hpp - PATHS - ${CMAKE_INSTALL_PREFIX} - "${GRIDTOOLS_STORAGE_PATH}" - ENV GRIDTOOLS_STORAGE_PATH - PATH_SUFFIXES include - ) - - ecbuild_debug( "Searching for Boost version >= 1.58, required for gridtools_storage..." ) - if( GRIDTOOLS_STORAGE_INCLUDE_DIR AND NOT Boost_FOUND ) - find_package(Boost 1.58.0 ) - endif() - if( Boost_FOUND ) - ecbuild_debug( "Boost, required for gridtools_storage found at ${Boost_INCLUDE_DIRS}" ) - else() - ecbuild_debug( "Boost, required for gridtools_storage not found" ) - endif() - - include(FindPackageHandleStandardArgs) - - # handle the QUIETLY and REQUIRED arguments and set GRIDTOOLS_STORAGE_FOUND to TRUE - find_package_handle_standard_args( gridtools_storage DEFAULT_MSG - GRIDTOOLS_STORAGE_INCLUDE_DIR Boost_INCLUDE_DIRS ) - - mark_as_advanced( GRIDTOOLS_STORAGE_INCLUDE_DIRS GRIDTOOLS_STORAGE_LIBRARIES ) - - set( gridtools_storage_FOUND ${GRIDTOOLS_STORAGE_FOUND} ) - set( GRIDTOOLS_STORAGE_INCLUDE_DIRS - ${GRIDTOOLS_STORAGE_INCLUDE_DIR} - ${Boost_INCLUDE_DIRS} - ) - - # message("DEBUG Findgridtools_storage : GRIDTOOLS_STORAGE_FOUND [${GRIDTOOLS_STORAGE_FOUND}]") - # message("DEBUG Findgridtools_storage : gridtools_storage_FOUND [${gridtools_storage_FOUND}]") - # message("DEBUG Findgridtools_storage : GRIDTOOLS_STORAGE_INCLUDE_DIRS [${GRIDTOOLS_STORAGE_INCLUDE_DIRS}]") - -endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 70742f1d5..c7e90ad77 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -55,11 +55,6 @@ if( ATLAS_HAVE_MPI ) endif() -if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) - include_directories( ${GRIDTOOLS_STORAGE_INCLUDE_DIRS} ) -endif() - - add_subdirectory( atlas ) if( ATLAS_HAVE_FORTRAN ) diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index d41ece1ca..2643ce88f 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -584,3 +584,7 @@ ecbuild_add_library( TARGET atlas DEFINITIONS ${ATLAS_DEFINITIONS} ) + +if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) + target_link_libraries( atlas gridtools_storage ) +endif() diff --git a/src/atlas/array/gridtools/GridToolsTraits.h b/src/atlas/array/gridtools/GridToolsTraits.h index 9079a4c0d..feaafb667 100644 --- a/src/atlas/array/gridtools/GridToolsTraits.h +++ b/src/atlas/array/gridtools/GridToolsTraits.h @@ -1,18 +1,9 @@ #pragma once #include "atlas/library/config.h" +#include "gridtools/common/generic_metafunctions/all_integrals.hpp" +#include "gridtools/storage/storage-facility.hpp" -//------------------------------------------------------------------------------ -#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA -#ifndef _USE_GPU_ -#define _USE_GPU_ -#endif -#endif -#include "common/generic_metafunctions/all_integrals.hpp" -#include "storage/storage-facility.hpp" -#ifdef _USE_GPU_ -#undef _USE_GPU_ -#endif //------------------------------------------------------------------------------ namespace atlas { diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index 859c804e5..0bfa71dea 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -31,7 +31,6 @@ #if @ATLAS_HAVE_GRIDTOOLS_STORAGE@ #define ATLAS_HAVE_GRIDTOOLS_STORAGE -#define BOOST_RESULT_OF_USE_TR1 #define ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST @ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST@ #define ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA @ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA@ #endif diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index b2bae014e..63fc52bfb 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -21,16 +21,12 @@ macro( atlas_add_cuda_test ) ecbuild_critical("Unknown keywords given to atlas_add_cuda_test(): \"${_PAR_UNPARSED_ARGUMENTS}\"") endif() - if( ATLAS_HAVE_GRIDTOOLS_STORAGE AND ENABLE_GPU AND ENABLE_TESTS ) + if( ATLAS_HAVE_GRIDTOOLS_STORAGE AND GRIDTOOLS_HAVE_CUDA AND ENABLE_TESTS ) ecbuild_debug("atlas_add_cuda_test: Adding test ${_PAR_TARGET}") list( APPEND _libs ${_PAR_LIBS} ) - if( _PAR_BOOST ) - list( APPEND _libs ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${Boost_TEST_EXEC_MONITOR_LIBRARY} ) - endif() - cuda_add_executable (${_PAR_TARGET} ${_PAR_SOURCES}) if( _libs ) ecbuild_debug("atlas_add_cuda_test: Test ${_PAR_TARGET} explicitly links with libraries ${_libs}") From 2378dff62c09c5f30c2dc2243791f5cc909e3104 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 30 Oct 2017 19:40:45 +0100 Subject: [PATCH 090/355] change API in order to pass an array instead of array view to halo exchange --- src/atlas/functionspace/EdgeColumns.cc | 14 +++---- src/atlas/functionspace/NodeColumns.cc | 12 +++--- src/atlas/functionspace/StructuredColumns.cc | 16 +++----- src/atlas/parallel/HaloExchange.cc | 6 +-- src/atlas/parallel/HaloExchange.h | 43 +++++++++++--------- src/tests/parallel/test_haloexchange.cc | 22 +++++----- src/tests/parallel/test_haloexchange_gpu.cc | 2 +- 7 files changed, 56 insertions(+), 59 deletions(-) diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index be1adc932..2d9a8d2da 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -254,22 +254,18 @@ Field EdgeColumns::createField( void EdgeColumns::haloExchange( FieldSet& fieldset ) const { for( size_t f=0; f() ) { - array::ArrayView view = array::make_view(field); - halo_exchange().execute( view ); + halo_exchange().template execute( field.array(), false ); } else if( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange().execute( view ); + halo_exchange().template execute( field.array(), false ); } else if( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange().execute( view ); + halo_exchange().template execute( field.array(), false ); } else if( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange().execute( view ); + halo_exchange().template execute( field.array(), false ); } else throw eckit::Exception("datatype not supported",Here()); } diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 5aba6fce1..11ae13f24 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -337,19 +337,19 @@ array::ArrayView get_field_view(const Field& field, bool on_devi } template -void dispatch_haloExchange( const Field& field, const parallel::HaloExchange& halo_exchange, bool on_device ) +void dispatch_haloExchange( Field& field, const parallel::HaloExchange& halo_exchange, bool on_device ) { if ( field.datatype() == array::DataType::kind() ) { - halo_exchange.execute( get_field_view(field, on_device) ); + halo_exchange.template execute( field.array(), on_device ); } else if( field.datatype() == array::DataType::kind() ) { - halo_exchange.execute( get_field_view(field, on_device) ); + halo_exchange.template execute( field.array(), on_device ); } else if( field.datatype() == array::DataType::kind() ) { - halo_exchange.execute( get_field_view(field, on_device) ); + halo_exchange.template execute( field.array(), on_device ); } else if( field.datatype() == array::DataType::kind() ) { - halo_exchange.execute( get_field_view(field, on_device) ); + halo_exchange.template execute( field.array(), on_device ); } else throw eckit::Exception("datatype not supported",Here()); } @@ -358,7 +358,7 @@ void dispatch_haloExchange( const Field& field, const parallel::HaloExchange& ha void NodeColumns::haloExchange( FieldSet& fieldset, bool on_device ) const { for( size_t f=0; f(field,halo_exchange(), on_device); diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index d0230b46f..99a581fb5 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -805,23 +805,19 @@ std::string StructuredColumns::checksum( const Field& field ) const { namespace { template -void dispatch_haloExchange( const Field& field, const parallel::HaloExchange& halo_exchange ) +void dispatch_haloExchange( Field& field, const parallel::HaloExchange& halo_exchange ) { if ( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange.execute( view ); + halo_exchange.template execute( field.array(), false); } else if( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange.execute( view ); + halo_exchange.template execute( field.array(), false ); } else if( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange.execute( view ); + halo_exchange.template execute( field.array(), false ); } else if( field.datatype() == array::DataType::kind() ) { - array::ArrayView view = array::make_view(field); - halo_exchange.execute( view ); + halo_exchange.template execute( field.array(), false ); } else throw eckit::Exception("datatype not supported",Here()); } @@ -830,7 +826,7 @@ void dispatch_haloExchange( const Field& field, const parallel::HaloExchange& ha void StructuredColumns::haloExchange( FieldSet& fieldset ) const { for( size_t f=0; f(field,*halo_exchange_); diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index edc538677..4dd64a9f2 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -222,15 +222,15 @@ void atlas__HaloExchange__execute_strided_double (HaloExchange* This, double fie } void atlas__HaloExchange__execute_int (HaloExchange* This, int field[], int nb_vars ) { - This->execute(field,nb_vars); +// This->execute(field,nb_vars); } void atlas__HaloExchange__execute_float (HaloExchange* This, float field[], int nb_vars ) { - This->execute(field,nb_vars); +// This->execute(field,nb_vars); } void atlas__HaloExchange__execute_double (HaloExchange* This, double field[], int nb_vars ) { - This->execute(field,nb_vars); +// This->execute(field,nb_vars); } ///////////////////// diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index d9a8dc794..299f1e33b 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -53,14 +53,14 @@ class HaloExchange: public eckit::Owned { const int remote_idx[], const int base, size_t size ); - template - void execute( DATA_TYPE field[], size_t nb_vars ) const; +// template +// void execute( DATA_TYPE field[], size_t nb_vars ) const; template - void execute( array::ArrayView& field ) const; + void execute( array::Array& field, bool on_device ) const; - template - void execute( array::ArrayView&& field ) const; +// template +// void execute( array::ArrayView&& field ) const; private: // methods @@ -121,7 +121,7 @@ constexpr typename boost::disable_if_c< (cnt == RANK), size_t >::type get_var_si } template -void HaloExchange::execute(array::ArrayView& field) const +void HaloExchange::execute(array::Array& field, bool on_device) const { if( ! is_setup_ ) { @@ -130,8 +130,10 @@ void HaloExchange::execute(array::ArrayView& field) const ATLAS_TRACE("HaloExchange",{"halo-exchange"}); + auto field_hv = array::make_host_view(field); + int tag=1; - size_t var_size = get_var_size<1>(field); + size_t var_size = get_var_size<1>(field_hv); int send_size = sendcnt_ * var_size; int recv_size = recvcnt_ * var_size; @@ -164,8 +166,11 @@ void HaloExchange::execute(array::ArrayView& field) const } } + auto field_dv = on_device ? array::make_device_view(field) : + array::make_host_view(field); + /// Pack - pack_send_buffer(field,send_buffer); + pack_send_buffer(field_dv,send_buffer); /// Send ATLAS_TRACE_MPI( ISEND ) { @@ -192,7 +197,7 @@ void HaloExchange::execute(array::ArrayView& field) const } /// Unpack - unpack_recv_buffer(recv_buffer,field); + unpack_recv_buffer(recv_buffer,field_dv); /// Wait for sending to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { @@ -301,15 +306,15 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf } -template -void HaloExchange::execute( DATA_TYPE field[], size_t nb_vars ) const -{ - throw eckit::AssertionFailed("Call not supported"); +//template +//void HaloExchange::execute( DATA_TYPE field[], size_t nb_vars ) const +//{ +// throw eckit::AssertionFailed("Call not supported"); // size_t strides[] = {1}; // size_t shape[] = {nb_vars}; // execute( field, strides, shape, 1); -} +//} template @@ -339,11 +344,11 @@ void HaloExchange::var_info( const array::ArrayView& arr, } } -template -void HaloExchange::execute( array::ArrayView&& field ) const -{ - execute(field); -} +//template +//void HaloExchange::execute( array::ArrayView&& field ) const +//{ +// execute(field); +//} //---------------------------------------------------------------------------------------------------------------------- // C wrapper interfaces to C++ routines diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index ca4af9942..ef3212019 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -114,7 +114,7 @@ CASE("test_haloexchange") { arrv(j) = (size_t(f.part[j]) != parallel::mpi::comm().rank() ? 0 : f.gidx[j] ); } - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(arr, false); switch( parallel::mpi::comm().rank() ) { @@ -136,7 +136,7 @@ CASE("test_haloexchange") { arrv(j,1) = (size_t(f.part[j]) != parallel::mpi::comm().rank() ? 0 : f.gidx[j]*100); } - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(arr, false); switch( parallel::mpi::comm().rank() ) { @@ -167,7 +167,7 @@ CASE("test_haloexchange") { array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); array::ArrayView arrv = array::make_view(*arr); - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(*arr, false); switch( parallel::mpi::comm().rank() ) { @@ -199,7 +199,7 @@ CASE("test_haloexchange") { array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); array::ArrayView arrv = array::make_view(*arr); - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(*arr, false); switch( parallel::mpi::comm().rank() ) { @@ -225,7 +225,7 @@ CASE("test_haloexchange") { } } - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(arr, false); switch( parallel::mpi::comm().rank() ) { @@ -282,7 +282,7 @@ CASE("test_haloexchange") { array::ArraySpec{array::make_shape(f.N, 1, 2), array::make_strides(6, 2, 1) } ) ); array::ArrayView arrv = array::make_view(*arr); - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(*arr, false); switch( parallel::mpi::comm().rank() ) { @@ -340,7 +340,7 @@ CASE("test_haloexchange") { array::ArraySpec{array::make_shape(f.N, 1, 1), array::make_strides(6, 2, 1) } ) ); array::ArrayView arrv = array::make_view(*arr); - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(*arr, false); switch( parallel::mpi::comm().rank() ) { @@ -397,7 +397,7 @@ CASE("test_haloexchange") { array::ArraySpec{array::make_shape(f.N, 3, 1), array::make_strides(6, 2, 2) } ) ); array::ArrayView arrv = array::make_view(*arr); - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(*arr, false); switch( parallel::mpi::comm().rank() ) { @@ -442,7 +442,7 @@ CASE("test_haloexchange") { eckit::SharedPtr arr ( array::Array::wrap(f.gidx.data(), array::make_shape(f.N) ) ); array::ArrayView arrv = array::make_view(*arr); - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(*arr, false); switch( parallel::mpi::comm().rank() ) { @@ -469,7 +469,7 @@ CASE("test_haloexchange") { // size_t strides[] = {1}; // BOOST_CHECK_EQUAL_COLLECTIONS( arrv.strides()+1,arrv.strides()+2, strides,strides+1); - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(arr, false); switch( parallel::mpi::comm().rank() ) { @@ -500,7 +500,7 @@ CASE("test_haloexchange") { // size_t strides[] = {2,1}; // BOOST_CHECK_EQUAL_COLLECTIONS( arrv.strides()+1,arrv.strides()+3, strides,strides+2); - f.halo_exchange.execute(arrv); + f.halo_exchange.template execute(arr, false); switch( parallel::mpi::comm().rank() ) { diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index 2b5d159f9..b09d9a320 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -102,7 +102,7 @@ CASE("test_haloexchange_gpu") { arr.syncHostDevice(); array::ArrayView arrvd = array::make_device_view(arr); - f.halo_exchange.execute(arrvd); + f.halo_exchange.template execute(arr, true); switch( parallel::mpi::comm().rank() ) { From c2a2d91452bc9ec41adef55616adc7657680a9f0 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 30 Oct 2017 19:42:50 +0100 Subject: [PATCH 091/355] cleanup --- src/tests/parallel/test_haloexchange.cc | 11 +++-------- src/tests/parallel/test_haloexchange_gpu.cc | 1 - 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index ef3212019..5720a14e3 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -165,18 +165,17 @@ CASE("test_haloexchange") { eckit::SharedPtr arr ( array::Array::wrap(arrv_t.data(), array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); - array::ArrayView arrv = array::make_view(*arr); f.halo_exchange.template execute(*arr, false); switch( parallel::mpi::comm().rank() ) { case 0: { POD arr_c[] = { 90,0, 10,100, 20,200, 30,300, 40,0 }; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } case 1: { POD arr_c[] = { 30,0, 40,400, 50,500, 60,600, 70,0, 80,0}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } case 2: { POD arr_c[] = { 50,0, 60,0, 70,700, 80,800, 90,900, 10,0, 20,0}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } } } @@ -197,7 +196,6 @@ CASE("test_haloexchange") { eckit::SharedPtr arr ( array::Array::wrap(&(arrv_t(0,1)), array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); - array::ArrayView arrv = array::make_view(*arr); f.halo_exchange.template execute(*arr, false); @@ -280,7 +278,6 @@ CASE("test_haloexchange") { eckit::SharedPtr arr ( array::Array::wrap(arrv_t.data(), array::ArraySpec{array::make_shape(f.N, 1, 2), array::make_strides(6, 2, 1) } ) ); - array::ArrayView arrv = array::make_view(*arr); f.halo_exchange.template execute(*arr, false); @@ -338,7 +335,6 @@ CASE("test_haloexchange") { eckit::SharedPtr arr ( array::Array::wrap(&arrv_t(0,1,1), array::ArraySpec{array::make_shape(f.N, 1, 1), array::make_strides(6, 2, 1) } ) ); - array::ArrayView arrv = array::make_view(*arr); f.halo_exchange.template execute(*arr, false); @@ -395,7 +391,6 @@ CASE("test_haloexchange") { eckit::SharedPtr arr ( array::Array::wrap(&arrv_t(0,0,1), array::ArraySpec{array::make_shape(f.N, 3, 1), array::make_strides(6, 2, 2) } ) ); - array::ArrayView arrv = array::make_view(*arr); f.halo_exchange.template execute(*arr, false); diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index b09d9a320..b173eb8a8 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -100,7 +100,6 @@ CASE("test_haloexchange_gpu") { size_t shape[] = {2}; arr.syncHostDevice(); - array::ArrayView arrvd = array::make_device_view(arr); f.halo_exchange.template execute(arr, true); From 97cd00d0b940bb890985a75994c78ab1acd3e3c6 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 30 Oct 2017 19:43:11 +0100 Subject: [PATCH 092/355] cleanup --- src/tests/parallel/test_haloexchange_gpu.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index b173eb8a8..f2497c9e7 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -96,9 +96,6 @@ CASE("test_haloexchange_gpu") { arrv(j,1) = (size_t(f.part[j]) != parallel::mpi::comm().rank() ? 0 : f.gidx[j]*100); } - size_t strides[] = {1}; - size_t shape[] = {2}; - arr.syncHostDevice(); f.halo_exchange.template execute(arr, true); From d8f5665224ecd1d56202bec1f5b166230b848334 Mon Sep 17 00:00:00 2001 From: cosunae Date: Tue, 31 Oct 2017 09:25:33 +0100 Subject: [PATCH 093/355] adding a readonly property to the array view --- .../array/gridtools/GridToolsArrayView.cc | 39 +++--- .../array/gridtools/GridToolsArrayView.h | 12 +- .../array/gridtools/GridToolsMakeView.cc | 120 +++++++++--------- src/atlas/array/gridtools/GridToolsMakeView.h | 4 +- src/atlas/array/gridtools/GridToolsTraits.h | 2 +- src/atlas/array_fwd.h | 8 +- src/atlas/parallel/HaloExchange.h | 10 +- 7 files changed, 101 insertions(+), 94 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index fb2438e80..e58e0751c 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -15,8 +15,8 @@ namespace atlas { namespace array { -template< typename Value, int Rank > -ArrayView::ArrayView( const ArrayView& other ) : +template< typename Value, int Rank, bool ReadOnly > +ArrayView::ArrayView( const ArrayView& other ) : gt_data_view_(other.gt_data_view_), data_store_orig_(other.data_store_orig_), array_(other.array_) { std::memcpy(shape_,other.shape_,sizeof(size_t)*Rank); std::memcpy(strides_,other.strides_,sizeof(size_t)*Rank); @@ -24,8 +24,8 @@ ArrayView::ArrayView( const ArrayView& other ) : // TODO: check compatibility } -template< typename Value, int Rank > -ArrayView::ArrayView(data_view_t data_view, const Array& array) : +template< typename Value, int Rank, bool ReadOnly > +ArrayView::ArrayView(data_view_t data_view, const Array& array) : gt_data_view_(data_view), data_store_orig_(array.data_store()), array_(&array) { if(data_view.valid()) { using seq = ::gridtools::apply_gt_integer_sequence::type>; @@ -57,13 +57,13 @@ ArrayView::ArrayView(data_view_t data_view, const Array& array) : } } -template< typename Value, int Rank > -bool ArrayView::valid() const { +template< typename Value, int Rank, bool ReadOnly> +bool ArrayView::valid() const { return gt_data_view_.valid() && (array_->data_store() == data_store_orig_); } -template< typename Value, int Rank > -void ArrayView::assign(const value_type& value) { +template< typename Value, int Rank, bool ReadOnly > +void ArrayView::assign(const value_type& value) { ASSERT( contiguous() ); value_type* raw_data = data(); for( size_t j=0; j::assign(const value_type& value) { } } -template -void ArrayView::assign(const std::initializer_list& list) { +template +void ArrayView::assign(const std::initializer_list& list) { ASSERT( contiguous() ); ASSERT( list.size() == size_ ); value_type* raw_data = data(); @@ -82,8 +82,8 @@ void ArrayView::assign(const std::initializer_list& list } } -template< typename Value, int Rank > -void ArrayView::dump(std::ostream& os) const { +template< typename Value, int Rank, bool ReadOnly > +void ArrayView::dump(std::ostream& os) const { ASSERT( contiguous() ); const value_type* data_ = data(); os << "size: " << size() << " , values: "; @@ -103,11 +103,16 @@ void ArrayView::dump(std::ostream& os) const { namespace atlas { namespace array { #define EXPLICIT_TEMPLATE_INSTANTIATION(Rank) \ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ // For each NDims in [1..9] EXPLICIT_TEMPLATE_INSTANTIATION(1) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 8e39a9bdc..ad04e2c1f 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -24,12 +24,12 @@ namespace atlas { namespace array { -template< typename Value, int Rank > class ArrayView { +template< typename Value, int Rank, bool ReadOnly > class ArrayView { public: // -- Type definitions using value_type = typename remove_const::type; using Slice = typename std::conditional<(Rank==1), value_type&, LocalView >::type; - using data_view_t = gridtools::data_view_tt; + using data_view_t = gridtools::data_view_tt; public: @@ -105,8 +105,8 @@ template< typename Value, int Rank > class ArrayView { template struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; + Slicer(ArrayView const& av) : av_(av) {} + ArrayView const& av_; ReturnType apply(const size_t i) const { return LocalView( av_.data()+av_.strides_[0]*i, @@ -117,8 +117,8 @@ template< typename Value, int Rank > class ArrayView { template struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; + Slicer(ArrayView const& av) : av_(av) {} + ArrayView const& av_; ReturnType apply(const size_t i) const { return *(const_cast(av_.data()) + av_.strides_[0] * i); } diff --git a/src/atlas/array/gridtools/GridToolsMakeView.cc b/src/atlas/array/gridtools/GridToolsMakeView.cc index d2f4875e8..1133ae9ef 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.cc +++ b/src/atlas/array/gridtools/GridToolsMakeView.cc @@ -35,7 +35,7 @@ namespace { namespace gridtools { template -data_view_tt +data_view_tt make_gt_host_view(const Array& array) { using storage_info_ty = storage_traits::storage_info_t<0, Rank>; @@ -43,29 +43,29 @@ make_gt_host_view(const Array& array) { data_store_t* ds = reinterpret_cast(const_cast(array.storage())); - return ::gridtools::make_host_view<::gridtools::access_mode::ReadWrite>(*ds); + return ::gridtools::make_host_view< get_access_mode(ReadOnly) >(*ds); } template -data_view_tt +data_view_tt make_gt_device_view(const Array& array) { typedef storage_traits::storage_info_t<0, Rank> storage_info_ty; typedef storage_traits::data_store_t data_store_t; data_store_t* ds = reinterpret_cast(const_cast(array.storage())); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - return ::gridtools::make_device_view<::gridtools::access_mode::ReadWrite>(*ds); + return ::gridtools::make_device_view< get_access_mode(ReadOnly) >(*ds); #else - return ::gridtools::make_host_view<::gridtools::access_mode::ReadWrite>(*ds); + return ::gridtools::make_host_view< get_access_mode(ReadOnly) >(*ds); #endif } } template -ArrayView +ArrayView make_host_view(const Array& array) { check_metadata(array); - return ArrayView(gridtools::make_gt_host_view(array), array); + return ArrayView(gridtools::make_gt_host_view(array), array); } template @@ -78,10 +78,10 @@ make_host_storageview(const Array& array) { } template -ArrayView +ArrayView make_device_view(const Array& array) { check_metadata(array); - return ArrayView(gridtools::make_gt_device_view(array), array); + return ArrayView(gridtools::make_gt_device_view(array), array); } @@ -112,7 +112,7 @@ make_indexview(const Array& array) { } template -ArrayView +ArrayView make_view(const Array& array) { check_metadata(array); @@ -133,38 +133,38 @@ make_storageview(const Array& array) { namespace atlas { namespace array { #define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ \ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ \ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ \ template IndexView make_indexview(const Array&);\ template IndexView make_indexview(const Array&);\ @@ -173,27 +173,27 @@ template IndexView make_host_indexview(const Array&);\ template IndexView make_host_indexview(const Array&);\ \ namespace gridtools { \ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ \ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ } template StorageView make_storageview(const Array&); diff --git a/src/atlas/array/gridtools/GridToolsMakeView.h b/src/atlas/array/gridtools/GridToolsMakeView.h index 3eea6dbbc..fba59a322 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.h +++ b/src/atlas/array/gridtools/GridToolsMakeView.h @@ -17,11 +17,11 @@ namespace array { namespace gridtools { template -data_view_tt +data_view_tt make_gt_host_view(const Array& array); template -data_view_tt +data_view_tt make_gt_device_view(const Array& array); } // namespace gridtools diff --git a/src/atlas/array/gridtools/GridToolsTraits.h b/src/atlas/array/gridtools/GridToolsTraits.h index 9079a4c0d..d75da0b20 100644 --- a/src/atlas/array/gridtools/GridToolsTraits.h +++ b/src/atlas/array/gridtools/GridToolsTraits.h @@ -38,7 +38,7 @@ using data_view_tt = ::gridtools::data_view< gridtools::storage_traits::storage_info_t<0, Rank> >, AccessMode>; -constexpr ::gridtools::access_mode get_access_mode(bool readonly) { +inline constexpr ::gridtools::access_mode get_access_mode(bool readonly) { return readonly ? ::gridtools::access_mode::ReadOnly : ::gridtools::access_mode::ReadWrite; } diff --git a/src/atlas/array_fwd.h b/src/atlas/array_fwd.h index 412a743cc..ea826d578 100644 --- a/src/atlas/array_fwd.h +++ b/src/atlas/array_fwd.h @@ -27,22 +27,22 @@ class ArrayT; template class StorageView; -template +template class ArrayView; template class IndexView; template -ArrayView +ArrayView make_view(const Array& array); template -ArrayView +ArrayView make_host_view(const Array& array); template -ArrayView +ArrayView make_device_view(const Array& array); template diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 299f1e33b..263572a2f 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -110,13 +110,13 @@ class HaloExchange: public eckit::Owned { }; -template -constexpr typename boost::enable_if_c< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { +template +constexpr typename boost::enable_if_c< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { return 1; } -template -constexpr typename boost::disable_if_c< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { +template +constexpr typename boost::disable_if_c< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { return get_var_size(field) * field.template length(); } @@ -169,6 +169,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const auto field_dv = on_device ? array::make_device_view(field) : array::make_host_view(field); + /// Pack pack_send_buffer(field_dv,send_buffer); @@ -209,6 +210,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const } } } + } template From 7226d7fc89fdf3891f8a870127b656fc86e5fcc9 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 31 Oct 2017 12:05:06 +0100 Subject: [PATCH 094/355] adding the support for readonly views to the native views --- src/atlas/array/native/NativeArrayView.cc | 27 +++++---- src/atlas/array/native/NativeArrayView.h | 10 ++-- src/atlas/array/native/NativeMakeView.cc | 68 +++++++++++------------ src/atlas/parallel/HaloExchange.h | 11 ++-- src/atlas/parallel/HaloExchangeCUDA.h | 27 +++++++-- 5 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/atlas/array/native/NativeArrayView.cc b/src/atlas/array/native/NativeArrayView.cc index 88dc5559b..8ca95b5c2 100644 --- a/src/atlas/array/native/NativeArrayView.cc +++ b/src/atlas/array/native/NativeArrayView.cc @@ -19,8 +19,8 @@ namespace array { //------------------------------------------------------------------------------------------------------ -template -void ArrayView::assign(const value_type& value) { +template +void ArrayView::assign(const value_type& value) { ASSERT( contiguous() ); value_type* raw_data = data(); for( size_t j=0; j::assign(const value_type& value) { //------------------------------------------------------------------------------------------------------ -template -void ArrayView::assign(const std::initializer_list& list) { +template +void ArrayView::assign(const std::initializer_list& list) { ASSERT( contiguous() ); ASSERT( list.size() == size_ ); value_type* raw_data = data(); @@ -43,8 +43,8 @@ void ArrayView::assign(const std::initializer_list& list //------------------------------------------------------------------------------------------------------ -template -void ArrayView::dump(std::ostream& os) const { +template +void ArrayView::dump(std::ostream& os) const { ASSERT( contiguous() ); const value_type* data_ = data(); os << "size: " << size() << " , values: "; @@ -65,11 +65,16 @@ os << "]"; namespace atlas { namespace array { #define EXPLICIT_TEMPLATE_INSTANTIATION(Rank) \ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ // For each NDims in [1..9] EXPLICIT_TEMPLATE_INSTANTIATION(1) diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index b64089477..c95240f80 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -63,7 +63,7 @@ namespace array { //------------------------------------------------------------------------------------------------------ -template class ArrayView { +template class ArrayView { public: // -- Type definitions @@ -227,8 +227,8 @@ template class ArrayView { template struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; + Slicer(ArrayView const& av) : av_(av) {} + ArrayView const& av_; ReturnType apply(const size_t i) const { return LocalView(av_.data_ + av_.strides_[0] * i, av_.shape_.data() + 1, av_.strides_.data() + 1); } @@ -236,8 +236,8 @@ template class ArrayView { template struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; + Slicer(ArrayView const& av) : av_(av) {} + ArrayView const& av_; ReturnType apply(const size_t i) const { return *(av_.data_ + av_.strides_[0] * i); } diff --git a/src/atlas/array/native/NativeMakeView.cc b/src/atlas/array/native/NativeMakeView.cc index 21fce568c..c30d772d2 100644 --- a/src/atlas/array/native/NativeMakeView.cc +++ b/src/atlas/array/native/NativeMakeView.cc @@ -31,14 +31,14 @@ namespace { //------------------------------------------------------------------------------ template -ArrayView +ArrayView make_host_view(const Array& array) { - return ArrayView((const Value*)(array.storage()),array.shape()); + return ArrayView((const Value*)(array.storage()),array.shape()); } template -ArrayView +ArrayView make_device_view(const Array& array) { return make_host_view(array); } @@ -74,7 +74,7 @@ make_indexview(const Array& array) { template -ArrayView +ArrayView make_view(const Array& array) { check_metadata(array); return make_host_view(array); @@ -98,38 +98,38 @@ make_storageview(const Array& array) { namespace atlas { namespace array { #define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ \ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ \ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ template IndexView make_indexview(const Array&);\ template IndexView make_indexview(const Array&);\ diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 263572a2f..6355533fa 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -288,10 +288,8 @@ void HaloExchange::pack_send_buffer( const array::ArrayView& fi array::SVector& send_buffer ) const { ATLAS_TRACE(); - size_t ibuf = 0; - #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - pack_send_cuda(sendcnt_, sendmap_, field, send_buffer); + halo_packer_cuda::pack(sendcnt_, sendmap_, field, send_buffer); #else halo_packer::pack(sendcnt_, sendmap_, field, send_buffer); #endif @@ -302,9 +300,12 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf array::ArrayView& field) const { ATLAS_TRACE(); - size_t ibuf = 0; - halo_packer::unpack(recvcnt_, recvmap_, field, recv_buffer); +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + halo_packer_cuda::unpack(sendcnt_, recvmap_, field, recv_buffer); +#else + halo_packer::unpack(recvcnt_, recvmap_, field, recv_buffer); +#endif } diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index db72a9c5c..64da16f54 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -31,10 +31,13 @@ __global__ void pack_kernel(int sendcnt, array::SVector sendmap, } #endif -template -void pack_send_cuda( const int sendcnt, array::SVector const & sendmap, +template +struct halo_packer_cuda { + + template + static void pack( const int sendcnt, array::SVector const & sendmap, const array::ArrayView& field, array::SVector& send_buffer ) -{ + { #ifdef __CUDACC__ const unsigned int block_size_x = 32; const unsigned int block_size_y = 4; @@ -43,7 +46,23 @@ void pack_send_cuda( const int sendcnt, array::SVector const & sendmap, pack_kernel<<>>(sendcnt, sendmap, field, send_buffer); #endif -} + } + + template + static void unpack( const int sendcnt, array::SVector const & recvmap, + const array::ArrayView& field, array::SVector& recv_buffer ) + { +#ifdef __CUDACC__ + const unsigned int block_size_x = 32; + const unsigned int block_size_y = 4; + dim3 threads(block_size_x, block_size_y); + dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (field.data_view().template length<1>()+block_size_y-1)/block_size_y); + + unpack_kernel<<>>(sendcnt, recvmap, field, recv_buffer); +#endif + } + +}; } // namespace paralllel From ce768376a1a9be23249dabd371a3bd2a6769a119 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 31 Oct 2017 12:08:17 +0100 Subject: [PATCH 095/355] replace boost enable_if by std to avoid dependency with boost --- src/atlas/parallel/HaloExchange.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 6355533fa..de1bd2b0a 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -111,12 +111,12 @@ class HaloExchange: public eckit::Owned { }; template -constexpr typename boost::enable_if_c< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { +constexpr typename std::enable_if< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { return 1; } template -constexpr typename boost::disable_if_c< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { +constexpr typename std::enable_if< (cnt != RANK), size_t >::type get_var_size( array::ArrayView& field) { return get_var_size(field) * field.template length(); } From a654d58f36da56eb3cf0a843fe69ece8edfa8605 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 31 Oct 2017 13:23:38 +0100 Subject: [PATCH 096/355] adapt the native to latest API changes --- src/apps/atlas-benchmark.cc | 2 +- src/atlas/array/gridtools/GridToolsArrayView.h | 4 ++-- src/atlas/array/native/NativeArrayView.h | 5 ++++- src/atlas/array_fwd.h | 2 +- src/atlas/parallel/HaloExchange.h | 9 +++++---- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index b29a234e9..ef58f6f39 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -466,7 +466,7 @@ void AtlasBenchmark::iteration() // halo-exchange Trace halo( Here(), "halo-exchange"); - nodes_fs.halo_exchange().execute(grad); + nodes_fs.halo_exchange().execute(grad_field.array()); halo.stop(); t.stop(); diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index ad04e2c1f..7f5a64511 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -24,7 +24,7 @@ namespace atlas { namespace array { -template< typename Value, int Rank, bool ReadOnly > class ArrayView { +template< typename Value, int Rank, bool ReadOnly = false > class ArrayView { public: // -- Type definitions using value_type = typename remove_const::type; @@ -78,7 +78,7 @@ template< typename Value, int Rank, bool ReadOnly > class ArrayView { } template - size_t length() const { + size_t shape() const { return gt_data_view_.template length(); } diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index c95240f80..d6ee2a357 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -63,7 +63,7 @@ namespace array { //------------------------------------------------------------------------------------------------------ -template class ArrayView { +template class ArrayView { public: // -- Type definitions @@ -146,6 +146,9 @@ template class ArrayView { return Slicer(*this).apply(i); } + template + size_t shape() const { return shape(Dim);} + size_t size() const { return size_;} size_t rank() const { return Rank; } diff --git a/src/atlas/array_fwd.h b/src/atlas/array_fwd.h index ea826d578..6cf09825e 100644 --- a/src/atlas/array_fwd.h +++ b/src/atlas/array_fwd.h @@ -27,7 +27,7 @@ class ArrayT; template class StorageView; -template +template class ArrayView; template diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index de1bd2b0a..8a0d505f4 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -24,6 +24,7 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/mpi/Statistics.h" +#include "atlas/array_fwd.h" #include "atlas/array/ArrayView.h" #include "atlas/array/SVector.h" #include "atlas/runtime/Log.h" @@ -57,7 +58,7 @@ class HaloExchange: public eckit::Owned { // void execute( DATA_TYPE field[], size_t nb_vars ) const; template - void execute( array::Array& field, bool on_device ) const; + void execute( array::Array& field, bool on_device = false) const; // template // void execute( array::ArrayView&& field ) const; @@ -117,7 +118,7 @@ constexpr typename std::enable_if< (cnt == RANK), size_t >::type get_var_size( a template constexpr typename std::enable_if< (cnt != RANK), size_t >::type get_var_size( array::ArrayView& field) { - return get_var_size(field) * field.template length(); + return get_var_size(field) * field.template shape(); } template @@ -218,7 +219,7 @@ struct halo_packer_impl { template static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx... idxs) { - for( size_t i=0; i< field.data_view().template length(); ++i ) { + for( size_t i=0; i< field.template shape(); ++i ) { halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); } } @@ -239,7 +240,7 @@ struct halo_unpacker_impl { template static void apply(size_t& buf_idx, const size_t node_idx, array::ArrayView& field, array::SVector const & recv_buffer, Idx... idxs) { - for( size_t i=0; i< field.data_view().template length(); ++i ) { + for( size_t i=0; i< field.template shape(); ++i ) { halo_unpacker_impl::apply(buf_idx, node_idx, field, recv_buffer, idxs..., i); } } From 47df41c5eee60b7d6e3eb99ddf77468efd7a7530 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 31 Oct 2017 18:18:22 +0100 Subject: [PATCH 097/355] fix in native make array and add a test --- src/atlas/array/native/NativeArrayView.h | 11 +++++++ src/atlas/array/native/NativeMakeView.cc | 2 +- src/tests/array/test_array.cc | 38 ++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index d6ee2a357..69ddfd88a 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -91,6 +91,16 @@ template class ArrayView { } } + ArrayView( const value_type* data, const ArrayShape& shape, const ArrayStrides& strides ) : + data_(const_cast(data)) { + size_ = 1; + for( int j=0; j(data)) { size_ = 1; @@ -121,6 +131,7 @@ template class ArrayView { template < typename... Ints > const value_type& operator()(Ints... idx) const { + return data_[index(idx...)]; } diff --git a/src/atlas/array/native/NativeMakeView.cc b/src/atlas/array/native/NativeMakeView.cc index c30d772d2..5085f69e4 100644 --- a/src/atlas/array/native/NativeMakeView.cc +++ b/src/atlas/array/native/NativeMakeView.cc @@ -33,7 +33,7 @@ namespace { template ArrayView make_host_view(const Array& array) { - return ArrayView((const Value*)(array.storage()),array.shape()); + return ArrayView((const Value*)(array.storage()),array.shape(), array.strides()); } diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 18d582781..c0dc9f622 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -13,6 +13,7 @@ #include "atlas/array/MakeView.h" #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" +#include "eckit/memory/SharedPtr.h" using namespace atlas::array; using namespace eckit::testing; @@ -74,6 +75,7 @@ CASE("test_make_view") { } #endif + CASE("test_localview") { Array* ds = Array::create(8ul, 4ul, 2ul); auto hv = make_host_view(*ds); @@ -532,6 +534,42 @@ CASE("test_valid") { } } +CASE("test_wrap") { + + array::ArrayT arr_t(3,2); + EXPECT(arr_t.shape(0) == 3); + EXPECT(arr_t.stride(0) == 2); + EXPECT(arr_t.shape(1) == 2); + EXPECT(arr_t.stride(1) == 1); + EXPECT(arr_t.rank() == 2); + + array::ArrayView arrv_t = array::make_view(arr_t); + for(size_t i=0; i < arrv_t.shape(0); ++i) + { + for(size_t j=0; j < arrv_t.shape(1); ++j) + { + arrv_t(i,j) = i*10+j-1; + } + } + + eckit::SharedPtr arr ( array::Array::wrap(arrv_t.data(), + array::ArraySpec{array::make_shape(3), array::make_strides(2) } ) ); + + EXPECT(arr->shape(0) == 3); + EXPECT(arr->stride(0) == 2); + EXPECT(arr->rank() == 1); + + auto view = make_host_view(*arr); + + EXPECT(view.shape(0) == 3); + EXPECT(view.stride(0) == 2); + EXPECT(view.rank() == 1); + + EXPECT(view(0) == -1); + EXPECT(view(1) == 9); + EXPECT(view(2) == 19); +} + //----------------------------------------------------------------------------- } // namespace test From 0aea19c0c652c626c55a503f256d94dcbffb0679 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 31 Oct 2017 18:24:53 +0100 Subject: [PATCH 098/355] simplify API of the native array view --- src/atlas/array/native/NativeArrayView.h | 32 +----------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 69ddfd88a..67ca661b2 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -80,17 +80,7 @@ template class ArrayView { shape_(other.shape_), strides_(other.strides_) { } - - ArrayView( const value_type* data, const size_t shape[], const size_t strides[] ) : - data_(const_cast(data)) { - size_ = 1; - for( int j=0; j(data)) { size_ = 1; @@ -101,26 +91,6 @@ template class ArrayView { } } - ArrayView( const value_type* data, const size_t shape[] ) : - data_(const_cast(data)) { - size_ = 1; - for( int j=Rank-1; j>=0; --j ) { - shape_[j] = shape[j]; - strides_[j] = size_; - size_ *= shape_[j]; - } - } - - ArrayView( const value_type* data, const ArrayShape& shape ) : - data_(const_cast(data)) { - size_ = 1; - for( int j=Rank-1; j>=0; --j ) { - shape_[j] = shape[j]; - strides_[j] = size_; - size_ *= shape_[j]; - } - } - // -- Access methods template < typename... Idx > From be1d47b463c50e221bd5f01b9baf08159cfdbef5 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 31 Oct 2017 18:31:12 +0100 Subject: [PATCH 099/355] add test as mpi test --- src/atlas/parallel/HaloExchangeCUDA.h | 17 ++++++++++++++++- src/tests/parallel/CMakeLists.txt | 6 +++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index 64da16f54..4f53fb819 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -29,6 +29,21 @@ __global__ void pack_kernel(int sendcnt, array::SVector sendmap, send_buffer[buff_idx] = field(p, i); } + +template +__global__ void unpack_kernel(int sendcnt, array::SVector recvmap, + const array::SVector recv_buffer, array::ArrayView field) { + + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + + if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; + + const size_t buff_idx = field.data_view().template length<1>() * p + i; + + field(p, i) = send_buffer[buff_idx]; +} + #endif template @@ -58,7 +73,7 @@ struct halo_packer_cuda { dim3 threads(block_size_x, block_size_y); dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (field.data_view().template length<1>()+block_size_y-1)/block_size_y); - unpack_kernel<<>>(sendcnt, recvmap, field, recv_buffer); + unpack_kernel<<>>(sendcnt, recvmap, recv_buffer, field); #endif } diff --git a/src/tests/parallel/CMakeLists.txt b/src/tests/parallel/CMakeLists.txt index b4a93be76..52cccb02e 100644 --- a/src/tests/parallel/CMakeLists.txt +++ b/src/tests/parallel/CMakeLists.txt @@ -20,9 +20,9 @@ ecbuild_add_test( TARGET atlas_test_gather LIBS atlas ) -ecbuild_add_test( - TARGET atlas_test_haloexchange_gpu - BOOST +ecbuild_add_test( TARGET atlas_test_haloexchange_gpu + MPI 3 + CONDITION ECKIT_HAVE_MPI SOURCES test_haloexchange_gpu.cc LIBS atlas ) From b6600ce146d535f045cd1b41fab38f7b8a904f21 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 31 Oct 2017 18:34:25 +0100 Subject: [PATCH 100/355] fix in the gpu kernel --- src/atlas/parallel/HaloExchangeCUDA.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index 4f53fb819..4d6227d7d 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -27,7 +27,7 @@ __global__ void pack_kernel(int sendcnt, array::SVector sendmap, const size_t buff_idx = field.data_view().template length<1>() * p + i; - send_buffer[buff_idx] = field(p, i); + send_buffer[buff_idx] = field(sendmap[p], i); } template @@ -41,7 +41,7 @@ __global__ void unpack_kernel(int sendcnt, array::SVector recvmap, const size_t buff_idx = field.data_view().template length<1>() * p + i; - field(p, i) = send_buffer[buff_idx]; + field(sendmap[p], i) = recv_buffer[buff_idx]; } #endif From fd84f95b223f392dcca5de48473207a490d04c14 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 31 Oct 2017 18:35:43 +0100 Subject: [PATCH 101/355] fix in fn call --- src/atlas/parallel/HaloExchange.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 8a0d505f4..01d048d4a 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -305,7 +305,7 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA halo_packer_cuda::unpack(sendcnt_, recvmap_, field, recv_buffer); #else - halo_packer::unpack(recvcnt_, recvmap_, field, recv_buffer); + halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, field); #endif } From 45f3a16da4ef47e3e096f623b01a33a4d0b89640 Mon Sep 17 00:00:00 2001 From: cosunae Date: Tue, 31 Oct 2017 18:38:51 +0100 Subject: [PATCH 102/355] fix map --- src/atlas/parallel/HaloExchangeCUDA.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index 4d6227d7d..2d88d01b9 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -41,7 +41,7 @@ __global__ void unpack_kernel(int sendcnt, array::SVector recvmap, const size_t buff_idx = field.data_view().template length<1>() * p + i; - field(sendmap[p], i) = recv_buffer[buff_idx]; + field(recvmap[p], i) = recv_buffer[buff_idx]; } #endif From 184dab396e0ec5a2b7bbed66cd5e2b874517bbef Mon Sep 17 00:00:00 2001 From: cosunae Date: Tue, 31 Oct 2017 18:42:54 +0100 Subject: [PATCH 103/355] reorder the arguments --- src/atlas/parallel/HaloExchange.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 01d048d4a..bb7ad3a5e 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -238,8 +238,8 @@ struct halo_packer_impl<0, CurrentDim> { template struct halo_unpacker_impl { template - static void apply(size_t& buf_idx, const size_t node_idx, array::ArrayView& field, - array::SVector const & recv_buffer, Idx... idxs) { + static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, + array::ArrayView& field, Idx... idxs) { for( size_t i=0; i< field.template shape(); ++i ) { halo_unpacker_impl::apply(buf_idx, node_idx, field, recv_buffer, idxs..., i); } @@ -249,8 +249,8 @@ struct halo_unpacker_impl { template struct halo_unpacker_impl<0, CurrentDim> { template - static void apply(size_t& buf_idx, size_t node_idx, array::ArrayView& field, - array::SVector const & recv_buffer, Idx...idxs) + static void apply(size_t& buf_idx, size_t node_idx, array::SVector const & recv_buffer, + array::ArrayView& field, Idx...idxs) { field(node_idx, idxs...) = recv_buffer[buf_idx++]; } @@ -272,13 +272,13 @@ struct halo_packer { template static void unpack(const unsigned int recvcnt, array::SVector const & recvmap, - array::ArrayView& field, array::SVector const & recv_buffer ) + array::SVector const & recv_buffer, array::ArrayView& field ) { size_t ibuf = 0; for(int p=0; p < recvcnt; ++p) { const size_t pp = recvmap[p]; - halo_unpacker_impl::apply(ibuf, pp, field, recv_buffer); + halo_unpacker_impl::apply(ibuf, pp, recv_buffer, field); } } @@ -303,7 +303,7 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - halo_packer_cuda::unpack(sendcnt_, recvmap_, field, recv_buffer); + halo_packer_cuda::unpack(sendcnt_, recvmap_, recv_buffer, field); #else halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, field); #endif From 21b49ab8dcc671dd3420427fbd7f25d55f3489f7 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Wed, 1 Nov 2017 01:55:14 +0100 Subject: [PATCH 104/355] move kernel headers to a translation unit --- src/atlas/CMakeLists.txt | 9 +-- src/atlas/parallel/HaloExchange.h | 4 +- src/atlas/parallel/HaloExchangeCUDA.cu | 108 +++++++++++++++++++++++++ src/atlas/parallel/HaloExchangeCUDA.h | 68 +++------------- 4 files changed, 123 insertions(+), 66 deletions(-) create mode 100644 src/atlas/parallel/HaloExchangeCUDA.cu diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index a46543033..530a3daf5 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -430,6 +430,7 @@ parallel/Checksum.cc parallel/Checksum.h parallel/GatherScatter.cc parallel/GatherScatter.h +parallel/HaloExchange.cc parallel/HaloExchange.h parallel/mpi/Buffer.h runtime/ErrorHandling.cc @@ -448,12 +449,6 @@ util/Rotation.h util/detail/BlackMagic.h ) -if( NOT ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) - list( APPEND atlas_util_srcs - parallel/HaloExchange.cc - ) -endif() - list( APPEND atlas_internals_srcs mesh/detail/AccumulateFacets.h mesh/detail/AccumulateFacets.cc @@ -560,7 +555,7 @@ if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) array/gridtools/GridToolsArrayView.cu array/gridtools/GridToolsIndexView.cu mesh/Connectivity.cu - parallel/HaloExchange.cu + parallel/HaloExchangeCUDA.cu ) endif() diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 01d048d4a..a555407f8 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -290,7 +290,7 @@ void HaloExchange::pack_send_buffer( const array::ArrayView& fi { ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - halo_packer_cuda::pack(sendcnt_, sendmap_, field, send_buffer); + halo_packer_cuda::pack(sendcnt_, sendmap_, field, send_buffer); #else halo_packer::pack(sendcnt_, sendmap_, field, send_buffer); #endif @@ -303,7 +303,7 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - halo_packer_cuda::unpack(sendcnt_, recvmap_, field, recv_buffer); + halo_packer_cuda::unpack(sendcnt_, recvmap_, recv_buffer, field); #else halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, field); #endif diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu new file mode 100644 index 000000000..ff623651d --- /dev/null +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -0,0 +1,108 @@ +/* + * (C) Copyright 1996-2017 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 "HaloExchangeCUDA.h" + +namespace atlas { +namespace parallel { + +template +__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, + const array::ArrayView field, array::SVector send_buffer, + typename std::enable_if::type* = 0) { + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + + if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; + + const size_t buff_idx = field.data_view().template length<1>() * p + i; + + send_buffer[buff_idx] = field(sendmap[p], i); +} + +template +__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, + const array::ArrayView field, array::SVector send_buffer, + typename std::enable_if::type* = 0) { +} + +template +__global__ void unpack_kernel(const int sendcnt, const array::SVector recvmap, + const array::SVector recv_buffer, array::ArrayView field, + typename std::enable_if::type* = 0) { + + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + + if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; + + const size_t buff_idx = field.data_view().template length<1>() * p + i; + + field(recvmap[p], i) = recv_buffer[buff_idx]; +} + +template +__global__ void unpack_kernel(const int sendcnt, const array::SVector recvmap, + const array::SVector recv_buffer, array::ArrayView field, + typename std::enable_if::type* = 0) { +} + +template +void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, + const array::ArrayView& field, array::SVector& send_buffer ) +{ +} + +template +void halo_packer_cuda::unpack(const int sendcnt, array::SVector const & recvmap, + const array::SVector &recv_buffer , + array::ArrayView &field) +{ +} + +template +void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, + const array::ArrayView& field, array::SVector& send_buffer ) +{ + const unsigned int block_size_x = 32; + const unsigned int block_size_y = 4; + dim3 threads(block_size_x, block_size_y); + dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (field.data_view().template length<1>()+block_size_y-1)/block_size_y); + + pack_kernel<<>>(sendcnt, sendmap, field, send_buffer); +} + +template +void halo_packer_cuda::unpack(const int sendcnt, array::SVector const & recvmap, + const array::SVector &recv_buffer , + array::ArrayView &field) +{ + const unsigned int block_size_x = 32; + const unsigned int block_size_y = 4; + dim3 threads(block_size_x, block_size_y); + dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (field.data_view().template length<1>()+block_size_y-1)/block_size_y); + + unpack_kernel<<>>(sendcnt, recvmap, recv_buffer, field); +} + +#define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ +template class halo_packer_cuda; \ +template class halo_packer_cuda; \ +template class halo_packer_cuda; \ +template class halo_packer_cuda; \ +template class halo_packer_cuda; \ + + EXPLICIT_TEMPLATE_INSTANTIATION(1) + EXPLICIT_TEMPLATE_INSTANTIATION(2) + EXPLICIT_TEMPLATE_INSTANTIATION(3) + EXPLICIT_TEMPLATE_INSTANTIATION(4) + +} //namespace array +} //namespace atlas diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index 4d6227d7d..b8bb88d22 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -15,68 +15,22 @@ namespace atlas { namespace parallel { -#ifdef __CUDACC__ template -__global__ void pack_kernel(int sendcnt, array::SVector sendmap, - const array::ArrayView field, array::SVector send_buffer) { - - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - - if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; - - const size_t buff_idx = field.data_view().template length<1>() * p + i; - - send_buffer[buff_idx] = field(sendmap[p], i); -} - -template -__global__ void unpack_kernel(int sendcnt, array::SVector recvmap, - const array::SVector recv_buffer, array::ArrayView field) { - - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - - if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; - - const size_t buff_idx = field.data_view().template length<1>() * p + i; - - field(sendmap[p], i) = recv_buffer[buff_idx]; -} - -#endif - -template struct halo_packer_cuda { + static void pack( const int sendcnt, array::SVector const & sendmap, + const array::ArrayView& field, array::SVector& send_buffer ); - template - static void pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ) - { -#ifdef __CUDACC__ - const unsigned int block_size_x = 32; - const unsigned int block_size_y = 4; - dim3 threads(block_size_x, block_size_y); - dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (field.data_view().template length<1>()+block_size_y-1)/block_size_y); - - pack_kernel<<>>(sendcnt, sendmap, field, send_buffer); -#endif - } - - template - static void unpack( const int sendcnt, array::SVector const & recvmap, - const array::ArrayView& field, array::SVector& recv_buffer ) - { -#ifdef __CUDACC__ - const unsigned int block_size_x = 32; - const unsigned int block_size_y = 4; - dim3 threads(block_size_x, block_size_y); - dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (field.data_view().template length<1>()+block_size_y-1)/block_size_y); + static void unpack( const int sendcnt, array::SVector const & recvmap, + const array::SVector& recv_buffer, array::ArrayView& field ); +}; - unpack_kernel<<>>(sendcnt, recvmap, recv_buffer, field); -#endif - } +template +struct halo_packer_cuda { + static void pack( const int sendcnt, array::SVector const & sendmap, + const array::ArrayView& field, array::SVector& send_buffer ); + static void unpack( const int sendcnt, array::SVector const & recvmap, + const array::SVector& recv_buffer, array::ArrayView& field ); }; From dfb910f768c896b99a2ad0fb0d904ab16b164221 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 1 Nov 2017 16:37:56 +0000 Subject: [PATCH 105/355] Compatibility with gridtools --- CMakeLists.txt | 9 +-- src/atlas/CMakeLists.txt | 5 +- src/atlas/array/gridtools/GridToolsArray.cc | 1 + .../array/gridtools/GridToolsArrayHelpers.h | 1 - .../array/gridtools/GridToolsArrayView.cc | 40 ++++++++--- .../array/gridtools/GridToolsArrayView.h | 10 ++- src/atlas/array/helpers/ArrayAssigner.h | 71 +++++++++++++++++++ src/atlas/array/helpers/ArrayInitializer.h | 21 +++--- src/atlas/mesh/Connectivity.cc | 5 +- src/atlas/mesh/Connectivity.h | 20 +++--- .../meshgenerator/StructuredMeshGenerator.cc | 2 +- src/tests/AtlasTestEnvironment.h | 1 + src/tests/array/test_array.cc | 12 ++-- src/tests/array/test_array_kernel.cu | 23 +++--- src/tests/array/test_vector_kernel.cu | 34 +++++---- src/tests/mesh/test_connectivity_kernel.cu | 43 ++++++----- 16 files changed, 211 insertions(+), 87 deletions(-) create mode 100644 src/atlas/array/helpers/ArrayAssigner.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 47bee8d8c..f24ee543e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,18 +121,19 @@ endif() ### FIND GRIDTOOLS STORAGE ecbuild_add_option( - FEATURE GRIDTOOLS_STORAGE - DESCRIPTION "Arrays internally use GridTools storage layer" - REQUIRED_PACKAGES "gridtools_storage" ) + FEATURE GRIDTOOLS_STORAGE + DESCRIPTION "Arrays internally use GridTools storage layer" + REQUIRED_PACKAGES "gridtools_storage" ) + if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) + set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST 1 ) set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA 0 ) if( GRIDTOOLS_HAVE_CUDA ) ecbuild_info( "Gridtools found with CUDA support" ) - set( CUDA_NVCC_FLAGS "--relaxed-constexpr" "${CUDA_NVCC_FLAGS}" ) set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST 0 ) set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA 1 ) endif() diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 2643ce88f..223fc63f7 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -382,6 +382,7 @@ array/LocalView.h array/StorageView.h array/Vector.h array/helpers/ArrayInitializer.h +array/helpers/ArrayAssigner.h #array/Table.h #array/Table.cc #array/TableView.h @@ -496,8 +497,6 @@ function( use_cuda srclist ) cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${ARGN} ) set( use_cuda_srclist ${ARGN} ) - ecbuild_list_exclude_pattern( LIST ${srclist} REGEX ${use_cuda_srclist} ) - foreach( src ${use_cuda_srclist} ) create_cuda_wrapper( cuda_wrapper SOURCE ${src} ) list( APPEND ${srclist} ${cuda_wrapper} ) @@ -586,5 +585,5 @@ ecbuild_add_library( TARGET atlas ) if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) - target_link_libraries( atlas gridtools_storage ) + target_link_libraries( atlas gridtools::storage ) endif() diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index c6f3f667a..b64c81d5f 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -21,6 +21,7 @@ #include "atlas/array/gridtools/GridToolsTraits.h" #include "atlas/array/gridtools/GridToolsDataStore.h" #include "atlas/array/gridtools/GridToolsArrayHelpers.h" +#include "atlas/array/helpers/ArrayInitializer.h" #include "eckit/exception/Exceptions.h" diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index e8effa59b..da8b1b247 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -20,7 +20,6 @@ #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" #include "atlas/array/gridtools/GridToolsTraits.h" -#include "atlas/array/helpers/ArrayInitializer.h" #include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------ diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index fb2438e80..0f2f29893 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -8,13 +8,37 @@ * does it submit to any jurisdiction. */ +#include #include "atlas/array/gridtools/GridToolsArrayView.h" #include "atlas/array/gridtools/GridToolsArrayHelpers.h" +#include "atlas/array/helpers/ArrayInitializer.h" +#include "atlas/array/helpers/ArrayAssigner.h" #include "eckit/exception/Exceptions.h" namespace atlas { namespace array { +template< typename T > +struct private_vector { + + ATLAS_HOST_DEVICE private_vector( std::initializer_list list ) { + data_ = new T( list.size() ); + size_t i(0); + for( const T v : list ) { + data_[i++] = v; + } + } + ATLAS_HOST_DEVICE ~private_vector() { + delete data_; + } + + ATLAS_HOST_DEVICE const T* data() const { + return data_; + } + + T* data_; +}; + template< typename Value, int Rank > ArrayView::ArrayView( const ArrayView& other ) : gt_data_view_(other.gt_data_view_), data_store_orig_(other.data_store_orig_), array_(other.array_) { @@ -38,13 +62,15 @@ ArrayView::ArrayView(data_view_t data_view, const Array& array) : auto storage_info_ = *((reinterpret_cast(const_cast(array.storage())))->get_storage_info_ptr()); auto stridest = seq::template apply< - std::vector, + private_vector, atlas::array::gridtools::get_stride_component >::template get_component>( &(storage_info_)); - auto shapet = seq::template apply, atlas::array::gridtools::get_shape_component>(&(storage_info_)); + auto shapet = seq::template apply< + private_vector, + atlas::array::gridtools::get_shape_component>(&(storage_info_)); - std::memcpy(strides_, &(stridest[0]), sizeof(size_t)*Rank); - std::memcpy(shape_, &(shapet[0]), sizeof(size_t)*Rank); + std::memcpy(strides_, stridest.data(), sizeof(size_t)*Rank); + std::memcpy(shape_, shapet.data(), sizeof(size_t)*Rank); size_ = storage_info_.total_length(); } @@ -64,11 +90,7 @@ bool ArrayView::valid() const { template< typename Value, int Rank > void ArrayView::assign(const value_type& value) { - ASSERT( contiguous() ); - value_type* raw_data = data(); - for( size_t j=0; j::apply(*this,value); } template diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 6dcf209b4..9bc2211ba 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -52,8 +52,6 @@ template< typename Value, int Rank > class ArrayView { return gt_data_view_(c...); } - size_t shape(size_t idx) const { return shape_[idx]; } - const Slice operator[](size_t i) const { return Slicer(*this).apply(i); } @@ -93,6 +91,14 @@ template< typename Value, int Rank > class ArrayView { void assign(const std::initializer_list&); + const size_t* strides() const { return strides_; } + + const size_t* shape() const { return shape_; } + + size_t shape(size_t idx) const { return shape_[idx]; } + + size_t stride(size_t idx) const { return strides_[idx]; } + private: template diff --git a/src/atlas/array/helpers/ArrayAssigner.h b/src/atlas/array/helpers/ArrayAssigner.h new file mode 100644 index 000000000..9582dfeea --- /dev/null +++ b/src/atlas/array/helpers/ArrayAssigner.h @@ -0,0 +1,71 @@ +/* + * (C) Copyright 1996-2016 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/array.h" + +//------------------------------------------------------------------------------ + +namespace atlas { +namespace array { +namespace helpers { + +//------------------------------------------------------------------------------ + +/// Helper to assign a value to an array or arrayview +template +struct array_assigner; + +//------------------------------------------------------------------------------ + +// Recursive function to apply value to every index +template +struct array_assigner_impl { + template + static void apply(ArrayView& arr, Value value, DimIndex... idxs) { + for(size_t i=0; i < arr.shape(Dim); ++i) { + array_assigner_impl::apply( arr, value, idxs..., i ); + } + } +}; + +// End of recursion when Dim == Rank +template +struct array_assigner_impl { + template + static void apply(ArrayView& arr, Value value, DimIndex... idxs) { + arr(idxs...) = value; + } +}; + +//------------------------------------------------------------------------------ + + +template +struct array_assigner { + + template + static void apply(Array& arr, Value value) { + return apply( make_host_view(arr), value ); + } + + static void apply(ArrayView& arr, Value value) { + array_assigner_impl::apply( arr, value ); + // Note: no need to apply variadic pack (idxs...) + } + +}; + +//------------------------------------------------------------------------------ + +} // namespace helpers +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/helpers/ArrayInitializer.h b/src/atlas/array/helpers/ArrayInitializer.h index 3959f24b4..c4627ab8f 100644 --- a/src/atlas/array/helpers/ArrayInitializer.h +++ b/src/atlas/array/helpers/ArrayInitializer.h @@ -75,14 +75,13 @@ struct array_initializer_impl { template struct array_initializer { - template - static void apply(Array const& orig, Array& array_resized, DimIndex... idxs) { + static void apply(Array const& orig, Array& array_resized) { switch (orig.datatype().kind()) { - case DataType::KIND_REAL64: return array_initializer_impl::apply(orig, array_resized, idxs...); - case DataType::KIND_REAL32: return array_initializer_impl::apply(orig, array_resized, idxs...); - case DataType::KIND_INT32: return array_initializer_impl::apply(orig, array_resized, idxs...); - case DataType::KIND_INT64: return array_initializer_impl::apply(orig, array_resized, idxs...); - case DataType::KIND_UINT64: return array_initializer_impl::apply(orig, array_resized, idxs...); + case DataType::KIND_REAL64: return array_initializer_impl::apply(orig, array_resized); + case DataType::KIND_REAL32: return array_initializer_impl::apply(orig, array_resized); + case DataType::KIND_INT32: return array_initializer_impl::apply(orig, array_resized); + case DataType::KIND_INT64: return array_initializer_impl::apply(orig, array_resized); + case DataType::KIND_UINT64: return array_initializer_impl::apply(orig, array_resized); default: { std::stringstream err; err << "data kind " << orig.datatype().kind() << " not recognised."; @@ -140,10 +139,10 @@ template struct array_initializer_partitioned_impl { static void apply( Array const& orig, Array& dest, unsigned int pos, unsigned int offset) { switch (orig.datatype().kind()) { - case DataType::KIND_REAL64: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); - case DataType::KIND_REAL32: return array_initializer_partitioned_val_impl::apply(orig, dest,pos, offset ); - case DataType::KIND_INT32: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); - case DataType::KIND_INT64: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); + case DataType::KIND_REAL64: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); + case DataType::KIND_REAL32: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); + case DataType::KIND_INT32: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); + case DataType::KIND_INT64: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); case DataType::KIND_UINT64: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); default: { std::stringstream err; diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index a21a5a174..1931c89dc 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -142,7 +142,10 @@ void IrregularConnectivityImpl::clear() } else { - std::for_each(data_.begin(), data_.end(), [](array::Array* a){ a=0;}); + data_[_values_] = nullptr; + data_[_displs_] = nullptr; + data_[_counts_] = nullptr; +//std::for_each(data_.begin(), data_.end(), [](array::Array* a){ a=0;}); } maxcols_ = 0; mincols_ = std::numeric_limits::max(); diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 2ca7b7873..22772556d 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -98,18 +98,18 @@ class ConnectivityIndex public: enum { BASE = 1 }; public: - ConnectivityIndex(idx_t* idx): idx_(idx) {} - void set(const idx_t& value) { *(idx_) = value+BASE; } - idx_t get() const { return *(idx_)-BASE; } - void operator=(const idx_t& value) { set(value); } - ConnectivityIndex& operator=(const ConnectivityIndex& other) { set(other.get()); return *this; } - ConnectivityIndex& operator+(const idx_t& value) { *(idx_)+=value; return *this; } - ConnectivityIndex& operator-(const idx_t& value) { *(idx_)-=value; return *this; } - ConnectivityIndex& operator--() { --(*(idx_)); return *this; } - ConnectivityIndex& operator++() { ++(*(idx_)); return *this; } + ATLAS_HOST_DEVICE ConnectivityIndex(idx_t* idx): idx_(idx) {} + ATLAS_HOST_DEVICE void set(const idx_t& value) { *(idx_) = value+BASE; } + ATLAS_HOST_DEVICE idx_t get() const { return *(idx_)-BASE; } + ATLAS_HOST_DEVICE void operator=(const idx_t& value) { set(value); } + ATLAS_HOST_DEVICE ConnectivityIndex& operator=(const ConnectivityIndex& other) { set(other.get()); return *this; } + ATLAS_HOST_DEVICE ConnectivityIndex& operator+(const idx_t& value) { *(idx_)+=value; return *this; } + ATLAS_HOST_DEVICE ConnectivityIndex& operator-(const idx_t& value) { *(idx_)-=value; return *this; } + ATLAS_HOST_DEVICE ConnectivityIndex& operator--() { --(*(idx_)); return *this; } + ATLAS_HOST_DEVICE ConnectivityIndex& operator++() { ++(*(idx_)); return *this; } //implicit conversion - operator idx_t() const { return get(); } + ATLAS_HOST_DEVICE operator idx_t() const { return get(); } private: idx_t* idx_; diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 9a04fcec4..d4681ac99 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -300,13 +300,13 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co array::ArrayShape shape = array::make_shape(region.south-region.north, 4*rg.nxmax(), 4); region.elems.reset( array::Array::create(shape) ); - array::make_storageview(*region.elems).assign(-1); int nelems=0; region.nquads=0; region.ntriags=0; array::ArrayView elemview = array::make_view(*region.elems); + elemview.assign(-1); bool stagger = options.get("stagger"); for (int jlat=lat_north; jlat(as); - auto hv = atlas::array::gridtools::make_gt_host_view(*ds); + auto gt_hv = atlas::array::gridtools::make_gt_host_view(*ds); atlas::array::ArrayView atlas_hv = make_host_view(*ds); - hv(1, 1) = 4.5; + gt_hv(1, 1) = 4.5; - EXPECT(hv(1, 1) == 4.5); + EXPECT(gt_hv(1, 1) == 4.5); EXPECT(atlas_hv(1, 1) == 4.5); EXPECT(ds->size() == 6); EXPECT(ds->rank() == 2); - EXPECT(ds->stride(0) == 3); - EXPECT(ds->stride(1) == 1); + EXPECT(ds->stride(0) == gt_hv.storage_info().stride<0>()); + EXPECT(ds->stride(1) == gt_hv.storage_info().stride<1>()); EXPECT(ds->contiguous() == true); delete ds; @@ -506,6 +506,6 @@ CASE("test_valid") { int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return eckit::testing::run_tests ( argc, argv, false ); } diff --git a/src/tests/array/test_array_kernel.cu b/src/tests/array/test_array_kernel.cu index b802ceec8..c5bcea56e 100644 --- a/src/tests/array/test_array_kernel.cu +++ b/src/tests/array/test_array_kernel.cu @@ -8,34 +8,36 @@ * does it submit to any jurisdiction. */ -#define BOOST_TEST_MODULE TestArrayKernel #include -#include "ecbuild/boost_test_framework.h" #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "atlas/runtime/Log.h" +#include "tests/AtlasTestEnvironment.h" +#include "eckit/testing/Test.h" + using namespace atlas::array; +using namespace eckit::testing; namespace atlas { namespace test { template __global__ -void kernel_ex(ArrayView dv) +void kernel_ex(array::ArrayView dv) { dv(3, 3, 3) += 1; } -BOOST_AUTO_TEST_CASE( test_array ) +CASE( "test_array" ) { - Array* ds = Array::create(4ul, 4ul, 4ul); - ArrayView hv = make_host_view(*ds); + array::Array* ds = Array::create(4ul, 4ul, 4ul); + array::ArrayView hv = array::make_host_view(*ds); hv(3, 3, 3) = 4.5; ds->cloneToDevice(); - auto cv = make_device_view(*ds); + auto cv = array::make_device_view(*ds); kernel_ex<<<1,1>>>(cv); @@ -44,10 +46,15 @@ BOOST_AUTO_TEST_CASE( test_array ) ds->cloneFromDevice(); ds->reactivateHostWriteViews(); - BOOST_CHECK_EQUAL( hv(3, 3, 3) , 5.5 ); + EXPECT( hv(3, 3, 3) == 5.5 ); delete ds; } } } + +int main(int argc, char **argv) { + atlas::test::AtlasTestEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} diff --git a/src/tests/array/test_vector_kernel.cu b/src/tests/array/test_vector_kernel.cu index d963be2a5..4148d3a03 100644 --- a/src/tests/array/test_vector_kernel.cu +++ b/src/tests/array/test_vector_kernel.cu @@ -8,13 +8,18 @@ * does it submit to any jurisdiction. */ -#define BOOST_TEST_MODULE TestArrayKernel #include -#include "ecbuild/boost_test_framework.h" #include "atlas/array/Vector.h" #include "atlas/array/gridtools/GPUClonable.h" +#include "atlas/array.h" +#include "atlas/array/MakeView.h" +#include "atlas/runtime/Log.h" + +#include "tests/AtlasTestEnvironment.h" +#include "eckit/testing/Test.h" using namespace atlas::array; +using namespace eckit::testing; namespace atlas { namespace test { @@ -42,7 +47,7 @@ void kernel_ex(VectorView* list_ints ) } } -BOOST_AUTO_TEST_CASE( test_resize ) +CASE( "test_resize" ) { Vector list_ints(2); @@ -50,24 +55,24 @@ BOOST_AUTO_TEST_CASE( test_resize ) list_ints_h[0] = new int_gpu(3); list_ints_h[1] = new int_gpu(4); - BOOST_CHECK_EQUAL( list_ints_h[0]->val_ , 3 ); - BOOST_CHECK_EQUAL( list_ints_h[1]->val_ , 4 ); + EXPECT( list_ints_h[0]->val_ == 3 ); + EXPECT( list_ints_h[1]->val_ == 4 ); list_ints.resize(6); - BOOST_CHECK_EQUAL( list_ints_h.is_valid(list_ints) , false ); + EXPECT( list_ints_h.is_valid(list_ints) == false ); VectorView list_ints_h2 = make_host_vector_view(list_ints); - BOOST_CHECK_EQUAL( list_ints_h2[0]->val_ , 3 ); - BOOST_CHECK_EQUAL( list_ints_h2[1]->val_ , 4 ); - BOOST_CHECK_EQUAL( list_ints_h2.size() , 6 ); + EXPECT( list_ints_h2[0]->val_ == 3 ); + EXPECT( list_ints_h2[1]->val_ == 4 ); + EXPECT( list_ints_h2.size() == 6 ); } -BOOST_AUTO_TEST_CASE( test_vector_kernel ) +CASE( "test_vector_kernel" ) { Vector list_ints(4); @@ -91,11 +96,16 @@ BOOST_AUTO_TEST_CASE( test_vector_kernel ) if( cudaPeekAtLastError() != cudaSuccess) std::cout << "ERROR " << std::endl; list_ints.cloneFromDevice(); - BOOST_CHECK_EQUAL( list_ints_h[0]->val_ , 8 ); + EXPECT( list_ints_h[0]->val_ == 8 ); - BOOST_CHECK_THROW( list_ints.resize(6), eckit::AssertionFailed ); + EXPECT_THROWS_AS( list_ints.resize(6), eckit::AssertionFailed ); } } } + +int main(int argc, char **argv) { + atlas::test::AtlasTestEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} diff --git a/src/tests/mesh/test_connectivity_kernel.cu b/src/tests/mesh/test_connectivity_kernel.cu index 8b901eca9..22ad7c019 100644 --- a/src/tests/mesh/test_connectivity_kernel.cu +++ b/src/tests/mesh/test_connectivity_kernel.cu @@ -8,12 +8,12 @@ * does it submit to any jurisdiction. */ -#define BOOST_TEST_MODULE TestConnectivityKernel #include -#include "ecbuild/boost_test_framework.h" #include "atlas/mesh/Connectivity.h" +#include "tests/AtlasTestEnvironment.h" using namespace atlas::mesh; +using namespace eckit::testing; namespace atlas { namespace test { @@ -85,7 +85,7 @@ void kernel_multiblock(MultiBlockConnectivityImpl* conn_, bool* result) -BOOST_AUTO_TEST_CASE( test_block_connectivity ) +CASE( "test_block_connectivity" ) { BlockConnectivity conn; @@ -98,26 +98,26 @@ BOOST_AUTO_TEST_CASE( test_block_connectivity ) conn.add(2,5, vals2); conn.cloneToDevice(); - BOOST_CHECK( !conn.deviceNeedsUpdate() ); + EXPECT( !conn.deviceNeedsUpdate() ); kernel_block<<<1,1>>>(conn.gpu_object_ptr(), result); cudaDeviceSynchronize(); - BOOST_CHECK_EQUAL( *result , true ); + EXPECT( *result == true ); // copy back, although not strickly needed since the gpu copy does not modify values, // but for the sake of testing it conn.cloneFromDevice(); - BOOST_CHECK_EQUAL((conn)(0,4), 356 ); + EXPECT((conn)(0,4) == 356 ); } -BOOST_AUTO_TEST_CASE( test_irregular_connectivity ) +CASE( "test_irregular_connectivity" ) { IrregularConnectivity conn("mesh"); - BOOST_CHECK_EQUAL(conn.rows(),0); - BOOST_CHECK_EQUAL(conn.maxcols(),0); + EXPECT(conn.rows() == 0); + EXPECT(conn.maxcols() ==0); constexpr idx_t vals[6] = {1,3,4,3,7,8}; bool from_fortran = true; @@ -128,53 +128,58 @@ BOOST_AUTO_TEST_CASE( test_irregular_connectivity ) *result = true; conn.cloneToDevice(); - BOOST_CHECK( !conn.deviceNeedsUpdate() ); + EXPECT( !conn.deviceNeedsUpdate() ); kernel_irr<<<1,1>>>(conn.gpu_object_ptr(), result); cudaDeviceSynchronize(); - BOOST_CHECK_EQUAL( *result , true ); + EXPECT( *result == true ); // copy back, although not strickly needed since the gpu copy does not modify values, // but for the sake of testing it conn.cloneFromDevice(); - BOOST_CHECK_EQUAL(conn(0,1), 3 IN_FORTRAN); + EXPECT(conn(0,1) == 3 IN_FORTRAN); } -BOOST_AUTO_TEST_CASE( test_multiblock_connectivity ) +CASE( "test_multiblock_connectivity" ) { MultiBlockConnectivity conn("mesh"); - BOOST_CHECK_EQUAL(conn.rows(),0); - BOOST_CHECK_EQUAL(conn.maxcols(),0); + EXPECT(conn.rows() == 0); + EXPECT(conn.maxcols() == 0); constexpr idx_t vals[6] = {1,3,4,3,7,8}; bool from_fortran = true; conn.add(2, 3, vals, from_fortran); - BOOST_CHECK(conn.block(0)(0,0) == 1); + EXPECT(conn.block(0)(0,0) == 1); bool* result; cudaMallocManaged(&result, sizeof(bool)); *result = true; conn.cloneToDevice(); - BOOST_CHECK( !conn.deviceNeedsUpdate() ); + EXPECT( !conn.deviceNeedsUpdate() ); kernel_multiblock<<<1,1>>>(conn.gpu_object_ptr(), result); cudaDeviceSynchronize(); - BOOST_CHECK_EQUAL( *result , true ); + EXPECT( *result == true ); // copy back, although not strickly needed since the gpu copy does not modify values, // but for the sake of testing it conn.cloneFromDevice(); - BOOST_CHECK(conn.block(0)(0,0) == 1); + EXPECT(conn.block(0)(0,0) == 1); } } } + +int main(int argc, char **argv) { + atlas::test::AtlasTestEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} From 62b93c1f26aff340631a348f29be9184cfdc1cc4 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 1 Nov 2017 18:08:46 +0000 Subject: [PATCH 106/355] cleanup cuda compile --- cmake/atlas_host_device.cmake | 42 +++++++++++++++++++ src/atlas/CMakeLists.txt | 76 +++++------------------------------ 2 files changed, 52 insertions(+), 66 deletions(-) create mode 100644 cmake/atlas_host_device.cmake diff --git a/cmake/atlas_host_device.cmake b/cmake/atlas_host_device.cmake new file mode 100644 index 000000000..29d99774c --- /dev/null +++ b/cmake/atlas_host_device.cmake @@ -0,0 +1,42 @@ +function( create_cuda_wrapper variable ) + set( options "" ) + set( single_value_args SOURCE ) + set( multi_value_args "" ) + cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} ) + + get_filename_component(directory ${_PAR_SOURCE} DIRECTORY) + get_filename_component(base ${_PAR_SOURCE} NAME_WE) + get_filename_component(name ${_PAR_SOURCE} NAME) + if( directory ) + set(cuda_wrapper ${CMAKE_CURRENT_BINARY_DIR}/${directory}/${base}.cu) + else() + set(cuda_wrapper ${CMAKE_CURRENT_BINARY_DIR}/${base}.cu) + endif() + set(${variable} ${cuda_wrapper} PARENT_SCOPE) + set(content +" +#include \"atlas/${directory}/${name}\" +") + file(WRITE ${cuda_wrapper} "${content}") +endfunction() + + + +function( atlas_host_device srclist ) + set( options "" ) + set( single_value_args "" ) + set( multi_value_args SOURCES ) + cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${ARGN} ) + + if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) + set( use_cuda_srclist ${_PAR_SOURCES} ) + + foreach( src ${use_cuda_srclist} ) + create_cuda_wrapper( cuda_wrapper SOURCE ${src} ) + list( APPEND ${srclist} ${cuda_wrapper} ) + ecbuild_list_exclude_pattern( LIST ${srclist} REGEX ${src} ) + endforeach() + + set( ${srclist} "${${srclist}}" PARENT_SCOPE ) + endif() +endfunction() diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 223fc63f7..70032a5a5 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -201,6 +201,7 @@ endif() list( APPEND atlas_mesh_srcs mesh.h +mesh/Connectivity.cc mesh/Connectivity.h mesh/ElementType.cc mesh/ElementType.h @@ -263,13 +264,6 @@ mesh/actions/BuildTorusXYZField.h mesh/actions/BuildTorusXYZField.cc ) -if(NOT ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA) -list( APPEND atlas_mesh_srcs -mesh/Connectivity.cc -) -endif() - - list( APPEND atlas_output_srcs output/Output.h output/Output.cc @@ -393,22 +387,16 @@ list( APPEND atlas_array_srcs array/gridtools/GPUClonable.h array/gridtools/GridToolsArray.cc array/gridtools/GridToolsArrayHelpers.h +array/gridtools/GridToolsArrayView.cc array/gridtools/GridToolsArrayView.h array/gridtools/GridToolsDataStore.h +array/gridtools/GridToolsIndexView.cc array/gridtools/GridToolsIndexView.h array/gridtools/GridToolsMakeView.cc array/gridtools/GridToolsMakeView.h array/gridtools/GridToolsStorageView.h array/gridtools/GridToolsTraits.h ) - -if(NOT ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA) -list( APPEND atlas_array_srcs -array/gridtools/GridToolsArrayView.cc -array/gridtools/GridToolsIndexView.cc -) -endif() - else() list( APPEND atlas_array_srcs array/native/NativeArray.cc @@ -465,49 +453,6 @@ util/Unique.h #parallel/detail/MPLArrayView.h ) - -function( create_cuda_wrapper variable ) -set( options "" ) -set( single_value_args SOURCE ) -set( multi_value_args "" ) -cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${_FIRST_ARG} ${ARGN} ) - - get_filename_component(directory ${_PAR_SOURCE} DIRECTORY) - get_filename_component(base ${_PAR_SOURCE} NAME_WE) - get_filename_component(name ${_PAR_SOURCE} NAME) - if( directory ) - set(cuda_wrapper ${CMAKE_CURRENT_BINARY_DIR}/${directory}/${base}.cu) - else() - set(cuda_wrapper ${CMAKE_CURRENT_BINARY_DIR}/${base}.cu) - endif() - set(${variable} ${cuda_wrapper} PARENT_SCOPE) - set(content -" -#include \"atlas/${directory}/${name}\" -") - - file(WRITE ${cuda_wrapper} "${content}") - -endfunction() - -function( use_cuda srclist ) - set( options "" ) - set( single_value_args "" ) - set( multi_value_args "" ) - cmake_parse_arguments( _PAR "${options}" "${single_value_args}" "${multi_value_args}" ${ARGN} ) - set( use_cuda_srclist ${ARGN} ) - - foreach( src ${use_cuda_srclist} ) - create_cuda_wrapper( cuda_wrapper SOURCE ${src} ) - list( APPEND ${srclist} ${cuda_wrapper} ) - endforeach() - - set( ${srclist} "${${srclist}}" PARENT_SCOPE ) - - add_custom_target( atlas_cuda SOURCES ${use_cuda_srclist} ) - -endfunction() - ### atlas c++ library ecbuild_debug_var(CGAL_LIBRARIES) @@ -546,13 +491,13 @@ list( APPEND source_list ${CMAKE_CURRENT_BINARY_DIR}/library/defines.h ) -if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) - use_cuda( source_list - array/gridtools/GridToolsArrayView.cu - array/gridtools/GridToolsIndexView.cu - mesh/Connectivity.cu - ) -endif() +include( atlas_host_device ) +atlas_host_device( source_list + SOURCES + array/gridtools/GridToolsArrayView.cc + array/gridtools/GridToolsIndexView.cc + mesh/Connectivity.cc +) ecbuild_add_library( TARGET atlas @@ -579,7 +524,6 @@ ecbuild_add_library( TARGET atlas "${CGAL_LIBRARIES}" "${TRANSI_LIBRARIES}" "${FCKIT_LIBRARIES}" - "${CUDA_LIBRARIES}" DEFINITIONS ${ATLAS_DEFINITIONS} ) From 8f68aab6bd45da14bb60c10b6dcfa50fef116a2a Mon Sep 17 00:00:00 2001 From: cosunae Date: Thu, 2 Nov 2017 02:04:46 +0100 Subject: [PATCH 107/355] complete packing and adding hack to make MPI communication work in GPU --- src/atlas/parallel/HaloExchange.cu | 13 ----- src/atlas/parallel/HaloExchange.h | 68 ++++++++++++++++++++------ src/atlas/parallel/HaloExchangeCUDA.cu | 62 +++++++++++++++++------ src/atlas/parallel/HaloExchangeCUDA.h | 42 +++------------- 4 files changed, 107 insertions(+), 78 deletions(-) delete mode 100644 src/atlas/parallel/HaloExchange.cu diff --git a/src/atlas/parallel/HaloExchange.cu b/src/atlas/parallel/HaloExchange.cu deleted file mode 100644 index bbb9955e6..000000000 --- a/src/atlas/parallel/HaloExchange.cu +++ /dev/null @@ -1,13 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 "atlas/parallel/HaloExchange.cc" - diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 08b4beab8..4595e0da5 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -77,12 +77,14 @@ class HaloExchange: public eckit::Owned { template< typename DATA_TYPE, int RANK> - void pack_send_buffer( const array::ArrayView& field, + void pack_send_buffer( const array::ArrayView& hfield, + const array::ArrayView& dfield, array::SVector& send_buffer ) const; template< typename DATA_TYPE, int RANK> void unpack_recv_buffer(const array::SVector& recv_buffer, - array::ArrayView& field) const; + const array::ArrayView& hfield, + array::ArrayView& dfield) const; template void var_info( const array::ArrayView& arr, @@ -156,23 +158,53 @@ void HaloExchange::execute(array::Array& field, bool on_device) const recv_displs[jproc] = recvdispls_[jproc]*var_size; } + auto field_dv = on_device ? array::make_device_view(field) : + array::make_host_view(field); + +#ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + DATA_TYPE* recv_ptr; + if(on_device) { + cudaMallocManaged(&recv_ptr, recv_size * sizeof(DATA_TYPE)); + memcpy(recv_ptr, &(recv_buffer[0]), recv_size*sizeof(DATA_TYPE)); + cudaDeviceSynchronize(); + } + else { + DATA_TYPE* recv_ptr = &recv_buffer[0]; + } +#else + DATA_TYPE* recv_ptr = &recv_buffer[0]; +#endif + ATLAS_TRACE_MPI( IRECEIVE ) { /// Let MPI know what we like to receive for(int jproc=0; jproc < nproc; ++jproc) { if(recv_counts[jproc] > 0) { - recv_req[jproc] = parallel::mpi::comm().iReceive(&recv_buffer[recv_displs[jproc]], recv_counts[jproc], jproc, tag); + recv_req[jproc] = parallel::mpi::comm().iReceive(recv_ptr/*&recv_buffer[recv_displs[jproc]]*/, recv_counts[jproc], jproc, tag); } } } - auto field_dv = on_device ? array::make_device_view(field) : - array::make_host_view(field); + /// Pack + pack_send_buffer(field_hv, field_dv,send_buffer); + cudaDeviceSynchronize(); - /// Pack - pack_send_buffer(field_dv,send_buffer); + #ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + DATA_TYPE* send_ptr; + if(on_device) { + cudaMallocManaged(&send_ptr, send_size * sizeof(DATA_TYPE)); +// HACK this does not work +// memcpy(send_ptr, &(send_buffer[0]), send_size*sizeof(DATA_TYPE)); + cudaDeviceSynchronize(); + } + else { + DATA_TYPE* send_ptr = &send_buffer[0]; + } +#else + DATA_TYPE* send_ptr = &send_buffer[0]; +#endif /// Send ATLAS_TRACE_MPI( ISEND ) { @@ -180,9 +212,11 @@ void HaloExchange::execute(array::Array& field, bool on_device) const { if(send_counts[jproc] > 0) { - send_req[jproc] = parallel::mpi::comm().iSend( - &send_buffer[send_displs[jproc]], + send_req[jproc] = parallel::mpi::comm().iSend( + send_ptr/*&send_buffer[send_displs[jproc]]*/, send_counts[jproc], jproc, tag); + cudaDeviceSynchronize(); + } } } @@ -199,7 +233,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const } /// Unpack - unpack_recv_buffer(recv_buffer,field_dv); + unpack_recv_buffer(recv_buffer, field_hv, field_dv); /// Wait for sending to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { @@ -285,27 +319,29 @@ struct halo_packer { }; template -void HaloExchange::pack_send_buffer( const array::ArrayView& field, +void HaloExchange::pack_send_buffer( const array::ArrayView& hfield, + const array::ArrayView& dfield, array::SVector& send_buffer ) const { ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - halo_packer_cuda::pack(sendcnt_, sendmap_, field, send_buffer); + halo_packer_cuda::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); #else - halo_packer::pack(sendcnt_, sendmap_, field, send_buffer); + halo_packer::pack(sendcnt_, sendmap_, hfield, send_buffer); #endif } template void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buffer, - array::ArrayView& field) const + const array::ArrayView& hfield, + array::ArrayView& dfield) const { ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - halo_packer_cuda::unpack(sendcnt_, recvmap_, recv_buffer, field); + halo_packer_cuda::unpack(sendcnt_, recvmap_, recv_buffer, hfield, dfield); #else - halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, field); + halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, ffield); #endif } diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index ff623651d..901e910b6 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -9,26 +9,27 @@ */ #include "HaloExchangeCUDA.h" +#include namespace atlas { namespace parallel { template -__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, - const array::ArrayView field, array::SVector send_buffer, - typename std::enable_if::type* = 0) { +__global__ void pack_kernel2d(const int sendcnt, const array::SVector sendmap, + const array::ArrayView field, array::SVector send_buffer, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - +/* if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; const size_t buff_idx = field.data_view().template length<1>() * p + i; send_buffer[buff_idx] = field(sendmap[p], i); +*/ } template -__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, +__global__ void pack_kernel2d(const int sendcnt, const array::SVector sendmap, const array::ArrayView field, array::SVector send_buffer, typename std::enable_if::type* = 0) { } @@ -40,12 +41,13 @@ __global__ void unpack_kernel(const int sendcnt, const array::SVector recvm const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - +/* if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; const size_t buff_idx = field.data_view().template length<1>() * p + i; field(recvmap[p], i) = recv_buffer[buff_idx]; +*/ } template @@ -56,40 +58,70 @@ __global__ void unpack_kernel(const int sendcnt, const array::SVector recvm template void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ) + const array::ArrayView& hfield, const array::ArrayView& dfield, + array::SVector& send_buffer ) { } template void halo_packer_cuda::unpack(const int sendcnt, array::SVector const & recvmap, const array::SVector &recv_buffer , - array::ArrayView &field) + const array::ArrayView &hfield, array::ArrayView &dfield) { } template void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ) + const array::ArrayView& hfield, const array::ArrayView& dfield, + array::SVector& send_buffer ) { const unsigned int block_size_x = 32; const unsigned int block_size_y = 4; + dim3 threads(block_size_x, block_size_y); - dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (field.data_view().template length<1>()+block_size_y-1)/block_size_y); + dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y); + cudaDeviceSynchronize(); + + pack_kernel2d<<>>(sendcnt, sendmap, dfield, send_buffer); + + cudaDeviceSynchronize(); + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + throw eckit::Exception("Error launching GPU packing kernel"); - pack_kernel<<>>(sendcnt, sendmap, field, send_buffer); } template void halo_packer_cuda::unpack(const int sendcnt, array::SVector const & recvmap, const array::SVector &recv_buffer , - array::ArrayView &field) + const array::ArrayView &hfield, array::ArrayView &dfield) { const unsigned int block_size_x = 32; const unsigned int block_size_y = 4; dim3 threads(block_size_x, block_size_y); - dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (field.data_view().template length<1>()+block_size_y-1)/block_size_y); - - unpack_kernel<<>>(sendcnt, recvmap, recv_buffer, field); + dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y); + + cudaDeviceSynchronize(); + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + std::string msg = std::string("Error synchronizing device")+ cudaGetErrorString(err); + throw eckit::Exception(msg); + } + + unpack_kernel<<>>(sendcnt, recvmap, recv_buffer, dfield); + + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::string msg = std::string("Error launching GPU packing kernel")+ cudaGetErrorString(err); + throw eckit::Exception(msg); + } + + cudaDeviceSynchronize(); + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::string msg = std::string("Error synchronizing device")+ cudaGetErrorString(err); + throw eckit::Exception(msg); + } } #define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index bb74521db..3540b5e5d 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -16,51 +16,25 @@ namespace atlas { namespace parallel { template -__global__ void pack_kernel(int sendcnt, array::SVector sendmap, - const array::ArrayView field, array::SVector send_buffer) { - - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - - if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; - - const size_t buff_idx = field.data_view().template length<1>() * p + i; - - send_buffer[buff_idx] = field(sendmap[p], i); -} - -template -__global__ void unpack_kernel(int sendcnt, array::SVector recvmap, - const array::SVector recv_buffer, array::ArrayView field) { - - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - - if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; - - const size_t buff_idx = field.data_view().template length<1>() * p + i; - - field(recvmap[p], i) = recv_buffer[buff_idx]; -} - -#endif - -template struct halo_packer_cuda { static void pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ); + const array::ArrayView& hfield, const array::ArrayView& dfield, + array::SVector& send_buffer ); static void unpack( const int sendcnt, array::SVector const & recvmap, - const array::SVector& recv_buffer, array::ArrayView& field ); + const array::SVector& recv_buffer, const array::ArrayView& hfield, + array::ArrayView& dhfield ); }; template struct halo_packer_cuda { static void pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ); + const array::ArrayView& hfield, const array::ArrayView& dfield, + array::SVector& send_buffer ); static void unpack( const int sendcnt, array::SVector const & recvmap, - const array::SVector& recv_buffer, array::ArrayView& field ); + const array::SVector& recv_buffer, const array::ArrayView& hfield, + array::ArrayView& dfield); }; From 0fb385dddecbbcc349d16c664f2f658248e29e9b Mon Sep 17 00:00:00 2001 From: cosunae Date: Thu, 2 Nov 2017 12:05:59 +0100 Subject: [PATCH 108/355] fix the hack for cuda managed memory and MPI --- src/atlas/array/SVector.h | 1 + src/atlas/parallel/HaloExchange.h | 9 ++++++--- src/atlas/parallel/HaloExchangeCUDA.cu | 19 +++++++++++++------ src/atlas/parallel/HaloExchangeCUDA.h | 2 +- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/atlas/array/SVector.h b/src/atlas/array/SVector.h index 3c3f0dde6..d3712ab2a 100644 --- a/src/atlas/array/SVector.h +++ b/src/atlas/array/SVector.h @@ -68,6 +68,7 @@ class SVector { } } T* data() { return data_; } + T const * data() const { return data_; } ATLAS_HOST_DEVICE T& operator()(const size_t idx) { return data_[idx]; } diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 4595e0da5..7c7b28838 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -181,7 +181,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const { if(recv_counts[jproc] > 0) { - recv_req[jproc] = parallel::mpi::comm().iReceive(recv_ptr/*&recv_buffer[recv_displs[jproc]]*/, recv_counts[jproc], jproc, tag); + recv_req[jproc] = parallel::mpi::comm().iReceive(&recv_buffer[recv_displs[jproc]], recv_counts[jproc], jproc, tag); } } } @@ -195,8 +195,11 @@ void HaloExchange::execute(array::Array& field, bool on_device) const DATA_TYPE* send_ptr; if(on_device) { cudaMallocManaged(&send_ptr, send_size * sizeof(DATA_TYPE)); + cudaDeviceSynchronize(); + +//std::cout << "HACK " << send_buffer[0] << std::endl; // HACK this does not work -// memcpy(send_ptr, &(send_buffer[0]), send_size*sizeof(DATA_TYPE)); + memcpy(send_ptr, &(send_buffer[0]), send_size*sizeof(DATA_TYPE)); cudaDeviceSynchronize(); } else { @@ -213,7 +216,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const if(send_counts[jproc] > 0) { send_req[jproc] = parallel::mpi::comm().iSend( - send_ptr/*&send_buffer[send_displs[jproc]]*/, + &send_buffer[send_displs[jproc]], send_counts[jproc], jproc, tag); cudaDeviceSynchronize(); diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 901e910b6..1e48486d0 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -16,7 +16,7 @@ namespace parallel { template __global__ void pack_kernel2d(const int sendcnt, const array::SVector sendmap, - const array::ArrayView field, array::SVector send_buffer, const typename std::enable_if::type = 0) { + const array::ArrayView field, DATA_TYPE& send_buffer, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; /* @@ -30,13 +30,13 @@ __global__ void pack_kernel2d(const int sendcnt, const array::SVector send template __global__ void pack_kernel2d(const int sendcnt, const array::SVector sendmap, - const array::ArrayView field, array::SVector send_buffer, + const array::ArrayView field, DATA_TYPE& send_buffer, typename std::enable_if::type* = 0) { } template __global__ void unpack_kernel(const int sendcnt, const array::SVector recvmap, - const array::SVector recv_buffer, array::ArrayView field, + const DATA_TYPE& recv_buffer, const array::ArrayView field, typename std::enable_if::type* = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; @@ -52,7 +52,7 @@ __global__ void unpack_kernel(const int sendcnt, const array::SVector recvm template __global__ void unpack_kernel(const int sendcnt, const array::SVector recvmap, - const array::SVector recv_buffer, array::ArrayView field, + const DATA_TYPE& recv_buffer, const array::ArrayView field, typename std::enable_if::type* = 0) { } @@ -82,7 +82,14 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y); cudaDeviceSynchronize(); - pack_kernel2d<<>>(sendcnt, sendmap, dfield, send_buffer); +std::cout << "HACK " << send_buffer[0] << std::endl; + cudaDeviceSynchronize(); + + pack_kernel2d<<>>(sendcnt, sendmap, dfield, *(send_buffer.data())); + + cudaDeviceSynchronize(); +std::cout << "HACK " << send_buffer[0] << std::endl; + cudaDeviceSynchronize(); cudaDeviceSynchronize(); cudaError_t err = cudaGetLastError(); @@ -108,7 +115,7 @@ void halo_packer_cuda::unpack(const int sendcnt, array::SVector throw eckit::Exception(msg); } - unpack_kernel<<>>(sendcnt, recvmap, recv_buffer, dfield); + unpack_kernel<<>>(sendcnt, recvmap, *(recv_buffer.data()), dfield); err = cudaGetLastError(); if (err != cudaSuccess) { diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index 3540b5e5d..72b13da17 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -30,7 +30,7 @@ template struct halo_packer_cuda { static void pack( const int sendcnt, array::SVector const & sendmap, const array::ArrayView& hfield, const array::ArrayView& dfield, - array::SVector& send_buffer ); + array::SVector& send_buffer ); static void unpack( const int sendcnt, array::SVector const & recvmap, const array::SVector& recv_buffer, const array::ArrayView& hfield, From 22d55ce0f84504922bf2974a73a9d4c626c0c8b8 Mon Sep 17 00:00:00 2001 From: cosunae Date: Thu, 2 Nov 2017 12:12:07 +0100 Subject: [PATCH 109/355] fix the hack for cuda managed memory and MPI --- src/atlas/parallel/HaloExchange.h | 32 ------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 7c7b28838..06391ec61 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -161,20 +161,6 @@ void HaloExchange::execute(array::Array& field, bool on_device) const auto field_dv = on_device ? array::make_device_view(field) : array::make_host_view(field); -#ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - DATA_TYPE* recv_ptr; - if(on_device) { - cudaMallocManaged(&recv_ptr, recv_size * sizeof(DATA_TYPE)); - memcpy(recv_ptr, &(recv_buffer[0]), recv_size*sizeof(DATA_TYPE)); - cudaDeviceSynchronize(); - } - else { - DATA_TYPE* recv_ptr = &recv_buffer[0]; - } -#else - DATA_TYPE* recv_ptr = &recv_buffer[0]; -#endif - ATLAS_TRACE_MPI( IRECEIVE ) { /// Let MPI know what we like to receive for(int jproc=0; jproc < nproc; ++jproc) @@ -191,24 +177,6 @@ void HaloExchange::execute(array::Array& field, bool on_device) const cudaDeviceSynchronize(); - #ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - DATA_TYPE* send_ptr; - if(on_device) { - cudaMallocManaged(&send_ptr, send_size * sizeof(DATA_TYPE)); - cudaDeviceSynchronize(); - -//std::cout << "HACK " << send_buffer[0] << std::endl; -// HACK this does not work - memcpy(send_ptr, &(send_buffer[0]), send_size*sizeof(DATA_TYPE)); - cudaDeviceSynchronize(); - } - else { - DATA_TYPE* send_ptr = &send_buffer[0]; - } -#else - DATA_TYPE* send_ptr = &send_buffer[0]; -#endif - /// Send ATLAS_TRACE_MPI( ISEND ) { for(int jproc=0; jproc < nproc; ++jproc) From 0f336a35047e07b8c9c891e58d3c4b134607386b Mon Sep 17 00:00:00 2001 From: cosunae Date: Thu, 2 Nov 2017 16:37:27 +0100 Subject: [PATCH 110/355] fix kernels --- src/atlas/parallel/HaloExchange.h | 4 +-- src/atlas/parallel/HaloExchangeCUDA.cu | 37 +++++++++------------ src/tests/parallel/test_haloexchange_gpu.cc | 13 ++++++++ 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 06391ec61..70e041d14 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -310,9 +310,9 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - halo_packer_cuda::unpack(sendcnt_, recvmap_, recv_buffer, hfield, dfield); + halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); #else - halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, ffield); + halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, hfield); #endif } diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 1e48486d0..9f3c72221 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -16,43 +16,43 @@ namespace parallel { template __global__ void pack_kernel2d(const int sendcnt, const array::SVector sendmap, - const array::ArrayView field, DATA_TYPE& send_buffer, const typename std::enable_if::type = 0) { + const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; -/* + if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; const size_t buff_idx = field.data_view().template length<1>() * p + i; send_buffer[buff_idx] = field(sendmap[p], i); -*/ + } template __global__ void pack_kernel2d(const int sendcnt, const array::SVector sendmap, - const array::ArrayView field, DATA_TYPE& send_buffer, + const array::ArrayView field, DATA_TYPE* send_buffer, typename std::enable_if::type* = 0) { } template -__global__ void unpack_kernel(const int sendcnt, const array::SVector recvmap, - const DATA_TYPE& recv_buffer, const array::ArrayView field, +__global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, + const DATA_TYPE* recv_buffer, array::ArrayView field, typename std::enable_if::type* = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; -/* - if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; + + if(p >= recvcnt || i >= field.data_view().template length<1>() ) return; const size_t buff_idx = field.data_view().template length<1>() * p + i; field(recvmap[p], i) = recv_buffer[buff_idx]; -*/ + } template -__global__ void unpack_kernel(const int sendcnt, const array::SVector recvmap, - const DATA_TYPE& recv_buffer, const array::ArrayView field, +__global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, + const DATA_TYPE* recv_buffer, array::ArrayView field, typename std::enable_if::type* = 0) { } @@ -82,14 +82,7 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y); cudaDeviceSynchronize(); -std::cout << "HACK " << send_buffer[0] << std::endl; - cudaDeviceSynchronize(); - - pack_kernel2d<<>>(sendcnt, sendmap, dfield, *(send_buffer.data())); - - cudaDeviceSynchronize(); -std::cout << "HACK " << send_buffer[0] << std::endl; - cudaDeviceSynchronize(); + pack_kernel2d<<>>(sendcnt, sendmap, dfield, (send_buffer.data())); cudaDeviceSynchronize(); cudaError_t err = cudaGetLastError(); @@ -99,14 +92,14 @@ std::cout << "HACK " << send_buffer[0] << std::endl; } template -void halo_packer_cuda::unpack(const int sendcnt, array::SVector const & recvmap, +void halo_packer_cuda::unpack(const int recvcnt, array::SVector const & recvmap, const array::SVector &recv_buffer , const array::ArrayView &hfield, array::ArrayView &dfield) { const unsigned int block_size_x = 32; const unsigned int block_size_y = 4; dim3 threads(block_size_x, block_size_y); - dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y); + dim3 blocks((recvcnt+block_size_x-1)/block_size_x, (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y); cudaDeviceSynchronize(); cudaError_t err = cudaGetLastError(); @@ -115,7 +108,7 @@ void halo_packer_cuda::unpack(const int sendcnt, array::SVector throw eckit::Exception(msg); } - unpack_kernel<<>>(sendcnt, recvmap, *(recv_buffer.data()), dfield); + unpack_kernel<<>>(recvcnt, recvmap, recv_buffer.data(), dfield); err = cudaGetLastError(); if (err != cudaSuccess) { diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index f2497c9e7..a154e8eef 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -83,6 +83,14 @@ struct Fixture { //----------------------------------------------------------------------------- +template +bool validate(array::ArrayView arrv, DATA_TYPE arr_c[]); + +template +bool validate(array::ArrayView arrv, DATA_TYPE arr_c[]) { + +} + CASE("test_haloexchange_gpu") { SETUP("Fixture") { Fixture f; @@ -100,9 +108,14 @@ CASE("test_haloexchange_gpu") { f.halo_exchange.template execute(arr, true); + arr.syncHostDevice(); +std::cout << arrv(0,0) << " " << arrv(0,1) << " " << arrv(1,0) << " " << arrv(1,1) << " " << arrv(2,0) << " " << + arrv(2,1) << " " << arrv(3,0) << " " << arrv(3,1) << " " << arrv(4,0) << " " << arrv(4,1) << std::endl; + switch( parallel::mpi::comm().rank() ) { case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; + EXPECT(validate(arrv, arr_c)); EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } From 3341d9655ee5e7dec321581f3c3de6efdb5a9bc9 Mon Sep 17 00:00:00 2001 From: cosunae Date: Thu, 2 Nov 2017 17:27:49 +0100 Subject: [PATCH 111/355] validation of test passes --- src/tests/parallel/test_haloexchange_gpu.cc | 27 +++++++++++++-------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index a154e8eef..7f8a870b2 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -84,12 +84,22 @@ struct Fixture { //----------------------------------------------------------------------------- template -bool validate(array::ArrayView arrv, DATA_TYPE arr_c[]); +struct validate; template -bool validate(array::ArrayView arrv, DATA_TYPE arr_c[]) { - -} +struct validate { + + static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { + int strides[2]; + strides[0] = 1; + strides[1] = arrv.template shape<1>(); + for(size_t i = 0; i < arrv.template shape<0>(); ++i) { + for(size_t j = 0; j < arrv.template shape<1>(); ++j) { + EXPECT(arrv(i,j) == arr_c[i*strides[1] + j*strides[0]]); + } + } + } +}; CASE("test_haloexchange_gpu") { SETUP("Fixture") { @@ -109,18 +119,15 @@ CASE("test_haloexchange_gpu") { f.halo_exchange.template execute(arr, true); arr.syncHostDevice(); -std::cout << arrv(0,0) << " " << arrv(0,1) << " " << arrv(1,0) << " " << arrv(1,1) << " " << arrv(2,0) << " " << - arrv(2,1) << " " << arrv(3,0) << " " << arrv(3,1) << " " << arrv(4,0) << " " << arrv(4,1) << std::endl; switch( parallel::mpi::comm().rank() ) { case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; - EXPECT(validate(arrv, arr_c)); - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv, arr_c); break; } case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv, arr_c); break; } case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv, arr_c); break; } } } } From 69e65a13e0d297be0f19035dd55db80362bc2ab2 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 2 Nov 2017 17:46:13 +0100 Subject: [PATCH 112/355] add a 1D case --- src/atlas/parallel/HaloExchangeCUDA.cu | 95 +++++++++++++++++---- src/tests/parallel/test_haloexchange_gpu.cc | 21 +++++ 2 files changed, 100 insertions(+), 16 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 9f3c72221..025963abd 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -15,7 +15,7 @@ namespace atlas { namespace parallel { template -__global__ void pack_kernel2d(const int sendcnt, const array::SVector sendmap, +__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; @@ -29,9 +29,19 @@ __global__ void pack_kernel2d(const int sendcnt, const array::SVector send } template -__global__ void pack_kernel2d(const int sendcnt, const array::SVector sendmap, +__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, const array::ArrayView field, DATA_TYPE* send_buffer, - typename std::enable_if::type* = 0) { + typename std::enable_if::type* = 0) { + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + + if(p >= sendcnt) return; + send_buffer[p] = field(sendmap[p]); +} + +template +__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, + const array::ArrayView field, DATA_TYPE* send_buffer, + typename std::enable_if<(RANK>2), int>::type* = 0) { } template @@ -53,21 +63,20 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm template __global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, const DATA_TYPE* recv_buffer, array::ArrayView field, - typename std::enable_if::type* = 0) { -} + typename std::enable_if::type* = 0) { + + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + + if(p >= recvcnt) return; + + field(recvmap[p]) = recv_buffer[p]; -template -void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& hfield, const array::ArrayView& dfield, - array::SVector& send_buffer ) -{ } -template -void halo_packer_cuda::unpack(const int sendcnt, array::SVector const & recvmap, - const array::SVector &recv_buffer , - const array::ArrayView &hfield, array::ArrayView &dfield) -{ +template +__global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, + const DATA_TYPE* recv_buffer, array::ArrayView field, + typename std::enable_if<(RANK>2), int>::type* = 0) { } template @@ -82,7 +91,7 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y); cudaDeviceSynchronize(); - pack_kernel2d<<>>(sendcnt, sendmap, dfield, (send_buffer.data())); + pack_kernel<<>>(sendcnt, sendmap, dfield, (send_buffer.data())); cudaDeviceSynchronize(); cudaError_t err = cudaGetLastError(); @@ -91,6 +100,27 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< } +template +void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, + const array::ArrayView& hfield, const array::ArrayView& dfield, + array::SVector& send_buffer ) +{ + const unsigned int block_size_x = 32; + + dim3 threads(block_size_x, 1); + dim3 blocks((sendcnt+block_size_x-1)/block_size_x, 1); + cudaDeviceSynchronize(); + + pack_kernel<<>>(sendcnt, sendmap, dfield, (send_buffer.data())); + + cudaDeviceSynchronize(); + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) + throw eckit::Exception("Error launching GPU packing kernel"); + +} + + template void halo_packer_cuda::unpack(const int recvcnt, array::SVector const & recvmap, const array::SVector &recv_buffer , @@ -124,6 +154,39 @@ void halo_packer_cuda::unpack(const int recvcnt, array::SVector } } +template +void halo_packer_cuda::unpack(const int recvcnt, array::SVector const & recvmap, + const array::SVector &recv_buffer , + const array::ArrayView &hfield, array::ArrayView &dfield) +{ + const unsigned int block_size_x = 32; + + dim3 threads(block_size_x, 1); + dim3 blocks((recvcnt+block_size_x-1)/block_size_x, 1); + + cudaDeviceSynchronize(); + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + std::string msg = std::string("Error synchronizing device")+ cudaGetErrorString(err); + throw eckit::Exception(msg); + } + + unpack_kernel<<>>(recvcnt, recvmap, recv_buffer.data(), dfield); + + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::string msg = std::string("Error launching GPU packing kernel")+ cudaGetErrorString(err); + throw eckit::Exception(msg); + } + + cudaDeviceSynchronize(); + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::string msg = std::string("Error synchronizing device")+ cudaGetErrorString(err); + throw eckit::Exception(msg); + } +} + #define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ template class halo_packer_cuda; \ template class halo_packer_cuda; \ diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index 7f8a870b2..0c089e098 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -105,6 +105,27 @@ CASE("test_haloexchange_gpu") { SETUP("Fixture") { Fixture f; + SECTION( "test_rank0_arrview" ) + { + array::ArrayT arr(f.N); + array::ArrayView arrv = array::make_view(arr); + for( int j=0; j(arr, false); + + switch( parallel::mpi::comm().rank() ) + { + case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; + EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } + case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; + EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } + case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; + EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } + } + } + SECTION( "test_rank1" ) { array::ArrayT arr(f.N,2); From 6d4657fe3009abe086f5c892a91ce58d12e0ad01 Mon Sep 17 00:00:00 2001 From: cosunae Date: Thu, 2 Nov 2017 19:09:12 +0100 Subject: [PATCH 113/355] support for rank 1 --- src/atlas/parallel/HaloExchangeCUDA.cu | 10 +++--- src/tests/parallel/test_haloexchange_gpu.cc | 36 ++++++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 025963abd..1effdb1b6 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -10,6 +10,7 @@ #include "HaloExchangeCUDA.h" #include +#include namespace atlas { namespace parallel { @@ -31,23 +32,24 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendma template __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, const array::ArrayView field, DATA_TYPE* send_buffer, - typename std::enable_if::type* = 0) { + const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; if(p >= sendcnt) return; +printf("FU %d %d %f \n", p, sendmap[p], field(0)); send_buffer[p] = field(sendmap[p]); } template __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, const array::ArrayView field, DATA_TYPE* send_buffer, - typename std::enable_if<(RANK>2), int>::type* = 0) { + const typename std::enable_if<(RANK>2), int>::type = 0) { } template __global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, const DATA_TYPE* recv_buffer, array::ArrayView field, - typename std::enable_if::type* = 0) { + const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; @@ -63,7 +65,7 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm template __global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, const DATA_TYPE* recv_buffer, array::ArrayView field, - typename std::enable_if::type* = 0) { + const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index 0c089e098..6b6eedbf2 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -86,6 +86,20 @@ struct Fixture { template struct validate; +template +struct validate { + + static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { + int strides[1]; + strides[0] = 1; + for(size_t i = 0; i < arrv.template shape<0>(); ++i) { +std::cout << parallel::mpi::comm().rank() << "] VAL " << arrv(i) << " " << i << " " << arr_c[i*strides[0]] << std::endl; + EXPECT(arrv(i) == arr_c[i*strides[0]]); + + } + } +}; + template struct validate { @@ -108,22 +122,27 @@ CASE("test_haloexchange_gpu") { SECTION( "test_rank0_arrview" ) { array::ArrayT arr(f.N); - array::ArrayView arrv = array::make_view(arr); + array::ArrayView arrv = array::make_host_view(arr); for( int j=0; j(arr, false); + arr.syncHostDevice(); + + f.halo_exchange.template execute(arr, true); + + arr.syncHostDevice(); switch( parallel::mpi::comm().rank() ) { - case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; - EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } - case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; - EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } - case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; - EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } + case 0: { POD arr_c[] = { 9, 1, 2, 3, 4}; + validate::apply(arrv, arr_c); break; } + case 1: { POD arr_c[] = { 3, 4, 5, 6, 7, 8}; + validate::apply(arrv, arr_c); break; } + case 2: { POD arr_c[] = { 5, 6, 7, 8, 9, 1, 2}; + validate::apply(arrv, arr_c); break; } } + cudaDeviceSynchronize(); } SECTION( "test_rank1" ) @@ -151,6 +170,7 @@ CASE("test_haloexchange_gpu") { validate::apply(arrv, arr_c); break; } } } + } } From 456bbdca67fecc21f9dd1a5ae500475cf72aaae8 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 2 Nov 2017 18:21:38 +0000 Subject: [PATCH 114/355] Fix gridtools import --- src/atlas/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 70032a5a5..a95294626 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -529,5 +529,5 @@ ecbuild_add_library( TARGET atlas ) if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) - target_link_libraries( atlas gridtools::storage ) + target_link_libraries( atlas gridtools::gridtools_storage ) endif() From 637e4a3de28d13dae7f98bce0428b5a1c4a343ff Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Thu, 2 Nov 2017 20:12:23 +0100 Subject: [PATCH 115/355] add support for 4d exchanges --- src/atlas/parallel/HaloExchangeCUDA.cu | 39 ++++++++++++-- src/tests/parallel/test_haloexchange_gpu.cc | 57 +++++++++++++++++++++ 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 025963abd..ab39159fc 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -28,6 +28,22 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendma } +template +__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, + const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + + if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; + + size_t buff_idx = field.data_view().template length<2>() * p + field.data_view().template length<1>() * i; + + for(size_t varid=0; varid < field.data_view().template length<2>(); ++varid) { + send_buffer[buff_idx++] = field(sendmap[p], i, varid); + } + +} + template __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, const array::ArrayView field, DATA_TYPE* send_buffer, @@ -41,7 +57,7 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap template __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, const array::ArrayView field, DATA_TYPE* send_buffer, - typename std::enable_if<(RANK>2), int>::type* = 0) { + typename std::enable_if<(RANK>3), int>::type* = 0) { } template @@ -60,6 +76,23 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm } +template +__global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, + const DATA_TYPE* recv_buffer, array::ArrayView field, + typename std::enable_if::type* = 0) { + + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + + if(p >= recvcnt || i >= field.data_view().template length<1>() ) return; + + size_t buff_idx = field.data_view().template length<2>() * p + field.data_view().template length<1>() * i; + + for(size_t varid=0; varid < field.data_view().template length<2>(); ++varid) { + field(recvmap[p], i, varid) = recv_buffer[buff_idx++]; + } +} + template __global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, const DATA_TYPE* recv_buffer, array::ArrayView field, @@ -68,15 +101,13 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm const size_t p = blockIdx.x*blockDim.x + threadIdx.x; if(p >= recvcnt) return; - field(recvmap[p]) = recv_buffer[p]; - } template __global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, const DATA_TYPE* recv_buffer, array::ArrayView field, - typename std::enable_if<(RANK>2), int>::type* = 0) { + typename std::enable_if<(RANK>3), int>::type* = 0) { } template diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index 0c089e098..060c5578d 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -151,6 +151,63 @@ CASE("test_haloexchange_gpu") { validate::apply(arrv, arr_c); break; } } } + + SECTION( "test_rank2" ) + { + array::ArrayT arr(f.N,3,2); + array::ArrayView arrv = array::make_host_view(arr); + for( int p=0; p(arr, true); + + arr.syncHostDevice(); + + switch( parallel::mpi::comm().rank() ) + { + case 0: + { + int arr_c[] = { -9,9, -90,90, -900,900, + -1,1, -10,10, -100,100, + -2,2, -20,20, -200,200, + -3,3, -30,30, -300,300, + -4,4, -40,40, -400,400}; + EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 1: + { + int arr_c[] = { -3,3, -30,30, -300,300, + -4,4, -40,40, -400,400, + -5,5, -50,50, -500,500, + -6,6, -60,60, -600,600, + -7,7, -70,70, -700,700, + -8,8, -80,80, -800,800}; + EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 2: + { + int arr_c[] = { -5,5, -50,50, -500,500, + -6,6, -60,60, -600,600, + -7,7, -70,70, -700,700, + -8,8, -80,80, -800,800, + -9,9, -90,90, -900,900, + -1,1, -10,10, -100,100, + -2,2, -20,20, -200,200}; + EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + } + } } } From d97974276a02635cd981b3092ee745d39e0f3bec Mon Sep 17 00:00:00 2001 From: cosunae Date: Fri, 3 Nov 2017 00:16:05 +0100 Subject: [PATCH 116/355] add a test for rank 3 --- src/atlas/parallel/HaloExchangeCUDA.cu | 4 +-- src/tests/parallel/test_haloexchange_gpu.cc | 37 ++++++++++++++++----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 9fd67720b..0c60e78b6 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -37,7 +37,7 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendma if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; - size_t buff_idx = field.data_view().template length<2>() * p + field.data_view().template length<1>() * i; + size_t buff_idx = field.data_view().template length<2>() * field.data_view().template length<1>() * p + field.data_view().template length<2>() * i; for(size_t varid=0; varid < field.data_view().template length<2>(); ++varid) { send_buffer[buff_idx++] = field(sendmap[p], i, varid); @@ -87,7 +87,7 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm if(p >= recvcnt || i >= field.data_view().template length<1>() ) return; - size_t buff_idx = field.data_view().template length<2>() * p + field.data_view().template length<1>() * i; + size_t buff_idx = field.data_view().template length<2>() * field.data_view().template length<1>() * p + field.data_view().template length<2>() * i; for(size_t varid=0; varid < field.data_view().template length<2>(); ++varid) { field(recvmap[p], i, varid) = recv_buffer[buff_idx++]; diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index 1a0976d61..6d4827780 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -115,6 +115,26 @@ struct validate { } }; + +template +struct validate { + + static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { + int strides[3]; + strides[0] = 1; + strides[1] = arrv.template shape<2>(); + strides[2] = arrv.template shape<1>()*strides[1]; + + for(size_t i = 0; i < arrv.template shape<0>(); ++i) { + for(size_t j = 0; j < arrv.template shape<1>(); ++j) { + for(size_t k = 0; k < arrv.template shape<2>(); ++k) { + EXPECT(arrv(i,j,k) == arr_c[i*strides[2] + j*strides[1] + k*strides[0]]); + } + } + } + } +}; + CASE("test_haloexchange_gpu") { SETUP("Fixture") { Fixture f; @@ -145,6 +165,7 @@ CASE("test_haloexchange_gpu") { cudaDeviceSynchronize(); } + SECTION( "test_rank1" ) { array::ArrayT arr(f.N,2); @@ -194,39 +215,37 @@ CASE("test_haloexchange_gpu") { { case 0: { - int arr_c[] = { -9,9, -90,90, -900,900, + POD arr_c[] = { -9,9, -90,90, -900,900, -1,1, -10,10, -100,100, -2,2, -20,20, -200,200, -3,3, -30,30, -300,300, -4,4, -40,40, -400,400}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; + validate::apply(arrv, arr_c); break; } case 1: { - int arr_c[] = { -3,3, -30,30, -300,300, + POD arr_c[] = { -3,3, -30,30, -300,300, -4,4, -40,40, -400,400, -5,5, -50,50, -500,500, -6,6, -60,60, -600,600, -7,7, -70,70, -700,700, -8,8, -80,80, -800,800}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; + validate::apply(arrv, arr_c); break; } case 2: { - int arr_c[] = { -5,5, -50,50, -500,500, + POD arr_c[] = { -5,5, -50,50, -500,500, -6,6, -60,60, -600,600, -7,7, -70,70, -700,700, -8,8, -80,80, -800,800, -9,9, -90,90, -900,900, -1,1, -10,10, -100,100, -2,2, -20,20, -200,200}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; + validate::apply(arrv, arr_c); break; } } } + } } From 7f4f2b350aee519f5629f3d29ab257cf1abfa384 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 09:28:44 +0100 Subject: [PATCH 117/355] generic version of validate --- src/tests/parallel/test_haloexchange_gpu.cc | 125 ++++++++++++++------ 1 file changed, 86 insertions(+), 39 deletions(-) diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index 6d4827780..ec5f320f0 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -83,56 +83,103 @@ struct Fixture { //----------------------------------------------------------------------------- +//template +//struct validate; + +//template +//struct validate { + +// static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { +// int strides[1]; +// strides[0] = 1; +// for(size_t i = 0; i < arrv.template shape<0>(); ++i) { +// EXPECT(arrv(i) == arr_c[i*strides[0]]); +// } +// } +//}; + +//template +//struct validate { + +// static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { +// int strides[2]; +// strides[0] = arrv.template shape<1>(); +// strides[1] = 1; +// for(size_t i = 0; i < arrv.template shape<0>(); ++i) { +// for(size_t j = 0; j < arrv.template shape<1>(); ++j) { +// EXPECT(arrv(i,j) == arr_c[i*strides[0] + j*strides[1]]); +// } +// } +// } +//}; + + +//template +//struct validate { + +// static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { +// int strides[3]; +// strides[0] = arrv.template shape<1>()*strides[1]; +// strides[1] = arrv.template shape<2>(); +// strides[2] = 1; + +// for(size_t i = 0; i < arrv.template shape<0>(); ++i) { +// for(size_t j = 0; j < arrv.template shape<1>(); ++j) { +// for(size_t k = 0; k < arrv.template shape<2>(); ++k) { +// EXPECT(arrv(i,j,k) == arr_c[i*strides[0] + j*strides[1] + k*strides[2]]); +// } +// } +// } +// } +//}; + +template +size_t eval_idx(size_t pos, std::array& strides, FirstDim first) +{ + return first*strides[pos]; +} + +template +size_t eval_idx(size_t pos, std::array& strides, FirstDim first, Int...dims ) +{ + return first*strides[pos] + eval_idx((size_t)pos++, strides, dims...); +} + +template +struct validate_impl; + template -struct validate; - -template -struct validate { - - static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { - int strides[1]; - strides[0] = 1; - for(size_t i = 0; i < arrv.template shape<0>(); ++i) { -std::cout << parallel::mpi::comm().rank() << "] VAL " << arrv(i) << " " << i << " " << arr_c[i*strides[0]] << std::endl; - EXPECT(arrv(i) == arr_c[i*strides[0]]); - +struct validate_impl { + template + static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { + EXPECT(arrv(dims...) == arr_c[eval_idx((size_t)0, strides, dims...)]); +// EXPECT(arrv(i,j,k) == arr_c[i*strides[0] + j*strides[1] + k*strides[2]]); } - } }; -template -struct validate { +template +struct validate_impl { - static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { - int strides[2]; - strides[0] = 1; - strides[1] = arrv.template shape<1>(); - for(size_t i = 0; i < arrv.template shape<0>(); ++i) { - for(size_t j = 0; j < arrv.template shape<1>(); ++j) { - EXPECT(arrv(i,j) == arr_c[i*strides[1] + j*strides[0]]); - } + template + static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { + strides[Dim-1] = strides[Dim]*arrv.template shape<(unsigned int)Dim>(); + for(size_t cnt = 0; cnt < arrv.template shape(); ++cnt) { + validate_impl::apply(arrv, arr_c, strides, dims..., cnt); + } } - } }; +template +struct validate { -template -struct validate { - - static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { - int strides[3]; - strides[0] = 1; - strides[1] = arrv.template shape<2>(); - strides[2] = arrv.template shape<1>()*strides[1]; - - for(size_t i = 0; i < arrv.template shape<0>(); ++i) { - for(size_t j = 0; j < arrv.template shape<1>(); ++j) { - for(size_t k = 0; k < arrv.template shape<2>(); ++k) { - EXPECT(arrv(i,j,k) == arr_c[i*strides[2] + j*strides[1] + k*strides[0]]); + static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { + std::array strides; + strides[Rank-1] = 1; + for(size_t i = 0; i < arrv.template shape<0>(); ++i) { + validate_impl::apply(arrv, arr_c, strides, i); } - } } - } + }; CASE("test_haloexchange_gpu") { From 4b1fd9cb1b66318df592a8ccea128a86c7a6046c Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 10:03:17 +0100 Subject: [PATCH 118/355] fix the stride computation --- src/tests/parallel/test_haloexchange_gpu.cc | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index ec5f320f0..42d6f734c 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -162,19 +162,37 @@ struct validate_impl { template static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { - strides[Dim-1] = strides[Dim]*arrv.template shape<(unsigned int)Dim>(); for(size_t cnt = 0; cnt < arrv.template shape(); ++cnt) { validate_impl::apply(arrv, arr_c, strides, dims..., cnt); } } }; +template +struct comput_strides; + +template<> +struct comput_strides<0> { + template + static void apply(array::ArrayView& arrv, std::array& strides) {} +}; + +template +struct comput_strides { + template + static void apply(array::ArrayView& arrv, std::array& strides) { + strides[Rank-1] = strides[Rank]*arrv.template shape<(unsigned int)Rank>(); + } +}; + template struct validate { static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { std::array strides; strides[Rank-1] = 1; + compute_strides::apply(arrv, strides); + for(size_t i = 0; i < arrv.template shape<0>(); ++i) { validate_impl::apply(arrv, arr_c, strides, i); } From 8808784aa928a4bc4124bfc2c3f673ff1f5202f3 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 10:26:35 +0100 Subject: [PATCH 119/355] fix the stride computation --- src/tests/parallel/test_haloexchange_gpu.cc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index 42d6f734c..96d826b59 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -168,20 +168,21 @@ struct validate_impl { } }; -template -struct comput_strides; +template +struct compute_strides; template<> -struct comput_strides<0> { - template - static void apply(array::ArrayView& arrv, std::array& strides) {} +struct compute_strides<0> { + template + static void apply(array::ArrayView& arrv, std::array& strides) {} }; -template -struct comput_strides { - template - static void apply(array::ArrayView& arrv, std::array& strides) { - strides[Rank-1] = strides[Rank]*arrv.template shape<(unsigned int)Rank>(); +template +struct compute_strides { + template + static void apply(array::ArrayView& arrv, std::array& strides) { + strides[Dim-1] = strides[Dim]*arrv.template shape<(unsigned int)Dim>(); + } }; From 8f98b5fb9ecbe6d03f8ac4cd8565d0bb0f122b77 Mon Sep 17 00:00:00 2001 From: cosunae Date: Fri, 3 Nov 2017 11:04:11 +0100 Subject: [PATCH 120/355] fix for rank 3 --- src/tests/parallel/test_haloexchange_gpu.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index 96d826b59..ac041a15d 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -25,6 +25,9 @@ #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" +#include +#include + using namespace eckit::testing; /// POD: Type to test @@ -142,7 +145,7 @@ size_t eval_idx(size_t pos, std::array& strides, FirstDim first) template size_t eval_idx(size_t pos, std::array& strides, FirstDim first, Int...dims ) { - return first*strides[pos] + eval_idx((size_t)pos++, strides, dims...); + return first*strides[pos] + eval_idx((size_t)pos+1, strides, dims...); } template @@ -153,7 +156,6 @@ struct validate_impl { template static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { EXPECT(arrv(dims...) == arr_c[eval_idx((size_t)0, strides, dims...)]); -// EXPECT(arrv(i,j,k) == arr_c[i*strides[0] + j*strides[1] + k*strides[2]]); } }; @@ -182,6 +184,7 @@ struct compute_strides { template static void apply(array::ArrayView& arrv, std::array& strides) { strides[Dim-1] = strides[Dim]*arrv.template shape<(unsigned int)Dim>(); + compute_strides::apply(arrv,strides); } }; @@ -204,7 +207,7 @@ struct validate { CASE("test_haloexchange_gpu") { SETUP("Fixture") { Fixture f; - +/* SECTION( "test_rank0_arrview" ) { array::ArrayT arr(f.N); @@ -257,7 +260,7 @@ CASE("test_haloexchange_gpu") { validate::apply(arrv, arr_c); break; } } } - +*/ SECTION( "test_rank2" ) { array::ArrayT arr(f.N,3,2); @@ -311,7 +314,6 @@ CASE("test_haloexchange_gpu") { } } } - } } From 161c797fe437671e1efc03f2c2573f1f3e425663 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 11:06:34 +0100 Subject: [PATCH 121/355] cleanup debugging code --- src/atlas/parallel/HaloExchange.h | 4 -- src/atlas/parallel/HaloExchangeCUDA.cu | 2 - src/tests/parallel/test_haloexchange_gpu.cc | 57 +-------------------- 3 files changed, 2 insertions(+), 61 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 70e041d14..9a74c118c 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -60,10 +60,6 @@ class HaloExchange: public eckit::Owned { template void execute( array::Array& field, bool on_device = false) const; -// template -// void execute( array::ArrayView&& field ) const; - - private: // methods void create_mappings( std::vector& send_map, std::vector& recv_map, size_t nb_vars ) const; diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 0c60e78b6..5523026c2 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -9,8 +9,6 @@ */ #include "HaloExchangeCUDA.h" -#include -#include namespace atlas { namespace parallel { diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc index ac041a15d..7c5951969 100644 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ b/src/tests/parallel/test_haloexchange_gpu.cc @@ -25,9 +25,6 @@ #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" -#include -#include - using namespace eckit::testing; /// POD: Type to test @@ -86,56 +83,6 @@ struct Fixture { //----------------------------------------------------------------------------- -//template -//struct validate; - -//template -//struct validate { - -// static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { -// int strides[1]; -// strides[0] = 1; -// for(size_t i = 0; i < arrv.template shape<0>(); ++i) { -// EXPECT(arrv(i) == arr_c[i*strides[0]]); -// } -// } -//}; - -//template -//struct validate { - -// static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { -// int strides[2]; -// strides[0] = arrv.template shape<1>(); -// strides[1] = 1; -// for(size_t i = 0; i < arrv.template shape<0>(); ++i) { -// for(size_t j = 0; j < arrv.template shape<1>(); ++j) { -// EXPECT(arrv(i,j) == arr_c[i*strides[0] + j*strides[1]]); -// } -// } -// } -//}; - - -//template -//struct validate { - -// static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { -// int strides[3]; -// strides[0] = arrv.template shape<1>()*strides[1]; -// strides[1] = arrv.template shape<2>(); -// strides[2] = 1; - -// for(size_t i = 0; i < arrv.template shape<0>(); ++i) { -// for(size_t j = 0; j < arrv.template shape<1>(); ++j) { -// for(size_t k = 0; k < arrv.template shape<2>(); ++k) { -// EXPECT(arrv(i,j,k) == arr_c[i*strides[0] + j*strides[1] + k*strides[2]]); -// } -// } -// } -// } -//}; - template size_t eval_idx(size_t pos, std::array& strides, FirstDim first) { @@ -207,7 +154,7 @@ struct validate { CASE("test_haloexchange_gpu") { SETUP("Fixture") { Fixture f; -/* + SECTION( "test_rank0_arrview" ) { array::ArrayT arr(f.N); @@ -260,7 +207,7 @@ CASE("test_haloexchange_gpu") { validate::apply(arrv, arr_c); break; } } } -*/ + SECTION( "test_rank2" ) { array::ArrayT arr(f.N,3,2); From 8a86454649316f8f5327f393691a983825c21f03 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 3 Nov 2017 10:28:32 +0000 Subject: [PATCH 122/355] Find gridtools_storage and use as gridtools::storage --- CMakeLists.txt | 2 +- src/atlas/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f24ee543e..cce800820 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,7 +123,7 @@ endif() ecbuild_add_option( FEATURE GRIDTOOLS_STORAGE DESCRIPTION "Arrays internally use GridTools storage layer" - REQUIRED_PACKAGES "gridtools_storage" ) + REQUIRED_PACKAGES "PROJECT gridtools_storage" ) if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index a95294626..70032a5a5 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -529,5 +529,5 @@ ecbuild_add_library( TARGET atlas ) if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) - target_link_libraries( atlas gridtools::gridtools_storage ) + target_link_libraries( atlas gridtools::storage ) endif() From 51621727419862224dbbf80c52101e77f2af0c08 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 19:34:31 +0100 Subject: [PATCH 123/355] some fixes of the CPU backend for halos --- src/atlas/parallel/HaloExchange.h | 41 ++++--------------------------- 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 9a74c118c..41870389e 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -171,8 +171,6 @@ void HaloExchange::execute(array::Array& field, bool on_device) const /// Pack pack_send_buffer(field_hv, field_dv,send_buffer); - cudaDeviceSynchronize(); - /// Send ATLAS_TRACE_MPI( ISEND ) { for(int jproc=0; jproc < nproc; ++jproc) @@ -182,8 +180,6 @@ void HaloExchange::execute(array::Array& field, bool on_device) const send_req[jproc] = parallel::mpi::comm().iSend( &send_buffer[send_displs[jproc]], send_counts[jproc], jproc, tag); - cudaDeviceSynchronize(); - } } } @@ -218,7 +214,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const template struct halo_packer_impl { template - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx... idxs) { for( size_t i=0; i< field.template shape(); ++i ) { halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); @@ -229,7 +225,7 @@ struct halo_packer_impl { template struct halo_packer_impl<0, CurrentDim> { template - static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, + static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx...idxs) { send_buffer[buf_idx++] = field(node_idx, idxs...); @@ -242,7 +238,7 @@ struct halo_unpacker_impl { static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, array::ArrayView& field, Idx... idxs) { for( size_t i=0; i< field.template shape(); ++i ) { - halo_unpacker_impl::apply(buf_idx, node_idx, field, recv_buffer, idxs..., i); + halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs..., i); } } }; @@ -261,7 +257,7 @@ template struct halo_packer { template static void pack(const unsigned int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ) + const array::ArrayView& field, array::SVector& send_buffer ) { size_t ibuf = 0; for(int p=0; p < sendcnt; ++p) @@ -308,7 +304,7 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); #else - halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, hfield); + halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); #endif } @@ -324,33 +320,6 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf //} -template -void HaloExchange::var_info( const array::ArrayView& arr, - std::vector& varstrides, - std::vector& varshape ) const -{ - int rank = std::max(1,RANK-1) ; - varstrides.resize(rank); - varshape.resize(rank); - - if( RANK>1 ) - { - size_t stride=1; - for( int j=RANK-1; j>0; --j ) { - varstrides[j-1] = stride; - varshape[j-1] = arr.shape(j); - stride *= varshape[j-1]; - } -// varstrides.assign(arr.strides()+1,arr.strides()+RANK); -// varshape.assign(arr.shape()+1,arr.shape()+RANK); - } - else - { - varstrides[0] = 1; - varshape[0] = 1; - } -} - //template //void HaloExchange::execute( array::ArrayView&& field ) const //{ From 4b17e2d3b3e5ca220802b07cfaebc0a57b406757 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 20:54:30 +0100 Subject: [PATCH 124/355] replace bool readonly by enum class --- src/atlas/array/ArrayViewDefs.h | 19 +++ .../array/gridtools/GridToolsArrayView.cc | 44 +++--- .../array/gridtools/GridToolsArrayView.h | 13 +- .../array/gridtools/GridToolsMakeView.cc | 144 +++++++++--------- src/atlas/array/gridtools/GridToolsMakeView.h | 8 +- src/atlas/array/gridtools/GridToolsTraits.h | 6 +- src/atlas/array_fwd.h | 19 +-- src/atlas/parallel/HaloExchange.h | 24 +-- src/atlas/parallel/HaloExchangeCUDA.h | 9 +- 9 files changed, 155 insertions(+), 131 deletions(-) create mode 100644 src/atlas/array/ArrayViewDefs.h diff --git a/src/atlas/array/ArrayViewDefs.h b/src/atlas/array/ArrayViewDefs.h new file mode 100644 index 000000000..666d90631 --- /dev/null +++ b/src/atlas/array/ArrayViewDefs.h @@ -0,0 +1,19 @@ +/* + * (C) Copyright 1996-2017 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 size_tergovernmental organisation nor + * does it submit to any jurisdiction. + */ + +#pragma once + +namespace atlas { +namespace array { + + enum class Intent {ReadOnly, ReadWrite}; + +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index e58e0751c..6f6b7db7d 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -15,8 +15,8 @@ namespace atlas { namespace array { -template< typename Value, int Rank, bool ReadOnly > -ArrayView::ArrayView( const ArrayView& other ) : +template< typename Value, int Rank, Intent AccessMode > +ArrayView::ArrayView( const ArrayView& other ) : gt_data_view_(other.gt_data_view_), data_store_orig_(other.data_store_orig_), array_(other.array_) { std::memcpy(shape_,other.shape_,sizeof(size_t)*Rank); std::memcpy(strides_,other.strides_,sizeof(size_t)*Rank); @@ -24,8 +24,8 @@ ArrayView::ArrayView( const ArrayView& other ) : // TODO: check compatibility } -template< typename Value, int Rank, bool ReadOnly > -ArrayView::ArrayView(data_view_t data_view, const Array& array) : +template< typename Value, int Rank, Intent AccessMode > +ArrayView::ArrayView(data_view_t data_view, const Array& array) : gt_data_view_(data_view), data_store_orig_(array.data_store()), array_(&array) { if(data_view.valid()) { using seq = ::gridtools::apply_gt_integer_sequence::type>; @@ -57,13 +57,13 @@ ArrayView::ArrayView(data_view_t data_view, const Array& a } } -template< typename Value, int Rank, bool ReadOnly> -bool ArrayView::valid() const { +template< typename Value, int Rank, Intent AccessMode> +bool ArrayView::valid() const { return gt_data_view_.valid() && (array_->data_store() == data_store_orig_); } -template< typename Value, int Rank, bool ReadOnly > -void ArrayView::assign(const value_type& value) { +template< typename Value, int Rank, Intent AccessMode > +void ArrayView::assign(const value_type& value) { ASSERT( contiguous() ); value_type* raw_data = data(); for( size_t j=0; j::assign(const value_type& value) { } } -template -void ArrayView::assign(const std::initializer_list& list) { +template +void ArrayView::assign(const std::initializer_list& list) { ASSERT( contiguous() ); ASSERT( list.size() == size_ ); value_type* raw_data = data(); @@ -82,8 +82,8 @@ void ArrayView::assign(const std::initializer_list -void ArrayView::dump(std::ostream& os) const { +template< typename Value, int Rank, Intent AccessMode > +void ArrayView::dump(std::ostream& os) const { ASSERT( contiguous() ); const value_type* data_ = data(); os << "size: " << size() << " , values: "; @@ -103,16 +103,16 @@ void ArrayView::dump(std::ostream& os) const { namespace atlas { namespace array { #define EXPLICIT_TEMPLATE_INSTANTIATION(Rank) \ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ // For each NDims in [1..9] EXPLICIT_TEMPLATE_INSTANTIATION(1) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 7f5a64511..160e89906 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -18,18 +18,19 @@ #include "atlas/array/LocalView.h" #include "atlas/array/gridtools/GridToolsTraits.h" #include "atlas/array/gridtools/GridToolsMakeView.h" +#include "atlas/array/ArrayViewDefs.h" //------------------------------------------------------------------------------------------------------ namespace atlas { namespace array { -template< typename Value, int Rank, bool ReadOnly = false > class ArrayView { +template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > class ArrayView { public: // -- Type definitions using value_type = typename remove_const::type; using Slice = typename std::conditional<(Rank==1), value_type&, LocalView >::type; - using data_view_t = gridtools::data_view_tt; + using data_view_t = gridtools::data_view_tt; public: @@ -105,8 +106,8 @@ template< typename Value, int Rank, bool ReadOnly = false > class ArrayView { template struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; + Slicer(ArrayView const& av) : av_(av) {} + ArrayView const& av_; ReturnType apply(const size_t i) const { return LocalView( av_.data()+av_.strides_[0]*i, @@ -117,8 +118,8 @@ template< typename Value, int Rank, bool ReadOnly = false > class ArrayView { template struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; + Slicer(ArrayView const& av) : av_(av) {} + ArrayView const& av_; ReturnType apply(const size_t i) const { return *(const_cast(av_.data()) + av_.strides_[0] * i); } diff --git a/src/atlas/array/gridtools/GridToolsMakeView.cc b/src/atlas/array/gridtools/GridToolsMakeView.cc index 1133ae9ef..56eb54f5a 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.cc +++ b/src/atlas/array/gridtools/GridToolsMakeView.cc @@ -34,8 +34,8 @@ namespace { namespace gridtools { -template -data_view_tt +template +data_view_tt make_gt_host_view(const Array& array) { using storage_info_ty = storage_traits::storage_info_t<0, Rank>; @@ -43,29 +43,29 @@ make_gt_host_view(const Array& array) { data_store_t* ds = reinterpret_cast(const_cast(array.storage())); - return ::gridtools::make_host_view< get_access_mode(ReadOnly) >(*ds); + return ::gridtools::make_host_view< get_access_mode(AccessMode) >(*ds); } -template -data_view_tt +template +data_view_tt make_gt_device_view(const Array& array) { typedef storage_traits::storage_info_t<0, Rank> storage_info_ty; typedef storage_traits::data_store_t data_store_t; data_store_t* ds = reinterpret_cast(const_cast(array.storage())); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - return ::gridtools::make_device_view< get_access_mode(ReadOnly) >(*ds); + return ::gridtools::make_device_view< get_access_mode(AccessMode) >(*ds); #else - return ::gridtools::make_host_view< get_access_mode(ReadOnly) >(*ds); + return ::gridtools::make_host_view< get_access_mode(AccessMode) >(*ds); #endif } } -template -ArrayView +template +ArrayView make_host_view(const Array& array) { check_metadata(array); - return ArrayView(gridtools::make_gt_host_view(array), array); + return ArrayView(gridtools::make_gt_host_view(array), array); } template @@ -77,11 +77,11 @@ make_host_storageview(const Array& array) { return StorageView(::gridtools::make_host_view(*ds),array.size(),array.contiguous()); } -template -ArrayView +template +ArrayView make_device_view(const Array& array) { check_metadata(array); - return ArrayView(gridtools::make_gt_device_view(array), array); + return ArrayView(gridtools::make_gt_device_view(array), array); } @@ -91,7 +91,7 @@ make_device_storageview(const Array& array) { return StorageView(gridtools::make_gt_device_view(array),array.size(),array.contiguous()); } -template +template IndexView make_host_indexview(const Array& array) { typedef gridtools::storage_traits::storage_info_t<0, Rank> storage_info_ty; @@ -104,19 +104,19 @@ make_host_indexview(const Array& array) { // -------------------------------------------------------------------------------------------- -template +template IndexView make_indexview(const Array& array) { check_metadata(array); return make_host_indexview(array); } -template -ArrayView +template +ArrayView make_view(const Array& array) { check_metadata(array); - return make_host_view(array); + return make_host_view(array); } template @@ -133,67 +133,67 @@ make_storageview(const Array& array) { namespace atlas { namespace array { #define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ \ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ \ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ \ -template IndexView make_indexview(const Array&);\ -template IndexView make_indexview(const Array&);\ +template IndexView make_indexview(const Array&);\ +template IndexView make_indexview(const Array&);\ \ -template IndexView make_host_indexview(const Array&);\ -template IndexView make_host_indexview(const Array&);\ +template IndexView make_host_indexview(const Array&);\ +template IndexView make_host_indexview(const Array&);\ \ namespace gridtools { \ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ + template data_view_tt make_gt_host_view(const Array& array);\ \ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ + template data_view_tt make_gt_device_view(const Array& array);\ } template StorageView make_storageview(const Array&); diff --git a/src/atlas/array/gridtools/GridToolsMakeView.h b/src/atlas/array/gridtools/GridToolsMakeView.h index fba59a322..0cb1c5da6 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.h +++ b/src/atlas/array/gridtools/GridToolsMakeView.h @@ -16,12 +16,12 @@ namespace atlas { namespace array { namespace gridtools { -template -data_view_tt +template +data_view_tt make_gt_host_view(const Array& array); -template -data_view_tt +template +data_view_tt make_gt_device_view(const Array& array); } // namespace gridtools diff --git a/src/atlas/array/gridtools/GridToolsTraits.h b/src/atlas/array/gridtools/GridToolsTraits.h index d75da0b20..bc1590545 100644 --- a/src/atlas/array/gridtools/GridToolsTraits.h +++ b/src/atlas/array/gridtools/GridToolsTraits.h @@ -10,6 +10,8 @@ #endif #include "common/generic_metafunctions/all_integrals.hpp" #include "storage/storage-facility.hpp" +#include "atlas/array/ArrayViewDefs.h" + #ifdef _USE_GPU_ #undef _USE_GPU_ #endif @@ -38,8 +40,8 @@ using data_view_tt = ::gridtools::data_view< gridtools::storage_traits::storage_info_t<0, Rank> >, AccessMode>; -inline constexpr ::gridtools::access_mode get_access_mode(bool readonly) { - return readonly ? ::gridtools::access_mode::ReadOnly : ::gridtools::access_mode::ReadWrite; +inline constexpr ::gridtools::access_mode get_access_mode(Intent kind) { + return (kind == Intent::ReadOnly) ? ::gridtools::access_mode::ReadOnly : ::gridtools::access_mode::ReadWrite; } //------------------------------------------------------------------------------ diff --git a/src/atlas/array_fwd.h b/src/atlas/array_fwd.h index 6cf09825e..cd343848b 100644 --- a/src/atlas/array_fwd.h +++ b/src/atlas/array_fwd.h @@ -11,6 +11,7 @@ /// @author Willem Deconinck #pragma once +#include "atlas/array/ArrayViewDefs.h" namespace atlas { namespace array { @@ -27,29 +28,29 @@ class ArrayT; template class StorageView; -template +template class ArrayView; template class IndexView; -template -ArrayView +template +ArrayView make_view(const Array& array); -template -ArrayView +template +ArrayView make_host_view(const Array& array); -template -ArrayView +template +ArrayView make_device_view(const Array& array); -template +template IndexView make_indexview(const Array& array); -template +template IndexView make_host_indexview(const Array& array); diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 41870389e..29e45052f 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -73,13 +73,13 @@ class HaloExchange: public eckit::Owned { template< typename DATA_TYPE, int RANK> - void pack_send_buffer( const array::ArrayView& hfield, + void pack_send_buffer( const array::ArrayView& hfield, const array::ArrayView& dfield, array::SVector& send_buffer ) const; template< typename DATA_TYPE, int RANK> void unpack_recv_buffer(const array::SVector& recv_buffer, - const array::ArrayView& hfield, + const array::ArrayView& hfield, array::ArrayView& dfield) const; template @@ -109,13 +109,13 @@ class HaloExchange: public eckit::Owned { }; -template -constexpr typename std::enable_if< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { +template +constexpr typename std::enable_if< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { return 1; } -template -constexpr typename std::enable_if< (cnt != RANK), size_t >::type get_var_size( array::ArrayView& field) { +template +constexpr typename std::enable_if< (cnt != RANK), size_t >::type get_var_size( array::ArrayView& field) { return get_var_size(field) * field.template shape(); } @@ -129,7 +129,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const ATLAS_TRACE("HaloExchange",{"halo-exchange"}); - auto field_hv = array::make_host_view(field); + auto field_hv = array::make_host_view(field); int tag=1; size_t var_size = get_var_size<1>(field_hv); @@ -214,7 +214,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const template struct halo_packer_impl { template - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx... idxs) { for( size_t i=0; i< field.template shape(); ++i ) { halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); @@ -225,7 +225,7 @@ struct halo_packer_impl { template struct halo_packer_impl<0, CurrentDim> { template - static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, + static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx...idxs) { send_buffer[buf_idx++] = field(node_idx, idxs...); @@ -257,7 +257,7 @@ template struct halo_packer { template static void pack(const unsigned int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ) + const array::ArrayView& field, array::SVector& send_buffer ) { size_t ibuf = 0; for(int p=0; p < sendcnt; ++p) @@ -282,7 +282,7 @@ struct halo_packer { }; template -void HaloExchange::pack_send_buffer( const array::ArrayView& hfield, +void HaloExchange::pack_send_buffer( const array::ArrayView& hfield, const array::ArrayView& dfield, array::SVector& send_buffer ) const { @@ -296,7 +296,7 @@ void HaloExchange::pack_send_buffer( const array::ArrayView void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buffer, - const array::ArrayView& hfield, + const array::ArrayView& hfield, array::ArrayView& dfield) const { ATLAS_TRACE(); diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index 72b13da17..ac924e1ed 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -11,6 +11,7 @@ */ #include "atlas/array/ArrayView.h" #include "atlas/array/SVector.h" +#include "atlas/array/ArrayViewDefs.h" namespace atlas { namespace parallel { @@ -18,22 +19,22 @@ namespace parallel { template struct halo_packer_cuda { static void pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& hfield, const array::ArrayView& dfield, + const array::ArrayView& hfield, const array::ArrayView& dfield, array::SVector& send_buffer ); static void unpack( const int sendcnt, array::SVector const & recvmap, - const array::SVector& recv_buffer, const array::ArrayView& hfield, + const array::SVector& recv_buffer, const array::ArrayView& hfield, array::ArrayView& dhfield ); }; template struct halo_packer_cuda { static void pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& hfield, const array::ArrayView& dfield, + const array::ArrayView& hfield, const array::ArrayView& dfield, array::SVector& send_buffer ); static void unpack( const int sendcnt, array::SVector const & recvmap, - const array::SVector& recv_buffer, const array::ArrayView& hfield, + const array::SVector& recv_buffer, const array::ArrayView& hfield, array::ArrayView& dfield); }; From 22cd42d4e36cd65f72b2bde860a641829b6269a5 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 22:13:21 +0100 Subject: [PATCH 125/355] make the get_var_size generic and add unittest --- src/atlas/CMakeLists.txt | 2 + src/atlas/array/ArrayViewDefs.h | 15 ++++++++ src/atlas/parallel/HaloExchange.h | 18 +++------ src/tests/array/CMakeLists.txt | 6 +++ src/tests/array/test_array_view_util.cc | 50 +++++++++++++++++++++++++ 5 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 src/tests/array/test_array_view_util.cc diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 530a3daf5..f084b8c6b 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -375,6 +375,8 @@ array/ArrayStrides.h array/ArrayUtil.cc array/ArrayUtil.h array/ArrayView.h +array/ArrayViewUtil.h +array/ArrayViewDefs.h array/DataType.h array/IndexView.h array/LocalView.cc diff --git a/src/atlas/array/ArrayViewDefs.h b/src/atlas/array/ArrayViewDefs.h index 666d90631..f8c16d69a 100644 --- a/src/atlas/array/ArrayViewDefs.h +++ b/src/atlas/array/ArrayViewDefs.h @@ -9,11 +9,26 @@ */ #pragma once +#include namespace atlas { namespace array { enum class Intent {ReadOnly, ReadWrite}; + template + struct Dim{ + static constexpr int cdim = cDim; + }; + + struct LastDim{}; + struct FirstDim{}; + + template struct is_dim_policy : std::false_type {}; + template struct is_dim_policy > : std::true_type {}; + + template<> struct is_dim_policy : std::true_type {}; + template<> struct is_dim_policy : std::true_type {}; + } // namespace array } // namespace atlas diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 29e45052f..22f26c343 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -28,6 +28,8 @@ #include "atlas/array/ArrayView.h" #include "atlas/array/SVector.h" #include "atlas/runtime/Log.h" +#include "atlas/array/ArrayViewDefs.h" +#include "atlas/array/ArrayViewUtil.h" #ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA #include "atlas/parallel/HaloExchangeCUDA.h" @@ -57,7 +59,7 @@ class HaloExchange: public eckit::Owned { // template // void execute( DATA_TYPE field[], size_t nb_vars ) const; - template + template void execute( array::Array& field, bool on_device = false) const; private: // methods @@ -109,17 +111,7 @@ class HaloExchange: public eckit::Owned { }; -template -constexpr typename std::enable_if< (cnt == RANK), size_t >::type get_var_size( array::ArrayView& field) { - return 1; -} - -template -constexpr typename std::enable_if< (cnt != RANK), size_t >::type get_var_size( array::ArrayView& field) { - return get_var_size(field) * field.template shape(); -} - -template +template void HaloExchange::execute(array::Array& field, bool on_device) const { if( ! is_setup_ ) @@ -132,7 +124,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const auto field_hv = array::make_host_view(field); int tag=1; - size_t var_size = get_var_size<1>(field_hv); + size_t var_size = array::get_var_size<0>(field_hv); int send_size = sendcnt_ * var_size; int recv_size = recvcnt_ * var_size; diff --git a/src/tests/array/CMakeLists.txt b/src/tests/array/CMakeLists.txt index 40a0a3eb9..861335c89 100644 --- a/src/tests/array/CMakeLists.txt +++ b/src/tests/array/CMakeLists.txt @@ -21,6 +21,12 @@ ecbuild_add_test( TARGET atlas_test_svector LIBS atlas ) +ecbuild_add_test( TARGET atlas_test_array_view_util + SOURCES test_array_view_util.cc + LIBS atlas +) + + if( CMAKE_BUILD_TYPE MATCHES "DEBUG" ) set ( CMAKE_NVCC_FLAGS "-G" ) endif() diff --git a/src/tests/array/test_array_view_util.cc b/src/tests/array/test_array_view_util.cc new file mode 100644 index 000000000..cf6230b06 --- /dev/null +++ b/src/tests/array/test_array_view_util.cc @@ -0,0 +1,50 @@ +/* + * (C) Copyright 1996-2016 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 "atlas/array/Array.h" +#include "atlas/array/ArrayViewUtil.h" +#include "tests/AtlasTestEnvironment.h" +#include "eckit/testing/Test.h" + +using namespace atlas::array; +using namespace eckit::testing; + +namespace atlas { +namespace test { + +//----------------------------------------------------------------------------- + +CASE("test_var_size") { + + Array* ds = Array::create(4ul, 5ul, 7ul, 9ul); + + auto arrv = make_host_view(*ds); + EXPECT(ds->size() == 1260); + + EXPECT( get_var_size<0>(arrv) == 315); + EXPECT( get_var_size<1>(arrv) == 252); + EXPECT( get_var_size<2>(arrv) == 180); + EXPECT( get_var_size<3>(arrv) == 140); + + delete ds; + +} + +//----------------------------------------------------------------------------- + +} // namespace test +} // namespace atlas + + +int main(int argc, char **argv) { + atlas::test::AtlasTestEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} + From ce32ecb765f36d87843cc51d8d79c1c63bd73e82 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 23:18:58 +0100 Subject: [PATCH 126/355] translate the parallel dim tag into a int --- src/atlas/parallel/HaloExchange.h | 2 +- src/tests/array/test_array_view_util.cc | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 22f26c343..d5a28a062 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -124,7 +124,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const auto field_hv = array::make_host_view(field); int tag=1; - size_t var_size = array::get_var_size<0>(field_hv); + size_t var_size = array::get_var_size< array::get_parallel_dim(field_hv) >(field_hv); int send_size = sendcnt_ * var_size; int recv_size = recvcnt_ * var_size; diff --git a/src/tests/array/test_array_view_util.cc b/src/tests/array/test_array_view_util.cc index cf6230b06..69f02910c 100644 --- a/src/tests/array/test_array_view_util.cc +++ b/src/tests/array/test_array_view_util.cc @@ -33,6 +33,21 @@ CASE("test_var_size") { EXPECT( get_var_size<2>(arrv) == 180); EXPECT( get_var_size<3>(arrv) == 140); + delete ds; +} + +CASE("test_get_parallel_dim") { + + Array* ds = Array::create(4ul, 5ul, 7ul, 9ul); + + auto arrv = make_host_view(*ds); + EXPECT(ds->size() == 1260); + + EXPECT( get_parallel_dim(arrv) == 0); + EXPECT( get_parallel_dim(arrv) == 3); + EXPECT( get_parallel_dim>(arrv) == 1); + EXPECT( get_parallel_dim>(arrv) == 2); + delete ds; } From f6b265839c8a5bb8446d8ae497525fba9a031f37 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 23:21:22 +0100 Subject: [PATCH 127/355] pass the parallel dim to the pack/unpack --- src/atlas/parallel/HaloExchange.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index d5a28a062..d93f0d26a 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -74,12 +74,12 @@ class HaloExchange: public eckit::Owned { size_t index(size_t i, size_t j, size_t ni, size_t nj) const { return( i + ni*j ); } - template< typename DATA_TYPE, int RANK> + template< int ParallelDim, typename DATA_TYPE, int RANK> void pack_send_buffer( const array::ArrayView& hfield, const array::ArrayView& dfield, array::SVector& send_buffer ) const; - template< typename DATA_TYPE, int RANK> + template< int ParallelDim, typename DATA_TYPE, int RANK> void unpack_recv_buffer(const array::SVector& recv_buffer, const array::ArrayView& hfield, array::ArrayView& dfield) const; @@ -124,7 +124,8 @@ void HaloExchange::execute(array::Array& field, bool on_device) const auto field_hv = array::make_host_view(field); int tag=1; - size_t var_size = array::get_var_size< array::get_parallel_dim(field_hv) >(field_hv); + constexpr int parallelDim = array::get_parallel_dim(field_hv); + size_t var_size = array::get_var_size< parallelDim >(field_hv); int send_size = sendcnt_ * var_size; int recv_size = recvcnt_ * var_size; @@ -161,7 +162,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const } /// Pack - pack_send_buffer(field_hv, field_dv,send_buffer); + pack_send_buffer(field_hv, field_dv,send_buffer); /// Send ATLAS_TRACE_MPI( ISEND ) { @@ -188,7 +189,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const } /// Unpack - unpack_recv_buffer(recv_buffer, field_hv, field_dv); + unpack_recv_buffer(recv_buffer, field_hv, field_dv); /// Wait for sending to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { @@ -273,7 +274,7 @@ struct halo_packer { }; -template +template void HaloExchange::pack_send_buffer( const array::ArrayView& hfield, const array::ArrayView& dfield, array::SVector& send_buffer ) const @@ -286,7 +287,7 @@ void HaloExchange::pack_send_buffer( const array::ArrayView +template void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buffer, const array::ArrayView& hfield, array::ArrayView& dfield) const From b90c303042662baae198d6fbcca2f765676cda77 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Fri, 3 Nov 2017 23:57:23 +0100 Subject: [PATCH 128/355] generalize the packer and unpacker impl --- src/atlas/parallel/HaloExchange.h | 58 +++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index d93f0d26a..31c7e782e 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -204,19 +204,30 @@ void HaloExchange::execute(array::Array& field, bool on_device) const } -template +template struct halo_packer_impl { template static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx... idxs) { - for( size_t i=0; i< field.template shape(); ++i ) { - halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); - } + for( size_t i=0; i< field.template shape(); ++i ) { + halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); + } } }; -template -struct halo_packer_impl<0, CurrentDim> { +template +struct halo_packer_impl +{ + template + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, + array::SVector& send_buffer, Idx... idxs) { + //TODO node should be inserted in the right place accordim to parallel dim + halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs...); + } +}; + +template +struct halo_packer_impl { template static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx...idxs) @@ -225,19 +236,28 @@ struct halo_packer_impl<0, CurrentDim> { } }; -template +template struct halo_unpacker_impl { template static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, array::ArrayView& field, Idx... idxs) { for( size_t i=0; i< field.template shape(); ++i ) { - halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs..., i); + halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs..., i); } } }; -template -struct halo_unpacker_impl<0, CurrentDim> { +template +struct halo_unpacker_impl { + template + static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, + array::ArrayView& field, Idx... idxs) { + halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs...); + } +}; + +template +struct halo_unpacker_impl { template static void apply(size_t& buf_idx, size_t node_idx, array::SVector const & recv_buffer, array::ArrayView& field, Idx...idxs) @@ -246,17 +266,17 @@ struct halo_unpacker_impl<0, CurrentDim> { } }; -template +template struct halo_packer { template static void pack(const unsigned int sendcnt, array::SVector const & sendmap, const array::ArrayView& field, array::SVector& send_buffer ) { size_t ibuf = 0; - for(int p=0; p < sendcnt; ++p) + for(int node_cnt=0; node_cnt < sendcnt; ++node_cnt) { - const size_t pp = sendmap[p]; - halo_packer_impl::apply(ibuf, pp, field, send_buffer); + const size_t node_idx = sendmap[node_cnt]; + halo_packer_impl::apply(ibuf, node_idx, field, send_buffer); } } @@ -265,10 +285,10 @@ struct halo_packer { array::SVector const & recv_buffer, array::ArrayView& field ) { size_t ibuf = 0; - for(int p=0; p < recvcnt; ++p) + for(int node_cnt=0; node_cnt < recvcnt; ++node_cnt) { - const size_t pp = recvmap[p]; - halo_unpacker_impl::apply(ibuf, pp, recv_buffer, field); + const size_t node_idx = recvmap[node_cnt]; + halo_unpacker_impl::apply(ibuf, node_idx, recv_buffer, field); } } @@ -283,7 +303,7 @@ void HaloExchange::pack_send_buffer( const array::ArrayView::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); #else - halo_packer::pack(sendcnt_, sendmap_, hfield, send_buffer); + halo_packer::pack(sendcnt_, sendmap_, hfield, send_buffer); #endif } @@ -297,7 +317,7 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); #else - halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); + halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); #endif } From 2381a57031b2b135d45d255328c90c2902c2e50b Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sat, 4 Nov 2017 21:13:23 +0100 Subject: [PATCH 129/355] test the policy that determines the parallel dimension --- src/atlas/parallel/HaloExchange.h | 9 ++-- src/tests/parallel/test_haloexchange.cc | 68 +++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 31c7e782e..cbd680f84 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -221,8 +221,7 @@ struct halo_packer_impl template static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx... idxs) { - //TODO node should be inserted in the right place accordim to parallel dim - halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs...); + halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs...,node_idx); } }; @@ -232,7 +231,7 @@ struct halo_packer_impl { static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx...idxs) { - send_buffer[buf_idx++] = field(node_idx, idxs...); + send_buffer[buf_idx++] = field(idxs...); } }; @@ -252,7 +251,7 @@ struct halo_unpacker_impl { template static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, array::ArrayView& field, Idx... idxs) { - halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs...); + halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs...,node_idx); } }; @@ -262,7 +261,7 @@ struct halo_unpacker_impl { static void apply(size_t& buf_idx, size_t node_idx, array::SVector const & recv_buffer, array::ArrayView& field, Idx...idxs) { - field(node_idx, idxs...) = recv_buffer[buf_idx++]; + field(idxs...) = recv_buffer[buf_idx++]; } }; diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 5720a14e3..dc8efc2ad 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -534,6 +534,74 @@ CASE("test_haloexchange") { } } } + + SECTION( "test_rank1_paralleldim_1" ) + { + array::ArrayT arr(2,f.N); + array::ArrayView arrv = array::make_view(arr); + for( int j=0; j(arr, false); + + switch( parallel::mpi::comm().rank() ) + { + case 0: { POD arr_c[] = { 90, 10, 20 , 30 , 40, 900, 100, 200, 300, 400 }; //90,900, 10,100, 20,200, 30,300, 40,400 }; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 1: { POD arr_c[] = { 30,40,50,60,70,80, 300,400,500,600,700,800}; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 2: { POD arr_c[] = { 50,60,70,80,90,10,20, 500,600,700,800,900,100,200}; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + } + } + + SECTION( "test_rank2_paralleldim_2" ) + { + array::ArrayT arr(3,f.N,2); + array::ArrayView arrv = array::make_view(arr); + for( int p=0; p >(arr, false); + + switch( parallel::mpi::comm().rank() ) + { + case 0: + { + int arr_c[] = { -9,9, -1,1, -2,2, -3,3, -4,4, + -90,90, -10,10, -20,20, -30,30, -40,40, + -900,900, -100,100, -200,200, -300,300, -400,400}; + + EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 1: + { + int arr_c[] = { -3,3, -4,4, -5,5, -6,6, -7,7, -8,8, + -30,30, -40,40, -50,50, -60,60, -70,70, -80,80, + -300,300, -400,400, -500,500, -600,600, -700,700, -800,800}; + EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 2: + { + int arr_c[] = { -5,5, -6,6, -7,7, -8,8, -9,9, -1,1, -2,2, + -50,50, -60,60, -70,70, -80,80, -90,90, -10,10, -20,20, + -500,500, -600,600, -700,700, -800,800, -900,900, -100,100, -200,200}; + EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + } + } + } } From e33b3f1e1f2ef8f0c037bfdebbe2aae541d81df3 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sat, 4 Nov 2017 21:18:53 +0100 Subject: [PATCH 130/355] adapt GPU to latest API --- src/atlas/parallel/HaloExchangeCUDA.cu | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 5523026c2..4847572bd 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -15,7 +15,7 @@ namespace parallel { template __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, - const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { + const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; @@ -29,7 +29,7 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendma template __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, - const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { + const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; @@ -45,7 +45,7 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendma template __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, - const array::ArrayView field, DATA_TYPE* send_buffer, + const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; @@ -55,13 +55,13 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap template __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, - const array::ArrayView field, DATA_TYPE* send_buffer, + const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if<(RANK>3), int>::type = 0) { } template __global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, - const DATA_TYPE* recv_buffer, array::ArrayView field, + const DATA_TYPE* recv_buffer, array::ArrayView field, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; @@ -77,7 +77,7 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm template __global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, - const DATA_TYPE* recv_buffer, array::ArrayView field, + const DATA_TYPE* recv_buffer, array::ArrayView field, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; @@ -94,7 +94,7 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm template __global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, - const DATA_TYPE* recv_buffer, array::ArrayView field, + const DATA_TYPE* recv_buffer, array::ArrayView field, const typename std::enable_if::type = 0) { const size_t p = blockIdx.x*blockDim.x + threadIdx.x; @@ -105,13 +105,13 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm template __global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, - const DATA_TYPE* recv_buffer, array::ArrayView field, + const DATA_TYPE* recv_buffer, array::ArrayView field, typename std::enable_if<(RANK>3), int>::type* = 0) { } template void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& hfield, const array::ArrayView& dfield, + const array::ArrayView& hfield, const array::ArrayView& dfield, array::SVector& send_buffer ) { const unsigned int block_size_x = 32; @@ -132,7 +132,7 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< template void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& hfield, const array::ArrayView& dfield, + const array::ArrayView& hfield, const array::ArrayView& dfield, array::SVector& send_buffer ) { const unsigned int block_size_x = 32; @@ -154,7 +154,7 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector void halo_packer_cuda::unpack(const int recvcnt, array::SVector const & recvmap, const array::SVector &recv_buffer , - const array::ArrayView &hfield, array::ArrayView &dfield) + const array::ArrayView &hfield, array::ArrayView &dfield) { const unsigned int block_size_x = 32; const unsigned int block_size_y = 4; @@ -187,7 +187,7 @@ void halo_packer_cuda::unpack(const int recvcnt, array::SVector template void halo_packer_cuda::unpack(const int recvcnt, array::SVector const & recvmap, const array::SVector &recv_buffer , - const array::ArrayView &hfield, array::ArrayView &dfield) + const array::ArrayView &hfield, array::ArrayView &dfield) { const unsigned int block_size_x = 32; From 2f7f1d70335af3fc62e03ab58371070813662ad3 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sat, 4 Nov 2017 21:29:35 +0100 Subject: [PATCH 131/355] add missing header --- src/atlas/array/ArrayViewUtil.h | 50 ++++++++++++++++++++++++++ src/atlas/parallel/HaloExchangeCUDA.cu | 27 +++----------- 2 files changed, 54 insertions(+), 23 deletions(-) create mode 100644 src/atlas/array/ArrayViewUtil.h diff --git a/src/atlas/array/ArrayViewUtil.h b/src/atlas/array/ArrayViewUtil.h new file mode 100644 index 000000000..6724464ad --- /dev/null +++ b/src/atlas/array/ArrayViewUtil.h @@ -0,0 +1,50 @@ +/* + * (C) Copyright 1996-2017 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/array/ArrayView.h" + +namespace atlas { +namespace array { + +template +constexpr typename std::enable_if< (cnt == RANK), size_t >::type get_var_size_impl( array::ArrayView& field) { + return 1; +} + +template +constexpr typename std::enable_if< (cnt != RANK), size_t >::type get_var_size_impl( array::ArrayView& field) { + return (cnt == DimSkip) ? get_var_size_impl(field) : get_var_size_impl(field) * field.template shape(); +} + +template +constexpr size_t get_var_size( array::ArrayView& field) { + return get_var_size_impl<0, DimSkip>(field); +} + +template struct get_dim { + static constexpr int value = -1; +}; + +template struct get_dim > +{ + static constexpr int value = cDim; +}; + +template +constexpr unsigned int get_parallel_dim(array::ArrayView& field) { + static_assert(is_dim_policy::value, "DimPolicy required"); + return std::is_same::value ? 0 : + ( std::is_same::value ? RANK - 1 : + (get_dim::value) + ); +} + +} // namespace array +} // namespace atlas diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 4847572bd..7258f8ee9 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -115,10 +115,12 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< array::SVector& send_buffer ) { const unsigned int block_size_x = 32; - const unsigned int block_size_y = 4; + const unsigned int block_size_y = (RANK==1) ? 1 : 4; + + unsigned int nblocks_y = (RANK==1) ? 1 : (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y; dim3 threads(block_size_x, block_size_y); - dim3 blocks((sendcnt+block_size_x-1)/block_size_x, (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y); + dim3 blocks((sendcnt+block_size_x-1)/block_size_x, nblocks_y); cudaDeviceSynchronize(); pack_kernel<<>>(sendcnt, sendmap, dfield, (send_buffer.data())); @@ -130,27 +132,6 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< } -template -void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& hfield, const array::ArrayView& dfield, - array::SVector& send_buffer ) -{ - const unsigned int block_size_x = 32; - - dim3 threads(block_size_x, 1); - dim3 blocks((sendcnt+block_size_x-1)/block_size_x, 1); - cudaDeviceSynchronize(); - - pack_kernel<<>>(sendcnt, sendmap, dfield, (send_buffer.data())); - - cudaDeviceSynchronize(); - cudaError_t err = cudaGetLastError(); - if (err != cudaSuccess) - throw eckit::Exception("Error launching GPU packing kernel"); - -} - - template void halo_packer_cuda::unpack(const int recvcnt, array::SVector const & recvmap, const array::SVector &recv_buffer , From 99353b06f7667602fc767baf7a7e69ece0639b9e Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sat, 4 Nov 2017 21:31:57 +0100 Subject: [PATCH 132/355] generic version of kernel launcher --- src/atlas/parallel/HaloExchangeCUDA.cu | 38 +++----------------------- 1 file changed, 4 insertions(+), 34 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 7258f8ee9..ea3052110 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -138,42 +138,12 @@ void halo_packer_cuda::unpack(const int recvcnt, array::SVector const array::ArrayView &hfield, array::ArrayView &dfield) { const unsigned int block_size_x = 32; - const unsigned int block_size_y = 4; - dim3 threads(block_size_x, block_size_y); - dim3 blocks((recvcnt+block_size_x-1)/block_size_x, (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y); - - cudaDeviceSynchronize(); - cudaError_t err = cudaGetLastError(); - if (err != cudaSuccess) { - std::string msg = std::string("Error synchronizing device")+ cudaGetErrorString(err); - throw eckit::Exception(msg); - } - - unpack_kernel<<>>(recvcnt, recvmap, recv_buffer.data(), dfield); - - err = cudaGetLastError(); - if (err != cudaSuccess) { - std::string msg = std::string("Error launching GPU packing kernel")+ cudaGetErrorString(err); - throw eckit::Exception(msg); - } - - cudaDeviceSynchronize(); - err = cudaGetLastError(); - if (err != cudaSuccess) { - std::string msg = std::string("Error synchronizing device")+ cudaGetErrorString(err); - throw eckit::Exception(msg); - } -} + const unsigned int block_size_y = (RANK==1) ? 1 : 4; -template -void halo_packer_cuda::unpack(const int recvcnt, array::SVector const & recvmap, - const array::SVector &recv_buffer , - const array::ArrayView &hfield, array::ArrayView &dfield) -{ - const unsigned int block_size_x = 32; + unsigned int nblocks_y = (RANK==1) ? 1 : (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y; - dim3 threads(block_size_x, 1); - dim3 blocks((recvcnt+block_size_x-1)/block_size_x, 1); + dim3 threads(block_size_x, block_size_y); + dim3 blocks((sendcnt+block_size_x-1)/block_size_x, nblocks_y); cudaDeviceSynchronize(); cudaError_t err = cudaGetLastError(); From 2ec09e394e64f201f40a71a4f2e36ac547dcd6c5 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 5 Nov 2017 02:38:07 +0100 Subject: [PATCH 133/355] fix --- src/atlas/parallel/HaloExchangeCUDA.cu | 23 ++++++++++++++++++++--- src/atlas/parallel/HaloExchangeCUDA.h | 12 ------------ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index ea3052110..5070f65ab 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -109,6 +109,23 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm typename std::enable_if<(RANK>3), int>::type* = 0) { } +template +struct get_n_cuda_blocks +{ + template + static unsigned int apply(const array::ArrayView& hfield, const unsigned int block_size_y) { + return (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y; + } +}; + +template<> +struct get_n_cuda_blocks<1> { + template + static unsigned int apply(const array::ArrayView& hfield, const unsigned int block_size_y) { + return 1; + } +}; + template void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, const array::ArrayView& hfield, const array::ArrayView& dfield, @@ -117,7 +134,7 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< const unsigned int block_size_x = 32; const unsigned int block_size_y = (RANK==1) ? 1 : 4; - unsigned int nblocks_y = (RANK==1) ? 1 : (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y; + unsigned int nblocks_y = get_n_cuda_blocks::apply(hfield, block_size_y); dim3 threads(block_size_x, block_size_y); dim3 blocks((sendcnt+block_size_x-1)/block_size_x, nblocks_y); @@ -140,10 +157,10 @@ void halo_packer_cuda::unpack(const int recvcnt, array::SVector const unsigned int block_size_x = 32; const unsigned int block_size_y = (RANK==1) ? 1 : 4; - unsigned int nblocks_y = (RANK==1) ? 1 : (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y; + unsigned int nblocks_y = get_n_cuda_blocks::apply(hfield, block_size_y); dim3 threads(block_size_x, block_size_y); - dim3 blocks((sendcnt+block_size_x-1)/block_size_x, nblocks_y); + dim3 blocks((recvcnt+block_size_x-1)/block_size_x, nblocks_y); cudaDeviceSynchronize(); cudaError_t err = cudaGetLastError(); diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index ac924e1ed..27d27b323 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -27,18 +27,6 @@ struct halo_packer_cuda { array::ArrayView& dhfield ); }; -template -struct halo_packer_cuda { - static void pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& hfield, const array::ArrayView& dfield, - array::SVector& send_buffer ); - - static void unpack( const int sendcnt, array::SVector const & recvmap, - const array::SVector& recv_buffer, const array::ArrayView& hfield, - array::ArrayView& dfield); -}; - - } // namespace paralllel } // namespace atlas From bd39ef1277f6a7a6420f17fc352b7ede247fbc6a Mon Sep 17 00:00:00 2001 From: cosunae Date: Sun, 5 Nov 2017 03:36:49 +0100 Subject: [PATCH 134/355] fix for SVector and workaround in CUDA kernels in order to fix issue with CUDA managed --- src/atlas/array/SVector.h | 36 ++++++++++++++++++++------ src/atlas/parallel/HaloExchangeCUDA.cu | 34 ++++++++++++++++-------- src/tests/array/test_svector_kernel.cu | 8 +++--- 3 files changed, 56 insertions(+), 22 deletions(-) diff --git a/src/atlas/array/SVector.h b/src/atlas/array/SVector.h index d3712ab2a..01ac313a1 100644 --- a/src/atlas/array/SVector.h +++ b/src/atlas/array/SVector.h @@ -30,10 +30,13 @@ namespace array { template class SVector { public: - SVector() : data_(nullptr), size_(0) {} + SVector() : data_(nullptr), size_(0), externally_allocated_(false) {} ATLAS_HOST_DEVICE - SVector(SVector const & other) : data_(other.data_), size_(other.size_){} + SVector(SVector const & other) : data_(other.data_), size_(other.size_), externally_allocated_(other.externally_allocated_){} + + ATLAS_HOST_DEVICE + SVector(T* data, size_t size): data_(data), size_(size) {} SVector(size_t N) : size_(N) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA @@ -44,8 +47,12 @@ class SVector { data_ = (T*)malloc(N*sizeof(T)); #endif } + ATLAS_HOST_DEVICE ~SVector(){ +#ifndef __CUDA_ARCH__ + if(!externally_allocated_) delete_managedmem(data_); +#endif } void delete_managedmem(T*& data) { @@ -57,10 +64,10 @@ class SVector { err = cudaFree(data); // The following throws an invalid device memory -/* + if(err != cudaSuccess) throw eckit::AssertionFailed("failed to free GPU memory"); -*/ + #else free(data_); #endif @@ -71,14 +78,26 @@ class SVector { T const * data() const { return data_; } ATLAS_HOST_DEVICE - T& operator()(const size_t idx) { return data_[idx]; } + T& operator()(const size_t idx) { + assert(data_ && idx < size_); + return data_[idx]; + } ATLAS_HOST_DEVICE - T const& operator()(const size_t idx) const { return data_[idx]; } + T const& operator()(const size_t idx) const { + assert(data_ && idx < size_); + return data_[idx]; + } ATLAS_HOST_DEVICE - T& operator[](const size_t idx) { return data_[idx]; } + T& operator[](const size_t idx) { + assert(data_ && idx < size_); + return data_[idx]; + } ATLAS_HOST_DEVICE - T const& operator[](const size_t idx) const { return data_[idx]; } + T const& operator[](const size_t idx) const { + assert(data_ && idx < size_); + return data_[idx]; + } ATLAS_HOST_DEVICE size_t size() const { return size_; } @@ -111,6 +130,7 @@ class SVector { private: T* data_; size_t size_; + bool externally_allocated_; }; //------------------------------------------------------------------------------ diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 5070f65ab..b3214c208 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -8,14 +8,16 @@ * does it submit to any jurisdiction. */ -#include "HaloExchangeCUDA.h" +#include "atlas/parallel/HaloExchangeCUDA.h" +#include "atlas/array/SVector.h" namespace atlas { namespace parallel { template -__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, +__global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { + const array::SVector sendmap(const_cast(sendmap_ptr), sendmap_size); const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; @@ -28,8 +30,10 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendma } template -__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, +__global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { + const array::SVector sendmap(const_cast(sendmap_ptr), sendmap_size); + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; @@ -44,9 +48,11 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendma } template -__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, +__global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { + const array::SVector sendmap(const_cast(sendmap_ptr), sendmap_size); + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; if(p >= sendcnt) return; @@ -54,16 +60,18 @@ __global__ void pack_kernel(const int sendcnt, const array::SVector sendmap } template -__global__ void pack_kernel(const int sendcnt, const array::SVector sendmap, +__global__ void pack_kernel(const int sendcnt, const int* sendmap, const size_t sendmap_size, const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if<(RANK>3), int>::type = 0) { } template -__global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, +__global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, const DATA_TYPE* recv_buffer, array::ArrayView field, const typename std::enable_if::type = 0) { + const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; @@ -76,10 +84,12 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm } template -__global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, +__global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, const DATA_TYPE* recv_buffer, array::ArrayView field, const typename std::enable_if::type = 0) { + const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; @@ -93,10 +103,12 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm } template -__global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, +__global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, const DATA_TYPE* recv_buffer, array::ArrayView field, const typename std::enable_if::type = 0) { + const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); + const size_t p = blockIdx.x*blockDim.x + threadIdx.x; if(p >= recvcnt) return; @@ -104,7 +116,7 @@ __global__ void unpack_kernel(const int recvcnt, const array::SVector recvm } template -__global__ void unpack_kernel(const int recvcnt, const array::SVector recvmap, +__global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, const DATA_TYPE* recv_buffer, array::ArrayView field, typename std::enable_if<(RANK>3), int>::type* = 0) { } @@ -140,7 +152,7 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< dim3 blocks((sendcnt+block_size_x-1)/block_size_x, nblocks_y); cudaDeviceSynchronize(); - pack_kernel<<>>(sendcnt, sendmap, dfield, (send_buffer.data())); + pack_kernel<<>>(sendcnt, sendmap.data(), sendmap.size(), dfield, (send_buffer.data())); cudaDeviceSynchronize(); cudaError_t err = cudaGetLastError(); @@ -169,7 +181,7 @@ void halo_packer_cuda::unpack(const int recvcnt, array::SVector throw eckit::Exception(msg); } - unpack_kernel<<>>(recvcnt, recvmap, recv_buffer.data(), dfield); + unpack_kernel<<>>(recvcnt, recvmap.data(), recvmap.size(), recv_buffer.data(), dfield); err = cudaGetLastError(); if (err != cudaSuccess) { diff --git a/src/tests/array/test_svector_kernel.cu b/src/tests/array/test_svector_kernel.cu index 489701968..9d84786d5 100644 --- a/src/tests/array/test_svector_kernel.cu +++ b/src/tests/array/test_svector_kernel.cu @@ -21,8 +21,10 @@ namespace atlas { namespace test { __global__ -void kernel_exe(array::SVector list_ints, int offset, bool* result ) +void kernel_exe(int* list_ints_ptr, size_t size, int offset, bool* result ) { + SVector list_ints(list_ints_ptr, size); + *result = *result && (list_ints[offset] == 3); *result = *result && (list_ints[offset+1] == 4); @@ -50,7 +52,7 @@ CASE( "test_svector" ) throw eckit::AssertionFailed("failed to allocate GPU memory"); *result=true; - kernel_exe<<<1,1>>>(list_ints, 0, result); + kernel_exe<<<1,1>>>(list_ints.data(), list_ints.size(), 0, result); cudaDeviceSynchronize(); err = cudaGetLastError(); @@ -90,7 +92,7 @@ CASE( "test_svector_resize" ) list_ints[3] = 3; list_ints[4] = 4; - kernel_exe<<<1,1>>>(list_ints, 3, result); + kernel_exe<<<1,1>>>(list_ints.data(), list_ints.size(), 3, result); cudaDeviceSynchronize(); err = cudaGetLastError(); From 3ac32ba5672327ae0adc6d0607259e0564849887 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 5 Nov 2017 12:49:36 +0100 Subject: [PATCH 135/355] generalize the gpu --- src/atlas/CMakeLists.txt | 1 + .../array/gridtools/GridToolsArrayView.h | 1 + src/atlas/parallel/HaloExchange.h | 62 +------------------ src/atlas/parallel/HaloExchangeCUDA.cu | 55 ++++++++++------ 4 files changed, 40 insertions(+), 79 deletions(-) diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index f084b8c6b..523cf3c41 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -434,6 +434,7 @@ parallel/GatherScatter.cc parallel/GatherScatter.h parallel/HaloExchange.cc parallel/HaloExchange.h +parallel/HaloExchangeImpl.h parallel/mpi/Buffer.h runtime/ErrorHandling.cc runtime/ErrorHandling.h diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 160e89906..5983b2184 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -79,6 +79,7 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas } template + ATLAS_HOST_DEVICE size_t shape() const { return gt_data_view_.template length(); } diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index cbd680f84..a201b75ea 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -23,6 +23,7 @@ #include "eckit/exception/Exceptions.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/mpi/Statistics.h" +#include "atlas/parallel/HaloExchangeImpl.h" #include "atlas/array_fwd.h" #include "atlas/array/ArrayView.h" @@ -204,67 +205,6 @@ void HaloExchange::execute(array::Array& field, bool on_device) const } -template -struct halo_packer_impl { - template - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, - array::SVector& send_buffer, Idx... idxs) { - for( size_t i=0; i< field.template shape(); ++i ) { - halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); - } - } -}; - -template -struct halo_packer_impl -{ - template - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, - array::SVector& send_buffer, Idx... idxs) { - halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs...,node_idx); - } -}; - -template -struct halo_packer_impl { - template - static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, - array::SVector& send_buffer, Idx...idxs) - { - send_buffer[buf_idx++] = field(idxs...); - } -}; - -template -struct halo_unpacker_impl { - template - static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, - array::ArrayView& field, Idx... idxs) { - for( size_t i=0; i< field.template shape(); ++i ) { - halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs..., i); - } - } -}; - -template -struct halo_unpacker_impl { - template - static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, - array::ArrayView& field, Idx... idxs) { - halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs...,node_idx); - } -}; - -template -struct halo_unpacker_impl { - template - static void apply(size_t& buf_idx, size_t node_idx, array::SVector const & recv_buffer, - array::ArrayView& field, Idx...idxs) - { - field(idxs...) = recv_buffer[buf_idx++]; - } -}; - template struct halo_packer { template diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index b3214c208..3009a3084 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -9,6 +9,7 @@ */ #include "atlas/parallel/HaloExchangeCUDA.h" +#include "atlas/parallel/HaloExchangeImpl.h" #include "atlas/array/SVector.h" namespace atlas { @@ -67,57 +68,65 @@ __global__ void pack_kernel(const int sendcnt, const int* sendmap, const size_t template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, - const DATA_TYPE* recv_buffer, array::ArrayView field, - const typename std::enable_if::type = 0) { + const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, + array::ArrayView field, + const typename std::enable_if::type = 0) { const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); + const array::SVector recv_buffer(const_cast(recv_buffer_ptr), recv_buffer_size); const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; if(p >= recvcnt || i >= field.data_view().template length<1>() ) return; - const size_t buff_idx = field.data_view().template length<1>() * p + i; + const size_t node_idx = recvmap[p]; - field(recvmap[p], i) = recv_buffer[buff_idx]; + size_t buff_idx = field.data_view().template length<1>() * p + i; + halo_unpacker_impl<0, 0, 1>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,i); } template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, - const DATA_TYPE* recv_buffer, array::ArrayView field, - const typename std::enable_if::type = 0) { + const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView field, const typename std::enable_if::type = 0) { const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); + const array::SVector recv_buffer(const_cast(recv_buffer_ptr), recv_buffer_size); const size_t p = blockIdx.x*blockDim.x + threadIdx.x; const size_t i = blockIdx.y*blockDim.y + threadIdx.y; if(p >= recvcnt || i >= field.data_view().template length<1>() ) return; + const size_t node_idx = recvmap[p]; + size_t buff_idx = field.data_view().template length<2>() * field.data_view().template length<1>() * p + field.data_view().template length<2>() * i; - for(size_t varid=0; varid < field.data_view().template length<2>(); ++varid) { - field(recvmap[p], i, varid) = recv_buffer[buff_idx++]; - } + halo_unpacker_impl<0, 1, 2>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,i); } template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, - const DATA_TYPE* recv_buffer, array::ArrayView field, - const typename std::enable_if::type = 0) { + const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView field, const typename std::enable_if::type = 0) { const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); + const array::SVector recv_buffer(const_cast(recv_buffer_ptr), recv_buffer_size); - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; + size_t p = blockIdx.x*blockDim.x + threadIdx.x; if(p >= recvcnt) return; - field(recvmap[p]) = recv_buffer[p]; + + const size_t node_idx = recvmap[p]; + + halo_unpacker_impl<0, 0, 1>::apply(p, node_idx, recv_buffer, field,node_idx); } template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, - const DATA_TYPE* recv_buffer, array::ArrayView field, + const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView field, typename std::enable_if<(RANK>3), int>::type* = 0) { } @@ -151,13 +160,23 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< dim3 threads(block_size_x, block_size_y); dim3 blocks((sendcnt+block_size_x-1)/block_size_x, nblocks_y); cudaDeviceSynchronize(); + cudaError_t err = cudaGetLastError(); + if (err != cudaSuccess) { + std::string msg = std::string("Error synchronizing device")+ cudaGetErrorString(err); + throw eckit::Exception(msg); + } pack_kernel<<>>(sendcnt, sendmap.data(), sendmap.size(), dfield, (send_buffer.data())); + err = cudaGetLastError(); + if (err != cudaSuccess) + throw eckit::Exception("Error launching GPU packing kernel"); cudaDeviceSynchronize(); - cudaError_t err = cudaGetLastError(); - if (err != cudaSuccess) - throw eckit::Exception("Error launching GPU packing kernel"); + err = cudaGetLastError(); + if (err != cudaSuccess) { + std::string msg = std::string("Error synchronizing device")+ cudaGetErrorString(err); + throw eckit::Exception(msg); + } } @@ -181,7 +200,7 @@ void halo_packer_cuda::unpack(const int recvcnt, array::SVector throw eckit::Exception(msg); } - unpack_kernel<<>>(recvcnt, recvmap.data(), recvmap.size(), recv_buffer.data(), dfield); + unpack_kernel<<>>(recvcnt, recvmap.data(), recvmap.size(), recv_buffer.data(), recv_buffer.size(), dfield); err = cudaGetLastError(); if (err != cudaSuccess) { From a1d2e855d10f90e0952cfdff6790ad265fda1832 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 5 Nov 2017 12:51:57 +0100 Subject: [PATCH 136/355] add missing file --- src/atlas/parallel/HaloExchangeImpl.h | 90 +++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/atlas/parallel/HaloExchangeImpl.h diff --git a/src/atlas/parallel/HaloExchangeImpl.h b/src/atlas/parallel/HaloExchangeImpl.h new file mode 100644 index 000000000..f8e7907fc --- /dev/null +++ b/src/atlas/parallel/HaloExchangeImpl.h @@ -0,0 +1,90 @@ +#pragma once + +/* + * (C) Copyright 1996-2017 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 "atlas/array/SVector.h" +#include "atlas/array/ArrayView.h" + + +namespace atlas { +namespace parallel { + +template +struct halo_packer_impl { + template + ATLAS_HOST_DEVICE + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, + array::SVector& send_buffer, Idx... idxs) { + for( size_t i=0; i< field.template shape(); ++i ) { + halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); + } + } +}; + +template +struct halo_packer_impl +{ + template + ATLAS_HOST_DEVICE + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, + array::SVector& send_buffer, Idx... idxs) { + halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs...,node_idx); + } +}; + +template +struct halo_packer_impl { + template + ATLAS_HOST_DEVICE + static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, + array::SVector& send_buffer, Idx...idxs) + { + send_buffer[buf_idx++] = field(idxs...); + } +}; + +template +struct halo_unpacker_impl { + template + ATLAS_HOST_DEVICE + static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, + array::ArrayView& field, Idx... idxs) { + for( size_t i=0; i< field.template shape(); ++i ) { + halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs..., i); + } + } +}; + +template +struct halo_unpacker_impl { + template + ATLAS_HOST_DEVICE + static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, + array::ArrayView& field, Idx... idxs) { + halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs...,node_idx); + } +}; + +template +struct halo_unpacker_impl { + + template + ATLAS_HOST_DEVICE + static void apply(size_t& buf_idx, size_t node_idx, array::SVector const & recv_buffer, + array::ArrayView& field, Idx...idxs) + { + field(idxs...) = recv_buffer[buf_idx++]; + } +}; + + +} //namespace parallel +} //namespace atlas + From 91f832e7e813b415cef5193b7cc3496ec40ac3c3 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 5 Nov 2017 22:55:25 +0100 Subject: [PATCH 137/355] generalize the buffer index computation --- src/atlas/parallel/HaloExchangeCUDA.cu | 47 +++++++++++++++++++------- src/atlas/parallel/HaloExchangeImpl.h | 12 +++++++ 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 3009a3084..77b0549e4 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -66,6 +66,27 @@ __global__ void pack_kernel(const int sendcnt, const int* sendmap, const size_t const typename std::enable_if<(RANK>3), int>::type = 0) { } +template +struct get_buffer_index{ + template + ATLAS_HOST_DEVICE + static size_t apply(array::ArrayView& field, + const size_t node_cnt, const size_t var1_idx) { + return field.data_view().template length() * field.data_view().template length() * node_cnt + + field.data_view().template length() * var1_idx; + } +}; + +template<> +struct get_buffer_index<2>{ + template + ATLAS_HOST_DEVICE + static size_t apply(array::ArrayView& field, + const size_t node_cnt, const size_t var1_idx) { + return field.data_view().template length<1>() * node_cnt + var1_idx; + } +}; + template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, @@ -75,16 +96,16 @@ __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const s const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); const array::SVector recv_buffer(const_cast(recv_buffer_ptr), recv_buffer_size); - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + const size_t node_cnt = blockIdx.x*blockDim.x + threadIdx.x; + const size_t var1_idx = blockIdx.y*blockDim.y + threadIdx.y; - if(p >= recvcnt || i >= field.data_view().template length<1>() ) return; + if(node_cnt >= recvcnt || var1_idx >= field.data_view().template length<1>() ) return; - const size_t node_idx = recvmap[p]; + const size_t node_idx = recvmap[node_cnt]; - size_t buff_idx = field.data_view().template length<1>() * p + i; + size_t buff_idx = get_buffer_index::apply(field, node_cnt, var1_idx); - halo_unpacker_impl<0, 0, 1>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,i); + halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, (RANK-1)>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,var1_idx); } template @@ -95,16 +116,16 @@ __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const s const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); const array::SVector recv_buffer(const_cast(recv_buffer_ptr), recv_buffer_size); - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; + const size_t node_cnt = blockIdx.x*blockDim.x + threadIdx.x; + const size_t var1_idx = blockIdx.y*blockDim.y + threadIdx.y; - if(p >= recvcnt || i >= field.data_view().template length<1>() ) return; + if(node_cnt >= recvcnt || var1_idx >= field.data_view().template length<1>() ) return; - const size_t node_idx = recvmap[p]; + const size_t node_idx = recvmap[node_cnt]; - size_t buff_idx = field.data_view().template length<2>() * field.data_view().template length<1>() * p + field.data_view().template length<2>() * i; + size_t buff_idx = get_buffer_index::apply(field, node_cnt, var1_idx); - halo_unpacker_impl<0, 1, 2>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,i); + halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, (RANK-1)>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,var1_idx); } template @@ -121,7 +142,7 @@ __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const s const size_t node_idx = recvmap[p]; - halo_unpacker_impl<0, 0, 1>::apply(p, node_idx, recv_buffer, field,node_idx); + halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, (RANK-1)>::apply(p, node_idx, recv_buffer, field,node_idx); } template diff --git a/src/atlas/parallel/HaloExchangeImpl.h b/src/atlas/parallel/HaloExchangeImpl.h index f8e7907fc..bd3ef7280 100644 --- a/src/atlas/parallel/HaloExchangeImpl.h +++ b/src/atlas/parallel/HaloExchangeImpl.h @@ -62,6 +62,18 @@ struct halo_unpacker_impl { } }; +template +struct halo_unpacker_impl { + + template + ATLAS_HOST_DEVICE + static void apply(size_t& buf_idx, size_t node_idx, array::SVector const & recv_buffer, + array::ArrayView& field, Idx...idxs) + { + field(idxs...) = recv_buffer[buf_idx++]; + } +}; + template struct halo_unpacker_impl { template From 56aa01e297edff1ee600ac3f41f092d2b5c7db7b Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Sun, 5 Nov 2017 23:17:20 +0100 Subject: [PATCH 138/355] some more fix --- src/atlas/parallel/HaloExchangeCUDA.cu | 46 ++++++-------------------- 1 file changed, 10 insertions(+), 36 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 77b0549e4..7aaf6256e 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -32,7 +32,8 @@ __global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const si template __global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, - const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { + const array::ArrayView field, DATA_TYPE* send_buffer, + const typename std::enable_if::type = 0) { const array::SVector sendmap(const_cast(sendmap_ptr), sendmap_size); const size_t p = blockIdx.x*blockDim.x + threadIdx.x; @@ -89,29 +90,25 @@ struct get_buffer_index<2>{ template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, - const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, - array::ArrayView field, - const typename std::enable_if::type = 0) { + const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView field, const typename std::enable_if::type = 0) { const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); const array::SVector recv_buffer(const_cast(recv_buffer_ptr), recv_buffer_size); - const size_t node_cnt = blockIdx.x*blockDim.x + threadIdx.x; - const size_t var1_idx = blockIdx.y*blockDim.y + threadIdx.y; - - if(node_cnt >= recvcnt || var1_idx >= field.data_view().template length<1>() ) return; + size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t node_idx = recvmap[node_cnt]; + if(p >= recvcnt) return; - size_t buff_idx = get_buffer_index::apply(field, node_cnt, var1_idx); + const size_t node_idx = recvmap[p]; - halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, (RANK-1)>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,var1_idx); + halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, (RANK-1)>::apply(p, node_idx, recv_buffer, field,node_idx); } template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView field, const typename std::enable_if::type = 0) { + array::Intent::ReadWrite> field, const typename std::enable_if=2, int>::type = 0) { const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); const array::SVector recv_buffer(const_cast(recv_buffer_ptr), recv_buffer_size); @@ -125,30 +122,7 @@ __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const s size_t buff_idx = get_buffer_index::apply(field, node_cnt, var1_idx); - halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, (RANK-1)>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,var1_idx); -} - -template -__global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, - const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView field, const typename std::enable_if::type = 0) { - - const array::SVector recvmap(const_cast(recvmap_ptr), recvmap_size); - const array::SVector recv_buffer(const_cast(recv_buffer_ptr), recv_buffer_size); - - size_t p = blockIdx.x*blockDim.x + threadIdx.x; - - if(p >= recvcnt) return; - - const size_t node_idx = recvmap[p]; - - halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, (RANK-1)>::apply(p, node_idx, recv_buffer, field,node_idx); -} - -template -__global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, - const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView field, - typename std::enable_if<(RANK>3), int>::type* = 0) { + halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, 2>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,var1_idx); } template From 0e485b205d57b3ea870e39ed868616782a7db446 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 6 Nov 2017 08:23:53 +0100 Subject: [PATCH 139/355] fixes for packer --- src/atlas/parallel/HaloExchangeCUDA.cu | 98 ++++++++++---------------- src/atlas/parallel/HaloExchangeImpl.h | 21 ++++-- 2 files changed, 55 insertions(+), 64 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 7aaf6256e..51183ff4d 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -15,63 +15,11 @@ namespace atlas { namespace parallel { -template -__global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, - const array::ArrayView field, DATA_TYPE* send_buffer, const typename std::enable_if::type = 0) { - const array::SVector sendmap(const_cast(sendmap_ptr), sendmap_size); - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - - if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; - - const size_t buff_idx = field.data_view().template length<1>() * p + i; - - send_buffer[buff_idx] = field(sendmap[p], i); - -} - -template -__global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, - const array::ArrayView field, DATA_TYPE* send_buffer, - const typename std::enable_if::type = 0) { - const array::SVector sendmap(const_cast(sendmap_ptr), sendmap_size); - - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - const size_t i = blockIdx.y*blockDim.y + threadIdx.y; - - if(p >= sendcnt || i >= field.data_view().template length<1>() ) return; - - size_t buff_idx = field.data_view().template length<2>() * field.data_view().template length<1>() * p + field.data_view().template length<2>() * i; - - for(size_t varid=0; varid < field.data_view().template length<2>(); ++varid) { - send_buffer[buff_idx++] = field(sendmap[p], i, varid); - } - -} - -template -__global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, - const array::ArrayView field, DATA_TYPE* send_buffer, - const typename std::enable_if::type = 0) { - const array::SVector sendmap(const_cast(sendmap_ptr), sendmap_size); - - const size_t p = blockIdx.x*blockDim.x + threadIdx.x; - - if(p >= sendcnt) return; - send_buffer[p] = field(sendmap[p]); -} - -template -__global__ void pack_kernel(const int sendcnt, const int* sendmap, const size_t sendmap_size, - const array::ArrayView field, DATA_TYPE* send_buffer, - const typename std::enable_if<(RANK>3), int>::type = 0) { -} - template struct get_buffer_index{ template ATLAS_HOST_DEVICE - static size_t apply(array::ArrayView& field, + static size_t apply(const array::ArrayView& field, const size_t node_cnt, const size_t var1_idx) { return field.data_view().template length() * field.data_view().template length() * node_cnt + field.data_view().template length() * var1_idx; @@ -82,12 +30,44 @@ template<> struct get_buffer_index<2>{ template ATLAS_HOST_DEVICE - static size_t apply(array::ArrayView& field, + static size_t apply(const array::ArrayView& field, const size_t node_cnt, const size_t var1_idx) { return field.data_view().template length<1>() * node_cnt + var1_idx; } }; +template +__global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, + const array::ArrayView field, DATA_TYPE* send_buffer_ptr, + const size_t send_buffer_size, const typename std::enable_if::type = 0) { + const array::SVector sendmap(const_cast(sendmap_ptr), sendmap_size); + array::SVector send_buffer(const_cast(send_buffer_ptr), send_buffer_size); + + const size_t node_cnt = blockIdx.x*blockDim.x + threadIdx.x; + + if(node_cnt >= sendcnt) return; + + send_buffer[node_cnt] = field(sendmap[node_cnt]); +} + +template +__global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, + const array::ArrayView field, DATA_TYPE* send_buffer_ptr, + const size_t send_buffer_size, const typename std::enable_if=2, int>::type = 0) { + const array::SVector sendmap(const_cast(sendmap_ptr), sendmap_size); + array::SVector send_buffer(const_cast(send_buffer_ptr), send_buffer_size); + + const size_t node_cnt = blockIdx.x*blockDim.x + threadIdx.x; + const size_t var1_idx = blockIdx.y*blockDim.y + threadIdx.y; + + if(node_cnt >= sendcnt || var1_idx >= field.data_view().template length<1>() ) return; + + size_t buff_idx = get_buffer_index::apply(field, node_cnt, var1_idx); + const size_t node_idx = sendmap[node_cnt]; + + halo_packer_impl<0, (RANK>=3) ? (RANK-2) : 0, 2>::apply(buff_idx, node_idx, field, send_buffer, node_idx,var1_idx); +} + template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView recvmap(const_cast(recvmap_ptr), recvmap_size); const array::SVector recv_buffer(const_cast(recv_buffer_ptr), recv_buffer_size); - size_t p = blockIdx.x*blockDim.x + threadIdx.x; + size_t node_cnt = blockIdx.x*blockDim.x + threadIdx.x; - if(p >= recvcnt) return; + if(node_cnt >= recvcnt) return; - const size_t node_idx = recvmap[p]; + const size_t node_idx = recvmap[node_cnt]; - halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, (RANK-1)>::apply(p, node_idx, recv_buffer, field,node_idx); + field(node_idx) = recv_buffer[node_cnt]; } template @@ -161,7 +141,7 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< throw eckit::Exception(msg); } - pack_kernel<<>>(sendcnt, sendmap.data(), sendmap.size(), dfield, (send_buffer.data())); + pack_kernel<<>>(sendcnt, sendmap.data(), sendmap.size(), dfield, send_buffer.data(), send_buffer.size()); err = cudaGetLastError(); if (err != cudaSuccess) throw eckit::Exception("Error launching GPU packing kernel"); diff --git a/src/atlas/parallel/HaloExchangeImpl.h b/src/atlas/parallel/HaloExchangeImpl.h index bd3ef7280..b71757e41 100644 --- a/src/atlas/parallel/HaloExchangeImpl.h +++ b/src/atlas/parallel/HaloExchangeImpl.h @@ -20,7 +20,7 @@ template struct halo_packer_impl { template ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx... idxs) { for( size_t i=0; i< field.template shape(); ++i ) { halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); @@ -28,12 +28,23 @@ struct halo_packer_impl { } }; +template +struct halo_packer_impl { + template + ATLAS_HOST_DEVICE + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, + array::SVector& send_buffer, Idx...idxs) + { + send_buffer[buf_idx++] = field(idxs...); + } +}; + template struct halo_packer_impl { template ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx... idxs) { halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs...,node_idx); } @@ -43,7 +54,7 @@ template struct halo_packer_impl { template ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, size_t node_idx, const array::ArrayView& field, + static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, array::SVector& send_buffer, Idx...idxs) { send_buffer[buf_idx++] = field(idxs...); @@ -67,7 +78,7 @@ struct halo_unpacker_impl { template ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, size_t node_idx, array::SVector const & recv_buffer, + static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, array::ArrayView& field, Idx...idxs) { field(idxs...) = recv_buffer[buf_idx++]; @@ -89,7 +100,7 @@ struct halo_unpacker_impl { template ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, size_t node_idx, array::SVector const & recv_buffer, + static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, array::ArrayView& field, Idx...idxs) { field(idxs...) = recv_buffer[buf_idx++]; From d2bb5a9bcf221d3a9098fe79e4be5bcf5c7f8338 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 6 Nov 2017 08:27:12 +0100 Subject: [PATCH 140/355] remove old disabled test --- src/tests/parallel/test_haloexchange.cc | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index dc8efc2ad..ad9525c6d 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -87,25 +87,6 @@ CASE("test_haloexchange") { SETUP("Fixture") { Fixture f; - - - SECTION( "test_rank0" ) - { -// size_t strides[] = {1}; -// size_t shape[] = {1}; -// f.halo_exchange.execute(f.gidx.data(),strides,shape,1); - -// switch( parallel::mpi::comm().rank() ) -// { -// case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; -// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } -// case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; -// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } -// case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; -// EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } -// } - } - SECTION( "test_rank0_arrview" ) { array::ArrayT arr(f.N); From 8ac19902c2f7669f22ce392f0aa356a044b91c04 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 6 Nov 2017 08:59:42 +0100 Subject: [PATCH 141/355] unify unittests --- src/atlas/parallel/HaloExchange.h | 4 +- src/tests/parallel/test_haloexchange.cc | 809 ++++++++++++------------ 2 files changed, 403 insertions(+), 410 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index a201b75ea..9c2a75ce7 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -209,7 +209,7 @@ template struct halo_packer { template static void pack(const unsigned int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ) + const array::ArrayView& field, array::SVector& send_buffer ) { size_t ibuf = 0; for(int node_cnt=0; node_cnt < sendcnt; ++node_cnt) @@ -242,7 +242,7 @@ void HaloExchange::pack_send_buffer( const array::ArrayView::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); #else - halo_packer::pack(sendcnt_, sendmap_, hfield, send_buffer); + halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); #endif } diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index ad9525c6d..23e3048c0 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -42,7 +42,7 @@ std::vector vec( const T (&list)[N] ) } struct Fixture { - Fixture() + Fixture(bool on_device) : on_device_(on_device) { int nnodes_c[] = {5, 6, 7}; nb_nodes = vec(nnodes_c); N = nb_nodes[parallel::mpi::comm().rank()]; @@ -79,511 +79,504 @@ struct Fixture { std::vector gidx; int N; + bool on_device_; }; //----------------------------------------------------------------------------- -CASE("test_haloexchange") { - SETUP("Fixture") { - Fixture f; +void test_rank0_arrview(Fixture& f) { + array::ArrayT arr(f.N); + array::ArrayView arrv = array::make_host_view(arr); + for( int j=0; j arr(f.N); - array::ArrayView arrv = array::make_view(arr); - for( int j=0; j(arr, false); + f.halo_exchange.template execute(arr, f.on_device_); - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; - EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } - case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; - EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } - case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; - EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } - } - } + arr.syncHostDevice(); - SECTION( "test_rank1" ) + switch( parallel::mpi::comm().rank() ) { - array::ArrayT arr(f.N,2); - array::ArrayView arrv = array::make_view(arr); - for( int j=0; j(arr, false); + case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; + EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } + case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; + EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } + case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; + EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } + } +} - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - } +void test_rank1(Fixture& f) { + array::ArrayT arr(f.N,2); + array::ArrayView arrv = array::make_host_view(arr); + for( int j=0; j arr_t(f.N,2); - array::ArrayView arrv_t = array::make_view(arr_t); - for( int j=0; j(arr, f.on_device_); - eckit::SharedPtr arr ( array::Array::wrap(arrv_t.data(), - array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); + arr.syncHostDevice(); - f.halo_exchange.template execute(*arr, false); + switch( parallel::mpi::comm().rank() ) + { + case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + } +} - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 90,0, 10,100, 20,200, 30,300, 40,0 }; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 1: { POD arr_c[] = { 30,0, 40,400, 50,500, 60,600, 70,0, 80,0}; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 2: { POD arr_c[] = { 50,0, 60,0, 70,700, 80,800, 90,900, 10,0, 20,0}; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - } +void test_rank1_strided_v1(Fixture& f) { + //create a 2d field from the gidx data, with two components per grid point + array::ArrayT arr_t(f.N,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int j=0; j arr ( array::Array::wrap(arrv_t.data(), + array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); + + f.halo_exchange.template execute(*arr, false); + + switch( parallel::mpi::comm().rank() ) { + case 0: { POD arr_c[] = { 90,0, 10,100, 20,200, 30,300, 40,0 }; + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 1: { POD arr_c[] = { 30,0, 40,400, 50,500, 60,600, 70,0, 80,0}; + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 2: { POD arr_c[] = { 50,0, 60,0, 70,700, 80,800, 90,900, 10,0, 20,0}; + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + } +} - //create a 2d field from the gidx data, with two components per grid point - array::ArrayT arr_t(f.N,2); - array::ArrayView arrv_t = array::make_view(arr_t); - for( int j=0; j arr_t(f.N,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int j=0; j arr ( array::Array::wrap(&(arrv_t(0,1)), - array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); + eckit::SharedPtr arr ( array::Array::wrap(&(arrv_t(0,1)), + array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); - f.halo_exchange.template execute(*arr, false); + f.halo_exchange.template execute(*arr, false); - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 0,900, 10,100, 20,200, 30,300, 0,400 }; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 1: { POD arr_c[] = { 0,300, 40,400, 50,500, 60,600, 0,700, 0,800}; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 2: { POD arr_c[] = { 0,500, 0,600, 70,700, 80,800, 90,900, 0,100, 0,200}; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - } + switch( parallel::mpi::comm().rank() ) + { + case 0: { POD arr_c[] = { 0,900, 10,100, 20,200, 30,300, 0,400 }; + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 1: { POD arr_c[] = { 0,300, 40,400, 50,500, 60,600, 0,700, 0,800}; + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 2: { POD arr_c[] = { 0,500, 0,600, 70,700, 80,800, 90,900, 0,100, 0,200}; + EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } } +} - SECTION( "test_rank2" ) +void test_rank2(Fixture& f) { + array::ArrayT arr(f.N,3,2); + array::ArrayView arrv = array::make_view(arr); + for( int p=0; p arr(f.N,3,2); - array::ArrayView arrv = array::make_view(arr); - for( int p=0; p(arr, false); + f.halo_exchange.template execute(arr, f.on_device_); - switch( parallel::mpi::comm().rank() ) + arr.syncHostDevice(); + + switch( parallel::mpi::comm().rank() ) + { + case 0: + { + int arr_c[] = { -9,9, -90,90, -900,900, + -1,1, -10,10, -100,100, + -2,2, -20,20, -200,200, + -3,3, -30,30, -300,300, + -4,4, -40,40, -400,400}; + EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 1: { - case 0: - { - int arr_c[] = { -9,9, -90,90, -900,900, - -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200, - -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 1: - { - int arr_c[] = { -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400, - -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 2: - { - int arr_c[] = { -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800, - -9,9, -90,90, -900,900, - -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } + int arr_c[] = { -3,3, -30,30, -300,300, + -4,4, -40,40, -400,400, + -5,5, -50,50, -500,500, + -6,6, -60,60, -600,600, + -7,7, -70,70, -700,700, + -8,8, -80,80, -800,800}; + EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 2: + { + int arr_c[] = { -5,5, -50,50, -500,500, + -6,6, -60,60, -600,600, + -7,7, -70,70, -700,700, + -8,8, -80,80, -800,800, + -9,9, -90,90, -900,900, + -1,1, -10,10, -100,100, + -2,2, -20,20, -200,200}; + EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; } } +} - SECTION( "test_rank2_l1" ) +void test_rank2_l1(Fixture& f) { + array::ArrayT arr_t(f.N,3,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int p=0; p arr_t(f.N,3,2); - array::ArrayView arrv_t = array::make_view(arr_t); - for( int p=0; p arr ( array::Array::wrap(arrv_t.data(), - array::ArraySpec{array::make_shape(f.N, 1, 2), array::make_strides(6, 2, 1) } ) ); + eckit::SharedPtr arr ( array::Array::wrap(arrv_t.data(), + array::ArraySpec{array::make_shape(f.N, 1, 2), array::make_strides(6, 2, 1) } ) ); - f.halo_exchange.template execute(*arr, false); + f.halo_exchange.template execute(*arr, false); - switch( parallel::mpi::comm().rank() ) + switch( parallel::mpi::comm().rank() ) + { + case 0: + { + POD arr_c[] = { -9,9, 0, 0, 0, 0, // halo + -1,1, -10,10, -100,100, // core + -2,2, -20,20, -200,200, // core + -3,3, -30,30, -300,300, // core + -4,4, 0, 0, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 1: + { + POD arr_c[] = { -3,3, 0, 0, 0, 0, // halo + -4,4, -40,40, -400,400, // core + -5,5, -50,50, -500,500, // core + -6,6, -60,60, -600,600, // core + -7,7, 0, 0, 0, 0, // halo + -8,8, 0, 0, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 2: { - case 0: - { - POD arr_c[] = { -9,9, 0, 0, 0, 0, // halo - -1,1, -10,10, -100,100, // core - -2,2, -20,20, -200,200, // core - -3,3, -30,30, -300,300, // core - -4,4, 0, 0, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 1: - { - POD arr_c[] = { -3,3, 0, 0, 0, 0, // halo - -4,4, -40,40, -400,400, // core - -5,5, -50,50, -500,500, // core - -6,6, -60,60, -600,600, // core - -7,7, 0, 0, 0, 0, // halo - -8,8, 0, 0, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 2: - { - POD arr_c[] = { -5,5, 0, 0, 0, 0, // halo - -6,6, 0, 0, 0, 0, // halo - -7,7, -70,70, -700,700, // core - -8,8, -80,80, -800,800, // core - -9,9, -90,90, -900,900, // core - -1,1, 0, 0, 0, 0, // halo - -2,2, 0, 0, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } + POD arr_c[] = { -5,5, 0, 0, 0, 0, // halo + -6,6, 0, 0, 0, 0, // halo + -7,7, -70,70, -700,700, // core + -8,8, -80,80, -800,800, // core + -9,9, -90,90, -900,900, // core + -1,1, 0, 0, 0, 0, // halo + -2,2, 0, 0, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; } } +} - SECTION( "test_rank2_l2_v2" ) +void test_rank2_l2_v2(Fixture& f) { + // Test rank 2 halo-exchange + array::ArrayT arr_t(f.N,3,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int p=0; p arr_t(f.N,3,2); - array::ArrayView arrv_t = array::make_view(arr_t); - for( int p=0; p arr ( array::Array::wrap(&arrv_t(0,1,1), - array::ArraySpec{array::make_shape(f.N, 1, 1), array::make_strides(6, 2, 1) } ) ); + eckit::SharedPtr arr ( array::Array::wrap(&arrv_t(0,1,1), + array::ArraySpec{array::make_shape(f.N, 1, 1), array::make_strides(6, 2, 1) } ) ); - f.halo_exchange.template execute(*arr, false); + f.halo_exchange.template execute(*arr, false); - switch( parallel::mpi::comm().rank() ) + switch( parallel::mpi::comm().rank() ) + { + case 0: { - case 0: - { - POD arr_c[] = { 0,0, 0,90, 0, 0, // halo - -1,1, -10,10, -100,100, // core - -2,2, -20,20, -200,200, // core - -3,3, -30,30, -300,300, // core - 0,0, 0,40, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 1: - { - POD arr_c[] = { 0,0, 0,30, 0, 0, // halo - -4,4, -40,40, -400,400, // core - -5,5, -50,50, -500,500, // core - -6,6, -60,60, -600,600, // core - 0,0, 0,70, 0, 0, // halo - 0,0, 0,80, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 2: - { - POD arr_c[] = { 0,0, 0,50, 0, 0, // halo - 0,0, 0,60, 0, 0, // halo - -7,7, -70,70, -700,700, // core - -8,8, -80,80, -800,800, // core - -9,9, -90,90, -900,900, // core - 0,0, 0,10, 0, 0, // halo - 0,0, 0,20, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } + POD arr_c[] = { 0,0, 0,90, 0, 0, // halo + -1,1, -10,10, -100,100, // core + -2,2, -20,20, -200,200, // core + -3,3, -30,30, -300,300, // core + 0,0, 0,40, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 1: + { + POD arr_c[] = { 0,0, 0,30, 0, 0, // halo + -4,4, -40,40, -400,400, // core + -5,5, -50,50, -500,500, // core + -6,6, -60,60, -600,600, // core + 0,0, 0,70, 0, 0, // halo + 0,0, 0,80, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 2: + { + POD arr_c[] = { 0,0, 0,50, 0, 0, // halo + 0,0, 0,60, 0, 0, // halo + -7,7, -70,70, -700,700, // core + -8,8, -80,80, -800,800, // core + -9,9, -90,90, -900,900, // core + 0,0, 0,10, 0, 0, // halo + 0,0, 0,20, 0, 0}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; } } +} - SECTION( "test_rank2_v2" ) +void test_rank2_v2(Fixture& f) { + array::ArrayT arr_t(f.N,3,2); + array::ArrayView arrv_t = array::make_view(arr_t); + for( int p=0; p arr_t(f.N,3,2); - array::ArrayView arrv_t = array::make_view(arr_t); - for( int p=0; p arr ( array::Array::wrap(&arrv_t(0,0,1), - array::ArraySpec{array::make_shape(f.N, 3, 1), array::make_strides(6, 2, 2) } ) ); + eckit::SharedPtr arr ( array::Array::wrap(&arrv_t(0,0,1), + array::ArraySpec{array::make_shape(f.N, 3, 1), array::make_strides(6, 2, 2) } ) ); - f.halo_exchange.template execute(*arr, false); + f.halo_exchange.template execute(*arr, false); - switch( parallel::mpi::comm().rank() ) + switch( parallel::mpi::comm().rank() ) + { + case 0: + { + POD arr_c[] = { 0,9, 0,90, 0,900, // halo + -1,1, -10,10, -100,100, // core + -2,2, -20,20, -200,200, // core + -3,3, -30,30, -300,300, // core + 0,4, 0,40, 0,400}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 1: + { + POD arr_c[] = { 0,3, 0,30, 0,300, // halo + -4,4, -40,40, -400,400, // core + -5,5, -50,50, -500,500, // core + -6,6, -60,60, -600,600, // core + 0,7, 0,70, 0,700, // halo + 0,8, 0,80, 0,800}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; + } + case 2: { - case 0: - { - POD arr_c[] = { 0,9, 0,90, 0,900, // halo - -1,1, -10,10, -100,100, // core - -2,2, -20,20, -200,200, // core - -3,3, -30,30, -300,300, // core - 0,4, 0,40, 0,400}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 1: - { - POD arr_c[] = { 0,3, 0,30, 0,300, // halo - -4,4, -40,40, -400,400, // core - -5,5, -50,50, -500,500, // core - -6,6, -60,60, -600,600, // core - 0,7, 0,70, 0,700, // halo - 0,8, 0,80, 0,800}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 2: - { - POD arr_c[] = { 0,5, 0,50, 0,500, // halo - 0,6, 0,60, 0,600, // halo - -7,7, -70,70, -700,700, // core - -8,8, -80,80, -800,800, // core - -9,9, -90,90, -900,900, // core - 0,1, 0,10, 0,100, // halo - 0,2, 0,20, 0,200}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } + POD arr_c[] = { 0,5, 0,50, 0,500, // halo + 0,6, 0,60, 0,600, // halo + -7,7, -70,70, -700,700, // core + -8,8, -80,80, -800,800, // core + -9,9, -90,90, -900,900, // core + 0,1, 0,10, 0,100, // halo + 0,2, 0,20, 0,200}; // halo + EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + break; } } +} + +void test_rank0_wrap(Fixture& f) { + eckit::SharedPtr arr ( array::Array::wrap(f.gidx.data(), array::make_shape(f.N) ) ); + array::ArrayView arrv = array::make_view(*arr); - SECTION( "test_rank0_ArrayView" ) + f.halo_exchange.template execute(*arr, false); + + switch( parallel::mpi::comm().rank() ) { - eckit::SharedPtr arr ( array::Array::wrap(f.gidx.data(), array::make_shape(f.N) ) ); - array::ArrayView arrv = array::make_view(*arr); + case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; + EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } + case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; + EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } + case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; + EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } + } +} + +void test_rank1_paralleldim1(Fixture& f) { + array::ArrayT arr(2,f.N); + array::ArrayView arrv = array::make_view(arr); + for( int j=0; j(*arr, false); + f.halo_exchange.template execute(arr, false); + + switch( parallel::mpi::comm().rank() ) + { + case 0: { POD arr_c[] = { 90, 10, 20 , 30 , 40, 900, 100, 200, 300, 400 }; //90,900, 10,100, 20,200, 30,300, 40,400 }; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 1: { POD arr_c[] = { 30,40,50,60,70,80, 300,400,500,600,700,800}; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + case 2: { POD arr_c[] = { 50,60,70,80,90,10,20, 500,600,700,800,900,100,200}; + EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + } +} - switch( parallel::mpi::comm().rank() ) +void test_rank2_paralleldim2(Fixture& f) { + array::ArrayT arr(3,f.N,2); + array::ArrayView arrv = array::make_view(arr); + for( int p=0; p >(arr, false); - SECTION( "test_rank1_ArrayView" ) + switch( parallel::mpi::comm().rank() ) { - array::ArrayT arr(f.N,2); - array::ArrayView arrv = array::make_view(arr); - for( int j=0; j(arr, false); + SECTION( "test_rank0_arrview" ) + { + test_rank0_arrview(f); + } - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - } + SECTION( "test_rank1" ) + { + test_rank1(f); } - SECTION( "test_rank2_ArrayView" ) + SECTION( "test_rank1_strided_v1" ) { - array::ArrayT arr(f.N,3,2); - array::ArrayView arrv = array::make_view(arr); - for( int p=0; p(arr, false); + SECTION( "test_rank2" ) + { + test_rank2(f); + } - switch( parallel::mpi::comm().rank() ) - { - case 0: - { - POD arr_c[] = { -9,9, -90,90, -900,900, - -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200, - -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 1: - { - POD arr_c[] = { -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400, - -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 2: - { - POD arr_c[] = { -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800, - -9,9, -90,90, -900,900, - -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - } + SECTION( "test_rank2_l1" ) + { + test_rank2_l1(f); } - SECTION( "test_rank1_paralleldim_1" ) + SECTION( "test_rank2_l2_v2" ) { - array::ArrayT arr(2,f.N); - array::ArrayView arrv = array::make_view(arr); - for( int j=0; j(arr, false); + SECTION( "test_rank2_v2" ) + { + test_rank2_v2(f); + } - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 90, 10, 20 , 30 , 40, 900, 100, 200, 300, 400 }; //90,900, 10,100, 20,200, 30,300, 40,400 }; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 1: { POD arr_c[] = { 30,40,50,60,70,80, 300,400,500,600,700,800}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - case 2: { POD arr_c[] = { 50,60,70,80,90,10,20, 500,600,700,800,900,100,200}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } - } + SECTION( "test_rank0_wrap" ) + { + test_rank0_wrap(f); + } + + SECTION( "test_rank1_paralleldim_1" ) + { + test_rank1_paralleldim1(f); } SECTION( "test_rank2_paralleldim_2" ) { - array::ArrayT arr(3,f.N,2); - array::ArrayView arrv = array::make_view(arr); - for( int p=0; p >(arr, false); + } - switch( parallel::mpi::comm().rank() ) - { - case 0: - { - int arr_c[] = { -9,9, -1,1, -2,2, -3,3, -4,4, - -90,90, -10,10, -20,20, -30,30, -40,40, - -900,900, -100,100, -200,200, -300,300, -400,400}; - - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 1: - { - int arr_c[] = { -3,3, -4,4, -5,5, -6,6, -7,7, -8,8, - -30,30, -40,40, -50,50, -60,60, -70,70, -80,80, - -300,300, -400,400, -500,500, -600,600, -700,700, -800,800}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - case 2: - { - int arr_c[] = { -5,5, -6,6, -7,7, -8,8, -9,9, -1,1, -2,2, - -50,50, -60,60, -70,70, -80,80, -90,90, -10,10, -20,20, - -500,500, -600,600, -700,700, -800,800, -900,900, -100,100, -200,200}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } - } +#ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + SETUP("HaloExchanges_gpu") { + Fixture f(true); + + SECTION( "test_rank0_arrview" ) + { + test_rank0_arrview(f); } + SECTION( "test_rank1" ) + { + test_rank1(f); + } + + SECTION( "test_rank2" ) + { + test_rank2(f); + } } +#endif + } //----------------------------------------------------------------------------- From 4445c2db555733b8ed85987ff5f5baad3f81a31a Mon Sep 17 00:00:00 2001 From: cosunae Date: Mon, 6 Nov 2017 09:09:56 +0100 Subject: [PATCH 142/355] fix --- src/tests/parallel/test_haloexchange.cc | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 23e3048c0..27481719f 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -498,7 +498,6 @@ void test_rank2_paralleldim2(Fixture& f) { CASE("test_haloexchange") { SETUP("HaloExchanges_cpu") { Fixture f(false); - SECTION( "test_rank0_arrview" ) { test_rank0_arrview(f); @@ -553,12 +552,8 @@ CASE("test_haloexchange") { { test_rank2_paralleldim2(f); } - - } - #ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - SETUP("HaloExchanges_gpu") { - Fixture f(true); + f.on_device_ = true; SECTION( "test_rank0_arrview" ) { @@ -574,8 +569,8 @@ CASE("test_haloexchange") { { test_rank2(f); } - } #endif + } } From cc481669fe5facc81441b9dae49520d106c49e4c Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 6 Nov 2017 09:35:42 +0100 Subject: [PATCH 143/355] use validate infstrcutrue in test --- src/tests/parallel/test_haloexchange.cc | 106 +++++++++++++++++++----- 1 file changed, 84 insertions(+), 22 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 23e3048c0..540ec6dc7 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -41,6 +41,74 @@ std::vector vec( const T (&list)[N] ) return std::vector(list,list+N); } +template +size_t eval_idx(size_t pos, std::array& strides, FirstDim first) +{ + return first*strides[pos]; +} + +template +size_t eval_idx(size_t pos, std::array& strides, FirstDim first, Int...dims ) +{ + return first*strides[pos] + eval_idx((size_t)pos+1, strides, dims...); +} + +template +struct validate_impl; + +template +struct validate_impl { + template + static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { + EXPECT(arrv(dims...) == arr_c[eval_idx((size_t)0, strides, dims...)]); + } +}; + +template +struct validate_impl { + + template + static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { + for(size_t cnt = 0; cnt < arrv.template shape(); ++cnt) { + validate_impl::apply(arrv, arr_c, strides, dims..., cnt); + } + } +}; + +template +struct compute_strides; + +template<> +struct compute_strides<0> { + template + static void apply(array::ArrayView& arrv, std::array& strides) {} +}; + +template +struct compute_strides { + template + static void apply(array::ArrayView& arrv, std::array& strides) { + strides[Dim-1] = strides[Dim]*arrv.template shape<(unsigned int)Dim>(); + compute_strides::apply(arrv,strides); + + } +}; + +template +struct validate { + + static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { + std::array strides; + strides[Rank-1] = 1; + compute_strides::apply(arrv, strides); + + for(size_t i = 0; i < arrv.template shape<0>(); ++i) { + validate_impl::apply(arrv, arr_c, strides, i); + } + } + +}; + struct Fixture { Fixture(bool on_device) : on_device_(on_device) { @@ -99,12 +167,12 @@ void test_rank0_arrview(Fixture& f) { switch( parallel::mpi::comm().rank() ) { - case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; - EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } - case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; - EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } - case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; - EXPECT( make_view(arrv.data(), arrv.data()+f.N) == make_view(gidx_c,gidx_c+f.N)); break; } + case 0: { POD arr_c[] = { 9, 1, 2, 3, 4}; + validate::apply(arrv, arr_c); break; } + case 1: { POD arr_c[] = { 3, 4, 5, 6, 7, 8}; + validate::apply(arrv, arr_c); break; } + case 2: { POD arr_c[] = { 5, 6, 7, 8, 9, 1, 2}; + validate::apply(arrv, arr_c); break; } } } @@ -125,11 +193,11 @@ void test_rank1(Fixture& f) { switch( parallel::mpi::comm().rank() ) { case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv, arr_c); break; } case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv, arr_c); break; } case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv, arr_c); break; } } } @@ -193,7 +261,7 @@ void test_rank1_strided_v2(Fixture& f) { void test_rank2(Fixture& f) { array::ArrayT arr(f.N,3,2); - array::ArrayView arrv = array::make_view(arr); + array::ArrayView arrv = array::make_host_view(arr); for( int p=0; p::apply(arrv, arr_c); break; } case 1: { - int arr_c[] = { -3,3, -30,30, -300,300, + POD arr_c[] = { -3,3, -30,30, -300,300, -4,4, -40,40, -400,400, -5,5, -50,50, -500,500, -6,6, -60,60, -600,600, -7,7, -70,70, -700,700, -8,8, -80,80, -800,800}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } + validate::apply(arrv, arr_c); break; } case 2: { - int arr_c[] = { -5,5, -50,50, -500,500, + POD arr_c[] = { -5,5, -50,50, -500,500, -6,6, -60,60, -600,600, -7,7, -70,70, -700,700, -8,8, -80,80, -800,800, -9,9, -90,90, -900,900, -1,1, -10,10, -100,100, -2,2, -20,20, -200,200}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); - break; - } + validate::apply(arrv, arr_c); break; } } } From 5f091fa4b1d96d452079b84cf6f613d50b4a63a5 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 6 Nov 2017 10:05:58 +0100 Subject: [PATCH 144/355] pass an ondevice flag in order to be able to do cpu comm also with GPU backend --- src/atlas/parallel/HaloExchange.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 9c2a75ce7..90d42c75c 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -78,12 +78,12 @@ class HaloExchange: public eckit::Owned { template< int ParallelDim, typename DATA_TYPE, int RANK> void pack_send_buffer( const array::ArrayView& hfield, const array::ArrayView& dfield, - array::SVector& send_buffer ) const; + array::SVector& send_buffer, const bool on_device ) const; template< int ParallelDim, typename DATA_TYPE, int RANK> void unpack_recv_buffer(const array::SVector& recv_buffer, const array::ArrayView& hfield, - array::ArrayView& dfield) const; + array::ArrayView& dfield, const bool on_device) const; template void var_info( const array::ArrayView& arr, @@ -163,7 +163,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const } /// Pack - pack_send_buffer(field_hv, field_dv,send_buffer); + pack_send_buffer(field_hv, field_dv,send_buffer, on_device); /// Send ATLAS_TRACE_MPI( ISEND ) { @@ -190,7 +190,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const } /// Unpack - unpack_recv_buffer(recv_buffer, field_hv, field_dv); + unpack_recv_buffer(recv_buffer, field_hv, field_dv, on_device); /// Wait for sending to finish ATLAS_TRACE_MPI( WAIT, "mpi-wait send" ) { @@ -236,11 +236,14 @@ struct halo_packer { template void HaloExchange::pack_send_buffer( const array::ArrayView& hfield, const array::ArrayView& dfield, - array::SVector& send_buffer ) const + array::SVector& send_buffer, const bool on_device ) const { ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - halo_packer_cuda::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); + if(on_device) + halo_packer_cuda::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); + else + halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); #else halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); #endif @@ -249,12 +252,15 @@ void HaloExchange::pack_send_buffer( const array::ArrayView void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buffer, const array::ArrayView& hfield, - array::ArrayView& dfield) const + array::ArrayView& dfield, const bool on_device) const { ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); + if(on_device) + halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); + else + halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); #else halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); #endif From 96a3765b76cb01b7688f0cbe9f688fa27fac03a6 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 6 Nov 2017 14:01:15 +0100 Subject: [PATCH 145/355] adapt all unittests to use validate function --- src/tests/parallel/test_haloexchange.cc | 60 ++++++++++++------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index aa8a03d2d..1600ac0d5 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -222,11 +222,11 @@ void test_rank1_strided_v1(Fixture& f) { switch( parallel::mpi::comm().rank() ) { case 0: { POD arr_c[] = { 90,0, 10,100, 20,200, 30,300, 40,0 }; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv_t, arr_c); break; } case 1: { POD arr_c[] = { 30,0, 40,400, 50,500, 60,600, 70,0, 80,0}; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv_t, arr_c); break; } case 2: { POD arr_c[] = { 50,0, 60,0, 70,700, 80,800, 90,900, 10,0, 20,0}; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv_t, arr_c); break; } } } @@ -251,11 +251,11 @@ void test_rank1_strided_v2(Fixture& f) { switch( parallel::mpi::comm().rank() ) { case 0: { POD arr_c[] = { 0,900, 10,100, 20,200, 30,300, 0,400 }; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv_t, arr_c); break; } case 1: { POD arr_c[] = { 0,300, 40,400, 50,500, 60,600, 0,700, 0,800}; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv_t, arr_c); break; } case 2: { POD arr_c[] = { 0,500, 0,600, 70,700, 80,800, 90,900, 0,100, 0,200}; - EXPECT(make_view(arrv_t.data(),arrv_t.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv_t, arr_c); break; } } } @@ -335,7 +335,7 @@ void test_rank2_l1(Fixture& f) { -2,2, -20,20, -200,200, // core -3,3, -30,30, -300,300, // core -4,4, 0, 0, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv_t, arr_c); break; } case 1: @@ -346,7 +346,7 @@ void test_rank2_l1(Fixture& f) { -6,6, -60,60, -600,600, // core -7,7, 0, 0, 0, 0, // halo -8,8, 0, 0, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv_t, arr_c); break; } case 2: @@ -358,7 +358,7 @@ void test_rank2_l1(Fixture& f) { -9,9, -90,90, -900,900, // core -1,1, 0, 0, 0, 0, // halo -2,2, 0, 0, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv_t, arr_c); break; } } @@ -391,7 +391,7 @@ void test_rank2_l2_v2(Fixture& f) { -2,2, -20,20, -200,200, // core -3,3, -30,30, -300,300, // core 0,0, 0,40, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv_t, arr_c); break; } case 1: @@ -402,7 +402,7 @@ void test_rank2_l2_v2(Fixture& f) { -6,6, -60,60, -600,600, // core 0,0, 0,70, 0, 0, // halo 0,0, 0,80, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv_t, arr_c); break; } case 2: @@ -414,7 +414,7 @@ void test_rank2_l2_v2(Fixture& f) { -9,9, -90,90, -900,900, // core 0,0, 0,10, 0, 0, // halo 0,0, 0,20, 0, 0}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv_t, arr_c); break; } } @@ -446,7 +446,7 @@ void test_rank2_v2(Fixture& f) { -2,2, -20,20, -200,200, // core -3,3, -30,30, -300,300, // core 0,4, 0,40, 0,400}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv_t, arr_c); break; } case 1: @@ -457,7 +457,7 @@ void test_rank2_v2(Fixture& f) { -6,6, -60,60, -600,600, // core 0,7, 0,70, 0,700, // halo 0,8, 0,80, 0,800}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv_t, arr_c); break; } case 2: @@ -469,7 +469,7 @@ void test_rank2_v2(Fixture& f) { -9,9, -90,90, -900,900, // core 0,1, 0,10, 0,100, // halo 0,2, 0,20, 0,200}; // halo - EXPECT(make_view(arrv_t.data(),arrv_t.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv_t, arr_c); break; } } @@ -483,12 +483,12 @@ void test_rank0_wrap(Fixture& f) { switch( parallel::mpi::comm().rank() ) { - case 0: { POD gidx_c[] = { 9, 1, 2, 3, 4}; - EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } - case 1: { POD gidx_c[] = { 3, 4, 5, 6, 7, 8}; - EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } - case 2: { POD gidx_c[] = { 5, 6, 7, 8, 9, 1, 2}; - EXPECT(f.gidx == make_view(gidx_c,gidx_c+f.N)); break; } + case 0: { POD arr_c[] = { 9, 1, 2, 3, 4}; + validate::apply(arrv, arr_c); break; } + case 1: { POD arr_c[] = { 3, 4, 5, 6, 7, 8}; + validate::apply(arrv, arr_c); break; } + case 2: { POD arr_c[] = { 5, 6, 7, 8, 9, 1, 2}; + validate::apply(arrv, arr_c); break; } } } @@ -505,11 +505,11 @@ void test_rank1_paralleldim1(Fixture& f) { switch( parallel::mpi::comm().rank() ) { case 0: { POD arr_c[] = { 90, 10, 20 , 30 , 40, 900, 100, 200, 300, 400 }; //90,900, 10,100, 20,200, 30,300, 40,400 }; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv, arr_c); break; } case 1: { POD arr_c[] = { 30,40,50,60,70,80, 300,400,500,600,700,800}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv, arr_c); break; } case 2: { POD arr_c[] = { 50,60,70,80,90,10,20, 500,600,700,800,900,100,200}; - EXPECT(make_view(arrv.data(),arrv.data()+2*f.N) == make_view(arr_c,arr_c+2*f.N)); break; } + validate::apply(arrv, arr_c); break; } } } @@ -531,27 +531,27 @@ void test_rank2_paralleldim2(Fixture& f) { { case 0: { - int arr_c[] = { -9,9, -1,1, -2,2, -3,3, -4,4, + POD arr_c[] = { -9,9, -1,1, -2,2, -3,3, -4,4, -90,90, -10,10, -20,20, -30,30, -40,40, -900,900, -100,100, -200,200, -300,300, -400,400}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv, arr_c); break; } case 1: { - int arr_c[] = { -3,3, -4,4, -5,5, -6,6, -7,7, -8,8, + POD arr_c[] = { -3,3, -4,4, -5,5, -6,6, -7,7, -8,8, -30,30, -40,40, -50,50, -60,60, -70,70, -80,80, -300,300, -400,400, -500,500, -600,600, -700,700, -800,800}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv, arr_c); break; } case 2: { - int arr_c[] = { -5,5, -6,6, -7,7, -8,8, -9,9, -1,1, -2,2, + POD arr_c[] = { -5,5, -6,6, -7,7, -8,8, -9,9, -1,1, -2,2, -50,50, -60,60, -70,70, -80,80, -90,90, -10,10, -20,20, -500,500, -600,600, -700,700, -800,800, -900,900, -100,100, -200,200}; - EXPECT(make_view(arrv.data(),arrv.data()+6*f.N) == make_view(arr_c,arr_c+6*f.N)); + validate::apply(arrv, arr_c); break; } } From fb7b3961677b924209a83d0b3781510c9476ab59 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 6 Nov 2017 18:44:09 +0100 Subject: [PATCH 146/355] add a stride method to the view --- src/atlas/array/gridtools/GridToolsArrayView.h | 6 ++++++ src/atlas/array/native/NativeArrayView.h | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 5983b2184..276ffd533 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -89,6 +89,12 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas ATLAS_HOST_DEVICE data_view_t const & data_view() const { return gt_data_view_;} + template + ATLAS_HOST_DEVICE + size_t stride() const { + return gt_data_view_.storage_info().template stride(); + } + size_t rank() const { return Rank; } size_t size() const { return size_; } bool valid() const; diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 67ca661b2..dea77a812 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -130,6 +130,11 @@ template class ArrayView { template size_t shape() const { return shape(Dim);} + template + size_t stride() const { + return stride(Dim); + } + size_t size() const { return size_;} size_t rank() const { return Rank; } From 65bc4c44279af1bf9b2faa7db3d5c1efec861494 Mon Sep 17 00:00:00 2001 From: cosunae Date: Mon, 6 Nov 2017 19:03:10 +0100 Subject: [PATCH 147/355] fix some tests in CPU --- src/tests/parallel/test_haloexchange.cc | 54 ++++++++++++++++++++----- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 1600ac0d5..6f9dd0442 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -204,20 +204,32 @@ void test_rank1(Fixture& f) { void test_rank1_strided_v1(Fixture& f) { //create a 2d field from the gidx data, with two components per grid point array::ArrayT arr_t(f.N,2); - array::ArrayView arrv_t = array::make_view(arr_t); + array::ArrayView arrv_t = array::make_host_view(arr_t); for( int j=0; j arr ( array::Array::wrap(arrv_t.data(), - array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); + eckit::SharedPtr arr ( array::Array::wrap( + (f.on_device_ ? array::make_device_view(arr_t).data() : + arrv_t.data()), + array::ArraySpec{array::make_shape(f.N, 1), +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + array::make_strides(32, 1) } +#else + array::make_strides(2, 1) } +#endif + ) ); - f.halo_exchange.template execute(*arr, false); + f.halo_exchange.template execute(*arr, f.on_device_); + + arr_t.syncHostDevice(); switch( parallel::mpi::comm().rank() ) { @@ -231,14 +243,17 @@ void test_rank1_strided_v1(Fixture& f) { } void test_rank1_strided_v2(Fixture& f) { +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST //create a 2d field from the gidx data, with two components per grid point array::ArrayT arr_t(f.N,2); - array::ArrayView arrv_t = array::make_view(arr_t); + array::ArrayView arrv_t = array::make_host_view(arr_t); for( int j=0; j::apply(arrv_t, arr_c); break; } } +#endif } void test_rank2(Fixture& f) { @@ -311,7 +327,7 @@ void test_rank2(Fixture& f) { void test_rank2_l1(Fixture& f) { array::ArrayT arr_t(f.N,3,2); - array::ArrayView arrv_t = array::make_view(arr_t); + array::ArrayView arrv_t = array::make_host_view(arr_t); for( int p=0; p arr ( array::Array::wrap(arrv_t.data(), - array::ArraySpec{array::make_shape(f.N, 1, 2), array::make_strides(6, 2, 1) } ) ); + eckit::SharedPtr arr ( array::Array::wrap( + (f.on_device_ ? array::make_device_view(arr_t).data() : + arrv_t.data()), + array::ArraySpec{array::make_shape(f.N, 1, 2), +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + array::make_strides(96,32, 1) +#else + array::make_strides(6, 2, 1) +#endif + + } ) ); f.halo_exchange.template execute(*arr, false); + arr_t.syncHostDevice(); + switch( parallel::mpi::comm().rank() ) { case 0: @@ -365,6 +393,7 @@ void test_rank2_l1(Fixture& f) { } void test_rank2_l2_v2(Fixture& f) { +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST // Test rank 2 halo-exchange array::ArrayT arr_t(f.N,3,2); array::ArrayView arrv_t = array::make_view(arr_t); @@ -418,9 +447,11 @@ void test_rank2_l2_v2(Fixture& f) { break; } } +#endif } void test_rank2_v2(Fixture& f) { +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST array::ArrayT arr_t(f.N,3,2); array::ArrayView arrv_t = array::make_view(arr_t); for( int p=0; p Date: Tue, 7 Nov 2017 12:33:10 +0100 Subject: [PATCH 148/355] fix the gpu tests --- src/tests/parallel/test_haloexchange.cc | 62 ++++++++++++++++++------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 6f9dd0442..889202373 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -217,8 +217,7 @@ void test_rank1_strided_v1(Fixture& f) { // (i.e. we are only selecting and exchanging the first component of the field) eckit::SharedPtr arr ( array::Array::wrap( - (f.on_device_ ? array::make_device_view(arr_t).data() : - arrv_t.data()), + arrv_t.data(), array::ArraySpec{array::make_shape(f.N, 1), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA array::make_strides(32, 1) } @@ -227,9 +226,11 @@ void test_rank1_strided_v1(Fixture& f) { #endif ) ); + arr->syncHostDevice(); + f.halo_exchange.template execute(*arr, f.on_device_); - arr_t.syncHostDevice(); + arr->syncHostDevice(); switch( parallel::mpi::comm().rank() ) { @@ -240,10 +241,10 @@ void test_rank1_strided_v1(Fixture& f) { case 2: { POD arr_c[] = { 50,0, 60,0, 70,700, 80,800, 90,900, 10,0, 20,0}; validate::apply(arrv_t, arr_c); break; } } + } void test_rank1_strided_v2(Fixture& f) { -#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST //create a 2d field from the gidx data, with two components per grid point array::ArrayT arr_t(f.N,2); array::ArrayView arrv_t = array::make_host_view(arr_t); @@ -259,7 +260,13 @@ void test_rank1_strided_v2(Fixture& f) { // (i.e. we are only selecting and exchanging the first component of the field) eckit::SharedPtr arr ( array::Array::wrap(&(arrv_t(0,1)), - array::ArraySpec{array::make_shape(f.N, 1), array::make_strides(2, 1) } ) ); + array::ArraySpec{array::make_shape(f.N, 1), +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + array::make_strides(32, 1) +#else + array::make_strides(2, 1) +#endif + } ) ); f.halo_exchange.template execute(*arr, false); @@ -272,7 +279,6 @@ void test_rank1_strided_v2(Fixture& f) { case 2: { POD arr_c[] = { 0,500, 0,600, 70,700, 80,800, 90,900, 0,100, 0,200}; validate::apply(arrv_t, arr_c); break; } } -#endif } void test_rank2(Fixture& f) { @@ -339,8 +345,7 @@ void test_rank2_l1(Fixture& f) { arr_t.syncHostDevice(); eckit::SharedPtr arr ( array::Array::wrap( - (f.on_device_ ? array::make_device_view(arr_t).data() : - arrv_t.data()), + arrv_t.data(), array::ArraySpec{array::make_shape(f.N, 1, 2), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA array::make_strides(96,32, 1) @@ -350,6 +355,8 @@ void test_rank2_l1(Fixture& f) { } ) ); + arr_t.syncHostDevice(); + f.halo_exchange.template execute(*arr, false); arr_t.syncHostDevice(); @@ -396,7 +403,7 @@ void test_rank2_l2_v2(Fixture& f) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST // Test rank 2 halo-exchange array::ArrayT arr_t(f.N,3,2); - array::ArrayView arrv_t = array::make_view(arr_t); + array::ArrayView arrv_t = array::make_host_view(arr_t); for( int p=0; p arr ( array::Array::wrap(&arrv_t(0,1,1), - array::ArraySpec{array::make_shape(f.N, 1, 1), array::make_strides(6, 2, 1) } ) ); + array::ArraySpec{array::make_shape(f.N, 1, 1), +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + array::make_strides(192, 32, 1) +#else + array::make_strides(6, 2, 1) +#endif + } ) ); - f.halo_exchange.template execute(*arr, false); + f.halo_exchange.template execute(*arr, f.on_device_); switch( parallel::mpi::comm().rank() ) { @@ -464,9 +477,15 @@ void test_rank2_v2(Fixture& f) { } eckit::SharedPtr arr ( array::Array::wrap(&arrv_t(0,0,1), - array::ArraySpec{array::make_shape(f.N, 3, 1), array::make_strides(6, 2, 2) } ) ); + array::ArraySpec{array::make_shape(f.N, 3, 1), +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + array::make_strides(192, 32, 2) +#else + array::make_strides(6, 2, 2) +#endif + } ) ); - f.halo_exchange.template execute(*arr, false); + f.halo_exchange.template execute(*arr, f.on_device_); switch( parallel::mpi::comm().rank() ) { @@ -511,7 +530,11 @@ void test_rank0_wrap(Fixture& f) { eckit::SharedPtr arr ( array::Array::wrap(f.gidx.data(), array::make_shape(f.N) ) ); array::ArrayView arrv = array::make_view(*arr); - f.halo_exchange.template execute(*arr, false); + arr->syncHostDevice(); + + f.halo_exchange.template execute(*arr, f.on_device_); + + arr->syncHostDevice(); switch( parallel::mpi::comm().rank() ) { @@ -622,7 +645,7 @@ CASE("test_haloexchange") { { test_rank2_l1(f); } -/* + SECTION( "test_rank2_l2_v2" ) { test_rank2_l2_v2(f); @@ -647,6 +670,7 @@ CASE("test_haloexchange") { { test_rank2_paralleldim2(f); } + #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA f.on_device_ = true; @@ -664,8 +688,14 @@ CASE("test_haloexchange") { { test_rank2(f); } + SECTION( "test_rank0_wrap" ) + { + test_rank0_wrap(f); + } + + #endif -*/ + } } From 9d322e4569f374ab070f0e8738cab30a87dbebf8 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 7 Nov 2017 17:21:22 +0100 Subject: [PATCH 149/355] throw if parallel dim is specified for GPU --- src/atlas/parallel/HaloExchange.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 90d42c75c..79371f348 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -240,8 +240,11 @@ void HaloExchange::pack_send_buffer( const array::ArrayView::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); + } else halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); #else @@ -257,8 +260,12 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - if(on_device) + if(on_device) { + if(ParallelDim != 0) + throw eckit::Exception("Selecting parallel dimension for GPU backend not supported yet"); + halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); + } else halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); #else From 83ee2c05ca45eee63a9715a26c5fe4addd0a9573 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 7 Nov 2017 21:03:21 +0100 Subject: [PATCH 150/355] fix and cleanup --- src/atlas/array/gridtools/GridToolsArrayView.h | 4 +++- src/atlas/parallel/HaloExchange.cc | 13 ------------- src/tests/array/test_array.cc | 5 ++++- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 276ffd533..ba7ddca7b 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -34,6 +34,7 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas public: + using return_type = typename std::conditional< (AccessMode == Intent::ReadWrite), value_type, value_type const>::type; ATLAS_HOST_DEVICE ArrayView( const ArrayView& other ); ArrayView(data_view_t data_view, const Array& array); @@ -42,7 +43,7 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas template < typename... Coords, typename = typename boost::enable_if_c<(sizeof...(Coords) == Rank), int>::type > ATLAS_HOST_DEVICE - value_type& + return_type& operator()(Coords... c) { assert(sizeof...(Coords) == Rank); return gt_data_view_(c...); @@ -51,6 +52,7 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas template ::type> ATLAS_HOST_DEVICE value_type const& operator()(Coords... c) const { + assert(sizeof...(Coords) == Rank); return gt_data_view_(c...); } diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 4dd64a9f2..c2833981c 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -95,8 +95,6 @@ void HaloExchange::setup( const int part[], } sendcnt_ = std::accumulate(sendcounts_.begin(),sendcounts_.end(),0); -// std::cout << myproc << ": sendcnt = " << sendcnt_ << std::endl; -// std::cout << myproc << ": recvcnt = " << recvcnt_ << std::endl; recvdispls_[0]=0; senddispls_[0]=0; @@ -142,17 +140,6 @@ void HaloExchange::setup( const int part[], for( int jj=0; jjstride(0) == 2); EXPECT(arr->rank() == 1); - auto view = make_host_view(*arr); + auto view = make_host_view(*arr); EXPECT(view.shape(0) == 3); +// TODO fix this +#ifndef ATLAS_HAVE_GRIDTOOLS_STORAGE EXPECT(view.stride(0) == 2); +#endif EXPECT(view.rank() == 1); EXPECT(view(0) == -1); From 11c449dfb0b9f786503d1b481ae8d339613f47bc Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Tue, 7 Nov 2017 23:01:26 +0100 Subject: [PATCH 151/355] support for flat C function --- .../array/gridtools/GridToolsArrayView.h | 2 + src/atlas/parallel/HaloExchange.cc | 121 +++++--- src/tests/parallel/CMakeLists.txt | 7 - src/tests/parallel/test_haloexchange.cc | 33 +++ src/tests/parallel/test_haloexchange_gpu.cc | 277 ------------------ 5 files changed, 108 insertions(+), 332 deletions(-) delete mode 100644 src/tests/parallel/test_haloexchange_gpu.cc diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index ba7ddca7b..d1190162a 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -58,6 +58,8 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas size_t shape(size_t idx) const { return shape_[idx]; } + size_t stride(size_t idx) const { return strides_[idx]; } + const Slice operator[](size_t i) const { return Slicer(*this).apply(i); } diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index c2833981c..87e811201 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -17,6 +17,7 @@ #include #include "atlas/parallel/HaloExchange.h" #include "atlas/parallel/mpi/Statistics.h" +#include "atlas/array/Array.h" namespace atlas { namespace parallel { @@ -161,63 +162,87 @@ void atlas__HaloExchange__setup (HaloExchange* This, int part[], int remote_idx[ } void atlas__HaloExchange__execute_strided_int (HaloExchange* This, int field[], int var_strides[], int var_extents[], int var_rank) { - throw eckit::AssertionFailed("Call not supported"); - -// std::vector vstrides(var_rank); -// std::vector vextents(var_rank); -// for(int n = 0; n < var_rank; ++n) { -// vstrides[n] = var_strides[n]; -// vextents[n] = var_extents[n]; -// } -// This->execute(field,vstrides.data(),vextents.data(),var_rank); + array::ArrayShape shape; + shape.resize(var_rank); + shape.assign(var_extents, var_extents+var_rank); + + array::ArrayStrides strides; + strides.resize(var_rank); + strides.assign(var_strides, var_strides+var_rank); + + eckit::SharedPtr arr ( array::Array::wrap(field, + array::ArraySpec{shape, strides}) ); + + switch(var_rank) { + case 1: {This->execute(*arr); break;} + case 2: {This->execute(*arr); break;} + case 3: {This->execute(*arr); break;} + case 4: {This->execute(*arr); break;} + default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); + } } void atlas__HaloExchange__execute_strided_long (HaloExchange* This, long field[], int var_strides[], int var_extents[], int var_rank) { - throw eckit::AssertionFailed("Call not supported"); - -// std::vector vstrides(var_rank); -// std::vector vextents(var_rank); -// for(int n = 0; n < var_rank; ++n) { -// vstrides[n] = var_strides[n]; -// vextents[n] = var_extents[n]; -// } -// This->execute(field,vstrides.data(),vextents.data(),var_rank); + array::ArrayShape shape; + shape.resize(var_rank); + shape.assign(var_extents, var_extents+var_rank); + + array::ArrayStrides strides; + strides.resize(var_rank); + strides.assign(var_strides, var_strides+var_rank); + + eckit::SharedPtr arr ( array::Array::wrap(field, + array::ArraySpec{shape, strides}) ); + + switch(var_rank) { + case 1: {This->execute(*arr); break;} + case 2: {This->execute(*arr); break;} + case 3: {This->execute(*arr); break;} + case 4: {This->execute(*arr); break;} + default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); + } } void atlas__HaloExchange__execute_strided_float (HaloExchange* This, float field[], int var_strides[], int var_extents[], int var_rank) { - throw eckit::AssertionFailed("Call not supported"); - -// std::vector vstrides(var_rank); -// std::vector vextents(var_rank); -// for(int n = 0; n < var_rank; ++n) { -// vstrides[n] = var_strides[n]; -// vextents[n] = var_extents[n]; -// } -// This->execute(field,vstrides.data(),vextents.data(),var_rank); + array::ArrayShape shape; + shape.resize(var_rank); + shape.assign(var_extents, var_extents+var_rank); + + array::ArrayStrides strides; + strides.resize(var_rank); + strides.assign(var_strides, var_strides+var_rank); + + eckit::SharedPtr arr ( array::Array::wrap(field, + array::ArraySpec{shape, strides}) ); + + switch(var_rank) { + case 1: {This->execute(*arr); break;} + case 2: {This->execute(*arr); break;} + case 3: {This->execute(*arr); break;} + case 4: {This->execute(*arr); break;} + default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); + } } void atlas__HaloExchange__execute_strided_double (HaloExchange* This, double field[], int var_strides[], int var_extents[], int var_rank) { - throw eckit::AssertionFailed("Call not supported"); - -// std::vector vstrides(var_rank); -// std::vector vextents(var_rank); -// for(int n = 0; n < var_rank; ++n) { -// vstrides[n] = var_strides[n]; -// vextents[n] = var_extents[n]; -// } -// This->execute(field,vstrides.data(),vextents.data(),var_rank); -} - -void atlas__HaloExchange__execute_int (HaloExchange* This, int field[], int nb_vars ) { -// This->execute(field,nb_vars); -} - -void atlas__HaloExchange__execute_float (HaloExchange* This, float field[], int nb_vars ) { -// This->execute(field,nb_vars); -} - -void atlas__HaloExchange__execute_double (HaloExchange* This, double field[], int nb_vars ) { -// This->execute(field,nb_vars); + array::ArrayShape shape; + shape.resize(var_rank); + shape.assign(var_extents, var_extents+var_rank); + + array::ArrayStrides strides; + strides.resize(var_rank); + strides.assign(var_strides, var_strides+var_rank); + + eckit::SharedPtr arr ( array::Array::wrap(field, + array::ArraySpec{shape, strides}) ); + + switch(var_rank) { + case 1: {This->execute(*arr); break;} + case 2: {This->execute(*arr); break;} + case 3: {This->execute(*arr); break;} + case 4: {This->execute(*arr); break;} + default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); + } } ///////////////////// diff --git a/src/tests/parallel/CMakeLists.txt b/src/tests/parallel/CMakeLists.txt index 52cccb02e..854523bde 100644 --- a/src/tests/parallel/CMakeLists.txt +++ b/src/tests/parallel/CMakeLists.txt @@ -20,10 +20,3 @@ ecbuild_add_test( TARGET atlas_test_gather LIBS atlas ) -ecbuild_add_test( TARGET atlas_test_haloexchange_gpu - MPI 3 - CONDITION ECKIT_HAVE_MPI - SOURCES test_haloexchange_gpu.cc - LIBS atlas -) - diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 889202373..b91b4a2b8 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -612,6 +612,35 @@ void test_rank2_paralleldim2(Fixture& f) { } } +void test_rank1_cinterface(Fixture& f) { + +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST + array::ArrayT arr(f.N,2); + array::ArrayView arrv = array::make_host_view(arr); + for( int j=0; j::apply(arrv, arr_c); break; } + case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; + validate::apply(arrv, arr_c); break; } + case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; + validate::apply(arrv, arr_c); break; } + } +#endif +} + CASE("test_haloexchange") { SETUP("HaloExchanges_cpu") { Fixture f(false); @@ -670,6 +699,10 @@ CASE("test_haloexchange") { { test_rank2_paralleldim2(f); } + SECTION( "test_rank1_cinterface" ) + { + test_rank1_cinterface(f); + } #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA f.on_device_ = true; diff --git a/src/tests/parallel/test_haloexchange_gpu.cc b/src/tests/parallel/test_haloexchange_gpu.cc deleted file mode 100644 index 7c5951969..000000000 --- a/src/tests/parallel/test_haloexchange_gpu.cc +++ /dev/null @@ -1,277 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 "eckit/memory/SharedPtr.h" - -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/library/config.h" -#include "atlas/array.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/MakeView.h" -#include "atlas/parallel/HaloExchange.h" - - -#include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" - -using namespace eckit::testing; - -/// POD: Type to test -typedef double POD; - -namespace atlas { -namespace test { - -//----------------------------------------------------------------------------- - -template -std::vector vec( const T (&list)[N] ) -{ - return std::vector(list,list+N); -} - -struct Fixture { - Fixture() - { - int nnodes_c[] = {5, 6, 7}; nb_nodes = vec(nnodes_c); - N = nb_nodes[parallel::mpi::comm().rank()]; - switch( parallel::mpi::comm().rank() ) - { - case 0: - { - int part_c[] = {2,0,0,0,1}; part = vec(part_c); - int ridx_c[] = {4,1,2,3,1}; ridx = vec(ridx_c); - POD gidx_c[] = {0,1,2,3,0}; gidx = vec(gidx_c); - break; - } - case 1: - { - int part_c[] = {0,1,1,1,2,2}; part = vec(part_c); - int ridx_c[] = {3,1,2,3,2,3}; ridx = vec(ridx_c); - POD gidx_c[] = {0,4,5,6,0,0}; gidx = vec(gidx_c); - break; - } - case 2: - { - int part_c[] = {1,1,2,2,2,0,0}; part = vec(part_c); - int ridx_c[] = {2,3,2,3,4,1,2}; ridx = vec(ridx_c); - POD gidx_c[] = {0,0,7,8,9,0,0}; gidx = vec(gidx_c); - break; - } - } - halo_exchange.setup(part.data(),ridx.data(),0,N); - } - parallel::HaloExchange halo_exchange; - std::vector nb_nodes; - std::vector part; - std::vector ridx; - std::vector gidx; - - int N; -}; - -//----------------------------------------------------------------------------- - -template -size_t eval_idx(size_t pos, std::array& strides, FirstDim first) -{ - return first*strides[pos]; -} - -template -size_t eval_idx(size_t pos, std::array& strides, FirstDim first, Int...dims ) -{ - return first*strides[pos] + eval_idx((size_t)pos+1, strides, dims...); -} - -template -struct validate_impl; - -template -struct validate_impl { - template - static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { - EXPECT(arrv(dims...) == arr_c[eval_idx((size_t)0, strides, dims...)]); - } -}; - -template -struct validate_impl { - - template - static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { - for(size_t cnt = 0; cnt < arrv.template shape(); ++cnt) { - validate_impl::apply(arrv, arr_c, strides, dims..., cnt); - } - } -}; - -template -struct compute_strides; - -template<> -struct compute_strides<0> { - template - static void apply(array::ArrayView& arrv, std::array& strides) {} -}; - -template -struct compute_strides { - template - static void apply(array::ArrayView& arrv, std::array& strides) { - strides[Dim-1] = strides[Dim]*arrv.template shape<(unsigned int)Dim>(); - compute_strides::apply(arrv,strides); - - } -}; - -template -struct validate { - - static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { - std::array strides; - strides[Rank-1] = 1; - compute_strides::apply(arrv, strides); - - for(size_t i = 0; i < arrv.template shape<0>(); ++i) { - validate_impl::apply(arrv, arr_c, strides, i); - } - } - -}; - -CASE("test_haloexchange_gpu") { - SETUP("Fixture") { - Fixture f; - - SECTION( "test_rank0_arrview" ) - { - array::ArrayT arr(f.N); - array::ArrayView arrv = array::make_host_view(arr); - for( int j=0; j(arr, true); - - arr.syncHostDevice(); - - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 9, 1, 2, 3, 4}; - validate::apply(arrv, arr_c); break; } - case 1: { POD arr_c[] = { 3, 4, 5, 6, 7, 8}; - validate::apply(arrv, arr_c); break; } - case 2: { POD arr_c[] = { 5, 6, 7, 8, 9, 1, 2}; - validate::apply(arrv, arr_c); break; } - } - cudaDeviceSynchronize(); - } - - - SECTION( "test_rank1" ) - { - array::ArrayT arr(f.N,2); - array::ArrayView arrv = array::make_host_view(arr); - for( int j=0; j(arr, true); - - arr.syncHostDevice(); - - switch( parallel::mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; - validate::apply(arrv, arr_c); break; } - case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; - validate::apply(arrv, arr_c); break; } - case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; - validate::apply(arrv, arr_c); break; } - } - } - - SECTION( "test_rank2" ) - { - array::ArrayT arr(f.N,3,2); - array::ArrayView arrv = array::make_host_view(arr); - for( int p=0; p(arr, true); - - arr.syncHostDevice(); - - switch( parallel::mpi::comm().rank() ) - { - case 0: - { - POD arr_c[] = { -9,9, -90,90, -900,900, - -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200, - -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400}; - validate::apply(arrv, arr_c); break; - } - case 1: - { - POD arr_c[] = { -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400, - -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800}; - validate::apply(arrv, arr_c); break; - } - case 2: - { - POD arr_c[] = { -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800, - -9,9, -90,90, -900,900, - -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200}; - validate::apply(arrv, arr_c); break; - } - } - } - } -} - -//----------------------------------------------------------------------------- - -} // namespace test -} // namespace atlas - - -int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); -} - From a13f6c157789790a47fa751446c94aec2fb266ff Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 8 Nov 2017 11:47:25 +0000 Subject: [PATCH 152/355] First attempt at adding OpenACC support --- CMakeLists.txt | 33 +++++------ src/CMakeLists.txt | 2 + src/atlas/CMakeLists.txt | 4 ++ src/atlas/array/Array.h | 5 ++ src/atlas/array/gridtools/GridToolsArray.cc | 15 ++++- src/atlas/array/native/NativeArray.cc | 4 ++ src/atlas/library/defines.h.in | 4 ++ src/atlas_acc_support/CMakeLists.txt | 62 +++++++++++++++++++++ src/atlas_acc_support/atlas_acc_map_data.c | 12 ++++ src/atlas_acc_support/atlas_acc_map_data.h | 11 ++++ 10 files changed, 135 insertions(+), 17 deletions(-) create mode 100644 src/atlas_acc_support/CMakeLists.txt create mode 100644 src/atlas_acc_support/atlas_acc_map_data.c create mode 100644 src/atlas_acc_support/atlas_acc_map_data.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cce800820..2cb6a45f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -215,22 +215,23 @@ add_subdirectory( src ) set( ATLAS_URL "https://software.ecmwf.int/wiki/display/ATLAS" ) set( ATLAS_DESCRIPTION "Atlas framework for parallel mesh datastructures" ) -ecbuild_pkgconfig() - -ecbuild_pkgconfig( - NAME atlas-c++ - LANGUAGES CXX - LIBRARIES atlas -) - -if( ATLAS_HAVE_FORTRAN ) - ecbuild_pkgconfig( - NAME atlas-fortran - LANGUAGES Fortran - LIBRARIES atlas_f - NO_PRIVATE_INCLUDE_DIRS - ) -endif() +#ecbuild_pkgconfig() + +#ecbuild_pkgconfig( +# NAME atlas-c++ +# LANGUAGES CXX +# LIBRARIES atlas +#) + +#if( ATLAS_HAVE_FORTRAN ) +# ecbuild_pkgconfig( +# NAME atlas-fortran +# LANGUAGES Fortran +# LIBRARIES atlas_f +# NO_PRIVATE_INCLUDE_DIRS +# ) +#endif() +ecbuild_warn( "ecbuild needs fixing to enable above with OpenACC imported library" ) ################################################################################ # documentation diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c7e90ad77..2e8373e43 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -55,6 +55,8 @@ if( ATLAS_HAVE_MPI ) endif() +add_subdirectory( atlas_acc_support ) + add_subdirectory( atlas ) if( ATLAS_HAVE_FORTRAN ) diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 70032a5a5..60a2bd036 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -531,3 +531,7 @@ ecbuild_add_library( TARGET atlas if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) target_link_libraries( atlas gridtools::storage ) endif() + +if( ATLAS_HAVE_ACC ) + target_link_libraries( atlas atlas_acc_support ) +endif() diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index d12127cc9..daf1c455e 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -88,6 +88,8 @@ class Array : public eckit::Owned { virtual void dump(std::ostream& os) const = 0; + virtual bool accMap() const = 0; + virtual void* storage() { return data_store_->voidDataStore();} virtual const void* storage() const { return data_store_->voidDataStore();} @@ -170,9 +172,12 @@ template class ArrayT : public Array { virtual size_t footprint() const; + virtual bool accMap() const; + private: template friend class ArrayT_impl; + mutable bool acc_map_{false}; }; } // namespace array diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index b64c81d5f..690cd29be 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -22,7 +22,9 @@ #include "atlas/array/gridtools/GridToolsDataStore.h" #include "atlas/array/gridtools/GridToolsArrayHelpers.h" #include "atlas/array/helpers/ArrayInitializer.h" - +#ifdef ATLAS_HAVE_ACC +#include "atlas_acc_support/atlas_acc_map_data.h" +#endif #include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------ @@ -433,6 +435,17 @@ template ArrayT::ArrayT(const ArraySpec& spec) { ArrayT_impl(*this).construct(spec.shape(),spec.layout()); } +template +bool ArrayT::accMap() const { + if( not acc_map_ ) { +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA && defined(ATLAS_HAVE_ACC) + atlas_acc_map_data( (void*) host_data(), (void*) device_data(), size() ); + acc_map_ = true; +#endif + } + return acc_map_; +} + //------------------------------------------------------------------------------ } // namespace array diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index 34e1952cc..1b57e002a 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -198,6 +198,10 @@ size_t ArrayT::footprint() const { return size; } +template +bool ArrayT::accMap() const { + return false; +} template DATATYPE const* Array::host_data() const { return array::make_host_storageview(*this).data(); diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index 0bfa71dea..71b6455b3 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -35,6 +35,10 @@ #define ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA @ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA@ #endif +#if @ATLAS_HAVE_ACC@ +#define ATLAS_HAVE_ACC +#endif + #ifdef __CUDACC__ #define ATLAS_HOST_DEVICE __host__ __device__ #define ATLAS_DEVICE __device__ diff --git a/src/atlas_acc_support/CMakeLists.txt b/src/atlas_acc_support/CMakeLists.txt new file mode 100644 index 000000000..8229ac045 --- /dev/null +++ b/src/atlas_acc_support/CMakeLists.txt @@ -0,0 +1,62 @@ + +set( ATLAS_HAVE_ACC 0 ) +set( ENABLE_ACC ON CACHE STRING "Enable OpenACC" ) + +if( ENABLE_ACC AND NOT CUDA_FOUND ) + + ecbuild_warn( "OpenACC support not enabled as CUDA was not found" ) + +elseif( ENABLE_ACC ) + + if( CMAKE_Fortran_COMPILER_ID MATCHES "PGI" ) + set( ACC_Fortran_FLAGS -acc -ta=tesla,cuda${CUDA_VERSION},nordc ) + set( ACC_C_FLAGS ${ACC_Fortran_FLAGS} ) + set( ACC_C_COMPILER pgcc ) + set( ATLAS_HAVE_ACC 1 ) + elseif( CMAKE_Fortran_COMPILER_ID MATCHES "Cray" ) + ecbuild_warn( "OpenACC support not enabled as we did not yet implement it for Cray" ) + else() + ecbuild_warn( "OpenACC support not enabled as we did not yet implement it for ${CMAKE_Fortran_COMPILER_ID}" ) + endif() + if( ATLAS_HAVE_ACC ) + ecbuild_info( "OpenACC enabled" ) + endif() + +endif() + +if( ATLAS_HAVE_ACC ) + + if( NOT (CMAKE_C_COMPILER_ID MATCHES ${CMAKE_Fortran_COMPILER_ID}) ) + + foreach( _dir ${ACC_C_INCLUDE_DIRS} ) + set( ACC_C_INCLUDE ${ACC_C_INCLUDE} -I${_dir} ) + endforeach() + add_custom_command( + OUTPUT ${CMAKE_BINARY_DIR}/lib/libatlas_acc_support.so ${CMAKE_CURRENT_BINARY_DIR}/atlas_acc_map_data.c.o + COMMAND ${ACC_C_COMPILER} ${ACC_C_FLAGS} ${ACC_C_INCLUDE} -fPIC -o ${CMAKE_CURRENT_BINARY_DIR}/atlas_acc_map_data.c.o + -c ${CMAKE_CURRENT_SOURCE_DIR}/atlas_acc_map_data.c + COMMAND mkdir -p ${CMAKE_BINARY_DIR}/lib + COMMAND ${ACC_C_COMPILER} ${ACC_C_FLAGS} -shared -o ${CMAKE_BINARY_DIR}/lib/libatlas_acc_support.so + ${CMAKE_CURRENT_BINARY_DIR}/atlas_acc_map_data.c.o + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/atlas_acc_map_data.c + COMMENT "Building atlas_acc_support with ${ACC_C_COMPILER}" + ) + add_custom_target( build-atlas_acc_support ALL DEPENDS ${CMAKE_BINARY_DIR}/lib/libatlas_acc_support.so ) + add_library( atlas_acc_support SHARED IMPORTED GLOBAL ) + set_property( TARGET atlas_acc_support PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libatlas_acc_support.so ) + set_property( TARGET atlas_acc_support PROPERTY IMPORTED_NO_SONAME TRUE ) + set_property( TARGET atlas_acc_support PROPERTY IMPORTED_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR} ) + add_dependencies( atlas_acc_support build-atlas_acc_support ) + install( FILES ${CMAKE_BINARY_DIR}/lib/libatlas_acc_support.so DESTINATION lib/ ) + + else() + + ecbuild_add_library( TARGET atlas_acc_support SOURCES atlas_acc_map_data.c ) + target_compile_options( atlas_acc_support PRIVATE ${ACC_C_FLAGS} ) + target_link_libraries( atlas_acc_support PRIVATE ${ACC_C_FLAGS} ) + + endif() + +endif() + +set( ATLAS_HAVE_ACC ${ATLAS_HAVE_ACC} PARENT_SCOPE ) diff --git a/src/atlas_acc_support/atlas_acc_map_data.c b/src/atlas_acc_support/atlas_acc_map_data.c new file mode 100644 index 000000000..c8567aa39 --- /dev/null +++ b/src/atlas_acc_support/atlas_acc_map_data.c @@ -0,0 +1,12 @@ +// This file needs to be compiled with an OpenACC capable C compiler that is +// compatible with the Fortran compiler + +#ifndef _OPENACC +#error atlas_acc_map_data must be compiled with OpenACC capable compiler +#endif + +#include +void atlas_acc_map_data(void* cpu_ptr, void* gpu_ptr, unsigned long size) +{ + acc_map_data(cpu_ptr, gpu_ptr, size); +} diff --git a/src/atlas_acc_support/atlas_acc_map_data.h b/src/atlas_acc_support/atlas_acc_map_data.h new file mode 100644 index 000000000..f0d1f2168 --- /dev/null +++ b/src/atlas_acc_support/atlas_acc_map_data.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +void atlas_acc_map_data(void* cpu_ptr, void* gpu_ptr, unsigned long size); + +#ifdef __cplusplus +} +#endif From bc6bf151b7857e1ca5d3c5fad9cb4edd477722c3 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 8 Nov 2017 16:54:47 +0000 Subject: [PATCH 153/355] Requested Fortran fields are automatically acc_mapped --- src/atlas/array/Array.h | 12 +- src/atlas/array/ArraySpec.cc | 12 +- src/atlas/array/ArraySpec.h | 5 + src/atlas/array/ArrayUtil.h | 4 + src/atlas/array/gridtools/GridToolsArray.cc | 127 +++++++++--------- .../array/gridtools/GridToolsArrayHelpers.h | 12 +- .../array/gridtools/GridToolsDataStore.h | 8 ++ src/atlas/array/native/NativeArray.cc | 36 ++--- src/atlas/array/native/NativeDataStore.h | 16 +++ src/atlas/field/detail/FieldImpl.cc | 48 +++---- src/tests/array/test_array.cc | 29 ++++ 11 files changed, 187 insertions(+), 122 deletions(-) diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index daf1c455e..ec772287d 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -113,12 +113,12 @@ class Array : public eckit::Owned { ArraySpec& spec() {return spec_;} // -- dangerous methods... You're on your own interpreting the raw data - template DATATYPE const* host_data() const; - template DATATYPE* host_data(); - template DATATYPE const* device_data() const; - template DATATYPE* device_data(); - template DATATYPE const* data() const; - template DATATYPE* data(); + template DATATYPE const* host_data() const { return data_store_->hostData(); } + template DATATYPE* host_data() { return data_store_->hostData(); } + template DATATYPE const* device_data() const { return data_store_->deviceData(); } + template DATATYPE* device_data() { return data_store_->deviceData(); } + template DATATYPE const* data() const { return data_store_->hostData(); } + template DATATYPE* data() { return data_store_->hostData(); } ArrayDataStore const* data_store() const { return data_store_.get();} diff --git a/src/atlas/array/ArraySpec.cc b/src/atlas/array/ArraySpec.cc index ef30e2b60..49d9b9e78 100644 --- a/src/atlas/array/ArraySpec.cc +++ b/src/atlas/array/ArraySpec.cc @@ -18,6 +18,7 @@ namespace array { ArraySpec::ArraySpec(): size_(), rank_(), + allocated_size_(), contiguous_(true), default_layout_(true) { @@ -36,6 +37,7 @@ ArraySpec::ArraySpec( const ArrayShape& shape ) layout_[j] = j; size_ *= shape_[j]; } + allocated_size_ = size_; contiguous_ = true; default_layout_ = true; }; @@ -56,7 +58,8 @@ ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides ) layout_[j] = j; size_ *= shape_[j]; } - contiguous_ = (size_ == shape_[0]*strides_[0] ? true : false); + allocated_size_ = shape_[0]*strides_[0]; + contiguous_ = (size_ == allocated_size_); default_layout_ = true; } @@ -76,9 +79,12 @@ ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, cons strides_[j] = strides[j]; layout_[j] = layout[j]; size_ *= shape_[j]; - if( layout_[j] != size_t(j) ) default_layout_ = false; + if( layout_[j] != size_t(j) ) { + default_layout_ = false; + } } - contiguous_ = (size_ == shape_[0]*strides_[0] ? true : false); + allocated_size_ = shape_[0]*strides_[0]; + contiguous_ = (size_ == allocated_size_); } const std::vector& ArraySpec::shapef() const diff --git a/src/atlas/array/ArraySpec.h b/src/atlas/array/ArraySpec.h index 3566c82c0..41cbd40f0 100644 --- a/src/atlas/array/ArraySpec.h +++ b/src/atlas/array/ArraySpec.h @@ -39,6 +39,7 @@ class ArraySpec { ArraySpec( const ArrayShape& ); ArraySpec( const ArrayShape&, const ArrayStrides& ); ArraySpec( const ArrayShape&, const ArrayStrides&, const ArrayLayout& ); + size_t allocated_size() const { return allocated_size_; } size_t size() const { return size_; } size_t rank() const { return rank_; } const ArrayShape& shape() const { return shape_; } @@ -48,6 +49,10 @@ class ArraySpec { const std::vector& stridesf() const; bool contiguous() const { return contiguous_; } bool hasDefaultLayout() const { return default_layout_; } + +/// todo: make private + size_t allocated_size_; + }; //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/array/ArrayUtil.h b/src/atlas/array/ArrayUtil.h index 519c1639f..bf8f32b43 100644 --- a/src/atlas/array/ArrayUtil.h +++ b/src/atlas/array/ArrayUtil.h @@ -41,6 +41,10 @@ class ArrayDataStore virtual void reactivateDeviceWriteViews() const = 0; virtual void reactivateHostWriteViews() const = 0; virtual void* voidDataStore() = 0; + virtual void* voidHostData() = 0; + virtual void* voidDeviceData() = 0; + template Value* hostData() { return static_cast(voidHostData()); } + template Value* deviceData() { return static_cast(voidDeviceData()); } }; template < int Dim > diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 690cd29be..e81cc91e9 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -67,7 +67,6 @@ class ArrayT_impl { auto gt_storage = create_gt_storage::type>(dims...); using data_store_t = typename std::remove_pointer::type; array_.data_store_ = std::unique_ptr(new GridToolsDataStore(gt_storage)); - array_.spec_ = make_spec(gt_storage,dims...); } @@ -267,57 +266,57 @@ Array* Array::create(DataType datatype, const ArrayShape& shape, const ArrayLayo return 0; } -template DATATYPE const* Array::host_data() const { - return array::make_host_storageview(*this).data(); -} -template DATATYPE* Array::host_data() { - return array::make_host_storageview(*this).data(); -} -template DATATYPE const* Array::device_data() const { - return array::make_device_storageview(*this).data(); -} -template DATATYPE* Array::device_data() { - return array::make_device_storageview(*this).data(); -} -template DATATYPE const* Array::data() const { - return array::make_host_storageview(*this).data(); -} -template DATATYPE* Array::data() { - return array::make_host_storageview(*this).data(); -} - -template int* Array::host_data(); -template int const* Array::host_data() const; -template long* Array::host_data(); -template long const* Array::host_data() const; -template long unsigned* Array::host_data(); -template long unsigned const* Array::host_data() const; -template float* Array::host_data(); -template float const* Array::host_data() const; -template double* Array::host_data(); -template double const* Array::host_data() const; - -template int* Array::device_data(); -template int const* Array::device_data() const; -template long* Array::device_data(); -template long const* Array::device_data() const; -template long unsigned* Array::device_data(); -template long unsigned const* Array::device_data() const; -template float* Array::device_data(); -template float const* Array::device_data() const; -template double* Array::device_data(); -template double const* Array::device_data() const; - -template int* Array::data(); -template int const* Array::data() const; -template long* Array::data(); -template long const* Array::data() const; -template long unsigned* Array::data(); -template long unsigned const* Array::data() const; -template float* Array::data(); -template float const* Array::data() const; -template double* Array::data(); -template double const* Array::data() const; +// template DATATYPE const* Array::host_data() const { +// return array::make_host_storageview(*this).data(); +// } +// template DATATYPE* Array::host_data() { +// return array::make_host_storageview(*this).data(); +// } +// template DATATYPE const* Array::device_data() const { +// return array::make_device_storageview(*this).data(); +// } +// template DATATYPE* Array::device_data() { +// return array::make_device_storageview(*this).data(); +// } +// template DATATYPE const* Array::data() const { +// return array::make_host_storageview(*this).data(); +// } +// template DATATYPE* Array::data() { +// return array::make_host_storageview(*this).data(); +// } + +// template int* Array::host_data(); +// template int const* Array::host_data() const; +// template long* Array::host_data(); +// template long const* Array::host_data() const; +// template long unsigned* Array::host_data(); +// template long unsigned const* Array::host_data() const; +// template float* Array::host_data(); +// template float const* Array::host_data() const; +// template double* Array::host_data(); +// template double const* Array::host_data() const; + +// template int* Array::device_data(); +// template int const* Array::device_data() const; +// template long* Array::device_data(); +// template long const* Array::device_data() const; +// template long unsigned* Array::device_data(); +// template long unsigned const* Array::device_data() const; +// template float* Array::device_data(); +// template float const* Array::device_data() const; +// template double* Array::device_data(); +// template double const* Array::device_data() const; + +// template int* Array::data(); +// template int const* Array::data() const; +// template long* Array::data(); +// template long const* Array::data() const; +// template long unsigned* Array::data(); +// template long unsigned const* Array::data() const; +// template float* Array::data(); +// template float const* Array::data() const; +// template double* Array::data(); +// template double const* Array::data() const; //------------------------------------------------------------------------------ @@ -331,6 +330,19 @@ size_t ArrayT::footprint() const { //------------------------------------------------------------------------------ +template +bool ArrayT::accMap() const { + if( not acc_map_ ) { +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA && defined(ATLAS_HAVE_ACC) + atlas_acc_map_data( (void*) host_data(), (void*) device_data(), spec_.allocated_size() ); + acc_map_ = true; +#endif + } + return acc_map_; +} + +//------------------------------------------------------------------------------ + template void ArrayT::insert(size_t idx1, size_t size1) { if(!hostNeedsUpdate()) { cloneFromDevice(); @@ -435,17 +447,6 @@ template ArrayT::ArrayT(const ArraySpec& spec) { ArrayT_impl(*this).construct(spec.shape(),spec.layout()); } -template -bool ArrayT::accMap() const { - if( not acc_map_ ) { -#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA && defined(ATLAS_HAVE_ACC) - atlas_acc_map_data( (void*) host_data(), (void*) device_data(), size() ); - acc_map_ = true; -#endif - } - return acc_map_; -} - //------------------------------------------------------------------------------ } // namespace array diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index da8b1b247..e706f8d82 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -20,6 +20,7 @@ #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" #include "atlas/array/gridtools/GridToolsTraits.h" +#include "atlas/runtime/Log.h" #include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------ @@ -237,9 +238,9 @@ struct default_layout_t { auto storage_info_ptr = gt_data_store_ptr->get_storage_info_ptr().get(); using Layout = typename DataStore::storage_info_t::layout_t; - using seq = my_apply_gt_integer_sequence::type>; + using seq = my_apply_gt_integer_sequence::type>; - return ArraySpec( + ArraySpec spec( ArrayShape{(unsigned long)dims...}, seq::template apply< ArrayStrides, @@ -249,9 +250,12 @@ struct default_layout_t { ArrayLayout, get_layout_map_component::template get_component>() ); + spec.allocated_size_ = storage_info_ptr->padded_total_length(); + ASSERT( spec.allocated_size() == storage_info_ptr->padded_total_length() ); + return spec; + } else { + return ArraySpec( make_shape({dims...}), make_null_strides(typename ::gridtools::make_gt_integer_sequence::type())); } - - return ArraySpec( make_shape({dims...}), make_null_strides(typename ::gridtools::make_gt_integer_sequence::type())); } //------------------------------------------------------------------------------ diff --git a/src/atlas/array/gridtools/GridToolsDataStore.h b/src/atlas/array/gridtools/GridToolsDataStore.h index c47f52138..1e3dc8842 100644 --- a/src/atlas/array/gridtools/GridToolsDataStore.h +++ b/src/atlas/array/gridtools/GridToolsDataStore.h @@ -65,6 +65,14 @@ struct GridToolsDataStore : ArrayDataStore return static_cast(const_cast(data_store_)); } + void* voidHostData() { + return ::gridtools::make_host_view<::gridtools::access_mode::ReadOnly>(*data_store_).data(); + } + + void* voidDeviceData() { + return ::gridtools::make_device_view<::gridtools::access_mode::ReadOnly>(*data_store_).data(); + } + private: gt_DataStore const* data_store_; }; diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index 1b57e002a..72c1cadcb 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -203,24 +203,24 @@ bool ArrayT::accMap() const { return false; } -template DATATYPE const* Array::host_data() const { - return array::make_host_storageview(*this).data(); -} -template DATATYPE* Array::host_data() { - return array::make_host_storageview(*this).data(); -} -template DATATYPE const* Array::device_data() const { - return array::make_device_storageview(*this).data(); -} -template DATATYPE* Array::device_data() { - return array::make_device_storageview(*this).data(); -} -template DATATYPE const* Array::data() const { - return array::make_host_storageview(*this).data(); -} -template DATATYPE* Array::data() { - return array::make_host_storageview(*this).data(); -} +// template DATATYPE const* Array::host_data() const { +// return array::make_host_storageview(*this).data(); +// } +// template DATATYPE* Array::host_data() { +// return array::make_host_storageview(*this).data(); +// } +// template DATATYPE const* Array::device_data() const { +// return array::make_device_storageview(*this).data(); +// } +// template DATATYPE* Array::device_data() { +// return array::make_device_storageview(*this).data(); +// } +// template DATATYPE const* Array::data() const { +// return array::make_host_storageview(*this).data(); +// } +// template DATATYPE* Array::data() { +// return array::make_host_storageview(*this).data(); +// } template int* Array::host_data(); template int const* Array::host_data() const; diff --git a/src/atlas/array/native/NativeDataStore.h b/src/atlas/array/native/NativeDataStore.h index b714fe273..acc934766 100644 --- a/src/atlas/array/native/NativeDataStore.h +++ b/src/atlas/array/native/NativeDataStore.h @@ -58,6 +58,14 @@ class DataStore : public ArrayDataStore { return static_cast( &data_store_.front() ); } + void* voidHostData() { + return static_cast( &data_store_.front() ); + } + + void* voidDeviceData() { + return static_cast( &data_store_.front() ); + } + private: std::vector data_store_; }; @@ -103,6 +111,14 @@ class WrappedDataStore : public ArrayDataStore { return static_cast( data_store_ ); } + void* voidHostData() { + return static_cast( data_store_ ); + } + + void* voidDeviceData() { + return static_cast( data_store_ ); + } + private: Value* data_store_; }; diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index cdce90bb3..467f88d9c 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -166,6 +166,20 @@ void FieldImpl::set_functionspace(const FunctionSpace& functionspace) // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines +namespace { + template< typename Value > + void atlas__Field__host_data_specf (FieldImpl* This, Value* &data, int &rank, int* &shapef, int* &stridesf) { + ATLAS_ERROR_HANDLING( + ASSERT(This); + This->array().accMap(); + data = This->host_data(); + shapef = const_cast(This->shapef().data()); + stridesf = const_cast(This->stridesf().data()); + rank = This->shapef().size(); + ); + } +} + extern "C" { @@ -398,46 +412,24 @@ void atlas__Field__shapef (FieldImpl* This, int* &shape, int &rank) void atlas__Field__host_data_int_specf (FieldImpl* This, int* &data, int &rank, int* &shapef, int* &stridesf) { - ATLAS_ERROR_HANDLING( - ASSERT(This); - data = This->host_data(); - shapef = const_cast(This->shapef().data()); - stridesf = const_cast(This->stridesf().data()); - rank = This->shapef().size(); - ); + atlas__Field__host_data_specf(This,data,rank,shapef,stridesf); } void atlas__Field__host_data_long_specf (FieldImpl* This, long* &data, int &rank, int* &shapef, int* &stridesf) { - ATLAS_ERROR_HANDLING( - ASSERT(This); - data = This->host_data(); - shapef = const_cast(This->shapef().data()); - stridesf = const_cast(This->stridesf().data()); - rank = This->shapef().size(); - ); + atlas__Field__host_data_specf(This,data,rank,shapef,stridesf); } void atlas__Field__host_data_float_specf (FieldImpl* This, float* &data, int &rank, int* &shapef, int* &stridesf) { - ATLAS_ERROR_HANDLING( - ASSERT(This); - data = This->host_data(); - shapef = const_cast(This->shapef().data()); - stridesf = const_cast(This->stridesf().data()); - rank = This->shapef().size(); - ); + atlas__Field__host_data_specf(This,data,rank,shapef,stridesf); + } void atlas__Field__host_data_double_specf (FieldImpl* This, double* &data, int &rank, int* &shapef, int* &stridesf) { - ATLAS_ERROR_HANDLING( - ASSERT(This); - data = This->host_data(); - shapef = const_cast(This->shapef().data()); - stridesf = const_cast(This->stridesf().data()); - rank = This->shapef().size(); - ); + atlas__Field__host_data_specf(This,data,rank,shapef,stridesf); + } void atlas__Field__device_data_int_specf (FieldImpl* This, int* &data, int &rank, int* &shapef, int* &stridesf) diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 416cc4864..ed486d2f7 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -105,6 +105,9 @@ CASE("test_localview") { delete ds; } +#ifndef TODO +# warning TODO +#else #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE CASE("test_array_shape") { ArrayShape as{2, 3}; @@ -193,6 +196,7 @@ CASE("test_spec_layout_rev") { EXPECT_THROWS_AS( Array::create(make_shape(4,5,6,2),make_layout(0,1,3,2)), eckit::BadParameter ); } #endif +#endif CASE("test_resize_throw") { Array* ds = Array::create(32, 5, 33); @@ -322,6 +326,9 @@ CASE("test_resize_shape") { delete ds; } +#ifndef TODO +#warning TODO +#else CASE("test_insert") { Array* ds = Array::create(7, 5, 8); @@ -358,6 +365,7 @@ CASE("test_insert") { delete ds; } +#endif CASE("test_insert_throw") { Array* ds = Array::create(7, 5, 8); @@ -365,6 +373,9 @@ CASE("test_insert_throw") { EXPECT_THROWS_AS(ds->insert(8, 2), eckit::BadParameter); } +#ifndef TODO +#warning TODO +#else CASE("test_wrap_storage") { { Array* ds = Array::create(4, 5, 6); @@ -400,6 +411,7 @@ CASE("test_wrap_storage") { delete ds_ext; } } +#endif CASE("test_storageview") { Array* ds = Array::create(2ul, 3ul, 4ul); @@ -414,6 +426,9 @@ CASE("test_storageview") { delete ds; } +#ifndef TODO +#warning TODO +#else CASE("test_assign") { Array* ds = Array::create(2ul, 3ul, 4ul); auto hv = make_host_view(*ds); @@ -476,6 +491,7 @@ CASE("test_ArrayT") { EXPECT(ds.shape(2) == 4); } } +#endif CASE("test_valid") { @@ -498,6 +514,19 @@ CASE("test_valid") { } } +#ifdef ATLAS_HAVE_ACC +CASE("test_acc_map") { + Array* ds = Array::create(2, 3, 4); +#ifdef ATLAS_HAVE_ACC + EXPECT( ds->accMap() == true ); + EXPECT( ds->accMap() == true ); +#else + EXPECT( ds->accMap() == false ); +#endif + +} +#endif + //----------------------------------------------------------------------------- } // namespace test From 7789b8e3c713fe78f41b5874543c97c9996fcd6f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 8 Nov 2017 20:24:08 +0000 Subject: [PATCH 154/355] Work on test_array --- src/tests/array/test_array.cc | 44 ++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index ed486d2f7..b0adb6159 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -14,6 +14,18 @@ #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" +#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA +#define PADDED 1 +#else +#define PADDED 0 +#endif +#else +#define PADDED 0 +#endif +#define NOT_PADDED 1-PADDED + + using namespace atlas::array; using namespace eckit::testing; @@ -105,9 +117,6 @@ CASE("test_localview") { delete ds; } -#ifndef TODO -# warning TODO -#else #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE CASE("test_array_shape") { ArrayShape as{2, 3}; @@ -124,8 +133,7 @@ CASE("test_array_shape") { EXPECT(ds->rank() == 2); EXPECT(ds->stride(0) == gt_hv.storage_info().stride<0>()); EXPECT(ds->stride(1) == gt_hv.storage_info().stride<1>()); - EXPECT(ds->contiguous() == true); - + EXPECT(ds->contiguous() == NOT_PADDED ); delete ds; } #endif @@ -141,10 +149,11 @@ CASE("test_spec") { EXPECT(ds->spec().shapef()[1] == 5); EXPECT(ds->spec().shapef()[2] == 4); - EXPECT(ds->spec().strides()[0] == 6 * 5); - EXPECT(ds->spec().strides()[1] == 6); - EXPECT(ds->spec().strides()[2] == 1); - + if( NOT_PADDED ) { + EXPECT(ds->spec().strides()[0] == 6 * 5); + EXPECT(ds->spec().strides()[1] == 6); + EXPECT(ds->spec().strides()[2] == 1); + } EXPECT(ds->spec().hasDefaultLayout() == true); delete ds; @@ -160,9 +169,11 @@ CASE("test_spec_layout") { EXPECT(ds->spec().shapef()[0] == 6); EXPECT(ds->spec().shapef()[1] == 5); EXPECT(ds->spec().shapef()[2] == 4); - EXPECT(ds->spec().strides()[0] == 6 * 5); - EXPECT(ds->spec().strides()[1] == 6); - EXPECT(ds->spec().strides()[2] == 1); + if( NOT_PADDED ) { + EXPECT(ds->spec().strides()[0] == 6 * 5); + EXPECT(ds->spec().strides()[1] == 6); + EXPECT(ds->spec().strides()[2] == 1); + } EXPECT(ds->spec().hasDefaultLayout() == true); EXPECT(ds->spec().layout()[0] == 0); EXPECT(ds->spec().layout()[1] == 1); @@ -182,9 +193,11 @@ CASE("test_spec_layout_rev") { EXPECT(ds->spec().shapef()[0] == 4); EXPECT(ds->spec().shapef()[1] == 5); EXPECT(ds->spec().shapef()[2] == 6); - EXPECT(ds->spec().strides()[0] == 1); - EXPECT(ds->spec().strides()[1] == 4); - EXPECT(ds->spec().strides()[2] == 4 * 5); + if( NOT_PADDED ) { + EXPECT(ds->spec().strides()[0] == 1); + EXPECT(ds->spec().strides()[1] == 4); + EXPECT(ds->spec().strides()[2] == 4 * 5); + } EXPECT(ds->spec().hasDefaultLayout() == false); EXPECT(ds->spec().layout()[0] == 2); EXPECT(ds->spec().layout()[1] == 1); @@ -196,7 +209,6 @@ CASE("test_spec_layout_rev") { EXPECT_THROWS_AS( Array::create(make_shape(4,5,6,2),make_layout(0,1,3,2)), eckit::BadParameter ); } #endif -#endif CASE("test_resize_throw") { Array* ds = Array::create(32, 5, 33); From 7f5cc6163835ff63f9f0d85e8d0dcac1be2b4e65 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 8 Nov 2017 20:42:45 +0000 Subject: [PATCH 155/355] LocalView::assign works with padded data --- src/atlas/array/LocalView.cc | 7 ++--- src/atlas/array/helpers/ArrayAssigner.h | 13 ++++++--- src/tests/array/test_array.cc | 35 +++++++++++-------------- 3 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/atlas/array/LocalView.cc b/src/atlas/array/LocalView.cc index 58be6202a..ec0d32840 100644 --- a/src/atlas/array/LocalView.cc +++ b/src/atlas/array/LocalView.cc @@ -11,6 +11,7 @@ #include #include "eckit/exception/Exceptions.h" #include "atlas/array/LocalView.h" +#include "atlas/array/helpers/ArrayAssigner.h" //------------------------------------------------------------------------------------------------------ @@ -21,11 +22,7 @@ namespace array { template void LocalView::assign(const value_type& value) { - ASSERT( contiguous() ); - value_type* raw_data = data(); - for( size_t j=0; j::apply(*this,value); } //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/array/helpers/ArrayAssigner.h b/src/atlas/array/helpers/ArrayAssigner.h index 9582dfeea..6ed37753c 100644 --- a/src/atlas/array/helpers/ArrayAssigner.h +++ b/src/atlas/array/helpers/ArrayAssigner.h @@ -29,8 +29,8 @@ struct array_assigner; // Recursive function to apply value to every index template struct array_assigner_impl { - template - static void apply(ArrayView& arr, Value value, DimIndex... idxs) { + template + static void apply(View& arr, Value value, DimIndex... idxs) { for(size_t i=0; i < arr.shape(Dim); ++i) { array_assigner_impl::apply( arr, value, idxs..., i ); } @@ -40,8 +40,8 @@ struct array_assigner_impl { // End of recursion when Dim == Rank template struct array_assigner_impl { - template - static void apply(ArrayView& arr, Value value, DimIndex... idxs) { + template + static void apply(View& arr, Value value, DimIndex... idxs) { arr(idxs...) = value; } }; @@ -62,6 +62,11 @@ struct array_assigner { // Note: no need to apply variadic pack (idxs...) } + static void apply(LocalView& arr, Value value) { + array_assigner_impl::apply( arr, value ); + // Note: no need to apply variadic pack (idxs...) + } + }; //------------------------------------------------------------------------------ diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index b0adb6159..90e19412b 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -438,9 +438,6 @@ CASE("test_storageview") { delete ds; } -#ifndef TODO -#warning TODO -#else CASE("test_assign") { Array* ds = Array::create(2ul, 3ul, 4ul); auto hv = make_host_view(*ds); @@ -456,13 +453,6 @@ CASE("test_assign") { EXPECT(hv(1, 2, 3) == 5.0); EXPECT(lv(2, 3) == 5.0); - auto sv = make_storageview(*ds); - sv.assign(0.); - - EXPECT(hv(0, 2, 3) == 0.); - EXPECT(hv(1, 2, 3) == 0.); - EXPECT(lv(2, 3) == 0.); - delete ds; } @@ -471,9 +461,11 @@ CASE("test_ArrayT") { ArrayT ds(2, 3, 4); EXPECT(ds.size() == 2 * 3 * 4); - EXPECT(ds.stride(0) == 3 * 4); - EXPECT(ds.stride(1) == 4); - EXPECT(ds.stride(2) == 1); + if( NOT_PADDED ) { + EXPECT(ds.stride(0) == 3 * 4); + EXPECT(ds.stride(1) == 4); + EXPECT(ds.stride(2) == 1); + } EXPECT(ds.shape(0) == 2); EXPECT(ds.shape(1) == 3); EXPECT(ds.shape(2) == 4); @@ -483,9 +475,11 @@ CASE("test_ArrayT") { ArrayT ds(make_shape(2, 3, 4)); EXPECT(ds.size() == 2 * 3 * 4); - EXPECT(ds.stride(0) == 3 * 4); - EXPECT(ds.stride(1) == 4); - EXPECT(ds.stride(2) == 1); + if( NOT_PADDED ) { + EXPECT(ds.stride(0) == 3 * 4); + EXPECT(ds.stride(1) == 4); + EXPECT(ds.stride(2) == 1); + } EXPECT(ds.shape(0) == 2); EXPECT(ds.shape(1) == 3); EXPECT(ds.shape(2) == 4); @@ -495,15 +489,16 @@ CASE("test_ArrayT") { ArrayT ds(ArraySpec(make_shape(2, 3, 4))); EXPECT(ds.size() == 2 * 3 * 4); - EXPECT(ds.stride(0) == 3 * 4); - EXPECT(ds.stride(1) == 4); - EXPECT(ds.stride(2) == 1); + if( NOT_PADDED ) { + EXPECT(ds.stride(0) == 3 * 4); + EXPECT(ds.stride(1) == 4); + EXPECT(ds.stride(2) == 1); + } EXPECT(ds.shape(0) == 2); EXPECT(ds.shape(1) == 3); EXPECT(ds.shape(2) == 4); } } -#endif CASE("test_valid") { From b48205efd6309621a0404a47ee0ccc717dbcf143 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 8 Nov 2017 22:28:37 +0000 Subject: [PATCH 156/355] Fix Array::insert with CUDA backend --- src/atlas/array/gridtools/GridToolsArray.cc | 6 ++++- src/atlas/array/helpers/ArrayInitializer.h | 27 ++++++++++++++++----- src/tests/array/test_array.cc | 13 +++++----- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index e81cc91e9..936a87257 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -344,9 +344,12 @@ bool ArrayT::accMap() const { //------------------------------------------------------------------------------ template void ArrayT::insert(size_t idx1, size_t size1) { - if(!hostNeedsUpdate()) { + + if( hostNeedsUpdate() ) { cloneFromDevice(); } + if( not hasDefaultLayout() ) + NOTIMP; ArrayShape nshape = shape(); if(idx1 > nshape[0]) { @@ -357,6 +360,7 @@ template void ArrayT::insert(size_t idx1, size_t size1) Array* resized = Array::create(nshape); array_initializer_partitioned<0>::apply( *this, *resized, idx1, size1); + replace(*resized); delete resized; } diff --git a/src/atlas/array/helpers/ArrayInitializer.h b/src/atlas/array/helpers/ArrayInitializer.h index c4627ab8f..4f200fae9 100644 --- a/src/atlas/array/helpers/ArrayInitializer.h +++ b/src/atlas/array/helpers/ArrayInitializer.h @@ -103,10 +103,10 @@ struct array_initializer_partitioned_val_impl { pos, offset); } - template + template static void apply( ArrayView const&& orig, ArrayView&& dest, - unsigned int pos, unsigned int offset, DimIndex... idxs) { + unsigned int pos, unsigned int offset, DimIndexPair... idxs) { for(size_t i=0; i < orig.shape(Dim); ++i) { unsigned int displ = i; @@ -123,14 +123,29 @@ struct array_initializer_partitioned_val_impl { }; + +// template< typename stdarray > +// inline std::string print_array(const stdarray& v) +// { +// std::stringstream s; +// s << "[ "; +// for( int j=0; j struct array_initializer_partitioned_val_impl { - template - static void apply(ArrayView const&& orig, ArrayView&& dest, unsigned int pos, unsigned int offset, DimIndex... idxs) { - dest(std::get<1>(idxs)...) = orig(std::get<0>(idxs)...); - } + template + static void apply(ArrayView const&& orig, ArrayView&& dest, unsigned int pos, unsigned int offset, DimIndexPair... idxs) { +// Log::info() << print_array(std::array{std::get<0>(idxs)...}) << " --> " << print_array(std::array{std::get<1>(idxs)...}) << " " << orig(std::get<0>(idxs)...) << std::endl; + dest(std::get<1>(idxs)...) = orig(std::get<0>(idxs)...); + } }; //------------------------------------------------------------------------------ diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 90e19412b..2b09525ba 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -338,13 +338,14 @@ CASE("test_resize_shape") { delete ds; } -#ifndef TODO -#warning TODO -#else CASE("test_insert") { Array* ds = Array::create(7, 5, 8); - atlas::array::ArrayView hv = make_host_view(*ds); + EXPECT( ds->hostNeedsUpdate() == false ); + auto hv = make_host_view(*ds); + hv.assign(-1.); + + EXPECT( hv(0,0,0) == -1. ); hv(1, 3, 3) = 1.5; hv(2, 3, 3) = 2.5; hv(3, 3, 3) = 3.5; @@ -359,12 +360,13 @@ CASE("test_insert") { EXPECT(ds->spec().rank() == 3); EXPECT(ds->spec().size() == 9 * 5 * 8); - atlas::array::ArrayView hv2 = make_host_view(*ds); + auto hv2 = make_host_view(*ds); // currently we have no mechanism to invalidate the old views after an insertion into the Array // The original gt data store is deleted and replaced, but the former atlas::array::ArrayView keeps a pointer to it // wihtout noticing it has been deleted #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE + // Following statement seems to contradict previous comment EXPECT(hv.valid() == false); #endif @@ -377,7 +379,6 @@ CASE("test_insert") { delete ds; } -#endif CASE("test_insert_throw") { Array* ds = Array::create(7, 5, 8); From 18f31e6f176d23ad7dd9f31d6a5639630d5c9e49 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 8 Nov 2017 23:12:22 +0000 Subject: [PATCH 157/355] Fixed test_array with CUDA backend --- src/atlas/array/gridtools/GridToolsArray.cc | 54 +-- src/atlas/array/native/NativeArray.cc | 55 +-- .../meshgenerator/StructuredMeshGenerator.cc | 1 - src/tests/array/test_array.cc | 15 +- src/tests/mesh/test_rgg.cc | 1 + src/tests/util/test_array.cc | 459 ------------------ src/tests/util/test_array_kernel.cu | 53 -- 7 files changed, 6 insertions(+), 632 deletions(-) delete mode 100644 src/tests/util/test_array.cc delete mode 100644 src/tests/util/test_array_kernel.cu diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 936a87257..eea678430 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -266,58 +266,6 @@ Array* Array::create(DataType datatype, const ArrayShape& shape, const ArrayLayo return 0; } -// template DATATYPE const* Array::host_data() const { -// return array::make_host_storageview(*this).data(); -// } -// template DATATYPE* Array::host_data() { -// return array::make_host_storageview(*this).data(); -// } -// template DATATYPE const* Array::device_data() const { -// return array::make_device_storageview(*this).data(); -// } -// template DATATYPE* Array::device_data() { -// return array::make_device_storageview(*this).data(); -// } -// template DATATYPE const* Array::data() const { -// return array::make_host_storageview(*this).data(); -// } -// template DATATYPE* Array::data() { -// return array::make_host_storageview(*this).data(); -// } - -// template int* Array::host_data(); -// template int const* Array::host_data() const; -// template long* Array::host_data(); -// template long const* Array::host_data() const; -// template long unsigned* Array::host_data(); -// template long unsigned const* Array::host_data() const; -// template float* Array::host_data(); -// template float const* Array::host_data() const; -// template double* Array::host_data(); -// template double const* Array::host_data() const; - -// template int* Array::device_data(); -// template int const* Array::device_data() const; -// template long* Array::device_data(); -// template long const* Array::device_data() const; -// template long unsigned* Array::device_data(); -// template long unsigned const* Array::device_data() const; -// template float* Array::device_data(); -// template float const* Array::device_data() const; -// template double* Array::device_data(); -// template double const* Array::device_data() const; - -// template int* Array::data(); -// template int const* Array::data() const; -// template long* Array::data(); -// template long const* Array::data() const; -// template long unsigned* Array::data(); -// template long unsigned const* Array::data() const; -// template float* Array::data(); -// template float const* Array::data() const; -// template double* Array::data(); -// template double const* Array::data() const; - //------------------------------------------------------------------------------ template @@ -360,7 +308,7 @@ template void ArrayT::insert(size_t idx1, size_t size1) Array* resized = Array::create(nshape); array_initializer_partitioned<0>::apply( *this, *resized, idx1, size1); - + replace(*resized); delete resized; } diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index 72c1cadcb..f54eed1d7 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -178,7 +178,7 @@ template< typename Value > void ArrayT::dump(std::ostream& os) const { if( not contiguous() ) NOTIMP; - Value *data = make_storageview(*this).data(); + const Value *data = data(); for(size_t i=0; i::accMap() const { return false; } -// template DATATYPE const* Array::host_data() const { -// return array::make_host_storageview(*this).data(); -// } -// template DATATYPE* Array::host_data() { -// return array::make_host_storageview(*this).data(); -// } -// template DATATYPE const* Array::device_data() const { -// return array::make_device_storageview(*this).data(); -// } -// template DATATYPE* Array::device_data() { -// return array::make_device_storageview(*this).data(); -// } -// template DATATYPE const* Array::data() const { -// return array::make_host_storageview(*this).data(); -// } -// template DATATYPE* Array::data() { -// return array::make_host_storageview(*this).data(); -// } - -template int* Array::host_data(); -template int const* Array::host_data() const; -template long* Array::host_data(); -template long const* Array::host_data() const; -template long unsigned* Array::host_data(); -template long unsigned const* Array::host_data() const; -template float* Array::host_data(); -template float const* Array::host_data() const; -template double* Array::host_data(); -template double const* Array::host_data() const; - -template int* Array::device_data(); -template int const* Array::device_data() const; -template long* Array::device_data(); -template long const* Array::device_data() const; -template long unsigned* Array::device_data(); -template long unsigned const* Array::device_data() const; -template float* Array::device_data(); -template float const* Array::device_data() const; -template double* Array::device_data(); -template double const* Array::device_data() const; - -template int* Array::data(); -template int const* Array::data() const; -template long* Array::data(); -template long const* Array::data() const; -template long unsigned* Array::data(); -template long unsigned const* Array::data() const; -template float* Array::data(); -template float const* Array::data() const; -template double* Array::data(); -template double const* Array::data() const; - - //------------------------------------------------------------------------------ template Array* Array::create(size_t); diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index d4681ac99..bf64e078e 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -1358,7 +1358,6 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons } } } - generate_global_element_numbering( mesh ); } diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 2b09525ba..66cfd3d07 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -386,9 +386,6 @@ CASE("test_insert_throw") { EXPECT_THROWS_AS(ds->insert(8, 2), eckit::BadParameter); } -#ifndef TODO -#warning TODO -#else CASE("test_wrap_storage") { { Array* ds = Array::create(4, 5, 6); @@ -407,24 +404,18 @@ CASE("test_wrap_storage") { delete ds_ext; } { - Array* ds = Array::create(4, 5, 6); - - atlas::array::ArrayView hv = make_host_view(*ds); - - hv(2, 3, 3) = 2.5; - + std::vector v(4*5*6, 0.); + v[ 2*(5*6) + 3*6 + 3 ] = 2.5; ArrayShape shape{4, 5, 6}; - Array* ds_ext = Array::wrap(hv.data(), shape); + Array* ds_ext = Array::wrap(v.data(), shape); atlas::array::ArrayView hv_ext = make_host_view(*ds_ext); EXPECT(hv_ext(2, 3, 3) == 2.5); - delete ds; delete ds_ext; } } -#endif CASE("test_storageview") { Array* ds = Array::create(2ul, 3ul, 4ul); diff --git a/src/tests/mesh/test_rgg.cc b/src/tests/mesh/test_rgg.cc index 0e165bb85..0528166c4 100644 --- a/src/tests/mesh/test_rgg.cc +++ b/src/tests/mesh/test_rgg.cc @@ -391,6 +391,7 @@ CASE( "test_rgg_meshgen_many_parts" ) ("part",p) ("include_pole",false) ("3d",false) ); + ATLAS_DEBUG_HERE(); Mesh m = generate( grid ); ATLAS_DEBUG_HERE(); diff --git a/src/tests/util/test_array.cc b/src/tests/util/test_array.cc deleted file mode 100644 index d7ee408a2..000000000 --- a/src/tests/util/test_array.cc +++ /dev/null @@ -1,459 +0,0 @@ -/* - * (C) Copyright 1996-2016 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 "atlas/array.h" -#include "atlas/array/MakeView.h" -#include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" - -using namespace eckit::testing; -using namespace atlas::array; - -namespace atlas { -namespace test { - -//----------------------------------------------------------------------------- - -CASE("test_array") { - Array* ds = Array::create(4ul); - auto hv = atlas::array::gridtools::make_gt_host_view(*ds); - hv(3) = 4.5; - - array::ArrayView atlas_hv = make_host_view(*ds); - - EXPECT(hv(3) == 4.5); - EXPECT(atlas_hv(3) == 4.5); - - delete ds; -} - -CASE("test_array_zero_size") { - Array* ds = Array::create(0); - - EXPECT(ds->size() == 0); - delete ds; -} - -CASE("test_create") { - Array* ds = Array::create(array::DataType::create(), ArrayShape({4, 3})); - auto hv = atlas::array::gridtools::make_gt_host_view(*ds); - hv(3, 2) = 4; - - array::ArrayView atlas_hv = make_host_view(*ds); - - EXPECT(hv(3, 2) == 4); - EXPECT(atlas_hv(3, 2) == 4); - - delete ds; -} - -CASE("test_make_view") { - Array* ds = Array::create(4ul); - auto hv = atlas::array::gridtools::make_gt_host_view(*ds); - hv(3) = 4.5; - - array::ArrayView atlas_hv = make_view(*ds); - - EXPECT(hv(3) == 4.5); - EXPECT(atlas_hv(3) == 4.5); - - delete ds; -} - -CASE("test_localview") { - Array* ds = Array::create(8ul, 4ul, 2ul); - auto hv = make_host_view(*ds); - - EXPECT(hv.shape(0) == 8ul); - EXPECT(hv.shape(1) == 4ul); - EXPECT(hv.shape(2) == 2ul); - EXPECT(hv.size() == 8ul * 4ul * 2ul); - - // Initialize fields - for (size_t i = 0; i < ds->shape(0); ++i) { - for (size_t j = 0; j < ds->shape(1); ++j) { - for (size_t k = 0; k < ds->shape(2); ++k) { - hv(i, j, k) = (i * 100) + (j * 10) + (k); - } - } - } - - // Check values - for (size_t i = 0; i < ds->shape(0); ++i) { - LocalView lv = hv.at(i); - for (size_t j = 0; j < lv.shape(0); ++j) { - for (size_t k = 0; k < lv.shape(1); ++k) { - EXPECT(lv(j, k) == (i * 100) + (j * 10) + (k)); - } - } - } - - delete ds; -} - -CASE("test_array_shape") { - ArrayShape as{2, 3}; - Array* ds = Array::create(as); - auto hv = atlas::array::gridtools::make_gt_host_view(*ds); - array::ArrayView atlas_hv = make_host_view(*ds); - - hv(1, 1) = 4.5; - - EXPECT(hv(1, 1) == 4.5); - EXPECT(atlas_hv(1, 1) == 4.5); - - EXPECT(ds->size() == 6); - EXPECT(ds->rank() == 2); - EXPECT(ds->stride(0) == 3); - EXPECT(ds->stride(1) == 1); - EXPECT(ds->contiguous() == true); - - delete ds; -} - -CASE("test_spec") { - Array* ds = Array::create(4, 5, 6); - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 4 * 5 * 6); - EXPECT(ds->spec().shape()[0] == 4); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 6); - EXPECT(ds->spec().shapef()[0] == 6); - EXPECT(ds->spec().shapef()[1] == 5); - EXPECT(ds->spec().shapef()[2] == 4); - - EXPECT(ds->spec().strides()[0] == 6 * 5); - EXPECT(ds->spec().strides()[1] == 6); - EXPECT(ds->spec().strides()[2] == 1); - - EXPECT(ds->spec().hasDefaultLayout()); - - delete ds; -} - -CASE("test_spec_layout") { - Array* ds = Array::create(make_shape(4,5,6), make_layout(0,1,2)); - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 4 * 5 * 6); - EXPECT(ds->spec().shape()[0] == 4); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 6); - EXPECT(ds->spec().shapef()[0] == 6); - EXPECT(ds->spec().shapef()[1] == 5); - EXPECT(ds->spec().shapef()[2] == 4); - EXPECT(ds->spec().strides()[0] == 6 * 5); - EXPECT(ds->spec().strides()[1] == 6); - EXPECT(ds->spec().strides()[2] == 1); - EXPECT(ds->spec().hasDefaultLayout()); - EXPECT(ds->spec().layout()[0] == 0); - EXPECT(ds->spec().layout()[1] == 1); - EXPECT(ds->spec().layout()[2] == 2); - - delete ds; -} - -CASE("test_spec_layout_rev") { - Array* ds = Array::create(make_shape(4,5,6),make_layout(2,1,0)); - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 4 * 5 * 6); - EXPECT(ds->spec().shape()[0] == 4); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 6); - EXPECT(ds->spec().shapef()[0] == 4); - EXPECT(ds->spec().shapef()[1] == 5); - EXPECT(ds->spec().shapef()[2] == 6); - EXPECT(ds->spec().strides()[0] == 1); - EXPECT(ds->spec().strides()[1] == 4); - EXPECT(ds->spec().strides()[2] == 4 * 5); - EXPECT(!ds->spec().hasDefaultLayout()); - EXPECT(ds->spec().layout()[0] == 2); - EXPECT(ds->spec().layout()[1] == 1); - EXPECT(ds->spec().layout()[2] == 0); - - delete ds; - - - EXPECT_THROWS_AS( Array::create(make_shape(4,5,6,2),make_layout(0,1,3,2)), eckit::BadParameter ); -} - -CASE("test_resize_throw") { - Array* ds = Array::create(32, 5, 33); - - EXPECT_NO_THROW(ds->resize(32, 5, 33)); - EXPECT_THROWS_AS(ds->resize(32, 4, 33), eckit::BadParameter); - EXPECT_THROWS_AS(ds->resize(32, 5, 32), eckit::BadParameter); - EXPECT_THROWS_AS(ds->resize(32, 5, 33, 4), eckit::BadParameter); - - delete ds; -} - -CASE("test_resize") { - { - Array* ds = Array::create(0); - EXPECT(ds->size() == 0); - ds->resize(0); - delete ds; - } - - { - Array* ds = Array::create(7, 5, 8); - { - array::ArrayView hv = make_host_view(*ds); - hv(3, 3, 3) = 4.5; - hv(6, 4, 7) = 7.5; - } - ds->resize(32, 5, 33); - array::ArrayView hv = make_host_view(*ds); - - EXPECT(ds->spec().shape()[0] == 32); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 33); - - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 32 * 5 * 33); - - EXPECT(hv(3, 3, 3) == 4.5); - EXPECT(hv(6, 4, 7) == 7.5); - - delete ds; - } - - { - Array* ds = Array::create(3, 2); - { - array::ArrayView hv = make_host_view(*ds); - hv(2, 1) = 4; - hv(1, 1) = 7; - } - ds->resize(6, 2); - array::ArrayView hv = make_host_view(*ds); - - EXPECT(ds->spec().shape()[0] == 6); - EXPECT(ds->spec().shape()[1] == 2); - - EXPECT(ds->spec().rank() == 2); - EXPECT(ds->spec().size() == 6 * 2); - - EXPECT(hv(2, 1) == 4); - EXPECT(hv(1, 1) == 7); - - delete ds; - } - // test the resize with wrap - { - int vals[6] = {3, 4, 6, 7, 5, 4}; - - Array* ds = Array::wrap(vals, array::ArrayShape{3, 2}); - { - array::ArrayView hv = make_host_view(*ds); - hv(2, 1) = 4; - hv(1, 1) = 7; - } - ds->resize(6, 2); - array::ArrayView hv = make_host_view(*ds); - - EXPECT(ds->spec().shape()[0] == 6); - EXPECT(ds->spec().shape()[1] == 2); - - EXPECT(ds->spec().rank() == 2); - EXPECT(ds->spec().size() == 6 * 2); - - EXPECT(hv(2, 1) == 4); - EXPECT(hv(1, 1) == 7); - - delete ds; - } -} - -CASE("test_resize_shape") { - Array* ds = Array::create(7, 5, 8); - { - array::ArrayView hv = make_host_view(*ds); - hv(3, 3, 3) = 4.5; - hv(6, 4, 7) = 7.5; - } - ds->resize(ArrayShape{32, 5, 33}); - - array::ArrayView hv = make_host_view(*ds); - EXPECT(ds->spec().shape()[0] == 32); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 33); - - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 32 * 5 * 33); - - EXPECT(hv(3, 3, 3) == 4.5); - EXPECT(hv(6, 4, 7) == 7.5); - - delete ds; -} - -CASE("test_insert") { - Array* ds = Array::create(7, 5, 8); - - array::ArrayView hv = make_host_view(*ds); - hv(1, 3, 3) = 1.5; - hv(2, 3, 3) = 2.5; - hv(3, 3, 3) = 3.5; - hv(6, 4, 7) = 6.5; - - ds->insert(3, 2); - - EXPECT(ds->spec().shape()[0] == 9); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 8); - - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 9 * 5 * 8); - - array::ArrayView hv2 = make_host_view(*ds); - - // currently we have no mechanism to invalidate the old views after an insertion into the Array - // The original gt data store is deleted and replaced, but the former ArrayView keeps a pointer to it - // wihtout noticing it has been deleted - EXPECT(hv.valid() == true); - EXPECT(hv2.valid() == true); - - EXPECT(hv2(1, 3, 3) == 1.5); - EXPECT(hv2(2, 3, 3) == 2.5); - EXPECT(hv2(5, 3, 3) == 3.5); - EXPECT(hv2(8, 4, 7) == 6.5); - - delete ds; -} - -CASE("test_insert_throw") { - Array* ds = Array::create(7, 5, 8); - - EXPECT_THROWS_AS(ds->insert(8, 2), eckit::BadParameter); -} - -CASE("test_wrap_storage") { - { - Array* ds = Array::create(4, 5, 6); - - array::ArrayView hv = make_host_view(*ds); - - hv(2, 3, 3) = 2.5; - - Array* ds_ext = Array::wrap(hv.data(), ds->spec()); - - array::ArrayView hv_ext = make_host_view(*ds_ext); - - EXPECT(hv_ext(2, 3, 3) == 2.5); - - delete ds; - delete ds_ext; - } - { - Array* ds = Array::create(4, 5, 6); - - array::ArrayView hv = make_host_view(*ds); - - hv(2, 3, 3) = 2.5; - - ArrayShape shape{4, 5, 6}; - Array* ds_ext = Array::wrap(hv.data(), shape); - - array::ArrayView hv_ext = make_host_view(*ds_ext); - - EXPECT(hv_ext(2, 3, 3) == 2.5); - - delete ds; - delete ds_ext; - } -} - -CASE("test_storageview") { - Array* ds = Array::create(2ul, 3ul, 4ul); - auto hv = make_host_view(*ds); - - EXPECT(hv.size() == 2 * 3 * 4); - - auto sv = make_storageview(*ds); - - EXPECT(sv.size() == 2 * 3 * 4); - - delete ds; -} - -CASE("test_assign") { - Array* ds = Array::create(2ul, 3ul, 4ul); - auto hv = make_host_view(*ds); - - hv.assign(2.5); - - EXPECT(hv(1, 2, 3) == 2.5); - - auto lv = hv.at(1); - lv.assign(5.0); - - EXPECT(hv(0, 2, 3) == 2.5); - EXPECT(hv(1, 2, 3) == 5.0); - EXPECT(lv(2, 3) == 5.0); - - auto sv = make_storageview(*ds); - sv.assign(0.); - - EXPECT(hv(0, 2, 3) == 0.); - EXPECT(hv(1, 2, 3) == 0.); - EXPECT(lv(2, 3) == 0.); - - delete ds; -} - -CASE("test_ArrayT") { - { - ArrayT ds(2, 3, 4); - - EXPECT(ds.size() == 2 * 3 * 4); - EXPECT(ds.stride(0) == 3 * 4); - EXPECT(ds.stride(1) == 4); - EXPECT(ds.stride(2) == 1); - EXPECT(ds.shape(0) == 2); - EXPECT(ds.shape(1) == 3); - EXPECT(ds.shape(2) == 4); - } - - { - ArrayT ds(make_shape(2, 3, 4)); - - EXPECT(ds.size() == 2 * 3 * 4); - EXPECT(ds.stride(0) == 3 * 4); - EXPECT(ds.stride(1) == 4); - EXPECT(ds.stride(2) == 1); - EXPECT(ds.shape(0) == 2); - EXPECT(ds.shape(1) == 3); - EXPECT(ds.shape(2) == 4); - } - - { - ArrayT ds(ArraySpec(make_shape(2, 3, 4))); - - EXPECT(ds.size() == 2 * 3 * 4); - EXPECT(ds.stride(0) == 3 * 4); - EXPECT(ds.stride(1) == 4); - EXPECT(ds.stride(2) == 1); - EXPECT(ds.shape(0) == 2); - EXPECT(ds.shape(1) == 3); - EXPECT(ds.shape(2) == 4); - } -} - -//----------------------------------------------------------------------------- - -} // namespace test -} // namespace atlas - - -int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); -} \ No newline at end of file diff --git a/src/tests/util/test_array_kernel.cu b/src/tests/util/test_array_kernel.cu deleted file mode 100644 index b802ceec8..000000000 --- a/src/tests/util/test_array_kernel.cu +++ /dev/null @@ -1,53 +0,0 @@ -/* - * (C) Copyright 1996-2016 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. - */ - -#define BOOST_TEST_MODULE TestArrayKernel -#include -#include "ecbuild/boost_test_framework.h" -#include "atlas/array.h" -#include "atlas/array/MakeView.h" -#include "atlas/runtime/Log.h" - -using namespace atlas::array; - -namespace atlas { -namespace test { - -template -__global__ -void kernel_ex(ArrayView dv) -{ - dv(3, 3, 3) += 1; -} - -BOOST_AUTO_TEST_CASE( test_array ) -{ - Array* ds = Array::create(4ul, 4ul, 4ul); - ArrayView hv = make_host_view(*ds); - hv(3, 3, 3) = 4.5; - - ds->cloneToDevice(); - - auto cv = make_device_view(*ds); - - kernel_ex<<<1,1>>>(cv); - - cudaDeviceSynchronize(); - - ds->cloneFromDevice(); - ds->reactivateHostWriteViews(); - - BOOST_CHECK_EQUAL( hv(3, 3, 3) , 5.5 ); - - delete ds; -} - -} -} From ad014b72f0308dcfa6b5ef5ec526d1b868822e2a Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 9 Nov 2017 01:39:31 +0000 Subject: [PATCH 158/355] Cosmetic todo's --- src/atlas/array/ArrayShape.h | 9 +++++ src/atlas/array/ArraySpec.cc | 36 +++++++++++++++---- src/atlas/array/ArraySpec.h | 12 ++++--- src/atlas/array/gridtools/GridToolsArray.cc | 2 +- .../array/gridtools/GridToolsArrayHelpers.h | 7 ++-- src/tests/array/test_array.cc | 2 +- 6 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/atlas/array/ArrayShape.h b/src/atlas/array/ArrayShape.h index ce52a878c..f81d7dd64 100644 --- a/src/atlas/array/ArrayShape.h +++ b/src/atlas/array/ArrayShape.h @@ -18,6 +18,15 @@ namespace atlas { namespace array { +class ArrayAlignment { +public: + ArrayAlignment() : alignment_(1) {} + ArrayAlignment( int alignment ) : alignment_(alignment) {} + operator int() const { return alignment_; } +private: + int alignment_; +}; + class ArrayShape : public std::vector { private: using Base = std::vector; diff --git a/src/atlas/array/ArraySpec.cc b/src/atlas/array/ArraySpec.cc index 49d9b9e78..2af2489b6 100644 --- a/src/atlas/array/ArraySpec.cc +++ b/src/atlas/array/ArraySpec.cc @@ -15,6 +15,16 @@ namespace atlas { namespace array { +namespace { + size_t compute_allocated_size( size_t size, int alignment ) { + int div = size/alignment; + int mod = size%alignment; + size_t _allocated_size = div*alignment; + if( mod > 0 ) _allocated_size += alignment; + return _allocated_size; + } +} + ArraySpec::ArraySpec(): size_(), rank_(), @@ -24,8 +34,14 @@ ArraySpec::ArraySpec(): { } -ArraySpec::ArraySpec( const ArrayShape& shape ) +ArraySpec::ArraySpec( const ArrayShape& shape ) : + ArraySpec( shape, ArrayAlignment() ) { +} + +ArraySpec::ArraySpec( const ArrayShape& shape, ArrayAlignment&& alignment ) { + if( int(alignment) > 1 ) NOTIMP; // innermost dimension needs to be padded + rank_ = shape.size(); size_ = 1; shape_.resize(rank_); @@ -37,12 +53,16 @@ ArraySpec::ArraySpec( const ArrayShape& shape ) layout_[j] = j; size_ *= shape_[j]; } - allocated_size_ = size_; + allocated_size_ = compute_allocated_size(size_,alignment); contiguous_ = true; default_layout_ = true; }; -ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides ) +ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides ) : + ArraySpec( shape, strides, ArrayAlignment() ) { +} + +ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, ArrayAlignment&& alignment ) { if( shape.size() != strides.size() ) throw eckit::BadParameter("dimensions of shape and stride don't match", Here()); @@ -58,12 +78,16 @@ ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides ) layout_[j] = j; size_ *= shape_[j]; } - allocated_size_ = shape_[0]*strides_[0]; + allocated_size_ = compute_allocated_size(shape_[0]*strides_[0],alignment); contiguous_ = (size_ == allocated_size_); default_layout_ = true; } -ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, const ArrayLayout& layout ) +ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, const ArrayLayout& layout ) : + ArraySpec( shape, strides, layout, ArrayAlignment() ) { +} + +ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, const ArrayLayout& layout, ArrayAlignment&& alignment ) { if( shape.size() != strides.size() ) throw eckit::BadParameter("dimensions of shape and stride don't match", Here()); @@ -83,7 +107,7 @@ ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, cons default_layout_ = false; } } - allocated_size_ = shape_[0]*strides_[0]; + allocated_size_ = compute_allocated_size(shape_[layout_[0]]*strides_[layout_[0]],alignment); contiguous_ = (size_ == allocated_size_); } diff --git a/src/atlas/array/ArraySpec.h b/src/atlas/array/ArraySpec.h index 41cbd40f0..fb6a8f81a 100644 --- a/src/atlas/array/ArraySpec.h +++ b/src/atlas/array/ArraySpec.h @@ -27,9 +27,11 @@ class ArraySpec { private: size_t size_; size_t rank_; + size_t allocated_size_; ArrayShape shape_; ArrayStrides strides_; ArrayLayout layout_; + ArrayAlignment alignment_; mutable std::vector shapef_; mutable std::vector stridesf_; bool contiguous_; @@ -39,20 +41,20 @@ class ArraySpec { ArraySpec( const ArrayShape& ); ArraySpec( const ArrayShape&, const ArrayStrides& ); ArraySpec( const ArrayShape&, const ArrayStrides&, const ArrayLayout& ); - size_t allocated_size() const { return allocated_size_; } + ArraySpec( const ArrayShape&, ArrayAlignment&& ); + ArraySpec( const ArrayShape&, const ArrayStrides&, ArrayAlignment&& ); + ArraySpec( const ArrayShape&, const ArrayStrides&, const ArrayLayout&, ArrayAlignment&& ); + size_t allocatedSize() const { return allocated_size_; } size_t size() const { return size_; } size_t rank() const { return rank_; } const ArrayShape& shape() const { return shape_; } + const ArrayAlignment& alignment() const { return alignment_; } const ArrayStrides& strides() const { return strides_; } const ArrayLayout& layout() const { return layout_; } const std::vector& shapef() const; const std::vector& stridesf() const; bool contiguous() const { return contiguous_; } bool hasDefaultLayout() const { return default_layout_; } - -/// todo: make private - size_t allocated_size_; - }; //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index eea678430..5daa2e1ef 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -282,7 +282,7 @@ template bool ArrayT::accMap() const { if( not acc_map_ ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA && defined(ATLAS_HAVE_ACC) - atlas_acc_map_data( (void*) host_data(), (void*) device_data(), spec_.allocated_size() ); + atlas_acc_map_data( (void*) host_data(), (void*) device_data(), spec_.allocatedSize() ); acc_map_ = true; #endif } diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index e706f8d82..de04c8141 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -237,6 +237,7 @@ struct default_layout_t { if(gt_data_store_ptr->valid()) { auto storage_info_ptr = gt_data_store_ptr->get_storage_info_ptr().get(); using Layout = typename DataStore::storage_info_t::layout_t; + using Alignment = typename DataStore::storage_info_t::alignment_t; using seq = my_apply_gt_integer_sequence::type>; @@ -248,10 +249,10 @@ struct default_layout_t { storage_info_ptr), seq::template apply< ArrayLayout, - get_layout_map_component::template get_component>() + get_layout_map_component::template get_component>(), + ArrayAlignment( Alignment::value ) ); - spec.allocated_size_ = storage_info_ptr->padded_total_length(); - ASSERT( spec.allocated_size() == storage_info_ptr->padded_total_length() ); + ASSERT( spec.allocatedSize() == storage_info_ptr->padded_total_length() ); return spec; } else { return ArraySpec( make_shape({dims...}), make_null_strides(typename ::gridtools::make_gt_integer_sequence::type())); diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 66cfd3d07..4774ce9f5 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -173,6 +173,7 @@ CASE("test_spec_layout") { EXPECT(ds->spec().strides()[0] == 6 * 5); EXPECT(ds->spec().strides()[1] == 6); EXPECT(ds->spec().strides()[2] == 1); + EXPECT(ds->spec().size() == ds->spec().allocatedSize()); } EXPECT(ds->spec().hasDefaultLayout() == true); EXPECT(ds->spec().layout()[0] == 0); @@ -205,7 +206,6 @@ CASE("test_spec_layout_rev") { delete ds; - EXPECT_THROWS_AS( Array::create(make_shape(4,5,6,2),make_layout(0,1,3,2)), eckit::BadParameter ); } #endif From fe3d0e6feda54b8bb922a0b9b4176a582c8ca2ca Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 9 Nov 2017 12:47:32 +0000 Subject: [PATCH 159/355] Working sandbox example using OpenACC. Victory --- src/atlas/array/gridtools/GridToolsArray.cc | 2 +- src/atlas_acc_support/CMakeLists.txt | 1 + .../autogenerated/atlas_Field_module_fypp.F90 | 426 ++++++++---------- src/atlas_f/field/atlas_Field_module.F90 | 27 +- src/sandbox/CMakeLists.txt | 2 +- src/sandbox/fortran_acc_fields/CMakeLists.txt | 18 + .../fortran_acc_fields/atlas-acc-fields.F90 | 44 ++ 7 files changed, 260 insertions(+), 260 deletions(-) create mode 100644 src/sandbox/fortran_acc_fields/CMakeLists.txt create mode 100644 src/sandbox/fortran_acc_fields/atlas-acc-fields.F90 diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 5daa2e1ef..25b15a51c 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -282,7 +282,7 @@ template bool ArrayT::accMap() const { if( not acc_map_ ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA && defined(ATLAS_HAVE_ACC) - atlas_acc_map_data( (void*) host_data(), (void*) device_data(), spec_.allocatedSize() ); + atlas_acc_map_data( (void*) host_data(), (void*) device_data(), spec_.allocatedSize()*sizeof(Value) ); acc_map_ = true; #endif } diff --git a/src/atlas_acc_support/CMakeLists.txt b/src/atlas_acc_support/CMakeLists.txt index 8229ac045..7c264fe22 100644 --- a/src/atlas_acc_support/CMakeLists.txt +++ b/src/atlas_acc_support/CMakeLists.txt @@ -60,3 +60,4 @@ if( ATLAS_HAVE_ACC ) endif() set( ATLAS_HAVE_ACC ${ATLAS_HAVE_ACC} PARENT_SCOPE ) +set( ACC_Fortran_FLAGS ${ACC_Fortran_FLAGS} PARENT_SCOPE ) \ No newline at end of file diff --git a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 index 2b33e5381..0aa652414 100644 --- a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 +++ b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 @@ -366,32 +366,29 @@ subroutine array_c_to_f_int32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr integer(c_int), pointer, intent(out) :: array_fptr(:) - integer(c_int), pointer :: tmp(:,:) + integer(c_int), pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:1) - integer :: accumulated, factor, j + integer :: eshape(1) + integer :: j if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1)) + array_fptr => tmp(1:shape(1)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -403,32 +400,29 @@ subroutine array_c_to_f_int64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr integer(c_long), pointer, intent(out) :: array_fptr(:) - integer(c_long), pointer :: tmp(:,:) + integer(c_long), pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:1) - integer :: accumulated, factor, j + integer :: eshape(1) + integer :: j if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1)) + array_fptr => tmp(1:shape(1)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -440,32 +434,29 @@ subroutine array_c_to_f_real32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr real(c_float), pointer, intent(out) :: array_fptr(:) - real(c_float), pointer :: tmp(:,:) + real(c_float), pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:1) - integer :: accumulated, factor, j + integer :: eshape(1) + integer :: j if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1)) + array_fptr => tmp(1:shape(1)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -477,32 +468,29 @@ subroutine array_c_to_f_real64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr real(c_double), pointer, intent(out) :: array_fptr(:) - real(c_double), pointer :: tmp(:,:) + real(c_double), pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:1) - integer :: accumulated, factor, j + integer :: eshape(1) + integer :: j if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1)) + array_fptr => tmp(1:shape(1)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -514,32 +502,29 @@ subroutine array_c_to_f_logical32_r1(array_cptr,rank,shape_cptr,strides_cptr,arr type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr logical, pointer, intent(out) :: array_fptr(:) - logical, pointer :: tmp(:,:) + logical, pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:1) - integer :: accumulated, factor, j + integer :: eshape(1) + integer :: j if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1)) + array_fptr => tmp(1:shape(1)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -551,32 +536,29 @@ subroutine array_c_to_f_int32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr integer(c_int), pointer, intent(out) :: array_fptr(:,:) - integer(c_int), pointer :: tmp(:,:,:) + integer(c_int), pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:2) - integer :: accumulated, factor, j + integer :: eshape(2) + integer :: j if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2)) + array_fptr => tmp(1:shape(1),1:shape(2)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -588,32 +570,29 @@ subroutine array_c_to_f_int64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr integer(c_long), pointer, intent(out) :: array_fptr(:,:) - integer(c_long), pointer :: tmp(:,:,:) + integer(c_long), pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:2) - integer :: accumulated, factor, j + integer :: eshape(2) + integer :: j if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2)) + array_fptr => tmp(1:shape(1),1:shape(2)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -625,32 +604,29 @@ subroutine array_c_to_f_real32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr real(c_float), pointer, intent(out) :: array_fptr(:,:) - real(c_float), pointer :: tmp(:,:,:) + real(c_float), pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:2) - integer :: accumulated, factor, j + integer :: eshape(2) + integer :: j if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2)) + array_fptr => tmp(1:shape(1),1:shape(2)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -662,32 +638,29 @@ subroutine array_c_to_f_real64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr real(c_double), pointer, intent(out) :: array_fptr(:,:) - real(c_double), pointer :: tmp(:,:,:) + real(c_double), pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:2) - integer :: accumulated, factor, j + integer :: eshape(2) + integer :: j if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2)) + array_fptr => tmp(1:shape(1),1:shape(2)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -699,32 +672,29 @@ subroutine array_c_to_f_logical32_r2(array_cptr,rank,shape_cptr,strides_cptr,arr type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr logical, pointer, intent(out) :: array_fptr(:,:) - logical, pointer :: tmp(:,:,:) + logical, pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:2) - integer :: accumulated, factor, j + integer :: eshape(2) + integer :: j if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2)) + array_fptr => tmp(1:shape(1),1:shape(2)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -736,32 +706,29 @@ subroutine array_c_to_f_int32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr integer(c_int), pointer, intent(out) :: array_fptr(:,:,:) - integer(c_int), pointer :: tmp(:,:,:,:) + integer(c_int), pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:3) - integer :: accumulated, factor, j + integer :: eshape(3) + integer :: j if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -773,32 +740,29 @@ subroutine array_c_to_f_int64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr integer(c_long), pointer, intent(out) :: array_fptr(:,:,:) - integer(c_long), pointer :: tmp(:,:,:,:) + integer(c_long), pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:3) - integer :: accumulated, factor, j + integer :: eshape(3) + integer :: j if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -810,32 +774,29 @@ subroutine array_c_to_f_real32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr real(c_float), pointer, intent(out) :: array_fptr(:,:,:) - real(c_float), pointer :: tmp(:,:,:,:) + real(c_float), pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:3) - integer :: accumulated, factor, j + integer :: eshape(3) + integer :: j if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -847,32 +808,29 @@ subroutine array_c_to_f_real64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr real(c_double), pointer, intent(out) :: array_fptr(:,:,:) - real(c_double), pointer :: tmp(:,:,:,:) + real(c_double), pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:3) - integer :: accumulated, factor, j + integer :: eshape(3) + integer :: j if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -884,32 +842,29 @@ subroutine array_c_to_f_logical32_r3(array_cptr,rank,shape_cptr,strides_cptr,arr type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr logical, pointer, intent(out) :: array_fptr(:,:,:) - logical, pointer :: tmp(:,:,:,:) + logical, pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:3) - integer :: accumulated, factor, j + integer :: eshape(3) + integer :: j if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -921,32 +876,29 @@ subroutine array_c_to_f_int32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr integer(c_int), pointer, intent(out) :: array_fptr(:,:,:,:) - integer(c_int), pointer :: tmp(:,:,:,:,:) + integer(c_int), pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:4) - integer :: accumulated, factor, j + integer :: eshape(4) + integer :: j if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3),1:shape(4)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3),1:shape(4)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -958,32 +910,29 @@ subroutine array_c_to_f_int64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr integer(c_long), pointer, intent(out) :: array_fptr(:,:,:,:) - integer(c_long), pointer :: tmp(:,:,:,:,:) + integer(c_long), pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:4) - integer :: accumulated, factor, j + integer :: eshape(4) + integer :: j if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3),1:shape(4)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3),1:shape(4)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -995,32 +944,29 @@ subroutine array_c_to_f_real32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr real(c_float), pointer, intent(out) :: array_fptr(:,:,:,:) - real(c_float), pointer :: tmp(:,:,:,:,:) + real(c_float), pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:4) - integer :: accumulated, factor, j + integer :: eshape(4) + integer :: j if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3),1:shape(4)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3),1:shape(4)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -1032,32 +978,29 @@ subroutine array_c_to_f_real64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr real(c_double), pointer, intent(out) :: array_fptr(:,:,:,:) - real(c_double), pointer :: tmp(:,:,:,:,:) + real(c_double), pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:4) - integer :: accumulated, factor, j + integer :: eshape(4) + integer :: j if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3),1:shape(4)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3),1:shape(4)) end subroutine + !------------------------------------------------------------------------------- !------------------------------------------------------------------------------- @@ -1069,32 +1012,29 @@ subroutine array_c_to_f_logical32_r4(array_cptr,rank,shape_cptr,strides_cptr,arr type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr logical, pointer, intent(out) :: array_fptr(:,:,:,:) - logical, pointer :: tmp(:,:,:,:,:) + logical, pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:4) - integer :: accumulated, factor, j + integer :: eshape(4) + integer :: j if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3),1:shape(4)) + array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3),1:shape(4)) end subroutine + !------------------------------------------------------------------------------- subroutine access_host_data_int32_r1(this, field) @@ -2252,7 +2192,7 @@ integer function atlas_real(kind) else if (kind == c_float) then atlas_real = ATLAS_KIND_REAL32 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",275)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",272)) end if end function @@ -2268,7 +2208,7 @@ integer function atlas_integer(kind) else if (kind == c_long) then atlas_integer = ATLAS_KIND_INT64 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",291)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",288)) end if end if end function @@ -2294,7 +2234,7 @@ function atlas_data_type(kind) else if( kind == ATLAS_KIND_REAL64 ) then atlas_data_type = "real64" else - call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",317)) + call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",314)) endif end function diff --git a/src/atlas_f/field/atlas_Field_module.F90 b/src/atlas_f/field/atlas_Field_module.F90 index e1831ddea..cb3721666 100644 --- a/src/atlas_f/field/atlas_Field_module.F90 +++ b/src/atlas_f/field/atlas_Field_module.F90 @@ -162,32 +162,29 @@ subroutine array_c_to_f_${dtype}$_r${rank}$(array_cptr,rank,shape_cptr,strides_c type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr ${ftype}$, pointer, intent(out) :: array_fptr(${dim[rank]}$) - ${ftype}$, pointer :: tmp(${dim[rank+1]}$) + ${ftype}$, pointer :: tmp(${dim[rank]}$) integer, pointer :: shape(:) integer, pointer :: strides(:) - integer :: eshape(0:${rank}$) - integer :: accumulated, factor, j + integer :: eshape(${rank}$) + integer :: j if( rank /= ${rank}$ ) call ${atlas_abort("Rank mismatch")}$ call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - eshape(0)=1 - accumulated = 1 - do j=1,rank - accumulated = accumulated*shape(j) - factor = shape(j)*strides(j)/max(accumulated,1) - eshape(j-1) = eshape(j-1)*factor - eshape(j) = shape(j) - accumulated = accumulated*factor + do j=1,rank-1 + eshape(j) = strides(j+1)/strides(j) enddo + eshape(rank) = shape(rank) + write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) - #{if rank == 1}# array_fptr => tmp(1,1:shape(1)) #{endif}# - #{if rank == 2}# array_fptr => tmp(1,1:shape(1),1:shape(2)) #{endif}# - #{if rank == 3}# array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3)) #{endif}# - #{if rank == 4}# array_fptr => tmp(1,1:shape(1),1:shape(2),1:shape(3),1:shape(4)) #{endif}# + #{if rank == 1}# array_fptr => tmp(1:shape(1)) #{endif}# + #{if rank == 2}# array_fptr => tmp(1:shape(1),1:shape(2)) #{endif}# + #{if rank == 3}# array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3)) #{endif}# + #{if rank == 4}# array_fptr => tmp(1:shape(1),1:shape(2),1:shape(3),1:shape(4)) #{endif}# end subroutine + !------------------------------------------------------------------------------- #:endfor diff --git a/src/sandbox/CMakeLists.txt b/src/sandbox/CMakeLists.txt index b8502a142..88761b2f2 100644 --- a/src/sandbox/CMakeLists.txt +++ b/src/sandbox/CMakeLists.txt @@ -10,7 +10,7 @@ add_subdirectory( fortran_submodule ) add_subdirectory( fortran_modinc ) add_subdirectory( fortran_object ) add_subdirectory( example_fortran ) - +add_subdirectory( fortran_acc_fields ) add_subdirectory( interpolation ) add_subdirectory( interpolation-fortran ) add_subdirectory( grid_distribution ) diff --git a/src/sandbox/fortran_acc_fields/CMakeLists.txt b/src/sandbox/fortran_acc_fields/CMakeLists.txt new file mode 100644 index 000000000..83e2f1888 --- /dev/null +++ b/src/sandbox/fortran_acc_fields/CMakeLists.txt @@ -0,0 +1,18 @@ +# (C) Copyright 1996-2017 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. + +if( ATLAS_HAVE_ACC ) + ecbuild_add_executable( + TARGET atlas-acc-fields + SOURCES atlas-acc-fields.F90 + LIBS atlas_f + NOINSTALL + ) + target_compile_options( atlas-acc-fields PUBLIC ${ACC_Fortran_FLAGS} ) + target_link_libraries( atlas-acc-fields ${ACC_Fortran_FLAGS} ) +endif() diff --git a/src/sandbox/fortran_acc_fields/atlas-acc-fields.F90 b/src/sandbox/fortran_acc_fields/atlas-acc-fields.F90 new file mode 100644 index 000000000..aeda9073b --- /dev/null +++ b/src/sandbox/fortran_acc_fields/atlas-acc-fields.F90 @@ -0,0 +1,44 @@ +program atlas_acc_fields +use atlas_module +implicit none + +type(atlas_Field) :: field +integer(4), pointer :: view(:,:,:) +integer :: i,j,k +integer, parameter :: Ni = 2 +integer, parameter :: Nj = 3 +integer, parameter :: Nk = 5 + +call atlas_library%initialise() +field = atlas_Field(kind=atlas_integer(4),shape=[Nk,Nj,Ni]) +call field%data(view) + +!$acc data present(view) +!$acc kernels +do i=1,Ni + do j=1,Nj + do k=1,Nk + view(k,j,i) = i*100*100 + j*100 + k + enddo + enddo +enddo +!$acc end kernels +!$acc end data + + +! We can either use the acc directive, or +! use the field's API to update the host +! !$acc update host(view) +call field%clone_from_device() + + +! Note that field%sync_host_device() is not working here... +! Because internal state of host_needs_update has not been changed + +do i=1,Ni + write(0,*) " " + write(0,*) "i=",i + write(0,*) view(:,:,i) +enddo + +end program From 8f4f8d419b1f5fd2236ec34261649a5aa46f8ff2 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 9 Nov 2017 17:23:27 +0000 Subject: [PATCH 160/355] Finetune ACC configuration --- CMakeLists.txt | 62 +++++++++++++++++++--------- project_summary.cmake | 52 ++++++++++++++++++----- src/atlas_acc_support/CMakeLists.txt | 32 -------------- 3 files changed, 83 insertions(+), 63 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2cb6a45f8..1296d3457 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,16 +119,15 @@ if( HAVE_TESSELATION ) endif() endif() -### FIND GRIDTOOLS STORAGE +### GridTools storage module + ecbuild_add_option( FEATURE GRIDTOOLS_STORAGE DESCRIPTION "Arrays internally use GridTools storage layer" REQUIRED_PACKAGES "PROJECT gridtools_storage" ) - if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) - set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST 1 ) set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA 0 ) @@ -140,6 +139,30 @@ if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) endif() +### OpenACC + +set( ATLAS_ACC_CAPABLE FALSE ) +if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) + if( CMAKE_Fortran_COMPILER_ID MATCHES "PGI" ) + set( ATLAS_ACC_CAPABLE TRUE ) + endif() +endif() + +ecbuild_add_option( FEATURE ACC + DESCRIPTION "OpenACC capable data structures" + CONDITION ATLAS_ACC_CAPABLE ) + +if( ATLAS_HAVE_ACC ) + if( CMAKE_Fortran_COMPILER_ID MATCHES "PGI" ) + set( ACC_Fortran_FLAGS -acc -ta=tesla,cuda${CUDA_VERSION},nordc ) + set( ACC_C_FLAGS ${ACC_Fortran_FLAGS} ) + find_program( ACC_C_COMPILER NAMES pgcc HINTS ${PGI_DIR} ENV PGI_DIR PATH_SUFFIXES bin ) + if( NOT ACC_C_COMPILER ) + ecbuild_error( "Could not find OpenACC capable C compiler" ) + endif() + endif() +endif() + ### Eigen ecbuild_add_option( FEATURE EIGEN @@ -215,23 +238,22 @@ add_subdirectory( src ) set( ATLAS_URL "https://software.ecmwf.int/wiki/display/ATLAS" ) set( ATLAS_DESCRIPTION "Atlas framework for parallel mesh datastructures" ) -#ecbuild_pkgconfig() - -#ecbuild_pkgconfig( -# NAME atlas-c++ -# LANGUAGES CXX -# LIBRARIES atlas -#) - -#if( ATLAS_HAVE_FORTRAN ) -# ecbuild_pkgconfig( -# NAME atlas-fortran -# LANGUAGES Fortran -# LIBRARIES atlas_f -# NO_PRIVATE_INCLUDE_DIRS -# ) -#endif() -ecbuild_warn( "ecbuild needs fixing to enable above with OpenACC imported library" ) +ecbuild_pkgconfig() + +ecbuild_pkgconfig( + NAME atlas-c++ + LANGUAGES CXX + LIBRARIES atlas +) + +if( ATLAS_HAVE_FORTRAN ) + ecbuild_pkgconfig( + NAME atlas-fortran + LANGUAGES Fortran + LIBRARIES atlas_f + NO_PRIVATE_INCLUDE_DIRS + ) +endif() ################################################################################ # documentation diff --git a/project_summary.cmake b/project_summary.cmake index df1ca1b8e..142b40434 100644 --- a/project_summary.cmake +++ b/project_summary.cmake @@ -8,24 +8,54 @@ if( MPI_CXX_FOUND AND MPI_Fortan_FOUND ) - message( STATUS "MPI") + ecbuild_info( "MPI" ) - message( STATUS " MPI_CXX_COMPILER : [${MPI_CXX_COMPILER}]") - message( STATUS " MPI_CXX_INCLUDE_PATH : [${MPI_CXX_INCLUDE_PATH}]") - message( STATUS " MPI_CXX_LIBRARIES : [${MPI_CXX_LIBRARIES}]") + ecbuild_info( " MPI_CXX_COMPILER : [${MPI_CXX_COMPILER}]" ) + ecbuild_info( " MPI_CXX_INCLUDE_PATH : [${MPI_CXX_INCLUDE_PATH}]" ) + ecbuild_info( " MPI_CXX_LIBRARIES : [${MPI_CXX_LIBRARIES}]" ) - message( STATUS " MPI_Fortan_COMPILER : [${MPI_Fortan_COMPILER}]") - message( STATUS " MPI_Fortan_INCLUDE_PATH : [${MPI_Fortan_INCLUDE_PATH}]") - message( STATUS " MPI_Fortan_LIBRARIES : [${MPI_Fortan_LIBRARIES}]") + ecbuild_info( " MPI_Fortan_COMPILER : [${MPI_Fortan_COMPILER}]" ) + ecbuild_info( " MPI_Fortan_INCLUDE_PATH : [${MPI_Fortan_INCLUDE_PATH}]" ) + ecbuild_info( " MPI_Fortan_LIBRARIES : [${MPI_Fortan_LIBRARIES}]" ) - message( STATUS " MPIEXEC : [${MPIEXEC}]") + ecbuild_info( " MPIEXEC : [${MPIEXEC}]" ) endif() if( CGAL_FOUND ) - message( STATUS "CGAL (${CGAL_VERSION})") - message( STATUS " includes : [${CGAL_INCLUDE_DIRS}]") - message( STATUS " libs : [${CGAL_LIBRARY}]") + ecbuild_info( "CGAL (${CGAL_VERSION})" ) + ecbuild_info( " includes : [${CGAL_INCLUDE_DIRS}]" ) + ecbuild_info( " libs : [${CGAL_LIBRARY}]" ) endif() + +if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) + + ecbuild_info( "GRIDTOOLS_STORAGE" ) + if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST ) + ecbuild_info( " BACKEND : [HOST]" ) + endif() + if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) + ecbuild_info( " BACKEND : [CUDA]" ) + endif() + +endif() + +if( CUDA_FOUND ) + + ecbuild_info( "CUDA (${CUDA_VERSION})" ) + ecbuild_info( " CUDA_NVCC_COMPILER : [${CUDA_NVCC_EXECUTABLE}]" ) + ecbuild_info( " CUDA_CUDART_LIBRARY : [${CUDA_CUDART_LIBRARY}]" ) + ecbuild_info( " CUDA_NVCC_FLAGS : [${CUDA_NVCC_FLAGS}]" ) + +endif() + +if( ATLAS_HAVE_ACC ) + + ecbuild_info( "ACC" ) + ecbuild_info( " ACC_C_COMPILER : [${ACC_C_COMPILER}]" ) + ecbuild_info( " ACC_C_FLAGS : [${ACC_C_FLAGS}]" ) + ecbuild_info( " ACC_Fortran_FLAGS : [${ACC_Fortran_FLAGS}]" ) + +endif() \ No newline at end of file diff --git a/src/atlas_acc_support/CMakeLists.txt b/src/atlas_acc_support/CMakeLists.txt index 7c264fe22..678f23fa7 100644 --- a/src/atlas_acc_support/CMakeLists.txt +++ b/src/atlas_acc_support/CMakeLists.txt @@ -1,36 +1,7 @@ -set( ATLAS_HAVE_ACC 0 ) -set( ENABLE_ACC ON CACHE STRING "Enable OpenACC" ) - -if( ENABLE_ACC AND NOT CUDA_FOUND ) - - ecbuild_warn( "OpenACC support not enabled as CUDA was not found" ) - -elseif( ENABLE_ACC ) - - if( CMAKE_Fortran_COMPILER_ID MATCHES "PGI" ) - set( ACC_Fortran_FLAGS -acc -ta=tesla,cuda${CUDA_VERSION},nordc ) - set( ACC_C_FLAGS ${ACC_Fortran_FLAGS} ) - set( ACC_C_COMPILER pgcc ) - set( ATLAS_HAVE_ACC 1 ) - elseif( CMAKE_Fortran_COMPILER_ID MATCHES "Cray" ) - ecbuild_warn( "OpenACC support not enabled as we did not yet implement it for Cray" ) - else() - ecbuild_warn( "OpenACC support not enabled as we did not yet implement it for ${CMAKE_Fortran_COMPILER_ID}" ) - endif() - if( ATLAS_HAVE_ACC ) - ecbuild_info( "OpenACC enabled" ) - endif() - -endif() - if( ATLAS_HAVE_ACC ) if( NOT (CMAKE_C_COMPILER_ID MATCHES ${CMAKE_Fortran_COMPILER_ID}) ) - - foreach( _dir ${ACC_C_INCLUDE_DIRS} ) - set( ACC_C_INCLUDE ${ACC_C_INCLUDE} -I${_dir} ) - endforeach() add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/lib/libatlas_acc_support.so ${CMAKE_CURRENT_BINARY_DIR}/atlas_acc_map_data.c.o COMMAND ${ACC_C_COMPILER} ${ACC_C_FLAGS} ${ACC_C_INCLUDE} -fPIC -o ${CMAKE_CURRENT_BINARY_DIR}/atlas_acc_map_data.c.o @@ -58,6 +29,3 @@ if( ATLAS_HAVE_ACC ) endif() endif() - -set( ATLAS_HAVE_ACC ${ATLAS_HAVE_ACC} PARENT_SCOPE ) -set( ACC_Fortran_FLAGS ${ACC_Fortran_FLAGS} PARENT_SCOPE ) \ No newline at end of file From 41062d9dbbbbe40716b35691047e5a7657be132e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 9 Nov 2017 19:36:36 +0000 Subject: [PATCH 161/355] Fix atlas_test_field_gpu --- .../autogenerated/atlas_Field_module_fypp.F90 | 26 +------ src/atlas_f/field/atlas_Field_module.F90 | 1 - src/tests/array/CMakeLists.txt | 2 - src/tests/field/CMakeLists.txt | 6 +- src/tests/field/external_acc_routine.F90 | 12 +++ src/tests/field/fctest_field_gpu.F90 | 73 ++++++++++++------- 6 files changed, 65 insertions(+), 55 deletions(-) create mode 100644 src/tests/field/external_acc_routine.F90 diff --git a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 index 0aa652414..985388aa7 100644 --- a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 +++ b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 @@ -381,7 +381,6 @@ subroutine array_c_to_f_int32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1)) @@ -415,7 +414,6 @@ subroutine array_c_to_f_int64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1)) @@ -449,7 +447,6 @@ subroutine array_c_to_f_real32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1)) @@ -483,7 +480,6 @@ subroutine array_c_to_f_real64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1)) @@ -517,7 +513,6 @@ subroutine array_c_to_f_logical32_r1(array_cptr,rank,shape_cptr,strides_cptr,arr eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1)) @@ -551,7 +546,6 @@ subroutine array_c_to_f_int32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1),1:shape(2)) @@ -585,7 +579,6 @@ subroutine array_c_to_f_int64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1),1:shape(2)) @@ -619,7 +612,6 @@ subroutine array_c_to_f_real32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1),1:shape(2)) @@ -653,7 +645,6 @@ subroutine array_c_to_f_real64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1),1:shape(2)) @@ -687,7 +678,6 @@ subroutine array_c_to_f_logical32_r2(array_cptr,rank,shape_cptr,strides_cptr,arr eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) array_fptr => tmp(1:shape(1),1:shape(2)) @@ -721,7 +711,6 @@ subroutine array_c_to_f_int32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -755,7 +744,6 @@ subroutine array_c_to_f_int64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -789,7 +777,6 @@ subroutine array_c_to_f_real32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -823,7 +810,6 @@ subroutine array_c_to_f_real64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -857,7 +843,6 @@ subroutine array_c_to_f_logical32_r3(array_cptr,rank,shape_cptr,strides_cptr,arr eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -891,7 +876,6 @@ subroutine array_c_to_f_int32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -925,7 +909,6 @@ subroutine array_c_to_f_int64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -959,7 +942,6 @@ subroutine array_c_to_f_real32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -993,7 +975,6 @@ subroutine array_c_to_f_real64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -1027,7 +1008,6 @@ subroutine array_c_to_f_logical32_r4(array_cptr,rank,shape_cptr,strides_cptr,arr eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -2192,7 +2172,7 @@ integer function atlas_real(kind) else if (kind == c_float) then atlas_real = ATLAS_KIND_REAL32 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",272)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",271)) end if end function @@ -2208,7 +2188,7 @@ integer function atlas_integer(kind) else if (kind == c_long) then atlas_integer = ATLAS_KIND_INT64 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",288)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",287)) end if end if end function @@ -2234,7 +2214,7 @@ function atlas_data_type(kind) else if( kind == ATLAS_KIND_REAL64 ) then atlas_data_type = "real64" else - call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",314)) + call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",313)) endif end function diff --git a/src/atlas_f/field/atlas_Field_module.F90 b/src/atlas_f/field/atlas_Field_module.F90 index cb3721666..d24eaa8d0 100644 --- a/src/atlas_f/field/atlas_Field_module.F90 +++ b/src/atlas_f/field/atlas_Field_module.F90 @@ -177,7 +177,6 @@ subroutine array_c_to_f_${dtype}$_r${rank}$(array_cptr,rank,shape_cptr,strides_c eshape(j) = strides(j+1)/strides(j) enddo eshape(rank) = shape(rank) - write(0,*) "padded shape = ",eshape call c_f_pointer ( array_cptr , tmp , shape=eshape ) #{if rank == 1}# array_fptr => tmp(1:shape(1)) #{endif}# #{if rank == 2}# array_fptr => tmp(1:shape(1),1:shape(2)) #{endif}# diff --git a/src/tests/array/CMakeLists.txt b/src/tests/array/CMakeLists.txt index 2ac6336cc..f32483fa4 100644 --- a/src/tests/array/CMakeLists.txt +++ b/src/tests/array/CMakeLists.txt @@ -22,13 +22,11 @@ endif() atlas_add_cuda_test( TARGET atlas_test_array_kernel - BOOST SOURCES test_array_kernel.cu LIBS atlas ) atlas_add_cuda_test( TARGET atlas_test_vector_kernel - BOOST SOURCES test_vector_kernel.cu LIBS atlas ) diff --git a/src/tests/field/CMakeLists.txt b/src/tests/field/CMakeLists.txt index 2941bf6fa..69e88b4d1 100644 --- a/src/tests/field/CMakeLists.txt +++ b/src/tests/field/CMakeLists.txt @@ -18,9 +18,13 @@ if( HAVE_FCTEST ) add_fctest( TARGET atlas_fctest_field_gpu CONDITION ATLAS_HAVE_GRIDTOOLS_STORAGE AND ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA LINKER_LANGUAGE Fortran - SOURCES fctest_field_gpu.F90 + SOURCES fctest_field_gpu.F90 external_acc_routine.F90 LIBS atlas_f ) + if( TARGET atlas_fctest_field_gpu ) + target_compile_options( atlas_fctest_field_gpu PUBLIC ${ACC_Fortran_FLAGS} ) + target_link_libraries( atlas_fctest_field_gpu ${ACC_Fortran_FLAGS} ) + endif() endif() diff --git a/src/tests/field/external_acc_routine.F90 b/src/tests/field/external_acc_routine.F90 new file mode 100644 index 000000000..12a8e2a6f --- /dev/null +++ b/src/tests/field/external_acc_routine.F90 @@ -0,0 +1,12 @@ +subroutine external_acc_routine(view) + + implicit none + real(4), intent(inout) :: view(:,:) + + !$acc data present(view) + !$acc kernels + view(1,1) = 4. + !$acc end kernels + !$acc end data + +end subroutine external_acc_routine \ No newline at end of file diff --git a/src/tests/field/fctest_field_gpu.F90 b/src/tests/field/fctest_field_gpu.F90 index 2ff51a17b..2ba719cad 100644 --- a/src/tests/field/fctest_field_gpu.F90 +++ b/src/tests/field/fctest_field_gpu.F90 @@ -11,6 +11,8 @@ #include "fckit/fctest.h" + + ! ----------------------------------------------------------------------------- module fcta_Field_gpu_fxt @@ -20,22 +22,22 @@ module fcta_Field_gpu_fxt contains -end module - +subroutine module_acc_routine(view) -subroutine test_res(ie, je, v1, vres) implicit none - integer :: ie, je - real(8), intent(in) :: v1(ie, je) - real(8), intent(out) :: vres - integer :: i,j + real(4), intent(inout) :: view(:,:) - !$acc kernels deviceptr(v1) copyout(vres) - vres = v1(1,1) - !$acc end kernels + !$acc data present(view) + !$acc kernels + view(1,1) = 4. + !$acc end kernels + !$acc end data -end subroutine test_res +end subroutine module_acc_routine +end module + +! ----------------------------------------------------------------------------- ! ----------------------------------------------------------------------------- @@ -56,38 +58,53 @@ end subroutine test_res ! ----------------------------------------------------------------------------- TEST( test_host_data ) +implicit none type(atlas_Field) :: field -real(8), pointer :: host(:,:) -real(8), pointer :: device_ptr(:,:) -real(8),pointer :: v1(:, :) -real(8) :: vres +real(4), pointer :: view(:,:) -field = atlas_Field(kind=atlas_real(8),shape=[10,5]) +!!! WARNING !!! Without this interface, there is a runtime error !!! +interface + subroutine external_acc_routine(view) + real(4), intent(inout) :: view(:,:) + end subroutine external_acc_routine +end interface -FCTEST_CHECK( .not. field%host_needs_update() ) -FCTEST_CHECK( field%device_needs_update() ) +field = atlas_Field(kind=atlas_real(8),shape=[5,3]) +call field%data(view) +view(:,:) = 0 +view(1,1) = 1 call field%clone_to_device() -call field%host_data(host) -call field%device_data(device_ptr) -call test_res(10,5,device_ptr, vres) +!$acc data present(view) +!$acc kernels +view(1,1) = 2. +!$acc end kernels +!$acc end data +FCTEST_CHECK_EQUAL( view(1,1), 1. ) +call field%clone_from_device() +FCTEST_CHECK_EQUAL( view(1,1), 2. ) -!! acc kernels deviceptr(v1) copyout(vres) -! v1(2,2) = 3.5 -! vres = 2!v1(2,2) -!! acc end kernels +view(1,1) = 3. -!FCTEST_CHECK_EQUAL( val, 3.5_c_float ) +call field%clone_to_device() +write(0,*) "Calling module_acc_routine ..." +call module_acc_routine(view) +write(0,*) "Calling module_acc_routine ... done" -FCTEST_CHECK( .not. field%device_needs_update() ) +write(0,*) "Calling external_acc_routine ..." +call external_acc_routine(view) +write(0,*) "Calling external_acc_routine ... done" + +FCTEST_CHECK_EQUAL( view(1,1), 3. ) +call field%clone_from_device() +FCTEST_CHECK_EQUAL( view(1,1), 4. ) call field%final() END_TEST - ! ----------------------------------------------------------------------------- END_TESTSUITE From 9a5db6b09d1f8db4955cad46567a33dd617e9621 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 9 Nov 2017 19:42:02 +0000 Subject: [PATCH 162/355] Fix atlas_test_footprint --- src/atlas/array/Array.h | 4 ++-- src/atlas/array/gridtools/GridToolsArray.cc | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index ec772287d..3678d4ce8 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -50,7 +50,7 @@ class Array : public eckit::Owned { template static Array* wrap(Value* data, const ArraySpec& spec); - size_t bytes() const { return sizeof_data() * size();} + size_t bytes() const { return sizeof_data() * spec().allocatedSize();} size_t size() const { return spec_.size(); } @@ -110,7 +110,7 @@ class Array : public eckit::Owned { void reactivateHostWriteViews() const { data_store_->reactivateHostWriteViews(); } - ArraySpec& spec() {return spec_;} + const ArraySpec& spec() const {return spec_;} // -- dangerous methods... You're on your own interpreting the raw data template DATATYPE const* host_data() const { return data_store_->hostData(); } diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 25b15a51c..51002b75a 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -272,7 +272,6 @@ template size_t ArrayT::footprint() const { size_t size = sizeof(*this); size += bytes(); - if( not contiguous() ) NOTIMP; return size; } From 540606342bf3b419e5db77db09a3e1f720dc735e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 9 Nov 2017 20:22:57 +0000 Subject: [PATCH 163/355] Add warning to remind us that gridtools storage cuda backend does not support zero-element allocation --- src/atlas/array/gridtools/GridToolsArrayView.cc | 4 +++- src/tests/mesh/test_connectivity.cc | 12 ++++++++++++ src/tests/mesh/test_elements.cc | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index 0f2f29893..11b5cca21 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -95,8 +95,9 @@ void ArrayView::assign(const value_type& value) { template void ArrayView::assign(const std::initializer_list& list) { - ASSERT( contiguous() ); ASSERT( list.size() == size_ ); + + ASSERT( contiguous() ); value_type* raw_data = data(); size_t j(0); for( const value_type& v : list ) { @@ -107,6 +108,7 @@ void ArrayView::assign(const std::initializer_list& list template< typename Value, int Rank > void ArrayView::dump(std::ostream& os) const { ASSERT( contiguous() ); + const value_type* data_ = data(); os << "size: " << size() << " , values: "; os << "[ "; diff --git a/src/tests/mesh/test_connectivity.cc b/src/tests/mesh/test_connectivity.cc index a0968d951..94e974747 100644 --- a/src/tests/mesh/test_connectivity.cc +++ b/src/tests/mesh/test_connectivity.cc @@ -10,6 +10,7 @@ #include "atlas/mesh/Connectivity.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Trace.h" #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" @@ -21,6 +22,17 @@ using namespace atlas::mesh; namespace atlas { namespace test { +#undef CASE +#define CASE(description) \ +void UNIQUE_NAME2(test_, __LINE__) (std::string&); \ +static eckit::testing::TestRegister UNIQUE_NAME2(test_registration_, __LINE__)(description, &UNIQUE_NAME2(test_, __LINE__)); \ +void UNIQUE_NAME2(traced_test_, __LINE__) (std::string&); \ +void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection) { \ + ATLAS_TRACE(description); \ + UNIQUE_NAME2(traced_test_, __LINE__); \ +} \ +void UNIQUE_NAME2(traced_test_, __LINE__) (std::string& _test_subsection) + //----------------------------------------------------------------------------- #ifdef ATLAS_HAVE_FORTRAN diff --git a/src/tests/mesh/test_elements.cc b/src/tests/mesh/test_elements.cc index aa663e4fa..b6aff9941 100644 --- a/src/tests/mesh/test_elements.cc +++ b/src/tests/mesh/test_elements.cc @@ -280,6 +280,7 @@ CASE( "block_connectivity" ) } +#warning TODO: gridtools storage cuda backend cannot allocate zero elements CASE( "zero_elements" ) { HybridElements hybrid_elements; From 0e9425df04029465ca0a07cd01942588d9b6bc25 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 13 Nov 2017 09:02:14 +0100 Subject: [PATCH 164/355] add a boost pp repeat --- src/atlas/parallel/HaloExchange.h | 9 ++----- src/atlas/parallel/HaloExchangeCUDA.cu | 33 ++++++++++++++------------ src/atlas/parallel/HaloExchangeCUDA.h | 2 +- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 79371f348..b065e071a 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -241,9 +241,7 @@ void HaloExchange::pack_send_buffer( const array::ArrayView::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); + halo_packer_cuda::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); } else halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); @@ -261,10 +259,7 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA if(on_device) { - if(ParallelDim != 0) - throw eckit::Exception("Selecting parallel dimension for GPU backend not supported yet"); - - halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); + halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); } else halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 51183ff4d..0edc72885 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -122,8 +122,8 @@ struct get_n_cuda_blocks<1> { } }; -template -void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, +template +void halo_packer_cuda::pack( const int sendcnt, array::SVector const & sendmap, const array::ArrayView& hfield, const array::ArrayView& dfield, array::SVector& send_buffer ) { @@ -155,8 +155,8 @@ void halo_packer_cuda::pack( const int sendcnt, array::SVector< } -template -void halo_packer_cuda::unpack(const int recvcnt, array::SVector const & recvmap, +template +void halo_packer_cuda::unpack(const int recvcnt, array::SVector const & recvmap, const array::SVector &recv_buffer , const array::ArrayView &hfield, array::ArrayView &dfield) { @@ -191,17 +191,20 @@ void halo_packer_cuda::unpack(const int recvcnt, array::SVector } } -#define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ -template class halo_packer_cuda; \ -template class halo_packer_cuda; \ -template class halo_packer_cuda; \ -template class halo_packer_cuda; \ -template class halo_packer_cuda; \ - - EXPLICIT_TEMPLATE_INSTANTIATION(1) - EXPLICIT_TEMPLATE_INSTANTIATION(2) - EXPLICIT_TEMPLATE_INSTANTIATION(3) - EXPLICIT_TEMPLATE_INSTANTIATION(4) +#define EXPLICIT_TEMPLATE_INSTANTIATION(z, ParallelDim, RANK ) \ +template class halo_packer_cuda; \ +template class halo_packer_cuda; \ +template class halo_packer_cuda; \ +template class halo_packer_cuda; \ +template class halo_packer_cuda; \ + +#define EXPLICIT_TEMPLATE_INSTANTIATION_REP(RANK) \ + BOOST_PP_REPEAT(RANK, EXPLICIT_TEMPLATE_INSTANTIATION, RANK) + + EXPLICIT_TEMPLATE_INSTANTIATION_REP(1) + EXPLICIT_TEMPLATE_INSTANTIATION_REP(2) + EXPLICIT_TEMPLATE_INSTANTIATION_REP(3) + EXPLICIT_TEMPLATE_INSTANTIATION_REP(4) } //namespace array } //namespace atlas diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index 27d27b323..4cc81f1cc 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -16,7 +16,7 @@ namespace atlas { namespace parallel { -template +template struct halo_packer_cuda { static void pack( const int sendcnt, array::SVector const & sendmap, const array::ArrayView& hfield, const array::ArrayView& dfield, From a812d3c2f326ccead97ed5a469213195366bea38 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 13 Nov 2017 10:12:27 +0100 Subject: [PATCH 165/355] generalize get_n_cuda_blocks --- src/atlas/parallel/HaloExchangeCUDA.cu | 28 +++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 0edc72885..55eaac60a 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -105,17 +105,35 @@ __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const s halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, 2>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,var1_idx); } -template +template +struct get_first_non_parallel_dim +{ + static_assert((ParallelDim <= RANK), "Error: parallelDim larger than RANK"); + constexpr static int apply() { + return (DimCnt == ParallelDim) ? get_first_non_parallel_dim::apply() : DimCnt; + } +}; + +template +struct get_first_non_parallel_dim +{ + static_assert((ParallelDim <= RANK), "Error: parallelDim larger than RANK"); + constexpr static int apply() { + return -1; + } +}; + +template struct get_n_cuda_blocks { template static unsigned int apply(const array::ArrayView& hfield, const unsigned int block_size_y) { - return (hfield.data_view().template length<1>()+block_size_y-1)/block_size_y; + return (hfield.data_view().template length::apply()>()+block_size_y-1)/block_size_y; } }; template<> -struct get_n_cuda_blocks<1> { +struct get_n_cuda_blocks<0, 1> { template static unsigned int apply(const array::ArrayView& hfield, const unsigned int block_size_y) { return 1; @@ -130,7 +148,7 @@ void halo_packer_cuda::pack( const int sendcnt, ar const unsigned int block_size_x = 32; const unsigned int block_size_y = (RANK==1) ? 1 : 4; - unsigned int nblocks_y = get_n_cuda_blocks::apply(hfield, block_size_y); + unsigned int nblocks_y = get_n_cuda_blocks::apply(hfield, block_size_y); dim3 threads(block_size_x, block_size_y); dim3 blocks((sendcnt+block_size_x-1)/block_size_x, nblocks_y); @@ -163,7 +181,7 @@ void halo_packer_cuda::unpack(const int recvcnt, a const unsigned int block_size_x = 32; const unsigned int block_size_y = (RANK==1) ? 1 : 4; - unsigned int nblocks_y = get_n_cuda_blocks::apply(hfield, block_size_y); + unsigned int nblocks_y = get_n_cuda_blocks::apply(hfield, block_size_y); dim3 threads(block_size_x, block_size_y); dim3 blocks((recvcnt+block_size_x-1)/block_size_x, nblocks_y); From 4d2543fead562f367cdccc9c0f589bb10d93e404 Mon Sep 17 00:00:00 2001 From: carlos osuna Date: Mon, 13 Nov 2017 13:49:19 +0100 Subject: [PATCH 166/355] add more parallel extensions --- src/atlas/parallel/HaloExchangeCUDA.cu | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/atlas/parallel/HaloExchangeCUDA.cu b/src/atlas/parallel/HaloExchangeCUDA.cu index 55eaac60a..945e65e14 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.cu +++ b/src/atlas/parallel/HaloExchangeCUDA.cu @@ -15,7 +15,7 @@ namespace atlas { namespace parallel { -template +template struct get_buffer_index{ template ATLAS_HOST_DEVICE @@ -26,8 +26,8 @@ struct get_buffer_index{ } }; -template<> -struct get_buffer_index<2>{ +template +struct get_buffer_index{ template ATLAS_HOST_DEVICE static size_t apply(const array::ArrayView& field, @@ -36,7 +36,7 @@ struct get_buffer_index<2>{ } }; -template +template __global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, const array::ArrayView field, DATA_TYPE* send_buffer_ptr, const size_t send_buffer_size, const typename std::enable_if::type = 0) { @@ -50,7 +50,7 @@ __global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const siz send_buffer[node_cnt] = field(sendmap[node_cnt]); } -template +template __global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const size_t sendmap_size, const array::ArrayView field, DATA_TYPE* send_buffer_ptr, const size_t send_buffer_size, const typename std::enable_if=2, int>::type = 0) { @@ -62,13 +62,13 @@ __global__ void pack_kernel(const int sendcnt, const int* sendmap_ptr, const si if(node_cnt >= sendcnt || var1_idx >= field.data_view().template length<1>() ) return; - size_t buff_idx = get_buffer_index::apply(field, node_cnt, var1_idx); + size_t buff_idx = get_buffer_index::apply(field, node_cnt, var1_idx); const size_t node_idx = sendmap[node_cnt]; halo_packer_impl<0, (RANK>=3) ? (RANK-2) : 0, 2>::apply(buff_idx, node_idx, field, send_buffer, node_idx,var1_idx); } -template +template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView field, const typename std::enable_if::type = 0) { @@ -85,7 +85,7 @@ __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const s field(node_idx) = recv_buffer[node_cnt]; } -template +template __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const size_t recvmap_size, const DATA_TYPE* recv_buffer_ptr, const size_t recv_buffer_size, array::ArrayView field, const typename std::enable_if=2, int>::type = 0) { @@ -100,7 +100,7 @@ __global__ void unpack_kernel(const int recvcnt, const int* recvmap_ptr, const s const size_t node_idx = recvmap[node_cnt]; - size_t buff_idx = get_buffer_index::apply(field, node_cnt, var1_idx); + size_t buff_idx = get_buffer_index::apply(field, node_cnt, var1_idx); halo_unpacker_impl<0, (RANK>=3) ? (RANK-2) : 0, 2>::apply(buff_idx, node_idx, recv_buffer, field,node_idx,var1_idx); } @@ -159,7 +159,7 @@ void halo_packer_cuda::pack( const int sendcnt, ar throw eckit::Exception(msg); } - pack_kernel<<>>(sendcnt, sendmap.data(), sendmap.size(), dfield, send_buffer.data(), send_buffer.size()); + pack_kernel<<>>(sendcnt, sendmap.data(), sendmap.size(), dfield, send_buffer.data(), send_buffer.size()); err = cudaGetLastError(); if (err != cudaSuccess) throw eckit::Exception("Error launching GPU packing kernel"); @@ -193,7 +193,7 @@ void halo_packer_cuda::unpack(const int recvcnt, a throw eckit::Exception(msg); } - unpack_kernel<<>>(recvcnt, recvmap.data(), recvmap.size(), recv_buffer.data(), recv_buffer.size(), dfield); + unpack_kernel<<>>(recvcnt, recvmap.data(), recvmap.size(), recv_buffer.data(), recv_buffer.size(), dfield); err = cudaGetLastError(); if (err != cudaSuccess) { From 4fb73e1538cf70cee47de970153ac89dec28b557 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 14 Nov 2017 17:09:04 +0000 Subject: [PATCH 167/355] ATLAS-134 First steps in redesigning Trans --- src/atlas/CMakeLists.txt | 7 +- src/atlas/functionspace/EdgeColumns.h | 2 +- src/atlas/functionspace/FunctionSpace.cc | 6 +- src/atlas/functionspace/FunctionSpace.h | 6 +- src/atlas/functionspace/NodeColumns.h | 11 +- src/atlas/functionspace/PointCloud.h | 2 +- src/atlas/functionspace/Spectral.cc | 128 +- src/atlas/functionspace/Spectral.h | 14 +- src/atlas/functionspace/StructuredColumns.h | 7 +- .../detail/partitioner/TransPartitioner.cc | 4 +- src/atlas/output/detail/GmshIO.cc | 4 +- src/atlas/trans/Trans.cc | 1606 +-------------- src/atlas/trans/Trans.h | 534 +---- src/atlas/trans/detail/TransIFS.cc | 1734 +++++++++++++++++ src/atlas/trans/detail/TransIFS.h | 557 ++++++ src/atlas_f/CMakeLists.txt | 4 +- src/atlas_f/trans/atlas_Trans_module.F90 | 341 +--- src/tests/functionspace/test_functionspace.cc | 7 +- src/tests/trans/fctest_trans.F90 | 12 +- .../trans/fctest_trans_invtrans_grad.F90 | 4 +- src/tests/trans/test_trans.cc | 88 +- src/tests/trans/test_trans_invtrans_grad.cc | 19 +- 22 files changed, 2647 insertions(+), 2450 deletions(-) create mode 100644 src/atlas/trans/detail/TransIFS.cc create mode 100644 src/atlas/trans/detail/TransIFS.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index c12e6dd12..6726cf73f 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -316,11 +316,14 @@ numerics/fvm/Method.h numerics/fvm/Method.cc numerics/fvm/Nabla.h numerics/fvm/Nabla.cc + +trans/Trans.h +trans/Trans.cc ) if( ATLAS_HAVE_TRANS ) list( APPEND atlas_numerics_srcs - trans/Trans.h - trans/Trans.cc + trans/detail/TransIFS.h + trans/detail/TransIFS.cc ) endif() diff --git a/src/atlas/functionspace/EdgeColumns.h b/src/atlas/functionspace/EdgeColumns.h index d26d4af3f..bc705e948 100644 --- a/src/atlas/functionspace/EdgeColumns.h +++ b/src/atlas/functionspace/EdgeColumns.h @@ -49,7 +49,7 @@ class EdgeColumns : public FunctionSpaceImpl virtual ~EdgeColumns(); - virtual std::string name() const { return "Edges"; } + virtual std::string type() const { return "Edges"; } size_t nb_edges() const; size_t nb_edges_global() const; // Only on MPI rank 0, will this be different from 0 diff --git a/src/atlas/functionspace/FunctionSpace.cc b/src/atlas/functionspace/FunctionSpace.cc index 9970e90ae..65665a491 100644 --- a/src/atlas/functionspace/FunctionSpace.cc +++ b/src/atlas/functionspace/FunctionSpace.cc @@ -41,7 +41,7 @@ extern "C" { const char* atlas__FunctionSpace__name (FunctionSpaceImpl* This) { ATLAS_ERROR_HANDLING( ASSERT( This ); - return This->name().c_str(); + return This->type().c_str(); ); return 0; } @@ -113,8 +113,8 @@ FunctionSpace::FunctionSpace( const FunctionSpace& functionspace ) : functionspace_( functionspace.functionspace_ ) { } -std::string FunctionSpace::name() const { - return functionspace_->name(); +std::string FunctionSpace::type() const { + return functionspace_->type(); } FunctionSpace::operator bool() const { diff --git a/src/atlas/functionspace/FunctionSpace.h b/src/atlas/functionspace/FunctionSpace.h index 75c10da24..ec90d15db 100644 --- a/src/atlas/functionspace/FunctionSpace.h +++ b/src/atlas/functionspace/FunctionSpace.h @@ -37,7 +37,7 @@ class FunctionSpaceImpl : public eckit::Owned public: FunctionSpaceImpl() {} virtual ~FunctionSpaceImpl() = 0; - virtual std::string name() const = 0; + virtual std::string type() const = 0; virtual operator bool() const { return true; } virtual size_t footprint() const = 0; @@ -102,7 +102,7 @@ class NoFunctionSpace : public FunctionSpaceImpl public: NoFunctionSpace() {} virtual ~NoFunctionSpace() {} - virtual std::string name() const { return "NoFunctionSpace"; } + virtual std::string type() const { return "NoFunctionSpace"; } virtual operator bool() const { return false; } virtual size_t footprint() const { return sizeof(*this); } @@ -144,7 +144,7 @@ class FunctionSpace { FunctionSpace( const Implementation* ); FunctionSpace( const FunctionSpace& ); - std::string name() const; + std::string type() const; operator bool() const; size_t footprint() const; diff --git a/src/atlas/functionspace/NodeColumns.h b/src/atlas/functionspace/NodeColumns.h index bd0841570..2d369efe7 100644 --- a/src/atlas/functionspace/NodeColumns.h +++ b/src/atlas/functionspace/NodeColumns.h @@ -55,19 +55,20 @@ class NodeColumns : public FunctionSpaceImpl virtual ~NodeColumns(); - virtual std::string name() const { return "Nodes"; } + static std::string static_type() { return "NodeColumns"; } + virtual std::string type() const { return static_type(); } size_t nb_nodes() const; size_t nb_nodes_global() const; // All MPI ranks will have same output const Mesh& mesh() const { return mesh_; } - + size_t levels() const { return nb_levels_; } mesh::Nodes& nodes() const { return nodes_; } // -- Field creation methods - + using FunctionSpaceImpl::createField; /// @brief Create a field @@ -242,7 +243,7 @@ class NodeColumns : public FunctionSpaceImpl size_t config_levels(const eckit::Configuration&) const; array::ArrayShape config_shape(const eckit::Configuration&) const; void set_field_metadata(const eckit::Configuration&, Field& ) const; - + size_t footprint() const; private: // data @@ -434,6 +435,8 @@ class NodeColumns : public FunctionSpace NodeColumns( Mesh& mesh ); NodeColumns( Mesh& mesh, const eckit::Configuration & ); + static std::string type() { return detail::NodeColumns::static_type(); } + operator bool() const { return valid(); } bool valid() const { return functionspace_; } diff --git a/src/atlas/functionspace/PointCloud.h b/src/atlas/functionspace/PointCloud.h index b6d012bd5..20b27519c 100644 --- a/src/atlas/functionspace/PointCloud.h +++ b/src/atlas/functionspace/PointCloud.h @@ -28,7 +28,7 @@ class PointCloud : public FunctionSpaceImpl PointCloud(const Field& lonlat); PointCloud(const Field& lonlat, const Field& ghost); virtual ~PointCloud() {} - virtual std::string name() const { return "PointCloud"; } + virtual std::string type() const { return "PointCloud"; } virtual operator bool() const { return true; } virtual size_t footprint() const { return sizeof(*this); } diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index ad36d1012..ae8a087fb 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -20,15 +20,62 @@ #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" #include "atlas/array/MakeView.h" +#include "atlas/trans/Trans.h" #ifdef ATLAS_HAVE_TRANS -#include "atlas/trans/Trans.h" +#include "atlas/trans/detail/TransIFS.h" +namespace { +void trans_check(const int code, const char* msg, const eckit::CodeLocation& location) { + if(code != TRANS_SUCCESS) { + std::stringstream errmsg; + errmsg << "atlas::trans ERROR: " << msg << " failed: \n"; + errmsg << ::trans_error_msg(code); + throw eckit::Exception(errmsg.str(),location); + } +} +#define TRANS_CHECK( CALL ) trans_check(CALL, #CALL, Here() ) +} #endif namespace atlas { namespace functionspace { namespace detail { +#ifdef ATLAS_HAVE_TRANS +class Spectral::Parallelisation { +public: + + 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)); + delete p; + }); + TRANS_CHECK(::trans_new(trans_.get())); + TRANS_CHECK(::trans_set_trunc(trans_.get(),truncation)); + TRANS_CHECK(::trans_use_mpi(parallel::mpi::comm().size()>1)); + TRANS_CHECK(::trans_setup(trans_.get())); + } + + int nb_spectral_coefficients_global() const { return trans_->nspec2g; } + int nb_spectral_coefficients() const { return trans_->nspec2; } + + operator ::Trans_t*() const { return trans_.get(); } + std::shared_ptr<::Trans_t> trans_; +}; +#else +class Spectral::Parallelisation { +public: + Parallelisation(int truncation) : truncation_(truncation) {} + int nb_spectral_coefficients_global() const { return (truncation_+1)*(truncation_+2); } + int nb_spectral_coefficients() const { return nb_spectral_coefficients_global(); } + int truncation_; +}; +#endif + void Spectral::set_field_metadata(const eckit::Configuration& config, Field& field) const { field.set_functionspace(this); @@ -77,24 +124,18 @@ Spectral::Spectral( const eckit::Configuration& config ) : Spectral::Spectral( const size_t truncation, const eckit::Configuration& config ) : truncation_(truncation), -#ifdef ATLAS_HAVE_TRANS - trans_( new trans::Trans(truncation_) ), - delete_trans_(true), -#else - trans_(0), -#endif + parallelisation_( new Parallelisation(truncation_) ), nb_levels_(0) { config.get("levels",nb_levels_); } -Spectral::Spectral( trans::Trans& trans, const eckit::Configuration& config ) : -#ifdef ATLAS_HAVE_TRANS +Spectral::Spectral( trans::TransImpl& trans, const eckit::Configuration& config ) : truncation_(trans.truncation()), - trans_(&trans), +#ifdef ATLAS_HAVE_TRANS + parallelisation_( new Parallelisation( dynamic_cast(trans).trans_) ), #else - truncation_(0), - trans_(0), + parallelisation_( new Parallelisation(truncation_) ), #endif nb_levels_(0) { @@ -103,10 +144,6 @@ Spectral::Spectral( trans::Trans& trans, const eckit::Configuration& config ) : Spectral::~Spectral() { -#ifdef ATLAS_HAVE_TRANS - if( delete_trans_ ) - delete trans_; -#endif } size_t Spectral::footprint() const { @@ -116,17 +153,11 @@ size_t Spectral::footprint() const { } size_t Spectral::nb_spectral_coefficients() const { -#ifdef ATLAS_HAVE_TRANS - if( trans_ ) return trans_->nb_spectral_coefficients(); -#endif - return (truncation_+1)*(truncation_+2); + return parallelisation_->nb_spectral_coefficients(); } size_t Spectral::nb_spectral_coefficients_global() const { -#ifdef ATLAS_HAVE_TRANS - if( trans_ ) return trans_->nb_spectral_coefficients_global(); -#endif - return (truncation_+1)*(truncation_+2); + return parallelisation_->nb_spectral_coefficients_global(); } @@ -179,7 +210,6 @@ Field Spectral::createField( void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset ) const { - ASSERT( trans_ ); ASSERT(local_fieldset.size() == global_fieldset.size()); for( size_t f=0; fgathspec(nto.size(),nto.data(), - array::make_storageview(loc).data(), - array::make_storageview(glb).data()); + + struct ::GathSpec_t args = new_gathspec( *parallelisation_ ); + args.nfld = nto.size(); + args.rspecg = glb.data(); + args.nto = nto.data(); + args.rspec = loc.data(); + TRANS_CHECK( ::trans_gathspec(&args) ); #else throw eckit::Exception("Cannot gather spectral fields because Atlas has not been compiled with TRANS support."); @@ -225,7 +259,6 @@ void Spectral::gather( const Field& local, Field& global ) const void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldset ) const { - ASSERT( trans_ ); ASSERT(local_fieldset.size() == global_fieldset.size()); for( size_t f=0; fdistspec(nfrom.size(),nfrom.data(), - array::make_storageview(glb).data(), - array::make_storageview(loc).data()); + + struct ::DistSpec_t args = new_distspec( *parallelisation_ ); + args.nfld = nfrom.size(); + args.rspecg = glb.data(); + args.nfrom = nfrom.data(); + args.rspec = loc.data(); + TRANS_CHECK( ::trans_distspec(&args) ); + glb.metadata().broadcast(loc.metadata(),root); loc.metadata().set("global",false); #else @@ -285,14 +323,25 @@ std::string Spectral::checksum( const Field& field ) const { void Spectral::norm( const Field& field, double& norm, int rank ) const { #ifdef ATLAS_HAVE_TRANS ASSERT( std::max(1,field.levels()) == 1 ); - trans_->specnorm(1,field.data(), &norm, rank); + struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); + args.nfld = 1; + args.rspec = field.data(); + args.rnorm = &norm; + args.nmaster = rank+1; + TRANS_CHECK( ::trans_specnorm(&args) ); #else throw eckit::Exception("Cannot compute spectral norms because Atlas has not been compiled with TRANS support."); #endif } void Spectral::norm( const Field& field, double norm_per_level[], int rank ) const { #ifdef ATLAS_HAVE_TRANS - trans_->specnorm( std::max(1,field.levels()),field.data(), norm_per_level, rank); + ASSERT( std::max(1,field.levels()) == 1 ); + struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); + args.nfld = std::max(1,field.levels()); + args.rspec = field.data(); + args.rnorm = norm_per_level; + args.nmaster = rank+1; + TRANS_CHECK( ::trans_specnorm(&args) ); #else throw eckit::Exception("Cannot compute spectral norms because Atlas has not been compiled with TRANS support."); #endif @@ -300,7 +349,12 @@ void Spectral::norm( const Field& field, double norm_per_level[], int rank ) con void Spectral::norm( const Field& field, std::vector& norm_per_level, int rank ) const { #ifdef ATLAS_HAVE_TRANS norm_per_level.resize( std::max(1,field.levels()) ); - trans_->specnorm(norm_per_level.size(),field.data(), norm_per_level.data(), rank); + struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); + args.nfld = norm_per_level.size(); + args.rspec = field.data(); + args.rnorm = norm_per_level.data(); + args.nmaster = rank+1; + TRANS_CHECK( ::trans_specnorm(&args) ); #else throw eckit::Exception("Cannot compute spectral norms because Atlas has not been compiled with TRANS support."); #endif @@ -325,7 +379,7 @@ Spectral::Spectral( const size_t truncation, const eckit::Configuration& config functionspace_( dynamic_cast< const detail::Spectral* >( get() ) ) { } -Spectral::Spectral( trans::Trans& trans, const eckit::Configuration& config ) : +Spectral::Spectral( trans::TransImpl& trans, const eckit::Configuration& config ) : FunctionSpace( new detail::Spectral(trans,config) ), functionspace_( dynamic_cast< const detail::Spectral* >( get() ) ) { } @@ -388,7 +442,7 @@ const detail::Spectral* atlas__SpectralFunctionSpace__new__config ( const eckit: return 0; } -const detail::Spectral* atlas__SpectralFunctionSpace__new__trans (trans::Trans* trans, const eckit::Configuration* config ) +const detail::Spectral* atlas__SpectralFunctionSpace__new__trans (trans::TransImpl* trans, const eckit::Configuration* config ) { ATLAS_ERROR_HANDLING( return new detail::Spectral(*trans,*config); diff --git a/src/atlas/functionspace/Spectral.h b/src/atlas/functionspace/Spectral.h index 20bbc5e3e..0b7cf7b3f 100644 --- a/src/atlas/functionspace/Spectral.h +++ b/src/atlas/functionspace/Spectral.h @@ -22,7 +22,7 @@ namespace atlas { namespace atlas { namespace trans { - class Trans; + class TransImpl; } } @@ -40,11 +40,11 @@ class Spectral : public FunctionSpaceImpl Spectral(const size_t truncation, const eckit::Configuration& = util::NoConfig() ); - Spectral(trans::Trans&, const eckit::Configuration& = util::NoConfig() ); + Spectral(trans::TransImpl&, const eckit::Configuration& = util::NoConfig() ); virtual ~Spectral(); - virtual std::string name() const { return "Spectral"; } + virtual std::string type() const { return "Spectral"; } /// @brief Create a spectral field using FunctionSpaceImpl::createField; @@ -84,8 +84,8 @@ class Spectral : public FunctionSpaceImpl size_t truncation_; - trans::Trans* trans_; - bool delete_trans_{false}; + class Parallelisation; + std::unique_ptr parallelisation_; }; @@ -99,7 +99,7 @@ class Spectral : public FunctionSpace { Spectral( const FunctionSpace& ); Spectral( const eckit::Configuration& ); Spectral( const size_t truncation, const eckit::Configuration& = util::NoConfig() ); - Spectral( trans::Trans&, const eckit::Configuration& = util::NoConfig() ); + Spectral( trans::TransImpl&, const eckit::Configuration& = util::NoConfig() ); operator bool() const { return valid(); } bool valid() const { return functionspace_; } @@ -131,7 +131,7 @@ class Spectral : public FunctionSpace { extern "C" { const detail::Spectral* atlas__SpectralFunctionSpace__new__config ( const eckit::Configuration* config ); - const detail::Spectral* atlas__SpectralFunctionSpace__new__trans (trans::Trans* trans, const eckit::Configuration* config ); + const detail::Spectral* atlas__SpectralFunctionSpace__new__trans (trans::TransImpl* trans, const eckit::Configuration* config ); void atlas__SpectralFunctionSpace__delete (detail::Spectral* This); field::FieldImpl* atlas__fs__Spectral__create_field(const detail::Spectral* This, const eckit::Configuration* options); void atlas__SpectralFunctionSpace__gather(const detail::Spectral* This, const field::FieldImpl* local, field::FieldImpl* global); diff --git a/src/atlas/functionspace/StructuredColumns.h b/src/atlas/functionspace/StructuredColumns.h index 8a9833040..e83ab19cb 100644 --- a/src/atlas/functionspace/StructuredColumns.h +++ b/src/atlas/functionspace/StructuredColumns.h @@ -37,7 +37,7 @@ namespace field { namespace atlas { namespace trans { - class Trans; + class TransIFS; } } @@ -57,7 +57,8 @@ class StructuredColumns : public FunctionSpaceImpl { virtual ~StructuredColumns(); - virtual std::string name() const { return "StructuredColumns"; } + static std::string static_type() { return "StructuredColumns"; } + virtual std::string type() const { return static_type(); } /// @brief Create a Structured field virtual Field createField( const eckit::Configuration&) const; @@ -257,6 +258,8 @@ class StructuredColumns: public FunctionSpace { StructuredColumns( const Grid&, const eckit::Configuration& = util::NoConfig() ); StructuredColumns( const Grid&, const grid::Partitioner&, const eckit::Configuration& = util::NoConfig() ); + static std::string type() { return detail::StructuredColumns::static_type(); } + operator bool() const { return valid(); } bool valid() const { return functionspace_; } diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index 021cb950e..0cab7784d 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -12,7 +12,7 @@ #include "atlas/grid/Grid.h" #include "atlas/grid/detail/partitioner/TransPartitioner.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" -#include "atlas/trans/Trans.h" +#include "atlas/trans/detail/TransIFS.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/array.h" #include "atlas/runtime/Trace.h" @@ -53,7 +53,7 @@ void TransPartitioner::partition(const Grid& grid, int part[]) const { if( not g ) throw eckit::BadCast("Grid is not a grid::Structured type. Cannot partition using IFS trans",Here()); - trans::Trans t(grid); + trans::TransIFS t(grid); if( nb_partitions() != size_t(t.nproc()) ) { std::stringstream msg; msg << "Requested to partition grid with TransPartitioner in "< 1 ) { field_glb = function_space.createField( - option::name("glb_field") | + option::name("glb_field") | option::global() ); function_space.gather(field, field_glb); data = array::LocalView( @@ -1097,7 +1097,7 @@ void GmshIO::write( std::stringstream msg; msg << "Field ["<& rgpview_; - IsGhostNode is_ghost; - size_t f; - - PackNodeColumns( ArrayView& rgpview, const NodeColumns& fs ) : - rgpview_(rgpview), is_ghost( fs.nodes() ), f(0) {} - - void operator()(const Field& field, int components = 0) { - switch (field.rank()) { - case 1: - pack_1(field,components); - break; - case 2: - pack_2(field,components); - break; - case 3: - pack_3(field,components); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; - } - } - - void pack_1(const Field& field, int) - { - const ArrayView gpfield = make_view( field ); - size_t n=0; - for( size_t jnode=0; jnode gpfield = make_view( field ); - const size_t nvars = gpfield.shape(1); - for( size_t jvar=0; jvar gpfield = make_view( field ); - if( not components ) components = gpfield.shape(2); - ATLAS_DEBUG_VAR( components ); - for( size_t jcomp=0; jcomp& rgpview_; - size_t f; - - PackStructuredColumns( ArrayView& rgpview ) : - rgpview_(rgpview), f(0) {} - - void operator()(const Field& field) { - switch (field.rank()) { - case 1: - pack_1(field); - break; - case 2: - pack_2(field); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; - } - } - - void pack_1(const Field& field) - { - const ArrayView gpfield = make_view( field ); - size_t n=0; - for( size_t jnode=0; jnode gpfield = make_view( field ); - const size_t nvars = gpfield.shape(1); - for( size_t jvar=0; jvar& rspecview_; - size_t f; - PackSpectral( ArrayView& rspecview ) : - rspecview_(rspecview), f(0) {} - - void operator()(const Field& field) { - switch (field.rank()) { - case 1: - pack_1(field); - break; - case 2: - pack_2(field); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; - } - } - - void pack_1(const Field& field) - { - const ArrayView spfield = make_view( field ); - - for( size_t jwave=0; jwave spfield = make_view( field ); - - const size_t nvars = spfield.shape(1); - - for( size_t jvar=0; jvar& rgpview_; - IsGhostNode is_ghost; - size_t f; - - UnpackNodeColumns( const ArrayView& rgpview, const NodeColumns& fs ) : - rgpview_(rgpview), is_ghost( fs.nodes() ), f(0) {} - - void operator()(Field& field, int components = 0) { - switch (field.rank()) { - case 1: - unpack_1(field,components); - break; - case 2: - unpack_2(field,components); - break; - case 3: - unpack_3(field,components); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; - } - } - - void unpack_1(Field& field, int) - { - ArrayView gpfield = make_view( field ); - size_t n(0); - for( size_t jnode=0; jnode gpfield = make_view( field ); - const size_t nvars = gpfield.shape(1); - for( size_t jvar=0; jvar gpfield = make_view( field ); - if( not components ) components = gpfield.shape(2); - for( size_t jcomp=0; jcomp& rgpview_; - size_t f; - - UnpackStructuredColumns( const ArrayView& rgpview ) : - rgpview_(rgpview), f(0) {} - - void operator()(Field& field) { - switch (field.rank()) { - case 1: - unpack_1(field); - break; - case 2: - unpack_2(field); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; - } - } - - void unpack_1(Field& field) - { - ArrayView gpfield = make_view( field ); - size_t n=0; - for( size_t jnode=0; jnode gpfield = make_view( field ); - const size_t nvars = gpfield.shape(1); - for( size_t jvar=0; jvar& rspecview_; - size_t f; - UnpackSpectral( const ArrayView& rspecview ) : - rspecview_(rspecview), f(0) {} - - void operator()(Field& field) { - switch (field.rank()) { - case 1: - unpack_1(field); - break; - case 2: - unpack_2(field); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; - } - } - - void unpack_1(Field& field) - { - ArrayView spfield = make_view( field ); - - for( size_t jwave=0; jwave spfield = make_view( field ); - - const size_t nvars = spfield.shape(1); - - for( size_t jvar=0; jvar1)); - TRANS_CHECK(::trans_setup(&trans_)); -} - -void Trans::ctor_rgg(const long nlat, const long pl[], long truncation, const Trans::Options& p ) -{ - std::vector nloen(nlat); - for( long jlat=0; jlat= 0 ) - TRANS_CHECK(::trans_set_trunc(&trans_,truncation)); - TRANS_CHECK(::trans_set_cache(&trans_,p.cache(),p.cachesize())); - - if( not p.read().empty() ) - { - if( eckit::PathName(p.read()).exists() ) - { - std::stringstream msg; msg << "File " << p.read() << "doesn't exist"; - throw eckit::CantOpenFile(msg.str(),Here()); - } - TRANS_CHECK(::trans_set_read(&trans_,p.read().c_str())); - } - if( !p.write().empty() ) - TRANS_CHECK(::trans_set_write(&trans_,p.write().c_str())); - - trans_.fft = p.fft(); - trans_.lsplit = p.split_latitudes(); - trans_.flt = p.flt(); - - TRANS_CHECK(::trans_use_mpi(parallel::mpi::comm().size()>1)); - TRANS_CHECK(::trans_setup(&trans_)); -} - -void Trans::ctor_lonlat(const long nlon, const long nlat, long truncation, const Trans::Options& p ) -{ - TRANS_CHECK(::trans_new(&trans_)); - TRANS_CHECK(::trans_set_resol_lonlat(&trans_,nlon,nlat)); - if( truncation >= 0 ) - TRANS_CHECK(::trans_set_trunc(&trans_,truncation)); - TRANS_CHECK(::trans_set_cache(&trans_,p.cache(),p.cachesize())); - - if( not p.read().empty() ) - { - if( eckit::PathName(p.read()).exists() ) - { - std::stringstream msg; msg << "File " << p.read() << "doesn't exist"; - throw eckit::CantOpenFile(msg.str(),Here()); - } - TRANS_CHECK(::trans_set_read(&trans_,p.read().c_str())); - } - if( not p.write().empty() ) - TRANS_CHECK(::trans_set_write(&trans_,p.write().c_str())); - - trans_.fft = p.fft(); - trans_.lsplit = p.split_latitudes(); - trans_.flt = p.flt(); - - TRANS_CHECK(::trans_use_mpi(parallel::mpi::comm().size()>1)); - TRANS_CHECK(::trans_setup(&trans_)); -} - -Trans::Options::Options() : util::Config() -{ - set_cache(nullptr,0); - set_split_latitudes(true); - set_fft(FFTW); - set_flt(false); -} - -void Trans::Options::set_cache(const void* buffer, size_t size) -{ - cacheptr_=buffer; - cachesize_=size; -} - -const void* Trans::Options::cache() const -{ - return cacheptr_; -} - -size_t Trans::Options::cachesize() const -{ - return cachesize_; -} - -void Trans::Options::set_fft( FFT fft ) -{ - if( fft == FFTW ) - { - set( "fft", "FFTW" ); - } - else if( fft == FFT992 ) - { - set( "fft", "FFT992" ); - } - else - { - NOTIMP; - } -} - -void Trans::Options::set_split_latitudes( bool split ) -{ - set("split_latitudes",split); -} - -void Trans::Options::set_flt( bool flt ) -{ - set("flt",flt); -} - -bool Trans::Options::split_latitudes() const -{ - return getBool("split_latitudes"); -} - -FFT Trans::Options::fft() const -{ - std::string fftstr = getString( "fft" ); - if( fftstr == "FFTW" ) - return FFTW; - else if( fftstr == "FFT992" ) - return FFT992; - else - NOTIMP; - return FFTW; -} - -bool Trans::Options::flt() const -{ - return getBool("flt"); -} - - -void Trans::Options::set_read(const std::string& file) -{ - set("read",file); -} - -std::string Trans::Options::read() const -{ - return getString("read",""); -} - -void Trans::Options::set_write(const std::string& file) -{ - set("write",file); -} - -std::string Trans::Options::write() const -{ - return getString("write",""); -} - - -// -------------------------------------------------------------------------------------------- - - - -void Trans::dirtrans(const functionspace::NodeColumns& gp, const Field& gpfield, - const Spectral& sp, Field& spfield, const TransParameters& context) const -{ - FieldSet gpfields; gpfields.add(gpfield); - FieldSet spfields; spfields.add(spfield); - dirtrans(gp,gpfields,sp,spfields,context); -} - - -// -------------------------------------------------------------------------------------------- - -void Trans::dirtrans(const functionspace::NodeColumns& gp,const FieldSet& gpfields, - const Spectral& sp, FieldSet& spfields, const TransParameters& context) const -{ - // Count total number of fields and do sanity checks - int nfld(0); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - { - const Field& f = gpfields[jfld]; - nfld += f.stride(0); - } - - int trans_spnfld(0); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - { - const Field& f = spfields[jfld]; - trans_spnfld += f.stride(0); - } - - if( nfld != trans_spnfld ) - { - throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); - } - // Arrays Trans expects - array::ArrayT rgp(nfld,ngptot()); - array::ArrayT rspec(nspec2(),nfld); - - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); - - // Pack gridpoints - { - PackNodeColumns pack(rgpview,gp); - for( size_t jfld=0; jfld(); - transform.rspscalar = rspec.data(); - - TRANS_CHECK( ::trans_dirtrans(&transform) ); - } - - // Unpack the spectral fields - { - UnpackSpectral unpack(rspecview); - for( size_t jfld=0; jfld(); - transform.rspscalar = spfield.data(); - transform.ngpblks = gpfield.shape(0); - transform.nproma = 1; - TRANS_CHECK( ::trans_dirtrans(&transform) ); - } -} - -void Trans::dirtrans( - const FieldSet& gpfields, - FieldSet& spfields, - const TransParameters& context) const -{ - // Count total number of fields and do sanity checks - int nfld(0); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - { - const Field& f = gpfields[jfld]; - nfld += f.stride(0); - ASSERT( f.functionspace() == 0 || - functionspace::StructuredColumns(f.functionspace()) ); - } - - int trans_spnfld(0); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - { - const Field& f = spfields[jfld]; - trans_spnfld += f.stride(0); - } - - if( nfld != trans_spnfld ) - { - throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); - } - // Arrays Trans expects - array::ArrayT rgp(nfld,ngptot()); - array::ArrayT rspec(nspec2(),nfld); - - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); - - // Pack gridpoints - { - PackStructuredColumns pack(rgpview); - for( size_t jfld=0; jfld(); - transform.rspscalar = rspec.data(); - - TRANS_CHECK( ::trans_dirtrans(&transform) ); - } - - // Unpack the spectral fields - { - UnpackSpectral unpack(rspecview); - for( size_t jfld=0; jfld(1,f.levels()) == f.stride(0) ); - } - - if( nb_gridpoint_field != 2*nfld ) // factor 2 because N-S and E-W derivatives - throw eckit::SeriousBug("invtrans_grad: different number of gridpoint fields than spectral fields",Here()); - - // Arrays Trans expects - // Allocate space for - array::ArrayT rgp(3*nfld,ngptot()); // (scalars) + (NS ders) + (EW ders) - array::ArrayT rspec(nspec2(),nfld); - - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); - - // Pack spectral fields - { - PackSpectral pack(rspecview); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - pack(spfields[jfld]); - } - - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(&trans_); - transform.nscalar = nfld; - transform.rgp = rgp.data(); - transform.rspscalar = rspec.data(); - transform.lscalarders = true; - - TRANS_CHECK(::trans_invtrans(&transform)); - } - - // Unpack the gridpoint fields - { - mesh::IsGhostNode is_ghost( gp.nodes()); - int f=nfld; // skip to where derivatives start - for(size_t dim=0; dim<2; ++dim) { - for(size_t jfld = 0; jfld < gradfields.size(); ++jfld) - { - const size_t nlev = std::max(1,gradfields[jfld].levels()); - const size_t nb_nodes = gradfields[jfld].shape(0); - - array::LocalView field ( gradfields[jfld].data(), - array::make_shape(nb_nodes, nlev, 2 ) ); - - for( size_t jlev=0; jlev rgp(nfld,ngptot()); - array::ArrayT rspec(nspec2(),nfld); - - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); - - // Pack spectral fields - { - PackSpectral pack(rspecview); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - pack(spfields[jfld]); - } - - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(&trans_); - transform.nscalar = nfld; - transform.rgp = rgp.data(); - transform.rspscalar = rspec.data(); - - TRANS_CHECK(::trans_invtrans(&transform)); - } - - // Unpack the gridpoint fields - { - UnpackNodeColumns unpack(rgpview,gp); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - unpack(gpfields[jfld]); - } - -} - -// -------------------------------------------------------------------------------------------- - - -void Trans::invtrans(const Field& spfield, - Field& gpfield, - const TransParameters& context) const -{ - ASSERT( gpfield.functionspace() == 0 || - functionspace::StructuredColumns( gpfield.functionspace() ) ); - ASSERT( spfield.functionspace() == 0 || - functionspace::Spectral( spfield.functionspace() ) ); - if ( gpfield.stride(0) != spfield.stride(0) ) - { - throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); - } - if ( (int)gpfield.shape(0) != ngptot() ) - { - throw eckit::SeriousBug("dirtrans: slowest moving index must be ngptot",Here()); - } - const int nfld = gpfield.stride(0); - - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(&trans_); - transform.nscalar = nfld; - transform.rgp = gpfield.data(); - transform.rspscalar = spfield.data(); - transform.ngpblks = gpfield.shape(0); - transform.nproma = 1; - TRANS_CHECK( ::trans_invtrans(&transform) ); - } -} - - -// -------------------------------------------------------------------------------------------- - - -void Trans::invtrans(const FieldSet& spfields, - FieldSet& gpfields, - const TransParameters& context) const -{ - // Count total number of fields and do sanity checks - int nfld(0); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - { - const Field& f = gpfields[jfld]; - nfld += f.stride(0); - ASSERT( f.functionspace() == 0 || - functionspace::StructuredColumns( f.functionspace() ) ); - } - - int nb_spectral_fields(0); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - { - const Field& f = spfields[jfld]; - nb_spectral_fields += f.stride(0); - } - - if( nfld != nb_spectral_fields ) { - std::stringstream msg; - msg << "invtrans: different number of gridpoint fields than spectral fields" - << "[ " << nfld << " != " << nb_spectral_fields << " ]"; - throw eckit::SeriousBug(msg.str(),Here()); - } - - // Arrays Trans expects - array::ArrayT rgp(nfld,ngptot()); - array::ArrayT rspec(nspec2(),nfld); - - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); - - // Pack spectral fields - { - PackSpectral pack(rspecview); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - pack(spfields[jfld]); - } - - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(&trans_); - transform.nscalar = nfld; - transform.rgp = rgp.data(); - transform.rspscalar = rspec.data(); - - TRANS_CHECK(::trans_invtrans(&transform)); - } - - // Unpack the gridpoint fields - { - UnpackStructuredColumns unpack(rgpview); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - unpack(gpfields[jfld]); - } -} - -// ----------------------------------------------------------------------------------------------- - -void Trans::dirtrans_wind2vordiv(const functionspace::NodeColumns& gp, const Field& gpwind, - const Spectral& sp, Field& spvor, Field&spdiv, - const TransParameters& context) const -{ - // Count total number of fields and do sanity checks - size_t nfld = spvor.stride(0); - if( spdiv.shape(0) != spvor.shape(0) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); - if( spdiv.shape(1) != spvor.shape(1) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); - size_t nwindfld = gpwind.stride(0); - if (nwindfld != 2*nfld && nwindfld != 3*nfld) throw eckit::SeriousBug("dirtrans: wind field is not compatible with vorticity, divergence.",Here()); - - if( spdiv.shape(0) != size_t(nspec2()) ) { - std::stringstream msg; - msg << "dirtrans: Spectral vorticity and divergence have wrong dimension: nspec2 "< rgp(2*nfld,size_t(ngptot())); - array::ArrayView rgpview = array::make_view(rgp); - - ATLAS_DEBUG_VAR(gpwind.size()); - ATLAS_DEBUG_VAR(rgp.size()); - ATLAS_DEBUG_VAR(gpwind.stride(0)); - ATLAS_DEBUG_VAR(2*nfld); - ATLAS_DEBUG_VAR(rgp.stride(0)); - - ATLAS_DEBUG_HERE(); - // Pack gridpoints - { - PackNodeColumns pack( rgpview, gp ); - int wind_components = 2; - pack(gpwind, wind_components); - } - ATLAS_DEBUG_HERE(); - - // Do transform - { - struct ::DirTrans_t transform = ::new_dirtrans(&trans_); - transform.nvordiv = nfld; - transform.rgp = rgp.data(); - transform.rspvor = spvor.data(); - transform.rspdiv = spdiv.data(); - - ASSERT( transform.rspvor ); - ASSERT( transform.rspdiv ); - TRANS_CHECK( ::trans_dirtrans(&transform) ); - } - ATLAS_DEBUG_HERE(); - -} - - -void Trans::invtrans_vordiv2wind(const Spectral& sp, const Field& spvor, const Field& spdiv, - const functionspace::NodeColumns& gp, Field& gpwind, const TransParameters&) const -{ - // Count total number of fields and do sanity checks - size_t nfld = spvor.stride(0); - if( spdiv.shape(0) != spvor.shape(0) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); - if( spdiv.shape(1) != spvor.shape(1) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); - size_t nwindfld = gpwind.stride(0); - if (nwindfld != 2*nfld && nwindfld != 3*nfld) throw eckit::SeriousBug("invtrans: wind field is not compatible with vorticity, divergence.",Here()); - - if( spdiv.shape(0) != size_t(nspec2()) ) { - std::stringstream msg; - msg << "invtrans: Spectral vorticity and divergence have wrong dimension: nspec2 "< rgp(2*nfld,size_t(ngptot())); - array::ArrayView rgpview = array::make_view(rgp); - - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(&trans_); - transform.nvordiv = nfld; - transform.rgp = rgp.data(); - transform.rspvor = spvor.data(); - transform.rspdiv = spdiv.data(); - - ASSERT( transform.rspvor ); - ASSERT( transform.rspdiv ); - TRANS_CHECK(::trans_invtrans(&transform)); - } - - // Unpack the gridpoint fields - { - UnpackNodeColumns unpack( rgpview, gp ); - int wind_components = 2; - unpack(gpwind,wind_components); - } - -} - - - - - -Trans* atlas__Trans__new (const Grid::Implementation* grid, int nsmax) -{ - Trans* trans(0); - ATLAS_ERROR_HANDLING( - ASSERT( grid ); - trans = new Trans( Grid(grid) ,nsmax); - ); - return trans; -} - -void atlas__Trans__delete (Trans* This) -{ - ASSERT( This ); - ATLAS_ERROR_HANDLING( delete This ); -} - -int atlas__Trans__handle (const Trans* This) -{ - ASSERT( This ); - ATLAS_ERROR_HANDLING( - ::Trans_t* t = *This; - return t->handle; - ); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// - - -void Trans::distspec( const int nb_fields, const int origin[], const double global_spectra[], double spectra[] ) const -{ - struct ::DistSpec_t args = new_distspec(&trans_); - args.nfld = nb_fields; - args.rspecg = global_spectra; - args.nfrom = origin; - args.rspec = spectra; - TRANS_CHECK( ::trans_distspec(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Trans::gathspec( const int nb_fields, const int destination[], const double spectra[], double global_spectra[] ) const -{ - struct ::GathSpec_t args = new_gathspec(&trans_); - args.nfld = nb_fields; - args.rspecg = global_spectra; - args.nto = destination; - args.rspec = spectra; - TRANS_CHECK( ::trans_gathspec(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Trans::distgrid( const int nb_fields, const int origin[], const double global_fields[], double fields[] ) const -{ - struct ::DistGrid_t args = new_distgrid(&trans_); - args.nfld = nb_fields; - args.nfrom = origin; - args.rgpg = global_fields; - args.rgp = fields; - TRANS_CHECK( ::trans_distgrid(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Trans::gathgrid( const int nb_fields, const int destination[], const double fields[], double global_fields[] ) const -{ - struct ::GathGrid_t args = new_gathgrid(&trans_); - args.nfld = nb_fields; - args.nto = destination; - args.rgp = fields; - args.rgpg = global_fields; - TRANS_CHECK( ::trans_gathgrid(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Trans::invtrans( const int nb_scalar_fields, const double scalar_spectra[], - const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const TransParameters& context ) const -{ - struct ::InvTrans_t args = new_invtrans(&trans_); - args.nscalar = nb_scalar_fields; - args.rspscalar = scalar_spectra; - args.nvordiv = nb_vordiv_fields; - args.rspvor = vorticity_spectra; - args.rspdiv = divergence_spectra; - args.rgp = gp_fields; - if( context.scalar_derivatives() ) { - args.lscalarders = true; - } - if( context.wind_EW_derivatives() ) { - args.luvder_EW = true; - } - if( context.vorticity_divergence_fields() ) { - args.lvordivgp = true; - } - TRANS_CHECK( ::trans_invtrans(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Trans::invtrans(const int nb_scalar_fields, const double scalar_spectra[], - double gp_fields[], - const TransParameters& context) const -{ - struct ::InvTrans_t args = new_invtrans(&trans_); - args.nscalar = nb_scalar_fields; - args.rspscalar = scalar_spectra; - args.rgp = gp_fields; - if( context.scalar_derivatives() ) { - args.lscalarders = true; - } - TRANS_CHECK( ::trans_invtrans(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Trans::invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const TransParameters& context ) const -{ - struct ::InvTrans_t args = new_invtrans(&trans_); - args.nvordiv = nb_vordiv_fields; - args.rspvor = vorticity_spectra; - args.rspdiv = divergence_spectra; - args.rgp = gp_fields; - if( context.wind_EW_derivatives() ) { - args.luvder_EW = true; - } - if( context.vorticity_divergence_fields() ) { - args.lvordivgp = true; - } - TRANS_CHECK( ::trans_invtrans(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Trans::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[] ) const -{ - struct ::DirTrans_t args = new_dirtrans(&trans_); - args.nscalar = nb_fields; - args.rgp = scalar_fields; - args.rspscalar = scalar_spectra; - TRANS_CHECK( ::trans_dirtrans(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Trans::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[] ) const -{ - struct ::DirTrans_t args = new_dirtrans(&trans_); - args.nvordiv = nb_fields; - args.rspvor = vorticity_spectra; - args.rspdiv = divergence_spectra; - args.rgp = wind_fields; - TRANS_CHECK( ::trans_dirtrans(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - - -void Trans::specnorm( const int nb_fields, const double spectra[], double norms[], int rank ) const -{ - struct ::SpecNorm_t args = new_specnorm(&trans_); - args.nfld = nb_fields; - args.rspec = spectra; - args.rnorm = norms; - args.nmaster = rank+1; - TRANS_CHECK( ::trans_specnorm(&args) ); -} - -/////////////////////////////////////////////////////////////////////////////// - -void atlas__Trans__distspec( const Trans* t, int nb_fields, int origin[], double global_spectra[], double spectra[] ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - return t->distspec(nb_fields,origin,global_spectra,spectra); - ); -} - -void atlas__Trans__gathspec( const Trans* t, int nb_fields, int destination[], double spectra[], double global_spectra[] ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - return t->gathspec(nb_fields,destination,spectra,global_spectra); - ); -} - -void atlas__Trans__distgrid( const Trans* t, int nb_fields, int origin[], double global_fields[], double fields[] ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - return t->distgrid(nb_fields,origin,global_fields,fields); - ); -} - -void atlas__Trans__gathgrid( const Trans* t, int nb_fields, int destination[], double fields[], double global_fields[] ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - return t->gathgrid(nb_fields,destination,fields,global_fields); - ); -} - -void atlas__Trans__invtrans_scalar( const Trans* t, int nb_fields, double scalar_spectra[], double scalar_fields[] ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - return t->invtrans(nb_fields,scalar_spectra,scalar_fields); - ); -} - -void atlas__Trans__invtrans_vordiv2wind( const Trans* t, int nb_fields, double vorticity_spectra[], double divergence_spectra[], double wind_fields[] ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - return t->invtrans(nb_fields,vorticity_spectra,divergence_spectra,wind_fields); - ); -} - -void atlas__Trans__dirtrans_scalar( const Trans* t, int nb_fields, double scalar_fields[], double scalar_spectra[] ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - return t->dirtrans(nb_fields,scalar_fields,scalar_spectra); - ); -} - -void atlas__Trans__dirtrans_wind2vordiv( const Trans* t, int nb_fields, double wind_fields[], double vorticity_spectra[], double divergence_spectra[] ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - return t->dirtrans(nb_fields,wind_fields,vorticity_spectra,divergence_spectra); - ); -} - -void atlas__Trans__specnorm (const Trans* t, int nb_fields, double spectra[], double norms[], int rank) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - return t->specnorm(nb_fields, spectra, norms, rank); - ); -} - -int atlas__Trans__nspec2 (const Trans* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->nb_spectral_coefficients(); - ); - return 0; -} - -int atlas__Trans__nspec2g (const Trans* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->nb_spectral_coefficients_global(); - ); - return 0; -} - -int atlas__Trans__ngptot (const Trans* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->nb_gridpoints(); - ); - return 0; -} - -int atlas__Trans__ngptotg (const Trans* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->nb_gridpoints_global(); - ); - return 0; -} - -int atlas__Trans__truncation (const Trans* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->truncation(); - ); - return 0; -} - -const Grid::Implementation* atlas__Trans__grid(const Trans* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( This->grid() ); - return This->grid().get(); - ); - return nullptr; -} - - -void atlas__Trans__dirtrans_fieldset_nodes (const Trans* This, const functionspace::detail::NodeColumns* gp, const field::FieldSetImpl* gpfields, const functionspace::detail::Spectral* sp, field::FieldSetImpl* spfields, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( gp ); - ASSERT( gpfields ); - ASSERT( sp ); - ASSERT( spfields ); - ASSERT( parameters ); - FieldSet fspfields(spfields); - This->dirtrans(FunctionSpace(gp),gpfields,FunctionSpace(sp),fspfields,*parameters); - ); -} - -void atlas__Trans__dirtrans_fieldset (const Trans* This, const field::FieldSetImpl* gpfields, field::FieldSetImpl* spfields, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( gpfields ); - ASSERT( spfields ); - ASSERT( parameters ); - FieldSet fspfields(spfields); - This->dirtrans(gpfields,fspfields,*parameters); - ); -} - -void atlas__Trans__invtrans_fieldset_nodes (const Trans* This, const functionspace::detail::Spectral* sp, const field::FieldSetImpl* spfields, const functionspace::detail::NodeColumns* gp, field::FieldSetImpl* gpfields, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( sp ); - ASSERT( spfields ); - ASSERT( gp ); - ASSERT( gpfields ); - ASSERT( parameters ); - FieldSet fgpfields(gpfields); - This->invtrans(FunctionSpace(sp),spfields,FunctionSpace(gp),fgpfields,*parameters); - ); -} - - -void atlas__Trans__dirtrans_field (const Trans* This, const field::FieldImpl* gpfield, field::FieldImpl* spfield, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( spfield ); - ASSERT( gpfield ); - ASSERT( parameters ); - Field fspfield(spfield); - This->dirtrans(gpfield,fspfield,*parameters); - ); -} - -void atlas__Trans__dirtrans_field_nodes (const Trans* This, const functionspace::detail::NodeColumns* gp, const field::FieldImpl* gpfield, const functionspace::detail::Spectral* sp, field::FieldImpl* spfield, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( spfield ); - ASSERT( gpfield ); - ASSERT( parameters ); - Field fspfield(spfield); - This->dirtrans(FunctionSpace(gp),gpfield,FunctionSpace(sp),fspfield,*parameters); - ); -} - -void atlas__Trans__invtrans_fieldset (const Trans* This, const field::FieldSetImpl* spfields, field::FieldSetImpl* gpfields, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( spfields ); - ASSERT( gpfields ); - ASSERT( parameters ); - FieldSet fgpfields(gpfields); - This->invtrans(spfields,fgpfields,*parameters); - ); -} - -void atlas__Trans__invtrans_field (const Trans* This, const field::FieldImpl* spfield, field::FieldImpl* gpfield, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( spfield ); - ASSERT( gpfield ); - ASSERT( parameters ); - Field fgpfield(gpfield); - This->invtrans(spfield,fgpfield,*parameters); - ); -} - -void atlas__Trans__invtrans_field_nodes (const Trans* This, const functionspace::detail::Spectral* sp, const field::FieldImpl* spfield, const functionspace::detail::NodeColumns* gp, field::FieldImpl* gpfield, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( sp ); - ASSERT( spfield ); - ASSERT( gp ); - ASSERT( gpfield ); - ASSERT( parameters ); - Field fgpfield(gpfield); - This->invtrans(FunctionSpace(sp),spfield,FunctionSpace(gp),fgpfield,*parameters); - ); -} - -void atlas__Trans__dirtrans_wind2vordiv_field_nodes (const Trans* This, const functionspace::detail::NodeColumns* gp, const field::FieldImpl* gpwind, const functionspace::detail::Spectral* sp, field::FieldImpl* spvor, field::FieldImpl* spdiv, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( gp ); - ASSERT( gpwind ); - ASSERT( sp ); - ASSERT( spvor ); - ASSERT( spdiv ); - ASSERT( parameters ); - Field fspvor(spvor); - Field fspdiv(spdiv); - This->dirtrans_wind2vordiv(FunctionSpace(gp),gpwind,FunctionSpace(sp),fspvor,fspdiv,*parameters); - ); -} - -void atlas__Trans__invtrans_vordiv2wind_field_nodes (const Trans* This, const functionspace::detail::Spectral* sp, const field::FieldImpl* spvor, const field::FieldImpl* spdiv, const functionspace::detail::NodeColumns* gp, field::FieldImpl* gpwind, const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( sp ); - ASSERT( spvor ); - ASSERT( spdiv ); - ASSERT( gp ); - ASSERT( gpwind ); - ASSERT( parameters ); - Field fgpwind(gpwind); - This->invtrans_vordiv2wind(FunctionSpace(sp),spvor,spdiv,FunctionSpace(gp),fgpwind,*parameters); - ); -} - -void atlas__Trans__invtrans (const Trans* This, int nb_scalar_fields, double scalar_spectra[], int nb_vordiv_fields, double vorticity_spectra[], double divergence_spectra[], double gp_fields[], const TransParameters* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - This->invtrans( nb_scalar_fields, scalar_spectra, - nb_vordiv_fields, vorticity_spectra, divergence_spectra, - gp_fields, - *parameters ); - ); -} - -void atlas__Trans__invtrans_grad_field_nodes (const Trans* This, const functionspace::detail::Spectral* sp, const field::FieldImpl* spfield, const functionspace::detail::NodeColumns* gp, field::FieldImpl* gpfield) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( sp ); - ASSERT( spfield ); - ASSERT( gp ); - ASSERT( gpfield ); - Field fgpfield(gpfield); - This->invtrans_grad(FunctionSpace(sp),spfield,FunctionSpace(gp),fgpfield); - ); -} - - - -TransParameters* atlas__TransParameters__new () -{ - return new TransParameters(); -} - -void atlas__TransParameters__delete (TransParameters* This) -{ - ATLAS_ERROR_HANDLING( ASSERT( This ); ); - delete This; +TransImpl::~TransImpl() { } } // namespace trans diff --git a/src/atlas/trans/Trans.h b/src/atlas/trans/Trans.h index 7204ff9b5..39bcb8976 100644 --- a/src/atlas/trans/Trans.h +++ b/src/atlas/trans/Trans.h @@ -10,11 +10,9 @@ #pragma once -#include "transi/trans.h" -#include "eckit/config/LocalConfiguration.h" +#include "eckit/config/Configuration.h" #include "eckit/memory/Owned.h" -#include "atlas/array/LocalView.h" -#include "atlas/grid/Grid.h" +#include "atlas/util/Config.h" //----------------------------------------------------------------------------- // Forward declarations @@ -22,45 +20,8 @@ namespace atlas { class Field; class FieldSet; -namespace field { - class FieldImpl; - class FieldSetImpl; -} } -namespace atlas { -namespace array { - class Array; -} -} - -namespace atlas { -namespace functionspace { - class NodeColumns; - class Spectral; -} -} - -namespace atlas { -namespace functionspace { -namespace detail { - class NodeColumns; - class Spectral; -} -} -} - -namespace atlas { -namespace grid { -namespace detail { -namespace partitioner { - class TransPartitioner; -} -} -} -} - - //----------------------------------------------------------------------------- namespace atlas { @@ -68,416 +29,99 @@ namespace trans { //----------------------------------------------------------------------------- -enum FFT { FFT992=TRANS_FFT992, FFTW=TRANS_FFTW }; - -//----------------------------------------------------------------------------- - -class TransParameters : public util::Config { -public: - TransParameters() {} - ~TransParameters() {} - static const char* className() { return "atlas::trans::TransParameters"; } - - void set_scalar_derivatives(bool v) { set("scalar_derivatives",v); } - void set_wind_EW_derivatives(bool v) { set("wind_EW_derivatives",v); } - void vorticity_divergence_fields(bool v) { set("vorticity_divergence_fields",v); } - - bool scalar_derivatives() const { - return getBool("scalar_derivatives",false); - } - - bool wind_EW_derivatives() const { - return getBool("wind_EW_derivatives",false); - } - - bool vorticity_divergence_fields() const { - return getBool("vorticity_divergence_fields",false); - } - -}; - -//----------------------------------------------------------------------------- - -class Trans : public eckit::Owned { -private: - typedef struct ::Trans_t Trans_t; +class TransImpl : public eckit::Owned { public: - class Options : public util::Config { - public: - - Options(); - ~Options() {} - static const char* className() { return "atlas::trans::Trans::Options"; } - - void set_split_latitudes(bool); - void set_fft( FFT ); - void set_flt(bool); - void set_cache(const void* buffer, const size_t size); - void set_read(const std::string&); - void set_write(const std::string&); - - bool split_latitudes() const; - FFT fft() const; - bool flt() const; - const void* cache()const; - size_t cachesize() const; - std::string read() const; - std::string write() const; - - private: // not represented in Property internals - const void* cacheptr_; - size_t cachesize_; - }; - -public: - - /// @brief Constructor for grid-only setup - /// (e.g. for parallelisation routines) - Trans(const Grid& g, const Options& = Options() ); - - /// @brief Constructor for spectral-only setup - /// (e.g. for parallelisation routines) - Trans(const long truncation, const Options& = Options() ); - - /// @brief Constructor given grid and spectral truncation - Trans( const Grid& g, const long truncation, const Options& = Options() ); - - virtual ~Trans(); - operator Trans_t*() const { return &trans_; } - - size_t truncation() const { return std::max(0,trans_.nsmax); } - size_t nb_spectral_coefficients() const { return trans_.nspec2; } - size_t nb_spectral_coefficients_global() const { return trans_.nspec2g; } - size_t nb_gridpoints() const { return trans_.ngptot; } - size_t nb_gridpoints_global() const { return trans_.ngptotg; } - - grid::StructuredGrid grid() const { return grid_; } - - - /*! - * @brief distspec - * @param nb_fields - * @param origin - * @param global_spectra - * @param spectra - */ - void distspec( const int nb_fields, const int origin[], const double global_spectra[], double spectra[] ) const; - - /*! - * @brief gathspec - * @param nb_fields - * @param destination - * @param spectra - * @param global_spectra - */ - void gathspec( const int nb_fields, const int destination[], const double spectra[], double global_spectra[] ) const; - - /*! - * @brief distgrid - * @param nb_fields - * @param origin - * @param global_fields - * @param fields - */ - void distgrid( const int nb_fields, const int origin[], const double global_fields[], double fields[] ) const; - - /*! - * @brief gathgrid - * @param nb_fields - * @param destination - * @param fields - * @param global_fields - */ - void gathgrid( const int nb_fields, const int destination[], const double fields[], double global_fields[] ) const; - - void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const TransParameters& = TransParameters() ) const; - - /*! - * @brief invtrans - * @param nb_fields - * @param scalar_spectra - * @param scalar_fields - */ - void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - double gp_fields[], - const TransParameters& = TransParameters() ) const; - - /*! - * @brief Inverse transform of vorticity/divergence to wind(U/V) - * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) - */ - void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const TransParameters& = TransParameters()) const; - - /*! - * @brief Direct transform of scalar fields - */ - void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[] ) const; - - /*! - * @brief Direct transform of wind(U/V) to vorticity/divergence - * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) - */ - void dirtrans(const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[] ) const; - - void dirtrans(const Field& gpfield, - Field& spfield, - const TransParameters& = TransParameters()) const; - void dirtrans(const FieldSet& gpfields, - FieldSet& spfields, - const TransParameters& = TransParameters()) const; - - void dirtrans(const functionspace::NodeColumns&, const Field& gpfield, - const functionspace::Spectral&, Field& spfield, - const TransParameters& = TransParameters()) const; - void dirtrans(const functionspace::NodeColumns&, const FieldSet& gpfields, - const functionspace::Spectral&, FieldSet& spfields, - const TransParameters& = TransParameters()) const; - void dirtrans_wind2vordiv(const functionspace::NodeColumns&, const Field& gpwind, - const functionspace::Spectral&, Field& spvor, Field& spdiv, - const TransParameters& = TransParameters()) const; - - void invtrans(const Field& spfield, - Field& gpfield, - const TransParameters& = TransParameters()) const; - void invtrans(const FieldSet& spfields, - FieldSet& gpfields, - const TransParameters& = TransParameters()) const; - - void invtrans(const functionspace::Spectral&, const Field& spfield, - const functionspace::NodeColumns&, Field& gpfield, - const TransParameters& = TransParameters()) const; - void invtrans(const functionspace::Spectral&, const FieldSet& spfields, - const functionspace::NodeColumns&, FieldSet& gpfields, - const TransParameters& = TransParameters()) const; - void invtrans_vordiv2wind(const functionspace::Spectral&, const Field& spvor, const Field& spdiv, - const functionspace::NodeColumns&, Field& gpwind, - const TransParameters& = TransParameters()) const; - - void invtrans_grad(const functionspace::Spectral& sp, const Field& spfield, - const functionspace::NodeColumns& gp, Field& gradfield) const; - - - void invtrans_grad(const functionspace::Spectral& sp, const FieldSet& spfields, - const functionspace::NodeColumns& gp, FieldSet& gradfields) const; - - void specnorm( const int nb_fields, const double spectra[], double norms[], int rank=0 ) const; - - -private: - - void ctor( const Grid&, long nsmax, const Options& ); - - void ctor_rgg(const long nlat, const long pl[], long nsmax, const Options& ); - - void ctor_lonlat(const long nlon, const long nlat, long nsmax, const Options& ); - - void ctor_spectral_only(long truncation, const Trans::Options& p ); - -private: - friend class grid::detail::partitioner::TransPartitioner; - int handle() const { return trans_.handle; } - int ndgl() const { return trans_.ndgl; } - int nsmax() const { return trans_.nsmax; } - int ngptot() const { return trans_.ngptot; } - int ngptotg() const { return trans_.ngptotg; } - int ngptotmx() const { return trans_.ngptotmx; } - int nspec() const { return trans_.nspec; } - int nspec2() const { return trans_.nspec2; } - int nspec2g() const { return trans_.nspec2g; } - int nspec2mx() const { return trans_.nspec2mx; } - int n_regions_NS() const { return trans_.n_regions_NS; } - int n_regions_EW() const { return trans_.n_regions_EW; } - int nump() const { return trans_.nump; } - int nproc() const { return trans_.nproc; } - int myproc(int proc0=0) const { return trans_.myproc-1+proc0; } - - const int* nloen(int& size) const - { - size = trans_.ndgl; - ASSERT( trans_.nloen != NULL ); - return trans_.nloen; - } - - array::LocalView nloen() const - { - ASSERT( trans_.nloen != NULL ); - return array::LocalView(trans_.nloen, array::make_shape(trans_.ndgl)); - } - - const int* n_regions(int& size) const - { - size = trans_.n_regions_NS; - ASSERT( trans_.n_regions != NULL ); - return trans_.n_regions; - } - - array::LocalView n_regions() const - { - ASSERT( trans_.n_regions != NULL ); - return array::LocalView(trans_.n_regions, array::make_shape(trans_.n_regions_NS)); - } - - - const int* nfrstlat(int& size) const - { - size = trans_.n_regions_NS; - if( trans_.nfrstlat == NULL ) ::trans_inquire(&trans_,"nfrstlat"); - return trans_.nfrstlat; - } - - array::LocalView nfrstlat() const - { - if( trans_.nfrstlat == NULL ) ::trans_inquire(&trans_,"nfrstlat"); - return array::LocalView(trans_.nfrstlat, array::make_shape(trans_.n_regions_NS)); - } - - const int* nlstlat(int& size) const - { - size = trans_.n_regions_NS; - if( trans_.nlstlat == NULL ) ::trans_inquire(&trans_,"nlstlat"); - return trans_.nlstlat; - } - - array::LocalView nlstlat() const - { - if( trans_.nlstlat == NULL ) ::trans_inquire(&trans_,"nlstlat"); - return array::LocalView(trans_.nlstlat, array::make_shape(trans_.n_regions_NS)); - } - - const int* nptrfrstlat(int& size) const - { - size = trans_.n_regions_NS; - if( trans_.nptrfrstlat == NULL ) ::trans_inquire(&trans_,"nptrfrstlat"); - return trans_.nptrfrstlat; - } - - array::LocalView nptrfrstlat() const - { - if( trans_.nptrfrstlat == NULL ) ::trans_inquire(&trans_,"nptrfrstlat"); - return array::LocalView(trans_.nptrfrstlat, array::make_shape(trans_.n_regions_NS)); - } - - const int* nsta(int& sizef2, int& sizef1) const - { - sizef1 = trans_.ndgl+trans_.n_regions_NS-1; - sizef2 = trans_.n_regions_EW; - if( trans_.nsta == NULL ) ::trans_inquire(&trans_,"nsta"); - return trans_.nsta; - } - - array::LocalView nsta() const - { - if( trans_.nsta == NULL ) ::trans_inquire(&trans_,"nsta"); - return array::LocalView( trans_.nsta, array::make_shape(trans_.n_regions_EW, trans_.ndgl+trans_.n_regions_NS-1) ); - } - - const int* nonl(int& sizef2, int& sizef1) const - { - sizef1 = trans_.ndgl+trans_.n_regions_NS-1; - sizef2 = trans_.n_regions_EW; - if( trans_.nonl == NULL ) ::trans_inquire(&trans_,"nonl"); - return trans_.nonl; - } - - array::LocalView nonl() const - { - if( trans_.nonl == NULL ) ::trans_inquire(&trans_,"nonl"); - return array::LocalView( trans_.nonl, array::make_shape(trans_.n_regions_EW, trans_.ndgl+trans_.n_regions_NS-1) ); - } - - const int* nmyms(int& size) const - { - size = trans_.nump; - if( trans_.nmyms == NULL ) ::trans_inquire(&trans_,"nmyms"); - return trans_.nmyms; - } - - array::LocalView nmyms() const - { - if( trans_.nmyms == NULL ) ::trans_inquire(&trans_,"nmyms"); - return array::LocalView (trans_.nmyms, array::make_shape(trans_.nump)); - } - - const int* nasm0(int& size) const - { - size = trans_.nsmax+1; // +1 because zeroth wave included - if( trans_.nasm0 == NULL ) ::trans_inquire(&trans_,"nasm0"); - return trans_.nasm0; - } - - array::LocalView nasm0() const - { - if( trans_.nasm0 == NULL ) ::trans_inquire(&trans_,"nasm0"); - return array::LocalView (trans_.nasm0, array::make_shape(trans_.nsmax+1) ); - } - - const int* nvalue(int& size) const - { - size = trans_.nspec2; - if( trans_.nvalue == NULL ) ::trans_inquire(&trans_,"nvalue"); - return trans_.nvalue; - } - - array::LocalView nvalue() const - { - if( trans_.nvalue == NULL ) ::trans_inquire(&trans_,"nvalue"); - return array::LocalView (trans_.nvalue, array::make_shape(trans_.nspec2)); - } - -private: - mutable Trans_t trans_; - grid::StructuredGrid grid_; + virtual ~TransImpl() = 0; + + virtual int truncation() const = 0; + + virtual void dirtrans( const Field& gpfield, + Field& spfield, + const eckit::Configuration& = util::NoConfig() ) const = 0; + + virtual void dirtrans( const FieldSet& gpfields, + FieldSet& spfields, + const eckit::Configuration& = util::NoConfig() ) const = 0; + + virtual void dirtrans_wind2vordiv( const Field& gpwind, + Field& spvor, Field& spdiv, + const eckit::Configuration& = util::NoConfig() ) const = 0; + + virtual void invtrans( const Field& spfield, + Field& gpfield, + const eckit::Configuration& = util::NoConfig() ) const = 0; + + virtual void invtrans( const FieldSet& spfields, + FieldSet& gpfields, + const eckit::Configuration& = util::NoConfig() ) const = 0; + + virtual void invtrans_grad( const Field& spfield, + Field& gradfield, + const eckit::Configuration& = util::NoConfig() ) const = 0; + + virtual void invtrans_grad( const FieldSet& spfields, + FieldSet& gradfields, + const eckit::Configuration& = util::NoConfig() ) const = 0; + + + virtual void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, + Field& gpwind, + const eckit::Configuration& = util::NoConfig() ) const = 0; + + // -- IFS type fields -- + // These fields have special interpretation required. You need to know what you're doing. + // See IFS trans library. + + /*! + * @brief invtrans + * @param nb_scalar_fields + * @param scalar_spectra + * @param nb_vordiv_fields + * @param vorticity_spectra + * @param divergence_spectra + * @param gp_fields + */ + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], + const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const = 0; + + /*! + * @brief invtrans + * @param nb_fields + * @param scalar_spectra + * @param scalar_fields + */ + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const = 0; + + /*! + * @brief Inverse transform of vorticity/divergence to wind(U/V) + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ + virtual void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const = 0; + + /*! + * @brief Direct transform of scalar fields + */ + virtual void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& = util::NoConfig() ) const = 0; + + /*! + * @brief Direct transform of wind(U/V) to vorticity/divergence + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ + virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], + const eckit::Configuration& = util::NoConfig() ) const = 0; }; -//----------------------------------------------------------------------------- - -// C wrapper interfaces to C++ routines - -extern "C" -{ - Trans* atlas__Trans__new (const Grid::Implementation* grid, int nsmax); - void atlas__Trans__delete (Trans* trans); - void atlas__Trans__distspec (const Trans* t, int nb_fields, int origin[], double global_spectra[], double spectra[]); - void atlas__Trans__gathspec (const Trans* t, int nb_fields, int destination[], double spectra[], double global_spectra[]); - void atlas__Trans__distgrid (const Trans* t, int nb_fields, int origin[], double global_fields[], double fields[]); - void atlas__Trans__gathgrid (const Trans* t, int nb_fields, int destination[], double fields[], double global_fields[]); - void atlas__Trans__invtrans (const Trans* t, int nb_scalar_fields, double scalar_spectra[], int nb_vordiv_fields, double vorticity_spectra[], double divergence_spectra[], double gp_fields[], const TransParameters* parameters); - void atlas__Trans__invtrans_scalar (const Trans* t, int nb_fields, double scalar_spectra[], double scalar_fields[]); - void atlas__Trans__invtrans_vordiv2wind (const Trans* t, int nb_fields, double vorticity_spectra[], double divergence_spectra[], double wind_fields[]); - void atlas__Trans__dirtrans_scalar (const Trans* t, int nb_fields, double scalar_fields[], double scalar_spectra[]); - void atlas__Trans__dirtrans_wind2vordiv (const Trans* t, int nb_fields, double wind_fields[], double vorticity_spectra[], double divergence_spectra[]); - void atlas__Trans__specnorm (const Trans* t, int nb_fields, double spectra[], double norms[], int rank); - void atlas__Trans__dirtrans_fieldset (const Trans* This, const field::FieldSetImpl* gpfields, field::FieldSetImpl* spfields, const TransParameters* parameters); - void atlas__Trans__dirtrans_field (const Trans* This, const field::FieldImpl* gpfield, field::FieldImpl* spfield, const TransParameters* parameters); - void atlas__Trans__invtrans_fieldset (const Trans* This, const field::FieldSetImpl* spfields, field::FieldSetImpl* gpfields, const TransParameters* parameters); - void atlas__Trans__invtrans_field (const Trans* This, const field::FieldImpl* spfield, field::FieldImpl* gpfield, const TransParameters* parameters); - void atlas__Trans__dirtrans_fieldset_nodes (const Trans* This, const functionspace::detail::NodeColumns* gp, const field::FieldSetImpl* gpfields, const functionspace::detail::Spectral* sp, field::FieldSetImpl* spfields, const TransParameters* parameters); - void atlas__Trans__invtrans_fieldset_nodes (const Trans* This, const functionspace::detail::Spectral* sp, const field::FieldSetImpl* spfields, const functionspace::detail::NodeColumns* gp, field::FieldSetImpl* gpfields, const TransParameters* parameters); - void atlas__Trans__dirtrans_field_nodes (const Trans* This, const functionspace::detail::NodeColumns* gp, const field::FieldImpl* gpfield, const functionspace::detail::Spectral* sp, field::FieldImpl* spfield, const TransParameters* parameters); - void atlas__Trans__invtrans_field_nodes (const Trans* This, const functionspace::detail::Spectral* sp, const field::FieldImpl* spfield, const functionspace::detail::NodeColumns* gp, field::FieldImpl* gpfield, const TransParameters* parameters); - void atlas__Trans__dirtrans_wind2vordiv_field_nodes (const Trans* This, const functionspace::detail::NodeColumns* gp, const field::FieldImpl* gpwind, const functionspace::detail::Spectral* sp, field::FieldImpl* spvor, field::FieldImpl* spdiv, const TransParameters* parameters); - void atlas__Trans__invtrans_vordiv2wind_field_nodes (const Trans* This, const functionspace::detail::Spectral* sp, const field::FieldImpl* spvor, const field::FieldImpl* spdiv, const functionspace::detail::NodeColumns* gp, field::FieldImpl* gpwind, const TransParameters* parameters); - void atlas__Trans__invtrans_grad_field_nodes (const Trans* This, const functionspace::detail::Spectral* sp, const field::FieldImpl* spfield, const functionspace::detail::NodeColumns* gp, field::FieldImpl* gpfield); - - int atlas__Trans__handle (const Trans* trans); - int atlas__Trans__truncation (const Trans* This); - int atlas__Trans__nspec2 (const Trans* This); - int atlas__Trans__nspec2g (const Trans* This); - int atlas__Trans__ngptot (const Trans* This); - int atlas__Trans__ngptotg (const Trans* This); - const Grid::Implementation* atlas__Trans__grid(const Trans* This); - TransParameters* atlas__TransParameters__new (); - void atlas__TransParameters__delete (TransParameters* parameters); -} - // ------------------------------------------------------------------ } // namespace trans } // namespace atlas + diff --git a/src/atlas/trans/detail/TransIFS.cc b/src/atlas/trans/detail/TransIFS.cc new file mode 100644 index 000000000..fcd2e4f97 --- /dev/null +++ b/src/atlas/trans/detail/TransIFS.cc @@ -0,0 +1,1734 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/trans/detail/TransIFS.h" + +#include "eckit/parser/JSON.h" +#include "atlas/array.h" +#include "atlas/functionspace/NodeColumns.h" +#include "atlas/functionspace/Spectral.h" +#include "atlas/functionspace/StructuredColumns.h" +#include "atlas/mesh/IsGhostNode.h" +#include "atlas/mesh/Nodes.h" +#include "atlas/runtime/ErrorHandling.h" +#include "atlas/runtime/Log.h" +#include "atlas/parallel/mpi/mpi.h" + +using Topology = atlas::mesh::Nodes::Topology; +using atlas::mesh::IsGhostNode; +using atlas::functionspace::StructuredColumns; +using atlas::functionspace::NodeColumns; +using atlas::functionspace::Spectral; +using atlas::Field; +using atlas::array::ArrayView; +using atlas::array::make_view; + +namespace atlas { +namespace trans { + +class TransParameters { +public: + TransParameters( const eckit::Configuration& config ) : config_(config) {} + ~TransParameters() {} + + bool scalar_derivatives() const { + return config_.getBool("scalar_derivatives",false); + } + + bool wind_EW_derivatives() const { + return config_.getBool("wind_EW_derivatives",false); + } + + bool vorticity_divergence_fields() const { + return config_.getBool("vorticity_divergence_fields",false); + } + +private: + const eckit::Configuration& config_; +}; + +namespace { +std::string fieldset_functionspace( const FieldSet& fields ) { + std::string functionspace("undefined"); + for( size_t jfld = 0; jfld < fields.size(); ++jfld) { + if( functionspace == "undefined" ) + functionspace = fields[jfld].functionspace().type(); + if( fields[jfld].functionspace().type() != functionspace ) { + throw eckit::SeriousBug("trans: fielset has fields with different functionspaces",Here()); + } + } + return functionspace; +} +void assert_spectral_functionspace( const FieldSet& fields ){ + for( size_t jfld = 0; jfld < fields.size(); ++jfld ) { + ASSERT( functionspace::Spectral( fields[jfld].functionspace() ) ); + } +} + +void trans_check(const int code, const char* msg, const eckit::CodeLocation& location) { + if(code != TRANS_SUCCESS) { + std::stringstream errmsg; + errmsg << "atlas::trans ERROR: " << msg << " failed: \n"; + errmsg << ::trans_error_msg(code); + throw eckit::Exception(errmsg.str(),location); + } +} +#define TRANS_CHECK( CALL ) trans_check(CALL, #CALL, Here() ) + +} + +void TransIFS::dirtrans( const Field& gpfield, + Field& spfield, + const eckit::Configuration& config ) const { + ASSERT( functionspace::Spectral(spfield.functionspace()) ); + if( functionspace::StructuredColumns( gpfield.functionspace() ) ) { + __dirtrans( functionspace::StructuredColumns( gpfield.functionspace() ), gpfield , functionspace::Spectral( spfield.functionspace() ), spfield, config ); + } else if( functionspace::NodeColumns( gpfield.functionspace() ) ) { + __dirtrans( functionspace::NodeColumns( gpfield.functionspace() ), gpfield, functionspace::Spectral( spfield.functionspace() ), spfield, config ); + } else { + NOTIMP; + } +} + + +void TransIFS::dirtrans( const FieldSet& gpfields, + FieldSet& spfields, + const eckit::Configuration& config ) const { + assert_spectral_functionspace(spfields); + std::string functionspace( fieldset_functionspace(gpfields) ); + + if( functionspace == StructuredColumns::type() ) { + __dirtrans( StructuredColumns( gpfields[0].functionspace() ), gpfields, + Spectral( spfields[0].functionspace()), spfields, config ); + } else if ( functionspace == NodeColumns::type() ) { + __dirtrans( NodeColumns( gpfields[0].functionspace() ), gpfields, + Spectral( spfields[0].functionspace()), spfields, config ); + } else { + NOTIMP; + } +} + + +void TransIFS::invtrans( const Field& spfield, + Field& gpfield, + const eckit::Configuration& config ) const +{ + ASSERT( Spectral( spfield.functionspace()) ); + if( StructuredColumns( gpfield.functionspace()) ) { + __invtrans( Spectral( spfield.functionspace() ), spfield, StructuredColumns( gpfield.functionspace() ), gpfield, config ); + } else if( NodeColumns( gpfield.functionspace()) ) { + __invtrans( Spectral( spfield.functionspace() ), spfield, NodeColumns( gpfield.functionspace() ), gpfield, config ); + } else { + NOTIMP; + } +} + +void TransIFS::invtrans( const FieldSet& spfields, + FieldSet& gpfields, + const eckit::Configuration& config ) const +{ + assert_spectral_functionspace( spfields ); + std::string functionspace( fieldset_functionspace(gpfields) ); + + if( functionspace == StructuredColumns::type() ) { + __invtrans( Spectral(spfields[0].functionspace()), spfields, StructuredColumns(gpfields[0].functionspace()), gpfields, config ); + } else if ( functionspace == NodeColumns::type() ) { + __invtrans( Spectral(spfields[0].functionspace()), spfields, NodeColumns(gpfields[0].functionspace()), gpfields, config ); + } else { + NOTIMP; + } +} + +// -------------------------------------------------------------------------------------------- + +void TransIFS::invtrans_grad( + const Field& spfield, + Field& gradfield, + const eckit::Configuration& config ) const +{ + ASSERT( Spectral(spfield.functionspace()) ); + ASSERT( NodeColumns(gradfield.functionspace()) ); + __invtrans_grad( Spectral(spfield.functionspace()), spfield, NodeColumns(gradfield.functionspace()), gradfield, config ); +} + +void TransIFS::invtrans_grad( + const FieldSet& spfields, + FieldSet& gradfields, + const eckit::Configuration& config ) const +{ + assert_spectral_functionspace(spfields); + std::string functionspace( fieldset_functionspace(gradfields) ); + + if ( functionspace == NodeColumns::type() ) { + __invtrans_grad( Spectral( spfields[0].functionspace()), spfields, + NodeColumns( gradfields[0].functionspace() ), gradfields, config ); + } else { + NOTIMP; + } +} + +void TransIFS::dirtrans_wind2vordiv( + const Field& gpwind, + Field& spvor, Field& spdiv, + const eckit::Configuration& config ) const { + ASSERT( Spectral( spvor.functionspace()) ); + ASSERT( Spectral( spdiv.functionspace()) ); + ASSERT( NodeColumns( gpwind.functionspace()) ); + __dirtrans_wind2vordiv( NodeColumns(gpwind.functionspace()), gpwind, Spectral(spvor.functionspace()), spvor, spdiv, config ); +} + +void TransIFS::invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, + Field& gpwind, + const eckit::Configuration& config ) const { + ASSERT( Spectral( spvor.functionspace() ) ); + ASSERT( Spectral( spdiv.functionspace() ) ); + ASSERT( NodeColumns( gpwind.functionspace() ) ); + __invtrans_vordiv2wind( Spectral(spvor.functionspace()), spvor, spdiv, NodeColumns(gpwind.functionspace()), gpwind, config ); +} + + +void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra[], + const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& config ) const +{ + TransParameters params(config); + struct ::InvTrans_t args = new_invtrans(trans_.get()); + args.nscalar = nb_scalar_fields; + args.rspscalar = scalar_spectra; + args.nvordiv = nb_vordiv_fields; + args.rspvor = vorticity_spectra; + args.rspdiv = divergence_spectra; + args.rgp = gp_fields; + if( params.scalar_derivatives() ) { + args.lscalarders = true; + } + if( params.wind_EW_derivatives() ) { + args.luvder_EW = true; + } + if( params.vorticity_divergence_fields() ) { + args.lvordivgp = true; + } + TRANS_CHECK( ::trans_invtrans(&args) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra[], + double gp_fields[], + const eckit::Configuration& config ) const +{ + TransParameters params(config); + struct ::InvTrans_t args = new_invtrans(trans_.get()); + args.nscalar = nb_scalar_fields; + args.rspscalar = scalar_spectra; + args.rgp = gp_fields; + if( params.scalar_derivatives() ) { + args.lscalarders = true; + } + TRANS_CHECK( ::trans_invtrans(&args) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void TransIFS::invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& config ) const +{ + TransParameters params(config); + struct ::InvTrans_t args = new_invtrans(trans_.get()); + args.nvordiv = nb_vordiv_fields; + args.rspvor = vorticity_spectra; + args.rspdiv = divergence_spectra; + args.rgp = gp_fields; + if( params.wind_EW_derivatives() ) { + args.luvder_EW = true; + } + if( params.vorticity_divergence_fields() ) { + args.lvordivgp = true; + } + TRANS_CHECK( ::trans_invtrans(&args) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void TransIFS::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& ) const +{ + struct ::DirTrans_t args = new_dirtrans(trans_.get()); + args.nscalar = nb_fields; + args.rgp = scalar_fields; + args.rspscalar = scalar_spectra; + TRANS_CHECK( ::trans_dirtrans(&args) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +void TransIFS::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], + const eckit::Configuration& ) const +{ + struct ::DirTrans_t args = new_dirtrans(trans_.get()); + args.nvordiv = nb_fields; + args.rspvor = vorticity_spectra; + args.rspdiv = divergence_spectra; + args.rgp = wind_fields; + TRANS_CHECK( ::trans_dirtrans(&args) ); +} + +} +} + + +// anonymous namespace +namespace { + +struct PackNodeColumns +{ + ArrayView& rgpview_; + IsGhostNode is_ghost; + size_t f; + + PackNodeColumns( ArrayView& rgpview, const NodeColumns& fs ) : + rgpview_(rgpview), is_ghost( fs.nodes() ), f(0) {} + + void operator()(const Field& field, int components = 0) { + switch (field.rank()) { + case 1: + pack_1(field,components); + break; + case 2: + pack_2(field,components); + break; + case 3: + pack_3(field,components); + break; + default: + ATLAS_DEBUG_VAR(field.rank()); + NOTIMP; + break; + } + } + + void pack_1(const Field& field, int) + { + const ArrayView gpfield = make_view( field ); + size_t n=0; + for( size_t jnode=0; jnode gpfield = make_view( field ); + const size_t nvars = gpfield.shape(1); + for( size_t jvar=0; jvar gpfield = make_view( field ); + if( not components ) components = gpfield.shape(2); + for( size_t jcomp=0; jcomp& rgpview_; + size_t f; + + PackStructuredColumns( ArrayView& rgpview ) : + rgpview_(rgpview), f(0) {} + + void operator()(const Field& field) { + switch (field.rank()) { + case 1: + pack_1(field); + break; + case 2: + pack_2(field); + break; + default: + ATLAS_DEBUG_VAR(field.rank()); + NOTIMP; + break; + } + } + + void pack_1(const Field& field) + { + const ArrayView gpfield = make_view( field ); + size_t n=0; + for( size_t jnode=0; jnode gpfield = make_view( field ); + const size_t nvars = gpfield.shape(1); + for( size_t jvar=0; jvar& rspecview_; + size_t f; + PackSpectral( ArrayView& rspecview ) : + rspecview_(rspecview), f(0) {} + + void operator()(const Field& field) { + switch (field.rank()) { + case 1: + pack_1(field); + break; + case 2: + pack_2(field); + break; + default: + ATLAS_DEBUG_VAR(field.rank()); + NOTIMP; + break; + } + } + + void pack_1(const Field& field) + { + const ArrayView spfield = make_view( field ); + + for( size_t jwave=0; jwave spfield = make_view( field ); + + const size_t nvars = spfield.shape(1); + + for( size_t jvar=0; jvar& rgpview_; + IsGhostNode is_ghost; + size_t f; + + UnpackNodeColumns( const ArrayView& rgpview, const NodeColumns& fs ) : + rgpview_(rgpview), is_ghost( fs.nodes() ), f(0) {} + + void operator()(Field& field, int components = 0) { + switch (field.rank()) { + case 1: + unpack_1(field,components); + break; + case 2: + unpack_2(field,components); + break; + case 3: + unpack_3(field,components); + break; + default: + ATLAS_DEBUG_VAR(field.rank()); + NOTIMP; + break; + } + } + + void unpack_1(Field& field, int) + { + ArrayView gpfield = make_view( field ); + size_t n(0); + for( size_t jnode=0; jnode gpfield = make_view( field ); + const size_t nvars = gpfield.shape(1); + for( size_t jvar=0; jvar gpfield = make_view( field ); + if( not components ) components = gpfield.shape(2); + for( size_t jcomp=0; jcomp& rgpview_; + size_t f; + + UnpackStructuredColumns( const ArrayView& rgpview ) : + rgpview_(rgpview), f(0) {} + + void operator()(Field& field) { + switch (field.rank()) { + case 1: + unpack_1(field); + break; + case 2: + unpack_2(field); + break; + default: + ATLAS_DEBUG_VAR(field.rank()); + NOTIMP; + break; + } + } + + void unpack_1(Field& field) + { + ArrayView gpfield = make_view( field ); + size_t n=0; + for( size_t jnode=0; jnode gpfield = make_view( field ); + const size_t nvars = gpfield.shape(1); + for( size_t jvar=0; jvar& rspecview_; + size_t f; + UnpackSpectral( const ArrayView& rspecview ) : + rspecview_(rspecview), f(0) {} + + void operator()(Field& field) { + switch (field.rank()) { + case 1: + unpack_1(field); + break; + case 2: + unpack_2(field); + break; + default: + ATLAS_DEBUG_VAR(field.rank()); + NOTIMP; + break; + } + } + + void unpack_1(Field& field) + { + ArrayView spfield = make_view( field ); + + for( size_t jwave=0; jwave spfield = make_view( field ); + + const size_t nvars = spfield.shape(1); + + for( size_t jvar=0; jvar( new ::Trans_t, [](::Trans_t* p) { + ::trans_delete(p); + delete p; + }); + + if( auto gg = grid::GaussianGrid(grid) ) { + ctor_rgg(gg.ny(), gg.nx().data(), truncation, p); + return; + } + if( auto ll = grid::RegularLonLatGrid(grid) ) { + if( ll.standard() || ll.shifted() ) { + ctor_lonlat( ll.nx(), ll.ny(), truncation, p ); + return; + } + } + throw eckit::NotImplemented("Grid type not supported for Spectral Transforms",Here()); +} + +void TransIFS::ctor_spectral_only(long truncation, const TransIFS::Options& p ) +{ + 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(parallel::mpi::comm().size()>1)); + TRANS_CHECK(::trans_setup(trans_.get())); +} + +void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const TransIFS::Options& p ) +{ + std::vector nloen(nlat); + for( long jlat=0; jlat= 0 ) + TRANS_CHECK(::trans_set_trunc(trans_.get(),truncation)); + TRANS_CHECK(::trans_set_cache(trans_.get(),p.cache(),p.cachesize())); + + if( not p.read().empty() ) + { + if( eckit::PathName(p.read()).exists() ) + { + std::stringstream msg; msg << "File " << p.read() << "doesn't exist"; + throw eckit::CantOpenFile(msg.str(),Here()); + } + TRANS_CHECK(::trans_set_read(trans_.get(),p.read().c_str())); + } + if( !p.write().empty() ) + TRANS_CHECK(::trans_set_write(trans_.get(),p.write().c_str())); + + trans_->fft = p.fft(); + trans_->lsplit = p.split_latitudes(); + trans_->flt = p.flt(); + + TRANS_CHECK(::trans_use_mpi(parallel::mpi::comm().size()>1)); + TRANS_CHECK(::trans_setup(trans_.get())); +} + +void TransIFS::ctor_lonlat(const long nlon, const long nlat, long truncation, const TransIFS::Options& p ) +{ + TRANS_CHECK(::trans_new(trans_.get())); + 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(),p.cache(),p.cachesize())); + + if( not p.read().empty() ) + { + if( eckit::PathName(p.read()).exists() ) + { + std::stringstream msg; msg << "File " << p.read() << "doesn't exist"; + throw eckit::CantOpenFile(msg.str(),Here()); + } + TRANS_CHECK(::trans_set_read(trans_.get(),p.read().c_str())); + } + if( not p.write().empty() ) + TRANS_CHECK(::trans_set_write(trans_.get(),p.write().c_str())); + + trans_->fft = p.fft(); + trans_->lsplit = p.split_latitudes(); + trans_->flt = p.flt(); + + TRANS_CHECK(::trans_use_mpi(parallel::mpi::comm().size()>1)); + TRANS_CHECK(::trans_setup(trans_.get())); +} + +TransIFS::Options::Options() : util::Config() +{ + set_cache(nullptr,0); + set_split_latitudes(true); + set_fft(FFTW); + set_flt(false); +} + +void TransIFS::Options::set_cache(const void* buffer, size_t size) +{ + cacheptr_=buffer; + cachesize_=size; +} + +const void* TransIFS::Options::cache() const +{ + return cacheptr_; +} + +size_t TransIFS::Options::cachesize() const +{ + return cachesize_; +} + +void TransIFS::Options::set_fft( FFT fft ) +{ + if( fft == FFTW ) + { + set( "fft", "FFTW" ); + } + else if( fft == FFT992 ) + { + set( "fft", "FFT992" ); + } + else + { + NOTIMP; + } +} + +void TransIFS::Options::set_split_latitudes( bool split ) +{ + set("split_latitudes",split); +} + +void TransIFS::Options::set_flt( bool flt ) +{ + set("flt",flt); +} + +bool TransIFS::Options::split_latitudes() const +{ + return getBool("split_latitudes"); +} + +FFT TransIFS::Options::fft() const +{ + std::string fftstr = getString( "fft" ); + if( fftstr == "FFTW" ) + return FFTW; + else if( fftstr == "FFT992" ) + return FFT992; + else + NOTIMP; + return FFTW; +} + +bool TransIFS::Options::flt() const +{ + return getBool("flt"); +} + + +void TransIFS::Options::set_read(const std::string& file) +{ + set("read",file); +} + +std::string TransIFS::Options::read() const +{ + return getString("read",""); +} + +void TransIFS::Options::set_write(const std::string& file) +{ + set("write",file); +} + +std::string TransIFS::Options::write() const +{ + return getString("write",""); +} + + +// -------------------------------------------------------------------------------------------- + + + +void TransIFS::__dirtrans( const functionspace::NodeColumns& gp, const Field& gpfield, + const Spectral& sp, Field& spfield, const eckit::Configuration& config ) const +{ + FieldSet gpfields; gpfields.add(gpfield); + FieldSet spfields; spfields.add(spfield); + __dirtrans(gp,gpfields,sp,spfields,config); +} + + +// -------------------------------------------------------------------------------------------- + +void TransIFS::__dirtrans( const functionspace::NodeColumns& gp,const FieldSet& gpfields, + const Spectral& sp, FieldSet& spfields, const eckit::Configuration& ) const +{ + // Count total number of fields and do sanity checks + int nfld(0); + for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) + { + const Field& f = gpfields[jfld]; + nfld += f.stride(0); + } + + int trans_spnfld(0); + for(size_t jfld = 0; jfld < spfields.size(); ++jfld) + { + const Field& f = spfields[jfld]; + trans_spnfld += f.stride(0); + } + + if( nfld != trans_spnfld ) + { + throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); + } + // Arrays Trans expects + array::ArrayT rgp(nfld,ngptot()); + array::ArrayT rspec(nspec2(),nfld); + + array::ArrayView rgpview = array::make_view(rgp); + array::ArrayView rspecview = array::make_view(rspec); + + // Pack gridpoints + { + PackNodeColumns pack(rgpview,gp); + for( size_t jfld=0; jfld(); + transform.rspscalar = rspec.data(); + + TRANS_CHECK( ::trans_dirtrans(&transform) ); + } + + // Unpack the spectral fields + { + UnpackSpectral unpack(rspecview); + for( size_t jfld=0; jfld(); + transform.rspscalar = spfield.data(); + transform.ngpblks = gpfield.shape(0); + transform.nproma = 1; + TRANS_CHECK( ::trans_dirtrans(&transform) ); + } +} + +void TransIFS::__dirtrans( + const StructuredColumns&, const FieldSet& gpfields, + const Spectral&, FieldSet& spfields, + const eckit::Configuration& ) const +{ + // Count total number of fields and do sanity checks + int nfld(0); + for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) + { + const Field& f = gpfields[jfld]; + nfld += f.stride(0); + ASSERT( f.functionspace() == 0 || + functionspace::StructuredColumns(f.functionspace()) ); + } + + int trans_spnfld(0); + for(size_t jfld = 0; jfld < spfields.size(); ++jfld) + { + const Field& f = spfields[jfld]; + trans_spnfld += f.stride(0); + } + + if( nfld != trans_spnfld ) + { + throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); + } + // Arrays Trans expects + array::ArrayT rgp(nfld,ngptot()); + array::ArrayT rspec(nspec2(),nfld); + + array::ArrayView rgpview = array::make_view(rgp); + array::ArrayView rspecview = array::make_view(rspec); + + // Pack gridpoints + { + PackStructuredColumns pack(rgpview); + for( size_t jfld=0; jfld(); + transform.rspscalar = rspec.data(); + + TRANS_CHECK( ::trans_dirtrans(&transform) ); + } + + // Unpack the spectral fields + { + UnpackSpectral unpack(rspecview); + for( size_t jfld=0; jfld(1,f.levels()) == f.stride(0) ); + } + + if( nb_gridpoint_field != 2*nfld ) // factor 2 because N-S and E-W derivatives + throw eckit::SeriousBug("invtrans_grad: different number of gridpoint fields than spectral fields",Here()); + + // Arrays Trans expects + // Allocate space for + array::ArrayT rgp(3*nfld,ngptot()); // (scalars) + (NS ders) + (EW ders) + array::ArrayT rspec(nspec2(),nfld); + + array::ArrayView rgpview = array::make_view(rgp); + array::ArrayView rspecview = array::make_view(rspec); + + // Pack spectral fields + { + PackSpectral pack(rspecview); + for(size_t jfld = 0; jfld < spfields.size(); ++jfld) + pack(spfields[jfld]); + } + + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); + transform.nscalar = nfld; + transform.rgp = rgp.data(); + transform.rspscalar = rspec.data(); + transform.lscalarders = true; + + TRANS_CHECK(::trans_invtrans(&transform)); + } + + // Unpack the gridpoint fields + { + mesh::IsGhostNode is_ghost( gp.nodes()); + int f=nfld; // skip to where derivatives start + for(size_t dim=0; dim<2; ++dim) { + for(size_t jfld = 0; jfld < gradfields.size(); ++jfld) + { + const size_t nlev = std::max(1,gradfields[jfld].levels()); + const size_t nb_nodes = gradfields[jfld].shape(0); + + array::LocalView field ( gradfields[jfld].data(), + array::make_shape(nb_nodes, nlev, 2 ) ); + + for( size_t jlev=0; jlev rgp(nfld,ngptot()); + array::ArrayT rspec(nspec2(),nfld); + + array::ArrayView rgpview = array::make_view(rgp); + array::ArrayView rspecview = array::make_view(rspec); + + // Pack spectral fields + { + PackSpectral pack(rspecview); + for(size_t jfld = 0; jfld < spfields.size(); ++jfld) + pack(spfields[jfld]); + } + + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); + transform.nscalar = nfld; + transform.rgp = rgp.data(); + transform.rspscalar = rspec.data(); + + TRANS_CHECK(::trans_invtrans(&transform)); + } + + // Unpack the gridpoint fields + { + UnpackNodeColumns unpack(rgpview,gp); + for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) + unpack(gpfields[jfld]); + } + +} + +// -------------------------------------------------------------------------------------------- + + +void TransIFS::__invtrans( const functionspace::Spectral& sp, const Field& spfield, + const functionspace::StructuredColumns& gp, Field& gpfield, + const eckit::Configuration& config ) const +{ + ASSERT( gpfield.functionspace() == 0 || + functionspace::StructuredColumns( gpfield.functionspace() ) ); + ASSERT( spfield.functionspace() == 0 || + functionspace::Spectral( spfield.functionspace() ) ); + if ( gpfield.stride(0) != spfield.stride(0) ) + { + throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); + } + if ( (int)gpfield.shape(0) != ngptot() ) + { + throw eckit::SeriousBug("dirtrans: slowest moving index must be ngptot",Here()); + } + const int nfld = gpfield.stride(0); + + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); + transform.nscalar = nfld; + transform.rgp = gpfield.data(); + transform.rspscalar = spfield.data(); + transform.ngpblks = gpfield.shape(0); + transform.nproma = 1; + TRANS_CHECK( ::trans_invtrans(&transform) ); + } +} + + +// -------------------------------------------------------------------------------------------- + +void TransIFS::__invtrans( const functionspace::Spectral& sp, const FieldSet& spfields, + const functionspace::StructuredColumns& gp, FieldSet& gpfields, + const eckit::Configuration& config ) const +{ + // Count total number of fields and do sanity checks + int nfld(0); + for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) + { + const Field& f = gpfields[jfld]; + nfld += f.stride(0); + ASSERT( f.functionspace() == 0 || + functionspace::StructuredColumns( f.functionspace() ) ); + } + + int nb_spectral_fields(0); + for(size_t jfld = 0; jfld < spfields.size(); ++jfld) + { + const Field& f = spfields[jfld]; + nb_spectral_fields += f.stride(0); + } + + if( nfld != nb_spectral_fields ) { + std::stringstream msg; + msg << "invtrans: different number of gridpoint fields than spectral fields" + << "[ " << nfld << " != " << nb_spectral_fields << " ]"; + throw eckit::SeriousBug(msg.str(),Here()); + } + + // Arrays Trans expects + array::ArrayT rgp(nfld,ngptot()); + array::ArrayT rspec(nspec2(),nfld); + + array::ArrayView rgpview = array::make_view(rgp); + array::ArrayView rspecview = array::make_view(rspec); + + // Pack spectral fields + { + PackSpectral pack(rspecview); + for(size_t jfld = 0; jfld < spfields.size(); ++jfld) + pack(spfields[jfld]); + } + + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); + transform.nscalar = nfld; + transform.rgp = rgp.data(); + transform.rspscalar = rspec.data(); + + TRANS_CHECK(::trans_invtrans(&transform)); + } + + // Unpack the gridpoint fields + { + UnpackStructuredColumns unpack(rgpview); + for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) + unpack(gpfields[jfld]); + } +} + +// ----------------------------------------------------------------------------------------------- + +void TransIFS::__dirtrans_wind2vordiv( const functionspace::NodeColumns& gp, const Field& gpwind, + const Spectral& sp, Field& spvor, Field&spdiv, + const eckit::Configuration& ) const +{ + // Count total number of fields and do sanity checks + size_t nfld = spvor.stride(0); + if( spdiv.shape(0) != spvor.shape(0) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); + if( spdiv.shape(1) != spvor.shape(1) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); + size_t nwindfld = gpwind.stride(0); + if (nwindfld != 2*nfld && nwindfld != 3*nfld) throw eckit::SeriousBug("dirtrans: wind field is not compatible with vorticity, divergence.",Here()); + + if( spdiv.shape(0) != size_t(nspec2()) ) { + std::stringstream msg; + msg << "dirtrans: Spectral vorticity and divergence have wrong dimension: nspec2 "< rgp(2*nfld,size_t(ngptot())); + array::ArrayView rgpview = array::make_view(rgp); + + // Pack gridpoints + { + PackNodeColumns pack( rgpview, gp ); + int wind_components = 2; + pack(gpwind, wind_components); + } + + // Do transform + { + struct ::DirTrans_t transform = ::new_dirtrans(trans_.get()); + transform.nvordiv = nfld; + transform.rgp = rgp.data(); + transform.rspvor = spvor.data(); + transform.rspdiv = spdiv.data(); + + ASSERT( transform.rspvor ); + ASSERT( transform.rspdiv ); + TRANS_CHECK( ::trans_dirtrans(&transform) ); + } + ATLAS_DEBUG_HERE(); + +} + + +void TransIFS::__invtrans_vordiv2wind( const Spectral& sp, const Field& spvor, const Field& spdiv, + const functionspace::NodeColumns& gp, Field& gpwind, + const eckit::Configuration& config ) const +{ + // Count total number of fields and do sanity checks + size_t nfld = spvor.stride(0); + if( spdiv.shape(0) != spvor.shape(0) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); + if( spdiv.shape(1) != spvor.shape(1) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); + size_t nwindfld = gpwind.stride(0); + if (nwindfld != 2*nfld && nwindfld != 3*nfld) throw eckit::SeriousBug("invtrans: wind field is not compatible with vorticity, divergence.",Here()); + + if( spdiv.shape(0) != size_t(nspec2()) ) { + std::stringstream msg; + msg << "invtrans: Spectral vorticity and divergence have wrong dimension: nspec2 "< rgp(2*nfld,size_t(ngptot())); + array::ArrayView rgpview = array::make_view(rgp); + + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); + transform.nvordiv = nfld; + transform.rgp = rgp.data(); + transform.rspvor = spvor.data(); + transform.rspdiv = spdiv.data(); + + ASSERT( transform.rspvor ); + ASSERT( transform.rspdiv ); + TRANS_CHECK(::trans_invtrans(&transform)); + } + + // Unpack the gridpoint fields + { + UnpackNodeColumns unpack( rgpview, gp ); + int wind_components = 2; + unpack(gpwind,wind_components); + } + +} + +/////////////////////////////////////////////////////////////////////////////// + + +void TransIFS::distspec( const int nb_fields, const int origin[], const double global_spectra[], double spectra[] ) const +{ + struct ::DistSpec_t args = new_distspec(trans_.get()); + args.nfld = nb_fields; + args.rspecg = global_spectra; + args.nfrom = origin; + args.rspec = spectra; + TRANS_CHECK( ::trans_distspec(&args) ); +} + +///////////////////////////////////////////////////////////////////////////// + +void TransIFS::gathspec( const int nb_fields, const int destination[], const double spectra[], double global_spectra[] ) const +{ + struct ::GathSpec_t args = new_gathspec(trans_.get()); + args.nfld = nb_fields; + args.rspecg = global_spectra; + args.nto = destination; + args.rspec = spectra; + TRANS_CHECK( ::trans_gathspec(&args) ); +} + +///////////////////////////////////////////////////////////////////////////// + +void TransIFS::distgrid( const int nb_fields, const int origin[], const double global_fields[], double fields[] ) const +{ + struct ::DistGrid_t args = new_distgrid(trans_.get()); + args.nfld = nb_fields; + args.nfrom = origin; + args.rgpg = global_fields; + args.rgp = fields; + TRANS_CHECK( ::trans_distgrid(&args) ); +} + +///////////////////////////////////////////////////////////////////////////// + +void TransIFS::gathgrid( const int nb_fields, const int destination[], const double fields[], double global_fields[] ) const +{ + struct ::GathGrid_t args = new_gathgrid(trans_.get()); + args.nfld = nb_fields; + args.nto = destination; + args.rgp = fields; + args.rgpg = global_fields; + TRANS_CHECK( ::trans_gathgrid(&args) ); +} + +/////////////////////////////////////////////////////////////////////////////// + + +void TransIFS::specnorm( const int nb_fields, const double spectra[], double norms[], int rank ) const +{ + struct ::SpecNorm_t args = new_specnorm(trans_.get()); + args.nfld = nb_fields; + args.rspec = spectra; + args.rnorm = norms; + args.nmaster = rank+1; + TRANS_CHECK( ::trans_specnorm(&args) ); +} + +/////////////////////////////////////////////////////////////////////////////// + +extern "C" { + +TransIFS* atlas__Trans__new (const Grid::Implementation* grid, int nsmax) +{ + TransIFS* trans(0); + ATLAS_ERROR_HANDLING( + ASSERT( grid ); + trans = new TransIFS( Grid(grid) ,nsmax); + ); + return trans; +} + +void atlas__Trans__delete (TransIFS* This) +{ + ASSERT( This ); + ATLAS_ERROR_HANDLING( delete This ); +} + +int atlas__Trans__handle (const TransIFS* This) +{ + ASSERT( This ); + ATLAS_ERROR_HANDLING( + ::Trans_t* t = *This; + return t->handle; + ); + return 0; +} + +void atlas__Trans__distspec( const TransIFS* t, int nb_fields, int origin[], double global_spectra[], double spectra[] ) +{ + ATLAS_ERROR_HANDLING( + ASSERT( t ); + 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_ERROR_HANDLING( + ASSERT( t ); + 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_ERROR_HANDLING( + ASSERT( t ); + 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_ERROR_HANDLING( + ASSERT( t ); + 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_ERROR_HANDLING( + ASSERT( t ); + 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_ERROR_HANDLING( + ASSERT( t ); + 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_ERROR_HANDLING( + ASSERT( t ); + 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_ERROR_HANDLING( + ASSERT( t ); + 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_ERROR_HANDLING( + ASSERT( t ); + return t->specnorm(nb_fields, spectra, norms, rank); + ); +} + +int atlas__Trans__nspec2 (const TransIFS* This) +{ + ATLAS_ERROR_HANDLING( + ASSERT( This ); + return This->nb_spectral_coefficients(); + ); + return 0; +} + +int atlas__Trans__nspec2g (const TransIFS* This) +{ + ATLAS_ERROR_HANDLING( + ASSERT( This ); + return This->nb_spectral_coefficients_global(); + ); + return 0; +} + +int atlas__Trans__ngptot (const TransIFS* This) +{ + ATLAS_ERROR_HANDLING( + ASSERT( This ); + return This->nb_gridpoints(); + ); + return 0; +} + +int atlas__Trans__ngptotg (const TransIFS* This) +{ + ATLAS_ERROR_HANDLING( + ASSERT( This ); + return This->nb_gridpoints_global(); + ); + return 0; +} + +int atlas__Trans__truncation (const TransIFS* This) +{ + ATLAS_ERROR_HANDLING( + ASSERT( This ); + return This->truncation(); + ); + return 0; +} + +const Grid::Implementation* atlas__Trans__grid(const TransIFS* This) +{ + ATLAS_ERROR_HANDLING( + ASSERT( This ); + ASSERT( This->grid() ); + return This->grid().get(); + ); + return nullptr; +} + +void atlas__Trans__dirtrans_fieldset (const TransIFS* This, const field::FieldSetImpl* gpfields, field::FieldSetImpl* spfields, const eckit::Configuration* parameters) +{ + ATLAS_ERROR_HANDLING( + ASSERT( This ); + ASSERT( gpfields ); + ASSERT( spfields ); + 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_ERROR_HANDLING( + ASSERT( This ); + ASSERT( spfield ); + ASSERT( gpfield ); + 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_ERROR_HANDLING( + ASSERT( This ); + ASSERT( spfields ); + ASSERT( gpfields ); + 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_ERROR_HANDLING( + ASSERT( This ); + ASSERT( spfield ); + ASSERT( gpfield ); + 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_ERROR_HANDLING( + ASSERT( This ); + ASSERT( gpwind ); + ASSERT( spvor ); + ASSERT( spdiv ); + 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_ERROR_HANDLING( + ASSERT( This ); + ASSERT( spvor ); + ASSERT( spdiv ); + ASSERT( gpwind ); + 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_ERROR_HANDLING( + ASSERT(This); + 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_ERROR_HANDLING( + ASSERT( This ); + ASSERT( spfield ); + ASSERT( gpfield ); + Field fgpfield(gpfield); + This->invtrans_grad(spfield,fgpfield,*config); + ); +} + +} + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/detail/TransIFS.h b/src/atlas/trans/detail/TransIFS.h new file mode 100644 index 000000000..2578cbfce --- /dev/null +++ b/src/atlas/trans/detail/TransIFS.h @@ -0,0 +1,557 @@ +/* + * (C) Copyright 1996-2017 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 "transi/trans.h" +#include "atlas/array/LocalView.h" +#include "atlas/grid/Grid.h" +#include "atlas/trans/Trans.h" + +//----------------------------------------------------------------------------- +// Forward declarations + +namespace atlas { + class Field; + class FieldSet; +namespace field { + class FieldImpl; + class FieldSetImpl; +} +} + +namespace atlas { +namespace array { + class Array; +} +} + +namespace atlas { +namespace functionspace { + class StructuredColumns; + class NodeColumns; + class Spectral; +} +} + +namespace atlas { +namespace functionspace { +namespace detail { + class NodeColumns; + class Spectral; +} +} +} + +namespace atlas { +namespace grid { +namespace detail { +namespace partitioner { + class TransPartitioner; +} +} +} +} + + +//----------------------------------------------------------------------------- + +namespace atlas { +namespace trans { + +////----------------------------------------------------------------------------- + +namespace options { + +class scalar_derivatives : public util::Config { +public: + scalar_derivatives( bool v ) { set("scalar_derivatives",v); } +}; + +class wind_EW_derivatives : public util::Config { +public: + wind_EW_derivatives( bool v ) { set("wind_EW_derivatives",v); } +}; + +class vorticity_divergence_fields : public util::Config { +public: + vorticity_divergence_fields( bool v ) { set("vorticity_divergence_fields",v); } +}; + +} + +//----------------------------------------------------------------------------- + +enum FFT { FFT992=TRANS_FFT992, FFTW=TRANS_FFTW }; + +class TransIFS : public trans::TransImpl { +private: + typedef struct ::Trans_t Trans_t; + +public: + + class Options : public util::Config { + public: + + Options(); + ~Options() {} + + void set_split_latitudes(bool); + void set_fft( FFT ); + void set_flt(bool); + void set_cache(const void* buffer, const size_t size); + void set_read(const std::string&); + void set_write(const std::string&); + + bool split_latitudes() const; + FFT fft() const; + bool flt() const; + const void* cache()const; + size_t cachesize() const; + std::string read() const; + std::string write() const; + + private: // not represented in Configuration internals + const void* cacheptr_; + size_t cachesize_; + }; + + +public: + +// /// @brief Constructor for spectral-only setup +// /// (e.g. for parallelisation routines) +// TransIFS(const long truncation, const Options& = Options() ); + + /// @brief Constructor given grid and spectral truncation + TransIFS( const Grid& g, const long truncation, const Options& = Options() ); + + virtual ~TransIFS(); + operator ::Trans_t*() const { return trans(); } + ::Trans_t* trans() const { return trans_.get(); } + + virtual int truncation() const { return std::max(0,trans_->nsmax); } + size_t nb_spectral_coefficients() const { return trans_->nspec2; } + size_t nb_spectral_coefficients_global() const { return trans_->nspec2g; } + size_t nb_gridpoints() const { return trans_->ngptot; } + size_t nb_gridpoints_global() const { return trans_->ngptotg; } + + grid::StructuredGrid grid() const { return grid_; } + + + + // pure virtual interface + + virtual void dirtrans( const Field& gpfield, + Field& spfield, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void dirtrans( const FieldSet& gpfields, + FieldSet& spfields, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void dirtrans_wind2vordiv( const Field& gpwind, + Field& spvor, Field& spdiv, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void invtrans( const Field& spfield, + Field& gpfield, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void invtrans( const FieldSet& spfields, + FieldSet& gpfields, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void invtrans_grad( const Field& spfield, + Field& gradfield, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void invtrans_grad( const FieldSet& spfields, + FieldSet& gradfields, + const eckit::Configuration& = util::NoConfig() ) const override; + + + virtual void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, + Field& gpwind, + const eckit::Configuration& = util::NoConfig() ) const override; + +// -- IFS style API -- +// These fields have special interpretation required. You need to know what you're doing. +// See IFS trans library. + + /*! + * @brief invtrans + * @param nb_scalar_fields + * @param scalar_spectra + * @param nb_vordiv_fields + * @param vorticity_spectra + * @param divergence_spectra + * @param gp_fields + */ + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], + const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; + + /*! + * @brief invtrans + * @param nb_fields + * @param scalar_spectra + * @param scalar_fields + */ + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; + + /*! + * @brief Inverse transform of vorticity/divergence to wind(U/V) + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ + virtual void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; + + /*! + * @brief Direct transform of scalar fields + */ + virtual void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& = util::NoConfig() ) const override; + + /*! + * @brief Direct transform of wind(U/V) to vorticity/divergence + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ + virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], + const eckit::Configuration& = util::NoConfig() ) const override; + + + + + + + + + + + + + + + + + + + + + +// implementations + +public: + + void __dirtrans(const functionspace::StructuredColumns&, const Field& gpfield, + const functionspace::Spectral&, Field& spfield, + const eckit::Configuration& = util::NoConfig() ) const; + void __dirtrans(const functionspace::StructuredColumns&, const FieldSet& gpfields, + const functionspace::Spectral&, FieldSet& spfields, + const eckit::Configuration& = util::NoConfig() ) const; + + void __dirtrans(const functionspace::NodeColumns&, const Field& gpfield, + const functionspace::Spectral&, Field& spfield, + const eckit::Configuration& = util::NoConfig() ) const; + void __dirtrans(const functionspace::NodeColumns&, const FieldSet& gpfields, + const functionspace::Spectral&, FieldSet& spfields, + const eckit::Configuration& = util::NoConfig() ) const; + + void __dirtrans_wind2vordiv(const functionspace::NodeColumns&, const Field& gpwind, + const functionspace::Spectral&, Field& spvor, Field& spdiv, + const eckit::Configuration& = util::NoConfig() ) const; + + + void __invtrans(const functionspace::Spectral&, const Field& spfield, + const functionspace::StructuredColumns&, Field& gpfield, + const eckit::Configuration& = util::NoConfig() ) const; + void __invtrans(const functionspace::Spectral&, const FieldSet& spfields, + const functionspace::StructuredColumns&, FieldSet& gpfields, + const eckit::Configuration& = util::NoConfig() ) const; + + void __invtrans(const functionspace::Spectral&, const Field& spfield, + const functionspace::NodeColumns&, Field& gpfield, + const eckit::Configuration& = util::NoConfig() ) const; + void __invtrans(const functionspace::Spectral&, const FieldSet& spfields, + const functionspace::NodeColumns&, FieldSet& gpfields, + const eckit::Configuration& = util::NoConfig() ) const; + + void __invtrans_vordiv2wind(const functionspace::Spectral&, const Field& spvor, const Field& spdiv, + const functionspace::NodeColumns&, Field& gpwind, + const eckit::Configuration& = util::NoConfig() ) const; + + void __invtrans_grad(const functionspace::Spectral& sp, const Field& spfield, + const functionspace::NodeColumns& gp, Field& gradfield, + const eckit::Configuration& = util::NoConfig() ) const; + + + void __invtrans_grad(const functionspace::Spectral& sp, const FieldSet& spfields, + const functionspace::NodeColumns& gp, FieldSet& gradfields, + const eckit::Configuration& = util::NoConfig() ) const; + +public: + void specnorm( const int nb_fields, const double spectra[], double norms[], int rank=0 ) const; + + +private: + + void ctor( const Grid&, long nsmax, const Options& ); + + void ctor_rgg(const long nlat, const long pl[], long nsmax, const Options& ); + + void ctor_lonlat(const long nlon, const long nlat, long nsmax, const Options& ); + + void ctor_spectral_only(long truncation, const TransIFS::Options& p ); + +private: + friend class grid::detail::partitioner::TransPartitioner; + + /// @brief Constructor for grid-only setup (e.g. for partitioning/parallelisation routines) + TransIFS(const Grid& g, const Options& = Options() ); + + int handle() const { return trans_->handle; } + int ndgl() const { return trans_->ndgl; } + int nsmax() const { return trans_->nsmax; } + int ngptot() const { return trans_->ngptot; } + int ngptotg() const { return trans_->ngptotg; } + int ngptotmx() const { return trans_->ngptotmx; } + int nspec() const { return trans_->nspec; } + int nspec2() const { return trans_->nspec2; } + int nspec2g() const { return trans_->nspec2g; } + int nspec2mx() const { return trans_->nspec2mx; } + int n_regions_NS() const { return trans_->n_regions_NS; } + int n_regions_EW() const { return trans_->n_regions_EW; } + int nump() const { return trans_->nump; } + int nproc() const { return trans_->nproc; } + int myproc(int proc0=0) const { return trans_->myproc-1+proc0; } + + const int* nloen(int& size) const + { + size = trans_->ndgl; + ASSERT( trans_->nloen != NULL ); + return trans_->nloen; + } + + array::LocalView nloen() const + { + ASSERT( trans_->nloen != NULL ); + return array::LocalView(trans_->nloen, array::make_shape(trans_->ndgl)); + } + + const int* n_regions(int& size) const + { + size = trans_->n_regions_NS; + ASSERT( trans_->n_regions != NULL ); + return trans_->n_regions; + } + + array::LocalView n_regions() const + { + ASSERT( trans_->n_regions != NULL ); + return array::LocalView(trans_->n_regions, array::make_shape(trans_->n_regions_NS)); + } + + + const int* nfrstlat(int& size) const + { + size = trans_->n_regions_NS; + if( trans_->nfrstlat == NULL ) ::trans_inquire(trans_.get(),"nfrstlat"); + return trans_->nfrstlat; + } + + array::LocalView nfrstlat() const + { + if( trans_->nfrstlat == NULL ) ::trans_inquire(trans_.get(),"nfrstlat"); + return array::LocalView(trans_->nfrstlat, array::make_shape(trans_->n_regions_NS)); + } + + const int* nlstlat(int& size) const + { + size = trans_->n_regions_NS; + if( trans_->nlstlat == NULL ) ::trans_inquire(trans_.get(),"nlstlat"); + return trans_->nlstlat; + } + + array::LocalView nlstlat() const + { + if( trans_->nlstlat == NULL ) ::trans_inquire(trans_.get(),"nlstlat"); + return array::LocalView(trans_->nlstlat, array::make_shape(trans_->n_regions_NS)); + } + + const int* nptrfrstlat(int& size) const + { + size = trans_->n_regions_NS; + if( trans_->nptrfrstlat == NULL ) ::trans_inquire(trans_.get(),"nptrfrstlat"); + return trans_->nptrfrstlat; + } + + array::LocalView nptrfrstlat() const + { + if( trans_->nptrfrstlat == NULL ) ::trans_inquire(trans_.get(),"nptrfrstlat"); + return array::LocalView(trans_->nptrfrstlat, array::make_shape(trans_->n_regions_NS)); + } + + const int* nsta(int& sizef2, int& sizef1) const + { + sizef1 = trans_->ndgl+trans_->n_regions_NS-1; + sizef2 = trans_->n_regions_EW; + if( trans_->nsta == NULL ) ::trans_inquire(trans_.get(),"nsta"); + return trans_->nsta; + } + + array::LocalView nsta() const + { + if( trans_->nsta == NULL ) ::trans_inquire(trans_.get(),"nsta"); + return array::LocalView( trans_->nsta, array::make_shape(trans_->n_regions_EW, trans_->ndgl+trans_->n_regions_NS-1) ); + } + + const int* nonl(int& sizef2, int& sizef1) const + { + sizef1 = trans_->ndgl+trans_->n_regions_NS-1; + sizef2 = trans_->n_regions_EW; + if( trans_->nonl == NULL ) ::trans_inquire(trans_.get(),"nonl"); + return trans_->nonl; + } + + array::LocalView nonl() const + { + if( trans_->nonl == NULL ) ::trans_inquire(trans_.get(),"nonl"); + return array::LocalView( trans_->nonl, array::make_shape(trans_->n_regions_EW, trans_->ndgl+trans_->n_regions_NS-1) ); + } + + const int* nmyms(int& size) const + { + size = trans_->nump; + if( trans_->nmyms == NULL ) ::trans_inquire(trans_.get(),"nmyms"); + return trans_->nmyms; + } + + array::LocalView nmyms() const + { + if( trans_->nmyms == NULL ) ::trans_inquire(trans_.get(),"nmyms"); + return array::LocalView (trans_->nmyms, array::make_shape(trans_->nump)); + } + + const int* nasm0(int& size) const + { + size = trans_->nsmax+1; // +1 because zeroth wave included + if( trans_->nasm0 == NULL ) ::trans_inquire(trans_.get(),"nasm0"); + return trans_->nasm0; + } + + array::LocalView nasm0() const + { + if( trans_->nasm0 == NULL ) ::trans_inquire(trans_.get(),"nasm0"); + return array::LocalView (trans_->nasm0, array::make_shape(trans_->nsmax+1) ); + } + + const int* nvalue(int& size) const + { + size = trans_->nspec2; + if( trans_->nvalue == NULL ) ::trans_inquire(trans_.get(),"nvalue"); + return trans_->nvalue; + } + + array::LocalView nvalue() const + { + if( trans_->nvalue == NULL ) ::trans_inquire(trans_.get(),"nvalue"); + return array::LocalView (trans_->nvalue, array::make_shape(trans_->nspec2)); + } + + +public: + + /*! + * @brief distspec + * @param nb_fields + * @param origin + * @param global_spectra + * @param spectra + */ + void distspec( const int nb_fields, const int origin[], const double global_spectra[], double spectra[] ) const; + + /*! + * @brief gathspec + * @param nb_fields + * @param destination + * @param spectra + * @param global_spectra + */ + void gathspec( const int nb_fields, const int destination[], const double spectra[], double global_spectra[] ) const; + + /*! + * @brief distgrid + * @param nb_fields + * @param origin + * @param global_fields + * @param fields + */ + void distgrid( const int nb_fields, const int origin[], const double global_fields[], double fields[] ) const; + + /*! + * @brief gathgrid + * @param nb_fields + * @param destination + * @param fields + * @param global_fields + */ + void gathgrid( const int nb_fields, const int destination[], const double fields[], double global_fields[] ) const; + + +private: + friend class functionspace::detail::Spectral; + mutable std::shared_ptr<::Trans_t> trans_; + grid::StructuredGrid grid_; +}; + +//----------------------------------------------------------------------------- + +// 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); +} + +// ------------------------------------------------------------------ + +} // namespace trans +} // namespace atlas diff --git a/src/atlas_f/CMakeLists.txt b/src/atlas_f/CMakeLists.txt index 523e9c2bd..086fad9bb 100644 --- a/src/atlas_f/CMakeLists.txt +++ b/src/atlas_f/CMakeLists.txt @@ -153,7 +153,9 @@ 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/Trans.h) +generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/trans/detail/TransIFS.h + MODULE atlas_trans_c_binding + OUTPUT trans_c_binding.f90 ) generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/util/Metadata.h) generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/util/Config.h) generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/output/detail/GmshIO.h) diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index 1df071795..857b65524 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -13,7 +13,6 @@ module atlas_Trans_module private :: fckit_object public :: atlas_Trans -public :: atlas_TransParameters private @@ -45,31 +44,23 @@ module atlas_Trans_module procedure :: nb_gridpoints procedure :: nb_gridpoints_global - procedure, private :: dirtrans_field_nodes procedure, private :: dirtrans_field - procedure, private :: dirtrans_fieldset_nodes procedure, private :: dirtrans_fieldset procedure, public :: dirtrans_wind2vordiv => dirtrans_wind2vordiv_field generic, public :: dirtrans => & & dirtrans_field, & - & dirtrans_fieldset, & - & dirtrans_fieldset_nodes, & - & dirtrans_field_nodes + & dirtrans_fieldset - procedure, private :: invtrans_field_nodes procedure, private :: invtrans_field - procedure, private :: invtrans_fieldset_nodes procedure, private :: invtrans_fieldset procedure, public :: invtrans_vordiv2wind => invtrans_vordiv2wind_field generic, public :: invtrans => & & invtrans_field, & - & invtrans_fieldset, & - & invtrans_field_nodes, & - & invtrans_fieldset_nodes + & invtrans_fieldset - procedure, private :: invtrans_grad_field_nodes + procedure, private :: invtrans_grad_field generic, public :: invtrans_grad => & - & invtrans_grad_field_nodes + & invtrans_grad_field procedure, private :: gathspec_r1 procedure, private :: gathspec_r2 @@ -92,32 +83,6 @@ module atlas_Trans_module !------------------------------------------------------------------------------ -TYPE, extends(fckit_object) :: atlas_TransParameters - -! Purpose : -! ------- -! *TransParameters* : Extra information to pass to dirtrans and invtrans - -! Author : -! ------ -! 20-Mar-2015 Willem Deconinck *ECMWF* - -!------------------------------------------------------------------------------ -contains - - procedure, public :: delete => atlas_TransParameters__delete - procedure, public :: copy => atlas_TransParameters__copy - -END TYPE atlas_TransParameters - -!------------------------------------------------------------------------------ - -interface atlas_TransParameters - module procedure atlas_TransParameters__ctor -end interface - -!------------------------------------------------------------------------------ - !======================================================== contains !======================================================== @@ -153,17 +118,6 @@ function atlas_Trans__ctor( grid, nsmax ) result(trans) #endif end function atlas_Trans__ctor -function atlas_TransParameters__ctor() result(params) - use atlas_trans_c_binding - use, intrinsic :: iso_c_binding, only: c_null_ptr - type(atlas_TransParameters) :: params -#ifdef ATLAS_HAVE_TRANS - call params%reset_c_ptr( atlas__TransParameters__new() ) -#else - ! IGNORE - call params%reset_c_ptr( c_null_ptr) -#endif -end function atlas_TransParameters__ctor subroutine atlas_Trans__delete( this ) use atlas_trans_c_binding @@ -185,22 +139,6 @@ subroutine atlas_Trans__copy(this,obj_in) -subroutine atlas_TransParameters__delete( this ) - use atlas_trans_c_binding - class(atlas_TransParameters), intent(inout) :: this -#ifdef ATLAS_HAVE_TRANS - call atlas__TransParameters__delete(this%c_ptr()); -#else - ! IGNORE -#endif -end subroutine - - -subroutine atlas_TransParameters__copy(this,obj_in) - class(atlas_TransParameters), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - function handle( this ) use atlas_trans_c_binding integer :: handle @@ -287,56 +225,23 @@ function grid( this ) #endif end function -subroutine dirtrans_fieldset_nodes(this, gp, gpfields, sp, spfields, parameters) - use atlas_trans_c_binding - use atlas_functionspace_module, only: atlas_Functionspace - use atlas_fieldset_module, only: atlas_FieldSet - use atlas_field_module, only: atlas_Field - class(atlas_Trans), intent(in) :: this - class(atlas_FunctionSpace), intent(in) :: gp - class(atlas_FieldSet), intent(in) :: gpfields - class(atlas_FunctionSpace), intent(in) :: sp - class(atlas_FieldSet), intent(inout) :: spfields - class(atlas_TransParameters), intent(in), optional :: parameters -#ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p - - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) - else - p = atlas_TransParameters() - endif - - call atlas__Trans__dirtrans_fieldset_nodes( this%c_ptr(), & - & gp%c_ptr(), & - & gpfields%c_ptr(), & - & sp%c_ptr(), & - & spfields%c_ptr(), & - & p%c_ptr() ) - - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) - endif -#else - THROW_ERROR -#endif -end subroutine dirtrans_fieldset_nodes -subroutine dirtrans_fieldset(this, gpfields, spfields, parameters) +subroutine dirtrans_fieldset(this, gpfields, spfields, config) use atlas_trans_c_binding use atlas_fieldset_module, only: atlas_FieldSet use atlas_field_module, only: atlas_Field + use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_FieldSet), intent(in) :: gpfields class(atlas_FieldSet), intent(inout) :: spfields - class(atlas_TransParameters), intent(in), optional :: parameters + class(atlas_Config), intent(in), optional :: config #ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p + type(atlas_Config) :: p - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) + if( present(config) ) then + call p%reset_c_ptr( config%c_ptr() ) else - p = atlas_TransParameters() + p = atlas_Config() endif call atlas__Trans__dirtrans_fieldset( this%c_ptr(), & @@ -344,64 +249,31 @@ subroutine dirtrans_fieldset(this, gpfields, spfields, parameters) & spfields%c_ptr(), & & p%c_ptr() ) - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) + if( .not. present(config) ) then + call p%final() endif #else THROW_ERROR #endif end subroutine dirtrans_fieldset -subroutine invtrans_fieldset_nodes(this, sp, spfields, gp, gpfields, parameters) - use atlas_trans_c_binding - use atlas_functionspace_module, only: atlas_Functionspace - use atlas_fieldset_module, only: atlas_FieldSet - use atlas_field_module, only: atlas_Field - class(atlas_Trans), intent(in) :: this - class(atlas_FunctionSpace), intent(in) :: sp - class(atlas_FieldSet), intent(in) :: spfields - class(atlas_FunctionSpace), intent(in) :: gp - class(atlas_FieldSet), intent(inout) :: gpfields - class(atlas_TransParameters), intent(in), optional :: parameters -#ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p - - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) - else - p = atlas_TransParameters() - endif - - call atlas__Trans__invtrans_fieldset_nodes( this%c_ptr(), & - & sp%c_ptr(), & - & spfields%c_ptr(), & - & gp%c_ptr(), & - & gpfields%c_ptr(), & - & p%c_ptr() ) - - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) - endif -#else - THROW_ERROR -#endif -end subroutine invtrans_fieldset_nodes -subroutine invtrans_fieldset(this, spfields, gpfields, parameters) +subroutine invtrans_fieldset(this, spfields, gpfields, config) use atlas_trans_c_binding use atlas_fieldset_module, only: atlas_FieldSet use atlas_field_module, only: atlas_Field + use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_FieldSet), intent(in) :: spfields class(atlas_FieldSet), intent(inout) :: gpfields - class(atlas_TransParameters), intent(in), optional :: parameters + class(atlas_Config), intent(in), optional :: config #ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p + type(atlas_Config) :: p - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) + if( present(config) ) then + call p%reset_c_ptr( config%c_ptr() ) else - p = atlas_TransParameters() + p = atlas_Config() endif call atlas__Trans__invtrans_fieldset( this%c_ptr(), & @@ -409,63 +281,29 @@ subroutine invtrans_fieldset(this, spfields, gpfields, parameters) & gpfields%c_ptr(), & & p%c_ptr() ) - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) + if( .not. present(config) ) then + call p%final() endif #else THROW_ERROR #endif end subroutine invtrans_fieldset - -subroutine dirtrans_field_nodes(this, gp, gpfield, sp, spfield, parameters) - use atlas_trans_c_binding - use atlas_functionspace_module, only: atlas_Functionspace - use atlas_field_module, only: atlas_Field - class(atlas_Trans), intent(in) :: this - class(atlas_FunctionSpace), intent(in) :: gp - class(atlas_Field), intent(in) :: gpfield - class(atlas_FunctionSpace), intent(in) :: sp - class(atlas_Field), intent(inout) :: spfield - class(atlas_TransParameters), intent(in), optional :: parameters -#ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p - - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) - else - p = atlas_TransParameters() - endif - - call atlas__Trans__dirtrans_field_nodes( this%c_ptr(), & - & gp%c_ptr(), & - & gpfield%c_ptr(), & - & sp%c_ptr(), & - & spfield%c_ptr(), & - & p%c_ptr() ) - - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) - endif -#else - THROW_ERROR -#endif -end subroutine dirtrans_field_nodes - -subroutine dirtrans_field(this, gpfield, spfield, parameters) +subroutine dirtrans_field(this, gpfield, spfield, config) use atlas_trans_c_binding use atlas_field_module, only: atlas_Field + use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_Field), intent(in) :: gpfield class(atlas_Field), intent(inout) :: spfield - class(atlas_TransParameters), intent(in), optional :: parameters + class(atlas_Config), intent(in), optional :: config #ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p + type(atlas_Config) :: p - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) + if( present(config) ) then + call p%reset_c_ptr( config%c_ptr() ) else - p = atlas_TransParameters() + p = atlas_Config() endif call atlas__Trans__dirtrans_field( this%c_ptr(), & @@ -473,44 +311,40 @@ subroutine dirtrans_field(this, gpfield, spfield, parameters) & spfield%c_ptr(), & & p%c_ptr() ) - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) + if( .not. present(config) ) then + call p%final() endif #else THROW_ERROR #endif end subroutine dirtrans_field -subroutine dirtrans_wind2vordiv_field(this, gp, gpwind, sp, spvor, spdiv, parameters) +subroutine dirtrans_wind2vordiv_field(this, gpwind, spvor, spdiv, config) use atlas_trans_c_binding - use atlas_functionspace_module, only: atlas_Functionspace use atlas_field_module, only: atlas_Field + use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this - class(atlas_FunctionSpace), intent(in) :: gp type(atlas_Field), intent(in) :: gpwind - class(atlas_FunctionSpace), intent(in) :: sp type(atlas_Field), intent(inout) :: spvor type(atlas_Field), intent(inout) :: spdiv - type(atlas_TransParameters), intent(in), optional :: parameters + type(atlas_Config), intent(in), optional :: config #ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p + type(atlas_Config) :: p - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) + if( present(config) ) then + call p%reset_c_ptr( config%c_ptr() ) else - p = atlas_TransParameters() + p = atlas_Config() endif - call atlas__Trans__dirtrans_wind2vordiv_field_nodes( this%c_ptr(), & - & gp%c_ptr(), & + call atlas__Trans__dirtrans_wind2vordiv_field( this%c_ptr(), & & gpwind%c_ptr(), & - & sp%c_ptr(), & & spvor%c_ptr(), & & spdiv%c_ptr(), & & p%c_ptr() ) - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) + if( .not. present(config) ) then + call p%final() endif #else THROW_ERROR @@ -518,54 +352,22 @@ subroutine dirtrans_wind2vordiv_field(this, gp, gpwind, sp, spvor, spdiv, parame end subroutine dirtrans_wind2vordiv_field -subroutine invtrans_field_nodes(this, sp, spfield, gp, gpfield, parameters) - use atlas_trans_c_binding - use atlas_functionspace_module, only: atlas_Functionspace - use atlas_field_module, only: atlas_Field - class(atlas_Trans), intent(in) :: this - class(atlas_FunctionSpace), intent(in) :: sp - class(atlas_Field), intent(in) :: spfield - class(atlas_FunctionSpace), intent(in) :: gp - class(atlas_Field), intent(inout) :: gpfield - class(atlas_TransParameters), intent(in), optional :: parameters -#ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p - - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) - else - p = atlas_TransParameters() - endif - - call atlas__Trans__invtrans_field_nodes( this%c_ptr(), & - & sp%c_ptr(), & - & spfield%c_ptr(), & - & gp%c_ptr(), & - & gpfield%c_ptr(), & - & p%c_ptr() ) - - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) - endif -#else - THROW_ERROR -#endif -end subroutine invtrans_field_nodes -subroutine invtrans_field(this, spfield, gpfield, parameters) +subroutine invtrans_field(this, spfield, gpfield, config) use atlas_trans_c_binding use atlas_field_module, only: atlas_Field + use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_Field), intent(in) :: spfield class(atlas_Field), intent(inout) :: gpfield - class(atlas_TransParameters), intent(in), optional :: parameters + class(atlas_Config), intent(in), optional :: config #ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p + type(atlas_Config) :: p - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) + if( present(config) ) then + call p%reset_c_ptr( config%c_ptr() ) else - p = atlas_TransParameters() + p = atlas_Config() endif call atlas__Trans__invtrans_field( this%c_ptr(), & @@ -573,8 +375,8 @@ subroutine invtrans_field(this, spfield, gpfield, parameters) & gpfield%c_ptr(), & & p%c_ptr() ) - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) + if( .not. present(config) ) then + call p%final() endif #else THROW_ERROR @@ -582,36 +384,32 @@ subroutine invtrans_field(this, spfield, gpfield, parameters) end subroutine invtrans_field -subroutine invtrans_vordiv2wind_field(this, sp, spvor, spdiv, gp, gpwind, parameters) +subroutine invtrans_vordiv2wind_field(this, spvor, spdiv, gpwind, config) use atlas_trans_c_binding - use atlas_functionspace_module, only: atlas_Functionspace use atlas_field_module, only: atlas_Field + use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this - class(atlas_FunctionSpace), intent(in) :: sp class(atlas_Field), intent(in) :: spvor class(atlas_Field), intent(in) :: spdiv - class(atlas_FunctionSpace), intent(in) :: gp class(atlas_Field), intent(inout) :: gpwind - class(atlas_TransParameters), intent(in), optional :: parameters + class(atlas_Config), intent(in), optional :: config #ifdef ATLAS_HAVE_TRANS - type(atlas_TransParameters) :: p + type(atlas_Config) :: p - if( present(parameters) ) then - call p%reset_c_ptr( parameters%c_ptr() ) + if( present(config) ) then + call p%reset_c_ptr( config%c_ptr() ) else - p = atlas_TransParameters() + p = atlas_Config() endif - call atlas__Trans__invtrans_vordiv2wind_field_nodes( this%c_ptr(), & - & sp%c_ptr(), & + call atlas__Trans__invtrans_vordiv2wind_field( this%c_ptr(), & & spvor%c_ptr(), & & spdiv%c_ptr(), & - & gp%c_ptr(), & & gpwind%c_ptr(), & & p%c_ptr() ) - if( .not. present(parameters) ) then - call atlas_TransParameters__delete(p) + if( .not. present(config) ) then + call p%final() endif #else THROW_ERROR @@ -620,26 +418,25 @@ subroutine invtrans_vordiv2wind_field(this, sp, spvor, spdiv, gp, gpwind, parame end subroutine invtrans_vordiv2wind_field -subroutine invtrans_grad_field_nodes(this, sp, spfield, gp, gpfield) +subroutine invtrans_grad_field(this, spfield, gpfield) use atlas_trans_c_binding - use atlas_functionspace_module, only: atlas_Functionspace use atlas_field_module, only: atlas_Field + use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this - class(atlas_FunctionSpace), intent(in) :: sp class(atlas_Field), intent(in) :: spfield - class(atlas_FunctionSpace), intent(in) :: gp class(atlas_Field), intent(inout) :: gpfield #ifdef ATLAS_HAVE_TRANS - - call atlas__Trans__invtrans_grad_field_nodes( this%c_ptr(), & - & sp%c_ptr(), & + type(atlas_Config) :: config + config = atlas_Config() + call atlas__Trans__invtrans_grad_field( this%c_ptr(), & & spfield%c_ptr(), & - & gp%c_ptr(), & - & gpfield%c_ptr() ) + & gpfield%c_ptr(), & + & config%c_ptr()) + call config%final() #else THROW_ERROR #endif -end subroutine invtrans_grad_field_nodes +end subroutine invtrans_grad_field diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index f16f99825..0bddf21d3 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -23,8 +23,9 @@ #include "atlas/grid/Grid.h" #include "atlas/field/Field.h" #include "atlas/parallel/mpi/mpi.h" -#ifdef ATLAS_HAVE_TRANS #include "atlas/trans/Trans.h" +#ifdef ATLAS_HAVE_TRANS +#include "atlas/trans/detail/TransIFS.h" #endif @@ -530,7 +531,7 @@ CASE( "test_SpectralFunctionSpace" ) CASE( "test_SpectralFunctionSpace_trans_dist" ) { - trans::Trans trans(Grid("F80"),159); + trans::TransIFS trans(Grid("F80"),159); size_t nb_levels(10); size_t nspec2 = trans.nb_spectral_coefficients(); @@ -619,7 +620,7 @@ CASE( "test_SpectralFunctionSpace_trans_global" ) } CASE( "test_SpectralFunctionSpace_norm" ) { - trans::Trans trans(Grid("F80"),159); + trans::TransIFS trans(Grid("F80"),159); size_t nb_levels(10); Spectral spectral_fs( trans ); diff --git a/src/tests/trans/fctest_trans.F90 b/src/tests/trans/fctest_trans.F90 index 0ae7aabf4..6a0302f72 100644 --- a/src/tests/trans/fctest_trans.F90 +++ b/src/tests/trans/fctest_trans.F90 @@ -121,8 +121,8 @@ end module fctest_atlas_trans_fixture spec2(:) = 0 spec2(1) = 4 - call trans%invtrans(spectral_fs,spectralfield1,nodes_fs,scalarfield1) - call trans%dirtrans(nodes_fs,scalarfield1,spectral_fs,spectralfield1) + call trans%invtrans(spectralfield1,scalarfield1) + call trans%dirtrans(scalarfield1,spectralfield1) allocate( check(nlev) ) check(:) = 3 @@ -137,8 +137,8 @@ end module fctest_atlas_trans_fixture call spectralfields%add(spectralfield1) call spectralfields%add(spectralfield2) - call trans%invtrans(spectral_fs,spectralfields,nodes_fs,scalarfields) - call trans%dirtrans(nodes_fs,scalarfields,spectral_fs,spectralfields) + call trans%invtrans(spectralfields,scalarfields) + call trans%dirtrans(scalarfields,spectralfields) allocate( check(nlev) ) check(:) = 3 @@ -170,9 +170,9 @@ end module fctest_atlas_trans_fixture call divfield%data(div) - call trans%dirtrans_wind2vordiv(nodes_fs,windfield,spectral_fs,vorfield,divfield) + call trans%dirtrans_wind2vordiv(windfield,vorfield,divfield) - call trans%invtrans_vordiv2wind(spectral_fs,vorfield,divfield,nodes_fs,windfield) + call trans%invtrans_vordiv2wind(vorfield,divfield,windfield) glb_vorfield = spectral_fs%create_field(name="vorticity",kind=atlas_real(c_double),levels=nlev,global=.true.) call spectral_fs%gather(vorfield,glb_vorfield) diff --git a/src/tests/trans/fctest_trans_invtrans_grad.F90 b/src/tests/trans/fctest_trans_invtrans_grad.F90 index bbc0f1afd..a77affe01 100644 --- a/src/tests/trans/fctest_trans_invtrans_grad.F90 +++ b/src/tests/trans/fctest_trans_invtrans_grad.F90 @@ -120,9 +120,9 @@ subroutine rotated_flow_magnitude(fs,field,beta) beta = pi*0.5; call rotated_flow_magnitude(nodes_fs,scalar,beta) - call trans%dirtrans(nodes_fs,scalar,spectral_fs,scalar_sp) + call trans%dirtrans(scalar,scalar_sp) - call trans%invtrans_grad(spectral_fs,scalar_sp,nodes_fs,grad); + call trans%invtrans_grad(scalar_sp,grad); call nodes_fs%halo_exchange(grad); diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index cf92c2f97..90f34f46d 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -28,11 +28,14 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/trans/Trans.h" #include "atlas/array/MakeView.h" -#include "transi/trans.h" #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" +#ifdef ATLAS_HAVE_TRANS +#include "atlas/trans/detail/TransIFS.h" +#endif + using namespace eckit; using namespace eckit::testing; using atlas::grid::detail::partitioner::TransPartitioner; @@ -57,7 +60,7 @@ struct AtlasTransEnvironment : public AtlasTestEnvironment { //----------------------------------------------------------------------------- -void read_rspecg(trans::Trans& trans, std::vector& rspecg, std::vector& nfrom, int &nfld ) +void read_rspecg(trans::TransIFS& trans, std::vector& rspecg, std::vector& nfrom, int &nfld ) { Log::info() << "read_rspecg ...\n"; nfld = 2; @@ -79,6 +82,26 @@ void read_rspecg(trans::Trans& trans, std::vector& rspecg, std::vector( spec ); + ASSERT( view.shape(1) >= 2 ); + for( int i=0; inproc == parallel::mpi::comm().size() ); @@ -131,21 +154,9 @@ CASE( "test_trans_distribution_matches_atlas" ) } } -CASE( "test_trans_partitioner" ) -{ - Log::info() << "test_trans_partitioner" << std::endl; - // Create grid and trans object - Grid g( "N80" ); - - trans::Trans trans( g ); - - EXPECT( trans.truncation() <= 0 ); - EXPECT( trans.nb_gridpoints_global() == g.size() ); -} - CASE( "test_trans_options" ) { - trans::Trans::Options opts; + trans::TransIFS::Options opts; opts.set_fft(trans::FFTW); opts.set_split_latitudes(false); opts.set_read("readfile"); @@ -155,14 +166,14 @@ CASE( "test_trans_options" ) CASE( "test_distspec" ) { - trans::Trans::Options p; + trans::TransIFS::Options p; #ifdef TRANS_HAVE_IO if( parallel::mpi::comm().size() == 1 ) p.set_write("cached_legendre_coeffs"); #endif p.set_flt(false); - trans::Trans trans( Grid("F400"), 159, p); + trans::TransIFS trans( Grid("F400"), 159, p); Log::info() << "Trans initialized" << std::endl; std::vector rspecg; std::vector nfrom; @@ -192,30 +203,22 @@ CASE( "test_distspec" ) CASE( "test_distspec_speconly" ) { - trans::Trans::Options p; - - p.set_flt(false); - trans::Trans trans( 159, p); - Log::info() << "Trans initialized" << std::endl; - std::vector rspecg; - std::vector nfrom; - int nfld; - Log::info() << "Read rspecg" << std::endl; - read_rspecg(trans,rspecg,nfrom,nfld); + functionspace::Spectral fs(159); + int nfld = 2; + Field glb = fs.createField(option::global()|option::levels(nfld)); + read_rspecg(glb); - - std::vector rspec(nfld*trans.nb_spectral_coefficients()); - std::vector nto(nfld,1); std::vector specnorms(nfld,0); - trans.distspec( nfld, nfrom.data(), rspecg.data(), rspec.data() ); - trans.specnorm( nfld, rspec.data(), specnorms.data() ); + Field dist = fs.createField(glb); + + fs.scatter(glb,dist); + fs.norm(dist,specnorms); if( parallel::mpi::comm().rank() == 0 ) { 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; } @@ -251,7 +254,6 @@ CASE( "test_generate_mesh" ) ("angle",0) ("triangulate",true) ); - trans::Trans trans(g); Mesh m_default = generate( g ); @@ -287,7 +289,7 @@ CASE( "test_spectral_fields" ) ); Mesh m = generate( g ); - trans::Trans trans(g,47); + trans::TransIFS trans(g,47); functionspace::NodeColumns nodal (m); @@ -297,17 +299,17 @@ CASE( "test_spectral_fields" ) Field gpf = nodal. createField(option::name("gpf")); - EXPECT_NO_THROW( trans.dirtrans(nodal,gpf,spectral,spf) ); - EXPECT_NO_THROW( trans.invtrans(spectral,spf,nodal,gpf) ); + EXPECT_NO_THROW( trans.dirtrans(gpf,spf) ); + EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); FieldSet gpfields; gpfields.add(gpf); FieldSet spfields; spfields.add(spf); - EXPECT_NO_THROW( trans.dirtrans(nodal,gpfields,spectral,spfields) ); - EXPECT_NO_THROW( trans.invtrans(spectral,spfields,nodal,gpfields) ); + EXPECT_NO_THROW( trans.dirtrans(gpfields,spfields) ); + EXPECT_NO_THROW( trans.invtrans(spfields,gpfields) ); gpfields.add(gpf); - EXPECT_THROWS_AS(trans.dirtrans(nodal,gpfields,spectral,spfields),eckit::SeriousBug); + EXPECT_THROWS_AS(trans.dirtrans(gpfields,spfields),eckit::SeriousBug); } @@ -317,7 +319,7 @@ CASE( "test_nomesh" ) Log::info() << "test_spectral_fields" << std::endl; Grid g( "O48" ); - trans::Trans trans(g,47) ; + trans::TransIFS trans(g,47) ; functionspace::Spectral spectral (trans); functionspace::StructuredColumns gridpoints (g); diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index 889c4ed52..bc640f5f7 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -27,11 +27,14 @@ #include "atlas/trans/Trans.h" #include "atlas/util/Earth.h" #include "atlas/util/CoordinateEnums.h" -#include "transi/trans.h" #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" +#ifdef ATLAS_HAVE_TRANS +#include "atlas/trans/detail/TransIFS.h" +#endif + using namespace eckit::testing; namespace atlas { @@ -104,7 +107,7 @@ CASE( "test_invtrans_ifsStyle" ) std::string grid_uid("O80"); grid::StructuredGrid g (grid_uid); long N = g.ny()/2; - trans::Trans trans(g,2*N-1); + trans::TransIFS trans(g,2*N-1); Log::info() << "Trans initialized" << std::endl; std::vector rspecg; int nfld = 1; @@ -121,12 +124,10 @@ CASE( "test_invtrans_ifsStyle" ) trans.dirtrans(nfld,init_gp.data(),init_sp.data()); std::vector rgp(3*nfld*trans.nb_gridpoints()); - double *no_vorticity(NULL), *no_divergence(NULL); + double *no_vorticity(nullptr), *no_divergence(nullptr); int nb_vordiv(0); int nb_scalar(nfld); - trans::TransParameters p; - p.set_scalar_derivatives(true); - trans.invtrans( nb_scalar, init_sp.data(), nb_vordiv, no_vorticity, no_divergence, rgp.data(), p ); + trans.invtrans( nb_scalar, init_sp.data(), nb_vordiv, no_vorticity, no_divergence, rgp.data(), trans::options::scalar_derivatives(true) ); std::vector nto(nfld,1); std::vector rgpg(3*nfld*trans.nb_gridpoints_global()); @@ -155,7 +156,7 @@ CASE( "test_invtrans_grad" ) grid::StructuredGrid g ( grid_uid ); Mesh mesh = meshgenerator::StructuredMeshGenerator().generate(g); long N = g.ny()/2; - trans::Trans trans(g, 2*N-1); + trans::TransIFS trans(g, 2*N-1); functionspace::NodeColumns gp(mesh); functionspace::Spectral sp(trans); @@ -168,10 +169,10 @@ CASE( "test_invtrans_grad" ) rotated_flow_magnitude(gp,scalar,beta); // Transform to spectral - trans.dirtrans(gp,scalar,sp,scalar_sp); + trans.dirtrans(scalar,scalar_sp); // Inverse transform for gradient - trans.invtrans_grad(sp,scalar_sp,gp,grad); + trans.invtrans_grad(scalar_sp,grad); gp.haloExchange(grad); From 0839f7f0fe1591c0fd05d34969bb314de42e9120 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 15 Nov 2017 10:03:21 +0000 Subject: [PATCH 168/355] ATLAS-134 Mesh contains grid reference --- src/atlas/mesh/Mesh.h | 3 +++ src/atlas/mesh/detail/MeshImpl.cc | 6 ++++++ src/atlas/mesh/detail/MeshImpl.h | 6 ++++++ src/atlas/meshgenerator/MeshGenerator.cc | 7 +++++-- src/atlas/meshgenerator/MeshGenerator.h | 11 ++++++----- src/atlas/meshgenerator/RegularMeshGenerator.cc | 4 ++-- src/atlas/meshgenerator/StructuredMeshGenerator.cc | 4 ++-- src/tests/mesh/test_meshgen3d.cc | 3 +++ 8 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/atlas/mesh/Mesh.h b/src/atlas/mesh/Mesh.h index 2b1f393b7..ccdd71087 100644 --- a/src/atlas/mesh/Mesh.h +++ b/src/atlas/mesh/Mesh.h @@ -119,6 +119,8 @@ class Mesh { const Polygon& polygon( size_t halo = 0) const { return impl_->polygon(halo); } + const Grid& grid() const { return impl_->grid(); } + private: // methods friend std::ostream& operator<<(std::ostream& s, const Mesh& p) { @@ -128,6 +130,7 @@ class Mesh { friend class meshgenerator::MeshGeneratorImpl; void setProjection(const Projection& p) { impl_->setProjection(p); } + void setGrid(const Grid& p) { impl_->setGrid(p); } private: diff --git a/src/atlas/mesh/detail/MeshImpl.cc b/src/atlas/mesh/detail/MeshImpl.cc index c925263e5..001978dfa 100644 --- a/src/atlas/mesh/detail/MeshImpl.cc +++ b/src/atlas/mesh/detail/MeshImpl.cc @@ -96,6 +96,12 @@ void MeshImpl::setProjection(const Projection& projection) { projection_ = projection; } +void MeshImpl::setGrid(const Grid& grid) { + grid_ = grid; + if( not projection_ ) + projection_ = grid_.projection(); +} + size_t MeshImpl::nb_partitions() const { return parallel::mpi::comm().size(); } diff --git a/src/atlas/mesh/detail/MeshImpl.h b/src/atlas/mesh/detail/MeshImpl.h index 4ed022ddd..063412520 100644 --- a/src/atlas/mesh/detail/MeshImpl.h +++ b/src/atlas/mesh/detail/MeshImpl.h @@ -16,6 +16,7 @@ #include "eckit/memory/SharedPtr.h" #include "atlas/util/Metadata.h" +#include "atlas/grid/Grid.h" #include "atlas/projection/Projection.h" #include "atlas/mesh/detail/PartitionGraph.h" #include "atlas/mesh/PartitionPolygon.h" @@ -103,6 +104,8 @@ class MeshImpl : public eckit::Owned { const PartitionPolygon& polygon(size_t halo=0) const; + const Grid& grid() const { return grid_; } + private: // methods friend class ::atlas::Mesh; @@ -115,6 +118,7 @@ class MeshImpl : public eckit::Owned { void createElements(); void setProjection(const Projection&); + void setGrid(const Grid&); private: // members @@ -134,6 +138,8 @@ class MeshImpl : public eckit::Owned { Projection projection_; + Grid grid_; + mutable eckit::SharedPtr partition_graph_; mutable std::vector> polygons_; diff --git a/src/atlas/meshgenerator/MeshGenerator.cc b/src/atlas/meshgenerator/MeshGenerator.cc index 641f4f226..050611268 100644 --- a/src/atlas/meshgenerator/MeshGenerator.cc +++ b/src/atlas/meshgenerator/MeshGenerator.cc @@ -97,7 +97,7 @@ Mesh MeshGeneratorImpl::generate( const Grid& grid, const grid::Distribution& di //---------------------------------------------------------------------------------------------------------------------- -void MeshGeneratorImpl::generate_global_element_numbering( Mesh& mesh ) const +void MeshGeneratorImpl::generateGlobalElementNumbering( Mesh& mesh ) const { size_t loc_nb_elems = mesh.cells().size(); std::vector elem_counts( parallel::mpi::comm().size() ); @@ -124,10 +124,13 @@ void MeshGeneratorImpl::generate_global_element_numbering( Mesh& mesh ) const } -void MeshGeneratorImpl::set_projection( Mesh& mesh, const Projection& p ) const { +void MeshGeneratorImpl::setProjection( Mesh& mesh, const Projection& p ) const { mesh.setProjection(p); } +void MeshGeneratorImpl::setGrid( Mesh& mesh, const Grid& g ) const { + mesh.setGrid(g); +} //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/meshgenerator/MeshGenerator.h b/src/atlas/meshgenerator/MeshGenerator.h index efdf30d82..3326b94ea 100644 --- a/src/atlas/meshgenerator/MeshGenerator.h +++ b/src/atlas/meshgenerator/MeshGenerator.h @@ -59,8 +59,9 @@ class MeshGeneratorImpl : public eckit::Owned { protected: - void generate_global_element_numbering( Mesh& mesh ) const; - void set_projection( Mesh&, const Projection& ) const; + void generateGlobalElementNumbering( Mesh& mesh ) const; + void setProjection( Mesh&, const Projection& ) const; + void setGrid( Mesh&, const Grid& ) const; }; //---------------------------------------------------------------------------------------------------------------------- @@ -135,9 +136,9 @@ class MeshGenerator { using Implementation = meshgenerator::MeshGeneratorImpl; typedef atlas::util::Config Parameters; - + private: - + eckit::SharedPtr< const Implementation > meshgenerator_; public: @@ -154,7 +155,7 @@ class MeshGenerator { Mesh operator()( const Grid&, const grid::Distribution& ) const; Mesh operator()( const Grid& ) const; - + const Implementation* get() const { return meshgenerator_.get(); } }; diff --git a/src/atlas/meshgenerator/RegularMeshGenerator.cc b/src/atlas/meshgenerator/RegularMeshGenerator.cc index d21102764..a1d4227ef 100644 --- a/src/atlas/meshgenerator/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/RegularMeshGenerator.cc @@ -140,7 +140,7 @@ void RegularMeshGenerator::generate(const Grid& grid, const grid::Distribution& } // clone some grid properties - set_projection(mesh,rg.projection()); + setGrid(mesh,rg); generate_mesh(rg,distribution,mesh); } @@ -494,7 +494,7 @@ void RegularMeshGenerator::generate_mesh( } #endif - generate_global_element_numbering( mesh ); + generateGlobalElementNumbering( mesh ); nodes.metadata().set("parallel",true); diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 9a04fcec4..9aa10e392 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -224,7 +224,7 @@ void StructuredMeshGenerator::generate(const Grid& grid, const grid::Distributio #endif // clone some grid properties - set_projection(mesh,rg.projection()); + setGrid(mesh,rg); Region region; generate_region(rg,distribution,mypart,region); @@ -1359,7 +1359,7 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons } } - generate_global_element_numbering( mesh ); + generateGlobalElementNumbering( mesh ); } namespace { diff --git a/src/tests/mesh/test_meshgen3d.cc b/src/tests/mesh/test_meshgen3d.cc index c7c8124e8..c8ea0519c 100644 --- a/src/tests/mesh/test_meshgen3d.cc +++ b/src/tests/mesh/test_meshgen3d.cc @@ -42,6 +42,9 @@ CASE( "test_create_mesh" ) m = generate( Grid("N24") ); + Grid grid = m.grid(); + std::cout << grid.spec() << std::endl; + Gmsh("out.msh", util::Config("coordinates","xyz") ).write(m); } From 6aebb30091d03ee3e09bb5966873249ae48a6655 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 15 Nov 2017 18:21:15 +0000 Subject: [PATCH 169/355] ATLAS-134 Value semantics for Trans with factories --- src/atlas/CMakeLists.txt | 4 + src/atlas/functionspace/NodeColumns.cc | 12 +- src/atlas/functionspace/NodeColumns.h | 12 +- src/atlas/functionspace/Spectral.cc | 6 +- src/atlas/functionspace/Spectral.h | 6 +- src/atlas/trans/Trans.cc | 296 ++++++++++++++++++ src/atlas/trans/Trans.h | 170 +++++++++- src/atlas/trans/detail/TransIFS.cc | 8 + src/atlas/trans/detail/TransIFS.h | 3 +- .../trans/detail/ifs/TransIFSNodeColumns.cc | 38 +++ .../trans/detail/ifs/TransIFSNodeColumns.h | 41 +++ .../detail/ifs/TransIFSStructuredColumns.cc | 36 +++ .../detail/ifs/TransIFSStructuredColumns.h | 41 +++ src/tests/trans/test_trans.cc | 99 ++++++ 14 files changed, 755 insertions(+), 17 deletions(-) create mode 100644 src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc create mode 100644 src/atlas/trans/detail/ifs/TransIFSNodeColumns.h create mode 100644 src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc create mode 100644 src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 6726cf73f..de3d8326a 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -324,6 +324,10 @@ if( ATLAS_HAVE_TRANS ) list( APPEND atlas_numerics_srcs trans/detail/TransIFS.h trans/detail/TransIFS.cc + trans/detail/ifs/TransIFSNodeColumns.h + trans/detail/ifs/TransIFSNodeColumns.cc + trans/detail/ifs/TransIFSStructuredColumns.h + trans/detail/ifs/TransIFSStructuredColumns.cc ) endif() diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index cf3cd37ce..29bdb433e 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -86,15 +86,15 @@ array::LocalView make_surface_scalar_view(const Field &field) } -NodeColumns::NodeColumns( Mesh& mesh ) : +NodeColumns::NodeColumns( Mesh mesh ) : NodeColumns( mesh, util::NoConfig() ) { } -NodeColumns::NodeColumns(Mesh& mesh, const mesh::Halo &halo) : +NodeColumns::NodeColumns(Mesh mesh, const mesh::Halo &halo) : NodeColumns( mesh, util::Config("halo",halo.size()) ) { } -NodeColumns::NodeColumns( Mesh& mesh, const eckit::Configuration & config ) : +NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration & config ) : mesh_(mesh), nodes_(mesh_.nodes()), halo_( mesh::Halo(config.getInt("halo",0) ) ), @@ -2115,17 +2115,17 @@ NodeColumns::NodeColumns( const FunctionSpace& functionspace ) : functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { } -NodeColumns::NodeColumns( Mesh& mesh, const mesh::Halo& halo ) : +NodeColumns::NodeColumns( Mesh mesh, const mesh::Halo& halo ) : FunctionSpace( new detail::NodeColumns(mesh,halo) ), functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { } -NodeColumns::NodeColumns( Mesh& mesh ) : +NodeColumns::NodeColumns( Mesh mesh ) : FunctionSpace( new detail::NodeColumns(mesh) ), functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { } -NodeColumns::NodeColumns( Mesh& mesh, const eckit::Configuration& config ) : +NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration& config ) : FunctionSpace( new detail::NodeColumns(mesh, config) ), functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { } diff --git a/src/atlas/functionspace/NodeColumns.h b/src/atlas/functionspace/NodeColumns.h index 2d369efe7..513ec3d41 100644 --- a/src/atlas/functionspace/NodeColumns.h +++ b/src/atlas/functionspace/NodeColumns.h @@ -49,9 +49,9 @@ class NodeColumns : public FunctionSpaceImpl { public: - NodeColumns( Mesh& mesh, const mesh::Halo & ); - NodeColumns( Mesh& mesh, const eckit::Configuration & ); - NodeColumns( Mesh& mesh ); + NodeColumns( Mesh mesh, const mesh::Halo & ); + NodeColumns( Mesh mesh, const eckit::Configuration & ); + NodeColumns( Mesh mesh ); virtual ~NodeColumns(); @@ -431,9 +431,9 @@ class NodeColumns : public FunctionSpace NodeColumns(); NodeColumns( const FunctionSpace& ); - NodeColumns( Mesh& mesh, const mesh::Halo & ); - NodeColumns( Mesh& mesh ); - NodeColumns( Mesh& mesh, const eckit::Configuration & ); + NodeColumns( Mesh mesh, const mesh::Halo & ); + NodeColumns( Mesh mesh ); + NodeColumns( Mesh mesh, const eckit::Configuration & ); static std::string type() { return detail::NodeColumns::static_type(); } diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index ae8a087fb..94febfd30 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -122,7 +122,7 @@ Spectral::Spectral( const eckit::Configuration& config ) : // ---------------------------------------------------------------------- -Spectral::Spectral( const size_t truncation, const eckit::Configuration& config ) : +Spectral::Spectral( const int truncation, const eckit::Configuration& config ) : truncation_(truncation), parallelisation_( new Parallelisation(truncation_) ), nb_levels_(0) @@ -392,6 +392,10 @@ size_t Spectral::nb_spectral_coefficients_global() const { return functionspace_->nb_spectral_coefficients_global(); } +int Spectral::truncation() const { + return functionspace_->truncation(); +} + void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset ) const { functionspace_->gather(local_fieldset,global_fieldset); } diff --git a/src/atlas/functionspace/Spectral.h b/src/atlas/functionspace/Spectral.h index 0b7cf7b3f..5b855697f 100644 --- a/src/atlas/functionspace/Spectral.h +++ b/src/atlas/functionspace/Spectral.h @@ -38,7 +38,7 @@ class Spectral : public FunctionSpaceImpl Spectral( const eckit::Configuration& ); - Spectral(const size_t truncation, const eckit::Configuration& = util::NoConfig() ); + Spectral(const int truncation, const eckit::Configuration& = util::NoConfig() ); Spectral(trans::TransImpl&, const eckit::Configuration& = util::NoConfig() ); @@ -68,6 +68,7 @@ class Spectral : public FunctionSpaceImpl size_t nb_spectral_coefficients() const; size_t nb_spectral_coefficients_global() const; + int truncation() const { return truncation_; } private: // methods @@ -82,7 +83,7 @@ class Spectral : public FunctionSpaceImpl size_t nb_levels_; - size_t truncation_; + int truncation_; class Parallelisation; std::unique_ptr parallelisation_; @@ -119,6 +120,7 @@ class Spectral : public FunctionSpace { size_t nb_spectral_coefficients() const; size_t nb_spectral_coefficients_global() const; + int truncation() const; private: diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index 58095c002..412bd1bef 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -8,7 +8,23 @@ * does it submit to any jurisdiction. */ +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/utils/Hash.h" + #include "atlas/trans/Trans.h" +#include "atlas/runtime/Log.h" +#include "atlas/functionspace.h" +#include "atlas/grid/Grid.h" + +#ifdef ATLAS_HAVE_TRANS +#include "atlas/trans/detail/ifs/TransIFSNodeColumns.h" +#include "atlas/trans/detail/ifs/TransIFSStructuredColumns.h" +#define TRANS_DEFAULT "ifs" +#else +#define TRANS_DEFAULT "local" +#endif namespace atlas { namespace trans { @@ -16,5 +32,285 @@ namespace trans { TransImpl::~TransImpl() { } + +namespace { + + static eckit::Mutex *local_mutex = 0; + static std::map *m = 0; + static pthread_once_t once = PTHREAD_ONCE_INIT; + + static void init() { + local_mutex = new eckit::Mutex(); + m = new std::map(); + } + + template void load_builder_functionspace() { TransBuilderFunctionSpace("tmp"); } + template void load_builder_grid() { TransBuilderGrid("tmp"); } + + struct force_link { + force_link() + { +#ifdef ATLAS_HAVE_TRANS + load_builder_functionspace(); + load_builder_functionspace(); + load_builder_grid(); +#endif + } + }; + +} + + + +TransFactory::TransFactory(const std::string &name): + name_(name) { + + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + ASSERT(m->find(name) == m->end()); + (*m)[name] = this; +} + + +TransFactory::~TransFactory() { + eckit::AutoLock lock(local_mutex); + m->erase(name_); +} + + +bool TransFactory::has(const std::string& name) { + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + return ( m->find(name) != m->end() ); +} + + +void TransFactory::list(std::ostream& out) { + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + const char* sep = ""; + for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { + out << sep << (*j).first; + sep = ", "; + } +} + + +Trans::Implementation *TransFactory::build( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { + + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + std::string suffix ( "("+gp.type()+","+sp.type()+")" ); + std::string name = config.getString("type",TRANS_DEFAULT)+suffix; + + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + + if( not config.has("type") and not has(name) ) { + name = std::string("local")+suffix; + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + } + + std::map::const_iterator j = m->find(name); + if (j == m->end()) { + Log::error() << "No TransFactory for [" << name << "]" << std::endl; + Log::error() << "TransFactories are:" << std::endl; + for (j = m->begin() ; j != m->end() ; ++j) + Log::error() << " " << (*j).first << std::endl; + throw eckit::SeriousBug(std::string("No TransFactory called ") + name); + } + + return (*j).second->make(gp,sp,config); +} + +Trans::Implementation *TransFactory::build( const Grid& grid, int truncation, const eckit::Configuration& config ) { + + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + std::string name = config.getString("type",TRANS_DEFAULT); + + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + + if( not config.has("type") and not has(name) ) { + name = std::string("local"); + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + } + + std::map::const_iterator j = m->find(name); + if (j == m->end()) { + Log::error() << "No TransFactory for [" << name << "]" << std::endl; + Log::error() << "TransFactories are:" << std::endl; + for (j = m->begin() ; j != m->end() ; ++j) + Log::error() << " " << (*j).first << std::endl; + throw eckit::SeriousBug(std::string("No TransFactory called ") + name); + } + + return (*j).second->make(grid,truncation,config); +} + + +Trans::Trans() { +} + +Trans::Trans( Implementation* impl ) : + impl_(impl) { +} + +Trans::Trans( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) : + impl_( TransFactory::build(gp,sp,config) ) { +} + +Trans::Trans( const Grid& grid, int truncation, const eckit::Configuration& config ) : + impl_( TransFactory::build(grid,truncation,config) ) { +} + +Trans::Trans( const Trans& trans ) : + impl_(trans.impl_) { +} + +int Trans::truncation() const { + return impl_->truncation(); +} + +const Grid& Trans::grid() const { + return impl_->grid(); +} + +void Trans::dirtrans( const Field& gpfield, + Field& spfield, + const eckit::Configuration& config ) const { + impl_->dirtrans( gpfield, spfield, config ); +} + +void Trans::dirtrans( const FieldSet& gpfields, + FieldSet& spfields, + const eckit::Configuration& config ) const { + impl_->dirtrans( gpfields, spfields, config ); +} + +void Trans::dirtrans_wind2vordiv( const Field& gpwind, + Field& spvor, Field& spdiv, + const eckit::Configuration& config ) const { + impl_->dirtrans_wind2vordiv( gpwind, spvor, spdiv, config ); +} + +void Trans::invtrans( const Field& spfield, + Field& gpfield, + const eckit::Configuration& config ) const { + impl_->invtrans( spfield, gpfield, config ); +} + +void Trans::invtrans( const FieldSet& spfields, + FieldSet& gpfields, + const eckit::Configuration& config ) const { + impl_->invtrans( spfields, gpfields, config ); +} + +void Trans::invtrans_grad( const Field& spfield, + Field& gradfield, + const eckit::Configuration& config ) const { + impl_->invtrans_grad( spfield, gradfield, config ); +} + +void Trans::invtrans_grad( const FieldSet& spfields, + FieldSet& gradfields, + const eckit::Configuration& config ) const { + impl_->invtrans_grad( spfields, gradfields, config ); +} + + +void Trans::invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, + Field& gpwind, + const eckit::Configuration& config ) const { + impl_->invtrans_vordiv2wind( spvor, spdiv, gpwind, config ); +} + +// -- IFS type fields -- +// These fields have special interpretation required. You need to know what you're doing. +// See IFS trans library. + +/*! + * @brief invtrans + * @param nb_scalar_fields + * @param scalar_spectra + * @param nb_vordiv_fields + * @param vorticity_spectra + * @param divergence_spectra + * @param gp_fields + */ +void Trans::invtrans( const int nb_scalar_fields, const double scalar_spectra[], + const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& config ) const { + impl_->invtrans( nb_scalar_fields, scalar_spectra, + nb_vordiv_fields, vorticity_spectra, divergence_spectra, + gp_fields, + config ); +} + +/*! + * @brief invtrans + * @param nb_fields + * @param scalar_spectra + * @param scalar_fields + */ +void Trans::invtrans( const int nb_scalar_fields, const double scalar_spectra[], + double gp_fields[], + const eckit::Configuration& config ) const { + impl_->invtrans( nb_scalar_fields, scalar_spectra, + gp_fields, + config ); +} + +/*! + * @brief Inverse transform of vorticity/divergence to wind(U/V) + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ +void Trans::invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& config ) const { + impl_->invtrans( nb_vordiv_fields, vorticity_spectra, divergence_spectra, + gp_fields, + config ); +} + +/*! + * @brief Direct transform of scalar fields + */ +void Trans::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& config ) const { + impl_->dirtrans( nb_fields, scalar_fields, scalar_spectra, + config ); +} + +/*! + * @brief Direct transform of wind(U/V) to vorticity/divergence + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ +void Trans::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], + const eckit::Configuration& config ) const { + impl_->dirtrans( nb_fields, wind_fields, vorticity_spectra, divergence_spectra, + config ); +} + + + } // namespace trans } // namespace atlas diff --git a/src/atlas/trans/Trans.h b/src/atlas/trans/Trans.h index 39bcb8976..0f3cc61f9 100644 --- a/src/atlas/trans/Trans.h +++ b/src/atlas/trans/Trans.h @@ -12,6 +12,7 @@ #include "eckit/config/Configuration.h" #include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" #include "atlas/util/Config.h" //----------------------------------------------------------------------------- @@ -20,6 +21,8 @@ namespace atlas { class Field; class FieldSet; + class FunctionSpace; + class Grid; } //----------------------------------------------------------------------------- @@ -37,9 +40,11 @@ class TransImpl : public eckit::Owned { virtual int truncation() const = 0; + virtual const Grid& grid() const = 0; + virtual void dirtrans( const Field& gpfield, Field& spfield, - const eckit::Configuration& = util::NoConfig() ) const = 0; + const eckit::Configuration& = util::NoConfig() ) const = 0; virtual void dirtrans( const FieldSet& gpfields, FieldSet& spfields, @@ -122,6 +127,169 @@ class TransImpl : public eckit::Owned { // ------------------------------------------------------------------ + + +class TransFactory { +public: + + /*! + * \brief build Trans with factory key, and default options + * \return mesh generator + */ + static TransImpl* build( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); + static TransImpl* build( const Grid&, int truncation, const eckit::Configuration& = util::Config() ); + + /*! + * \brief list all registered trans implementations + */ + static void list(std::ostream &); + + static bool has(const std::string& name); + +private: + + std::string name_; + virtual TransImpl* make(const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration&) { return nullptr; } + virtual TransImpl* make(const Grid& gp, int truncation, const eckit::Configuration&) { return nullptr; } + +protected: + + TransFactory(const std::string&); + virtual ~TransFactory(); + +}; + +//---------------------------------------------------------------------------------------------------------------------- + +template +class TransBuilderFunctionSpace : public TransFactory { + virtual TransImpl* make(const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config) { + return new T(gp,sp,config); + } +public: + TransBuilderFunctionSpace(const std::string& name) : TransFactory(name) {} +}; + +template +class TransBuilderGrid : public TransFactory { + virtual TransImpl* make(const Grid& grid, int truncation, const eckit::Configuration& config) { + return new T(grid,truncation,config); + } +public: + TransBuilderGrid(const std::string& name) : TransFactory(name) {} +}; + +//---------------------------------------------------------------------------------------------------------------------- + +class Trans { + +public: + + using Implementation = TransImpl; + +private: + + eckit::SharedPtr< Implementation > impl_; + +public: + + Trans(); + Trans( Implementation* ); + Trans( const Trans& ); + Trans( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); + Trans( const Grid&, int truncation, const eckit::Configuration& = util::NoConfig() ); + void hash(eckit::Hash&) const; + const Implementation* get() const { return impl_.get(); } + operator bool() const { return impl_.owners(); } + + int truncation() const; + const Grid& grid() const; + + void dirtrans( const Field& gpfield, + Field& spfield, + const eckit::Configuration& = util::NoConfig() ) const; + + void dirtrans( const FieldSet& gpfields, + FieldSet& spfields, + const eckit::Configuration& = util::NoConfig() ) const; + + void dirtrans_wind2vordiv( const Field& gpwind, + Field& spvor, Field& spdiv, + const eckit::Configuration& = util::NoConfig() ) const; + + void invtrans( const Field& spfield, + Field& gpfield, + const eckit::Configuration& = util::NoConfig() ) const; + + void invtrans( const FieldSet& spfields, + FieldSet& gpfields, + const eckit::Configuration& = util::NoConfig() ) const; + + void invtrans_grad( const Field& spfield, + Field& gradfield, + const eckit::Configuration& = util::NoConfig() ) const; + + void invtrans_grad( const FieldSet& spfields, + FieldSet& gradfields, + const eckit::Configuration& = util::NoConfig() ) const; + + + void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, + Field& gpwind, + const eckit::Configuration& = util::NoConfig() ) const; + + // -- IFS type fields -- + // These fields have special interpretation required. You need to know what you're doing. + // See IFS trans library. + + /*! + * @brief invtrans + * @param nb_scalar_fields + * @param scalar_spectra + * @param nb_vordiv_fields + * @param vorticity_spectra + * @param divergence_spectra + * @param gp_fields + */ + void invtrans( const int nb_scalar_fields, const double scalar_spectra[], + const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const; + + /*! + * @brief invtrans + * @param nb_fields + * @param scalar_spectra + * @param scalar_fields + */ + void invtrans( const int nb_scalar_fields, const double scalar_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const; + + /*! + * @brief Inverse transform of vorticity/divergence to wind(U/V) + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ + void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const; + + /*! + * @brief Direct transform of scalar fields + */ + void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& = util::NoConfig() ) const; + + /*! + * @brief Direct transform of wind(U/V) to vorticity/divergence + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ + void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], + const eckit::Configuration& = util::NoConfig() ) const; +}; + +//---------------------------------------------------------------------------------------------------------------------- + } // namespace trans } // namespace atlas diff --git a/src/atlas/trans/detail/TransIFS.cc b/src/atlas/trans/detail/TransIFS.cc index fcd2e4f97..2debf95c9 100644 --- a/src/atlas/trans/detail/TransIFS.cc +++ b/src/atlas/trans/detail/TransIFS.cc @@ -33,6 +33,10 @@ using atlas::array::make_view; namespace atlas { namespace trans { +namespace { +static TransBuilderGrid builder("ifs"); +} + class TransParameters { public: TransParameters( const eckit::Configuration& config ) : config_(config) {} @@ -679,6 +683,10 @@ TransIFS::TransIFS(const Grid& grid, const long truncation, const TransIFS::Opti ctor( grid,truncation,p); } +TransIFS::TransIFS( const Grid& g, const long truncation, const eckit::Configuration& config ) : + TransIFS(g,truncation) { +} + //TransIFS::TransIFS(const long truncation, const TransIFS::Options& p ) //{ // ctor_spectral_only(truncation,p); diff --git a/src/atlas/trans/detail/TransIFS.h b/src/atlas/trans/detail/TransIFS.h index 2578cbfce..9223fc42c 100644 --- a/src/atlas/trans/detail/TransIFS.h +++ b/src/atlas/trans/detail/TransIFS.h @@ -132,6 +132,7 @@ class TransIFS : public trans::TransImpl { /// @brief Constructor given grid and spectral truncation TransIFS( const Grid& g, const long truncation, const Options& = Options() ); + TransIFS( const Grid& g, const long truncation, const eckit::Configuration& ); virtual ~TransIFS(); operator ::Trans_t*() const { return trans(); } @@ -143,7 +144,7 @@ class TransIFS : public trans::TransImpl { size_t nb_gridpoints() const { return trans_->ngptot; } size_t nb_gridpoints_global() const { return trans_->ngptotg; } - grid::StructuredGrid grid() const { return grid_; } + virtual const Grid& grid() const { return grid_; } diff --git a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc b/src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc new file mode 100644 index 000000000..665d2073a --- /dev/null +++ b/src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc @@ -0,0 +1,38 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/trans/detail/ifs/TransIFSNodeColumns.h" + +#include "atlas/functionspace/NodeColumns.h" +#include "atlas/functionspace/Spectral.h" + +namespace atlas { +namespace trans { + +TransIFSNodeColumns::TransIFSNodeColumns( + const functionspace::NodeColumns& gp, + const functionspace::Spectral& sp, + const eckit::Configuration& ) : + TransIFS( gp.mesh().grid(), sp.truncation() ) { +} + + +TransIFSNodeColumns::~TransIFSNodeColumns() +{ +} + + +namespace { +static TransBuilderFunctionSpace< TransIFSNodeColumns > builder("ifs(NodeColumns,Spectral)"); +} + + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.h b/src/atlas/trans/detail/ifs/TransIFSNodeColumns.h new file mode 100644 index 000000000..ad69db101 --- /dev/null +++ b/src/atlas/trans/detail/ifs/TransIFSNodeColumns.h @@ -0,0 +1,41 @@ +/* + * (C) Copyright 1996-2017 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/trans/detail/TransIFS.h" + +//----------------------------------------------------------------------------- +// Forward declarations + +namespace atlas { +namespace functionspace { + class NodeColumns; + class Spectral; +} +} + +//----------------------------------------------------------------------------- + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +class TransIFSNodeColumns : public trans::TransIFS { +public: + TransIFSNodeColumns( const functionspace::NodeColumns&, const functionspace::Spectral&, const eckit::Configuration& = util::Config() ); + virtual ~TransIFSNodeColumns(); +}; + +//----------------------------------------------------------------------------- + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc b/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc new file mode 100644 index 000000000..8fdd79800 --- /dev/null +++ b/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc @@ -0,0 +1,36 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/trans/detail/ifs/TransIFSStructuredColumns.h" + +#include "atlas/functionspace/StructuredColumns.h" +#include "atlas/functionspace/Spectral.h" + +namespace atlas { +namespace trans { + +TransIFSStructuredColumns::TransIFSStructuredColumns( + const functionspace::StructuredColumns& gp, + const functionspace::Spectral& sp, + const eckit::Configuration& ) : + TransIFS( gp.grid(), sp.truncation() ) { +} + + +TransIFSStructuredColumns::~TransIFSStructuredColumns() +{ +} + +namespace { +static TransBuilderFunctionSpace< TransIFSStructuredColumns > builder("ifs(StructuredColumns,Spectral)"); +} + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h b/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h new file mode 100644 index 000000000..dac050cda --- /dev/null +++ b/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h @@ -0,0 +1,41 @@ +/* + * (C) Copyright 1996-2017 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/trans/detail/TransIFS.h" + +//----------------------------------------------------------------------------- +// Forward declarations + +namespace atlas { +namespace functionspace { + class StructuredColumns; + class Spectral; +} +} + +//----------------------------------------------------------------------------- + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +class TransIFSStructuredColumns : public trans::TransIFS { +public: + TransIFSStructuredColumns( const functionspace::StructuredColumns&, const functionspace::Spectral&, const eckit::Configuration& = util::Config() ); + virtual ~TransIFSStructuredColumns(); +}; + +//----------------------------------------------------------------------------- + +} // namespace trans +} // namespace atlas diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 90f34f46d..0d910603a 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -34,6 +34,8 @@ #ifdef ATLAS_HAVE_TRANS #include "atlas/trans/detail/TransIFS.h" +#include "atlas/trans/detail/ifs/TransIFSNodeColumns.h" +#include "atlas/trans/detail/ifs/TransIFSStructuredColumns.h" #endif using namespace eckit; @@ -368,6 +370,103 @@ CASE( "test_nomesh" ) } } + +CASE( "test_trans_factory" ) +{ + Log::info() << "test_trans_factory" << std::endl; + + trans::TransFactory::list( Log::info() ); + Log::info() << std::endl; + + functionspace::StructuredColumns gp ( Grid("O48") ); + functionspace::Spectral sp ( 47 ); + + trans::Trans trans1 = trans::Trans(gp,sp); + EXPECT( bool(trans1) == true ); + + trans::Trans trans2 = trans::Trans( Grid("O48"), 47 ); + EXPECT( bool(trans2) == true ); +} + +CASE( "test_trans_using_grid" ) +{ + Log::info() << "test_trans_using_grid" << std::endl; + + trans::Trans trans( Grid("O48"), 47 ); + + functionspace::StructuredColumns gp ( trans.grid() ); + functionspace::Spectral sp ( trans.truncation() ); + + Field spf = sp.createField(option::name("spf")); + Field gpf = gp.createField(option::name("gpf")); + + EXPECT_NO_THROW( trans.dirtrans(gpf,spf) ); + EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); + + FieldSet gpfields; gpfields.add(gpf); + FieldSet spfields; spfields.add(spf); + + EXPECT_NO_THROW( trans.dirtrans(gpfields,spfields) ); + EXPECT_NO_THROW( trans.invtrans(spfields,gpfields) ); + + gpfields.add(gpf); + EXPECT_THROWS_AS(trans.dirtrans(gpfields,spfields),eckit::SeriousBug); + +} + +CASE( "test_trans_using_functionspace_NodeColumns" ) +{ + Log::info() << "test_trans_using_functionspace_NodeColumns" << std::endl; + + functionspace::NodeColumns gp ( MeshGenerator("structured").generate( Grid("O48") ) ); + functionspace::Spectral sp ( 47 ); + + trans::Trans trans( gp, sp ); + + Field spf = sp.createField(option::name("spf")); + Field gpf = gp.createField(option::name("gpf")); + + EXPECT_NO_THROW( trans.dirtrans(gpf,spf) ); + EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); + + FieldSet gpfields; gpfields.add(gpf); + FieldSet spfields; spfields.add(spf); + + EXPECT_NO_THROW( trans.dirtrans(gpfields,spfields) ); + EXPECT_NO_THROW( trans.invtrans(spfields,gpfields) ); + + gpfields.add(gpf); + EXPECT_THROWS_AS(trans.dirtrans(gpfields,spfields),eckit::SeriousBug); + +} + +CASE( "test_trans_using_functionspace_StructuredColumns" ) +{ + Log::info() << "test_trans_using_functionspace_StructuredColumns" << std::endl; + + functionspace::StructuredColumns gp ( Grid("O48") ); + functionspace::Spectral sp ( 47 ); + + trans::Trans trans( gp, sp ); + + Field spf = sp.createField(option::name("spf")); + Field gpf = gp.createField(option::name("gpf")); + + EXPECT_NO_THROW( trans.dirtrans(gpf,spf) ); + EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); + + FieldSet gpfields; gpfields.add(gpf); + FieldSet spfields; spfields.add(spf); + + EXPECT_NO_THROW( trans.dirtrans(gpfields,spfields) ); + EXPECT_NO_THROW( trans.invtrans(spfields,gpfields) ); + + gpfields.add(gpf); + EXPECT_THROWS_AS(trans.dirtrans(gpfields,spfields),eckit::SeriousBug); + +} + + //----------------------------------------------------------------------------- } // namespace test From b6b3333ed6fa69bd0b303b0bcecaee84eb164631 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 16 Nov 2017 19:41:44 +0000 Subject: [PATCH 170/355] ATLAS-134 Work on caching of Trans --- src/atlas/trans/Trans.cc | 68 ++++++ src/atlas/trans/Trans.h | 42 +++- src/atlas/trans/detail/TransIFS.cc | 207 +++++++----------- src/atlas/trans/detail/TransIFS.h | 86 ++++---- .../trans/detail/ifs/TransIFSNodeColumns.cc | 11 +- .../trans/detail/ifs/TransIFSNodeColumns.h | 13 +- .../detail/ifs/TransIFSStructuredColumns.cc | 12 +- .../detail/ifs/TransIFSStructuredColumns.h | 13 +- src/tests/trans/fctest_trans.F90 | 6 +- src/tests/trans/test_trans.cc | 40 ++-- src/tests/trans/test_trans_invtrans_grad.cc | 2 +- 11 files changed, 302 insertions(+), 198 deletions(-) diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index 412bd1bef..71a5c8669 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -136,6 +136,36 @@ Trans::Implementation *TransFactory::build( const FunctionSpace& gp, const Funct return (*j).second->make(gp,sp,config); } +Trans::Implementation *TransFactory::build( const TransCache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { + + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + std::string suffix ( "("+gp.type()+","+sp.type()+")" ); + std::string name = config.getString("type",TRANS_DEFAULT)+suffix; + + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + + if( not config.has("type") and not has(name) ) { + name = std::string("local")+suffix; + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + } + + std::map::const_iterator j = m->find(name); + if (j == m->end()) { + Log::error() << "No TransFactory for [" << name << "]" << std::endl; + Log::error() << "TransFactories are:" << std::endl; + for (j = m->begin() ; j != m->end() ; ++j) + Log::error() << " " << (*j).first << std::endl; + throw eckit::SeriousBug(std::string("No TransFactory called ") + name); + } + + return (*j).second->make(cache,gp,sp,config); +} + Trans::Implementation *TransFactory::build( const Grid& grid, int truncation, const eckit::Configuration& config ) { pthread_once(&once, init); @@ -165,6 +195,36 @@ Trans::Implementation *TransFactory::build( const Grid& grid, int truncation, co return (*j).second->make(grid,truncation,config); } +Trans::Implementation *TransFactory::build( const TransCache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { + + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + std::string name = config.getString("type",TRANS_DEFAULT); + + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + + if( not config.has("type") and not has(name) ) { + name = std::string("local"); + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + } + + std::map::const_iterator j = m->find(name); + if (j == m->end()) { + Log::error() << "No TransFactory for [" << name << "]" << std::endl; + Log::error() << "TransFactories are:" << std::endl; + for (j = m->begin() ; j != m->end() ; ++j) + Log::error() << " " << (*j).first << std::endl; + throw eckit::SeriousBug(std::string("No TransFactory called ") + name); + } + + return (*j).second->make(cache,grid,truncation,config); +} + + Trans::Trans() { } @@ -181,6 +241,14 @@ Trans::Trans( const Grid& grid, int truncation, const eckit::Configuration& conf impl_( TransFactory::build(grid,truncation,config) ) { } +Trans::Trans( const TransCache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) : + impl_( TransFactory::build(cache,gp,sp,config) ) { +} + +Trans::Trans( const TransCache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) : + impl_( TransFactory::build(cache,grid,truncation,config) ) { +} + Trans::Trans( const Trans& trans ) : impl_(trans.impl_) { } diff --git a/src/atlas/trans/Trans.h b/src/atlas/trans/Trans.h index 0f3cc61f9..3ef592741 100644 --- a/src/atlas/trans/Trans.h +++ b/src/atlas/trans/Trans.h @@ -32,6 +32,20 @@ namespace trans { //----------------------------------------------------------------------------- +class TransCacheEntry { +public: + virtual operator bool() const = 0; + virtual size_t size() const = 0; + virtual const void* data() const = 0; + virtual std::string hash() const = 0; +}; + +class TransCache { +public: + virtual const TransCacheEntry& legendre() const = 0; + virtual const TransCacheEntry& fft() const = 0; +}; + class TransImpl : public eckit::Owned { public: @@ -133,12 +147,15 @@ class TransFactory { public: /*! - * \brief build Trans with factory key, and default options - * \return mesh generator + * \brief build Trans + * \return TransImpl */ static TransImpl* build( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); static TransImpl* build( const Grid&, int truncation, const eckit::Configuration& = util::Config() ); + static TransImpl* build( const TransCache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); + static TransImpl* build( const TransCache&, const Grid&, int truncation, const eckit::Configuration& = util::Config() ); + /*! * \brief list all registered trans implementations */ @@ -149,8 +166,10 @@ class TransFactory { private: std::string name_; - virtual TransImpl* make(const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration&) { return nullptr; } - virtual TransImpl* make(const Grid& gp, int truncation, const eckit::Configuration&) { return nullptr; } + virtual TransImpl* make( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& ) { return nullptr; } + virtual TransImpl* make( const Grid& gp, int truncation, const eckit::Configuration& ) { return nullptr; } + virtual TransImpl* make( const TransCache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& ) { return nullptr; } + virtual TransImpl* make( const TransCache&, const Grid& gp, int truncation, const eckit::Configuration& ) { return nullptr; } protected: @@ -163,18 +182,24 @@ class TransFactory { template class TransBuilderFunctionSpace : public TransFactory { - virtual TransImpl* make(const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config) { + virtual TransImpl* make( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { return new T(gp,sp,config); } + virtual TransImpl* make( const TransCache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { + return new T(cache,gp,sp,config); + } public: TransBuilderFunctionSpace(const std::string& name) : TransFactory(name) {} }; template class TransBuilderGrid : public TransFactory { - virtual TransImpl* make(const Grid& grid, int truncation, const eckit::Configuration& config) { + virtual TransImpl* make( const Grid& grid, int truncation, const eckit::Configuration& config ) { return new T(grid,truncation,config); } + virtual TransImpl* make( const TransCache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { + return new T(cache,grid,truncation,config); + } public: TransBuilderGrid(const std::string& name) : TransFactory(name) {} }; @@ -196,8 +221,13 @@ class Trans { Trans(); Trans( Implementation* ); Trans( const Trans& ); + Trans( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); Trans( const Grid&, int truncation, const eckit::Configuration& = util::NoConfig() ); + + Trans( const TransCache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); + Trans( const TransCache&, const Grid&, int truncation, const eckit::Configuration& = util::NoConfig() ); + void hash(eckit::Hash&) const; const Implementation* get() const { return impl_.get(); } operator bool() const { return impl_.owners(); } diff --git a/src/atlas/trans/detail/TransIFS.cc b/src/atlas/trans/detail/TransIFS.cc index 2debf95c9..16cfcdbf4 100644 --- a/src/atlas/trans/detail/TransIFS.cc +++ b/src/atlas/trans/detail/TransIFS.cc @@ -54,6 +54,26 @@ class TransParameters { return config_.getBool("vorticity_divergence_fields",false); } + bool split_latitudes() const { + return config_.getBool("split_latitudes",true); + } + + FFT fft() const { + return static_cast( config_.getInt("fft",int(FFTW)) ); + } + + bool flt() const { + return config_.getBool("flt",false); + } + + std::string read_legendre() const { + return config_.getString("read_legendre",""); + } + + std::string write_legendre() const { + return config_.getString("write_legendre",""); + } + private: const eckit::Configuration& config_; }; @@ -65,7 +85,7 @@ std::string fieldset_functionspace( const FieldSet& fields ) { if( functionspace == "undefined" ) functionspace = fields[jfld].functionspace().type(); if( fields[jfld].functionspace().type() != functionspace ) { - throw eckit::SeriousBug("trans: fielset has fields with different functionspaces",Here()); + throw eckit::SeriousBug(": fielset has fields with different functionspaces",Here()); } } return functionspace; @@ -668,55 +688,65 @@ struct UnpackSpectral namespace atlas { namespace trans { -TransIFS::TransIFS(const Grid& grid, const TransIFS::Options& p) : - grid_(grid) { +class EmptyCacheEntry : public TransCacheEntry { +public: + virtual operator bool() const { return false; } + virtual size_t size() const { return 0; } + virtual const void* data() const { return nullptr; } + virtual std::string hash() const { return "empty"; } +}; + +class NoCache : public TransCache { + virtual TransCacheEntry& legendre() const override { static EmptyCacheEntry cache; return cache; } + virtual TransCacheEntry& fft() const override { static EmptyCacheEntry cache; return cache; } +}; + + +TransIFS::TransIFS( const TransCache& cache, const Grid& grid, const long truncation, const eckit::Configuration& config ) : + grid_(grid), + cache_( cache.legendre().data() ), + cachesize_( cache.legendre().size() ) { ASSERT( grid.domain().global() ); ASSERT( not grid.projection() ); - size_t grid_only = -1; // triggers grid-only setup - ctor(grid,grid_only,p); + ctor( grid, truncation, config ); } -TransIFS::TransIFS(const Grid& grid, const long truncation, const TransIFS::Options& p ) : - grid_(grid) { +TransIFS::TransIFS( const Grid& grid, const long truncation, const eckit::Configuration& config ) : + TransIFS(NoCache(),grid,truncation,config) { ASSERT( grid.domain().global() ); ASSERT( not grid.projection() ); - ctor( grid,truncation,p); + ctor( grid, truncation, config ); } -TransIFS::TransIFS( const Grid& g, const long truncation, const eckit::Configuration& config ) : - TransIFS(g,truncation) { +TransIFS::TransIFS(const Grid& grid, const eckit::Configuration& config ) : + TransIFS( grid, /*grid-only*/-1, config ) { } -//TransIFS::TransIFS(const long truncation, const TransIFS::Options& p ) -//{ -// ctor_spectral_only(truncation,p); -//} - TransIFS::~TransIFS() { } -void TransIFS::ctor( const Grid& grid, long truncation, const TransIFS::Options& p ) { +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); delete p; }); if( auto gg = grid::GaussianGrid(grid) ) { - ctor_rgg(gg.ny(), gg.nx().data(), truncation, p); + ctor_rgg(gg.ny(), gg.nx().data(), truncation, config ); return; } if( auto ll = grid::RegularLonLatGrid(grid) ) { if( ll.standard() || ll.shifted() ) { - ctor_lonlat( ll.nx(), ll.ny(), truncation, p ); + ctor_lonlat( ll.nx(), ll.ny(), truncation, config ); return; } } throw eckit::NotImplemented("Grid type not supported for Spectral Transforms",Here()); } -void TransIFS::ctor_spectral_only(long truncation, const TransIFS::Options& p ) +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); @@ -728,8 +758,9 @@ void TransIFS::ctor_spectral_only(long truncation, const TransIFS::Options& p ) TRANS_CHECK(::trans_setup(trans_.get())); } -void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const TransIFS::Options& p ) +void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const eckit::Configuration& config ) { + TransParameters p(config); std::vector nloen(nlat); for( long jlat=0; jlat= 0 ) TRANS_CHECK(::trans_set_trunc(trans_.get(),truncation)); - TRANS_CHECK(::trans_set_cache(trans_.get(),p.cache(),p.cachesize())); - if( not p.read().empty() ) + TRANS_CHECK(::trans_set_cache(trans_.get(),cache_,cachesize_)); + + if( p.read_legendre().size() && parallel::mpi::comm().size() == 1 ) { - if( eckit::PathName(p.read()).exists() ) + eckit::PathName file( p.read_legendre() ); + if( not file.exists() ) { - std::stringstream msg; msg << "File " << p.read() << "doesn't exist"; + std::stringstream msg; msg << "File " << file << " doesn't exist"; throw eckit::CantOpenFile(msg.str(),Here()); } - TRANS_CHECK(::trans_set_read(trans_.get(),p.read().c_str())); + TRANS_CHECK(::trans_set_read(trans_.get(),file.asString().c_str())); + } + if( p.write_legendre().size() && parallel::mpi::comm().size() == 1 ) { + eckit::PathName file( p.write_legendre() ); + TRANS_CHECK(::trans_set_write(trans_.get(),file.asString().c_str())); } - if( !p.write().empty() ) - TRANS_CHECK(::trans_set_write(trans_.get(),p.write().c_str())); trans_->fft = p.fft(); trans_->lsplit = p.split_latitudes(); @@ -759,25 +794,28 @@ void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const TRANS_CHECK(::trans_setup(trans_.get())); } -void TransIFS::ctor_lonlat(const long nlon, const long nlat, long truncation, const TransIFS::Options& p ) +void TransIFS::ctor_lonlat(const long nlon, const long nlat, long truncation, const eckit::Configuration& config ) { + TransParameters p(config); TRANS_CHECK(::trans_new(trans_.get())); 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(),p.cache(),p.cachesize())); + TRANS_CHECK(::trans_set_cache(trans_.get(),cache_,cachesize_)); - if( not p.read().empty() ) - { - if( eckit::PathName(p.read()).exists() ) + if( p.read_legendre().size() && parallel::mpi::comm().size() == 1 ) { + eckit::PathName file( p.read_legendre() ); + if( not file.exists() ) { - std::stringstream msg; msg << "File " << p.read() << "doesn't exist"; + std::stringstream msg; msg << "File " << file << " doesn't exist"; throw eckit::CantOpenFile(msg.str(),Here()); } - TRANS_CHECK(::trans_set_read(trans_.get(),p.read().c_str())); + TRANS_CHECK(::trans_set_read(trans_.get(),file.asString().c_str())); + } + if( p.write_legendre().size() && parallel::mpi::comm().size() == 1 ) { + eckit::PathName file( p.write_legendre() ); + TRANS_CHECK(::trans_set_write(trans_.get(),file.asString().c_str())); } - if( not p.write().empty() ) - TRANS_CHECK(::trans_set_write(trans_.get(),p.write().c_str())); trans_->fft = p.fft(); trans_->lsplit = p.split_latitudes(); @@ -787,100 +825,12 @@ void TransIFS::ctor_lonlat(const long nlon, const long nlat, long truncation, co TRANS_CHECK(::trans_setup(trans_.get())); } -TransIFS::Options::Options() : util::Config() -{ - set_cache(nullptr,0); - set_split_latitudes(true); - set_fft(FFTW); - set_flt(false); -} - -void TransIFS::Options::set_cache(const void* buffer, size_t size) -{ - cacheptr_=buffer; - cachesize_=size; -} - -const void* TransIFS::Options::cache() const -{ - return cacheptr_; -} -size_t TransIFS::Options::cachesize() const -{ - return cachesize_; +namespace option{ +const std::map fft::to_str = { {FFT992,"FFT992"},{FFTW,"FFTW"} }; +const std::map fft::to_enum = { {"FFT992",FFT992},{"FFTW",FFTW} }; } -void TransIFS::Options::set_fft( FFT fft ) -{ - if( fft == FFTW ) - { - set( "fft", "FFTW" ); - } - else if( fft == FFT992 ) - { - set( "fft", "FFT992" ); - } - else - { - NOTIMP; - } -} - -void TransIFS::Options::set_split_latitudes( bool split ) -{ - set("split_latitudes",split); -} - -void TransIFS::Options::set_flt( bool flt ) -{ - set("flt",flt); -} - -bool TransIFS::Options::split_latitudes() const -{ - return getBool("split_latitudes"); -} - -FFT TransIFS::Options::fft() const -{ - std::string fftstr = getString( "fft" ); - if( fftstr == "FFTW" ) - return FFTW; - else if( fftstr == "FFT992" ) - return FFT992; - else - NOTIMP; - return FFTW; -} - -bool TransIFS::Options::flt() const -{ - return getBool("flt"); -} - - -void TransIFS::Options::set_read(const std::string& file) -{ - set("read",file); -} - -std::string TransIFS::Options::read() const -{ - return getString("read",""); -} - -void TransIFS::Options::set_write(const std::string& file) -{ - set("write",file); -} - -std::string TransIFS::Options::write() const -{ - return getString("write",""); -} - - // -------------------------------------------------------------------------------------------- @@ -1347,8 +1297,6 @@ void TransIFS::__dirtrans_wind2vordiv( const functionspace::NodeColumns& gp, con ASSERT( transform.rspdiv ); TRANS_CHECK( ::trans_dirtrans(&transform) ); } - ATLAS_DEBUG_HERE(); - } @@ -1634,6 +1582,7 @@ const Grid::Implementation* atlas__Trans__grid(const TransIFS* This) ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( This->grid() ); + ATLAS_DEBUG_VAR( This->grid().get()->owners() ); return This->grid().get(); ); return nullptr; diff --git a/src/atlas/trans/detail/TransIFS.h b/src/atlas/trans/detail/TransIFS.h index 9223fc42c..bc05a1fa8 100644 --- a/src/atlas/trans/detail/TransIFS.h +++ b/src/atlas/trans/detail/TransIFS.h @@ -10,6 +10,7 @@ #pragma once +#include "eckit/filesystem/PathName.h" #include "transi/trans.h" #include "atlas/array/LocalView.h" #include "atlas/grid/Grid.h" @@ -67,8 +68,9 @@ namespace atlas { namespace trans { ////----------------------------------------------------------------------------- +enum FFT { FFT992=TRANS_FFT992, FFTW=TRANS_FFTW }; -namespace options { +namespace option { class scalar_derivatives : public util::Config { public: @@ -85,54 +87,54 @@ class vorticity_divergence_fields : public util::Config { vorticity_divergence_fields( bool v ) { set("vorticity_divergence_fields",v); } }; -} - -//----------------------------------------------------------------------------- - -enum FFT { FFT992=TRANS_FFT992, FFTW=TRANS_FFTW }; +class flt : public util::Config { +public: + flt(bool); +}; +inline flt::flt(bool flt) { set("flt",flt); } -class TransIFS : public trans::TransImpl { +class fft : public util::Config { +public: + fft( FFT ); + fft( const std::string& ); private: - typedef struct ::Trans_t Trans_t; + static const std::map to_str; + static const std::map to_enum; +}; +inline fft::fft( FFT fft ) { set("fft",fft); } +inline fft::fft( const std::string& fft ) { set("fft",to_enum.at(fft)); } +class split_latitudes : public util::Config { public: + split_latitudes(bool); +}; +inline split_latitudes::split_latitudes(bool split_latitudes) { set("split_latitudes",split_latitudes); } - class Options : public util::Config { - public: +class write_legendre : public util::Config { +public: + write_legendre( const eckit::PathName& ); +}; +inline write_legendre::write_legendre( const eckit::PathName& filepath ) { set("write_legendre",filepath); } - Options(); - ~Options() {} +class read_legendre : public util::Config { +public: + read_legendre( const eckit::PathName& ); +}; +inline read_legendre::read_legendre( const eckit::PathName& filepath ) { set("read_legendre",filepath); } - void set_split_latitudes(bool); - void set_fft( FFT ); - void set_flt(bool); - void set_cache(const void* buffer, const size_t size); - void set_read(const std::string&); - void set_write(const std::string&); +} - bool split_latitudes() const; - FFT fft() const; - bool flt() const; - const void* cache()const; - size_t cachesize() const; - std::string read() const; - std::string write() const; +//----------------------------------------------------------------------------- - private: // not represented in Configuration internals - const void* cacheptr_; - size_t cachesize_; - }; +class TransIFS : public trans::TransImpl { +private: + typedef struct ::Trans_t Trans_t; public: -// /// @brief Constructor for spectral-only setup -// /// (e.g. for parallelisation routines) -// TransIFS(const long truncation, const Options& = Options() ); - - /// @brief Constructor given grid and spectral truncation - TransIFS( const Grid& g, const long truncation, const Options& = Options() ); - TransIFS( const Grid& g, const long truncation, const eckit::Configuration& ); + TransIFS( const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); + TransIFS( const TransCache&, const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); virtual ~TransIFS(); operator ::Trans_t*() const { return trans(); } @@ -308,19 +310,19 @@ class TransIFS : public trans::TransImpl { private: - void ctor( const Grid&, long nsmax, const Options& ); + void ctor( const Grid&, long nsmax, const eckit::Configuration& ); - void ctor_rgg(const long nlat, const long pl[], long nsmax, const Options& ); + void ctor_rgg(const long nlat, const long pl[], long nsmax, const eckit::Configuration& ); - void ctor_lonlat(const long nlon, const long nlat, long nsmax, const Options& ); + void ctor_lonlat(const long nlon, const long nlat, long nsmax, const eckit::Configuration& ); - void ctor_spectral_only(long truncation, const TransIFS::Options& p ); + void ctor_spectral_only(long truncation, const eckit::Configuration& ); private: friend class grid::detail::partitioner::TransPartitioner; /// @brief Constructor for grid-only setup (e.g. for partitioning/parallelisation routines) - TransIFS(const Grid& g, const Options& = Options() ); + TransIFS(const Grid& g, const eckit::Configuration& = util::NoConfig() ); int handle() const { return trans_->handle; } int ndgl() const { return trans_->ndgl; } @@ -515,6 +517,8 @@ class TransIFS : public trans::TransImpl { friend class functionspace::detail::Spectral; mutable std::shared_ptr<::Trans_t> trans_; grid::StructuredGrid grid_; + const void* cache_{nullptr}; + size_t cachesize_{0}; }; //----------------------------------------------------------------------------- diff --git a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc b/src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc index 665d2073a..20a48ed00 100644 --- a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc +++ b/src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc @@ -19,10 +19,17 @@ namespace trans { TransIFSNodeColumns::TransIFSNodeColumns( const functionspace::NodeColumns& gp, const functionspace::Spectral& sp, - const eckit::Configuration& ) : - TransIFS( gp.mesh().grid(), sp.truncation() ) { + const eckit::Configuration& config ) : + TransIFS( gp.mesh().grid(), sp.truncation(), config ) { } +TransIFSNodeColumns::TransIFSNodeColumns( + const TransCache& cache, + const functionspace::NodeColumns& gp, + const functionspace::Spectral& sp, + const eckit::Configuration& config ) : + TransIFS( cache, gp.mesh().grid(), sp.truncation(), config ) { +} TransIFSNodeColumns::~TransIFSNodeColumns() { diff --git a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.h b/src/atlas/trans/detail/ifs/TransIFSNodeColumns.h index ad69db101..491c41ef0 100644 --- a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.h +++ b/src/atlas/trans/detail/ifs/TransIFSNodeColumns.h @@ -31,7 +31,18 @@ namespace trans { class TransIFSNodeColumns : public trans::TransIFS { public: - TransIFSNodeColumns( const functionspace::NodeColumns&, const functionspace::Spectral&, const eckit::Configuration& = util::Config() ); + + TransIFSNodeColumns( + const functionspace::NodeColumns&, + const functionspace::Spectral&, + const eckit::Configuration& = util::Config() ); + + TransIFSNodeColumns( + const TransCache&, + const functionspace::NodeColumns&, + const functionspace::Spectral&, + const eckit::Configuration& = util::Config() ); + virtual ~TransIFSNodeColumns(); }; diff --git a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc b/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc index 8fdd79800..854f5de35 100644 --- a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc +++ b/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc @@ -19,8 +19,16 @@ namespace trans { TransIFSStructuredColumns::TransIFSStructuredColumns( const functionspace::StructuredColumns& gp, const functionspace::Spectral& sp, - const eckit::Configuration& ) : - TransIFS( gp.grid(), sp.truncation() ) { + const eckit::Configuration& config ) : + TransIFS( gp.grid(), sp.truncation(), config ) { +} + +TransIFSStructuredColumns::TransIFSStructuredColumns( + const TransCache& cache, + const functionspace::StructuredColumns& gp, + const functionspace::Spectral& sp, + const eckit::Configuration& config ) : + TransIFS( cache, gp.grid(), sp.truncation(), config ) { } diff --git a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h b/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h index dac050cda..619a1dd0d 100644 --- a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h +++ b/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h @@ -31,7 +31,18 @@ namespace trans { class TransIFSStructuredColumns : public trans::TransIFS { public: - TransIFSStructuredColumns( const functionspace::StructuredColumns&, const functionspace::Spectral&, const eckit::Configuration& = util::Config() ); + + TransIFSStructuredColumns( + const functionspace::StructuredColumns&, + const functionspace::Spectral&, + const eckit::Configuration& = util::Config() ); + + TransIFSStructuredColumns( + const TransCache&, + const functionspace::StructuredColumns&, + const functionspace::Spectral&, + const eckit::Configuration& = util::Config() ); + virtual ~TransIFSStructuredColumns(); }; diff --git a/src/tests/trans/fctest_trans.F90 b/src/tests/trans/fctest_trans.F90 index 6a0302f72..f8d6355d5 100644 --- a/src/tests/trans/fctest_trans.F90 +++ b/src/tests/trans/fctest_trans.F90 @@ -70,18 +70,20 @@ end module fctest_atlas_trans_fixture meshgenerator = atlas_MeshGenerator() mesh = meshgenerator%generate(grid) + call meshgenerator%final() FCTEST_CHECK_EQUAL( mesh%owners(), 1 ) + FCTEST_CHECK_EQUAL( grid%owners(), 2 ) ! mesh tracks grid trans = atlas_Trans(grid,truncation) - FCTEST_CHECK_EQUAL( grid%owners(), 2 ) + FCTEST_CHECK_EQUAL( grid%owners(), 3 ) ! trans tracks grid FCTEST_CHECK_EQUAL( trans%nb_gridpoints(), int(grid%size()) ) FCTEST_CHECK_EQUAL( trans%nb_gridpoints_global(), int(grid%size()) ) trans_grid = trans%grid() - FCTEST_CHECK_EQUAL( trans_grid%owners(), 3 ) + FCTEST_CHECK_EQUAL( trans_grid%owners(), 4 ) FCTEST_CHECK( .not. trans%is_null() ) FCTEST_CHECK_EQUAL( trans%truncation(), truncation ) diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 0d910603a..ebbcecbf5 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -158,24 +158,38 @@ CASE( "test_trans_distribution_matches_atlas" ) CASE( "test_trans_options" ) { - trans::TransIFS::Options opts; - opts.set_fft(trans::FFTW); - opts.set_split_latitudes(false); - opts.set_read("readfile"); - + util::Config opts ( + trans::option::fft(trans::FFTW) | + trans::option::split_latitudes(false) | + trans::option::read_legendre("readfile") ); Log::info() << "trans_opts = " << opts << std::endl; } -CASE( "test_distspec" ) -{ - trans::TransIFS::Options p; - #ifdef TRANS_HAVE_IO - if( parallel::mpi::comm().size() == 1 ) - p.set_write("cached_legendre_coeffs"); +CASE( "test_write_read_cache" ) +{ + util::Config write_legendre; + util::Config read_legendre; + if( parallel::mpi::comm().size() == 1 ) { + write_legendre = trans::option::write_legendre("cached_legendre_coeffs"); + read_legendre = trans::option::read_legendre("cached_legendre_coeffs"); + } + // Create trans that will write file + trans::Trans trans_write_F24( Grid("F24"), 23, trans::option::write_legendre("cached_legendre_coeffs-F24") | trans::option::flt(false) ); + trans::Trans trans_write_N24( Grid("N24"), 23, trans::option::write_legendre("cached_legendre_coeffs-N24") | trans::option::flt(false) ); + trans::Trans trans_write_O24( Grid("O24"), 23, trans::option::write_legendre("cached_legendre_coeffs-O24") | trans::option::flt(false) ); + + // Create trans that will read from file + trans::Trans trans_read_F24( Grid("F24"), 23, trans::option::read_legendre("cached_legendre_coeffs-F24") | trans::option::flt(false) ); + trans::Trans trans_read_N24( Grid("N24"), 23, trans::option::read_legendre("cached_legendre_coeffs-N24") | trans::option::flt(false) ); + trans::Trans trans_read_O24( Grid("O24"), 23, trans::option::read_legendre("cached_legendre_coeffs-O24") | trans::option::flt(false) ); +} #endif - p.set_flt(false); - trans::TransIFS trans( Grid("F400"), 159, p); + + +CASE( "test_distspec" ) +{ + trans::TransIFS trans( Grid("F80"), 159 ); Log::info() << "Trans initialized" << std::endl; std::vector rspecg; std::vector nfrom; diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index bc640f5f7..c599b85eb 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -127,7 +127,7 @@ CASE( "test_invtrans_ifsStyle" ) double *no_vorticity(nullptr), *no_divergence(nullptr); int nb_vordiv(0); int nb_scalar(nfld); - trans.invtrans( nb_scalar, init_sp.data(), nb_vordiv, no_vorticity, no_divergence, rgp.data(), trans::options::scalar_derivatives(true) ); + trans.invtrans( nb_scalar, init_sp.data(), nb_vordiv, no_vorticity, no_divergence, rgp.data(), trans::option::scalar_derivatives(true) ); std::vector nto(nfld,1); std::vector rgpg(3*nfld*trans.nb_gridpoints_global()); From 911b19e5dbd26ad367ed51460ddd91c090a2e566 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 17 Nov 2017 12:05:03 +0000 Subject: [PATCH 171/355] ATLAS-134 Caching for Trans with unit tests --- src/atlas/CMakeLists.txt | 13 +- src/atlas/functionspace/Spectral.cc | 2 +- src/atlas/functionspace/StructuredColumns.h | 6 - .../detail/partitioner/TransPartitioner.cc | 2 +- src/atlas/option/Options.cc | 99 ++++++++++ src/atlas/option/Options.h | 173 +++++++++++------- src/atlas/trans/Trans.cc | 12 +- src/atlas/trans/Trans.h | 75 ++++++-- src/atlas/trans/{detail => ifs}/TransIFS.cc | 35 +--- src/atlas/trans/{detail => ifs}/TransIFS.h | 65 +------ .../{detail => }/ifs/TransIFSNodeColumns.cc | 4 +- .../{detail => }/ifs/TransIFSNodeColumns.h | 4 +- .../ifs/TransIFSStructuredColumns.cc | 4 +- .../ifs/TransIFSStructuredColumns.h | 4 +- src/atlas_f/CMakeLists.txt | 2 +- src/tests/functionspace/test_functionspace.cc | 11 +- src/tests/trans/test_trans.cc | 63 ++++--- src/tests/trans/test_trans_invtrans_grad.cc | 15 +- 18 files changed, 346 insertions(+), 243 deletions(-) create mode 100644 src/atlas/option/Options.cc rename src/atlas/trans/{detail => ifs}/TransIFS.cc (97%) rename src/atlas/trans/{detail => ifs}/TransIFS.h (90%) rename src/atlas/trans/{detail => }/ifs/TransIFSNodeColumns.cc (93%) rename src/atlas/trans/{detail => }/ifs/TransIFSNodeColumns.h (95%) rename src/atlas/trans/{detail => }/ifs/TransIFSStructuredColumns.cc (93%) rename src/atlas/trans/{detail => }/ifs/TransIFSStructuredColumns.h (95%) diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index de3d8326a..f66b0ffa7 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -55,6 +55,7 @@ list( APPEND atlas_grid_srcs option.h option/Options.h +option/Options.cc projection.h @@ -322,12 +323,12 @@ trans/Trans.cc ) if( ATLAS_HAVE_TRANS ) list( APPEND atlas_numerics_srcs - trans/detail/TransIFS.h - trans/detail/TransIFS.cc - trans/detail/ifs/TransIFSNodeColumns.h - trans/detail/ifs/TransIFSNodeColumns.cc - trans/detail/ifs/TransIFSStructuredColumns.h - trans/detail/ifs/TransIFSStructuredColumns.cc + trans/ifs/TransIFS.h + trans/ifs/TransIFS.cc + trans/ifs/TransIFSNodeColumns.h + trans/ifs/TransIFSNodeColumns.cc + trans/ifs/TransIFSStructuredColumns.h + trans/ifs/TransIFSStructuredColumns.cc ) endif() diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index 94febfd30..d247c0478 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -23,7 +23,7 @@ #include "atlas/trans/Trans.h" #ifdef ATLAS_HAVE_TRANS -#include "atlas/trans/detail/TransIFS.h" +#include "atlas/trans/ifs/TransIFS.h" namespace { void trans_check(const int code, const char* msg, const eckit::CodeLocation& location) { if(code != TRANS_SUCCESS) { diff --git a/src/atlas/functionspace/StructuredColumns.h b/src/atlas/functionspace/StructuredColumns.h index e83ab19cb..f60b13904 100644 --- a/src/atlas/functionspace/StructuredColumns.h +++ b/src/atlas/functionspace/StructuredColumns.h @@ -35,12 +35,6 @@ namespace field { } } -namespace atlas { -namespace trans { - class TransIFS; -} -} - namespace atlas { namespace functionspace { diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index 0cab7784d..3009e4bc6 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -12,7 +12,7 @@ #include "atlas/grid/Grid.h" #include "atlas/grid/detail/partitioner/TransPartitioner.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" -#include "atlas/trans/detail/TransIFS.h" +#include "atlas/trans/ifs/TransIFS.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/array.h" #include "atlas/runtime/Trace.h" diff --git a/src/atlas/option/Options.cc b/src/atlas/option/Options.cc new file mode 100644 index 000000000..bed3c4a3c --- /dev/null +++ b/src/atlas/option/Options.cc @@ -0,0 +1,99 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/option/Options.h" + +// ---------------------------------------------------------------------------- + +namespace atlas { +namespace option { + +vorticity_divergence_fields::vorticity_divergence_fields(bool v) { set("vorticity_divergence_fields",v); } + +wind_EW_derivatives::wind_EW_derivatives(bool v) { set("wind_EW_derivatives",v); } + +scalar_derivatives::scalar_derivatives(bool v) { set("scalar_derivatives",v); } + +radius::radius(double _radius) +{ + set("radius",_radius); +} + +radius::radius(const std::string &key) +{ + if( key == "Earth" ) { + set("radius",util::Earth::radiusInMeters()); + } else { + NOTIMP; + } +} + +type::type(const std::string &_type) +{ + set("type",_type); +} + +halo::halo(size_t size) +{ + set("halo",size); +} + +datatype::datatype(array::DataType::kind_t kind) +{ + set("datatype",kind); +} + +datatype::datatype(const std::string &str ) +{ + set("datatype",array::DataType::str_to_kind(str)); +} + +datatype::datatype(array::DataType dtype) +{ + set("datatype",dtype.kind()); +} + +name::name(const std::string &_name) +{ + set("name",_name); +} + +global::global(size_t _owner) +{ + set("global",true); + set("owner",_owner); +} + +levels::levels(size_t _levels) +{ + set("levels",_levels); +} + +variables::variables(size_t _variables) +{ + set("variables",_variables); +} + +flt::flt(bool flt) { set("flt",flt); } + +static const std::map FFT_to_string = { {FFT992,"FFT992"},{FFTW,"FFTW"} }; +//static const std::map string_to_FFT = { {"FFT992",FFT992},{"FFTW",FFTW} }; + +fft::fft( FFT fft ) { set("fft",FFT_to_string.at(fft)); } +fft::fft( const std::string& fft ) { set("fft",fft); } +split_latitudes::split_latitudes(bool split_latitudes) { set("split_latitudes",split_latitudes); } +write_legendre::write_legendre( const eckit::PathName& filepath ) { set("write_legendre",filepath); } +read_legendre::read_legendre( const eckit::PathName& filepath ) { set("read_legendre",filepath); } + + +// ---------------------------------------------------------------------------- + +} // namespace option +} // namespace atlas diff --git a/src/atlas/option/Options.h b/src/atlas/option/Options.h index 01fd72f6f..b10d6797e 100644 --- a/src/atlas/option/Options.h +++ b/src/atlas/option/Options.h @@ -21,109 +21,140 @@ namespace option { // ---------------------------------------------------------------------------- -class type : public util::Config -{ +class type : public util::Config { public: - type( const std::string& _type ) - { - set("type",_type); - } + type( const std::string& ); }; -class global : public util::Config -{ +// ---------------------------------------------------------------------------- + +class global : public util::Config { public: - global(size_t _owner=0) - { - set("global",true); - set("owner",_owner); - } + global( size_t owner = 0 ); }; -class levels : public util::Config -{ +// ---------------------------------------------------------------------------- + +class levels : public util::Config { public: - levels(size_t _levels) - { - set("levels",_levels); - } + levels( size_t ); }; -class variables : public util::Config -{ +// ---------------------------------------------------------------------------- + +class variables : public util::Config { public: - variables(size_t _variables) - { - set("variables",_variables); - } + variables( size_t ); }; -class name : public util::Config -{ +// ---------------------------------------------------------------------------- + +class name : public util::Config { public: - name(const std::string& _name) - { - set("name",_name); - } + name( const std::string& ); }; +// ---------------------------------------------------------------------------- + template< typename T > -class datatypeT : public util::Config -{ +class datatypeT : public util::Config { +public: + datatypeT(); +}; + +// ---------------------------------------------------------------------------- + +class datatype : public util::Config { +public: + datatype( array::DataType::kind_t ); + datatype( const std::string& ); + datatype( array::DataType ); +}; + +// ---------------------------------------------------------------------------- + +class halo : public util::Config { +public: + halo(size_t size); +}; + +// ---------------------------------------------------------------------------- + +class radius : public util::Config { +public: + radius( double ); + radius( const std::string& = "Earth" ); +}; + +// ---------------------------------------------------------------------------- + +class scalar_derivatives : public util::Config { public: - datatypeT() - { - set("datatype",array::DataType::kind()); - } + scalar_derivatives( bool ); }; +// ---------------------------------------------------------------------------- -class datatype : public util::Config -{ +class wind_EW_derivatives : public util::Config { public: - datatype(array::DataType::kind_t kind) - { - set("datatype",kind); - } - datatype(const std::string& str) - { - set("datatype",array::DataType::str_to_kind(str)); - } - datatype(array::DataType dtype) - { - set("datatype",dtype.kind()); - } + wind_EW_derivatives( bool ); }; -class halo : public util::Config -{ +// ---------------------------------------------------------------------------- + +class vorticity_divergence_fields : public util::Config { public: - halo(size_t size) - { - set("halo",size); - } + vorticity_divergence_fields( bool ); }; -class radius : public util::Config -{ +// ---------------------------------------------------------------------------- + +class flt : public util::Config { public: - radius(double _radius) - { - set("radius",_radius); - } - radius(const std::string& key = "Earth") - { - if( key == "Earth" ) { - set("radius",util::Earth::radiusInMeters()); - } else { - NOTIMP; - } - } + flt( bool ); +}; +// ---------------------------------------------------------------------------- + +enum FFT { FFT992=1, FFTW=2 }; + +class fft : public util::Config { +public: + fft( FFT ); + fft( const std::string& ); }; +// ---------------------------------------------------------------------------- + +class split_latitudes : public util::Config { +public: + split_latitudes( bool ); +}; // ---------------------------------------------------------------------------- +class write_legendre : public util::Config { +public: + write_legendre( const eckit::PathName& ); +}; + +// ---------------------------------------------------------------------------- + +class read_legendre : public util::Config { +public: + read_legendre( const eckit::PathName& ); +}; + +// ---------------------------------------------------------------------------- +// Definitions +// ---------------------------------------------------------------------------- + +template +datatypeT::datatypeT() { + set("datatype",array::DataType::kind()); +} + + + } // namespace option } // namespace atlas diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index 71a5c8669..83284f969 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -19,8 +19,8 @@ #include "atlas/grid/Grid.h" #ifdef ATLAS_HAVE_TRANS -#include "atlas/trans/detail/ifs/TransIFSNodeColumns.h" -#include "atlas/trans/detail/ifs/TransIFSStructuredColumns.h" +#include "atlas/trans/ifs/TransIFSNodeColumns.h" +#include "atlas/trans/ifs/TransIFSStructuredColumns.h" #define TRANS_DEFAULT "ifs" #else #define TRANS_DEFAULT "local" @@ -136,7 +136,7 @@ Trans::Implementation *TransFactory::build( const FunctionSpace& gp, const Funct return (*j).second->make(gp,sp,config); } -Trans::Implementation *TransFactory::build( const TransCache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { +Trans::Implementation *TransFactory::build( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { pthread_once(&once, init); @@ -195,7 +195,7 @@ Trans::Implementation *TransFactory::build( const Grid& grid, int truncation, co return (*j).second->make(grid,truncation,config); } -Trans::Implementation *TransFactory::build( const TransCache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { +Trans::Implementation *TransFactory::build( const Cache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { pthread_once(&once, init); @@ -241,11 +241,11 @@ Trans::Trans( const Grid& grid, int truncation, const eckit::Configuration& conf impl_( TransFactory::build(grid,truncation,config) ) { } -Trans::Trans( const TransCache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) : +Trans::Trans( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) : impl_( TransFactory::build(cache,gp,sp,config) ) { } -Trans::Trans( const TransCache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) : +Trans::Trans( const Cache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) : impl_( TransFactory::build(cache,grid,truncation,config) ) { } diff --git a/src/atlas/trans/Trans.h b/src/atlas/trans/Trans.h index 3ef592741..f17517fc8 100644 --- a/src/atlas/trans/Trans.h +++ b/src/atlas/trans/Trans.h @@ -13,6 +13,10 @@ #include "eckit/config/Configuration.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" + +#include "eckit/io/Buffer.h" +#include "eckit/io/DataHandle.h" + #include "atlas/util/Config.h" //----------------------------------------------------------------------------- @@ -34,18 +38,59 @@ namespace trans { class TransCacheEntry { public: - virtual operator bool() const = 0; + operator bool() const { return size() != 0; } virtual size_t size() const = 0; virtual const void* data() const = 0; - virtual std::string hash() const = 0; }; -class TransCache { +class EmptyCacheEntry : public TransCacheEntry { +public: + virtual size_t size() const override { return 0; } + virtual const void* data() const override { return nullptr; } +}; + +class TransCacheFileEntry : public TransCacheEntry { + eckit::Buffer buffer_; public: - virtual const TransCacheEntry& legendre() const = 0; - virtual const TransCacheEntry& fft() const = 0; + TransCacheFileEntry( const eckit::PathName& path ) : + buffer_(path.size()) { + std::unique_ptr dh( path.fileHandle() ); + dh->openForRead(); + dh->read(buffer_.data(),buffer_.size()); + dh->close(); + } + virtual size_t size() const override { return buffer_.size(); } + virtual const void* data() const override { return buffer_.data(); } }; +class Cache { +public: + Cache() = default; + Cache( const Cache& other ) = default; +protected: + Cache( const std::shared_ptr& legendre ) : + legendre_(legendre) { + } + Cache( const std::shared_ptr& legendre, const std::shared_ptr& fft ) : + legendre_(legendre), + fft_(fft) { + } +public: + const TransCacheEntry& legendre() const { return *legendre_; } + const TransCacheEntry& fft() const { return *fft_; } +private: + std::shared_ptr legendre_{ new EmptyCacheEntry() }; + std::shared_ptr fft_{ new EmptyCacheEntry() } ; +}; + +class LegendreCache : public Cache { +public: + LegendreCache( const eckit::PathName& path ) : + Cache( std::shared_ptr( new TransCacheFileEntry( path ) ) ) { + } +}; + + class TransImpl : public eckit::Owned { public: @@ -54,6 +99,8 @@ class TransImpl : public eckit::Owned { virtual int truncation() const = 0; + virtual size_t spectralCoefficients() const = 0; + virtual const Grid& grid() const = 0; virtual void dirtrans( const Field& gpfield, @@ -137,6 +184,7 @@ class TransImpl : public eckit::Owned { */ virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], const eckit::Configuration& = util::NoConfig() ) const = 0; + }; // ------------------------------------------------------------------ @@ -153,8 +201,8 @@ class TransFactory { static TransImpl* build( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); static TransImpl* build( const Grid&, int truncation, const eckit::Configuration& = util::Config() ); - static TransImpl* build( const TransCache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); - static TransImpl* build( const TransCache&, const Grid&, int truncation, const eckit::Configuration& = util::Config() ); + static TransImpl* build( const Cache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); + static TransImpl* build( const Cache&, const Grid&, int truncation, const eckit::Configuration& = util::Config() ); /*! * \brief list all registered trans implementations @@ -168,8 +216,8 @@ class TransFactory { std::string name_; virtual TransImpl* make( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& ) { return nullptr; } virtual TransImpl* make( const Grid& gp, int truncation, const eckit::Configuration& ) { return nullptr; } - virtual TransImpl* make( const TransCache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& ) { return nullptr; } - virtual TransImpl* make( const TransCache&, const Grid& gp, int truncation, const eckit::Configuration& ) { return nullptr; } + virtual TransImpl* make( const Cache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& ) { return nullptr; } + virtual TransImpl* make( const Cache&, const Grid& gp, int truncation, const eckit::Configuration& ) { return nullptr; } protected: @@ -185,7 +233,7 @@ class TransBuilderFunctionSpace : public TransFactory { virtual TransImpl* make( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { return new T(gp,sp,config); } - virtual TransImpl* make( const TransCache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { + virtual TransImpl* make( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { return new T(cache,gp,sp,config); } public: @@ -197,7 +245,7 @@ class TransBuilderGrid : public TransFactory { virtual TransImpl* make( const Grid& grid, int truncation, const eckit::Configuration& config ) { return new T(grid,truncation,config); } - virtual TransImpl* make( const TransCache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { + virtual TransImpl* make( const Cache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { return new T(cache,grid,truncation,config); } public: @@ -225,14 +273,15 @@ class Trans { Trans( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); Trans( const Grid&, int truncation, const eckit::Configuration& = util::NoConfig() ); - Trans( const TransCache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); - Trans( const TransCache&, const Grid&, int truncation, const eckit::Configuration& = util::NoConfig() ); + Trans( const Cache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); + Trans( const Cache&, const Grid&, int truncation, const eckit::Configuration& = util::NoConfig() ); void hash(eckit::Hash&) const; const Implementation* get() const { return impl_.get(); } operator bool() const { return impl_.owners(); } int truncation() const; + size_t spectralCoefficients() const; const Grid& grid() const; void dirtrans( const Field& gpfield, diff --git a/src/atlas/trans/detail/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc similarity index 97% rename from src/atlas/trans/detail/TransIFS.cc rename to src/atlas/trans/ifs/TransIFS.cc index 16cfcdbf4..2a8cf653f 100644 --- a/src/atlas/trans/detail/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -8,7 +8,7 @@ * does it submit to any jurisdiction. */ -#include "atlas/trans/detail/TransIFS.h" +#include "atlas/trans/ifs/TransIFS.h" #include "eckit/parser/JSON.h" #include "atlas/array.h" @@ -58,8 +58,9 @@ class TransParameters { return config_.getBool("split_latitudes",true); } - FFT fft() const { - return static_cast( config_.getInt("fft",int(FFTW)) ); + int fft() const { + static const std::map string_to_FFT = { {"FFT992",TRANS_FFT992},{"FFTW",TRANS_FFTW} }; + return string_to_FFT.at( config_.getString("fft","FFTW") ); } bool flt() const { @@ -688,21 +689,10 @@ struct UnpackSpectral namespace atlas { namespace trans { -class EmptyCacheEntry : public TransCacheEntry { -public: - virtual operator bool() const { return false; } - virtual size_t size() const { return 0; } - virtual const void* data() const { return nullptr; } - virtual std::string hash() const { return "empty"; } -}; -class NoCache : public TransCache { - virtual TransCacheEntry& legendre() const override { static EmptyCacheEntry cache; return cache; } - virtual TransCacheEntry& fft() const override { static EmptyCacheEntry cache; return cache; } -}; -TransIFS::TransIFS( const TransCache& cache, const Grid& grid, const long truncation, const eckit::Configuration& config ) : +TransIFS::TransIFS( const Cache& cache, const Grid& grid, const long truncation, const eckit::Configuration& config ) : grid_(grid), cache_( cache.legendre().data() ), cachesize_( cache.legendre().size() ) { @@ -712,7 +702,7 @@ TransIFS::TransIFS( const TransCache& cache, const Grid& grid, const long trunca } TransIFS::TransIFS( const Grid& grid, const long truncation, const eckit::Configuration& config ) : - TransIFS(NoCache(),grid,truncation,config) { + TransIFS( Cache(), grid, truncation, config ) { ASSERT( grid.domain().global() ); ASSERT( not grid.projection() ); ctor( grid, truncation, config ); @@ -826,11 +816,6 @@ void TransIFS::ctor_lonlat(const long nlon, const long nlat, long truncation, co } -namespace option{ -const std::map fft::to_str = { {FFT992,"FFT992"},{FFTW,"FFTW"} }; -const std::map fft::to_enum = { {"FFT992",FFT992},{"FFTW",FFTW} }; -} - // -------------------------------------------------------------------------------------------- @@ -1536,7 +1521,7 @@ int atlas__Trans__nspec2 (const TransIFS* This) { ATLAS_ERROR_HANDLING( ASSERT( This ); - return This->nb_spectral_coefficients(); + return This->trans()->nspec2; ); return 0; } @@ -1545,7 +1530,7 @@ int atlas__Trans__nspec2g (const TransIFS* This) { ATLAS_ERROR_HANDLING( ASSERT( This ); - return This->nb_spectral_coefficients_global(); + return This->trans()->nspec2g; ); return 0; } @@ -1554,7 +1539,7 @@ int atlas__Trans__ngptot (const TransIFS* This) { ATLAS_ERROR_HANDLING( ASSERT( This ); - return This->nb_gridpoints(); + return This->trans()->ngptot; ); return 0; } @@ -1563,7 +1548,7 @@ int atlas__Trans__ngptotg (const TransIFS* This) { ATLAS_ERROR_HANDLING( ASSERT( This ); - return This->nb_gridpoints_global(); + return This->trans()->ngptotg; ); return 0; } diff --git a/src/atlas/trans/detail/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h similarity index 90% rename from src/atlas/trans/detail/TransIFS.h rename to src/atlas/trans/ifs/TransIFS.h index bc05a1fa8..3e7a08c64 100644 --- a/src/atlas/trans/detail/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -67,66 +67,8 @@ namespace partitioner { namespace atlas { namespace trans { -////----------------------------------------------------------------------------- -enum FFT { FFT992=TRANS_FFT992, FFTW=TRANS_FFTW }; - -namespace option { - -class scalar_derivatives : public util::Config { -public: - scalar_derivatives( bool v ) { set("scalar_derivatives",v); } -}; - -class wind_EW_derivatives : public util::Config { -public: - wind_EW_derivatives( bool v ) { set("wind_EW_derivatives",v); } -}; - -class vorticity_divergence_fields : public util::Config { -public: - vorticity_divergence_fields( bool v ) { set("vorticity_divergence_fields",v); } -}; - -class flt : public util::Config { -public: - flt(bool); -}; -inline flt::flt(bool flt) { set("flt",flt); } - -class fft : public util::Config { -public: - fft( FFT ); - fft( const std::string& ); -private: - static const std::map to_str; - static const std::map to_enum; -}; -inline fft::fft( FFT fft ) { set("fft",fft); } -inline fft::fft( const std::string& fft ) { set("fft",to_enum.at(fft)); } - -class split_latitudes : public util::Config { -public: - split_latitudes(bool); -}; -inline split_latitudes::split_latitudes(bool split_latitudes) { set("split_latitudes",split_latitudes); } - -class write_legendre : public util::Config { -public: - write_legendre( const eckit::PathName& ); -}; -inline write_legendre::write_legendre( const eckit::PathName& filepath ) { set("write_legendre",filepath); } - -class read_legendre : public util::Config { -public: - read_legendre( const eckit::PathName& ); -}; -inline read_legendre::read_legendre( const eckit::PathName& filepath ) { set("read_legendre",filepath); } - -} - //----------------------------------------------------------------------------- - class TransIFS : public trans::TransImpl { private: typedef struct ::Trans_t Trans_t; @@ -134,17 +76,14 @@ class TransIFS : public trans::TransImpl { public: TransIFS( const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); - TransIFS( const TransCache&, const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); + TransIFS( const Cache&, const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); virtual ~TransIFS(); operator ::Trans_t*() const { return trans(); } ::Trans_t* trans() const { return trans_.get(); } virtual int truncation() const { return std::max(0,trans_->nsmax); } - size_t nb_spectral_coefficients() const { return trans_->nspec2; } - size_t nb_spectral_coefficients_global() const { return trans_->nspec2g; } - size_t nb_gridpoints() const { return trans_->ngptot; } - size_t nb_gridpoints_global() const { return trans_->ngptotg; } + virtual size_t spectralCoefficients() const { return trans_->nspec2g; } virtual const Grid& grid() const { return grid_; } diff --git a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc b/src/atlas/trans/ifs/TransIFSNodeColumns.cc similarity index 93% rename from src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc rename to src/atlas/trans/ifs/TransIFSNodeColumns.cc index 20a48ed00..3390b9a95 100644 --- a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.cc +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.cc @@ -8,7 +8,7 @@ * does it submit to any jurisdiction. */ -#include "atlas/trans/detail/ifs/TransIFSNodeColumns.h" +#include "atlas/trans/ifs/TransIFSNodeColumns.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/Spectral.h" @@ -24,7 +24,7 @@ TransIFSNodeColumns::TransIFSNodeColumns( } TransIFSNodeColumns::TransIFSNodeColumns( - const TransCache& cache, + const Cache& cache, const functionspace::NodeColumns& gp, const functionspace::Spectral& sp, const eckit::Configuration& config ) : diff --git a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.h b/src/atlas/trans/ifs/TransIFSNodeColumns.h similarity index 95% rename from src/atlas/trans/detail/ifs/TransIFSNodeColumns.h rename to src/atlas/trans/ifs/TransIFSNodeColumns.h index 491c41ef0..098c269e0 100644 --- a/src/atlas/trans/detail/ifs/TransIFSNodeColumns.h +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.h @@ -10,7 +10,7 @@ #pragma once -#include "atlas/trans/detail/TransIFS.h" +#include "atlas/trans/ifs/TransIFS.h" //----------------------------------------------------------------------------- // Forward declarations @@ -38,7 +38,7 @@ class TransIFSNodeColumns : public trans::TransIFS { const eckit::Configuration& = util::Config() ); TransIFSNodeColumns( - const TransCache&, + const Cache&, const functionspace::NodeColumns&, const functionspace::Spectral&, const eckit::Configuration& = util::Config() ); diff --git a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc similarity index 93% rename from src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc rename to src/atlas/trans/ifs/TransIFSStructuredColumns.cc index 854f5de35..866513672 100644 --- a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.cc +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc @@ -8,7 +8,7 @@ * does it submit to any jurisdiction. */ -#include "atlas/trans/detail/ifs/TransIFSStructuredColumns.h" +#include "atlas/trans/ifs/TransIFSStructuredColumns.h" #include "atlas/functionspace/StructuredColumns.h" #include "atlas/functionspace/Spectral.h" @@ -24,7 +24,7 @@ TransIFSStructuredColumns::TransIFSStructuredColumns( } TransIFSStructuredColumns::TransIFSStructuredColumns( - const TransCache& cache, + const Cache& cache, const functionspace::StructuredColumns& gp, const functionspace::Spectral& sp, const eckit::Configuration& config ) : diff --git a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h b/src/atlas/trans/ifs/TransIFSStructuredColumns.h similarity index 95% rename from src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h rename to src/atlas/trans/ifs/TransIFSStructuredColumns.h index 619a1dd0d..045c16096 100644 --- a/src/atlas/trans/detail/ifs/TransIFSStructuredColumns.h +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.h @@ -10,7 +10,7 @@ #pragma once -#include "atlas/trans/detail/TransIFS.h" +#include "atlas/trans/ifs/TransIFS.h" //----------------------------------------------------------------------------- // Forward declarations @@ -38,7 +38,7 @@ class TransIFSStructuredColumns : public trans::TransIFS { const eckit::Configuration& = util::Config() ); TransIFSStructuredColumns( - const TransCache&, + const Cache&, const functionspace::StructuredColumns&, const functionspace::Spectral&, const eckit::Configuration& = util::Config() ); diff --git a/src/atlas_f/CMakeLists.txt b/src/atlas_f/CMakeLists.txt index 086fad9bb..55289f108 100644 --- a/src/atlas_f/CMakeLists.txt +++ b/src/atlas_f/CMakeLists.txt @@ -153,7 +153,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/detail/TransIFS.h +generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/trans/ifs/TransIFS.h MODULE atlas_trans_c_binding OUTPUT trans_c_binding.f90 ) generate_fortran_bindings(FORTRAN_BINDINGS ../atlas/util/Metadata.h) diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index 0bddf21d3..ce877e592 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -24,9 +24,7 @@ #include "atlas/field/Field.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/trans/Trans.h" -#ifdef ATLAS_HAVE_TRANS -#include "atlas/trans/detail/TransIFS.h" -#endif +#include "atlas/trans/ifs/TransIFS.h" using namespace eckit; @@ -531,12 +529,11 @@ CASE( "test_SpectralFunctionSpace" ) CASE( "test_SpectralFunctionSpace_trans_dist" ) { - trans::TransIFS trans(Grid("F80"),159); + trans::Trans trans(Grid("F80"),159); size_t nb_levels(10); - size_t nspec2 = trans.nb_spectral_coefficients(); - Spectral spectral_fs( trans ); + size_t nspec2 = spectral_fs.nb_spectral_coefficients(); Field surface_scalar_field = spectral_fs.createField( option::name("scalar") ); @@ -620,7 +617,7 @@ CASE( "test_SpectralFunctionSpace_trans_global" ) } CASE( "test_SpectralFunctionSpace_norm" ) { - trans::TransIFS trans(Grid("F80"),159); + trans::Trans trans(Grid("F80"),159); size_t nb_levels(10); Spectral spectral_fs( trans ); diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index ebbcecbf5..3266f314f 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -31,11 +31,13 @@ #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" +#include "eckit/io/DataHandle.h" +#include "eckit/filesystem/PathName.h" #ifdef ATLAS_HAVE_TRANS -#include "atlas/trans/detail/TransIFS.h" -#include "atlas/trans/detail/ifs/TransIFSNodeColumns.h" -#include "atlas/trans/detail/ifs/TransIFSStructuredColumns.h" +#include "atlas/trans/ifs/TransIFS.h" +#include "atlas/trans/ifs/TransIFSNodeColumns.h" +#include "atlas/trans/ifs/TransIFSStructuredColumns.h" #endif using namespace eckit; @@ -62,14 +64,14 @@ struct AtlasTransEnvironment : public AtlasTestEnvironment { //----------------------------------------------------------------------------- -void read_rspecg(trans::TransIFS& trans, std::vector& rspecg, std::vector& nfrom, int &nfld ) +void read_rspecg(trans::TransImpl& trans, std::vector& rspecg, std::vector& nfrom, int &nfld ) { Log::info() << "read_rspecg ...\n"; nfld = 2; if( parallel::mpi::comm().rank() == 0 ) { - rspecg.resize(nfld*trans.nb_spectral_coefficients_global()); - for( int i=0; ingptotg == g.size() ); + EXPECT( t->ngptot == npts[parallel::mpi::comm().rank()] ); EXPECT( t->ngptotmx == *std::max_element(npts.begin(),npts.end()) ); // array::LocalView n_regions ( trans.n_regions() ) ; @@ -159,30 +161,36 @@ CASE( "test_trans_distribution_matches_atlas" ) CASE( "test_trans_options" ) { util::Config opts ( - trans::option::fft(trans::FFTW) | - trans::option::split_latitudes(false) | - trans::option::read_legendre("readfile") ); + option::fft("FFTW") | + option::split_latitudes(false) | + option::read_legendre("readfile") ); Log::info() << "trans_opts = " << opts << std::endl; } #ifdef TRANS_HAVE_IO CASE( "test_write_read_cache" ) { - util::Config write_legendre; - util::Config read_legendre; + Log::info() << "test_write_read_cache" << std::endl; + using namespace trans; if( parallel::mpi::comm().size() == 1 ) { - write_legendre = trans::option::write_legendre("cached_legendre_coeffs"); - read_legendre = trans::option::read_legendre("cached_legendre_coeffs"); + // Create trans that will write file + Trans trans_write_F24( Grid("F24"), 23, option::write_legendre("cached_legendre_coeffs-F24") | option::flt(false) ); + Trans trans_write_N24( Grid("N24"), 23, option::write_legendre("cached_legendre_coeffs-N24") | option::flt(false) ); + Trans trans_write_O24( Grid("O24"), 23, option::write_legendre("cached_legendre_coeffs-O24") | option::flt(false) ); + + // Create trans that will read from file + Trans trans_read_F24( Grid("F24"), 23, option::read_legendre("cached_legendre_coeffs-F24") | option::flt(false) ); + Trans trans_read_N24( Grid("N24"), 23, option::read_legendre("cached_legendre_coeffs-N24") | option::flt(false) ); + Trans trans_read_O24( Grid("O24"), 23, option::read_legendre("cached_legendre_coeffs-O24") | option::flt(false) ); + + LegendreCache legendre_cache_F24( "cached_legendre_coeffs-F24" ); + LegendreCache legendre_cache_N24( "cached_legendre_coeffs-N24" ); + LegendreCache legendre_cache_O24( "cached_legendre_coeffs-O24" ); + + Trans trans_cache_F24( legendre_cache_F24, Grid("F24"), 23, option::flt(false) ); + Trans trans_cache_N24( legendre_cache_N24, Grid("N24"), 23, option::flt(false) ); + Trans trans_cache_O24( legendre_cache_O24, Grid("O24"), 23, option::flt(false) ); } - // Create trans that will write file - trans::Trans trans_write_F24( Grid("F24"), 23, trans::option::write_legendre("cached_legendre_coeffs-F24") | trans::option::flt(false) ); - trans::Trans trans_write_N24( Grid("N24"), 23, trans::option::write_legendre("cached_legendre_coeffs-N24") | trans::option::flt(false) ); - trans::Trans trans_write_O24( Grid("O24"), 23, trans::option::write_legendre("cached_legendre_coeffs-O24") | trans::option::flt(false) ); - - // Create trans that will read from file - trans::Trans trans_read_F24( Grid("F24"), 23, trans::option::read_legendre("cached_legendre_coeffs-F24") | trans::option::flt(false) ); - trans::Trans trans_read_N24( Grid("N24"), 23, trans::option::read_legendre("cached_legendre_coeffs-N24") | trans::option::flt(false) ); - trans::Trans trans_read_O24( Grid("O24"), 23, trans::option::read_legendre("cached_legendre_coeffs-O24") | trans::option::flt(false) ); } #endif @@ -197,11 +205,10 @@ CASE( "test_distspec" ) Log::info() << "Read rspecg" << std::endl; read_rspecg(trans,rspecg,nfrom,nfld); - - std::vector rspec(nfld*trans.nb_spectral_coefficients()); + std::vector rspec(nfld*trans.trans()->nspec2); std::vector nto(nfld,1); - std::vector rgp(nfld*trans.nb_gridpoints()); - std::vector rgpg(nfld*trans.nb_gridpoints_global()); + std::vector rgp(nfld*trans.trans()->ngptot); + std::vector rgpg(nfld*trans.grid().size()); std::vector specnorms(nfld,0); trans.distspec( nfld, nfrom.data(), rspecg.data(), rspec.data() ); diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index c599b85eb..6f355b3ba 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -27,12 +27,13 @@ #include "atlas/trans/Trans.h" #include "atlas/util/Earth.h" #include "atlas/util/CoordinateEnums.h" +#include "atlas/option.h" #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" #ifdef ATLAS_HAVE_TRANS -#include "atlas/trans/detail/TransIFS.h" +#include "atlas/trans/ifs/TransIFS.h" #endif using namespace eckit::testing; @@ -112,9 +113,9 @@ CASE( "test_invtrans_ifsStyle" ) std::vector rspecg; int nfld = 1; - std::vector init_gpg(trans.nb_gridpoints_global()); - std::vector init_gp (trans.nb_gridpoints ()); - std::vector init_sp (trans.nb_spectral_coefficients()); + std::vector init_gpg(trans.grid().size()); + std::vector init_gp (trans.trans()->ngptot); + std::vector init_sp (trans.trans()->nspec2); std::vector nfrom(nfld,1); if( parallel::mpi::comm().rank()==0) { double beta = M_PI*0.5; @@ -123,14 +124,14 @@ CASE( "test_invtrans_ifsStyle" ) trans.distgrid(nfld,nfrom.data(),init_gpg.data(),init_gp.data()); trans.dirtrans(nfld,init_gp.data(),init_sp.data()); - std::vector rgp(3*nfld*trans.nb_gridpoints()); + std::vector rgp(3*nfld*trans.trans()->ngptot); double *no_vorticity(nullptr), *no_divergence(nullptr); int nb_vordiv(0); int nb_scalar(nfld); - trans.invtrans( nb_scalar, init_sp.data(), nb_vordiv, no_vorticity, no_divergence, rgp.data(), trans::option::scalar_derivatives(true) ); + trans.invtrans( nb_scalar, init_sp.data(), nb_vordiv, no_vorticity, no_divergence, rgp.data(), option::scalar_derivatives(true) ); std::vector nto(nfld,1); - std::vector rgpg(3*nfld*trans.nb_gridpoints_global()); + std::vector rgpg(3*nfld*trans.grid().size()); trans.gathgrid( nfld, nto.data(), rgp.data(), rgpg.data() ); From 33f635405ca65011a6c30a371a114a1e026d7412 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 13 Nov 2017 11:08:32 +0000 Subject: [PATCH 172/355] UnstructuredGrid with initializer list constructor --- doc/CMakeLists.txt | 9 +++++---- .../core-functionalities/fields/CMakeLists.txt | 4 ++-- .../fields/fields-on-grid.cc | 6 ++++-- .../core-functionalities/fields/fields.cc | 5 +++-- .../functionspace/CMakeLists.txt | 4 ++-- .../global-grids/Structured/CMakeLists.txt | 4 ++-- .../global-grids/Unstructured/CMakeLists.txt | 2 +- .../Unstructured/global-grids-Unstructured.cc | 4 +--- .../core-functionalities/meshes/CMakeLists.txt | 6 +++--- .../installation/CMakeLists.txt | 12 ++++++------ src/atlas/grid/Grid.cc | 11 ++++++++++- src/atlas/grid/Grid.h | 2 ++ src/atlas/grid/detail/grid/Unstructured.cc | 17 ++++++++++++++++- src/atlas/grid/detail/grid/Unstructured.h | 18 ++++++++++++------ src/atlas/mesh/actions/BuildConvexHull3D.cc | 2 +- 15 files changed, 70 insertions(+), 36 deletions(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index d34a5a885..4e1d236b5 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,8 +1,9 @@ add_subdirectory(user-guide) -list( APPEND DOC_CODE_TARGETS +list( APPEND DOC_CODE_TARGETS atlas_c-hello-world atlas_c-global-grids-Structured + atlas_c-global-grids-Unstructured atlas_c-meshes-Structured atlas_c-fields atlas_c-fields-on-grid @@ -10,7 +11,7 @@ list( APPEND DOC_CODE_TARGETS atlas_c-StructuredColumns ) if( ATLAS_HAVE_FORTRAN ) - list( APPEND DOC_CODE_TARGETS + list( APPEND DOC_CODE_TARGETS atlas_f-hello-world atlas_f-global-grids-Structured atlas_f-meshes-Structured @@ -23,7 +24,7 @@ endif() add_custom_target(atlas_doc_code) add_dependencies (atlas_doc_code ${DOC_CODE_TARGETS} ) - + add_custom_target(atlas_doc_pdf) add_dependencies (atlas_doc_pdf atlas-user-guide-pdf ) @@ -36,7 +37,7 @@ add_custom_target(atlas_doc) add_dependencies (atlas_doc atlas_doc_code atlas_doc_pdf ) - + if( PROJECT_NAME STREQUAL CMAKE_PROJECT_NAME ) add_custom_target(doc) diff --git a/doc/user-guide/core-functionalities/fields/CMakeLists.txt b/doc/user-guide/core-functionalities/fields/CMakeLists.txt index 736111274..95080a48a 100644 --- a/doc/user-guide/core-functionalities/fields/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/fields/CMakeLists.txt @@ -12,7 +12,7 @@ ecbuild_add_executable( set_target_properties(atlas_c-fields atlas_c-fields-on-grid - PROPERTIES EXCLUDE_FROM_ALL true ) + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) if( ATLAS_HAVE_FORTRAN ) @@ -30,6 +30,6 @@ ecbuild_add_executable( set_target_properties(atlas_f-fields atlas_f-fields-on-grid - PROPERTIES EXCLUDE_FROM_ALL true ) + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) endif() diff --git a/doc/user-guide/core-functionalities/fields/fields-on-grid.cc b/doc/user-guide/core-functionalities/fields/fields-on-grid.cc index 9ec18fa6c..64f65562d 100644 --- a/doc/user-guide/core-functionalities/fields/fields-on-grid.cc +++ b/doc/user-guide/core-functionalities/fields/fields-on-grid.cc @@ -1,7 +1,9 @@ +#include "atlas/array.h" +#include "atlas/field/Field.h" +#include "atlas/grid/Grid.h" #include "atlas/library/Library.h" #include "atlas/runtime/Log.h" -#include "atlas/grid/Grid.h" -#include "atlas/field/Field.h" + using atlas::Log; using atlas::array::make_shape; diff --git a/doc/user-guide/core-functionalities/fields/fields.cc b/doc/user-guide/core-functionalities/fields/fields.cc index 4e9e4114f..601f4ce65 100644 --- a/doc/user-guide/core-functionalities/fields/fields.cc +++ b/doc/user-guide/core-functionalities/fields/fields.cc @@ -1,7 +1,8 @@ -#include "atlas/library/Library.h" -#include "atlas/runtime/Log.h" +#include "atlas/array.h" #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" +#include "atlas/library/Library.h" +#include "atlas/runtime/Log.h" #include "atlas/util/Metadata.h" using atlas::Log; diff --git a/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt b/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt index 25bad1ed4..397b0f3be 100644 --- a/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt @@ -12,7 +12,7 @@ ecbuild_add_executable( set_target_properties(atlas_c-NodeColumns atlas_c-StructuredColumns - PROPERTIES EXCLUDE_FROM_ALL true ) + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) if( ATLAS_HAVE_FORTRAN ) @@ -23,6 +23,6 @@ ecbuild_add_executable( NOINSTALL ) set_target_properties(atlas_f-NodeColumns - PROPERTIES EXCLUDE_FROM_ALL true ) + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) endif() diff --git a/doc/user-guide/core-functionalities/global-grids/Structured/CMakeLists.txt b/doc/user-guide/core-functionalities/global-grids/Structured/CMakeLists.txt index f2bd92925..a89cbf329 100644 --- a/doc/user-guide/core-functionalities/global-grids/Structured/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/global-grids/Structured/CMakeLists.txt @@ -5,7 +5,7 @@ ecbuild_add_executable( NOINSTALL ) set_target_properties(atlas_c-global-grids-Structured - PROPERTIES EXCLUDE_FROM_ALL true ) + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) if( ATLAS_HAVE_FORTRAN ) @@ -16,6 +16,6 @@ ecbuild_add_executable( NOINSTALL ) set_target_properties(atlas_f-global-grids-Structured - PROPERTIES EXCLUDE_FROM_ALL true ) + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) endif() diff --git a/doc/user-guide/core-functionalities/global-grids/Unstructured/CMakeLists.txt b/doc/user-guide/core-functionalities/global-grids/Unstructured/CMakeLists.txt index 2b0c18052..32da5319a 100644 --- a/doc/user-guide/core-functionalities/global-grids/Unstructured/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/global-grids/Unstructured/CMakeLists.txt @@ -5,5 +5,5 @@ ecbuild_add_executable( NOINSTALL ) set_target_properties(atlas_c-global-grids-Unstructured - PROPERTIES EXCLUDE_FROM_ALL true ) + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) diff --git a/doc/user-guide/core-functionalities/global-grids/Unstructured/global-grids-Unstructured.cc b/doc/user-guide/core-functionalities/global-grids/Unstructured/global-grids-Unstructured.cc index 53b8cf665..cc54397f9 100644 --- a/doc/user-guide/core-functionalities/global-grids/Unstructured/global-grids-Unstructured.cc +++ b/doc/user-guide/core-functionalities/global-grids/Unstructured/global-grids-Unstructured.cc @@ -1,5 +1,3 @@ -#include -#include #include "atlas/library/Library.h" #include "atlas/grid.h" #include "atlas/meshgenerator.h" @@ -16,7 +14,7 @@ int main(int argc, char *argv[]) { atlas::Library::instance().initialise(argc, argv); - Grid grid = UnstructuredGrid( new std::vector{ + Grid grid = UnstructuredGrid( { {180,0}, {90,0}, {-90,0}, diff --git a/doc/user-guide/core-functionalities/meshes/CMakeLists.txt b/doc/user-guide/core-functionalities/meshes/CMakeLists.txt index 8bbdbe8bd..1a68b97de 100644 --- a/doc/user-guide/core-functionalities/meshes/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/meshes/CMakeLists.txt @@ -4,8 +4,8 @@ ecbuild_add_executable( LIBS atlas NOINSTALL ) -set_target_properties(atlas_c-meshes-Structured - PROPERTIES EXCLUDE_FROM_ALL true ) +set_target_properties(atlas_c-meshes-Structured + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) if( ATLAS_HAVE_FORTRAN ) @@ -16,6 +16,6 @@ ecbuild_add_executable( NOINSTALL ) set_target_properties(atlas_f-meshes-Structured - PROPERTIES EXCLUDE_FROM_ALL true ) + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) endif() diff --git a/doc/user-guide/getting-started/installation/CMakeLists.txt b/doc/user-guide/getting-started/installation/CMakeLists.txt index acd4e7179..8ede27aea 100644 --- a/doc/user-guide/getting-started/installation/CMakeLists.txt +++ b/doc/user-guide/getting-started/installation/CMakeLists.txt @@ -1,18 +1,18 @@ ecbuild_add_executable( TARGET atlas_c-hello-world SOURCES hello-world.cc - LIBS atlas + LIBS atlas NOINSTALL ) -set_target_properties( atlas_c-hello-world - PROPERTIES EXCLUDE_FROM_ALL true ) +set_target_properties( atlas_c-hello-world + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) if( ATLAS_HAVE_FORTRAN ) ecbuild_add_executable( TARGET atlas_f-hello-world SOURCES hello-world.F90 - LIBS atlas_f + LIBS atlas_f NOINSTALL ) - set_target_properties( atlas_f-hello-world - PROPERTIES EXCLUDE_FROM_ALL true ) + set_target_properties( atlas_f-hello-world + PROPERTIES EXCLUDE_FROM_ALL ${ENABLE_TESTS} ) endif() diff --git a/src/atlas/grid/Grid.cc b/src/atlas/grid/Grid.cc index e00fc9d90..a160724f4 100644 --- a/src/atlas/grid/Grid.cc +++ b/src/atlas/grid/Grid.cc @@ -39,7 +39,7 @@ Grid::Grid( const Grid::Implementation *grid ): Grid::Grid( const std::string& shortname, const Domain& domain ) { grid_ = Grid::Implementation::create( - shortname, + shortname, Config("domain", domain.spec()) ); } @@ -79,6 +79,15 @@ UnstructuredGrid::UnstructuredGrid( std::vector* xy ): grid_( unstructured_grid(get()) ) { } +UnstructuredGrid::UnstructuredGrid( std::vector&& xy ): + Grid( new UnstructuredGrid::grid_t( std::forward< std::vector >(xy) ) ), + grid_( unstructured_grid(get()) ) { +} + +UnstructuredGrid::UnstructuredGrid( std::initializer_list xy ): + Grid( new UnstructuredGrid::grid_t( xy ) ), + grid_( unstructured_grid(get()) ) { +} inline const StructuredGrid::grid_t* structured_grid( const Grid::Implementation *grid ) { return dynamic_cast(grid); diff --git a/src/atlas/grid/Grid.h b/src/atlas/grid/Grid.h index 45685ebac..9b1aa0808 100644 --- a/src/atlas/grid/Grid.h +++ b/src/atlas/grid/Grid.h @@ -147,6 +147,8 @@ class UnstructuredGrid: public Grid { UnstructuredGrid( const Config& ); UnstructuredGrid( const Grid::Implementation* ); UnstructuredGrid( std::vector* ); // takes ownership + UnstructuredGrid( std::vector&& ); // move constructor + UnstructuredGrid( std::initializer_list ); operator bool() const { return valid(); diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index ec1d2cbfe..59f19abca 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -59,11 +59,26 @@ Unstructured::Unstructured(const util::Config& p) : Unstructured::Unstructured(std::vector* pts) : Grid(), points_(pts) { + util::Config config_domain; + config_domain.set("type","global"); + domain_ = Domain(config_domain); +} + +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); +} +Unstructured::Unstructured( std::initializer_list< PointXY > initializer_list ) : + Grid(), + points_( new std::vector( initializer_list ) ) { util::Config config_domain; config_domain.set("type","global"); domain_ = Domain(config_domain); - } +} Unstructured::~Unstructured() { diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index 6df416cee..ee5fc06c7 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -18,11 +18,11 @@ #include #include -#include "eckit/memory/ScopedPtr.h" +#include #include "eckit/utils/Hash.h" #include "atlas/grid/detail/grid/Grid.h" -namespace atlas { +namespace atlas { class Mesh; } @@ -73,7 +73,7 @@ class Unstructured : public Grid { const Unstructured& grid_; size_t n_; }; - + class IteratorLonLat: public Grid::IteratorLonLat { public: IteratorLonLat(const Unstructured& grid, bool begin=true): @@ -121,12 +121,18 @@ class Unstructured : public Grid { /// Constructor taking a list of parameters Unstructured( const Config& ); - /// Constructor taking a list of points + /// Constructor taking a list of points (takes ownership) Unstructured( std::vector< PointXY >* pts ); + /// Constructor taking a list of points (takes ownership) + Unstructured( std::vector< PointXY >&& pts ); + /// Constructor taking a mesh Unstructured( const Mesh& m ); + /// Constructor from initializer list + Unstructured( std::initializer_list< PointXY > ); + virtual ~Unstructured(); virtual size_t size() const; @@ -153,13 +159,13 @@ class Unstructured : public Grid { protected: /// Storage of coordinate points - eckit::ScopedPtr< std::vector< PointXY > > points_; + std::unique_ptr< std::vector< PointXY > > points_; /// Cache for the shortName mutable std::string shortName_; /// Cache for the spec since may be quite heavy to compute - mutable eckit::ScopedPtr cached_spec_; + mutable std::unique_ptr cached_spec_; }; diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.cc b/src/atlas/mesh/actions/BuildConvexHull3D.cc index 95ed76133..7fb76c237 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.cc +++ b/src/atlas/mesh/actions/BuildConvexHull3D.cc @@ -112,7 +112,7 @@ static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, Poin idx_t idx[3]; Polyhedron_3::Vertex_const_handle vts[3]; - std::cout << "Inserting triags (" << eckit::BigNum(nb_triags) << ")" << std::endl; + Log::debug() << "Inserting triags (" << eckit::BigNum(nb_triags) << ")" << std::endl; size_t tidx = 0; for( Polyhedron_3::Facet_const_iterator f = poly.facets_begin(); f != poly.facets_end(); ++f ) From c89a09c69558ff4652cde966776fdfaa06d16d84 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Thu, 2 Nov 2017 18:22:14 +0000 Subject: [PATCH 173/355] ATLAS-135 first version of local spectral transform. Currently implemented in test_transgeneral.cc --- src/tests/trans/CMakeLists.txt | 7 + src/tests/trans/test_transgeneral.cc | 352 +++++++++++++++++++++++++++ 2 files changed, 359 insertions(+) create mode 100644 src/tests/trans/test_transgeneral.cc diff --git a/src/tests/trans/CMakeLists.txt b/src/tests/trans/CMakeLists.txt index a969a18f4..b6780d358 100644 --- a/src/tests/trans/CMakeLists.txt +++ b/src/tests/trans/CMakeLists.txt @@ -44,3 +44,10 @@ ecbuild_add_test( TARGET atlas_test_trans_invtrans_grad CONDITION ATLAS_HAVE_TRANS LIBS atlas ) + +ecbuild_add_test( TARGET atlas_test_transgeneral + SOURCES test_transgeneral.cc + CONDITION ATLAS_HAVE_TRANS + LIBS atlas +) + diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc new file mode 100644 index 000000000..98449a2fb --- /dev/null +++ b/src/tests/trans/test_transgeneral.cc @@ -0,0 +1,352 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/library/Library.h" +#include "atlas/field/FieldSet.h" +#include "atlas/functionspace/NodeColumns.h" +#include "atlas/functionspace/Spectral.h" +#include "atlas/functionspace/StructuredColumns.h" +#include "atlas/grid/Distribution.h" +#include "atlas/grid/Partitioner.h" +#include "atlas/grid.h" +#include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" +#include "atlas/grid/detail/partitioner/TransPartitioner.h" +#include "atlas/meshgenerator/StructuredMeshGenerator.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" +#include "atlas/output/Gmsh.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/trans/Trans.h" +#include "atlas/array/MakeView.h" +#include "transi/trans.h" + +#include "tests/AtlasTestEnvironment.h" +#include "eckit/testing/Test.h" + +#include + +using namespace eckit; +using namespace eckit::testing; + +using atlas::array::Array; +using atlas::array::ArrayView; +using atlas::array::make_view; + +namespace atlas { +namespace test { + +//----------------------------------------------------------------------------- + +struct AtlasTransEnvironment : public AtlasTestEnvironment { + AtlasTransEnvironment(int argc, char * argv[]) : AtlasTestEnvironment(argc, argv) { + if( parallel::mpi::comm().size() == 1 ) + trans_use_mpi(false); + trans_init(); + } + + ~AtlasTransEnvironment() { + trans_finalize(); + } +}; + +//----------------------------------------------------------------------------- +// Routine to compute the Legendre polynomials in serial according to Belousov +// (using correction by Swarztrauber) +// +// Reference: +// S.L. Belousov, Tables of normalized associated Legendre Polynomials, Pergamon Press (1962) +// P.N. Swarztrauber, On computing the points and weights for Gauss-Legendre quadrature, +// SIAM J. Sci. Comput. Vol. 24 (3) pp. 945-954 (2002) +// +// Author of Fortran version: +// Mats Hamrud, Philippe Courtier, Nils Wedi *ECMWF* +// +// Ported to C++ by: +// Andreas Mueller *ECMWF* +// +void compute_legendre( + const size_t knsmax, // truncation + 1 (in) + double& lat, // latitude in degree (in) + array::ArrayView& zlfpol)// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) +{ + std::ostream& out = Log::info(); // just for debugging + array::ArrayT idxmn_(knsmax+1,knsmax+1); + array::ArrayView idxmn = make_view(idxmn_); + int j = 0; + for( int jm=0; jm<=knsmax; ++jm ) { + for( int jn=jm; jn<=knsmax; ++jn ) { + idxmn(jm,jn) = j++; + } + } + + array::ArrayT zfn_(knsmax+1,knsmax+1); + array::ArrayView zfn = make_view(zfn_); + + int iodd; + + // Belousov, Swarztrauber use zfn(0,0)=std::sqrt(2.) + // IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 + zfn(0,0) = 2.; + for( int jn=1; jn<=knsmax; ++jn ) { + double zfnn = zfn(0,0); + for( int jgl=1; jgl<=jn; ++jgl) { + zfnn *= std::sqrt(1.-0.25/(jgl*jgl)); + } + iodd = jn % 2; + zfn(jn,jn)=zfnn; + for( int jgl=2; jgl<=jn-iodd; jgl+=2 ) { + zfn(jn,jn-jgl) = zfn(jn,jn-jgl+2) * ((jgl-1.)*(2.*jn-jgl+2.)) / (jgl*(2.*jn-jgl+1.)); + } + } + + zlfpol.assign(0.); // just for debugging (shouldn't be necessary because not in trans library) + + // -------------------- + // 1. First two columns + // -------------------- + double zdlx1 = (90.-lat)*util::Constants::degreesToRadians(); // theta + double zdlx = std::cos(zdlx1); // cos(theta) + double zdlsita = std::sqrt(1.-zdlx*zdlx); // sin(theta) (this is how trans library does it) + + zlfpol(0,0) = 1.; + double zdl1sita = 0.; + + // if we are less than 1 meter from the pole, + if( std::abs(zdlsita) <= std::sqrt(std::numeric_limits::epsilon()) ) + { + zdlx = 1.; + zdlsita = 0.; + } else { + zdl1sita = 1./zdlsita; + } + + // ordinary Legendre polynomials from series expansion + // --------------------------------------------------- + + // even N + for( int jn=2; jn<=knsmax; jn+=2 ) { + double zdlk = 0.5*zfn(jn,0); + double zdlldn = 0.0; + // represented by only even k + for (int jk=2; jk<=jn; jk+=2 ) { + // normalised ordinary Legendre polynomial == \overbar{P_n}^0 + zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); + // normalised associated Legendre polynomial == \overbar{P_n}^1 + zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); + } + zlfpol(idxmn(0,jn)) = zdlk; + zlfpol(idxmn(1,jn)) = zdlldn; + } + + // odd N + for( int jn=1; jn<=knsmax; jn+=2 ) { + double zdlk = 0.5*zfn(jn,0); + double zdlldn = 0.0; + // represented by only even k + for (int jk=1; jk<=jn; jk+=2 ) { + // normalised ordinary Legendre polynomial == \overbar{P_n}^0 + zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); + // normalised associated Legendre polynomial == \overbar{P_n}^1 + zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); + } + zlfpol(idxmn(0,jn)) = zdlk; + zlfpol(idxmn(1,jn)) = zdlldn; + } + + // -------------------------------------------------------------- + // 2. Diagonal (the terms 0,0 and 1,1 have already been computed) + // Belousov, equation (23) + // -------------------------------------------------------------- + + double zdls = zdl1sita*std::numeric_limits::min(); + for( int jn=2; jn<=knsmax; ++jn ) { + zlfpol(idxmn(jn,jn)) = zlfpol(idxmn(jn-1,jn-1))*zdlsita*std::sqrt((2.*jn+1.)/(2.*jn)); + if( std::abs(zlfpol(idxmn(jn,jn))) < zdls ) zlfpol(idxmn(jn,jn)) = 0.0; + } + + // --------------------------------------------- + // 3. General recurrence (Belousov, equation 17) + // --------------------------------------------- + + for( int jn=3; jn<=knsmax; ++jn ) { + for( int jm=2; jm& zlfpol,// values of associated Legendre functions at desired latitude, size (knsmax+1)*knsmax/2 (in) + array::ArrayView& rspecg)// spectral data, size (knsmax+1)*knsmax (in) +{ + double result = 0., zfac = 1.; + int k = 0; + double lonRad = lon * util::Constants::degreesToRadians(); + for( int jm=0; jm<=knsmax; ++jm ) { + // Legendre transformation: + double rlegReal = 0., rlegImag = 0.; + for( int jn=jm; jn<=knsmax; ++jn ) { + if( jm>0 ) zfac = 2.; + // not completely sure where this zfac comes from. One possible explanation: + // normalization of trigonometric functions in the spherical harmonics + // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 + rlegReal += rspecg(2*k) * zfac * zlfpol(k); + rlegImag += rspecg(2*k+1) * zfac * zlfpol(k); + //Log::info() << zfac * zlfpol(k) << std::endl; // just for debugging + k++; + } + // local Fourier transformation: + // (FFT would be slower when computing the Fourier transformation for a single point) + if( jm<=knsmaxFT ) result += std::cos(jm*lonRad) * rlegReal - std::sin(jm*lonRad) * rlegImag; + } + return result; +} + + +//----------------------------------------------------------------------------- + +CASE( "test_transgeneral_legendrepolynomials" ) +{ + std::ostream& out = Log::info(); // just for debugging + out << "test_transgeneral_legendrepolynomials" << std::endl; +/* + Grid g( "O10" ); + trans::Trans trans(g,1279); +*/ + int trp1 = 1280; // truncation + 1 + int N = (trp1+2)*(trp1+1)/2; + atlas::array::ArrayT zlfpol_(N); + atlas::array::ArrayView zlfpol = make_view(zlfpol_); + + double lat = 50.; + lat = std::acos(0.99312859918509488)*util::Constants::radiansToDegrees(); + compute_legendre(trp1, lat, zlfpol); +/* + out << "zlfpol after compute legendre:" << std::endl; + int idx, col = 8; + for( int jn=0; jn rspecg_(2*N); + atlas::array::ArrayView rspecg = make_view(rspecg_); + rspecg.assign( { // copy and paste from Python output from print repr(data) for geopotential of T1279 truncated to T10 + 2.27058862e+03, 0.00000000e+00, 2.64344482e+02, + 0.00000000e+00, 1.04363721e+03, 0.00000000e+00, + -1.38711157e+03, 0.00000000e+00, 6.30294678e+02, + 0.00000000e+00, -1.47959766e+03, 0.00000000e+00, + 1.25787305e+03, 0.00000000e+00, -3.47238281e+02, + 0.00000000e+00, 6.09284912e+02, 0.00000000e+00, + -5.79417480e+02, 0.00000000e+00, -7.42720642e+01, + 0.00000000e+00, 4.70171387e+02, -4.99296387e+02, + -4.64239407e+00, -4.20254883e+02, -2.01318069e+02, + -4.17947510e+02, -8.64668579e+01, 6.79094482e+02, + 8.39252777e+01, 5.26367493e+01, -7.47528839e+01, + 7.56367920e+02, 2.95226318e+02, -4.45547119e+02, + 6.53360596e+01, 3.04475098e+02, 1.98545914e+02, + -6.05724854e+02, -4.66925335e+00, 4.36788086e+02, + -4.38317627e+02, -2.01735626e+02, -6.73341553e+02, + -3.45433105e+02, -7.00174316e+02, -1.59601822e+01, + -1.14086212e+02, 1.66471054e+02, 2.38090469e+02, + 1.47945251e+02, 5.53364014e+02, 1.67163818e+02, + 8.92426300e+01, 1.93021362e+02, 3.87085419e+01, + 7.25012970e+01, -3.77425781e+02, 1.46001043e+01, + 2.06437378e+01, -2.54263626e+02, 2.88258545e+02, + 4.34750977e+02, 2.13519592e+02, 3.96897217e+02, + 8.74137115e+01, 7.21976471e+01, 1.45806274e+02, + -1.06001190e+02, 4.55372467e+01, -1.79682510e+02, + 4.84295959e+01, -1.41918839e+02, -1.50270279e+02, + 2.25189957e+02, 1.10319427e+02, -4.35088135e+02, + 5.34815430e+02, 3.42563721e+02, 4.42061523e+02, + 1.75658325e+02, 1.22033813e+02, -2.49562073e+01, + -1.15247650e+02, 3.08883514e+01, -3.12923828e+02, + -1.02068848e+02, -3.29612549e+02, -1.96804504e+02, + -1.12869827e+02, -3.42539062e+02, -2.32903732e+02, + -9.58003235e+01, -7.35217896e+01, -3.16965576e+02, + -1.24462708e+02, -3.18577637e+02, -1.14058228e+02, + -2.69070282e+01, -3.63590851e+01, 6.86552277e+01, + -1.93415085e+02, -3.96717262e+00, -1.63823044e+02, + 6.96005821e-01, -6.39315796e+01, -9.11142426e+01, + -1.09771667e+02, -1.34256149e+02, -1.35531940e+01, + 1.38606615e+01, -1.35011963e+02, 2.22399918e+02, + 3.54877930e+02, 1.22672028e+02, 1.83927261e+02, + 2.95129639e+02, 8.63545532e+01, 2.30139908e+02, + -1.14560532e+02, 6.74462585e+01, 3.10108154e+02, + 9.13583469e+00, 1.77570038e+01, 1.12481117e+01, + -2.94228516e+01, -2.62760925e+01, 7.95001831e+01, + -8.78986206e+01, 1.31246429e+02, 6.75210419e+01 + } + ); + + double lat = 27.9878, lon = 86.9250; // latitude and longitude in degree + + atlas::array::ArrayT zlfpol_(N); + atlas::array::ArrayView zlfpol = make_view(zlfpol_); + + // compute associated Legendre functions: + compute_legendre(trp1, lat, zlfpol); + + // perform spectral transform: + double result = spectral_transform_point(trp1, trp1, lon, zlfpol, rspecg); + + // output result: + out << "result: " << result << std::endl; + +} + +//----------------------------------------------------------------------------- + +} // namespace test +} // namespace atlas + + +int main(int argc, char **argv) { + atlas::test::AtlasTransEnvironment env( argc, argv ); + return run_tests ( argc, argv, false ); +} From 4d07f06b7dcdef1c19572714606599d3b846ef8f Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Thu, 2 Nov 2017 19:13:28 +0000 Subject: [PATCH 174/355] ATLAS-135 quick runtime test for a grid of longitudes and latitudes --- src/tests/trans/test_transgeneral.cc | 69 ++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 98449a2fb..721c58854 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -34,6 +34,7 @@ #include "eckit/testing/Test.h" #include +#include using namespace eckit; using namespace eckit::testing; @@ -230,6 +231,47 @@ double spectral_transform_point( } +//----------------------------------------------------------------------------- +// Routine to compute the spectral transform by using a local Fourier transformation +// for a grid (same latitude for all longitudes, allows to compute Legendre functions +// once for all longitudes) +// +// Author: +// Andreas Mueller *ECMWF* +// +void spectral_transform_grid( + const size_t knsmax, // truncation + 1 (in) + const size_t knsmaxFT, // truncation + 1 for Fourier transformation (in) + array::ArrayView& lats, // vector of (unique) latitudes in degree (in) + array::ArrayView& lons, // vector of (unique) longitudes in degree (in) + array::ArrayView& rspecg,// spectral data, size (knsmax+1)*knsmax (in) + array::ArrayView& rgp) // resulting grid point data (out) +{ + int N = (knsmax+2)*(knsmax+1)/2, k = 0; + atlas::array::ArrayT zlfpol_(N); + atlas::array::ArrayView zlfpol = make_view(zlfpol_); + + auto start = std::chrono::high_resolution_clock::now(); + for( int jlat=0; jlat elapsed = finish - start; + + Log::info() << "performed " << k << " spectral transforms" << std::endl; + Log::info() << "took " << elapsed.count() << " seconds" << std::endl; + +} + + //----------------------------------------------------------------------------- CASE( "test_transgeneral_legendrepolynomials" ) @@ -342,6 +384,33 @@ CASE( "test_transgeneral_pointtrans" ) //----------------------------------------------------------------------------- +CASE( "test_transgeneral_gridtrans" ) +{ + std::ostream& out = Log::info(); + Log::info() << "test_transgeneral_gridtrans" << std::endl; + + int trp1 = 1280; // truncation + 1 + int N = (trp1+2)*(trp1+1)/2; + + atlas::array::ArrayT rspecg_(2*N); + atlas::array::ArrayView rspecg = make_view(rspecg_); + + int nlats = 100, nlons = 100; + atlas::array::ArrayT lats_(nlats); + atlas::array::ArrayView lats = make_view(lats_); + atlas::array::ArrayT lons_(nlons); + atlas::array::ArrayView lons = make_view(lons_); + + atlas::array::ArrayT rgp_(nlons, nlats); + atlas::array::ArrayView rgp = make_view(rgp_); + + // perform spectral transform: + spectral_transform_grid(trp1, trp1, lats, lons, rspecg, rgp); + +} + +//----------------------------------------------------------------------------- + } // namespace test } // namespace atlas From b94fe250ca03fe0bbb3c7899c216e9671c662015 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Wed, 8 Nov 2017 19:17:13 +0000 Subject: [PATCH 175/355] ATLAS-135 added analytic test and fixed a few bugs --- src/tests/trans/test_transgeneral.cc | 450 ++++++++++++++++++++++++++- 1 file changed, 440 insertions(+), 10 deletions(-) diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 721c58854..259d6870a 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -28,6 +28,7 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/trans/Trans.h" #include "atlas/array/MakeView.h" +#include "atlas/runtime/Trace.h" #include "transi/trans.h" #include "tests/AtlasTestEnvironment.h" @@ -207,6 +208,7 @@ double spectral_transform_point( array::ArrayView& zlfpol,// values of associated Legendre functions at desired latitude, size (knsmax+1)*knsmax/2 (in) array::ArrayView& rspecg)// spectral data, size (knsmax+1)*knsmax (in) { + std::ostream& out = Log::info(); // just for debugging double result = 0., zfac = 1.; int k = 0; double lonRad = lon * util::Constants::degreesToRadians(); @@ -225,7 +227,45 @@ double spectral_transform_point( } // local Fourier transformation: // (FFT would be slower when computing the Fourier transformation for a single point) - if( jm<=knsmaxFT ) result += std::cos(jm*lonRad) * rlegReal - std::sin(jm*lonRad) * rlegImag; + if( jm<=knsmaxFT ) { + result += std::cos(jm*lonRad) * rlegReal - std::sin(jm*lonRad) * rlegImag; + out << result << " "; + } + } + return result; +} + + +double spectral_transform_point( + const size_t knsmax, // truncation + 1 (in) + const size_t knsmaxFT, // truncation + 1 for Fourier transformation (in) + double& lon, // longitude in degree (in) + array::ArrayView& zlfpol,// values of associated Legendre functions at desired latitude, size (knsmax+1)*knsmax/2 (in) + double rspecg[]) // spectral data, size (knsmax+1)*knsmax (in) +{ + std::ostream& out = Log::info(); // just for debugging + double result = 0., zfac = 1.; + int k = 0; + double lonRad = lon * util::Constants::degreesToRadians(); + for( int jm=0; jm<=knsmax; ++jm ) { + // Legendre transformation: + double rlegReal = 0., rlegImag = 0.; + for( int jn=jm; jn<=knsmax; ++jn ) { + if( jm>0 ) zfac = 2.; + // not completely sure where this zfac comes from. One possible explanation: + // normalization of trigonometric functions in the spherical harmonics + // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 + rlegReal += rspecg[2*k] * zfac * zlfpol(k); + rlegImag += rspecg[2*k+1] * zfac * zlfpol(k); + //Log::info() << zfac * zlfpol(k) << std::endl; // just for debugging + k++; + } + // local Fourier transformation: + // (FFT would be slower when computing the Fourier transformation for a single point) + if( jm<=knsmaxFT ) { + result += std::cos(jm*lonRad) * rlegReal - std::sin(jm*lonRad) * rlegImag; + out << result << " "; + } } return result; } @@ -251,7 +291,7 @@ void spectral_transform_grid( atlas::array::ArrayT zlfpol_(N); atlas::array::ArrayView zlfpol = make_view(zlfpol_); - auto start = std::chrono::high_resolution_clock::now(); + ATLAS_TRACE(); for( int jlat=0; jlat elapsed = finish - start; Log::info() << "performed " << k << " spectral transforms" << std::endl; - Log::info() << "took " << elapsed.count() << " seconds" << std::endl; } +//----------------------------------------------------------------------------- +// Routine to compute the spectral transform by using a local Fourier transformation +// for a grid (same latitude for all longitudes, allows to compute Legendre functions +// once for all longitudes) +// +// Author: +// Andreas Mueller *ECMWF* +// +void spectral_transform_grid2( + const size_t knsmax, // truncation + 1 (in) + const size_t knsmaxFT, // truncation + 1 for Fourier transformation (in) + array::ArrayView& lats, // vector of (unique) latitudes in degree (in) + array::ArrayView& lons, // vector of (unique) longitudes in degree (in) + array::ArrayView& rspecg,// spectral data, size (knsmax+1)*knsmax (in) + array::ArrayView& rgp) // resulting grid point data (out) +{ + std::ostream& out = Log::info(); // just for debugging + int N = (knsmax+2)*(knsmax+1)/2; + ATLAS_TRACE(); + atlas::array::ArrayT zlfpol_(N); + atlas::array::ArrayView zlfpol = make_view(zlfpol_); + + atlas::array::ArrayT rlegReal_(knsmaxFT+1); + atlas::array::ArrayView rlegReal = make_view(rlegReal_); + + atlas::array::ArrayT rlegImag_(knsmaxFT+1); + atlas::array::ArrayView rlegImag = make_view(rlegImag_); + + for( int jlat=0; jlat0 ) zfac = 2.; + // not completely sure where this zfac comes from. One possible explanation: + // normalization of trigonometric functions in the spherical harmonics + // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 + rlegReal(jm) += rspecg(2*k) * zfac * zlfpol(k); + rlegImag(jm) += rspecg(2*k+1) * zfac * zlfpol(k); + //Log::info() << zfac * zlfpol(k) << std::endl; // just for debugging + k++; + } + } + + // local Fourier transformation: + // (FFT would be slower when computing the Fourier transformation for a single point) + for( int jlon=0; jlon zlfpol_(N); + atlas::array::ArrayView zlfpol = make_view(zlfpol_); + + atlas::array::ArrayT rlegReal_(knsmaxFT+1); + atlas::array::ArrayView rlegReal = make_view(rlegReal_); + + atlas::array::ArrayT rlegImag_(knsmaxFT+1); + atlas::array::ArrayView rlegImag = make_view(rlegImag_); + + for( int jm=0; jm0 ) zfac = 2.; + + // not completely sure where this zfac comes from. One possible explanation: + // normalization of trigonometric functions in the spherical harmonics + // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 + rlegReal[jm] += rspecg[2*k] * zfac * zlfpol(k); + rlegImag[jm] += rspecg[2*k+1] * zfac * zlfpol(k); + //Log::info() << zfac * zlfpol(k) << std::endl; // just for debugging + k++; + } + } + + for( size_t i=0; i zlfpol_(N); atlas::array::ArrayView zlfpol = make_view(zlfpol_); @@ -384,12 +622,12 @@ CASE( "test_transgeneral_pointtrans" ) //----------------------------------------------------------------------------- -CASE( "test_transgeneral_gridtrans" ) +/*CASE( "test_transgeneral_gridtrans_speed" ) { std::ostream& out = Log::info(); Log::info() << "test_transgeneral_gridtrans" << std::endl; - int trp1 = 1280; // truncation + 1 + int trp1 = 10;//1280; // truncation + 1 int N = (trp1+2)*(trp1+1)/2; atlas::array::ArrayT rspecg_(2*N); @@ -405,7 +643,197 @@ CASE( "test_transgeneral_gridtrans" ) atlas::array::ArrayView rgp = make_view(rgp_); // perform spectral transform: - spectral_transform_grid(trp1, trp1, lats, lons, rspecg, rgp); + spectral_transform_grid2(trp1, trp1, lats, lons, rspecg, rgp); + +} +*/ +//----------------------------------------------------------------------------- + +CASE( "test_transgeneral_gridtrans_result" ) +{ + std::ostream& out = Log::info(); + Log::info() << "test_transgeneral_gridtrans" << std::endl; + + std::string grid_uid("O80"); + grid::StructuredGrid g (grid_uid); + + int trp1 = 10; // truncation + 1 + int N = (trp1+2)*(trp1+1)/2; + + atlas::array::ArrayT rspecg_(2*N); + atlas::array::ArrayView rspecg = make_view(rspecg_); + rspecg.assign( { // copy and paste from Python output from print repr(data) for geopotential of T1279 truncated to T10 + 2.27058862e+03, 0.00000000e+00, 2.64344482e+02, + 0.00000000e+00, 1.04363721e+03, 0.00000000e+00, + -1.38711157e+03, 0.00000000e+00, 6.30294678e+02, + 0.00000000e+00, -1.47959766e+03, 0.00000000e+00, + 1.25787305e+03, 0.00000000e+00, -3.47238281e+02, + 0.00000000e+00, 6.09284912e+02, 0.00000000e+00, + -5.79417480e+02, 0.00000000e+00, -7.42720642e+01, + 0.00000000e+00, 4.70171387e+02, -4.99296387e+02, + -4.64239407e+00, -4.20254883e+02, -2.01318069e+02, + -4.17947510e+02, -8.64668579e+01, 6.79094482e+02, + 8.39252777e+01, 5.26367493e+01, -7.47528839e+01, + 7.56367920e+02, 2.95226318e+02, -4.45547119e+02, + 6.53360596e+01, 3.04475098e+02, 1.98545914e+02, + -6.05724854e+02, -4.66925335e+00, 4.36788086e+02, + -4.38317627e+02, -2.01735626e+02, -6.73341553e+02, + -3.45433105e+02, -7.00174316e+02, -1.59601822e+01, + -1.14086212e+02, 1.66471054e+02, 2.38090469e+02, + 1.47945251e+02, 5.53364014e+02, 1.67163818e+02, + 8.92426300e+01, 1.93021362e+02, 3.87085419e+01, + 7.25012970e+01, -3.77425781e+02, 1.46001043e+01, + 2.06437378e+01, -2.54263626e+02, 2.88258545e+02, + 4.34750977e+02, 2.13519592e+02, 3.96897217e+02, + 8.74137115e+01, 7.21976471e+01, 1.45806274e+02, + -1.06001190e+02, 4.55372467e+01, -1.79682510e+02, + 4.84295959e+01, -1.41918839e+02, -1.50270279e+02, + 2.25189957e+02, 1.10319427e+02, -4.35088135e+02, + 5.34815430e+02, 3.42563721e+02, 4.42061523e+02, + 1.75658325e+02, 1.22033813e+02, -2.49562073e+01, + -1.15247650e+02, 3.08883514e+01, -3.12923828e+02, + -1.02068848e+02, -3.29612549e+02, -1.96804504e+02, + -1.12869827e+02, -3.42539062e+02, -2.32903732e+02, + -9.58003235e+01, -7.35217896e+01, -3.16965576e+02, + -1.24462708e+02, -3.18577637e+02, -1.14058228e+02, + -2.69070282e+01, -3.63590851e+01, 6.86552277e+01, + -1.93415085e+02, -3.96717262e+00, -1.63823044e+02, + 6.96005821e-01, -6.39315796e+01, -9.11142426e+01, + -1.09771667e+02, -1.34256149e+02, -1.35531940e+01, + 1.38606615e+01, -1.35011963e+02, 2.22399918e+02, + 3.54877930e+02, 1.22672028e+02, 1.83927261e+02, + 2.95129639e+02, 8.63545532e+01, 2.30139908e+02, + -1.14560532e+02, 6.74462585e+01, 3.10108154e+02, + 9.13583469e+00, 1.77570038e+01, 1.12481117e+01, + -2.94228516e+01, -2.62760925e+01, 7.95001831e+01, + -8.78986206e+01, 1.31246429e+02, 6.75210419e+01 + } + ); + + int nlats = 1, nlons = 1; + atlas::array::ArrayT lats_(nlats); + atlas::array::ArrayView lats = make_view(lats_); + atlas::array::ArrayT lons_(nlons); + atlas::array::ArrayView lons = make_view(lons_); + lats.assign(27.9878); lons.assign(86.9250); // latitude and longitude of Mt. Everest in degree + + atlas::array::ArrayT rgp_(nlons, nlats); + atlas::array::ArrayView rgp = make_view(rgp_); + + // perform spectral transform: + spectral_transform_grid2(trp1, trp1, lats, lons, rspecg, rgp); + + out << "result of grid computation: " << rgp(0,0) << std::endl; + +} + +//----------------------------------------------------------------------------- + +CASE( "test_transgeneral_structured" ) +{ + std::ostream& out = Log::info(); + Log::info() << "test_transgeneral_gridtrans" << std::endl; + + std::string grid_uid("F1"); + grid::StructuredGrid g (grid_uid); + /*Grid g = grid::UnstructuredGrid( new std::vector{ + {27.9878, 86.9250}, + {27.9878, 86.9250}, + {27.9878, 86.9250} + });*/ + + int trp1 = 10; // truncation + 1 + int N = (trp1+2)*(trp1+1)/2; + + double rspecg[] = { 2.27058862e+03, 0.00000000e+00, 2.64344482e+02, + 0.00000000e+00, 1.04363721e+03, 0.00000000e+00, + -1.38711157e+03, 0.00000000e+00, 6.30294678e+02, + 0.00000000e+00, -1.47959766e+03, 0.00000000e+00, + 1.25787305e+03, 0.00000000e+00, -3.47238281e+02, + 0.00000000e+00, 6.09284912e+02, 0.00000000e+00, + -5.79417480e+02, 0.00000000e+00, -7.42720642e+01, + 0.00000000e+00, 4.70171387e+02, -4.99296387e+02, + -4.64239407e+00, -4.20254883e+02, -2.01318069e+02, + -4.17947510e+02, -8.64668579e+01, 6.79094482e+02, + 8.39252777e+01, 5.26367493e+01, -7.47528839e+01, + 7.56367920e+02, 2.95226318e+02, -4.45547119e+02, + 6.53360596e+01, 3.04475098e+02, 1.98545914e+02, + -6.05724854e+02, -4.66925335e+00, 4.36788086e+02, + -4.38317627e+02, -2.01735626e+02, -6.73341553e+02, + -3.45433105e+02, -7.00174316e+02, -1.59601822e+01, + -1.14086212e+02, 1.66471054e+02, 2.38090469e+02, + 1.47945251e+02, 5.53364014e+02, 1.67163818e+02, + 8.92426300e+01, 1.93021362e+02, 3.87085419e+01, + 7.25012970e+01, -3.77425781e+02, 1.46001043e+01, + 2.06437378e+01, -2.54263626e+02, 2.88258545e+02, + 4.34750977e+02, 2.13519592e+02, 3.96897217e+02, + 8.74137115e+01, 7.21976471e+01, 1.45806274e+02, + -1.06001190e+02, 4.55372467e+01, -1.79682510e+02, + 4.84295959e+01, -1.41918839e+02, -1.50270279e+02, + 2.25189957e+02, 1.10319427e+02, -4.35088135e+02, + 5.34815430e+02, 3.42563721e+02, 4.42061523e+02, + 1.75658325e+02, 1.22033813e+02, -2.49562073e+01, + -1.15247650e+02, 3.08883514e+01, -3.12923828e+02, + -1.02068848e+02, -3.29612549e+02, -1.96804504e+02, + -1.12869827e+02, -3.42539062e+02, -2.32903732e+02, + -9.58003235e+01, -7.35217896e+01, -3.16965576e+02, + -1.24462708e+02, -3.18577637e+02, -1.14058228e+02, + -2.69070282e+01, -3.63590851e+01, 6.86552277e+01, + -1.93415085e+02, -3.96717262e+00, -1.63823044e+02, + 6.96005821e-01, -6.39315796e+01, -9.11142426e+01, + -1.09771667e+02, -1.34256149e+02, -1.35531940e+01, + 1.38606615e+01, -1.35011963e+02, 2.22399918e+02, + 3.54877930e+02, 1.22672028e+02, 1.83927261e+02, + 2.95129639e+02, 8.63545532e+01, 2.30139908e+02, + -1.14560532e+02, 6.74462585e+01, 3.10108154e+02, + 9.13583469e+00, 1.77570038e+01, 1.12481117e+01, + -2.94228516e+01, -2.62760925e+01, 7.95001831e+01, + -8.78986206e+01, 1.31246429e+02, 6.75210419e+01}; + + double rgp[g.size()]; + + // perform spectral transform: + spectral_transform_grid(trp1, trp1, g, rspecg, rgp); + + out << "result of grid computation: "; + for( int jm=0; jm{ + {27.9878, 86.9250}, + {27.9878, 86.9250}, + {27.9878, 86.9250} + });*/ + + int trp1 = 4; // truncation + int N = (trp1+2)*(trp1+1)/2; + + double rspecg[2*N]; + double rgp[g.size()], rgp_analytic[g.size()]; + + + // compute analytic solution (this also initializes rspecg and needs to be done before the actual transform): + spectral_transform_grid_analytic(trp1, trp1, g, rspecg, rgp_analytic); + // perform spectral transform: + spectral_transform_grid(trp1, trp1, g, rspecg, rgp); + + out << "result of grid computation: rms-error: "; + double rms = 0.; + for( int jm=0; jm Date: Thu, 9 Nov 2017 18:35:23 +0000 Subject: [PATCH 176/355] ATLAS-135 implemented analytic tests. Still having an issue for m=2, n=2. --- src/tests/trans/test_transgeneral.cc | 634 +++++++++------------------ 1 file changed, 202 insertions(+), 432 deletions(-) diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 259d6870a..83c90bd80 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -195,135 +195,72 @@ void compute_legendre( } //----------------------------------------------------------------------------- -// Routine to compute the spectral transform by using a local Fourier transformation -// for a single point +// Routine to compute the Legendre transformation // // Author: // Andreas Mueller *ECMWF* // -double spectral_transform_point( - const size_t knsmax, // truncation + 1 (in) - const size_t knsmaxFT, // truncation + 1 for Fourier transformation (in) - double& lon, // longitude in degree (in) - array::ArrayView& zlfpol,// values of associated Legendre functions at desired latitude, size (knsmax+1)*knsmax/2 (in) - array::ArrayView& rspecg)// spectral data, size (knsmax+1)*knsmax (in) +void legendre_transform( + const size_t knsmax, // truncation + 1 (in) + const size_t knsmaxFT, // truncation + 1 for Fourier transformation (in) + array::ArrayView& rlegReal,// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) + array::ArrayView& rlegImag,// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) + array::ArrayView& zlfpol, // values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) + double rspecg[]) // spectral data, size (knsmax+1)*knsmax (in) { - std::ostream& out = Log::info(); // just for debugging - double result = 0., zfac = 1.; + // Legendre transformation: + rlegReal.assign(0.); rlegImag.assign(0.); + double zfac = 1.; int k = 0; - double lonRad = lon * util::Constants::degreesToRadians(); - for( int jm=0; jm<=knsmax; ++jm ) { - // Legendre transformation: - double rlegReal = 0., rlegImag = 0.; + for( int jm=0; jm<=knsmaxFT; ++jm ) { for( int jn=jm; jn<=knsmax; ++jn ) { if( jm>0 ) zfac = 2.; - // not completely sure where this zfac comes from. One possible explanation: - // normalization of trigonometric functions in the spherical harmonics - // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 - rlegReal += rspecg(2*k) * zfac * zlfpol(k); - rlegImag += rspecg(2*k+1) * zfac * zlfpol(k); - //Log::info() << zfac * zlfpol(k) << std::endl; // just for debugging - k++; - } - // local Fourier transformation: - // (FFT would be slower when computing the Fourier transformation for a single point) - if( jm<=knsmaxFT ) { - result += std::cos(jm*lonRad) * rlegReal - std::sin(jm*lonRad) * rlegImag; - out << result << " "; - } - } - return result; -} - -double spectral_transform_point( - const size_t knsmax, // truncation + 1 (in) - const size_t knsmaxFT, // truncation + 1 for Fourier transformation (in) - double& lon, // longitude in degree (in) - array::ArrayView& zlfpol,// values of associated Legendre functions at desired latitude, size (knsmax+1)*knsmax/2 (in) - double rspecg[]) // spectral data, size (knsmax+1)*knsmax (in) -{ - std::ostream& out = Log::info(); // just for debugging - double result = 0., zfac = 1.; - int k = 0; - double lonRad = lon * util::Constants::degreesToRadians(); - for( int jm=0; jm<=knsmax; ++jm ) { - // Legendre transformation: - double rlegReal = 0., rlegImag = 0.; - for( int jn=jm; jn<=knsmax; ++jn ) { - if( jm>0 ) zfac = 2.; // not completely sure where this zfac comes from. One possible explanation: // normalization of trigonometric functions in the spherical harmonics // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 - rlegReal += rspecg[2*k] * zfac * zlfpol(k); - rlegImag += rspecg[2*k+1] * zfac * zlfpol(k); + rlegReal[jm] += rspecg[2*k] * zfac * zlfpol(k); + rlegImag[jm] += rspecg[2*k+1] * zfac * zlfpol(k); //Log::info() << zfac * zlfpol(k) << std::endl; // just for debugging k++; } - // local Fourier transformation: - // (FFT would be slower when computing the Fourier transformation for a single point) - if( jm<=knsmaxFT ) { - result += std::cos(jm*lonRad) * rlegReal - std::sin(jm*lonRad) * rlegImag; - out << result << " "; - } } - return result; } - //----------------------------------------------------------------------------- -// Routine to compute the spectral transform by using a local Fourier transformation -// for a grid (same latitude for all longitudes, allows to compute Legendre functions -// once for all longitudes) +// Routine to compute the local Fourier transformation // // Author: // Andreas Mueller *ECMWF* // -void spectral_transform_grid( - const size_t knsmax, // truncation + 1 (in) - const size_t knsmaxFT, // truncation + 1 for Fourier transformation (in) - array::ArrayView& lats, // vector of (unique) latitudes in degree (in) - array::ArrayView& lons, // vector of (unique) longitudes in degree (in) - array::ArrayView& rspecg,// spectral data, size (knsmax+1)*knsmax (in) - array::ArrayView& rgp) // resulting grid point data (out) +double fourier_transform( + const size_t knsmaxFT, + array::ArrayView& rlegReal,// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) + array::ArrayView& rlegImag,// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) + double lon) { - int N = (knsmax+2)*(knsmax+1)/2, k = 0; - atlas::array::ArrayT zlfpol_(N); - atlas::array::ArrayView zlfpol = make_view(zlfpol_); - - ATLAS_TRACE(); - for( int jlat=0; jlat& lats, // vector of (unique) latitudes in degree (in) - array::ArrayView& lons, // vector of (unique) longitudes in degree (in) - array::ArrayView& rspecg,// spectral data, size (knsmax+1)*knsmax (in) - array::ArrayView& rgp) // resulting grid point data (out) + double lon, // longitude in degree (in) + double lat, // latitude in degree (in) + double rspecg[]) // spectral data, size (knsmax+1)*knsmax (in) { std::ostream& out = Log::info(); // just for debugging int N = (knsmax+2)*(knsmax+1)/2; @@ -337,41 +274,15 @@ void spectral_transform_grid2( atlas::array::ArrayT rlegImag_(knsmaxFT+1); atlas::array::ArrayView rlegImag = make_view(rlegImag_); - for( int jlat=0; jlat0 ) zfac = 2.; - // not completely sure where this zfac comes from. One possible explanation: - // normalization of trigonometric functions in the spherical harmonics - // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 - rlegReal(jm) += rspecg(2*k) * zfac * zlfpol(k); - rlegImag(jm) += rspecg(2*k+1) * zfac * zlfpol(k); - //Log::info() << zfac * zlfpol(k) << std::endl; // just for debugging - k++; - } - } - - // local Fourier transformation: - // (FFT would be slower when computing the Fourier transformation for a single point) - for( int jlon=0; jlon0 ) zfac = 2.; - - // not completely sure where this zfac comes from. One possible explanation: - // normalization of trigonometric functions in the spherical harmonics - // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 - rlegReal[jm] += rspecg[2*k] * zfac * zlfpol(k); - rlegImag[jm] += rspecg[2*k+1] * zfac * zlfpol(k); - //Log::info() << zfac * zlfpol(k) << std::endl; // just for debugging - k++; - } - } + legendre_transform(knsmax, knsmaxFT, rlegReal, rlegImag, zlfpol, rspecg); for( size_t i=0; i0 ) rft *= 2.; // the famous factor 2 that noone really understands + if( real ) { + rft *= std::cos(m*lonRad); + } else { + rft *= -std::sin(m*lonRad); + } + // Legendre part of the spherical harmonics (following http://mathworld.wolfram.com/SphericalHarmonic.html + // multiplied with -2*sqrt(pi) due to different normalization and different coordinates): + // (can also be computed on http://www.wolframalpha.com with: + // LegendreP[n, m, x]/Sqrt[1/2*Integrate[LegendreP[n, m, y]^2, {y, -1, 1}]]) + 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; // shouldn't this be minus? + if ( m==0 && n==3 ) + return std::sqrt(7.)/2.*(5.*latsin*latsin-3.)*latsin*rft; // shouldn't this be minus? + if ( m==1 && n==1 ) + return std::sqrt(3./2.)*latcos*rft; // shouldn't this be minus? + if ( m==1 && n==2 ) + return std::sqrt(15./2.)*latsin*latcos*rft; // shouldn't this be minus? + if ( m==1 && n==3 ) + return std::sqrt(21.)/4.*latcos*(5.*latsin*latsin-1.)*rft; // shouldn't this be minus? + 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; // shouldn't this be minus? + return 0; } void spectral_transform_grid_analytic( const size_t knsmax, // truncation + 1 (in) const size_t knsmaxFT,// truncation + 1 for Fourier transformation (in) + double n, // total wave number (implemented so far for n<4 + double m, // zonal wave number (implemented so far for m<4, m zlfpol_(N); atlas::array::ArrayView zlfpol = make_view(zlfpol_); double lat = 50.; lat = std::acos(0.99312859918509488)*util::Constants::radiansToDegrees(); - compute_legendre(trp1, lat, zlfpol); + compute_legendre(trc, lat, zlfpol); /* out << "zlfpol after compute legendre:" << std::endl; int idx, col = 8; @@ -546,184 +520,63 @@ CASE( "test_transgeneral_legendrepolynomials" ) //----------------------------------------------------------------------------- -CASE( "test_transgeneral_pointtrans" ) +CASE( "test_transgeneral_point" ) { std::ostream& out = Log::info(); - Log::info() << "test_transgeneral_pointtrans" << std::endl; - - int trp1 = 10; // truncation + 1 - int N = (trp1+2)*(trp1+1)/2; - - atlas::array::ArrayT rspecg_(2*N); - atlas::array::ArrayView rspecg = make_view(rspecg_); - rspecg.assign( { // copy and paste from Python output from print repr(data) for geopotential of T1279 truncated to T10 - 2.27058862e+03, 0.00000000e+00, 2.64344482e+02, - 0.00000000e+00, 1.04363721e+03, 0.00000000e+00, - -1.38711157e+03, 0.00000000e+00, 6.30294678e+02, - 0.00000000e+00, -1.47959766e+03, 0.00000000e+00, - 1.25787305e+03, 0.00000000e+00, -3.47238281e+02, - 0.00000000e+00, 6.09284912e+02, 0.00000000e+00, - -5.79417480e+02, 0.00000000e+00, -7.42720642e+01, - 0.00000000e+00, 4.70171387e+02, -4.99296387e+02, - -4.64239407e+00, -4.20254883e+02, -2.01318069e+02, - -4.17947510e+02, -8.64668579e+01, 6.79094482e+02, - 8.39252777e+01, 5.26367493e+01, -7.47528839e+01, - 7.56367920e+02, 2.95226318e+02, -4.45547119e+02, - 6.53360596e+01, 3.04475098e+02, 1.98545914e+02, - -6.05724854e+02, -4.66925335e+00, 4.36788086e+02, - -4.38317627e+02, -2.01735626e+02, -6.73341553e+02, - -3.45433105e+02, -7.00174316e+02, -1.59601822e+01, - -1.14086212e+02, 1.66471054e+02, 2.38090469e+02, - 1.47945251e+02, 5.53364014e+02, 1.67163818e+02, - 8.92426300e+01, 1.93021362e+02, 3.87085419e+01, - 7.25012970e+01, -3.77425781e+02, 1.46001043e+01, - 2.06437378e+01, -2.54263626e+02, 2.88258545e+02, - 4.34750977e+02, 2.13519592e+02, 3.96897217e+02, - 8.74137115e+01, 7.21976471e+01, 1.45806274e+02, - -1.06001190e+02, 4.55372467e+01, -1.79682510e+02, - 4.84295959e+01, -1.41918839e+02, -1.50270279e+02, - 2.25189957e+02, 1.10319427e+02, -4.35088135e+02, - 5.34815430e+02, 3.42563721e+02, 4.42061523e+02, - 1.75658325e+02, 1.22033813e+02, -2.49562073e+01, - -1.15247650e+02, 3.08883514e+01, -3.12923828e+02, - -1.02068848e+02, -3.29612549e+02, -1.96804504e+02, - -1.12869827e+02, -3.42539062e+02, -2.32903732e+02, - -9.58003235e+01, -7.35217896e+01, -3.16965576e+02, - -1.24462708e+02, -3.18577637e+02, -1.14058228e+02, - -2.69070282e+01, -3.63590851e+01, 6.86552277e+01, - -1.93415085e+02, -3.96717262e+00, -1.63823044e+02, - 6.96005821e-01, -6.39315796e+01, -9.11142426e+01, - -1.09771667e+02, -1.34256149e+02, -1.35531940e+01, - 1.38606615e+01, -1.35011963e+02, 2.22399918e+02, - 3.54877930e+02, 1.22672028e+02, 1.83927261e+02, - 2.95129639e+02, 8.63545532e+01, 2.30139908e+02, - -1.14560532e+02, 6.74462585e+01, 3.10108154e+02, - 9.13583469e+00, 1.77570038e+01, 1.12481117e+01, - -2.94228516e+01, -2.62760925e+01, 7.95001831e+01, - -8.78986206e+01, 1.31246429e+02, 6.75210419e+01 - } - ); - - double lat = 27.9878, lon = 86.9250; // latitude and longitude of Mt. Everest in degree - - atlas::array::ArrayT zlfpol_(N); - atlas::array::ArrayView zlfpol = make_view(zlfpol_); + Log::info() << "test_transgeneral_point" << std::endl; + double tolerance = 1.e-15; + // test spectral transform up to wave number 3 by comparing + // the result with the analytically computed spherical harmonics - // compute associated Legendre functions: - compute_legendre(trp1, lat, zlfpol); + Grid g = grid::UnstructuredGrid( new std::vector{ + {20., 50.}, + {-20., 30.}, + {-89., 179.}, + {70., -101.} + }); - // perform spectral transform: - double result = spectral_transform_point(trp1, trp1, lon, zlfpol, rspecg); + int trc = 1279; // truncation - // output result: - out << "result: " << result << std::endl; + int n = 3, m = 3; + double rms = 0.; + for( int m=0; m<=3; m++ ) + for( int n=m; n<=3; n++ ) { + rms = spectral_transform_test(trc, n, m, true, g, true); + EXPECT( rms < tolerance ); + rms = spectral_transform_test(trc, n, m, false, g, true); + EXPECT( rms < tolerance ); + } } //----------------------------------------------------------------------------- -/*CASE( "test_transgeneral_gridtrans_speed" ) +CASE( "test_transgeneral_unstructured" ) { std::ostream& out = Log::info(); - Log::info() << "test_transgeneral_gridtrans" << std::endl; - - int trp1 = 10;//1280; // truncation + 1 - int N = (trp1+2)*(trp1+1)/2; + Log::info() << "test_transgeneral_unstructured" << std::endl; + double tolerance = 1.e-15; + // test spectral transform up to wave number 3 by comparing + // the result with the analytically computed spherical harmonics - atlas::array::ArrayT rspecg_(2*N); - atlas::array::ArrayView rspecg = make_view(rspecg_); + Grid g = grid::UnstructuredGrid( new std::vector{ + {20., 50.}, + {-20., 30.}, + {-89., 179.}, + {70., -101.} + }); - int nlats = 100, nlons = 100; - atlas::array::ArrayT lats_(nlats); - atlas::array::ArrayView lats = make_view(lats_); - atlas::array::ArrayT lons_(nlons); - atlas::array::ArrayView lons = make_view(lons_); - - atlas::array::ArrayT rgp_(nlons, nlats); - atlas::array::ArrayView rgp = make_view(rgp_); - - // perform spectral transform: - spectral_transform_grid2(trp1, trp1, lats, lons, rspecg, rgp); - -} -*/ -//----------------------------------------------------------------------------- - -CASE( "test_transgeneral_gridtrans_result" ) -{ - std::ostream& out = Log::info(); - Log::info() << "test_transgeneral_gridtrans" << std::endl; - - std::string grid_uid("O80"); - grid::StructuredGrid g (grid_uid); + int trc = 1279; // truncation - int trp1 = 10; // truncation + 1 - int N = (trp1+2)*(trp1+1)/2; - - atlas::array::ArrayT rspecg_(2*N); - atlas::array::ArrayView rspecg = make_view(rspecg_); - rspecg.assign( { // copy and paste from Python output from print repr(data) for geopotential of T1279 truncated to T10 - 2.27058862e+03, 0.00000000e+00, 2.64344482e+02, - 0.00000000e+00, 1.04363721e+03, 0.00000000e+00, - -1.38711157e+03, 0.00000000e+00, 6.30294678e+02, - 0.00000000e+00, -1.47959766e+03, 0.00000000e+00, - 1.25787305e+03, 0.00000000e+00, -3.47238281e+02, - 0.00000000e+00, 6.09284912e+02, 0.00000000e+00, - -5.79417480e+02, 0.00000000e+00, -7.42720642e+01, - 0.00000000e+00, 4.70171387e+02, -4.99296387e+02, - -4.64239407e+00, -4.20254883e+02, -2.01318069e+02, - -4.17947510e+02, -8.64668579e+01, 6.79094482e+02, - 8.39252777e+01, 5.26367493e+01, -7.47528839e+01, - 7.56367920e+02, 2.95226318e+02, -4.45547119e+02, - 6.53360596e+01, 3.04475098e+02, 1.98545914e+02, - -6.05724854e+02, -4.66925335e+00, 4.36788086e+02, - -4.38317627e+02, -2.01735626e+02, -6.73341553e+02, - -3.45433105e+02, -7.00174316e+02, -1.59601822e+01, - -1.14086212e+02, 1.66471054e+02, 2.38090469e+02, - 1.47945251e+02, 5.53364014e+02, 1.67163818e+02, - 8.92426300e+01, 1.93021362e+02, 3.87085419e+01, - 7.25012970e+01, -3.77425781e+02, 1.46001043e+01, - 2.06437378e+01, -2.54263626e+02, 2.88258545e+02, - 4.34750977e+02, 2.13519592e+02, 3.96897217e+02, - 8.74137115e+01, 7.21976471e+01, 1.45806274e+02, - -1.06001190e+02, 4.55372467e+01, -1.79682510e+02, - 4.84295959e+01, -1.41918839e+02, -1.50270279e+02, - 2.25189957e+02, 1.10319427e+02, -4.35088135e+02, - 5.34815430e+02, 3.42563721e+02, 4.42061523e+02, - 1.75658325e+02, 1.22033813e+02, -2.49562073e+01, - -1.15247650e+02, 3.08883514e+01, -3.12923828e+02, - -1.02068848e+02, -3.29612549e+02, -1.96804504e+02, - -1.12869827e+02, -3.42539062e+02, -2.32903732e+02, - -9.58003235e+01, -7.35217896e+01, -3.16965576e+02, - -1.24462708e+02, -3.18577637e+02, -1.14058228e+02, - -2.69070282e+01, -3.63590851e+01, 6.86552277e+01, - -1.93415085e+02, -3.96717262e+00, -1.63823044e+02, - 6.96005821e-01, -6.39315796e+01, -9.11142426e+01, - -1.09771667e+02, -1.34256149e+02, -1.35531940e+01, - 1.38606615e+01, -1.35011963e+02, 2.22399918e+02, - 3.54877930e+02, 1.22672028e+02, 1.83927261e+02, - 2.95129639e+02, 8.63545532e+01, 2.30139908e+02, - -1.14560532e+02, 6.74462585e+01, 3.10108154e+02, - 9.13583469e+00, 1.77570038e+01, 1.12481117e+01, - -2.94228516e+01, -2.62760925e+01, 7.95001831e+01, - -8.78986206e+01, 1.31246429e+02, 6.75210419e+01 - } - ); - - int nlats = 1, nlons = 1; - atlas::array::ArrayT lats_(nlats); - atlas::array::ArrayView lats = make_view(lats_); - atlas::array::ArrayT lons_(nlons); - atlas::array::ArrayView lons = make_view(lons_); - lats.assign(27.9878); lons.assign(86.9250); // latitude and longitude of Mt. Everest in degree - - atlas::array::ArrayT rgp_(nlons, nlats); - atlas::array::ArrayView rgp = make_view(rgp_); - - // perform spectral transform: - spectral_transform_grid2(trp1, trp1, lats, lons, rspecg, rgp); - - out << "result of grid computation: " << rgp(0,0) << std::endl; + int n = 3, m = 3; + double rms = 0.; + for( int m=0; m<=3; m++ ) + for( int n=m; n<=3; n++ ) { + rms = spectral_transform_test(trc, n, m, true, g, false); + EXPECT( rms < tolerance ); + rms = spectral_transform_test(trc, n, m, false, g, false); + EXPECT( rms < tolerance ); + } } @@ -732,108 +585,25 @@ CASE( "test_transgeneral_gridtrans_result" ) CASE( "test_transgeneral_structured" ) { std::ostream& out = Log::info(); - Log::info() << "test_transgeneral_gridtrans" << std::endl; + Log::info() << "test_transgeneral_structured" << std::endl; + double tolerance = 1.e-15; + // test spectral transform up to wave number 3 by comparing + // the result with the analytically computed spherical harmonics - std::string grid_uid("F1"); + std::string grid_uid("O10"); grid::StructuredGrid g (grid_uid); - /*Grid g = grid::UnstructuredGrid( new std::vector{ - {27.9878, 86.9250}, - {27.9878, 86.9250}, - {27.9878, 86.9250} - });*/ - - int trp1 = 10; // truncation + 1 - int N = (trp1+2)*(trp1+1)/2; - - double rspecg[] = { 2.27058862e+03, 0.00000000e+00, 2.64344482e+02, - 0.00000000e+00, 1.04363721e+03, 0.00000000e+00, - -1.38711157e+03, 0.00000000e+00, 6.30294678e+02, - 0.00000000e+00, -1.47959766e+03, 0.00000000e+00, - 1.25787305e+03, 0.00000000e+00, -3.47238281e+02, - 0.00000000e+00, 6.09284912e+02, 0.00000000e+00, - -5.79417480e+02, 0.00000000e+00, -7.42720642e+01, - 0.00000000e+00, 4.70171387e+02, -4.99296387e+02, - -4.64239407e+00, -4.20254883e+02, -2.01318069e+02, - -4.17947510e+02, -8.64668579e+01, 6.79094482e+02, - 8.39252777e+01, 5.26367493e+01, -7.47528839e+01, - 7.56367920e+02, 2.95226318e+02, -4.45547119e+02, - 6.53360596e+01, 3.04475098e+02, 1.98545914e+02, - -6.05724854e+02, -4.66925335e+00, 4.36788086e+02, - -4.38317627e+02, -2.01735626e+02, -6.73341553e+02, - -3.45433105e+02, -7.00174316e+02, -1.59601822e+01, - -1.14086212e+02, 1.66471054e+02, 2.38090469e+02, - 1.47945251e+02, 5.53364014e+02, 1.67163818e+02, - 8.92426300e+01, 1.93021362e+02, 3.87085419e+01, - 7.25012970e+01, -3.77425781e+02, 1.46001043e+01, - 2.06437378e+01, -2.54263626e+02, 2.88258545e+02, - 4.34750977e+02, 2.13519592e+02, 3.96897217e+02, - 8.74137115e+01, 7.21976471e+01, 1.45806274e+02, - -1.06001190e+02, 4.55372467e+01, -1.79682510e+02, - 4.84295959e+01, -1.41918839e+02, -1.50270279e+02, - 2.25189957e+02, 1.10319427e+02, -4.35088135e+02, - 5.34815430e+02, 3.42563721e+02, 4.42061523e+02, - 1.75658325e+02, 1.22033813e+02, -2.49562073e+01, - -1.15247650e+02, 3.08883514e+01, -3.12923828e+02, - -1.02068848e+02, -3.29612549e+02, -1.96804504e+02, - -1.12869827e+02, -3.42539062e+02, -2.32903732e+02, - -9.58003235e+01, -7.35217896e+01, -3.16965576e+02, - -1.24462708e+02, -3.18577637e+02, -1.14058228e+02, - -2.69070282e+01, -3.63590851e+01, 6.86552277e+01, - -1.93415085e+02, -3.96717262e+00, -1.63823044e+02, - 6.96005821e-01, -6.39315796e+01, -9.11142426e+01, - -1.09771667e+02, -1.34256149e+02, -1.35531940e+01, - 1.38606615e+01, -1.35011963e+02, 2.22399918e+02, - 3.54877930e+02, 1.22672028e+02, 1.83927261e+02, - 2.95129639e+02, 8.63545532e+01, 2.30139908e+02, - -1.14560532e+02, 6.74462585e+01, 3.10108154e+02, - 9.13583469e+00, 1.77570038e+01, 1.12481117e+01, - -2.94228516e+01, -2.62760925e+01, 7.95001831e+01, - -8.78986206e+01, 1.31246429e+02, 6.75210419e+01}; - - double rgp[g.size()]; - - // perform spectral transform: - spectral_transform_grid(trp1, trp1, g, rspecg, rgp); - - out << "result of grid computation: "; - for( int jm=0; jm{ - {27.9878, 86.9250}, - {27.9878, 86.9250}, - {27.9878, 86.9250} - });*/ - - int trp1 = 4; // truncation - int N = (trp1+2)*(trp1+1)/2; - - double rspecg[2*N]; - double rgp[g.size()], rgp_analytic[g.size()]; - - - // compute analytic solution (this also initializes rspecg and needs to be done before the actual transform): - spectral_transform_grid_analytic(trp1, trp1, g, rspecg, rgp_analytic); - // perform spectral transform: - spectral_transform_grid(trp1, trp1, g, rspecg, rgp); - - out << "result of grid computation: rms-error: "; + int n = 3, m = 3; double rms = 0.; - for( int jm=0; jm Date: Fri, 10 Nov 2017 12:17:16 +0000 Subject: [PATCH 177/355] ATLAS-135 added comparison with trans library. Still need to revert some hacks inside the trans library. --- src/tests/trans/test_transgeneral.cc | 307 +++++++++++++++++---------- 1 file changed, 198 insertions(+), 109 deletions(-) diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 83c90bd80..364a73079 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -77,21 +77,21 @@ struct AtlasTransEnvironment : public AtlasTestEnvironment { // Andreas Mueller *ECMWF* // void compute_legendre( - const size_t knsmax, // truncation + 1 (in) + const size_t trc, // truncation (in) double& lat, // latitude in degree (in) - array::ArrayView& zlfpol)// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) + array::ArrayView& zlfpol)// values of associated Legendre functions, size (trc+1)*trc/2 (out) { std::ostream& out = Log::info(); // just for debugging - array::ArrayT idxmn_(knsmax+1,knsmax+1); + array::ArrayT idxmn_(trc+1,trc+1); array::ArrayView idxmn = make_view(idxmn_); int j = 0; - for( int jm=0; jm<=knsmax; ++jm ) { - for( int jn=jm; jn<=knsmax; ++jn ) { + for( int jm=0; jm<=trc; ++jm ) { + for( int jn=jm; jn<=trc; ++jn ) { idxmn(jm,jn) = j++; } } - array::ArrayT zfn_(knsmax+1,knsmax+1); + array::ArrayT zfn_(trc+1,trc+1); array::ArrayView zfn = make_view(zfn_); int iodd; @@ -99,7 +99,7 @@ void compute_legendre( // Belousov, Swarztrauber use zfn(0,0)=std::sqrt(2.) // IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 zfn(0,0) = 2.; - for( int jn=1; jn<=knsmax; ++jn ) { + for( int jn=1; jn<=trc; ++jn ) { double zfnn = zfn(0,0); for( int jgl=1; jgl<=jn; ++jgl) { zfnn *= std::sqrt(1.-0.25/(jgl*jgl)); @@ -136,7 +136,7 @@ void compute_legendre( // --------------------------------------------------- // even N - for( int jn=2; jn<=knsmax; jn+=2 ) { + for( int jn=2; jn<=trc; jn+=2 ) { double zdlk = 0.5*zfn(jn,0); double zdlldn = 0.0; // represented by only even k @@ -151,7 +151,7 @@ void compute_legendre( } // odd N - for( int jn=1; jn<=knsmax; jn+=2 ) { + for( int jn=1; jn<=trc; jn+=2 ) { double zdlk = 0.5*zfn(jn,0); double zdlldn = 0.0; // represented by only even k @@ -171,7 +171,7 @@ void compute_legendre( // -------------------------------------------------------------- double zdls = zdl1sita*std::numeric_limits::min(); - for( int jn=2; jn<=knsmax; ++jn ) { + for( int jn=2; jn<=trc; ++jn ) { zlfpol(idxmn(jn,jn)) = zlfpol(idxmn(jn-1,jn-1))*zdlsita*std::sqrt((2.*jn+1.)/(2.*jn)); if( std::abs(zlfpol(idxmn(jn,jn))) < zdls ) zlfpol(idxmn(jn,jn)) = 0.0; } @@ -180,7 +180,7 @@ void compute_legendre( // 3. General recurrence (Belousov, equation 17) // --------------------------------------------- - for( int jn=3; jn<=knsmax; ++jn ) { + for( int jn=3; jn<=trc; ++jn ) { for( int jm=2; jm& rlegReal,// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) - array::ArrayView& rlegImag,// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) - array::ArrayView& zlfpol, // values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) - double rspecg[]) // spectral data, size (knsmax+1)*knsmax (in) + const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + array::ArrayView& rlegReal,// values of associated Legendre functions, size (trc+1)*trc/2 (out) + array::ArrayView& rlegImag,// values of associated Legendre functions, size (trc+1)*trc/2 (out) + array::ArrayView& zlfpol, // values of associated Legendre functions, size (trc+1)*trc/2 (out) + double rspecg[]) // spectral data, size (trc+1)*trc (in) { // Legendre transformation: rlegReal.assign(0.); rlegImag.assign(0.); double zfac = 1.; int k = 0; - for( int jm=0; jm<=knsmaxFT; ++jm ) { - for( int jn=jm; jn<=knsmax; ++jn ) { + for( int jm=0; jm<=trcFT; ++jm ) { + for( int jn=jm; jn<=trc; ++jn ) { if( jm>0 ) zfac = 2.; // not completely sure where this zfac comes from. One possible explanation: @@ -234,15 +234,15 @@ void legendre_transform( // Andreas Mueller *ECMWF* // double fourier_transform( - const size_t knsmaxFT, - array::ArrayView& rlegReal,// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) - array::ArrayView& rlegImag,// values of associated Legendre functions, size (knsmax+1)*knsmax/2 (out) + const size_t trcFT, + array::ArrayView& rlegReal,// values of associated Legendre functions, size (trc+1)*trc/2 (out) + array::ArrayView& rlegImag,// values of associated Legendre functions, size (trc+1)*trc/2 (out) double lon) { // local Fourier transformation: // (FFT would be slower when computing the Fourier transformation for a single point) double lonRad = lon * util::Constants::degreesToRadians(), result = 0.; - for( int jm=0; jm<=knsmaxFT; ++jm ) { + for( int jm=0; jm<=trcFT; ++jm ) { result += std::cos(jm*lonRad) * rlegReal(jm) - std::sin(jm*lonRad) * rlegImag(jm); } return result; @@ -256,30 +256,30 @@ double fourier_transform( // Andreas Mueller *ECMWF* // double spectral_transform_point( - const size_t knsmax, // truncation + 1 (in) - const size_t knsmaxFT, // truncation + 1 for Fourier transformation (in) + const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) double lon, // longitude in degree (in) double lat, // latitude in degree (in) - double rspecg[]) // spectral data, size (knsmax+1)*knsmax (in) + double rspecg[]) // spectral data, size (trc+1)*trc (in) { std::ostream& out = Log::info(); // just for debugging - int N = (knsmax+2)*(knsmax+1)/2; + int N = (trc+2)*(trc+1)/2; ATLAS_TRACE(); atlas::array::ArrayT zlfpol_(N); atlas::array::ArrayView zlfpol = make_view(zlfpol_); - atlas::array::ArrayT rlegReal_(knsmaxFT+1); + atlas::array::ArrayT rlegReal_(trcFT+1); atlas::array::ArrayView rlegReal = make_view(rlegReal_); - atlas::array::ArrayT rlegImag_(knsmaxFT+1); + atlas::array::ArrayT rlegImag_(trcFT+1); atlas::array::ArrayView rlegImag = make_view(rlegImag_); // Legendre transform: - compute_legendre(knsmax, lat, zlfpol); - legendre_transform(knsmax, knsmaxFT, rlegReal, rlegImag, zlfpol, rspecg); + compute_legendre(trc, lat, zlfpol); + legendre_transform(trc, trcFT, rlegReal, rlegImag, zlfpol, rspecg); // Fourier transform: - return fourier_transform(knsmaxFT, rlegReal, rlegImag, lon); + return fourier_transform(trcFT, rlegReal, rlegImag, lon); } @@ -292,23 +292,23 @@ double spectral_transform_point( // Andreas Mueller *ECMWF* // void spectral_transform_grid( - const size_t knsmax, // truncation + 1 (in) - const size_t knsmaxFT,// truncation + 1 for Fourier transformation (in) + const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) Grid grid, // call with something like Grid("O32") - double rspecg[], // spectral data, size (knsmax+1)*knsmax (in) + double rspecg[], // spectral data, size (trc+1)*trc (in) double rgp[], // resulting grid point data (out) bool pointwise) // use point function for unstructured mesh for testing purposes { std::ostream& out = Log::info(); // just for debugging - int N = (knsmax+2)*(knsmax+1)/2; + int N = (trc+2)*(trc+1)/2; ATLAS_TRACE(); atlas::array::ArrayT zlfpol_(N); atlas::array::ArrayView zlfpol = make_view(zlfpol_); - atlas::array::ArrayT rlegReal_(knsmaxFT+1); + atlas::array::ArrayT rlegReal_(trcFT+1); atlas::array::ArrayView rlegReal = make_view(rlegReal_); - atlas::array::ArrayT rlegImag_(knsmaxFT+1); + atlas::array::ArrayT rlegImag_(trcFT+1); atlas::array::ArrayView rlegImag = make_view(rlegImag_); for( int jm=0; jm0 ) rft *= 2.; // the famous factor 2 that noone really understands - if( real ) { + if( imag==0 ) { rft *= std::cos(m*lonRad); } else { rft *= -std::sin(m*lonRad); @@ -377,6 +377,8 @@ double sphericalharmonics_analytic( // multiplied with -2*sqrt(pi) due to different normalization and different coordinates): // (can also be computed on http://www.wolframalpha.com with: // LegendreP[n, m, x]/Sqrt[1/2*Integrate[LegendreP[n, m, y]^2, {y, -1, 1}]]) + // n, m need to be replaced by hand with the correct values + // (otherwise the command will be too long for the free version of wolframalpha) if ( m==0 && n==0 ) return rft; if ( m==0 && n==1 ) @@ -394,35 +396,36 @@ double sphericalharmonics_analytic( 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; + return -std::sqrt(105./2.)/2.*latcos*latcos*latsin*rft; if ( m==3 && n==3 ) return std::sqrt(35.)/4.*latcos*latcos*latcos*rft; // shouldn't this be minus? return 0; } +//----------------------------------------------------------------------------- +// Routine to compute the spherical harmonics analytically on a grid +// (up to wave number 3) +// +// Author: +// Andreas Mueller *ECMWF* +// void spectral_transform_grid_analytic( - const size_t knsmax, // truncation + 1 (in) - const size_t knsmaxFT,// truncation + 1 for Fourier transformation (in) + const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) double n, // total wave number (implemented so far for n<4 double m, // zonal wave number (implemented so far for m<4, m 1.e-15 ) out << " !!!!"; + out << std::endl; return rms; } @@ -529,23 +555,21 @@ CASE( "test_transgeneral_point" ) // the result with the analytically computed spherical harmonics Grid g = grid::UnstructuredGrid( new std::vector{ - {20., 50.}, - {-20., 30.}, - {-89., 179.}, - {70., -101.} + { 20., 50.}, + {-20., 30.}, + {-89., 179.}, + { 70., -101.} }); - int trc = 1279; // truncation + int trc = 47; // truncation - int n = 3, m = 3; double rms = 0.; - for( int m=0; m<=3; m++ ) - for( int n=m; n<=3; n++ ) { - rms = spectral_transform_test(trc, n, m, true, g, true); - EXPECT( rms < tolerance ); - rms = spectral_transform_test(trc, n, m, false, g, true); - EXPECT( rms < tolerance ); - } + for( int m=0; m<=3; m++ ) // zonal wavenumber + for( int n=m; n<=3; n++ ) // total wavenumber + for( int imag=0; imag<=1; imag++ ) { // real and imaginary part + rms = spectral_transform_test(trc, n, m, imag, g, true); + //EXPECT( rms < tolerance ); + } } @@ -560,23 +584,21 @@ CASE( "test_transgeneral_unstructured" ) // the result with the analytically computed spherical harmonics Grid g = grid::UnstructuredGrid( new std::vector{ - {20., 50.}, - {-20., 30.}, - {-89., 179.}, - {70., -101.} + { 20., 50.}, + {-20., 30.}, + {-89., 179.}, + { 70., -101.} }); - int trc = 1279; // truncation + int trc = 47; // truncation - int n = 3, m = 3; double rms = 0.; - for( int m=0; m<=3; m++ ) - for( int n=m; n<=3; n++ ) { - rms = spectral_transform_test(trc, n, m, true, g, false); - EXPECT( rms < tolerance ); - rms = spectral_transform_test(trc, n, m, false, g, false); - EXPECT( rms < tolerance ); - } + for( int m=0; m<=3; m++ ) // zonal wavenumber + for( int n=m; n<=3; n++ ) // total wavenumber + for( int imag=0; imag<=1; imag++ ) { // real and imaginary part + rms = spectral_transform_test(trc, n, m, imag, g, false); + //EXPECT( rms < tolerance ); + } } @@ -593,18 +615,85 @@ CASE( "test_transgeneral_structured" ) std::string grid_uid("O10"); grid::StructuredGrid g (grid_uid); - int trc = 1279; // truncation + int trc = 47; // truncation - int n = 3, m = 3; double rms = 0.; - for( int m=0; m<=3; m++ ) - for( int n=m; n<=3; n++ ) { - rms = spectral_transform_test(trc, n, m, true, g, false); - EXPECT( rms < tolerance ); - rms = spectral_transform_test(trc, n, m, false, g, false); - EXPECT( rms < tolerance ); - } + for( int m=0; m<=3; m++ ) // zonal wavenumber + for( int n=m; n<=3; n++ ) // total wavenumber + for( int imag=0; imag<=1; imag++ ) { // real and imaginary part + rms = spectral_transform_test(trc, n, m, imag, g, false); + //EXPECT( rms < tolerance ); + } + +} + +//----------------------------------------------------------------------------- + +CASE( "test_transgeneral_with_translib" ) +{ + Log::info() << "test_transgeneral_with_translib" << std::endl; + // test transgeneral by comparing its result with the trans library + // this test is based on the test_nomesh case in test_trans.cc + + std::ostream& out = Log::info(); + double tolerance = 1.e-15; + Grid g( "O48" ); + int trc = 47; + trans::Trans trans(g,trc) ; + + functionspace::Spectral spectral (trans); + functionspace::StructuredColumns gridpoints (g); + + Field spfg = spectral. createField(option::name("spf") | option::global()); + Field spf = spectral. createField(option::name("spf")); + Field gpf = gridpoints.createField(option::name("gpf")); + Field gpfg = gridpoints.createField(option::name("gpf") | option::global()); + + auto *rgp = new double[g.size()]; + + int k = 0; + for( int m=0; m<=30; m++ ) // zonal wavenumber + for( int n=m; n<=30; n++ ) // total wavenumber + for( int imag=0; imag<=1; imag++ ) { // real and imaginary part + + array::ArrayView spg = array::make_view(spfg); + if( parallel::mpi::comm().rank() == 0 ) { + spg.assign(0.); + spg(2*k+imag) = 1.; + } + + EXPECT_NO_THROW( spectral.scatter(spfg,spf) ); + + if( parallel::mpi::comm().rank() == 0 ) { + array::ArrayView sp = array::make_view(spf); + EXPECT( eckit::types::is_approximately_equal( sp(2*k+imag), 1., 0.001 )); + for( size_t jp=0; jp gpg = array::make_view(gpfg); + + // compute spectral transform with the general transform: + spectral_transform_grid(trc, trc, g, spg.data(), rgp, false); + double rms = compute_rms(g.size(), gpg.data(), rgp); + + out << "m=" << m << " n=" << n << " imag:" << imag << " error:" << rms; + if( rms > tolerance ) out << " !!!!"; + out << std::endl; + //EXPECT( rms < tolerance ); + + } + + k++; + } + delete [] rgp; } //----------------------------------------------------------------------------- From dc0d82c56042a0c16b5eb5275a8fe8e5e94bd115 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Fri, 17 Nov 2017 16:46:43 +0000 Subject: [PATCH 178/355] ATLAS-135 analytic tests work now and test both general transform as well as trans library --- src/tests/trans/test_transgeneral.cc | 102 ++++++++++++++++++--------- 1 file changed, 67 insertions(+), 35 deletions(-) diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 364a73079..d60a1931e 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -384,22 +384,25 @@ double sphericalharmonics_analytic_point( 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; // shouldn't this be minus? + 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; // shouldn't this be minus? + return std::sqrt(7.)/2.*(5.*latsin*latsin-3.)*latsin*rft; // sign? if ( m==1 && n==1 ) - return std::sqrt(3./2.)*latcos*rft; // shouldn't this be minus? + return std::sqrt(3./2.)*latcos*rft; // sign? if ( m==1 && n==2 ) - return std::sqrt(15./2.)*latsin*latcos*rft; // shouldn't this be minus? + 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; // shouldn't this be minus? + 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; + return std::sqrt(15./2.)/2.*latcos*latcos*rft; if ( m==2 && n==3 ) - return -std::sqrt(105./2.)/2.*latcos*latcos*latsin*rft; + return std::sqrt(105./2.)/2.*latcos*latcos*latsin*rft; if ( m==3 && n==3 ) - return std::sqrt(35.)/4.*latcos*latcos*latcos*rft; // shouldn't this be minus? - return 0; + return std::sqrt(35.)/4.*latcos*latcos*latcos*rft; // sign? + if ( m==45 && n==45 ) + return std::pow(latcos,45)*rft*21.*std::sqrt(1339044123748208678378695.)/8796093022208.; // sign? + + return -1.; } //----------------------------------------------------------------------------- @@ -499,14 +502,20 @@ double spectral_transform_test( spectral_transform_grid(trc, trc, g, rspecg, rgp, pointwise); double rms = compute_rms(g.size(), rgp, rgp_analytic); - delete [] rspecg; - delete [] rgp; - delete [] rgp_analytic; out << "m=" << m << " n=" << n << " imag:" << imag << " structured:" << grid::StructuredGrid(g) << " error:" << rms; - if( rms > 1.e-15 ) out << " !!!!"; + if( rms > 1.e-15 ) { + out << " !!!!" << std::endl; + for( int jp=0; jp{ - { 20., 50.}, - {-20., 30.}, - {-89., 179.}, - { 70., -101.} + { 50., 20.}, + { 30., -20.}, + { 179., -89.}, + {-101., 70.} }); int trc = 47; // truncation @@ -584,10 +593,10 @@ CASE( "test_transgeneral_unstructured" ) // the result with the analytically computed spherical harmonics Grid g = grid::UnstructuredGrid( new std::vector{ - { 20., 50.}, - {-20., 30.}, - {-89., 179.}, - { 70., -101.} + { 50., 20.}, + { 30., -20.}, + { 179., -89.}, + {-101., 70.} }); int trc = 47; // truncation @@ -636,8 +645,9 @@ CASE( "test_transgeneral_with_translib" ) // this test is based on the test_nomesh case in test_trans.cc std::ostream& out = Log::info(); - double tolerance = 1.e-15; - Grid g( "O48" ); + double tolerance = 1.e-13; + Grid g( "F24" ); + grid::StructuredGrid gs(g); int trc = 47; trans::Trans trans(g,trc) ; @@ -649,24 +659,27 @@ CASE( "test_transgeneral_with_translib" ) Field gpf = gridpoints.createField(option::name("gpf")); Field gpfg = gridpoints.createField(option::name("gpf") | option::global()); - auto *rgp = new double[g.size()]; + int N = (trc+2)*(trc+1)/2; + auto *rspecg = new double[2*N]; + auto *rgp = new double[g.size()]; + auto *rgp_analytic = new double[g.size()]; int k = 0; - for( int m=0; m<=30; m++ ) // zonal wavenumber - for( int n=m; n<=30; n++ ) // total wavenumber + for( int m=0; m<=trc; m++ ) // zonal wavenumber + for( int n=m; n<=trc; n++ ) // total wavenumber for( int imag=0; imag<=1; imag++ ) { // real and imaginary part array::ArrayView spg = array::make_view(spfg); if( parallel::mpi::comm().rank() == 0 ) { spg.assign(0.); - spg(2*k+imag) = 1.; + spg(k) = 1.; } EXPECT_NO_THROW( spectral.scatter(spfg,spf) ); if( parallel::mpi::comm().rank() == 0 ) { array::ArrayView sp = array::make_view(spf); - EXPECT( eckit::types::is_approximately_equal( sp(2*k+imag), 1., 0.001 )); + EXPECT( eckit::types::is_approximately_equal( sp(k), 1., 0.001 )); for( size_t jp=0; jp gpg = array::make_view(gpfg); + spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg, rgp_analytic); + // compute spectral transform with the general transform: spectral_transform_grid(trc, trc, g, spg.data(), rgp, false); - double rms = compute_rms(g.size(), gpg.data(), rgp); - - out << "m=" << m << " n=" << n << " imag:" << imag << " error:" << rms; - if( rms > tolerance ) out << " !!!!"; - out << std::endl; - //EXPECT( rms < tolerance ); + double rms_trans = compute_rms(g.size(), gpg.data(), rgp); + double rms_gen = compute_rms(g.size(), rgp, rgp_analytic); + + /*int jp = 0; + for( size_t j=0; j Date: Mon, 20 Nov 2017 11:32:40 +0000 Subject: [PATCH 179/355] ATLAS-135 TransLocal class created with only scalar invtrans implemented --- src/atlas/CMakeLists.txt | 2 + src/atlas/trans/Trans.cc | 6 + src/atlas/trans/local/TransLocal.cc | 488 +++++++++++++++++++++++++++ src/atlas/trans/local/TransLocal.h | 130 +++++++ src/tests/trans/test_transgeneral.cc | 18 +- 5 files changed, 643 insertions(+), 1 deletion(-) create mode 100644 src/atlas/trans/local/TransLocal.cc create mode 100644 src/atlas/trans/local/TransLocal.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index f66b0ffa7..85837c0c6 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -320,6 +320,8 @@ numerics/fvm/Nabla.cc trans/Trans.h trans/Trans.cc +trans/local/TransLocal.h +trans/local/TransLocal.cc ) if( ATLAS_HAVE_TRANS ) list( APPEND atlas_numerics_srcs diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index 83284f969..dd788bc95 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -25,6 +25,8 @@ #else #define TRANS_DEFAULT "local" #endif +#include "atlas/trans/local/TransLocal.h" + namespace atlas { namespace trans { @@ -261,6 +263,10 @@ const Grid& Trans::grid() const { return impl_->grid(); } +size_t Trans::spectralCoefficients() const { + return impl_->spectralCoefficients(); +} + void Trans::dirtrans( const Field& gpfield, Field& spfield, const eckit::Configuration& config ) const { diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc new file mode 100644 index 000000000..a2a58fc12 --- /dev/null +++ b/src/atlas/trans/local/TransLocal.cc @@ -0,0 +1,488 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/trans/local/TransLocal.h" + +#include "atlas/array.h" +#include "atlas/runtime/ErrorHandling.h" +#include "atlas/runtime/Log.h" +#include "atlas/parallel/mpi/mpi.h" + +namespace atlas { +namespace trans { + +namespace { +static TransBuilderGrid builder("local"); +} + +// -------------------------------------------------------------------------------------------------------------------- +// Helper functions +// -------------------------------------------------------------------------------------------------------------------- +namespace { // anonymous + +size_t legendre_size( const size_t truncation ) { + return (truncation+2)*(truncation+1)/2; +} + +int fourier_truncation( double truncation, double lat ) { + return truncation; +} + +//----------------------------------------------------------------------------- +// Routine to compute the Legendre polynomials in serial according to Belousov +// (using correction by Swarztrauber) +// +// Reference: +// S.L. Belousov, Tables of normalized associated Legendre Polynomials, Pergamon Press (1962) +// P.N. Swarztrauber, On computing the points and weights for Gauss-Legendre quadrature, +// SIAM J. Sci. Comput. Vol. 24 (3) pp. 945-954 (2002) +// +// Author of Fortran version: +// Mats Hamrud, Philippe Courtier, Nils Wedi *ECMWF* +// +// Ported to C++ by: +// Andreas Mueller *ECMWF* +// +void compute_legendre( + const size_t trc, // truncation (in) + const double lat, // latitude in radians (in) + double zlfpol[] ) // values of associated Legendre functions, size (trc+1)*trc/2 (out) +{ + array::ArrayT idxmn_(trc+1,trc+1); + array::ArrayView idxmn = array::make_view(idxmn_); + int j = 0; + for( int jm=0; jm<=trc; ++jm ) { + for( int jn=jm; jn<=trc; ++jn ) { + idxmn(jm,jn) = j++; + } + } + + array::ArrayT zfn_(trc+1,trc+1); + array::ArrayView zfn = array::make_view(zfn_); + + int iodd; + + // Belousov, Swarztrauber use zfn(0,0)=std::sqrt(2.) + // IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 + zfn(0,0) = 2.; + for( int jn=1; jn<=trc; ++jn ) { + double zfnn = zfn(0,0); + for( int jgl=1; jgl<=jn; ++jgl) { + zfnn *= std::sqrt(1.-0.25/(jgl*jgl)); + } + iodd = jn % 2; + zfn(jn,jn)=zfnn; + for( int jgl=2; jgl<=jn-iodd; jgl+=2 ) { + zfn(jn,jn-jgl) = zfn(jn,jn-jgl+2) * ((jgl-1.)*(2.*jn-jgl+2.)) / (jgl*(2.*jn-jgl+1.)); + } + } + + // -------------------- + // 1. First two columns + // -------------------- + double zdlx1 = (M_PI_2-lat); // theta + double zdlx = std::cos(zdlx1); // cos(theta) + double zdlsita = std::sqrt(1.-zdlx*zdlx); // sin(theta) (this is how trans library does it) + + zlfpol[0] = 1.; + double zdl1sita = 0.; + + // if we are less than 1 meter from the pole, + if( std::abs(zdlsita) <= std::sqrt(std::numeric_limits::epsilon()) ) + { + zdlx = 1.; + zdlsita = 0.; + } else { + zdl1sita = 1./zdlsita; + } + + // ordinary Legendre polynomials from series expansion + // --------------------------------------------------- + + // even N + for( int jn=2; jn<=trc; jn+=2 ) { + double zdlk = 0.5*zfn(jn,0); + double zdlldn = 0.0; + // represented by only even k + for (int jk=2; jk<=jn; jk+=2 ) { + // normalised ordinary Legendre polynomial == \overbar{P_n}^0 + zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); + // normalised associated Legendre polynomial == \overbar{P_n}^1 + zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); + } + zlfpol[idxmn(0,jn)] = zdlk; + zlfpol[idxmn(1,jn)] = zdlldn; + } + + // odd N + for( int jn=1; jn<=trc; jn+=2 ) { + double zdlk = 0.5*zfn(jn,0); + double zdlldn = 0.0; + // represented by only even k + for (int jk=1; jk<=jn; jk+=2 ) { + // normalised ordinary Legendre polynomial == \overbar{P_n}^0 + zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); + // normalised associated Legendre polynomial == \overbar{P_n}^1 + zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); + } + zlfpol[idxmn(0,jn)] = zdlk; + zlfpol[idxmn(1,jn)] = zdlldn; + } + + // -------------------------------------------------------------- + // 2. Diagonal (the terms 0,0 and 1,1 have already been computed) + // Belousov, equation (23) + // -------------------------------------------------------------- + + double zdls = zdl1sita*std::numeric_limits::min(); + for( int jn=2; jn<=trc; ++jn ) { + zlfpol[idxmn(jn,jn)] = zlfpol[idxmn(jn-1,jn-1)]*zdlsita*std::sqrt((2.*jn+1.)/(2.*jn)); + if( std::abs(zlfpol[idxmn(jn,jn)]) < zdls ) zlfpol[idxmn(jn,jn)] = 0.0; + } + + // --------------------------------------------- + // 3. General recurrence (Belousov, equation 17) + // --------------------------------------------- + + for( int jn=3; jn<=trc; ++jn ) { + for( int jm=2; jm0 + rlegReal[jm] += 2. * rspecg[2*k] * zlfpol[k]; + rlegImag[jm] += 2. * rspecg[2*k+1] * zlfpol[k]; + } + } + // Undo factor 2 for (jm == 0) + rlegReal[0] /= 2.; + rlegImag[0] /= 2.; + +} + +//----------------------------------------------------------------------------- +// Routine to compute the local Fourier transformation +// +// Author: +// Andreas Mueller *ECMWF* +// +double fourier_transform( + const size_t trcFT, + const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + const double lon ) // longitude in radians (in) +{ + double result(0); + // local Fourier transformation: + // (FFT would be slower when computing the Fourier transformation for a single point) + for( int jm=0; jm<=trcFT; ++jm ) { + result += std::cos(jm*lon) * rlegReal[jm] - std::sin(jm*lon) * rlegImag[jm]; + } + return result; +} + + +} // namespace anonymous + +// -------------------------------------------------------------------------------------------------------------------- +// Class TransLocal +// -------------------------------------------------------------------------------------------------------------------- + +TransLocal::TransLocal( const Cache& cache, const Grid& grid, const long truncation, const eckit::Configuration& config ) : + grid_(grid), + truncation_(truncation), + precompute_ ( config.getBool("precompute", true) ) +{ + if ( precompute_ ) { + if( grid::StructuredGrid g = grid_ ) { + ATLAS_TRACE("Precompute legendre structured"); + size_t size(0); + legendre_begin_.resize( g.ny() ); + for( size_t j=0; j recomputed_legendre_; + + auto legPol = [&](double lat, int j) { + if( precompute_ ) { + return legendre_data(j); + } else { + recomputed_legendre_.resize( legendre_size( truncation_ ) ); + compute_legendre( truncation_, lat, recomputed_legendre_.data() ); + return recomputed_legendre_.data(); + } + }; + + // Temporary storage for legendre space + std::vector legReal(truncation_+1); + std::vector legImag(truncation_+1); + + // Transform + if( grid::StructuredGrid g = grid_ ) { + ATLAS_TRACE( "invtrans structured"); + int idx = 0; + for( size_t j=0; j +#include "atlas/grid/Grid.h" +#include "atlas/trans/Trans.h" + +//----------------------------------------------------------------------------- +// Forward declarations + +namespace atlas { + class Field; + class FieldSet; +} + +//----------------------------------------------------------------------------- + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +/// @class TransLocal +/// +/// Local spherical harmonics transformations to any grid +/// Optimisations are present for structured grids +/// For global grids, please consider using TransIFS instead. +/// +/// @todo: +/// - support multiple fields +/// - support atlas::Field and atlas::FieldSet based on function spaces +/// +/// @note: Direct transforms are not implemented and cannot be unless +/// the grid is global. There are no plans to support this at the moment. +class TransLocal : public trans::TransImpl { + +public: + + TransLocal( const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); + TransLocal( const Cache&, const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); + + virtual ~TransLocal(); + + virtual int truncation() const { return truncation_; } + virtual size_t spectralCoefficients() const { return (truncation_+1)*(truncation_+2); } + + virtual const Grid& grid() const { return grid_; } + + + virtual void invtrans( const Field& spfield, + Field& gpfield, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void invtrans( const FieldSet& spfields, + FieldSet& gpfields, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void invtrans_grad( const Field& spfield, + Field& gradfield, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void invtrans_grad( const FieldSet& spfields, + FieldSet& gradfields, + const eckit::Configuration& = util::NoConfig() ) const override; + + + virtual void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, + Field& gpwind, + const eckit::Configuration& = util::NoConfig() ) const override; + +// -- IFS style API -- + + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], + const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], + double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; + +// -- NOT SUPPORTED -- // + + virtual void dirtrans( const Field& gpfield, + Field& spfield, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void dirtrans( const FieldSet& gpfields, + FieldSet& spfields, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void dirtrans_wind2vordiv( const Field& gpwind, + Field& spvor, Field& spdiv, + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& = util::NoConfig() ) const override; + + virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], + const eckit::Configuration& = util::NoConfig() ) const override; + +private: + + double* legendre_data( int j ) { return legendre_.data() + legendre_begin_[j]; } + +private: + int truncation_; + Grid grid_; + bool precompute_; + std::vector legendre_; + std::vector legendre_begin_; +}; + +//----------------------------------------------------------------------------- + +} // namespace trans +} // namespace atlas diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index d60a1931e..c28831f07 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -262,7 +262,6 @@ double spectral_transform_point( double lat, // latitude in degree (in) double rspecg[]) // spectral data, size (trc+1)*trc (in) { - std::ostream& out = Log::info(); // just for debugging int N = (trc+2)*(trc+1)/2; ATLAS_TRACE(); atlas::array::ArrayT zlfpol_(N); @@ -730,6 +729,23 @@ CASE( "test_transgeneral_with_translib" ) //----------------------------------------------------------------------------- +CASE( "test_trans_invtrans" ) { + + trans::Trans trans( Grid("O64"), 63, util::Config("type","local") ); + + std::ostream& out = Log::info(); + std::vector rspec(trans.spectralCoefficients()); + std::vector rgp(trans.grid().size()); + + + // TODO: rspec needs proper initial data + + trans.invtrans(1,rspec.data(),rgp.data()); + +} + +//----------------------------------------------------------------------------- + } // namespace test } // namespace atlas From be28ca80616cd1d3cc37b96e81dd39f165496a52 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 20 Nov 2017 13:49:46 +0000 Subject: [PATCH 180/355] ATLAS-135 delegate test routines to library functions --- src/atlas/CMakeLists.txt | 6 + src/atlas/trans/local/FourierTransforms.cc | 37 ++++ src/atlas/trans/local/FourierTransforms.h | 34 +++ src/atlas/trans/local/LegendrePolynomials.cc | 138 ++++++++++++ src/atlas/trans/local/LegendrePolynomials.h | 41 ++++ src/atlas/trans/local/LegendreTransforms.cc | 49 +++++ src/atlas/trans/local/LegendreTransforms.h | 35 ++++ src/atlas/trans/local/TransLocal.cc | 201 +----------------- src/tests/trans/test_transgeneral.cc | 209 +++---------------- 9 files changed, 379 insertions(+), 371 deletions(-) create mode 100644 src/atlas/trans/local/FourierTransforms.cc create mode 100644 src/atlas/trans/local/FourierTransforms.h create mode 100644 src/atlas/trans/local/LegendrePolynomials.cc create mode 100644 src/atlas/trans/local/LegendrePolynomials.h create mode 100644 src/atlas/trans/local/LegendreTransforms.cc create mode 100644 src/atlas/trans/local/LegendreTransforms.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 85837c0c6..4342f1de7 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -322,6 +322,12 @@ trans/Trans.h trans/Trans.cc trans/local/TransLocal.h trans/local/TransLocal.cc +trans/local/LegendrePolynomials.h +trans/local/LegendrePolynomials.cc +trans/local/LegendreTransforms.h +trans/local/LegendreTransforms.cc +trans/local/FourierTransforms.h +trans/local/FourierTransforms.cc ) if( ATLAS_HAVE_TRANS ) list( APPEND atlas_numerics_srcs diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc new file mode 100644 index 000000000..e30b3949d --- /dev/null +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -0,0 +1,37 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/trans/local/FourierTransforms.h" + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +double invtrans_fourier( + const size_t trcFT, + const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + const double lon ) // longitude in radians (in) +{ + double result(0); + // local Fourier transformation: + // (FFT would be slower when computing the Fourier transformation for a single point) + for( int jm=0; jm<=trcFT; ++jm ) { + result += std::cos(jm*lon) * rlegReal[jm] - std::sin(jm*lon) * rlegImag[jm]; + } + return result; +} + +// -------------------------------------------------------------------------------------------------------------------- + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/FourierTransforms.h b/src/atlas/trans/local/FourierTransforms.h new file mode 100644 index 000000000..51b4f09bd --- /dev/null +++ b/src/atlas/trans/local/FourierTransforms.h @@ -0,0 +1,34 @@ +/* + * (C) Copyright 1996-2017 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 + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- +// Routine to compute the local Fourier transformation +// +// Author: +// Andreas Mueller *ECMWF* +// +double invtrans_fourier( + const size_t trcFT, + const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + const double lon ); // longitude in radians (in) + + +// -------------------------------------------------------------------------------------------------------------------- + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc new file mode 100644 index 000000000..4b3cc0472 --- /dev/null +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -0,0 +1,138 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/trans/local/LegendrePolynomials.h" +#include "atlas/array.h" + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +void compute_legendre_polynomials( + const size_t trc, // truncation (in) + const double lat, // latitude in radians (in) + double legpol[] ) // values of associated Legendre functions, size (trc+1)*trc/2 (out) +{ + array::ArrayT idxmn_(trc+1,trc+1); + array::ArrayView idxmn = array::make_view(idxmn_); + int j = 0; + for( int jm=0; jm<=trc; ++jm ) { + for( int jn=jm; jn<=trc; ++jn ) { + idxmn(jm,jn) = j++; + } + } + + array::ArrayT zfn_(trc+1,trc+1); + array::ArrayView zfn = array::make_view(zfn_); + + int iodd; + + // Belousov, Swarztrauber use zfn(0,0)=std::sqrt(2.) + // IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 + zfn(0,0) = 2.; + for( int jn=1; jn<=trc; ++jn ) { + double zfnn = zfn(0,0); + for( int jgl=1; jgl<=jn; ++jgl) { + zfnn *= std::sqrt(1.-0.25/(jgl*jgl)); + } + iodd = jn % 2; + zfn(jn,jn)=zfnn; + for( int jgl=2; jgl<=jn-iodd; jgl+=2 ) { + zfn(jn,jn-jgl) = zfn(jn,jn-jgl+2) * ((jgl-1.)*(2.*jn-jgl+2.)) / (jgl*(2.*jn-jgl+1.)); + } + } + + // -------------------- + // 1. First two columns + // -------------------- + double zdlx1 = (M_PI_2-lat); // theta + double zdlx = std::cos(zdlx1); // cos(theta) + double zdlsita = std::sqrt(1.-zdlx*zdlx); // sin(theta) (this is how trans library does it) + + legpol[0] = 1.; + double zdl1sita = 0.; + + // if we are less than 1 meter from the pole, + if( std::abs(zdlsita) <= std::sqrt(std::numeric_limits::epsilon()) ) + { + zdlx = 1.; + zdlsita = 0.; + } else { + zdl1sita = 1./zdlsita; + } + + // ordinary Legendre polynomials from series expansion + // --------------------------------------------------- + + // even N + for( int jn=2; jn<=trc; jn+=2 ) { + double zdlk = 0.5*zfn(jn,0); + double zdlldn = 0.0; + // represented by only even k + for (int jk=2; jk<=jn; jk+=2 ) { + // normalised ordinary Legendre polynomial == \overbar{P_n}^0 + zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); + // normalised associated Legendre polynomial == \overbar{P_n}^1 + zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); + } + legpol[idxmn(0,jn)] = zdlk; + legpol[idxmn(1,jn)] = zdlldn; + } + + // odd N + for( int jn=1; jn<=trc; jn+=2 ) { + double zdlk = 0.5*zfn(jn,0); + double zdlldn = 0.0; + // represented by only even k + for (int jk=1; jk<=jn; jk+=2 ) { + // normalised ordinary Legendre polynomial == \overbar{P_n}^0 + zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); + // normalised associated Legendre polynomial == \overbar{P_n}^1 + zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); + } + legpol[idxmn(0,jn)] = zdlk; + legpol[idxmn(1,jn)] = zdlldn; + } + + // -------------------------------------------------------------- + // 2. Diagonal (the terms 0,0 and 1,1 have already been computed) + // Belousov, equation (23) + // -------------------------------------------------------------- + + double zdls = zdl1sita*std::numeric_limits::min(); + for( int jn=2; jn<=trc; ++jn ) { + legpol[idxmn(jn,jn)] = legpol[idxmn(jn-1,jn-1)]*zdlsita*std::sqrt((2.*jn+1.)/(2.*jn)); + if( std::abs(legpol[idxmn(jn,jn)]) < zdls ) legpol[idxmn(jn,jn)] = 0.0; + } + + // --------------------------------------------- + // 3. General recurrence (Belousov, equation 17) + // --------------------------------------------- + + for( int jn=3; jn<=trc; ++jn ) { + for( int jm=2; jm + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- +// Routine to compute the Legendre polynomials in serial according to Belousov +// (using correction by Swarztrauber) +// +// Reference: +// S.L. Belousov, Tables of normalized associated Legendre Polynomials, Pergamon Press (1962) +// P.N. Swarztrauber, On computing the points and weights for Gauss-Legendre quadrature, +// SIAM J. Sci. Comput. Vol. 24 (3) pp. 945-954 (2002) +// +// Author of Fortran version: +// Mats Hamrud, Philippe Courtier, Nils Wedi *ECMWF* +// +// Ported to C++ by: +// Andreas Mueller *ECMWF* +// +void compute_legendre_polynomials( + const size_t trc, // truncation (in) + const double lat, // latitude in radians (in) + double legpol[] ); // values of associated Legendre functions, size (trc+1)*trc/2 (out) + +// -------------------------------------------------------------------------------------------------------------------- + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/LegendreTransforms.cc b/src/atlas/trans/local/LegendreTransforms.cc new file mode 100644 index 000000000..ddf5649ad --- /dev/null +++ b/src/atlas/trans/local/LegendreTransforms.cc @@ -0,0 +1,49 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/trans/local/LegendreTransforms.h" + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +void invtrans_legendre( + const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + const double legpol[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) + const double spec[], // spectral data, size (trc+1)*trc (in) + double leg_real[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + double leg_imag[] ) // values of associated Legendre functions, size (trc+1)*trc/2 (out) +{ + // Legendre transformation: + int k = 0; + for( int jm=0; jm<=trcFT; ++jm ) { + leg_real[jm] = 0.; + leg_imag[jm] = 0.; + for( int jn=jm; jn<=trc; ++jn, ++k ) { + // not completely sure where this factor 2 comes from. One possible explanation: + // normalization of trigonometric functions in the spherical harmonics + // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 + leg_real[jm] += 2. * spec[2*k] * legpol[k]; + leg_imag[jm] += 2. * spec[2*k+1] * legpol[k]; + } + } + // Undo factor 2 for (jm == 0) + leg_real[0] /= 2.; + leg_imag[0] /= 2.; + +} + +// -------------------------------------------------------------------------------------------------------------------- + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/LegendreTransforms.h b/src/atlas/trans/local/LegendreTransforms.h new file mode 100644 index 000000000..ddd3bd722 --- /dev/null +++ b/src/atlas/trans/local/LegendreTransforms.h @@ -0,0 +1,35 @@ +/* + * (C) Copyright 1996-2017 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 + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- +// Routine to compute the Legendre transformation +// +// Author: +// Andreas Mueller *ECMWF* +// +void invtrans_legendre( + const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + const double legpol[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) + const double spec[], // spectral data, size (trc+1)*trc (in) + double leg_real[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + double leg_imag[] ); // values of associated Legendre functions, size (trc+1)*trc/2 (out) + +// -------------------------------------------------------------------------------------------------------------------- + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index a2a58fc12..ef8bc5d2a 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -14,6 +14,9 @@ #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/trans/local/FourierTransforms.h" +#include "atlas/trans/local/LegendreTransforms.h" +#include "atlas/trans/local/LegendrePolynomials.h" namespace atlas { namespace trans { @@ -35,190 +38,6 @@ int fourier_truncation( double truncation, double lat ) { return truncation; } -//----------------------------------------------------------------------------- -// Routine to compute the Legendre polynomials in serial according to Belousov -// (using correction by Swarztrauber) -// -// Reference: -// S.L. Belousov, Tables of normalized associated Legendre Polynomials, Pergamon Press (1962) -// P.N. Swarztrauber, On computing the points and weights for Gauss-Legendre quadrature, -// SIAM J. Sci. Comput. Vol. 24 (3) pp. 945-954 (2002) -// -// Author of Fortran version: -// Mats Hamrud, Philippe Courtier, Nils Wedi *ECMWF* -// -// Ported to C++ by: -// Andreas Mueller *ECMWF* -// -void compute_legendre( - const size_t trc, // truncation (in) - const double lat, // latitude in radians (in) - double zlfpol[] ) // values of associated Legendre functions, size (trc+1)*trc/2 (out) -{ - array::ArrayT idxmn_(trc+1,trc+1); - array::ArrayView idxmn = array::make_view(idxmn_); - int j = 0; - for( int jm=0; jm<=trc; ++jm ) { - for( int jn=jm; jn<=trc; ++jn ) { - idxmn(jm,jn) = j++; - } - } - - array::ArrayT zfn_(trc+1,trc+1); - array::ArrayView zfn = array::make_view(zfn_); - - int iodd; - - // Belousov, Swarztrauber use zfn(0,0)=std::sqrt(2.) - // IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 - zfn(0,0) = 2.; - for( int jn=1; jn<=trc; ++jn ) { - double zfnn = zfn(0,0); - for( int jgl=1; jgl<=jn; ++jgl) { - zfnn *= std::sqrt(1.-0.25/(jgl*jgl)); - } - iodd = jn % 2; - zfn(jn,jn)=zfnn; - for( int jgl=2; jgl<=jn-iodd; jgl+=2 ) { - zfn(jn,jn-jgl) = zfn(jn,jn-jgl+2) * ((jgl-1.)*(2.*jn-jgl+2.)) / (jgl*(2.*jn-jgl+1.)); - } - } - - // -------------------- - // 1. First two columns - // -------------------- - double zdlx1 = (M_PI_2-lat); // theta - double zdlx = std::cos(zdlx1); // cos(theta) - double zdlsita = std::sqrt(1.-zdlx*zdlx); // sin(theta) (this is how trans library does it) - - zlfpol[0] = 1.; - double zdl1sita = 0.; - - // if we are less than 1 meter from the pole, - if( std::abs(zdlsita) <= std::sqrt(std::numeric_limits::epsilon()) ) - { - zdlx = 1.; - zdlsita = 0.; - } else { - zdl1sita = 1./zdlsita; - } - - // ordinary Legendre polynomials from series expansion - // --------------------------------------------------- - - // even N - for( int jn=2; jn<=trc; jn+=2 ) { - double zdlk = 0.5*zfn(jn,0); - double zdlldn = 0.0; - // represented by only even k - for (int jk=2; jk<=jn; jk+=2 ) { - // normalised ordinary Legendre polynomial == \overbar{P_n}^0 - zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); - // normalised associated Legendre polynomial == \overbar{P_n}^1 - zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); - } - zlfpol[idxmn(0,jn)] = zdlk; - zlfpol[idxmn(1,jn)] = zdlldn; - } - - // odd N - for( int jn=1; jn<=trc; jn+=2 ) { - double zdlk = 0.5*zfn(jn,0); - double zdlldn = 0.0; - // represented by only even k - for (int jk=1; jk<=jn; jk+=2 ) { - // normalised ordinary Legendre polynomial == \overbar{P_n}^0 - zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); - // normalised associated Legendre polynomial == \overbar{P_n}^1 - zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); - } - zlfpol[idxmn(0,jn)] = zdlk; - zlfpol[idxmn(1,jn)] = zdlldn; - } - - // -------------------------------------------------------------- - // 2. Diagonal (the terms 0,0 and 1,1 have already been computed) - // Belousov, equation (23) - // -------------------------------------------------------------- - - double zdls = zdl1sita*std::numeric_limits::min(); - for( int jn=2; jn<=trc; ++jn ) { - zlfpol[idxmn(jn,jn)] = zlfpol[idxmn(jn-1,jn-1)]*zdlsita*std::sqrt((2.*jn+1.)/(2.*jn)); - if( std::abs(zlfpol[idxmn(jn,jn)]) < zdls ) zlfpol[idxmn(jn,jn)] = 0.0; - } - - // --------------------------------------------- - // 3. General recurrence (Belousov, equation 17) - // --------------------------------------------- - - for( int jn=3; jn<=trc; ++jn ) { - for( int jm=2; jm0 - rlegReal[jm] += 2. * rspecg[2*k] * zlfpol[k]; - rlegImag[jm] += 2. * rspecg[2*k+1] * zlfpol[k]; - } - } - // Undo factor 2 for (jm == 0) - rlegReal[0] /= 2.; - rlegImag[0] /= 2.; - -} - -//----------------------------------------------------------------------------- -// Routine to compute the local Fourier transformation -// -// Author: -// Andreas Mueller *ECMWF* -// -double fourier_transform( - const size_t trcFT, - const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) - const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) - const double lon ) // longitude in radians (in) -{ - double result(0); - // local Fourier transformation: - // (FFT would be slower when computing the Fourier transformation for a single point) - for( int jm=0; jm<=trcFT; ++jm ) { - result += std::cos(jm*lon) * rlegReal[jm] - std::sin(jm*lon) * rlegImag[jm]; - } - return result; -} - - } // namespace anonymous // -------------------------------------------------------------------------------------------------------------------- @@ -243,7 +62,7 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const long truncat for( size_t j=0; j& zlfpol)// values of associated Legendre functions, size (trc+1)*trc/2 (out) { - std::ostream& out = Log::info(); // just for debugging - array::ArrayT idxmn_(trc+1,trc+1); - array::ArrayView idxmn = make_view(idxmn_); - int j = 0; - for( int jm=0; jm<=trc; ++jm ) { - for( int jn=jm; jn<=trc; ++jn ) { - idxmn(jm,jn) = j++; - } - } - - array::ArrayT zfn_(trc+1,trc+1); - array::ArrayView zfn = make_view(zfn_); - - int iodd; - - // Belousov, Swarztrauber use zfn(0,0)=std::sqrt(2.) - // IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 - zfn(0,0) = 2.; - for( int jn=1; jn<=trc; ++jn ) { - double zfnn = zfn(0,0); - for( int jgl=1; jgl<=jn; ++jgl) { - zfnn *= std::sqrt(1.-0.25/(jgl*jgl)); - } - iodd = jn % 2; - zfn(jn,jn)=zfnn; - for( int jgl=2; jgl<=jn-iodd; jgl+=2 ) { - zfn(jn,jn-jgl) = zfn(jn,jn-jgl+2) * ((jgl-1.)*(2.*jn-jgl+2.)) / (jgl*(2.*jn-jgl+1.)); - } - } - - zlfpol.assign(0.); // just for debugging (shouldn't be necessary because not in trans library) - - // -------------------- - // 1. First two columns - // -------------------- - double zdlx1 = (90.-lat)*util::Constants::degreesToRadians(); // theta - double zdlx = std::cos(zdlx1); // cos(theta) - double zdlsita = std::sqrt(1.-zdlx*zdlx); // sin(theta) (this is how trans library does it) - - zlfpol(0,0) = 1.; - double zdl1sita = 0.; - - // if we are less than 1 meter from the pole, - if( std::abs(zdlsita) <= std::sqrt(std::numeric_limits::epsilon()) ) - { - zdlx = 1.; - zdlsita = 0.; - } else { - zdl1sita = 1./zdlsita; - } - - // ordinary Legendre polynomials from series expansion - // --------------------------------------------------- - - // even N - for( int jn=2; jn<=trc; jn+=2 ) { - double zdlk = 0.5*zfn(jn,0); - double zdlldn = 0.0; - // represented by only even k - for (int jk=2; jk<=jn; jk+=2 ) { - // normalised ordinary Legendre polynomial == \overbar{P_n}^0 - zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); - // normalised associated Legendre polynomial == \overbar{P_n}^1 - zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); - } - zlfpol(idxmn(0,jn)) = zdlk; - zlfpol(idxmn(1,jn)) = zdlldn; - } - - // odd N - for( int jn=1; jn<=trc; jn+=2 ) { - double zdlk = 0.5*zfn(jn,0); - double zdlldn = 0.0; - // represented by only even k - for (int jk=1; jk<=jn; jk+=2 ) { - // normalised ordinary Legendre polynomial == \overbar{P_n}^0 - zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); - // normalised associated Legendre polynomial == \overbar{P_n}^1 - zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); - } - zlfpol(idxmn(0,jn)) = zdlk; - zlfpol(idxmn(1,jn)) = zdlldn; - } - - // -------------------------------------------------------------- - // 2. Diagonal (the terms 0,0 and 1,1 have already been computed) - // Belousov, equation (23) - // -------------------------------------------------------------- - - double zdls = zdl1sita*std::numeric_limits::min(); - for( int jn=2; jn<=trc; ++jn ) { - zlfpol(idxmn(jn,jn)) = zlfpol(idxmn(jn-1,jn-1))*zdlsita*std::sqrt((2.*jn+1.)/(2.*jn)); - if( std::abs(zlfpol(idxmn(jn,jn))) < zdls ) zlfpol(idxmn(jn,jn)) = 0.0; - } - - // --------------------------------------------- - // 3. General recurrence (Belousov, equation 17) - // --------------------------------------------- - - for( int jn=3; jn<=trc; ++jn ) { - for( int jm=2; jm& zlfpol, // values of associated Legendre functions, size (trc+1)*trc/2 (out) double rspecg[]) // spectral data, size (trc+1)*trc (in) { - // Legendre transformation: - rlegReal.assign(0.); rlegImag.assign(0.); - double zfac = 1.; - int k = 0; - for( int jm=0; jm<=trcFT; ++jm ) { - for( int jn=jm; jn<=trc; ++jn ) { - if( jm>0 ) zfac = 2.; - - // not completely sure where this zfac comes from. One possible explanation: - // normalization of trigonometric functions in the spherical harmonics - // integral over square of trig function is 1 for m=0 and 0.5 (?) for m>0 - rlegReal[jm] += rspecg[2*k] * zfac * zlfpol(k); - rlegImag[jm] += rspecg[2*k+1] * zfac * zlfpol(k); - //Log::info() << zfac * zlfpol(k) << std::endl; // just for debugging - k++; - } - } + trans::invtrans_legendre( trc, trcFT, zlfpol.data(), rspecg, rlegReal.data(), rlegImag.data() ); } //----------------------------------------------------------------------------- -// Routine to compute the local Fourier transformation -// -// Author: -// Andreas Mueller *ECMWF* -// + double fourier_transform( const size_t trcFT, array::ArrayView& rlegReal,// values of associated Legendre functions, size (trc+1)*trc/2 (out) array::ArrayView& rlegImag,// values of associated Legendre functions, size (trc+1)*trc/2 (out) - double lon) + double lon) // radians { - // local Fourier transformation: - // (FFT would be slower when computing the Fourier transformation for a single point) - double lonRad = lon * util::Constants::degreesToRadians(), result = 0.; - for( int jm=0; jm<=trcFT; ++jm ) { - result += std::cos(jm*lonRad) * rlegReal(jm) - std::sin(jm*lonRad) * rlegImag(jm); - } - return result; + return trans::invtrans_fourier( trcFT, rlegReal.data(), rlegImag.data(), lon ); } //----------------------------------------------------------------------------- @@ -258,8 +108,8 @@ double fourier_transform( double spectral_transform_point( const size_t trc, // truncation (in) const size_t trcFT, // truncation for Fourier transformation (in) - double lon, // longitude in degree (in) - double lat, // latitude in degree (in) + double lon, // longitude in radians (in) + double lat, // latitude in radians (in) double rspecg[]) // spectral data, size (trc+1)*trc (in) { int N = (trc+2)*(trc+1)/2; @@ -316,14 +166,14 @@ void spectral_transform_grid( grid::StructuredGrid g(grid); int idx = 0; for( size_t j=0; j0 ) rft *= 2.; // the famous factor 2 that noone really understands if( imag==0 ) { - rft *= std::cos(m*lonRad); + rft *= std::cos(m*lon); } else { - rft *= -std::sin(m*lonRad); + rft *= -std::sin(m*lon); } // Legendre part of the spherical harmonics (following http://mathworld.wolfram.com/SphericalHarmonic.html // multiplied with -2*sqrt(pi) due to different normalization and different coordinates): @@ -437,10 +286,10 @@ void spectral_transform_grid_analytic( grid::StructuredGrid g(grid); int idx = 0; for( size_t j=0; j zlfpol_(N); atlas::array::ArrayView zlfpol = make_view(zlfpol_); - double lat = 50.; - lat = std::acos(0.99312859918509488)*util::Constants::radiansToDegrees(); + double lat = std::acos(0.99312859918509488); compute_legendre(trc, lat, zlfpol); /* out << "zlfpol after compute legendre:" << std::endl; @@ -700,10 +549,10 @@ CASE( "test_transgeneral_with_translib" ) /*int jp = 0; for( size_t j=0; j Date: Mon, 20 Nov 2017 17:42:42 +0000 Subject: [PATCH 181/355] ATLAS-135 Fix Spectral functionspace bug --- src/atlas/functionspace/Spectral.cc | 8 +- src/atlas/functionspace/Spectral.h | 7 +- src/tests/trans/test_trans.cc | 4 +- src/tests/trans/test_trans_invtrans_grad.cc | 2 +- src/tests/trans/test_transgeneral.cc | 95 ++++++++++----------- 5 files changed, 57 insertions(+), 59 deletions(-) diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index d247c0478..e0d45751f 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -130,10 +130,10 @@ Spectral::Spectral( const int truncation, const eckit::Configuration& config ) : config.get("levels",nb_levels_); } -Spectral::Spectral( trans::TransImpl& trans, const eckit::Configuration& config ) : +Spectral::Spectral( const trans::Trans& trans, const eckit::Configuration& config ) : truncation_(trans.truncation()), #ifdef ATLAS_HAVE_TRANS - parallelisation_( new Parallelisation( dynamic_cast(trans).trans_) ), + parallelisation_( new Parallelisation( dynamic_cast(*trans.get()).trans_) ), #else parallelisation_( new Parallelisation(truncation_) ), #endif @@ -379,7 +379,7 @@ Spectral::Spectral( const size_t truncation, const eckit::Configuration& config functionspace_( dynamic_cast< const detail::Spectral* >( get() ) ) { } -Spectral::Spectral( trans::TransImpl& trans, const eckit::Configuration& config ) : +Spectral::Spectral( const trans::Trans& trans, const eckit::Configuration& config ) : FunctionSpace( new detail::Spectral(trans,config) ), functionspace_( dynamic_cast< const detail::Spectral* >( get() ) ) { } @@ -449,7 +449,7 @@ const detail::Spectral* atlas__SpectralFunctionSpace__new__config ( const eckit: const detail::Spectral* atlas__SpectralFunctionSpace__new__trans (trans::TransImpl* trans, const eckit::Configuration* config ) { ATLAS_ERROR_HANDLING( - return new detail::Spectral(*trans,*config); + return new detail::Spectral(trans::Trans(trans),*config); ); return 0; } diff --git a/src/atlas/functionspace/Spectral.h b/src/atlas/functionspace/Spectral.h index 5b855697f..ac50cc998 100644 --- a/src/atlas/functionspace/Spectral.h +++ b/src/atlas/functionspace/Spectral.h @@ -22,6 +22,7 @@ namespace atlas { namespace atlas { namespace trans { + class Trans; class TransImpl; } } @@ -38,9 +39,9 @@ class Spectral : public FunctionSpaceImpl Spectral( const eckit::Configuration& ); - Spectral(const int truncation, const eckit::Configuration& = util::NoConfig() ); + Spectral( const int truncation, const eckit::Configuration& = util::NoConfig() ); - Spectral(trans::TransImpl&, const eckit::Configuration& = util::NoConfig() ); + Spectral( const trans::Trans&, const eckit::Configuration& = util::NoConfig() ); virtual ~Spectral(); @@ -100,7 +101,7 @@ class Spectral : public FunctionSpace { Spectral( const FunctionSpace& ); Spectral( const eckit::Configuration& ); Spectral( const size_t truncation, const eckit::Configuration& = util::NoConfig() ); - Spectral( trans::TransImpl&, const eckit::Configuration& = util::NoConfig() ); + Spectral( const trans::Trans&, const eckit::Configuration& = util::NoConfig() ); operator bool() const { return valid(); } bool valid() const { return functionspace_; } diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 3266f314f..1078a385e 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -312,7 +312,7 @@ CASE( "test_spectral_fields" ) ); Mesh m = generate( g ); - trans::TransIFS trans(g,47); + trans::Trans trans(g,47); functionspace::NodeColumns nodal (m); @@ -342,7 +342,7 @@ CASE( "test_nomesh" ) Log::info() << "test_spectral_fields" << std::endl; Grid g( "O48" ); - trans::TransIFS trans(g,47) ; + trans::Trans trans(g,47) ; functionspace::Spectral spectral (trans); functionspace::StructuredColumns gridpoints (g); diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index 6f355b3ba..3c4218b2e 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -157,7 +157,7 @@ CASE( "test_invtrans_grad" ) grid::StructuredGrid g ( grid_uid ); Mesh mesh = meshgenerator::StructuredMeshGenerator().generate(g); long N = g.ny()/2; - trans::TransIFS trans(g, 2*N-1); + trans::Trans trans(g, 2*N-1); functionspace::NodeColumns gp(mesh); functionspace::Spectral sp(trans); diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 22b09fbfb..c15f3e747 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -508,72 +508,71 @@ CASE( "test_transgeneral_with_translib" ) Field gpfg = gridpoints.createField(option::name("gpf") | option::global()); int N = (trc+2)*(trc+1)/2; - auto *rspecg = new double[2*N]; - auto *rgp = new double[g.size()]; - auto *rgp_analytic = new double[g.size()]; + std::vector rspecg (2*N); + std::vector rgp (g.size()); + std::vector rgp_analytic (g.size()); + + ASSERT( 2*N == spectral.nb_spectral_coefficients_global() ); int k = 0; - for( int m=0; m<=trc; m++ ) // zonal wavenumber - for( int n=m; n<=trc; n++ ) // total wavenumber + for( int m=0; m<=trc; m++ ) { // zonal wavenumber + for( int n=m; n<=trc; n++ ) { // total wavenumber for( int imag=0; imag<=1; imag++ ) { // real and imaginary part - array::ArrayView spg = array::make_view(spfg); - if( parallel::mpi::comm().rank() == 0 ) { - spg.assign(0.); - spg(k) = 1.; - } + if( sphericalharmonics_analytic_point(n, m, true, 0., 0.) == 0. ) { - EXPECT_NO_THROW( spectral.scatter(spfg,spf) ); + ATLAS_DEBUG_VAR( k ); + array::ArrayView spg = array::make_view(spfg); + if( parallel::mpi::comm().rank() == 0 ) { + spg.assign(0.); + spg(k) = 1.; + } - if( parallel::mpi::comm().rank() == 0 ) { - array::ArrayView sp = array::make_view(spf); - EXPECT( eckit::types::is_approximately_equal( sp(k), 1., 0.001 )); - for( size_t jp=0; jp sp = array::make_view(spf); + EXPECT( eckit::types::is_approximately_equal( sp(k), 1., 0.001 )); + for( size_t jp=0; jp gpg = array::make_view(gpfg); + array::ArrayView gpg = array::make_view(gpfg); - spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg, rgp_analytic); + spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data()); - // compute spectral transform with the general transform: - spectral_transform_grid(trc, trc, g, spg.data(), rgp, false); - double rms_trans = compute_rms(g.size(), gpg.data(), rgp); - double rms_gen = compute_rms(g.size(), rgp, rgp_analytic); + // compute spectral transform with the general transform: + spectral_transform_grid(trc, trc, g, spg.data(), rgp.data(), false); - /*int jp = 0; - for( size_t j=0; j rspec(trans.spectralCoefficients()); std::vector rgp(trans.grid().size()); - // TODO: rspec needs proper initial data trans.invtrans(1,rspec.data(),rgp.data()); From 5d7a845fec5a04a67d81f83fdb14972f93a06c2f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 20 Nov 2017 18:10:51 +0000 Subject: [PATCH 182/355] ATLAS-135 Fix compilation --- src/atlas/trans/ifs/TransIFS.h | 6 +++--- src/atlas/trans/local/TransLocal.cc | 2 +- src/atlas/trans/local/TransLocal.h | 7 ++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/atlas/trans/ifs/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h index 3e7a08c64..1b40c55f5 100644 --- a/src/atlas/trans/ifs/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -82,10 +82,10 @@ class TransIFS : public trans::TransImpl { operator ::Trans_t*() const { return trans(); } ::Trans_t* trans() const { return trans_.get(); } - virtual int truncation() const { return std::max(0,trans_->nsmax); } - virtual size_t spectralCoefficients() const { return trans_->nspec2g; } + virtual int truncation() const override { return std::max(0,trans_->nsmax); } + virtual size_t spectralCoefficients() const override { return trans_->nspec2g; } - virtual const Grid& grid() const { return grid_; } + virtual const Grid& grid() const override { return grid_; } diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index ef8bc5d2a..13223e6a5 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -164,7 +164,7 @@ void TransLocal::invtrans( // legendre polynomials for every latitute std::vector recomputed_legendre_; - auto legPol = [&](double lat, int j) { + auto legPol = [&](double lat, int j) -> const double * { if( precompute_ ) { return legendre_data(j); } else { diff --git a/src/atlas/trans/local/TransLocal.h b/src/atlas/trans/local/TransLocal.h index d27eb70b7..cf971dcbd 100644 --- a/src/atlas/trans/local/TransLocal.h +++ b/src/atlas/trans/local/TransLocal.h @@ -50,10 +50,10 @@ class TransLocal : public trans::TransImpl { virtual ~TransLocal(); - virtual int truncation() const { return truncation_; } - virtual size_t spectralCoefficients() const { return (truncation_+1)*(truncation_+2); } + virtual int truncation() const override { return truncation_; } + virtual size_t spectralCoefficients() const override { return (truncation_+1)*(truncation_+2); } - virtual const Grid& grid() const { return grid_; } + virtual const Grid& grid() const override { return grid_; } virtual void invtrans( const Field& spfield, @@ -114,6 +114,7 @@ class TransLocal : public trans::TransImpl { private: + const double* legendre_data( int j ) const { return legendre_.data() + legendre_begin_[j]; } double* legendre_data( int j ) { return legendre_.data() + legendre_begin_[j]; } private: From 0c8807cb8aa46abb69f86a497ef5025058859d17 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 20 Nov 2017 17:53:20 +0000 Subject: [PATCH 183/355] ATLAS-135 test cosmetics --- src/tests/trans/test_transgeneral.cc | 59 +++++++++------------------- 1 file changed, 19 insertions(+), 40 deletions(-) diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index c15f3e747..0ca0368e4 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -274,11 +274,12 @@ void spectral_transform_grid_analytic( int N = (trc+2)*(trc+1)/2; for( int jm=0; jm<2*N; jm++) rspecg[jm] = 0.; int k = 0; - for( int jm=0; jm<=trc; jm++ ) + for( int jm=0; jm<=trc; jm++ ) { for( int jn=jm; jn<=trc; jn++ ) { if( jm==m && jn==n ) rspecg[2*k+imag] = 1.; k++; } + } for( int jm=0; jm Date: Tue, 21 Nov 2017 10:03:01 +0000 Subject: [PATCH 184/355] Fix compilation and unit tests with GRIDTOOLS_STORAGE=ON, CUDA=OFF --- .../array/gridtools/GridToolsArrayView.cc | 20 +-- .../array/gridtools/GridToolsArrayView.h | 2 +- .../array/gridtools/GridToolsDataStore.h | 4 + src/atlas/array/helpers/ArrayAssigner.h | 9 +- src/atlas/mesh/actions/BuildDualMesh.cc | 3 +- src/atlas_f/CMakeLists.txt | 5 + .../autogenerated/atlas_Field_module_fypp.F90 | 146 ++++++++++++------ src/atlas_f/field/atlas_Field_module.F90 | 7 +- 8 files changed, 137 insertions(+), 59 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index 7fc26af10..8a14c0e2f 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -18,25 +18,23 @@ namespace atlas { namespace array { -template< typename T > -struct private_vector { +template< typename T, size_t Rank > +struct host_device_array { - ATLAS_HOST_DEVICE private_vector( std::initializer_list list ) { - data_ = new T( list.size() ); + ATLAS_HOST_DEVICE host_device_array( std::initializer_list list ) { size_t i(0); for( const T v : list ) { data_[i++] = v; } } - ATLAS_HOST_DEVICE ~private_vector() { - delete data_; + ATLAS_HOST_DEVICE ~host_device_array() { } ATLAS_HOST_DEVICE const T* data() const { return data_; } - T* data_; + T data_[Rank]; }; template< typename Value, int Rank, Intent AccessMode > @@ -62,11 +60,11 @@ ArrayView::ArrayView(data_view_t data_view, const Array& auto storage_info_ = *((reinterpret_cast(const_cast(array.storage())))->get_storage_info_ptr()); auto stridest = seq::template apply< - private_vector, + host_device_array, atlas::array::gridtools::get_stride_component >::template get_component>( &(storage_info_)); auto shapet = seq::template apply< - private_vector, + host_device_array, atlas::array::gridtools::get_shape_component>(&(storage_info_)); std::memcpy(strides_, stridest.data(), sizeof(size_t)*Rank); @@ -88,7 +86,9 @@ bool ArrayView::valid() const { return gt_data_view_.valid() && (array_->data_store() == data_store_orig_); } -template< typename Value, int Rank, Intent AccessMode > + + +template< typename Value, int Rank, Intent AccessMode> void ArrayView::assign(const value_type& value) { helpers::array_assigner::apply(*this,value); } diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 25f356aa2..9c6b95503 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -31,10 +31,10 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas using value_type = typename remove_const::type; using Slice = typename std::conditional<(Rank==1), value_type&, LocalView >::type; using data_view_t = gridtools::data_view_tt; + using return_type = typename std::conditional< (AccessMode == Intent::ReadWrite), value_type, value_type const>::type; public: - using return_type = typename std::conditional< (AccessMode == Intent::ReadWrite), value_type, value_type const>::type; ATLAS_HOST_DEVICE ArrayView( const ArrayView& other ); ArrayView(data_view_t data_view, const Array& array); diff --git a/src/atlas/array/gridtools/GridToolsDataStore.h b/src/atlas/array/gridtools/GridToolsDataStore.h index 18edb67f7..61924dcda 100644 --- a/src/atlas/array/gridtools/GridToolsDataStore.h +++ b/src/atlas/array/gridtools/GridToolsDataStore.h @@ -71,7 +71,11 @@ struct GridToolsDataStore : ArrayDataStore } void* voidDeviceData() { +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA return ::gridtools::make_device_view<::gridtools::access_mode::ReadOnly>(*data_store_).data(); +#else + return ::gridtools::make_host_view<::gridtools::access_mode::ReadOnly>(*data_store_).data(); +#endif } private: diff --git a/src/atlas/array/helpers/ArrayAssigner.h b/src/atlas/array/helpers/ArrayAssigner.h index 6ed37753c..7983d3834 100644 --- a/src/atlas/array/helpers/ArrayAssigner.h +++ b/src/atlas/array/helpers/ArrayAssigner.h @@ -54,10 +54,15 @@ struct array_assigner { template static void apply(Array& arr, Value value) { - return apply( make_host_view(arr), value ); + return apply( make_host_view(arr), value ); } - static void apply(ArrayView& arr, Value value) { + static void apply(ArrayView& arr, Value value) { + throw eckit::AssertionFailed("Cannot assign ReadOnly array",Here()); + // TODO use SFINAE to disallow at compile time + } + + static void apply(ArrayView& arr, Value value) { array_assigner_impl::apply( arr, value ); // Note: no need to apply variadic pack (idxs...) } diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index 94e1177a7..4f0dba49e 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -121,7 +121,8 @@ void build_median_dual_mesh( Mesh& mesh ) mesh.edges().add( Field("centroids_xy",build_centroids_xy(mesh.edges(),mesh.nodes().xy())) ); - array::make_view(dual_volumes).assign(0.); + array::ArrayView v = array::make_view(dual_volumes); + v.assign(0.); add_median_dual_volume_contribution_cells(mesh.cells(),mesh.edges(),mesh.nodes(),dual_volumes); add_median_dual_volume_contribution_poles(mesh.edges(),mesh.nodes(),dual_volumes); diff --git a/src/atlas_f/CMakeLists.txt b/src/atlas_f/CMakeLists.txt index 523e9c2bd..3b2cd8612 100644 --- a/src/atlas_f/CMakeLists.txt +++ b/src/atlas_f/CMakeLists.txt @@ -165,6 +165,11 @@ generate_fortran_bindings(FORTRAN_BINDINGS internals/atlas_read_file.h) generate_fortran_bindings(FORTRAN_BINDINGS internals/Library.h) preprocess_fypp( atlas_f_src field/atlas_Field_module.F90 ) + +## gridtools_storage_files ## +add_custom_target( pre_processed_files SOURCES field/atlas_Field_module.F90 ) + + ecbuild_debug_var( atlas_f_src ) ### atlas fortran lib diff --git a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 index 985388aa7..2b9afe4c0 100644 --- a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 +++ b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 @@ -376,9 +376,12 @@ subroutine array_c_to_f_int32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -409,9 +412,12 @@ subroutine array_c_to_f_int64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -442,9 +448,12 @@ subroutine array_c_to_f_real32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -475,9 +484,12 @@ subroutine array_c_to_f_real64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -508,9 +520,12 @@ subroutine array_c_to_f_logical32_r1(array_cptr,rank,shape_cptr,strides_cptr,arr call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -541,9 +556,12 @@ subroutine array_c_to_f_int32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -574,9 +592,12 @@ subroutine array_c_to_f_int64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -607,9 +628,12 @@ subroutine array_c_to_f_real32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -640,9 +664,12 @@ subroutine array_c_to_f_real64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -673,9 +700,12 @@ subroutine array_c_to_f_logical32_r2(array_cptr,rank,shape_cptr,strides_cptr,arr call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -706,9 +736,12 @@ subroutine array_c_to_f_int32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -739,9 +772,12 @@ subroutine array_c_to_f_int64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -772,9 +808,12 @@ subroutine array_c_to_f_real32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -805,9 +844,12 @@ subroutine array_c_to_f_real64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -838,9 +880,12 @@ subroutine array_c_to_f_logical32_r3(array_cptr,rank,shape_cptr,strides_cptr,arr call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -871,9 +916,12 @@ subroutine array_c_to_f_int32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -904,9 +952,12 @@ subroutine array_c_to_f_int64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -937,9 +988,12 @@ subroutine array_c_to_f_real32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -970,9 +1024,12 @@ subroutine array_c_to_f_real64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -1003,9 +1060,12 @@ subroutine array_c_to_f_logical32_r4(array_cptr,rank,shape_cptr,strides_cptr,arr call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) @@ -2172,7 +2232,7 @@ integer function atlas_real(kind) else if (kind == c_float) then atlas_real = ATLAS_KIND_REAL32 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",271)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",274)) end if end function @@ -2188,7 +2248,7 @@ integer function atlas_integer(kind) else if (kind == c_long) then atlas_integer = ATLAS_KIND_INT64 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",287)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",290)) end if end if end function @@ -2214,7 +2274,7 @@ function atlas_data_type(kind) else if( kind == ATLAS_KIND_REAL64 ) then atlas_data_type = "real64" else - call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",313)) + call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",316)) endif end function diff --git a/src/atlas_f/field/atlas_Field_module.F90 b/src/atlas_f/field/atlas_Field_module.F90 index d24eaa8d0..75f1938ae 100644 --- a/src/atlas_f/field/atlas_Field_module.F90 +++ b/src/atlas_f/field/atlas_Field_module.F90 @@ -172,9 +172,12 @@ subroutine array_c_to_f_${dtype}$_r${rank}$(array_cptr,rank,shape_cptr,strides_c call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) - do j=1,rank-1 - eshape(j) = strides(j+1)/strides(j) + if( strides(j) /= 0 ) then + eshape(j) = strides(j+1)/strides(j) + else + eshape(j) = shape(j) + endif enddo eshape(rank) = shape(rank) call c_f_pointer ( array_cptr , tmp , shape=eshape ) From 8632c48053b137d157aff4eb33bf39e6da01599e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 21 Nov 2017 10:26:55 +0000 Subject: [PATCH 185/355] Fix compilation and unit tests with GRIDTOOLS_STORAGE=OFF --- src/atlas/array/Array.h | 1 + src/atlas/array/native/NativeArray.cc | 2 +- src/atlas/array/native/NativeArrayView.cc | 32 +++---- src/atlas/array/native/NativeArrayView.h | 13 +-- src/atlas/array/native/NativeDataStore.h | 2 +- src/atlas/array/native/NativeMakeView.cc | 104 +++++++++++----------- src/atlas/array_fwd.h | 18 ++-- src/tests/array/test_array_view_util.cc | 1 + 8 files changed, 88 insertions(+), 85 deletions(-) diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index 3678d4ce8..18a702d23 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -13,6 +13,7 @@ #include #include "eckit/memory/Owned.h" #include "atlas/library/config.h" +#include "atlas/array_fwd.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index f54eed1d7..706ac977d 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -178,7 +178,7 @@ template< typename Value > void ArrayT::dump(std::ostream& os) const { if( not contiguous() ) NOTIMP; - const Value *data = data(); + const Value *data = host_data(); for(size_t i=0; i -void ArrayView::assign(const value_type& value) { +template +void ArrayView::assign(const value_type& value) { ASSERT( contiguous() ); value_type* raw_data = data(); for( size_t j=0; j::assign(const value_type& value) { //------------------------------------------------------------------------------------------------------ -template -void ArrayView::assign(const std::initializer_list& list) { +template +void ArrayView::assign(const std::initializer_list& list) { ASSERT( contiguous() ); ASSERT( list.size() == size_ ); value_type* raw_data = data(); @@ -43,8 +43,8 @@ void ArrayView::assign(const std::initializer_list -void ArrayView::dump(std::ostream& os) const { +template +void ArrayView::dump(std::ostream& os) const { ASSERT( contiguous() ); const value_type* data_ = data(); os << "size: " << size() << " , values: "; @@ -65,16 +65,16 @@ os << "]"; namespace atlas { namespace array { #define EXPLICIT_TEMPLATE_INSTANTIATION(Rank) \ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ +template class ArrayView;\ // For each NDims in [1..9] EXPLICIT_TEMPLATE_INSTANTIATION(1) diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index dea77a812..763af1495 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -55,6 +55,7 @@ #include "atlas/library/config.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/LocalView.h" +#include "atlas/array/ArrayViewDefs.h" //------------------------------------------------------------------------------------------------------ @@ -63,7 +64,7 @@ namespace array { //------------------------------------------------------------------------------------------------------ -template class ArrayView { +template class ArrayView { public: // -- Type definitions @@ -80,7 +81,7 @@ template class ArrayView { shape_(other.shape_), strides_(other.strides_) { } - + ArrayView( const value_type* data, const ArrayShape& shape, const ArrayStrides& strides ) : data_(const_cast(data)) { size_ = 1; @@ -216,8 +217,8 @@ template class ArrayView { template struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; + Slicer(ArrayView const& av) : av_(av) {} + ArrayView const& av_; ReturnType apply(const size_t i) const { return LocalView(av_.data_ + av_.strides_[0] * i, av_.shape_.data() + 1, av_.strides_.data() + 1); } @@ -225,8 +226,8 @@ template class ArrayView { template struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; + Slicer(ArrayView const& av) : av_(av) {} + ArrayView const& av_; ReturnType apply(const size_t i) const { return *(av_.data_ + av_.strides_[0] * i); } diff --git a/src/atlas/array/native/NativeDataStore.h b/src/atlas/array/native/NativeDataStore.h index acc934766..57c0bc3a1 100644 --- a/src/atlas/array/native/NativeDataStore.h +++ b/src/atlas/array/native/NativeDataStore.h @@ -41,7 +41,7 @@ class DataStore : public ArrayDataStore { } bool hostNeedsUpdate() const { - return true; + return false; } bool deviceNeedsUpdate() const { diff --git a/src/atlas/array/native/NativeMakeView.cc b/src/atlas/array/native/NativeMakeView.cc index 5085f69e4..f1cfedfd8 100644 --- a/src/atlas/array/native/NativeMakeView.cc +++ b/src/atlas/array/native/NativeMakeView.cc @@ -30,21 +30,21 @@ namespace { //------------------------------------------------------------------------------ -template -ArrayView +template +ArrayView make_host_view(const Array& array) { - return ArrayView((const Value*)(array.storage()),array.shape(), array.strides()); + return ArrayView((const Value*)(array.storage()),array.shape(), array.strides()); } -template -ArrayView +template +ArrayView make_device_view(const Array& array) { - return make_host_view(array); + return make_host_view(array); } -template +template IndexView make_host_indexview(const Array& array) { return IndexView( (Value*)(array.storage()),array.shape().data() ); @@ -65,19 +65,19 @@ make_device_storageview(const Array& array) { } -template +template IndexView make_indexview(const Array& array) { check_metadata(array); - return make_host_indexview(array); + return make_host_indexview(array); } -template -ArrayView +template +ArrayView make_view(const Array& array) { check_metadata(array); - return make_host_view(array); + return make_host_view(array); } @@ -98,48 +98,48 @@ make_storageview(const Array& array) { namespace atlas { namespace array { #define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ +template ArrayView make_view(const Array&);\ \ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ +template ArrayView make_host_view(const Array&);\ \ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ - -template IndexView make_indexview(const Array&);\ -template IndexView make_indexview(const Array&);\ -template IndexView make_indexview(const Array&);\ -template IndexView make_indexview(const Array&);\ - -template IndexView make_host_indexview(const Array&);\ -template IndexView make_host_indexview(const Array&);\ -template IndexView make_host_indexview(const Array&);\ -template IndexView make_host_indexview(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ +template ArrayView make_device_view(const Array&);\ + +template IndexView make_indexview(const Array&);\ +template IndexView make_indexview(const Array&);\ +template IndexView make_indexview(const Array&);\ +template IndexView make_indexview(const Array&);\ + +template IndexView make_host_indexview(const Array&);\ +template IndexView make_host_indexview(const Array&);\ +template IndexView make_host_indexview(const Array&);\ +template IndexView make_host_indexview(const Array&);\ template StorageView make_storageview(const Array&); template StorageView make_storageview(const Array&); diff --git a/src/atlas/array_fwd.h b/src/atlas/array_fwd.h index cd343848b..f7afcb807 100644 --- a/src/atlas/array_fwd.h +++ b/src/atlas/array_fwd.h @@ -28,29 +28,29 @@ class ArrayT; template class StorageView; -template +template class ArrayView; template class IndexView; -template -ArrayView +template +ArrayView make_view(const Array& array); -template -ArrayView +template +ArrayView make_host_view(const Array& array); -template -ArrayView +template +ArrayView make_device_view(const Array& array); -template +template IndexView make_indexview(const Array& array); -template +template IndexView make_host_indexview(const Array& array); diff --git a/src/tests/array/test_array_view_util.cc b/src/tests/array/test_array_view_util.cc index 69f02910c..42825894a 100644 --- a/src/tests/array/test_array_view_util.cc +++ b/src/tests/array/test_array_view_util.cc @@ -8,6 +8,7 @@ * does it submit to any jurisdiction. */ +#include "atlas/array_fwd.h" #include "atlas/array/Array.h" #include "atlas/array/ArrayViewUtil.h" #include "tests/AtlasTestEnvironment.h" From 32b21c6008a14b7351fae8fbd03a530f9c897a77 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 21 Nov 2017 10:30:49 +0000 Subject: [PATCH 186/355] disable warning unless CUDA backend is chosen --- src/tests/mesh/test_elements.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tests/mesh/test_elements.cc b/src/tests/mesh/test_elements.cc index b6aff9941..4071dd4a8 100644 --- a/src/tests/mesh/test_elements.cc +++ b/src/tests/mesh/test_elements.cc @@ -280,7 +280,9 @@ CASE( "block_connectivity" ) } +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA #warning TODO: gridtools storage cuda backend cannot allocate zero elements +#endif CASE( "zero_elements" ) { HybridElements hybrid_elements; From f8a815a95d19b71da9c48141441c83cb3e5aa57d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 21 Nov 2017 11:51:21 +0000 Subject: [PATCH 187/355] Array list-assigner and writer --- src/atlas/CMakeLists.txt | 1 + src/atlas/array/gridtools/GridToolsArray.cc | 18 ++++- .../array/gridtools/GridToolsArrayView.cc | 20 ++--- src/atlas/array/helpers/ArrayAssigner.h | 34 +++++++- src/atlas/array/helpers/ArrayWriter.h | 78 +++++++++++++++++++ src/atlas/array/native/NativeArray.cc | 23 +++--- src/atlas/array/native/NativeArrayView.cc | 27 ++----- src/atlas/field/detail/FieldImpl.cc | 18 +++-- src/atlas/field/detail/FieldImpl.h | 2 +- src/tests/functionspace/test_pointcloud.cc | 5 +- 10 files changed, 170 insertions(+), 56 deletions(-) create mode 100644 src/atlas/array/helpers/ArrayWriter.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 8986c4e08..02c5017d0 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -379,6 +379,7 @@ array/StorageView.h array/Vector.h array/helpers/ArrayInitializer.h array/helpers/ArrayAssigner.h +array/helpers/ArrayWriter.h #array/Table.h #array/Table.cc #array/TableView.h diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 51002b75a..509f20511 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -159,7 +159,7 @@ class ArrayT_impl { check_dimension_lengths(array_.shape(), c...); - if(array_.valid()) + if(array_.valid()) array_.syncHostDevice(); Array* resized = Array::create(ArrayShape{(unsigned int)c...}); @@ -334,8 +334,20 @@ template void ArrayT::resize(size_t dim0, size_t dim1, s ArrayT_impl(*this).resize_variadic(dim0,dim1,dim2,dim3,dim4); } -template void ArrayT::dump(std::ostream& os) const { - os << "\nWARNING: Array dump not implemented\n"; +template< typename Value > +void ArrayT::dump(std::ostream& out) const { + switch( rank() ) { + case 1: make_host_view(*this).dump(out); break; + case 2: make_host_view(*this).dump(out); break; + case 3: make_host_view(*this).dump(out); break; + case 4: make_host_view(*this).dump(out); break; + case 5: make_host_view(*this).dump(out); break; + case 6: make_host_view(*this).dump(out); break; + case 7: make_host_view(*this).dump(out); break; + case 8: make_host_view(*this).dump(out); break; + case 9: make_host_view(*this).dump(out); break; + default: NOTIMP; + } } template diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index 8a14c0e2f..276f92c90 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -13,6 +13,7 @@ #include "atlas/array/gridtools/GridToolsArrayHelpers.h" #include "atlas/array/helpers/ArrayInitializer.h" #include "atlas/array/helpers/ArrayAssigner.h" +#include "atlas/array/helpers/ArrayWriter.h" #include "eckit/exception/Exceptions.h" namespace atlas { @@ -96,24 +97,15 @@ void ArrayView::assign(const value_type& value) { template void ArrayView::assign(const std::initializer_list& list) { ASSERT( list.size() == size_ ); - ASSERT( contiguous() ); - value_type* raw_data = data(); - size_t j(0); - for( const value_type& v : list ) { - raw_data[j++] = v; - } + helpers::array_assigner::apply(*this,list); } template< typename Value, int Rank, Intent AccessMode > void ArrayView::dump(std::ostream& os) const { - ASSERT( contiguous() ); - - const value_type* data_ = data(); - os << "size: " << size() << " , values: "; - os << "[ "; - for( size_t j=0; j struct array_assigner_impl { + template static void apply(View& arr, Value value, DimIndex... idxs) { for(size_t i=0; i < arr.shape(Dim); ++i) { array_assigner_impl::apply( arr, value, idxs..., i ); } } + + template + static void apply(View& arr, Iterator& it, DimIndex... idxs) { + for(size_t i=0; i < arr.shape(Dim); ++i) { + array_assigner_impl::apply( arr, it, idxs..., i ); + } + } + }; // End of recursion when Dim == Rank template struct array_assigner_impl { + template static void apply(View& arr, Value value, DimIndex... idxs) { arr(idxs...) = value; } + + template + static void apply(View& arr, Iterator& it, DimIndex... idxs) { + arr(idxs...) = *it; + ++it; + } + }; + //------------------------------------------------------------------------------ @@ -57,16 +75,30 @@ struct array_assigner { return apply( make_host_view(arr), value ); } - static void apply(ArrayView& arr, Value value) { + static void apply(ArrayView& arr, Value) { throw eckit::AssertionFailed("Cannot assign ReadOnly array",Here()); // TODO use SFINAE to disallow at compile time } + template + static void apply(ArrayView&, const Iterable&) { + throw eckit::AssertionFailed("Cannot assign ReadOnly array",Here()); + // TODO use SFINAE to disallow at compile time + } + + static void apply(ArrayView& arr, Value value) { array_assigner_impl::apply( arr, value ); // Note: no need to apply variadic pack (idxs...) } + template + static void apply(ArrayView& arr, const Iterable& iterable) { + typename Iterable::const_iterator it = iterable.begin(); + array_assigner_impl::apply( arr, it ); + ASSERT( it = iterable.end() ); + } + static void apply(LocalView& arr, Value value) { array_assigner_impl::apply( arr, value ); // Note: no need to apply variadic pack (idxs...) diff --git a/src/atlas/array/helpers/ArrayWriter.h b/src/atlas/array/helpers/ArrayWriter.h new file mode 100644 index 000000000..8e1601b20 --- /dev/null +++ b/src/atlas/array/helpers/ArrayWriter.h @@ -0,0 +1,78 @@ +/* + * (C) Copyright 1996-2016 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/array.h" + +//------------------------------------------------------------------------------ + +namespace atlas { +namespace array { +namespace helpers { + +//------------------------------------------------------------------------------ + +/// Helper to assign a value to an array or arrayview +//template +struct array_writer; + +//------------------------------------------------------------------------------ + +// Recursive function to apply value to every index +template +struct array_writer_impl { + + template + static void apply( View& arr, std::ostream& out, DimIndex... idxs ) { + for(size_t i=0; i < arr.shape(Dim); ++i) { + array_writer_impl::apply( arr, out, idxs..., i ); + if( i +struct array_writer_impl { + + template + static void apply(View& arr, std::ostream& out, DimIndex... idxs) { + out << arr(idxs...); + } + +}; + + +//------------------------------------------------------------------------------ + + +struct array_writer { + + template + static void apply( const ArrayView& arr, std::ostream& out ) { + array_writer_impl::apply( arr, out ); + // Note: no need to apply variadic pack (idxs...) + } + + template + static void apply( const LocalView& arr, std::ostream& out ) { + array_writer_impl::apply( arr, out ); + // Note: no need to apply variadic pack (idxs...) + } + +}; + +//------------------------------------------------------------------------------ + +} // namespace helpers +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index 706ac977d..66b3b074b 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -5,6 +5,7 @@ #include "atlas/array/native/NativeDataStore.h" #include "atlas/array/helpers/ArrayInitializer.h" +#include "atlas/array/helpers/ArrayWriter.h" using namespace atlas::array::helpers; @@ -175,17 +176,19 @@ template< typename Value > void ArrayT::resize(size_t size1, size_t size2, size_t size3, size_t size4, size_t size5) { resize( make_shape(size1,size2,size3,size4,size5) ); } template< typename Value > -void ArrayT::dump(std::ostream& os) const { - if( not contiguous() ) NOTIMP; - - const Value *data = host_data(); - - for(size_t i=0; i::dump(std::ostream& out) const { + switch( rank() ) { + case 1: make_host_view(*this).dump(out); break; + case 2: make_host_view(*this).dump(out); break; + case 3: make_host_view(*this).dump(out); break; + case 4: make_host_view(*this).dump(out); break; + case 5: make_host_view(*this).dump(out); break; + case 6: make_host_view(*this).dump(out); break; + case 7: make_host_view(*this).dump(out); break; + case 8: make_host_view(*this).dump(out); break; + case 9: make_host_view(*this).dump(out); break; + default: NOTIMP; } - os << std::endl; } //------------------------------------------------------------------------------ diff --git a/src/atlas/array/native/NativeArrayView.cc b/src/atlas/array/native/NativeArrayView.cc index 94589340d..0c72e9229 100644 --- a/src/atlas/array/native/NativeArrayView.cc +++ b/src/atlas/array/native/NativeArrayView.cc @@ -11,6 +11,8 @@ #include #include "eckit/exception/Exceptions.h" #include "atlas/array/ArrayView.h" +#include "atlas/array/helpers/ArrayAssigner.h" +#include "atlas/array/helpers/ArrayWriter.h" //------------------------------------------------------------------------------------------------------ @@ -21,37 +23,24 @@ namespace array { template void ArrayView::assign(const value_type& value) { - ASSERT( contiguous() ); - value_type* raw_data = data(); - for( size_t j=0; j::apply(*this,value); } //------------------------------------------------------------------------------------------------------ template void ArrayView::assign(const std::initializer_list& list) { - ASSERT( contiguous() ); - ASSERT( list.size() == size_ ); - value_type* raw_data = data(); - size_t j(0); - for( const value_type& v : list ) { - raw_data[j++] = v; - } + helpers::array_assigner::apply(*this,list); } //------------------------------------------------------------------------------------------------------ template void ArrayView::dump(std::ostream& os) const { -ASSERT( contiguous() ); -const value_type* data_ = data(); -os << "size: " << size() << " , values: "; -os << "[ "; -for( size_t j=0; jdump(os); + print(os,true); } namespace { @@ -127,7 +126,7 @@ const std::string& FieldImpl::name() const return name_; } -void FieldImpl::print(std::ostream& os) const +void FieldImpl::print(std::ostream& os, bool dump) const { os << "FieldImpl[name=" << name() << ",datatype=" << datatype().str() @@ -137,8 +136,13 @@ void FieldImpl::print(std::ostream& os) const #ifndef ATLAS_HAVE_GRIDTOOLS_STORAGE << ",bytes=" << bytes() #endif - << ",metadata=" << metadata() - << "]"; + << ",metadata=" << metadata(); + if( dump ) { + os << ",array=["; + array_->dump(os); + os << "]"; + } + os << "]"; } std::ostream& operator<<( std::ostream& os, const FieldImpl& f) @@ -294,7 +298,7 @@ FieldImpl* atlas__Field__create(eckit::Parametrisation* params) field->attach(); } field->detach(); - + ASSERT(field); return field; ); @@ -305,7 +309,7 @@ void atlas__Field__delete (FieldImpl* This) { delete This; } - + const char* atlas__Field__name (FieldImpl* This) { ATLAS_ERROR_HANDLING( diff --git a/src/atlas/field/detail/FieldImpl.h b/src/atlas/field/detail/FieldImpl.h index 35b17fe1b..9097f9eb1 100644 --- a/src/atlas/field/detail/FieldImpl.h +++ b/src/atlas/field/detail/FieldImpl.h @@ -185,7 +185,7 @@ class FieldImpl : public eckit::Owned { private: // methods - void print(std::ostream& os) const; + void print(std::ostream& os, bool dump=false) const; private: // members diff --git a/src/tests/functionspace/test_pointcloud.cc b/src/tests/functionspace/test_pointcloud.cc index 276e8dce0..8e39c35be 100644 --- a/src/tests/functionspace/test_pointcloud.cc +++ b/src/tests/functionspace/test_pointcloud.cc @@ -43,10 +43,13 @@ CASE( "test_functionspace_PointCloud" ) 80. , 0., 90. , 0. } ); - + functionspace::PointCloud pointcloud( points ); EXPECT( pointcloud.size() == 10 ); + points.dump( Log::info() ); + Log::info() << std::endl; + } //----------------------------------------------------------------------------- From 046e898bc7b3f992a9dd4e8e0b7c4c29350af298 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 21 Nov 2017 14:50:38 +0000 Subject: [PATCH 188/355] Fix Fortran style halo-exchanges --- src/atlas/parallel/HaloExchange.cc | 105 ++++++++++------------------- src/atlas/parallel/HaloExchange.h | 9 ++- src/atlas/runtime/trace/Timings.cc | 10 +-- 3 files changed, 43 insertions(+), 81 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 87e811201..c41012e25 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -142,36 +142,28 @@ void HaloExchange::setup( const int part[], sendmap_[jj] = recv_requests[jj]; is_setup_ = true; + backdoor.parsize = parsize_; } ///////////////////// +namespace { -HaloExchange* atlas__HaloExchange__new () { - return new HaloExchange(); -} - -void atlas__HaloExchange__delete (HaloExchange* This) { - delete This; -} +template +void execute_halo_exchange( HaloExchange* This, Value field[], int var_strides[], int var_extents[], int var_rank ) { + // WARNING: Only works if there is only one parallel dimension AND being slowest moving -void atlas__HaloExchange__setup (HaloExchange* This, int part[], int remote_idx[], int base, int size) -{ - This->setup(part,remote_idx,base,size); -} + array::ArrayShape shape{size_t(This->backdoor.parsize)}; + for( size_t j=0; j arr ( array::Array::wrap(field, - array::ArraySpec{shape, strides}) ); + eckit::SharedPtr arr ( array::Array::wrap(field, + array::ArraySpec{shape,strides} ) ); switch(var_rank) { case 1: {This->execute(*arr); break;} @@ -181,68 +173,39 @@ void atlas__HaloExchange__execute_strided_int (HaloExchange* This, int field[], default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); } } +} -void atlas__HaloExchange__execute_strided_long (HaloExchange* This, long field[], int var_strides[], int var_extents[], int var_rank) { - array::ArrayShape shape; - shape.resize(var_rank); - shape.assign(var_extents, var_extents+var_rank); - - array::ArrayStrides strides; - strides.resize(var_rank); - strides.assign(var_strides, var_strides+var_rank); +extern "C" { - eckit::SharedPtr arr ( array::Array::wrap(field, - array::ArraySpec{shape, strides}) ); +HaloExchange* atlas__HaloExchange__new () { + return new HaloExchange(); +} - switch(var_rank) { - case 1: {This->execute(*arr); break;} - case 2: {This->execute(*arr); break;} - case 3: {This->execute(*arr); break;} - case 4: {This->execute(*arr); break;} - default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); - } +void atlas__HaloExchange__delete (HaloExchange* This) { + delete This; } -void atlas__HaloExchange__execute_strided_float (HaloExchange* This, float field[], int var_strides[], int var_extents[], int var_rank) { - array::ArrayShape shape; - shape.resize(var_rank); - shape.assign(var_extents, var_extents+var_rank); +void atlas__HaloExchange__setup (HaloExchange* This, int part[], int remote_idx[], int base, int size) +{ + This->setup(part,remote_idx,base,size); +} - array::ArrayStrides strides; - strides.resize(var_rank); - strides.assign(var_strides, var_strides+var_rank); +void atlas__HaloExchange__execute_strided_int (HaloExchange* This, int field[], int var_strides[], int var_extents[], int var_rank) { + execute_halo_exchange(This,field,var_strides,var_extents,var_rank); +} - eckit::SharedPtr arr ( array::Array::wrap(field, - array::ArraySpec{shape, strides}) ); +void atlas__HaloExchange__execute_strided_long (HaloExchange* This, long field[], int var_strides[], int var_extents[], int var_rank) { + execute_halo_exchange(This,field,var_strides,var_extents,var_rank); +} - switch(var_rank) { - case 1: {This->execute(*arr); break;} - case 2: {This->execute(*arr); break;} - case 3: {This->execute(*arr); break;} - case 4: {This->execute(*arr); break;} - default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); - } +void atlas__HaloExchange__execute_strided_float (HaloExchange* This, float field[], int var_strides[], int var_extents[], int var_rank) { + execute_halo_exchange(This,field,var_strides,var_extents,var_rank); } void atlas__HaloExchange__execute_strided_double (HaloExchange* This, double field[], int var_strides[], int var_extents[], int var_rank) { - array::ArrayShape shape; - shape.resize(var_rank); - shape.assign(var_extents, var_extents+var_rank); - - array::ArrayStrides strides; - strides.resize(var_rank); - strides.assign(var_strides, var_strides+var_rank); - - eckit::SharedPtr arr ( array::Array::wrap(field, - array::ArraySpec{shape, strides}) ); + execute_halo_exchange(This,field,var_strides,var_extents,var_rank); +} - switch(var_rank) { - case 1: {This->execute(*arr); break;} - case 2: {This->execute(*arr); break;} - case 3: {This->execute(*arr); break;} - case 4: {This->execute(*arr); break;} - default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); - } } ///////////////////// diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index b065e071a..7b9565546 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -107,8 +107,10 @@ class HaloExchange: public eckit::Owned { int nproc; int myproc; - std::vector bounds_; - int par_bound_; +public: + struct Backdoor { + int parsize; + } backdoor ; }; @@ -244,7 +246,6 @@ void HaloExchange::pack_send_buffer( const array::ArrayView::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); } else - halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); #else halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); #endif @@ -256,13 +257,11 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf array::ArrayView& dfield, const bool on_device) const { ATLAS_TRACE(); - #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA if(on_device) { halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); } else - halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); #else halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); #endif diff --git a/src/atlas/runtime/trace/Timings.cc b/src/atlas/runtime/trace/Timings.cc index 9d43d450b..d9330c166 100644 --- a/src/atlas/runtime/trace/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -272,11 +272,11 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con std::vector prefix_(size()); if( indent ) { std::vector active(max_nest,false); - for( long j=long(size())-1; j>=0; --j ) { - const auto& nest = nest_[j]; + for( long k=long(size())-1; k>=0; --k ) { + const auto& nest = nest_[k]; - const CallStack& this_stack = stack_[j]; - const CallStack& next_stack = (j==size()-1) ? this_stack : stack_[j+1]; + const CallStack& this_stack = stack_[k]; + const CallStack& next_stack = (k==size()-1) ? this_stack : stack_[k+1]; auto this_it = this_stack.rbegin(); auto next_it = next_stack.rbegin(); @@ -308,7 +308,7 @@ void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& con out << box_horizontal(1); - prefix_[j] = out.str(); + prefix_[k] = out.str(); } } From 939e07987a5b91fd47939446901d4b21252b0ee7 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 22 Nov 2017 09:54:48 +0000 Subject: [PATCH 189/355] ATLAS-134 Assert grid point distribution matches TransIFS expectations --- src/atlas/functionspace/EdgeColumns.cc | 4 + src/atlas/functionspace/EdgeColumns.h | 2 + src/atlas/functionspace/FunctionSpace.cc | 4 + src/atlas/functionspace/FunctionSpace.h | 10 +++ src/atlas/functionspace/NodeColumns.cc | 4 + src/atlas/functionspace/NodeColumns.h | 2 + src/atlas/functionspace/PointCloud.cc | 16 ++-- src/atlas/functionspace/PointCloud.h | 2 +- src/atlas/functionspace/Spectral.cc | 6 ++ src/atlas/functionspace/Spectral.h | 2 + src/atlas/functionspace/StructuredColumns.cc | 13 ++- src/atlas/functionspace/StructuredColumns.h | 3 + src/atlas/grid/Distribution.cc | 20 ++++- src/atlas/grid/Distribution.h | 7 ++ src/atlas/meshgenerator/MeshGenerator.cc | 3 +- src/atlas/meshgenerator/MeshGenerator.h | 2 +- .../meshgenerator/RegularMeshGenerator.cc | 2 +- .../meshgenerator/StructuredMeshGenerator.cc | 2 +- src/atlas/trans/Trans.cc | 90 ++++--------------- src/atlas/trans/ifs/TransIFS.cc | 48 ++++++++-- src/atlas/trans/ifs/TransIFS.h | 3 + src/atlas/trans/ifs/TransIFSNodeColumns.cc | 5 +- .../trans/ifs/TransIFSStructuredColumns.cc | 4 +- 23 files changed, 153 insertions(+), 101 deletions(-) diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 2d9a8d2da..c20d01375 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -221,6 +221,10 @@ size_t EdgeColumns::footprint() const { return size; } +std::string EdgeColumns::distribution() const { + return mesh().metadata().getString("distribution"); +} + size_t EdgeColumns::nb_edges() const { return nb_edges_; diff --git a/src/atlas/functionspace/EdgeColumns.h b/src/atlas/functionspace/EdgeColumns.h index bc705e948..8cd4a7d80 100644 --- a/src/atlas/functionspace/EdgeColumns.h +++ b/src/atlas/functionspace/EdgeColumns.h @@ -51,6 +51,8 @@ class EdgeColumns : public FunctionSpaceImpl virtual std::string type() const { return "Edges"; } + virtual std::string distribution() const; + size_t nb_edges() const; size_t nb_edges_global() const; // Only on MPI rank 0, will this be different from 0 std::vector nb_edges_global_foreach_rank() const; diff --git a/src/atlas/functionspace/FunctionSpace.cc b/src/atlas/functionspace/FunctionSpace.cc index 65665a491..a8e8b337a 100644 --- a/src/atlas/functionspace/FunctionSpace.cc +++ b/src/atlas/functionspace/FunctionSpace.cc @@ -135,6 +135,10 @@ Field FunctionSpace::createField( return functionspace_->createField(other,config); } +std::string FunctionSpace::distribution() const { + return functionspace_->distribution(); +} + // ------------------------------------------------------------------ diff --git a/src/atlas/functionspace/FunctionSpace.h b/src/atlas/functionspace/FunctionSpace.h index ec90d15db..856874511 100644 --- a/src/atlas/functionspace/FunctionSpace.h +++ b/src/atlas/functionspace/FunctionSpace.h @@ -56,12 +56,20 @@ class FunctionSpaceImpl : public eckit::Owned template atlas::Field createField() const; + const util::Metadata& metadata() const { return metadata_; } + util::Metadata& metadata() { return metadata_; } + template FunctionspaceT_nonconst *cast(); template FunctionspaceT_const *cast() const; + virtual std::string distribution() const = 0; + +private: + util::Metadata metadata_; + }; inline FunctionSpaceImpl::~FunctionSpaceImpl() {} @@ -105,6 +113,7 @@ class NoFunctionSpace : public FunctionSpaceImpl virtual std::string type() const { return "NoFunctionSpace"; } virtual operator bool() const { return false; } virtual size_t footprint() const { return sizeof(*this); } + virtual std::string distribution() const { return std::string(); } virtual Field createField( const eckit::Configuration& ) const; virtual Field createField( const Field&, const eckit::Configuration& ) const; @@ -147,6 +156,7 @@ class FunctionSpace { std::string type() const; operator bool() const; size_t footprint() const; + std::string distribution() const; const Implementation* get() const { return functionspace_.get(); } diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 0cb126905..0b0778fa1 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -195,6 +195,10 @@ void NodeColumns::constructor() NodeColumns::~NodeColumns() {} +std::string NodeColumns::distribution() const { + return mesh().metadata().getString("distribution"); +} + size_t NodeColumns::footprint() const { size_t size = sizeof(*this); // TODO diff --git a/src/atlas/functionspace/NodeColumns.h b/src/atlas/functionspace/NodeColumns.h index 6be39494e..60018febc 100644 --- a/src/atlas/functionspace/NodeColumns.h +++ b/src/atlas/functionspace/NodeColumns.h @@ -58,6 +58,8 @@ class NodeColumns : public FunctionSpaceImpl static std::string static_type() { return "NodeColumns"; } virtual std::string type() const { return static_type(); } + virtual std::string distribution() const; + size_t nb_nodes() const; size_t nb_nodes_global() const; // All MPI ranks will have same output diff --git a/src/atlas/functionspace/PointCloud.cc b/src/atlas/functionspace/PointCloud.cc index fd6b7dad9..f4fe450a1 100644 --- a/src/atlas/functionspace/PointCloud.cc +++ b/src/atlas/functionspace/PointCloud.cc @@ -20,16 +20,16 @@ PointCloud::PointCloud(const std::vector& points) { lonlat_ = Field("lonlat", array::make_datatype(), array::make_shape(points.size(),2)); auto lonlat = array::make_view(lonlat_); for( size_t j=0; jnspec2g; } int nb_spectral_coefficients() const { return trans_->nspec2; } + std::string distribution() const { return "trans"; } operator ::Trans_t*() const { return trans_.get(); } std::shared_ptr<::Trans_t> trans_; }; @@ -73,6 +74,7 @@ class Spectral::Parallelisation { int nb_spectral_coefficients_global() const { return (truncation_+1)*(truncation_+2); } int nb_spectral_coefficients() const { return nb_spectral_coefficients_global(); } int truncation_; + std::string distribution() const { return "serial"; } }; #endif @@ -146,6 +148,10 @@ Spectral::~Spectral() { } +std::string Spectral::distribution() const { + return parallelisation_->distribution(); +} + size_t Spectral::footprint() const { size_t size = sizeof(*this); // TODO diff --git a/src/atlas/functionspace/Spectral.h b/src/atlas/functionspace/Spectral.h index ac50cc998..7015813d8 100644 --- a/src/atlas/functionspace/Spectral.h +++ b/src/atlas/functionspace/Spectral.h @@ -47,6 +47,8 @@ class Spectral : public FunctionSpaceImpl virtual std::string type() const { return "Spectral"; } + virtual std::string distribution() const; + /// @brief Create a spectral field using FunctionSpaceImpl::createField; virtual Field createField( const eckit::Configuration& ) const; diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 99a581fb5..d80a94306 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -36,9 +36,9 @@ namespace atlas { namespace functionspace { namespace detail { - + namespace { - + struct GridPoint { public: @@ -192,6 +192,10 @@ size_t StructuredColumns::config_size(const eckit::Configuration& config) const return size; } +std::string StructuredColumns::distribution() const { + return distribution_; +} + // ---------------------------------------------------------------------------- // Constructor // ---------------------------------------------------------------------------- @@ -228,6 +232,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& ATLAS_TRACE_SCOPE( "Partitioning grid ..." ) { distribution = grid::Distribution(grid,partitioner); } + distribution_ = distribution.type(); int mpi_rank = parallel::mpi::comm().rank(); @@ -611,10 +616,10 @@ Field StructuredColumns::createField( const eckit::Configuration& options ) cons } Field StructuredColumns::createField( - const Field& other, + const Field& other, const eckit::Configuration& config ) const { - return createField( + return createField( option::datatype ( other.datatype() ) | option::levels ( other.levels() ) | option::variables( other.variables() ) | diff --git a/src/atlas/functionspace/StructuredColumns.h b/src/atlas/functionspace/StructuredColumns.h index f60b13904..09226bb52 100644 --- a/src/atlas/functionspace/StructuredColumns.h +++ b/src/atlas/functionspace/StructuredColumns.h @@ -53,6 +53,7 @@ class StructuredColumns : public FunctionSpaceImpl { static std::string static_type() { return "StructuredColumns"; } virtual std::string type() const { return static_type(); } + virtual std::string distribution() const; /// @brief Create a Structured field virtual Field createField( const eckit::Configuration&) const; @@ -111,6 +112,8 @@ class StructuredColumns : public FunctionSpaceImpl { private: // data + std::string distribution_; + size_t size_owned_; size_t size_halo_; size_t nb_levels_; diff --git a/src/atlas/grid/Distribution.cc b/src/atlas/grid/Distribution.cc index 65f61ade4..774d5dd4a 100644 --- a/src/atlas/grid/Distribution.cc +++ b/src/atlas/grid/Distribution.cc @@ -18,12 +18,25 @@ namespace atlas { namespace grid { +namespace { +std::string distribution_type( int N, const Partitioner& p = Partitioner() ) { + if( N == 1 ) { + return "serial"; + } + if( not p ) { + return "custom"; + } + return p.type(); +} +} + Distribution::impl_t::impl_t( const Grid& grid ) : nb_partitions_(1), part_(grid.size(),0), nb_pts_(nb_partitions_,grid.size()), max_pts_(grid.size()), - min_pts_(grid.size()) { + min_pts_(grid.size()), + type_( distribution_type(nb_partitions_) ) { } Distribution::impl_t::impl_t( const Grid& grid, const Partitioner& partitioner ) { @@ -35,6 +48,7 @@ Distribution::impl_t::impl_t( const Grid& grid, const Partitioner& partitioner ) ++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); } Distribution::impl_t::impl_t( size_t npts, int part[], int part0 ) { @@ -48,12 +62,14 @@ Distribution::impl_t::impl_t( size_t npts, int part[], int part0 ) { } 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_); } void Distribution::impl_t::print( std::ostream& s ) const { s << "Distribution( " - << "nbPoints: " << part_.size() + << "type: " << type_ + <<", nbPoints: " << part_.size() <<", nbPartitions: " < nb_pts_; size_t max_pts_; size_t min_pts_; + std::string type_; }; @@ -132,6 +135,10 @@ class Distribution { return impl_->min_pts(); } + const std::string& type() const { + return impl_->type(); + } + friend std::ostream& operator<<(std::ostream& os, const Distribution& distribution ) { distribution.impl_->print(os); return os; diff --git a/src/atlas/meshgenerator/MeshGenerator.cc b/src/atlas/meshgenerator/MeshGenerator.cc index 050611268..c0986f534 100644 --- a/src/atlas/meshgenerator/MeshGenerator.cc +++ b/src/atlas/meshgenerator/MeshGenerator.cc @@ -128,8 +128,9 @@ void MeshGeneratorImpl::setProjection( Mesh& mesh, const Projection& p ) const { mesh.setProjection(p); } -void MeshGeneratorImpl::setGrid( Mesh& mesh, const Grid& g ) const { +void MeshGeneratorImpl::setGrid( Mesh& mesh, const Grid& g, const grid::Distribution& d ) const { mesh.setGrid(g); + mesh.metadata().set("distribution",d.type()); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/meshgenerator/MeshGenerator.h b/src/atlas/meshgenerator/MeshGenerator.h index 3326b94ea..0c06df696 100644 --- a/src/atlas/meshgenerator/MeshGenerator.h +++ b/src/atlas/meshgenerator/MeshGenerator.h @@ -61,7 +61,7 @@ class MeshGeneratorImpl : public eckit::Owned { void generateGlobalElementNumbering( Mesh& mesh ) const; void setProjection( Mesh&, const Projection& ) const; - void setGrid( Mesh&, const Grid& ) const; + void setGrid( Mesh&, const Grid&, const grid::Distribution& ) const; }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/meshgenerator/RegularMeshGenerator.cc b/src/atlas/meshgenerator/RegularMeshGenerator.cc index a1d4227ef..aa3403b2f 100644 --- a/src/atlas/meshgenerator/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/RegularMeshGenerator.cc @@ -140,7 +140,7 @@ void RegularMeshGenerator::generate(const Grid& grid, const grid::Distribution& } // clone some grid properties - setGrid(mesh,rg); + setGrid(mesh,rg,distribution); generate_mesh(rg,distribution,mesh); } diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 78446d112..d21da9de0 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -224,7 +224,7 @@ void StructuredMeshGenerator::generate(const Grid& grid, const grid::Distributio #endif // clone some grid properties - setGrid(mesh,rg); + setGrid(mesh,rg,distribution); Region region; generate_region(rg,distribution,mypart,region); diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index dd788bc95..f29582bf2 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -60,6 +60,19 @@ namespace { } }; + TransFactory& factory( const std::string& name ) { + std::map::const_iterator j = m->find(name); + if (j == m->end()) { + Log::error() << "No TransFactory for [" << name << "]" << std::endl; + Log::error() << "TransFactories are:" << std::endl; + for (j = m->begin() ; j != m->end() ; ++j) + Log::error() << " " << (*j).first << std::endl; + throw eckit::SeriousBug(std::string("No TransFactory called ") + name); + } + return *j->second; + } + + } @@ -109,33 +122,7 @@ void TransFactory::list(std::ostream& out) { Trans::Implementation *TransFactory::build( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); - - static force_link static_linking; - - std::string suffix ( "("+gp.type()+","+sp.type()+")" ); - std::string name = config.getString("type",TRANS_DEFAULT)+suffix; - - Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; - - if( not config.has("type") and not has(name) ) { - name = std::string("local")+suffix; - Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; - } - - std::map::const_iterator j = m->find(name); - if (j == m->end()) { - Log::error() << "No TransFactory for [" << name << "]" << std::endl; - Log::error() << "TransFactories are:" << std::endl; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No TransFactory called ") + name); - } - - return (*j).second->make(gp,sp,config); + return build( Cache(), gp, sp, config ); } Trans::Implementation *TransFactory::build( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { @@ -156,45 +143,11 @@ Trans::Implementation *TransFactory::build( const Cache& cache, const FunctionSp Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; } - std::map::const_iterator j = m->find(name); - if (j == m->end()) { - Log::error() << "No TransFactory for [" << name << "]" << std::endl; - Log::error() << "TransFactories are:" << std::endl; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No TransFactory called ") + name); - } - - return (*j).second->make(cache,gp,sp,config); + return factory(name).make(cache,gp,sp,config); } Trans::Implementation *TransFactory::build( const Grid& grid, int truncation, const eckit::Configuration& config ) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); - - static force_link static_linking; - - std::string name = config.getString("type",TRANS_DEFAULT); - - Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; - - if( not config.has("type") and not has(name) ) { - name = std::string("local"); - Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; - } - - std::map::const_iterator j = m->find(name); - if (j == m->end()) { - Log::error() << "No TransFactory for [" << name << "]" << std::endl; - Log::error() << "TransFactories are:" << std::endl; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No TransFactory called ") + name); - } - - return (*j).second->make(grid,truncation,config); + return build( Cache(), grid, truncation, config ); } Trans::Implementation *TransFactory::build( const Cache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { @@ -214,16 +167,7 @@ Trans::Implementation *TransFactory::build( const Cache& cache, const Grid& grid Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; } - std::map::const_iterator j = m->find(name); - if (j == m->end()) { - Log::error() << "No TransFactory for [" << name << "]" << std::endl; - Log::error() << "TransFactories are:" << std::endl; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No TransFactory called ") + name); - } - - return (*j).second->make(cache,grid,truncation,config); + return factory(name).make(cache,grid,truncation,config); } diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index 2a8cf653f..b95ef34ce 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -27,6 +27,7 @@ using atlas::functionspace::StructuredColumns; using atlas::functionspace::NodeColumns; using atlas::functionspace::Spectral; using atlas::Field; +using atlas::FunctionSpace; using atlas::array::ArrayView; using atlas::array::make_view; @@ -690,7 +691,17 @@ namespace atlas { namespace trans { - +void TransIFS::assertCompatibleDistributions( const FunctionSpace& gp, const FunctionSpace& /*sp*/ ) const { + std::string gp_dist = gp.distribution(); + if( gp_dist != "trans" && // distribution computed by TransPartitioner + gp_dist != "serial" && // serial distribution always works + gp_dist != "custom" ) { // trust user that he knows what he is doing + throw eckit::Exception( + gp.type() + " functionspace has unsupported distribution ("+gp_dist+") " + "to do spectral transforms. Please partition grid with TransPartitioner", + Here()); + } +} TransIFS::TransIFS( const Cache& cache, const Grid& grid, const long truncation, const eckit::Configuration& config ) : grid_(grid), @@ -834,6 +845,8 @@ void TransIFS::__dirtrans( const functionspace::NodeColumns& gp, const Field& gp void TransIFS::__dirtrans( const functionspace::NodeColumns& gp,const FieldSet& gpfields, const Spectral& sp, FieldSet& spfields, const eckit::Configuration& ) const { + assertCompatibleDistributions( gp, sp ); + // Count total number of fields and do sanity checks int nfld(0); for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) @@ -889,14 +902,17 @@ void TransIFS::__dirtrans( const functionspace::NodeColumns& gp,const FieldSet& // -------------------------------------------------------------------------------------------- void TransIFS::__dirtrans( - const StructuredColumns&, const Field& gpfield, - const Spectral&, Field& spfield, + const StructuredColumns& gp, const Field& gpfield, + const Spectral& sp, Field& spfield, const eckit::Configuration& ) const { ASSERT( gpfield.functionspace() == 0 || functionspace::StructuredColumns(gpfield.functionspace()) ); ASSERT( spfield.functionspace() == 0 || functionspace::Spectral(spfield.functionspace()) ); + + assertCompatibleDistributions( gp, sp ); + if ( gpfield.stride(0) != spfield.stride(0) ) { throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); @@ -920,10 +936,12 @@ void TransIFS::__dirtrans( } void TransIFS::__dirtrans( - const StructuredColumns&, const FieldSet& gpfields, - const Spectral&, FieldSet& spfields, + const StructuredColumns& gp, const FieldSet& gpfields, + const Spectral& sp, FieldSet& spfields, const eckit::Configuration& ) const { + assertCompatibleDistributions( gp, sp ); + // Count total number of fields and do sanity checks int nfld(0); for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) @@ -994,6 +1012,8 @@ void TransIFS::__invtrans_grad( const functionspace::NodeColumns& gp, FieldSet& gradfields, const eckit::Configuration& config ) const { + assertCompatibleDistributions( gp, sp ); + // Count total number of fields and do sanity checks int nb_gridpoint_field(0); for(size_t jfld = 0; jfld < gradfields.size(); ++jfld) @@ -1090,6 +1110,8 @@ void TransIFS::__invtrans( const Spectral& sp, const FieldSet& spfields, const functionspace::NodeColumns& gp, FieldSet& gpfields, const eckit::Configuration& config ) const { + assertCompatibleDistributions( gp, sp ); + // Count total number of fields and do sanity checks int nfld(0); for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) @@ -1148,6 +1170,8 @@ void TransIFS::__invtrans( const functionspace::Spectral& sp, const Field& spfie const functionspace::StructuredColumns& gp, Field& gpfield, const eckit::Configuration& config ) const { + assertCompatibleDistributions( gp, sp ); + ASSERT( gpfield.functionspace() == 0 || functionspace::StructuredColumns( gpfield.functionspace() ) ); ASSERT( spfield.functionspace() == 0 || @@ -1181,6 +1205,8 @@ void TransIFS::__invtrans( const functionspace::Spectral& sp, const FieldSet& sp const functionspace::StructuredColumns& gp, FieldSet& gpfields, const eckit::Configuration& config ) const { + assertCompatibleDistributions( gp, sp ); + // Count total number of fields and do sanity checks int nfld(0); for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) @@ -1240,9 +1266,11 @@ void TransIFS::__invtrans( const functionspace::Spectral& sp, const FieldSet& sp // ----------------------------------------------------------------------------------------------- void TransIFS::__dirtrans_wind2vordiv( const functionspace::NodeColumns& gp, const Field& gpwind, - const Spectral& sp, Field& spvor, Field&spdiv, - const eckit::Configuration& ) const + const Spectral& sp, Field& spvor, Field&spdiv, + const eckit::Configuration& ) const { + assertCompatibleDistributions( gp, sp ); + // Count total number of fields and do sanity checks size_t nfld = spvor.stride(0); if( spdiv.shape(0) != spvor.shape(0) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); @@ -1286,9 +1314,11 @@ void TransIFS::__dirtrans_wind2vordiv( const functionspace::NodeColumns& gp, con void TransIFS::__invtrans_vordiv2wind( const Spectral& sp, const Field& spvor, const Field& spdiv, - const functionspace::NodeColumns& gp, Field& gpwind, - const eckit::Configuration& config ) const + const functionspace::NodeColumns& gp, Field& gpwind, + const eckit::Configuration& config ) const { + assertCompatibleDistributions( gp, sp ); + // Count total number of fields and do sanity checks size_t nfld = spvor.stride(0); if( spdiv.shape(0) != spvor.shape(0) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); diff --git a/src/atlas/trans/ifs/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h index 1b40c55f5..4c721c013 100644 --- a/src/atlas/trans/ifs/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -246,6 +246,9 @@ class TransIFS : public trans::TransImpl { public: void specnorm( const int nb_fields, const double spectra[], double norms[], int rank=0 ) const; +protected: + + void assertCompatibleDistributions( const FunctionSpace& gp, const FunctionSpace& /*sp*/ ) const; private: diff --git a/src/atlas/trans/ifs/TransIFSNodeColumns.cc b/src/atlas/trans/ifs/TransIFSNodeColumns.cc index 3390b9a95..df76e6a29 100644 --- a/src/atlas/trans/ifs/TransIFSNodeColumns.cc +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.cc @@ -20,7 +20,7 @@ TransIFSNodeColumns::TransIFSNodeColumns( const functionspace::NodeColumns& gp, const functionspace::Spectral& sp, const eckit::Configuration& config ) : - TransIFS( gp.mesh().grid(), sp.truncation(), config ) { + TransIFSNodeColumns( Cache(), gp, sp, config ) { } TransIFSNodeColumns::TransIFSNodeColumns( @@ -29,6 +29,9 @@ TransIFSNodeColumns::TransIFSNodeColumns( const functionspace::Spectral& sp, const eckit::Configuration& config ) : TransIFS( cache, gp.mesh().grid(), sp.truncation(), config ) { + + assertCompatibleDistributions( gp, sp ); + } TransIFSNodeColumns::~TransIFSNodeColumns() diff --git a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc index 866513672..10ca8b546 100644 --- a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc @@ -20,7 +20,7 @@ TransIFSStructuredColumns::TransIFSStructuredColumns( const functionspace::StructuredColumns& gp, const functionspace::Spectral& sp, const eckit::Configuration& config ) : - TransIFS( gp.grid(), sp.truncation(), config ) { + TransIFSStructuredColumns( Cache(), gp, sp, config ) { } TransIFSStructuredColumns::TransIFSStructuredColumns( @@ -29,6 +29,8 @@ TransIFSStructuredColumns::TransIFSStructuredColumns( const functionspace::Spectral& sp, const eckit::Configuration& config ) : TransIFS( cache, gp.grid(), sp.truncation(), config ) { + + assertCompatibleDistributions( gp, sp ); } From 7391120f3ba75d3464bc5a44ce3d371b1a7be96e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 22 Nov 2017 10:18:35 +0000 Subject: [PATCH 190/355] ATLAS-134 cosmetics --- src/atlas/CMakeLists.txt | 2 + src/atlas/option.h | 1 + src/atlas/option/Options.cc | 42 +++++----------- src/atlas/option/Options.h | 60 ----------------------- src/atlas/option/TransOptions.cc | 71 +++++++++++++++++++++++++++ src/atlas/option/TransOptions.h | 84 ++++++++++++++++++++++++++++++++ 6 files changed, 171 insertions(+), 89 deletions(-) create mode 100644 src/atlas/option/TransOptions.cc create mode 100644 src/atlas/option/TransOptions.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index e0596b5a2..75b631a4e 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -56,6 +56,8 @@ list( APPEND atlas_grid_srcs option.h option/Options.h option/Options.cc +option/TransOptions.h +option/TransOptions.cc projection.h diff --git a/src/atlas/option.h b/src/atlas/option.h index 15bde3fa2..9c72bbbd8 100644 --- a/src/atlas/option.h +++ b/src/atlas/option.h @@ -13,3 +13,4 @@ #pragma once #include "atlas/option/Options.h" +#include "atlas/option/TransOptions.h" diff --git a/src/atlas/option/Options.cc b/src/atlas/option/Options.cc index bed3c4a3c..6f109ad19 100644 --- a/src/atlas/option/Options.cc +++ b/src/atlas/option/Options.cc @@ -9,32 +9,13 @@ */ #include "atlas/option/Options.h" +#include "atlas/util/Earth.h" // ---------------------------------------------------------------------------- namespace atlas { namespace option { -vorticity_divergence_fields::vorticity_divergence_fields(bool v) { set("vorticity_divergence_fields",v); } - -wind_EW_derivatives::wind_EW_derivatives(bool v) { set("wind_EW_derivatives",v); } - -scalar_derivatives::scalar_derivatives(bool v) { set("scalar_derivatives",v); } - -radius::radius(double _radius) -{ - set("radius",_radius); -} - -radius::radius(const std::string &key) -{ - if( key == "Earth" ) { - set("radius",util::Earth::radiusInMeters()); - } else { - NOTIMP; - } -} - type::type(const std::string &_type) { set("type",_type); @@ -81,17 +62,20 @@ variables::variables(size_t _variables) set("variables",_variables); } -flt::flt(bool flt) { set("flt",flt); } -static const std::map FFT_to_string = { {FFT992,"FFT992"},{FFTW,"FFTW"} }; -//static const std::map string_to_FFT = { {"FFT992",FFT992},{"FFTW",FFTW} }; - -fft::fft( FFT fft ) { set("fft",FFT_to_string.at(fft)); } -fft::fft( const std::string& fft ) { set("fft",fft); } -split_latitudes::split_latitudes(bool split_latitudes) { set("split_latitudes",split_latitudes); } -write_legendre::write_legendre( const eckit::PathName& filepath ) { set("write_legendre",filepath); } -read_legendre::read_legendre( const eckit::PathName& filepath ) { set("read_legendre",filepath); } +radius::radius(double _radius) +{ + set("radius",_radius); +} +radius::radius(const std::string &key) +{ + if( key == "Earth" ) { + set("radius",util::Earth::radiusInMeters()); + } else { + NOTIMP; + } +} // ---------------------------------------------------------------------------- diff --git a/src/atlas/option/Options.h b/src/atlas/option/Options.h index b10d6797e..ddb210b6d 100644 --- a/src/atlas/option/Options.h +++ b/src/atlas/option/Options.h @@ -11,7 +11,6 @@ #pragma once #include "atlas/util/Config.h" -#include "atlas/util/Earth.h" #include "atlas/array/DataType.h" // ---------------------------------------------------------------------------- @@ -86,65 +85,6 @@ class radius : public util::Config { radius( const std::string& = "Earth" ); }; -// ---------------------------------------------------------------------------- - -class scalar_derivatives : public util::Config { -public: - scalar_derivatives( bool ); -}; - -// ---------------------------------------------------------------------------- - -class wind_EW_derivatives : public util::Config { -public: - wind_EW_derivatives( bool ); -}; - -// ---------------------------------------------------------------------------- - -class vorticity_divergence_fields : public util::Config { -public: - vorticity_divergence_fields( bool ); -}; - -// ---------------------------------------------------------------------------- - -class flt : public util::Config { -public: - flt( bool ); -}; - -// ---------------------------------------------------------------------------- - -enum FFT { FFT992=1, FFTW=2 }; - -class fft : public util::Config { -public: - fft( FFT ); - fft( const std::string& ); -}; - -// ---------------------------------------------------------------------------- - -class split_latitudes : public util::Config { -public: - split_latitudes( bool ); -}; - -// ---------------------------------------------------------------------------- - -class write_legendre : public util::Config { -public: - write_legendre( const eckit::PathName& ); -}; - -// ---------------------------------------------------------------------------- - -class read_legendre : public util::Config { -public: - read_legendre( const eckit::PathName& ); -}; - // ---------------------------------------------------------------------------- // Definitions // ---------------------------------------------------------------------------- diff --git a/src/atlas/option/TransOptions.cc b/src/atlas/option/TransOptions.cc new file mode 100644 index 000000000..4bba28675 --- /dev/null +++ b/src/atlas/option/TransOptions.cc @@ -0,0 +1,71 @@ +/* + * (C) Copyright 1996-2017 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 "atlas/option/TransOptions.h" + +// ---------------------------------------------------------------------------- + +namespace atlas { +namespace option { + +vorticity_divergence_fields::vorticity_divergence_fields(bool v) +{ + set("vorticity_divergence_fields",v); +} + +wind_EW_derivatives::wind_EW_derivatives(bool v) +{ + set("wind_EW_derivatives",v); +} + +scalar_derivatives::scalar_derivatives(bool v) +{ + set("scalar_derivatives",v); +} + +flt::flt(bool flt) +{ + set("flt",flt); +} + +fft::fft( FFT fft ) +{ + static const std::map FFT_to_string = + { + {FFT::FFT992, "FFT992"}, + {FFT::FFTW, "FFTW" } + }; + set("fft",FFT_to_string.at(fft)); +} + +fft::fft( const std::string& fft ) +{ + set("fft",fft); +} + +split_latitudes::split_latitudes(bool split_latitudes) +{ + set("split_latitudes",split_latitudes); +} + +write_legendre::write_legendre( const eckit::PathName& filepath ) +{ + set("write_legendre",filepath); +} + +read_legendre::read_legendre( const eckit::PathName& filepath ) +{ + set("read_legendre",filepath); +} + +// ---------------------------------------------------------------------------- + +} // namespace option +} // namespace atlas diff --git a/src/atlas/option/TransOptions.h b/src/atlas/option/TransOptions.h new file mode 100644 index 000000000..a87789d28 --- /dev/null +++ b/src/atlas/option/TransOptions.h @@ -0,0 +1,84 @@ +/* + * (C) Copyright 1996-2017 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/util/Config.h" + +// ---------------------------------------------------------------------------- + +namespace atlas { +namespace option { + +// ---------------------------------------------------------------------------- + +enum class FFT { FFT992=1, FFTW=2 }; + +// ---------------------------------------------------------------------------- + +class scalar_derivatives : public util::Config { +public: + scalar_derivatives( bool ); +}; + +// ---------------------------------------------------------------------------- + +class wind_EW_derivatives : public util::Config { +public: + wind_EW_derivatives( bool ); +}; + +// ---------------------------------------------------------------------------- + +class vorticity_divergence_fields : public util::Config { +public: + vorticity_divergence_fields( bool ); +}; + +// ---------------------------------------------------------------------------- + +class flt : public util::Config { +public: + flt( bool ); +}; + +// ---------------------------------------------------------------------------- + +class fft : public util::Config { +public: + fft( FFT ); + fft( const std::string& ); +}; + +// ---------------------------------------------------------------------------- + +class split_latitudes : public util::Config { +public: + split_latitudes( bool ); +}; + +// ---------------------------------------------------------------------------- + +class write_legendre : public util::Config { +public: + write_legendre( const eckit::PathName& ); +}; + +// ---------------------------------------------------------------------------- + +class read_legendre : public util::Config { +public: + read_legendre( const eckit::PathName& ); +}; + +// ---------------------------------------------------------------------------- + +} // namespace option +} // namespace atlas From 7888c17f7e0a648cd38d200c2e38251d161134a9 Mon Sep 17 00:00:00 2001 From: Tiago Quintino Date: Wed, 22 Nov 2017 16:00:16 +0000 Subject: [PATCH 191/355] Comment test breaking cmake on the Cray --- src/tests/functionspace/CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tests/functionspace/CMakeLists.txt b/src/tests/functionspace/CMakeLists.txt index c135aa5a9..3b1c74ce3 100644 --- a/src/tests/functionspace/CMakeLists.txt +++ b/src/tests/functionspace/CMakeLists.txt @@ -6,17 +6,17 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -if( HAVE_FCTEST ) +#if( HAVE_FCTEST ) - add_fctest( TARGET atlas_fctest_functionspace - MPI 4 - CONDITION ECKIT_HAVE_MPI AND TRANSI_HAVE_MPI - LINKER_LANGUAGE Fortran - SOURCES fctest_functionspace.F90 - LIBS atlas_f - ) +# add_fctest( TARGET atlas_fctest_functionspace +# MPI 4 +# CONDITION ECKIT_HAVE_MPI AND TRANSI_HAVE_MPI +# LINKER_LANGUAGE Fortran +# SOURCES fctest_functionspace.F90 +# LIBS atlas_f +# ) -endif() +#endif() ecbuild_add_test( TARGET atlas_test_functionspace SOURCES test_functionspace.cc From d296a5b9229fcdd38c52269e28932b78dce2716d Mon Sep 17 00:00:00 2001 From: Tiago Quintino Date: Wed, 22 Nov 2017 16:05:44 +0000 Subject: [PATCH 192/355] Bring back test --- src/tests/functionspace/CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tests/functionspace/CMakeLists.txt b/src/tests/functionspace/CMakeLists.txt index 3b1c74ce3..c135aa5a9 100644 --- a/src/tests/functionspace/CMakeLists.txt +++ b/src/tests/functionspace/CMakeLists.txt @@ -6,17 +6,17 @@ # granted to it by virtue of its status as an intergovernmental organisation nor # does it submit to any jurisdiction. -#if( HAVE_FCTEST ) +if( HAVE_FCTEST ) -# add_fctest( TARGET atlas_fctest_functionspace -# MPI 4 -# CONDITION ECKIT_HAVE_MPI AND TRANSI_HAVE_MPI -# LINKER_LANGUAGE Fortran -# SOURCES fctest_functionspace.F90 -# LIBS atlas_f -# ) + add_fctest( TARGET atlas_fctest_functionspace + MPI 4 + CONDITION ECKIT_HAVE_MPI AND TRANSI_HAVE_MPI + LINKER_LANGUAGE Fortran + SOURCES fctest_functionspace.F90 + LIBS atlas_f + ) -#endif() +endif() ecbuild_add_test( TARGET atlas_test_functionspace SOURCES test_functionspace.cc From d1c0dd8e241f2b17a1b2d8147d98546d48b85520 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 23 Nov 2017 10:24:06 +0000 Subject: [PATCH 193/355] Update bamboo's cmake version when using fckit --- bamboo/opensuse131-env.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bamboo/opensuse131-env.sh b/bamboo/opensuse131-env.sh index 656adf2da..95fcd1563 100755 --- a/bamboo/opensuse131-env.sh +++ b/bamboo/opensuse131-env.sh @@ -3,4 +3,13 @@ # CC=mpicc # CXX=mpicxx # FC=mpif90 -ulimit -s unlimited \ No newline at end of file +ulimit -s unlimited + +# Initialise module environment if it is not +if [[ ! $(command -v module > /dev/null 2>&1) ]]; then + . /usr/local/apps/module/init/bash +fi + +# Minimum required cmake (3.1) when using fckit only +module unload cmake +module load cmake/3.7.1 From 3caffcc69aa37025d8c13addd3e0e14be5d0f28b Mon Sep 17 00:00:00 2001 From: Baudouin Raoult Date: Thu, 23 Nov 2017 12:31:09 +0100 Subject: [PATCH 194/355] Debug info --- src/atlas/util/Earth.cc | 100 +++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index 3798d4b5c..ea2ee0c78 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -57,22 +57,36 @@ double Sphere::centralAngle(const PointLonLat& p1, const PointLonLat& p2) { * doi = {10.1179/sre.1975.23.176.88} * } */ - ASSERT(-90. <= p1.lat() && p1.lat() <= 90.); - ASSERT(-90. <= p2.lat() && p2.lat() <= 90.); + if (!(-90. <= p1.lat() && p1.lat() <= 90.)) { + std::ostringstream oss; + oss << "Invalid greatCircleLatitudeGivenLongitude " + << p1.lat() << " 90 - lat: " + << (90.0 - p1.lat()) + << " -90 - lat: " << (-90.0 - p1.lat()); + throw eckit::SeriousBug(oss.str()); + } + if (!(-90. <= p2.lat() && p2.lat() <= 90.)) { + std::ostringstream oss; + oss << "Invalid greatCircleLatitudeGivenLongitude " + << p2.lat() << " 90 - lat: " + << (90.0 - p2.lat()) + << " -90 - lat: " << (-90.0 - p2.lat()); + throw eckit::SeriousBug(oss.str()); + } const double - phi1 = Constants::degreesToRadians() * p1.lat(), - phi2 = Constants::degreesToRadians() * p2.lat(), - lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()), - - cos_phi1 = cos(phi1), - sin_phi1 = sin(phi1), - cos_phi2 = cos(phi2), - sin_phi2 = sin(phi2), - cos_lambda = cos(lambda), - sin_lambda = sin(lambda), - - angle = atan2( + phi1 = Constants::degreesToRadians() * p1.lat(), + phi2 = Constants::degreesToRadians() * p2.lat(), + lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()), + + cos_phi1 = cos(phi1), + sin_phi1 = sin(phi1), + cos_phi2 = cos(phi2), + sin_phi2 = sin(phi2), + cos_lambda = cos(lambda), + sin_lambda = sin(lambda), + + angle = atan2( sqrt(pow(cos_phi2 * sin_lambda, 2) + pow(cos_phi1 * sin_phi2 - sin_phi1 * cos_phi2 * cos_lambda, 2)), sin_phi1 * sin_phi2 + cos_phi1 * cos_phi2 * cos_lambda ); @@ -96,8 +110,8 @@ double Sphere::centralAngle(const PointXYZ& p1, const PointXYZ& p2, const double } const double - chord = std::sqrt(d2) / radius, - angle = std::asin(chord * 0.5) * 2.; + chord = std::sqrt(d2) / radius, + angle = std::asin(chord * 0.5) * 2.; return angle; } @@ -120,15 +134,15 @@ void Sphere::greatCircleLatitudeGivenLongitude(const PointLonLat& p1, const Poin // http://www.edwilliams.org/avform.htm#Int ASSERT(!eckit::types::is_approximately_equal(p1.lon(), p2.lon())); const double - phi1 = Constants::degreesToRadians() * p1.lat(), - phi2 = Constants::degreesToRadians() * p2.lat(), - lambda1p = Constants::degreesToRadians() * (p.lon() - p1.lon()), - lambda2p = Constants::degreesToRadians() * (p.lon() - p2.lon()), - lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()); + phi1 = Constants::degreesToRadians() * p1.lat(), + phi2 = Constants::degreesToRadians() * p2.lat(), + lambda1p = Constants::degreesToRadians() * (p.lon() - p1.lon()), + lambda2p = Constants::degreesToRadians() * (p.lon() - p2.lon()), + lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()); p.lat() = Constants::radiansToDegrees() * atan( - (tan(phi2) * sin(lambda1p) - tan(phi1) * sin(lambda2p)) / - (sin(lambda)) ); + (tan(phi2) * sin(lambda1p) - tan(phi1) * sin(lambda2p)) / + (sin(lambda)) ); } @@ -139,31 +153,31 @@ PointXYZ Sphere::convertSphericalToCartesian(const PointLonLat& p, const double& // See https://en.wikipedia.org/wiki/Reference_ellipsoid#Coordinates // numerical conditioning for both ϕ (poles) and λ (Greenwich/Date Line) const double - &a = radius, - &b = radius, + &a = radius, + &b = radius, - lambda_deg = between_m180_and_p180(p.lon()), - lambda = Constants::degreesToRadians() * lambda_deg, - phi = Constants::degreesToRadians() * p.lat(), + lambda_deg = between_m180_and_p180(p.lon()), + lambda = Constants::degreesToRadians() * lambda_deg, + phi = Constants::degreesToRadians() * p.lat(), - sin_phi = std::sin(phi), - cos_phi = std::sqrt(1. - sin_phi * sin_phi), - sin_lambda = std::abs(lambda_deg) < 180. ? std::sin(lambda) : 0., - cos_lambda = std::abs(lambda_deg) > 90. ? std::cos(lambda) : std::sqrt(1. - sin_lambda * sin_lambda); + sin_phi = std::sin(phi), + cos_phi = std::sqrt(1. - sin_phi * sin_phi), + sin_lambda = std::abs(lambda_deg) < 180. ? std::sin(lambda) : 0., + cos_lambda = std::abs(lambda_deg) > 90. ? std::cos(lambda) : std::sqrt(1. - sin_lambda * sin_lambda); if (a == b) { // no eccentricity return PointXYZ( - (a + height) * cos_phi * cos_lambda, - (a + height) * cos_phi * sin_lambda, - (a + height) * sin_phi ); + (a + height) * cos_phi * cos_lambda, + (a + height) * cos_phi * sin_lambda, + (a + height) * sin_phi ); } const double N_phi = a * a / std::sqrt(a * a * cos_phi * cos_phi + b * b * sin_phi * sin_phi); return PointXYZ( - (N_phi + height) * cos_phi * cos_lambda, - (N_phi + height) * cos_phi * sin_lambda, - (N_phi * (b * b) / (a * a) + height) * sin_phi ); + (N_phi + height) * cos_phi * cos_lambda, + (N_phi + height) * cos_phi * sin_lambda, + (N_phi * (b * b) / (a * a) + height) * sin_phi ); } @@ -172,13 +186,13 @@ PointLonLat Sphere::convertCartesianToSpherical(const PointXYZ& p, const double& // numerical conditioning for both z (poles) and y const double - x = p.x(), - y = eckit::types::is_approximately_equal(p.y(), 0.) ? 0. : p.y(), - z = std::min(radius, std::max(-radius, p.z())) / radius; + x = p.x(), + y = eckit::types::is_approximately_equal(p.y(), 0.) ? 0. : p.y(), + z = std::min(radius, std::max(-radius, p.z())) / radius; return PointLonLat( - Constants::radiansToDegrees() * std::atan2(y, x), - Constants::radiansToDegrees() * std::asin(z) ); + Constants::radiansToDegrees() * std::atan2(y, x), + Constants::radiansToDegrees() * std::asin(z) ); } From ac48817e8652eb58e5eebad402a7a2b76809914d Mon Sep 17 00:00:00 2001 From: Tiago Quintino Date: Thu, 23 Nov 2017 12:14:53 +0000 Subject: [PATCH 195/355] Better error --- src/atlas/util/Earth.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index ea2ee0c78..b822b83ae 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -148,7 +148,14 @@ void Sphere::greatCircleLatitudeGivenLongitude(const PointLonLat& p1, const Poin PointXYZ Sphere::convertSphericalToCartesian(const PointLonLat& p, const double& radius, const double& height) { ASSERT(radius > 0.); - ASSERT(-90. <= p.lat() && p.lat() <= 90.); + if (!(-90. <= p.lat() && p.lat() <= 90.)) { + std::ostringstream oss; + oss << "Invalid latitute in convertSphericalToCartesian " + << p.lat() << " 90 - lat: " + << (90.0 - p.lat()) + << " -90 - lat: " << (-90.0 - p.lat()); + throw eckit::SeriousBug(oss.str(), Here()); + } // See https://en.wikipedia.org/wiki/Reference_ellipsoid#Coordinates // numerical conditioning for both ϕ (poles) and λ (Greenwich/Date Line) From b0302eeaf089c495c61725d56cd7a36871d7bd3f Mon Sep 17 00:00:00 2001 From: Tiago Quintino Date: Thu, 23 Nov 2017 13:37:18 +0000 Subject: [PATCH 196/355] ATLAS-139: fix comparison under non-IEEE 754 conformant rules --- src/atlas/util/Earth.cc | 126 ++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 62 deletions(-) diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index b822b83ae..e32755651 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -12,6 +12,8 @@ #include "atlas/util/Earth.h" #include +#include + #include "eckit/types/FloatCompare.h" #include "eckit/exception/Exceptions.h" #include "atlas/util/Constants.h" @@ -22,8 +24,7 @@ namespace atlas { namespace util { -//------------------------------------------------------------------------------------------------------ - +//---------------------------------------------------------------------------------------------------------------------- static inline double between_m180_and_p180(double a) { while (a > 180) { @@ -36,8 +37,7 @@ static inline double between_m180_and_p180(double a) { } -//------------------------------------------------------------------------------------------------------ - +//---------------------------------------------------------------------------------------------------------------------- double Sphere::centralAngle(const PointLonLat& p1, const PointLonLat& p2) { using namespace std; @@ -57,38 +57,40 @@ double Sphere::centralAngle(const PointLonLat& p1, const PointLonLat& p2) { * doi = {10.1179/sre.1975.23.176.88} * } */ - if (!(-90. <= p1.lat() && p1.lat() <= 90.)) { + + // guard against non-IEEE 754 conformant operations that may give latitudes not exaclty 90. + const double p1_lat = eckit::types::is_approximately_equal(p1.lat(), 90.) ? 90. : p1.lat(); + if (!(-90. <= p1_lat && p1_lat <= 90.)) { std::ostringstream oss; - oss << "Invalid greatCircleLatitudeGivenLongitude " - << p1.lat() << " 90 - lat: " - << (90.0 - p1.lat()) - << " -90 - lat: " << (-90.0 - p1.lat()); - throw eckit::SeriousBug(oss.str()); + oss.precision(std::numeric_limits::max_digits10); + oss << "Invalid latitude " << p1.lat(); + throw eckit::BadValue(oss.str(), Here()); } - if (!(-90. <= p2.lat() && p2.lat() <= 90.)) { + + // guard against non-IEEE 754 conformant operations that may give latitudes not exaclty 90. + const double p2_lat = eckit::types::is_approximately_equal(p2.lat(), 90.) ? 90. : p2.lat(); + if (!(-90. <= p2_lat && p2_lat <= 90.)) { std::ostringstream oss; - oss << "Invalid greatCircleLatitudeGivenLongitude " - << p2.lat() << " 90 - lat: " - << (90.0 - p2.lat()) - << " -90 - lat: " << (-90.0 - p2.lat()); - throw eckit::SeriousBug(oss.str()); + oss.precision(std::numeric_limits::max_digits10); + oss << "Invalid latitude " << p2.lat(); + throw eckit::BadValue(oss.str(), Here()); } - const double - phi1 = Constants::degreesToRadians() * p1.lat(), - phi2 = Constants::degreesToRadians() * p2.lat(), - lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()), + const double phi1 = Constants::degreesToRadians() * p1_lat; + const double phi2 = Constants::degreesToRadians() * p2_lat; + const double lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()); - cos_phi1 = cos(phi1), - sin_phi1 = sin(phi1), - cos_phi2 = cos(phi2), - sin_phi2 = sin(phi2), - cos_lambda = cos(lambda), - sin_lambda = sin(lambda), + const double cos_phi1 = cos(phi1); + const double sin_phi1 = sin(phi1); + const double cos_phi2 = cos(phi2); + const double sin_phi2 = sin(phi2); + const double cos_lambda = cos(lambda); + const double sin_lambda = sin(lambda); - angle = atan2( - sqrt(pow(cos_phi2 * sin_lambda, 2) + pow(cos_phi1 * sin_phi2 - sin_phi1 * cos_phi2 * cos_lambda, 2)), - sin_phi1 * sin_phi2 + cos_phi1 * cos_phi2 * cos_lambda ); + const double angle = atan2( + sqrt(pow(cos_phi2 * sin_lambda, 2) + + pow(cos_phi1 * sin_phi2 - sin_phi1 * cos_phi2 * cos_lambda, 2)), + sin_phi1 * sin_phi2 + cos_phi1 * cos_phi2 * cos_lambda ); if (eckit::types::is_approximately_equal(angle, 0.)) { return 0.; @@ -109,9 +111,8 @@ double Sphere::centralAngle(const PointXYZ& p1, const PointXYZ& p2, const double return 0.; } - const double - chord = std::sqrt(d2) / radius, - angle = std::asin(chord * 0.5) * 2.; + const double chord = std::sqrt(d2) / radius; + const double angle = std::asin(chord * 0.5) * 2.; return angle; } @@ -133,12 +134,12 @@ void Sphere::greatCircleLatitudeGivenLongitude(const PointLonLat& p1, const Poin // Intermediate great circle points (not applicable for meridians), see // http://www.edwilliams.org/avform.htm#Int ASSERT(!eckit::types::is_approximately_equal(p1.lon(), p2.lon())); - const double - phi1 = Constants::degreesToRadians() * p1.lat(), - phi2 = Constants::degreesToRadians() * p2.lat(), - lambda1p = Constants::degreesToRadians() * (p.lon() - p1.lon()), - lambda2p = Constants::degreesToRadians() * (p.lon() - p2.lon()), - lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()); + + const double phi1 = Constants::degreesToRadians() * p1.lat(); + const double phi2 = Constants::degreesToRadians() * p2.lat(); + const double lambda1p = Constants::degreesToRadians() * (p.lon() - p1.lon()); + const double lambda2p = Constants::degreesToRadians() * (p.lon() - p2.lon()); + const double lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()); p.lat() = Constants::radiansToDegrees() * atan( (tan(phi2) * sin(lambda1p) - tan(phi1) * sin(lambda2p)) / @@ -148,32 +149,32 @@ void Sphere::greatCircleLatitudeGivenLongitude(const PointLonLat& p1, const Poin PointXYZ Sphere::convertSphericalToCartesian(const PointLonLat& p, const double& radius, const double& height) { ASSERT(radius > 0.); - if (!(-90. <= p.lat() && p.lat() <= 90.)) { + + // guard against non-IEEE 754 conformant operations that may give latitudes not exaclty 90. + const double lat = eckit::types::is_approximately_equal(p.lat(), 90.) ? 90. : p.lat(); + if (!(-90. <= lat && lat <= 90.)) { std::ostringstream oss; - oss << "Invalid latitute in convertSphericalToCartesian " - << p.lat() << " 90 - lat: " - << (90.0 - p.lat()) - << " -90 - lat: " << (-90.0 - p.lat()); - throw eckit::SeriousBug(oss.str(), Here()); + oss.precision(std::numeric_limits::max_digits10); + oss << "Invalid latitude " << p.lat(); + throw eckit::BadValue(oss.str(), Here()); } // See https://en.wikipedia.org/wiki/Reference_ellipsoid#Coordinates // numerical conditioning for both ϕ (poles) and λ (Greenwich/Date Line) - const double - &a = radius, - &b = radius, + const double& a = radius; + const double& b = radius; + + const double lambda_deg = between_m180_and_p180(p.lon()); + const double lambda = Constants::degreesToRadians() * lambda_deg; + const double phi = Constants::degreesToRadians() * p.lat(); - lambda_deg = between_m180_and_p180(p.lon()), - lambda = Constants::degreesToRadians() * lambda_deg, - phi = Constants::degreesToRadians() * p.lat(), + const double sin_phi = std::sin(phi); + const double cos_phi = std::sqrt(1. - sin_phi * sin_phi); + const double sin_lambda = std::abs(lambda_deg) < 180. ? std::sin(lambda) : 0.; + const double cos_lambda = std::abs(lambda_deg) > 90. ? std::cos(lambda) : std::sqrt(1. - sin_lambda * sin_lambda); - sin_phi = std::sin(phi), - cos_phi = std::sqrt(1. - sin_phi * sin_phi), - sin_lambda = std::abs(lambda_deg) < 180. ? std::sin(lambda) : 0., - cos_lambda = std::abs(lambda_deg) > 90. ? std::cos(lambda) : std::sqrt(1. - sin_lambda * sin_lambda); + if (eckit::types::is_approximately_equal(a,b)) { // no eccentricity case - if (a == b) { - // no eccentricity return PointXYZ( (a + height) * cos_phi * cos_lambda, (a + height) * cos_phi * sin_lambda, @@ -181,6 +182,7 @@ PointXYZ Sphere::convertSphericalToCartesian(const PointLonLat& p, const double& } const double N_phi = a * a / std::sqrt(a * a * cos_phi * cos_phi + b * b * sin_phi * sin_phi); + return PointXYZ( (N_phi + height) * cos_phi * cos_lambda, (N_phi + height) * cos_phi * sin_lambda, @@ -192,10 +194,10 @@ PointLonLat Sphere::convertCartesianToSpherical(const PointXYZ& p, const double& ASSERT(radius > 0.); // numerical conditioning for both z (poles) and y - const double - x = p.x(), - y = eckit::types::is_approximately_equal(p.y(), 0.) ? 0. : p.y(), - z = std::min(radius, std::max(-radius, p.z())) / radius; + + const double x = p.x(); + const double y = eckit::types::is_approximately_equal(p.y(), 0.) ? 0. : p.y(); + const double z = std::min(radius, std::max(-radius, p.z())) / radius; return PointLonLat( Constants::radiansToDegrees() * std::atan2(y, x), @@ -203,7 +205,7 @@ PointLonLat Sphere::convertCartesianToSpherical(const PointXYZ& p, const double& } -//------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- double Earth::centralAngle(const PointLonLat& p1, const PointLonLat& p2) { @@ -241,7 +243,7 @@ PointLonLat Earth::convertGeocentricToGeodetic(const PointXYZ& p, const double& } -//------------------------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------------------------------------------- } // namespace util From 4e230c7a7cef6ef9d155bf62189995c098cac507 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 23 Nov 2017 15:20:26 +0000 Subject: [PATCH 197/355] Fix compilation of atlas_test_functionspace without transi --- src/tests/functionspace/test_functionspace.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index ce877e592..55ccbfcbb 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -24,7 +24,6 @@ #include "atlas/field/Field.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/trans/Trans.h" -#include "atlas/trans/ifs/TransIFS.h" using namespace eckit; From 256c99a0abc7aa74c9b1f689b158c6831a907484 Mon Sep 17 00:00:00 2001 From: Tiago Quintino Date: Thu, 23 Nov 2017 17:41:31 +0000 Subject: [PATCH 198/355] ATLAS-139: undo the fix --- src/atlas/util/Earth.cc | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index e32755651..9161e5e64 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -19,11 +19,9 @@ #include "atlas/util/Constants.h" #include "atlas/util/Point.h" - namespace atlas { namespace util { - //---------------------------------------------------------------------------------------------------------------------- static inline double between_m180_and_p180(double a) { @@ -58,26 +56,22 @@ double Sphere::centralAngle(const PointLonLat& p1, const PointLonLat& p2) { * } */ - // guard against non-IEEE 754 conformant operations that may give latitudes not exaclty 90. - const double p1_lat = eckit::types::is_approximately_equal(p1.lat(), 90.) ? 90. : p1.lat(); - if (!(-90. <= p1_lat && p1_lat <= 90.)) { + if (!(-90. <= p1.lat() && p1.lat() <= 90.)) { std::ostringstream oss; oss.precision(std::numeric_limits::max_digits10); oss << "Invalid latitude " << p1.lat(); throw eckit::BadValue(oss.str(), Here()); } - // guard against non-IEEE 754 conformant operations that may give latitudes not exaclty 90. - const double p2_lat = eckit::types::is_approximately_equal(p2.lat(), 90.) ? 90. : p2.lat(); - if (!(-90. <= p2_lat && p2_lat <= 90.)) { + if (!(-90. <= p2.lat() && p2.lat() <= 90.)) { std::ostringstream oss; oss.precision(std::numeric_limits::max_digits10); oss << "Invalid latitude " << p2.lat(); throw eckit::BadValue(oss.str(), Here()); } - const double phi1 = Constants::degreesToRadians() * p1_lat; - const double phi2 = Constants::degreesToRadians() * p2_lat; + const double phi1 = Constants::degreesToRadians() * p1.lat(); + const double phi2 = Constants::degreesToRadians() * p2.lat(); const double lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()); const double cos_phi1 = cos(phi1); @@ -150,9 +144,7 @@ void Sphere::greatCircleLatitudeGivenLongitude(const PointLonLat& p1, const Poin PointXYZ Sphere::convertSphericalToCartesian(const PointLonLat& p, const double& radius, const double& height) { ASSERT(radius > 0.); - // guard against non-IEEE 754 conformant operations that may give latitudes not exaclty 90. - const double lat = eckit::types::is_approximately_equal(p.lat(), 90.) ? 90. : p.lat(); - if (!(-90. <= lat && lat <= 90.)) { + if (!(-90. <= p.lat() && p.lat() <= 90.)) { std::ostringstream oss; oss.precision(std::numeric_limits::max_digits10); oss << "Invalid latitude " << p.lat(); From fd9613b2c7ecf23703921bb7c6d72fc357147742 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 23 Nov 2017 18:57:49 +0000 Subject: [PATCH 199/355] Revert "Update bamboo's cmake version when using fckit" This reverts commit d1c0dd8e241f2b17a1b2d8147d98546d48b85520. --- bamboo/opensuse131-env.sh | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/bamboo/opensuse131-env.sh b/bamboo/opensuse131-env.sh index 95fcd1563..656adf2da 100755 --- a/bamboo/opensuse131-env.sh +++ b/bamboo/opensuse131-env.sh @@ -3,13 +3,4 @@ # CC=mpicc # CXX=mpicxx # FC=mpif90 -ulimit -s unlimited - -# Initialise module environment if it is not -if [[ ! $(command -v module > /dev/null 2>&1) ]]; then - . /usr/local/apps/module/init/bash -fi - -# Minimum required cmake (3.1) when using fckit only -module unload cmake -module load cmake/3.7.1 +ulimit -s unlimited \ No newline at end of file From baa0b6b505453fe76b007195f90b39b95c6094eb Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 23 Nov 2017 19:22:20 +0000 Subject: [PATCH 200/355] ATLAS-138 Development of an ArraySlicer --- src/atlas/array/LocalView.h | 8 +- .../array/gridtools/GridToolsArrayView.h | 2 +- src/atlas/array/helpers/ArraySlicer.h | 240 ++++++++++++------ src/atlas/array/native/NativeArrayView.h | 5 +- src/tests/array/test_array_slicer.cc | 89 +++++-- 5 files changed, 245 insertions(+), 99 deletions(-) diff --git a/src/atlas/array/LocalView.h b/src/atlas/array/LocalView.h index 745b70878..4f9277982 100644 --- a/src/atlas/array/LocalView.h +++ b/src/atlas/array/LocalView.h @@ -44,6 +44,7 @@ #include #include "atlas/library/config.h" #include "atlas/array/ArrayUtil.h" +#include "atlas/array/ArrayViewDefs.h" //------------------------------------------------------------------------------------------------------ @@ -58,6 +59,9 @@ class LocalView { using value_type = typename remove_const::type; using Slice = typename std::conditional<(Rank==1), value_type&, LocalView >::type; + static constexpr Intent ACCESS{Intent::ReadWrite}; + static constexpr int RANK{Rank}; + public: // -- Constructors @@ -114,6 +118,8 @@ class LocalView { size_t shape(size_t idx) const { return shape_[idx]; } + size_t stride(size_t idx) const { return strides_[idx]; } + value_type const* data() const { return data_; } value_type* data() { return data_; } @@ -126,7 +132,7 @@ class LocalView { void dump(std::ostream& os) const; - static constexpr int rank() { return Rank; } + static constexpr size_t rank() { return Rank; } private: diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 0d22dd579..369e22c6e 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -103,7 +103,7 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas return gt_data_view_.storage_info().template stride(); } - size_t rank() const { return Rank; } + static constexpr size_t rank() { return Rank; } size_t size() const { return size_; } bool valid() const; diff --git a/src/atlas/array/helpers/ArraySlicer.h b/src/atlas/array/helpers/ArraySlicer.h index 96e876807..1bfdf5d0f 100644 --- a/src/atlas/array/helpers/ArraySlicer.h +++ b/src/atlas/array/helpers/ArraySlicer.h @@ -10,8 +10,7 @@ #pragma once -#include - +#include "atlas/runtime/Log.h" #include "atlas/array.h" //------------------------------------------------------------------------------ @@ -20,20 +19,66 @@ namespace atlas { namespace array { namespace helpers { +class RangeBase {}; + +class From : public RangeBase { +public: + From(int start) : start_(start) {} + + int start() const { return start_; } + + template < int Dim, typename View > + int end(const View& view) const { return view.shape(Dim); } + +private: + int start_; +}; -class Range { +class To : public RangeBase { public: - int start; - int end; + To(int end) : end_(end) {} + + int start() const { return 0; } + int end() const { return end_; } + +private: + int end_; }; +class All : public RangeBase { +public: + All() {} + + int start() const { return 0; } + + template < int Dim, typename View > + int end(const View& view) const { return view.shape(Dim); } +}; + +class Range : public RangeBase{ +public: + Range(int start, int end ) : start_(start), end_(end) {} + int start() const { return start_; } + int end() const { return end_; } + + static From from(int start) { return From(start); } + static To to(int end) { return To(end); } + static All all() { return All(); } + +private: + int start_; + int end_; +}; + + + class Index { public: int index; }; template< int Rank, typename ...Args > -struct SliceRank; +struct SliceRank_impl; @@ -47,7 +92,7 @@ struct deduce_slice_rank<1> { template static constexpr int apply() { - return std::is_same::value; + return std::is_base_of::value; } }; @@ -58,12 +103,12 @@ struct deduce_slice_rank { \ \ template \ static constexpr int apply() { \ - return std::is_same::value + deduce_slice_rank::apply(); \ + return std::is_base_of::value + deduce_slice_rank::apply(); \ } \ \ }; \ template \ -struct SliceRank \ +struct SliceRank_impl \ { \ enum { value = deduce_slice_rank::apply() }; \ } @@ -79,49 +124,64 @@ EXPLICIT_TEMPLATE_SPECIALISATION(9); #undef EXPLICIT_TEMPLATE_SPECIALISATION template -struct SliceRank<1,Args...> +struct SliceRank_impl<1,Args...> { enum { value = deduce_slice_rank<1>::apply() }; }; +template +struct get_slice_type { + using type = + typename std::conditional<(RANK==0), + typename std::conditional<(Access==Intent::ReadOnly), + const Value&, + Value& + >::type, + LocalView + >::type; +}; - -template +//template +template class ArraySlicer { public: - using value_type = Value; - template - struct Slice { - using type = typename std::conditional<(RANK==0), - typename std::conditional<(Access==Intent::ReadOnly), - const value_type&, - value_type& - >::type, - LocalView - >::type; - }; - ArraySlicer(ArrayView& av) : - av_(av) { + ArraySlicer(View& view) : + view_(view) { } template - typename Slice< SliceRank::value >::type apply(const Args ...args) const { - using ReturnType = typename Slice< SliceRank::value >::type; - return Slicer< ReturnType, (SliceRank::value==0) >::apply( av_, args... ); + struct SliceRank { + static constexpr int value{ SliceRank_impl::value }; + }; + + template + struct Slice { + using type = typename get_slice_type< typename View::value_type, SliceRank::value, View::ACCESS >::type; + }; + + template + typename Slice::type apply(const Args ...args) const { + using slicer_t = Slicer< typename Slice::type, (SliceRank::value==0) >; + return slicer_t::apply( view_, args... ); } private: + template + struct array { + using type = typename std::array::value >; + }; + template struct Slicer { template< typename ...Args > - static ReturnType apply(ArrayView& av, const Args...args) { + static ReturnType apply(View& view, const Args...args) { return ReturnType( - av.data()+offset(av,args...), - shape(av,args...).data(), - strides(av,args...).data() + view.data()+offset(view,args...), + shape(view,args...).data(), + strides(view,args...).data() ); } }; @@ -129,105 +189,133 @@ class ArraySlicer { template struct Slicer { template< typename ...Args > - static ReturnType apply(ArrayView& av, const Args...args) { - return *(av.data()+offset(av,args...)); + static ReturnType apply(View& view, const Args...args) { + return *(view.data()+offset(view,args...)); } }; template< typename Int > - static int start(Int idx) { + static int start( Int idx ) { return idx; } - static int start(Range range) { - return range.start; + static int start( Range range ) { + return range.start(); + } + + static int start( All range ) { + return range.start(); + } + + static int start( To range ) { + return range.start(); + } + + static int start( From range ) { + return range.start(); } template < int Dim, typename Int, typename... Ints > - static constexpr int offset_part(ArrayView& av, const Int idx, const Ints... next_idx) { - return start(idx)*av.stride(Dim) + offset_part( av, next_idx... ); + static constexpr int offset_part(View& view, const Int idx, const Ints... next_idx) { + return start(idx)*view.stride(Dim) + offset_part( view, next_idx... ); } template < int Dim, typename Int > - static constexpr int offset_part(ArrayView& av, const Int last_idx) { - return start(last_idx)*av.stride(Dim); + static constexpr int offset_part(View& view, const Int last_idx) { + return start(last_idx)*view.stride(Dim); } template < typename... Args > - static constexpr int offset(ArrayView& av, const Args... args) { - return offset_part<0>(av,args...); + static constexpr int offset(View& view, const Args... args) { + return offset_part<0>(view,args...); } - template< typename Shape, typename Int > - static void update_shape( Shape& shape, int& i, const Int& ){ + template< int Dim, typename Shape, typename Int > + static void update_shape( View&, Shape&, int& /*i*/, const Int& /*index*/ ){ // do nothing } - template< typename Shape > - static void update_shape( Shape& shape, int& i, const Range range ){ - shape[i++] = range.end-range.start; + template< int Dim, typename Shape > + static void update_shape( View&, Shape& shape, int& i, const Range range ){ + shape[i++] = range.end()-range.start(); + } + template< int Dim, typename Shape > + static void update_shape( View& view, Shape& shape, int& i, const All range ){ + shape[i++] = range.end(view)-range.start(); + } + template< int Dim, typename Shape > + static void update_shape( View& view, Shape& shape, int& i, const From range ){ + shape[i++] = range.end(view)-range.start(); + } + template< int Dim, typename Shape > + static void update_shape( View&, Shape& shape, int& i, const To range ){ + shape[i++] = range.end()-range.start(); } template< int Dim, typename Shape, typename Int, typename... Ints > - static void shape_part( ArrayView& av, Shape& shape, int& i, const Int idx, const Ints... next_idx ) { - update_shape(shape,i,idx); - shape_part(av,shape,i,next_idx...); + static void shape_part( View& view, Shape& shape, int& i, const Int idx, const Ints... next_idx ) { + update_shape(view,shape,i,idx); + shape_part(view,shape,i,next_idx...); } template< int Dim, typename Shape, typename Int > - static void shape_part( ArrayView& , Shape& shape, int& i, const Int idx) { - update_shape(shape,i,idx); + static void shape_part( View& view, Shape& shape, int& i, const Int idx) { + update_shape(view,shape,i,idx); } template< typename... Args > - static std::array::value> shape(ArrayView& av, const Args... args ) { - std::array::value> result; + static typename array::type shape( View& view, const Args... args ) { + typename array::type result; int i(0); - shape_part<0>(av,result,i,args...); + shape_part<0>(view,result,i,args...); return result; } template - static void update_strides( ArrayView&, Strides&, int& /*i*/, const Int& /*idx*/) { + static void update_strides( View&, Strides&, int& /*i*/, const Int& /*idx*/) { // do nothing } template - static void update_strides( ArrayView& av, Strides& strides, int& i, const Range& /*range*/ ) { - strides[i++] = av.stride(Dim); + static void update_strides( View& view, Strides& strides, int& i, const Range& /*range*/ ) { + strides[i++] = view.stride(Dim); + } + template + static void update_strides( View& view, Strides& strides, int& i, const From& /*range*/ ) { + strides[i++] = view.stride(Dim); + } + template + static void update_strides( View& view, Strides& strides, int& i, const To& /*range*/ ) { + strides[i++] = view.stride(Dim); + } + template + static void update_strides( View& view, Strides& strides, int& i, const All& /*range*/ ) { + strides[i++] = view.stride(Dim); } template< int Dim, typename Strides, typename Int, typename... Ints > - static void strides_part( ArrayView& av, Strides& strides, int& i, const Int idx, const Ints... next_idx ) { - update_strides(av,strides,i,idx); - strides_part(av,strides,i,next_idx...); + static void strides_part( View& view, Strides& strides, int& i, const Int idx, const Ints... next_idx ) { + update_strides(view,strides,i,idx); + strides_part(view,strides,i,next_idx...); } template< int Dim, typename Strides, typename Int > - static void strides_part( ArrayView& av, Strides& strides, int& i, const Int idx) { - update_strides(av,strides,i,idx); + static void strides_part( View& view, Strides& strides, int& i, const Int idx) { + update_strides(view,strides,i,idx); } template< typename... Args > - static std::array::value> strides(ArrayView& av, const Args... args ) { - std::array::value> result; + static typename array::type strides(View& view, const Args... args ) { + typename array::type result; int i(0); - strides_part<0>(av,result,i,args...); + strides_part<0>(view,result,i,args...); return result; } private: - ArrayView& av_; + View& view_; }; -//template -//struct ArraySlicer { -// ArraySlicer(ArrayView const& av) : av_(av) {} -// ArrayView const& av_; -// ReturnType apply(const size_t i) const { -// return *(av_.data_ + av_.strides_[0] * i); -// } -//}; //------------------------------------------------------------------------------ } // namespace helpers diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 763af1495..64546294f 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -71,6 +71,9 @@ template class using value_type = typename remove_const::type; using Slice = typename std::conditional<(Rank==1), value_type&, LocalView >::type; + static constexpr Intent ACCESS{AccessMode}; + static constexpr int RANK{Rank}; + public: // -- Constructors @@ -138,7 +141,7 @@ template class size_t size() const { return size_;} - size_t rank() const { return Rank; } + static constexpr size_t rank() { return Rank; } const size_t* strides() const { return strides_.data(); } diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index 3fc9b4218..7ac37521e 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -32,8 +32,8 @@ struct Slice { struct Slicer { template< int Rank, typename ...Args > - static typename Slice::value>::type apply(Args... args) { - typename Slice::value>::type a; + static typename Slice::value>::type apply(Args... args) { + typename Slice::value>::type a; } }; @@ -45,32 +45,34 @@ namespace test { CASE( "test_SliceRank" ){ - static_assert( SliceRank<1,int >::value == 0, "failed" ); - static_assert( SliceRank<1,Range>::value == 1, "failed" ); + static_assert( SliceRank_impl<1,int >::value == 0, "failed" ); + static_assert( SliceRank_impl<1,Range>::value == 1, "failed" ); - static_assert( SliceRank<2,int, int >::value == 0, "failed" ); - static_assert( SliceRank<2,Range,int >::value == 1, "failed" ); - static_assert( SliceRank<2,Range,Range>::value == 2, "failed" ); + static_assert( SliceRank_impl<2,int, int >::value == 0, "failed" ); + static_assert( SliceRank_impl<2,Range,int >::value == 1, "failed" ); + static_assert( SliceRank_impl<2,Range,Range>::value == 2, "failed" ); - static_assert( SliceRank<3,int, int ,int >::value == 0, "failed" ); - static_assert( SliceRank<3,Range,int ,int >::value == 1, "failed" ); - static_assert( SliceRank<3,Range,Range,int >::value == 2, "failed" ); - static_assert( SliceRank<3,int, int ,Range>::value == 1, "failed" ); - static_assert( SliceRank<3,Range,int ,Range>::value == 2, "failed" ); - static_assert( SliceRank<3,Range,Range,Range>::value == 3, "failed" ); - static_assert( SliceRank<3,Range,int ,Range>::value == 2, "failed" ); - static_assert( SliceRank<3,int ,int ,Range>::value == 1, "failed" ); - static_assert( SliceRank<3,int ,Range,Range>::value == 2, "failed" ); + static_assert( SliceRank_impl<3,int, int ,int >::value == 0, "failed" ); + static_assert( SliceRank_impl<3,Range,int ,int >::value == 1, "failed" ); + static_assert( SliceRank_impl<3,Range,Range,int >::value == 2, "failed" ); + static_assert( SliceRank_impl<3,int, int ,Range>::value == 1, "failed" ); + static_assert( SliceRank_impl<3,Range,int ,Range>::value == 2, "failed" ); + static_assert( SliceRank_impl<3,Range,Range,Range>::value == 3, "failed" ); + static_assert( SliceRank_impl<3,Range,int ,Range>::value == 2, "failed" ); + static_assert( SliceRank_impl<3,int ,int ,Range>::value == 1, "failed" ); + static_assert( SliceRank_impl<3,int ,Range,Range>::value == 2, "failed" ); } +#if 1 CASE( "test_array_slicer_1d" ) { ArrayT arr(10); auto view = make_view(arr); view.assign( {0,1,2,3,4,5,6,7,8,9} ); - ArraySlicer slicer(view); + using View = decltype(view); + ArraySlicer slicer(view); { auto slice = slicer.apply(Range{0,2}); @@ -100,7 +102,7 @@ CASE( "test_array_slicer_1d" ) } } - +#endif CASE( "test_array_slicer_2d" ) { ArrayT arr(3,5); @@ -108,8 +110,10 @@ CASE( "test_array_slicer_2d" ) view.assign( {11,12,13,14,15, 21,22,23,24,25, 31,32,33,34,35, } ); + using View = decltype(view); + ArraySlicer slicer(view); - ArraySlicer slicer(view); +// ArraySlicer slicer(view); { auto slice = slicer.apply(Range{0,2},2); @@ -139,7 +143,8 @@ CASE( "test_array_slicer_3d" ) 221,222,223,224,225, 231,232,233,234,235} ); - ArraySlicer slicer(view); + using View = decltype(view); + ArraySlicer slicer(view); { auto slice = slicer.apply(Range{0,2},2,Range{2,5}); @@ -154,6 +159,23 @@ CASE( "test_array_slicer_3d" ) EXPECT( slice(1,2) == 235 ); } + { + auto slice = slicer.apply(0,0,Range::from(3)); + EXPECT( slice.rank() == 1 ); + EXPECT( slice.shape(0) == 2 ); + EXPECT( slice(0) == 114 ); + EXPECT( slice(1) == 115 ); + } + + { + auto slice = slicer.apply(1,Range::all(),3); + EXPECT( slice.rank() == 1 ); + EXPECT( slice.shape(0) == 3 ); + EXPECT( slice(0) == 214 ); + EXPECT( slice(1) == 224 ); + EXPECT( slice(2) == 234 ); + } + { const double& slice = slicer.apply(1,2,3); EXPECT( slice == 234 ); @@ -162,6 +184,33 @@ CASE( "test_array_slicer_3d" ) } +CASE( "test_array_slicer_of_slice" ) +{ + ArrayT arr(2,3,5); + auto view = make_view(arr); + view.assign( {111,112,113,114,115, + 121,122,123,124,125, + 131,132,133,134,135, + + 211,212,213,214,215, + 221,222,223,224,225, + 231,232,233,234,235} ); + + using View = decltype(view); + ArraySlicer slicer(view); + + auto slice = slicer.apply(Range{0,2},2,Range{2,5}); + + using Slice = decltype(slice); + ArraySlicer subslicer(slice); + + auto subslice1 = subslicer.apply(0,0); + auto subslice2 = subslicer.apply(Range::all(),Range::all()); + auto subslice3 = subslicer.apply(Range::all(),0); + auto subslice4 = subslicer.apply(0,Range::to(2)); +} + + //----------------------------------------------------------------------------- } // namespace test From 91fb395aed515d051e6f865e69a4276c15ee9200 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 24 Nov 2017 13:32:48 +0000 Subject: [PATCH 201/355] ATLAS-138 slice function for NativeArrayView --- src/atlas/CMakeLists.txt | 2 + src/atlas/array/Range.h | 98 ++++++++++++++ src/atlas/array/helpers/ArraySlicer.h | 155 +++++++++-------------- src/atlas/array/native/NativeArrayView.h | 39 ++++-- src/tests/array/test_array_slicer.cc | 95 +++++++++++++- 5 files changed, 280 insertions(+), 109 deletions(-) create mode 100644 src/atlas/array/Range.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 75b631a4e..b4a409ee0 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -393,11 +393,13 @@ array/DataType.h array/IndexView.h array/LocalView.cc array/LocalView.h +array/Range.h array/StorageView.h array/Vector.h array/helpers/ArrayInitializer.h array/helpers/ArrayAssigner.h array/helpers/ArrayWriter.h +array/helpers/ArraySlicer.h #array/Table.h #array/Table.cc #array/TableView.h diff --git a/src/atlas/array/Range.h b/src/atlas/array/Range.h new file mode 100644 index 000000000..8b657bbea --- /dev/null +++ b/src/atlas/array/Range.h @@ -0,0 +1,98 @@ +/* + * (C) Copyright 1996-2016 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 + +//------------------------------------------------------------------------------ + +namespace atlas { +namespace array { + +//------------------------------------------------------------------------------ + +namespace helpers { + +//------------------------------------------------------------------------------ + +class RangeBase {}; + +//------------------------------------------------------------------------------ + +class RangeFrom : public RangeBase { +public: + RangeFrom(int start) : start_(start) {} + + int start() const { return start_; } + + template < int Dim, typename View > + int end(const View& view) const { return view.shape(Dim); } + +private: + int start_; +}; + +//------------------------------------------------------------------------------ + +class RangeTo : public RangeBase { +public: + RangeTo(int end) : end_(end) {} + + int start() const { return 0; } + + int end() const { return end_; } + +private: + int end_; +}; + +//------------------------------------------------------------------------------ + +class RangeAll : public RangeBase { +public: + + int start() const { return 0; } + + template < int Dim, typename View > + int end(const View& view) const { return view.shape(Dim); } +}; + +//------------------------------------------------------------------------------ + +} // helpers + +//------------------------------------------------------------------------------ + +class Range : public helpers::RangeBase{ +private: + using From = helpers::RangeFrom; + using To = helpers::RangeTo; + using All = helpers::RangeAll; + +public: + + static From from(int start) { return From(start); } + static To to(int end) { return To(end); } + static All all() { return All(); } + +public: + + Range(int start, int end ) : start_(start), end_(end) {} + int start() const { return start_; } + int end() const { return end_; } + +private: + int start_; + int end_; +}; + +//------------------------------------------------------------------------------ + +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/helpers/ArraySlicer.h b/src/atlas/array/helpers/ArraySlicer.h index 1bfdf5d0f..9e529e5da 100644 --- a/src/atlas/array/helpers/ArraySlicer.h +++ b/src/atlas/array/helpers/ArraySlicer.h @@ -11,7 +11,9 @@ #pragma once #include "atlas/runtime/Log.h" -#include "atlas/array.h" +#include "atlas/array/ArrayViewDefs.h" +#include "atlas/array/LocalView.h" +#include "atlas/array/Range.h" //------------------------------------------------------------------------------ @@ -19,73 +21,11 @@ namespace atlas { namespace array { namespace helpers { -class RangeBase {}; - -class From : public RangeBase { -public: - From(int start) : start_(start) {} - - int start() const { return start_; } - - template < int Dim, typename View > - int end(const View& view) const { return view.shape(Dim); } - -private: - int start_; -}; - -class To : public RangeBase { -public: - To(int end) : end_(end) {} - - int start() const { return 0; } - int end() const { return end_; } - -private: - int end_; -}; - -class All : public RangeBase { -public: - All() {} - - int start() const { return 0; } - - template < int Dim, typename View > - int end(const View& view) const { return view.shape(Dim); } -}; - -class Range : public RangeBase{ -public: - Range(int start, int end ) : start_(start), end_(end) {} - int start() const { return start_; } - int end() const { return end_; } - - static From from(int start) { return From(start); } - static To to(int end) { return To(end); } - static All all() { return All(); } - -private: - int start_; - int end_; -}; - - - -class Index { -public: - int index; -}; - -template< int Rank, typename ...Args > -struct SliceRank_impl; - - - - template< int Dim > struct deduce_slice_rank; +template< int Rank, typename ...Args > +struct SliceRank_impl; template<> struct deduce_slice_rank<1> { @@ -96,8 +36,13 @@ struct deduce_slice_rank<1> { } }; +template +struct SliceRank_impl<1,Args...> { + static constexpr int value{ deduce_slice_rank<1>::apply() }; +}; -#define EXPLICIT_TEMPLATE_SPECIALISATION(RANK) \ + +#define ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(RANK) \ template<> \ struct deduce_slice_rank { \ \ @@ -110,34 +55,52 @@ struct deduce_slice_rank { \ template \ struct SliceRank_impl \ { \ - enum { value = deduce_slice_rank::apply() }; \ + static constexpr int value{ deduce_slice_rank::apply() }; \ } -EXPLICIT_TEMPLATE_SPECIALISATION(2); -EXPLICIT_TEMPLATE_SPECIALISATION(3); -EXPLICIT_TEMPLATE_SPECIALISATION(4); -EXPLICIT_TEMPLATE_SPECIALISATION(5); -EXPLICIT_TEMPLATE_SPECIALISATION(6); -EXPLICIT_TEMPLATE_SPECIALISATION(7); -EXPLICIT_TEMPLATE_SPECIALISATION(8); -EXPLICIT_TEMPLATE_SPECIALISATION(9); -#undef EXPLICIT_TEMPLATE_SPECIALISATION - -template -struct SliceRank_impl<1,Args...> -{ - enum { value = deduce_slice_rank<1>::apply() }; +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(2); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(3); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(4); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(5); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(6); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(7); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(8); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(9); +#undef ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION + +template +struct Reference { + Value& value; + operator Value&() { return value; } + template < typename T > void operator=(const T a) { value = a; } + template < typename T > Reference& operator+(const T a) { value+=a; return *this; } + template < typename T > Reference& operator-(const T a) { value-=a; return *this; } + Reference& operator--() { --value; return *this; } + Reference& operator++() { ++value; return *this; } }; -template +//template +//struct get_slice_type { +// using type = +// typename std::conditional<(Rank==0), +// typename std::conditional<(Access==Intent::ReadOnly), +// const Value&, +// Value& +// >::type, +// LocalView +// >::type; +//}; + + +template struct get_slice_type { using type = - typename std::conditional<(RANK==0), + typename std::conditional<(Rank==0), typename std::conditional<(Access==Intent::ReadOnly), - const Value&, - Value& + Reference, + Reference >::type, - LocalView + LocalView >::type; }; @@ -190,7 +153,7 @@ class ArraySlicer { struct Slicer { template< typename ...Args > static ReturnType apply(View& view, const Args...args) { - return *(view.data()+offset(view,args...)); + return ReturnType{*(view.data()+offset(view,args...))}; } }; @@ -203,15 +166,15 @@ class ArraySlicer { return range.start(); } - static int start( All range ) { + static int start( RangeAll range ) { return range.start(); } - static int start( To range ) { + static int start( RangeTo range ) { return range.start(); } - static int start( From range ) { + static int start( RangeFrom range ) { return range.start(); } @@ -240,15 +203,15 @@ class ArraySlicer { shape[i++] = range.end()-range.start(); } template< int Dim, typename Shape > - static void update_shape( View& view, Shape& shape, int& i, const All range ){ + static void update_shape( View& view, Shape& shape, int& i, const RangeAll range ){ shape[i++] = range.end(view)-range.start(); } template< int Dim, typename Shape > - static void update_shape( View& view, Shape& shape, int& i, const From range ){ + static void update_shape( View& view, Shape& shape, int& i, const RangeFrom range ){ shape[i++] = range.end(view)-range.start(); } template< int Dim, typename Shape > - static void update_shape( View&, Shape& shape, int& i, const To range ){ + static void update_shape( View&, Shape& shape, int& i, const RangeTo range ){ shape[i++] = range.end()-range.start(); } @@ -281,15 +244,15 @@ class ArraySlicer { strides[i++] = view.stride(Dim); } template - static void update_strides( View& view, Strides& strides, int& i, const From& /*range*/ ) { + static void update_strides( View& view, Strides& strides, int& i, const RangeFrom& /*range*/ ) { strides[i++] = view.stride(Dim); } template - static void update_strides( View& view, Strides& strides, int& i, const To& /*range*/ ) { + static void update_strides( View& view, Strides& strides, int& i, const RangeTo& /*range*/ ) { strides[i++] = view.stride(Dim); } template - static void update_strides( View& view, Strides& strides, int& i, const All& /*range*/ ) { + static void update_strides( View& view, Strides& strides, int& i, const RangeAll& /*range*/ ) { strides[i++] = view.stride(Dim); } diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 64546294f..77d5b6d98 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -54,6 +54,8 @@ #include #include "atlas/library/config.h" #include "atlas/array/ArrayUtil.h" +#include "atlas/array/Range.h" +#include "atlas/array/helpers/ArraySlicer.h" #include "atlas/array/LocalView.h" #include "atlas/array/ArrayViewDefs.h" @@ -69,11 +71,21 @@ template class // -- Type definitions using value_type = typename remove_const::type; - using Slice = typename std::conditional<(Rank==1), value_type&, LocalView >::type; - static constexpr Intent ACCESS{AccessMode}; static constexpr int RANK{Rank}; +private: + using slicer_t = typename helpers::ArraySlicer< ArrayView >; + + using SliceDepr = typename std::conditional<(Rank==1), value_type&, LocalView >::type; + + +public: + template< typename ...Args > + struct Slice { + using type = typename slicer_t::template Slice::type; + }; + public: // -- Constructors @@ -109,26 +121,26 @@ template class return data_[index(idx...)]; } - const Slice operator[](size_t i) const { - return Slicer(*this).apply(i); + const SliceDepr operator[](size_t i) const { + return Slicer(*this).apply(i); } - Slice operator[](size_t i) { - return Slicer(*this).apply(i); + SliceDepr operator[](size_t i) { + return Slicer(*this).apply(i); } - const Slice at(size_t i) const { + const SliceDepr at(size_t i) const { if( i>= shape(0) ) { throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); } - return Slicer(*this).apply(i); + return Slicer(*this).apply(i); } - Slice at(size_t i) { + SliceDepr at(size_t i) { if( i>= shape(0) ) { throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); } - return Slicer(*this).apply(i); + return Slicer(*this).apply(i); } template @@ -165,6 +177,11 @@ template class void dump(std::ostream& os) const; + template< typename ...Args > + typename Slice::type slice(Args... args) { + return slicer_t(*this).apply(args...); + } + private: // -- Private methods @@ -218,7 +235,7 @@ template class // -- Type definitions - template + template struct Slicer { Slicer(ArrayView const& av) : av_(av) {} ArrayView const& av_; diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index 7ac37521e..2a9ab0e5a 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -96,9 +96,9 @@ CASE( "test_array_slicer_1d" ) } { - const double& slice = slicer.apply(5); + auto slice = slicer.apply(5); EXPECT( slice == 5 ); - //static_assert( std::is_same< decltype(slice) , double& >::value, "failed" ); + static_assert( std::is_same< decltype(slice) , Reference >::value, "failed" ); } } @@ -211,6 +211,97 @@ CASE( "test_array_slicer_of_slice" ) } +CASE( "test_arrayview_slice_type" ) +{ + ArrayT arr(2,3,5); + + // Assign + { + auto view = make_view(arr); + view.assign( {111,112,113,114,115, + 121,122,123,124,125, + 131,132,133,134,135, + + 211,212,213,214,215, + 221,222,223,224,225, + 231,232,233,234,235} ); + } + + { + auto read_write_view = make_view(arr); + + auto slice1 = read_write_view.slice( Range{0,2}, 2, Range{2,5} ); + + EXPECT( slice1(0,0) == 133 ); + EXPECT( slice1(0,1) == 134 ); + EXPECT( slice1(0,2) == 135 ); + EXPECT( slice1(1,0) == 233 ); + EXPECT( slice1(1,1) == 234 ); + EXPECT( slice1(1,2) == 235 ); + + auto slice2 = read_write_view.slice( Range::all(), Range::to(2), Range::from(3) ); + + EXPECT( slice2(0,0,0) == 114 ); + EXPECT( slice2(0,0,1) == 115 ); + EXPECT( slice2(0,1,0) == 124 ); + EXPECT( slice2(0,1,1) == 125 ); + EXPECT( slice2(1,0,0) == 214 ); + EXPECT( slice2(1,0,1) == 215 ); + EXPECT( slice2(1,1,0) == 224 ); + EXPECT( slice2(1,1,1) == 225 ); + + auto slice3 = read_write_view.slice( 0, 1, 2 ); + + EXPECT( slice3 == 123 ); + + static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); + static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); + static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); + static_assert( std::is_same< decltype(slice3), Reference >::value, "failed" ); + } + + { + auto read_only_view = make_view(arr); + + auto slice1 = read_only_view.slice( Range{0,2}, 2, Range{2,5} ); + + EXPECT( slice1(0,0) == 133 ); + EXPECT( slice1(0,1) == 134 ); + EXPECT( slice1(0,2) == 135 ); + EXPECT( slice1(1,0) == 233 ); + EXPECT( slice1(1,1) == 234 ); + EXPECT( slice1(1,2) == 235 ); + + auto slice2 = read_only_view.slice( Range::all(), Range::to(2), Range::from(3) ); + + EXPECT( slice2(0,0,0) == 114 ); + EXPECT( slice2(0,0,1) == 115 ); + EXPECT( slice2(0,1,0) == 124 ); + EXPECT( slice2(0,1,1) == 125 ); + EXPECT( slice2(1,0,0) == 214 ); + EXPECT( slice2(1,0,1) == 215 ); + EXPECT( slice2(1,1,0) == 224 ); + EXPECT( slice2(1,1,1) == 225 ); + + auto slice3 = read_only_view.slice( 0, 1, 2 ); + + EXPECT( slice3 == 123 ); + + const double& slice4 = read_only_view.slice( 0, 1, 2 ); + + EXPECT( slice4 == 123 ); + + static_assert( read_only_view.ACCESS == Intent::ReadOnly, "failed" ); + static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); + static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); + static_assert( std::is_same< decltype(slice3), Reference>::value, "failed" ); + static_assert( std::is_same< decltype(slice4), double const& >::value , "failed" ); + + } + +} + + //----------------------------------------------------------------------------- } // namespace test From 4d0ca3d5bc8a444ee9755d60313edf10bc03b43d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 24 Nov 2017 14:58:19 +0000 Subject: [PATCH 202/355] ATLAS-138 Preparations for MIR --- src/atlas/interpolation/element/Quad3D.h | 15 +++++++++----- src/atlas/interpolation/element/Triag3D.h | 14 ++++++++----- .../interpolation/method/FiniteElement.cc | 20 +++++++++---------- .../method/KNearestNeighbours.cc | 2 +- .../method/KNearestNeighboursBase.cc | 4 ++-- .../interpolation/method/NearestNeighbour.cc | 2 +- src/atlas/interpolation/method/Ray.cc | 10 ++++++++++ src/atlas/interpolation/method/Ray.h | 11 +++++----- src/atlas/mesh/actions/BuildTorusXYZField.cc | 13 +++++------- 9 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/atlas/interpolation/element/Quad3D.h b/src/atlas/interpolation/element/Quad3D.h index 013cd651e..18f269358 100644 --- a/src/atlas/interpolation/element/Quad3D.h +++ b/src/atlas/interpolation/element/Quad3D.h @@ -15,6 +15,7 @@ #include "atlas/interpolation/Vector3D.h" #include "atlas/interpolation/method/Intersect.h" +#include "atlas/util/Point.h" namespace atlas { namespace interpolation { @@ -28,11 +29,15 @@ namespace element { class Quad3D { public: - Quad3D(const double* x0, const double* x1, const double* x2, const double* x3) { - v00 = Vector3D::Map(x0); - v10 = Vector3D::Map(x1); - v11 = Vector3D::Map(x2); - v01 = Vector3D::Map(x3); + Quad3D(const double* x0, const double* x1, const double* x2, const double* x3) : + v00(x0), + v10(x1), + v11(x2), + v01(x3) { + } + + Quad3D(const PointXYZ& x0, const PointXYZ& x1, const PointXYZ& x2, const PointXYZ& x3) : + Quad3D(x0.data(),x1.data(),x2.data(),x3.data()) { } method::Intersect intersects( diff --git a/src/atlas/interpolation/element/Triag3D.h b/src/atlas/interpolation/element/Triag3D.h index 55ee7322e..64e89ef79 100644 --- a/src/atlas/interpolation/element/Triag3D.h +++ b/src/atlas/interpolation/element/Triag3D.h @@ -15,6 +15,7 @@ #include "atlas/interpolation/Vector3D.h" #include "atlas/interpolation/method/Intersect.h" +#include "atlas/util/Point.h" namespace atlas { namespace interpolation { @@ -33,16 +34,19 @@ class Triag3D { public: // types - Triag3D(const Vector3D& x0, const Vector3D& x1, const Vector3D& x2): + + Triag3D(const double* x0, const double* x1, const double* x2) : v0(x0), v1(x1), v2(x2) { } - Triag3D(const double* x0, const double* x1, const double* x2) { - v0 = Vector3D::Map(x0); - v1 = Vector3D::Map(x1); - v2 = Vector3D::Map(x2); + Triag3D(const PointXYZ& x0, const PointXYZ& x1, const PointXYZ& x2) : + Triag3D(x0.data(),x1.data(),x2.data()) { + } + + Triag3D(const Vector3D& x0, const Vector3D& x1, const Vector3D& x2) : + Triag3D(x0.data(),x1.data(),x2.data()) { } method::Intersect intersects( diff --git a/src/atlas/interpolation/method/FiniteElement.cc b/src/atlas/interpolation/method/FiniteElement.cc index b93c70fef..68f949119 100644 --- a/src/atlas/interpolation/method/FiniteElement.cc +++ b/src/atlas/interpolation/method/FiniteElement.cc @@ -133,7 +133,7 @@ void FiniteElement::setup(const FunctionSpace& source) { continue; } - PointXYZ p ( (*ocoords_)[ip].data() ); // lookup point + PointXYZ p{(*ocoords_)(ip,0),(*ocoords_)(ip,1),(*ocoords_)(ip,2)}; // lookup point size_t kpts = 1; bool success = false; @@ -172,7 +172,7 @@ void FiniteElement::setup(const FunctionSpace& source) { std::ostringstream msg; msg << "Rank " << eckit::mpi::comm().rank() << " failed to project points:\n"; for (std::vector::const_iterator i = failures.begin(); i != failures.end(); ++i) { - const PointXYZ p ( (*ocoords_)[*i].data() ); // lookup point + const PointXYZ p{ (*ocoords_)(*i,0), (*ocoords_)(*i,1), (*ocoords_)(*i,2) }; // lookup point const PointLonLat pll = util::Earth::convertGeocentricToGeodetic(p); msg << "\t(lon,lat) = " << pll << "\n"; } @@ -200,7 +200,7 @@ Method::Triplets FiniteElement::projectPointToElements( double w[4]; Triplets triplets; - Ray ray( (*ocoords_)[ip].data() ); + Ray ray( PointXYZ{(*ocoords_)(ip,0),(*ocoords_)(ip,1),(*ocoords_)(ip,2)} ); for (ElemIndex3::NodeList::const_iterator itc = elems.begin(); itc != elems.end(); ++itc) { @@ -219,9 +219,9 @@ Method::Triplets FiniteElement::projectPointToElements( /* triangle */ element::Triag3D triag( - (*icoords_)[idx[0]].data(), - (*icoords_)[idx[1]].data(), - (*icoords_)[idx[2]].data()); + PointXYZ{(*icoords_)(idx[0],0),(*icoords_)(idx[0],1),(*icoords_)(idx[0],2)}, + PointXYZ{(*icoords_)(idx[1],0),(*icoords_)(idx[1],1),(*icoords_)(idx[1],2)}, + PointXYZ{(*icoords_)(idx[2],0),(*icoords_)(idx[2],1),(*icoords_)(idx[2],2)}); // pick an epsilon based on a characteristic length (sqrt(area)) // (this scales linearly so it better compares with linear weights u,v,w) @@ -248,10 +248,10 @@ Method::Triplets FiniteElement::projectPointToElements( /* quadrilateral */ element::Quad3D quad( - (*icoords_)[idx[0]].data(), - (*icoords_)[idx[1]].data(), - (*icoords_)[idx[2]].data(), - (*icoords_)[idx[3]].data() ); + PointXYZ{(*icoords_)(idx[0],0),(*icoords_)(idx[0],1),(*icoords_)(idx[0],2)}, + PointXYZ{(*icoords_)(idx[1],0),(*icoords_)(idx[1],1),(*icoords_)(idx[1],2)}, + PointXYZ{(*icoords_)(idx[2],0),(*icoords_)(idx[2],1),(*icoords_)(idx[2],2)}, + PointXYZ{(*icoords_)(idx[3],0),(*icoords_)(idx[3],1),(*icoords_)(idx[3],2)}); // pick an epsilon based on a characteristic length (sqrt(area)) // (this scales linearly so it better compares with linear weights u,v,w) diff --git a/src/atlas/interpolation/method/KNearestNeighbours.cc b/src/atlas/interpolation/method/KNearestNeighbours.cc index 049f39baf..694dab2e6 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.cc +++ b/src/atlas/interpolation/method/KNearestNeighbours.cc @@ -78,7 +78,7 @@ void KNearestNeighbours::setup(const FunctionSpace& source, const FunctionSpace& } // find the closest input points to the output point - PointIndex3::Point p(coords[ip].data()); + PointIndex3::Point p{coords(ip,0),coords(ip,1),coords(ip,2)}; PointIndex3::NodeList nn = pTree_->kNearestNeighbours(p, k_); // calculate weights (individual and total, to normalise) using distance squared diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.cc b/src/atlas/interpolation/method/KNearestNeighboursBase.cc index e957bcccc..f5b906db0 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.cc +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.cc @@ -41,14 +41,14 @@ void KNearestNeighboursBase::buildPointSearchTree(Mesh& meshSource) { std::vector pidx; pidx.reserve(meshSource.nodes().size()); for (size_t ip = 0; ip < meshSource.nodes().size(); ++ip) { - PointIndex3::Point p(coords[ip].data()); + PointIndex3::Point p{coords(ip,0),coords(ip,1),coords(ip,2)}; pidx.push_back(PointIndex3::Value(p, ip)); } pTree_->build(pidx.begin(), pidx.end()); } else { for (size_t ip = 0; ip < meshSource.nodes().size(); ++ip) { - PointIndex3::Point p(coords[ip].data()); + PointIndex3::Point p{coords(ip,0),coords(ip,1),coords(ip,2)}; pTree_->insert(PointIndex3::Value(p, ip)); } } diff --git a/src/atlas/interpolation/method/NearestNeighbour.cc b/src/atlas/interpolation/method/NearestNeighbour.cc index 3385defda..5c5c78350 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.cc +++ b/src/atlas/interpolation/method/NearestNeighbour.cc @@ -67,7 +67,7 @@ void NearestNeighbour::setup(const FunctionSpace& source, const FunctionSpace& t } // find the closest input point to the output point - PointIndex3::Point p(coords[ip].data()); + PointIndex3::Point p{coords(ip,0),coords(ip,1),coords(ip,2)}; PointIndex3::NodeInfo nn = pTree_->nearestNeighbour(p); size_t jp = nn.payload(); diff --git a/src/atlas/interpolation/method/Ray.cc b/src/atlas/interpolation/method/Ray.cc index a110edbcf..2bf697d92 100644 --- a/src/atlas/interpolation/method/Ray.cc +++ b/src/atlas/interpolation/method/Ray.cc @@ -28,6 +28,16 @@ Ray::Ray(const double* o, const double* d) { dir = Vector3D::Map(d); } +Ray::Ray(const PointXYZ& p ) { + orig = Vector3D::Map(p.data()); + dir = -orig; +} + +Ray::Ray(const PointXYZ& o, const Vector3D& d) { + orig = Vector3D::Map(o.data()); + dir = d; +} + void Ray::print(std::ostream& s) const { s << "Ray[orig=" << orig << ",dir=" << dir << "]"; } std::ostream& operator<<(std::ostream& s, const Ray& p) { diff --git a/src/atlas/interpolation/method/Ray.h b/src/atlas/interpolation/method/Ray.h index a3a99cc39..7b8ce1a9d 100644 --- a/src/atlas/interpolation/method/Ray.h +++ b/src/atlas/interpolation/method/Ray.h @@ -8,12 +8,12 @@ * does it submit to any jurisdiction. */ -#ifndef atlas_interpolation_method_Ray_h -#define atlas_interpolation_method_Ray_h +#pragma once #include #include "atlas/interpolation/Vector3D.h" +#include "atlas/util/Point.h" namespace atlas { namespace interpolation { @@ -33,6 +33,10 @@ struct Ray { Ray(const double* o, const double* d); + explicit Ray( const PointXYZ& ); + + Ray(const PointXYZ&, const Vector3D&); + Vector3D operator()(double t) const { return orig + t * dir; } void print(std::ostream& s) const; @@ -46,6 +50,3 @@ struct Ray { } // namespace method } // namespace interpolation } // namespace atlas - - -#endif diff --git a/src/atlas/mesh/actions/BuildTorusXYZField.cc b/src/atlas/mesh/actions/BuildTorusXYZField.cc index 7ffe89167..a0e9d6575 100644 --- a/src/atlas/mesh/actions/BuildTorusXYZField.cc +++ b/src/atlas/mesh/actions/BuildTorusXYZField.cc @@ -57,15 +57,12 @@ Field& BuildTorusXYZField::operator()(mesh::Nodes& nodes, const Domain& dom, dou const double c2 = 2.*pi/double(ny)*(ny-1)/(ymax-ymin); for( size_t n=0; n Date: Fri, 24 Nov 2017 15:36:02 +0000 Subject: [PATCH 203/355] ATLAS-138 Preparations for MIR --- src/atlas/interpolation/Vector3D.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/atlas/interpolation/Vector3D.h b/src/atlas/interpolation/Vector3D.h index f83b5b832..03e1aa7e6 100644 --- a/src/atlas/interpolation/Vector3D.h +++ b/src/atlas/interpolation/Vector3D.h @@ -106,6 +106,13 @@ class Vector3D { return s; } + double* data() { + return xyz_; + } + + const double* data() const { + return xyz_; + } private: From 451621e899f67eca4ceeddd1de3ebe4710cc837f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 24 Nov 2017 15:46:42 +0000 Subject: [PATCH 204/355] ATLAS-138 More fixes to internal Vector3D --- src/atlas/interpolation/Vector3D.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/atlas/interpolation/Vector3D.h b/src/atlas/interpolation/Vector3D.h index 03e1aa7e6..c98294c52 100644 --- a/src/atlas/interpolation/Vector3D.h +++ b/src/atlas/interpolation/Vector3D.h @@ -38,7 +38,7 @@ typedef Eigen::Vector3d Vector3D; #else class Vector3D { - private: + public: Vector3D(const double *d) { xyz_[0] = d[0]; @@ -52,8 +52,6 @@ class Vector3D { xyz_[2] = z; } - public: - Vector3D() { // Warning, data_ is uninitialised } From f07bf0a5f6df0fa014e7d0bde6364a3c2755290f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 24 Nov 2017 16:47:47 +0000 Subject: [PATCH 205/355] ATLAS-137 Fix HaloExchange Fortran/C interface --- src/atlas/parallel/HaloExchange.cc | 10 +++++----- src/tests/parallel/test_haloexchange.cc | 26 ++++++++++++------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index c41012e25..7e36efc90 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -165,11 +165,11 @@ void execute_halo_exchange( HaloExchange* This, Value field[], int var_strides[] eckit::SharedPtr arr ( array::Array::wrap(field, array::ArraySpec{shape,strides} ) ); - switch(var_rank) { - case 1: {This->execute(*arr); break;} - case 2: {This->execute(*arr); break;} - case 3: {This->execute(*arr); break;} - case 4: {This->execute(*arr); break;} + switch(arr->rank()) { + case 1: {This->execute(*arr); break;} + case 2: {This->execute(*arr); break;} + case 3: {This->execute(*arr); break;} + case 4: {This->execute(*arr); break;} default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); } } diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index b91b4a2b8..63245f5f7 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -218,9 +218,9 @@ void test_rank1_strided_v1(Fixture& f) { eckit::SharedPtr arr ( array::Array::wrap( arrv_t.data(), - array::ArraySpec{array::make_shape(f.N, 1), + array::ArraySpec{array::make_shape(f.N, 1), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(32, 1) } + array::make_strides(32, 1) } #else array::make_strides(2, 1) } #endif @@ -260,11 +260,11 @@ void test_rank1_strided_v2(Fixture& f) { // (i.e. we are only selecting and exchanging the first component of the field) eckit::SharedPtr arr ( array::Array::wrap(&(arrv_t(0,1)), - array::ArraySpec{array::make_shape(f.N, 1), + array::ArraySpec{array::make_shape(f.N, 1), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(32, 1) + array::make_strides(32, 1) #else - array::make_strides(2, 1) + array::make_strides(2, 1) #endif } ) ); @@ -346,9 +346,9 @@ void test_rank2_l1(Fixture& f) { eckit::SharedPtr arr ( array::Array::wrap( arrv_t.data(), - array::ArraySpec{array::make_shape(f.N, 1, 2), + array::ArraySpec{array::make_shape(f.N, 1, 2), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(96,32, 1) + array::make_strides(96,32, 1) #else array::make_strides(6, 2, 1) #endif @@ -414,9 +414,9 @@ void test_rank2_l2_v2(Fixture& f) { } eckit::SharedPtr arr ( array::Array::wrap(&arrv_t(0,1,1), - array::ArraySpec{array::make_shape(f.N, 1, 1), + array::ArraySpec{array::make_shape(f.N, 1, 1), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(192, 32, 1) + array::make_strides(192, 32, 1) #else array::make_strides(6, 2, 1) #endif @@ -477,11 +477,11 @@ void test_rank2_v2(Fixture& f) { } eckit::SharedPtr arr ( array::Array::wrap(&arrv_t(0,0,1), - array::ArraySpec{array::make_shape(f.N, 3, 1), + array::ArraySpec{array::make_shape(f.N, 3, 1), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(192, 32, 2) + array::make_strides(192, 32, 2) #else - array::make_strides(6, 2, 2) + array::make_strides(6, 2, 2) #endif } ) ); @@ -627,7 +627,7 @@ void test_rank1_cinterface(Fixture& f) { int shapes[2] = {(int)arrv.shape(0), (int)arrv.shape(1)}; int strides[2] = {(int)arrv.stride(0), (int)arrv.stride(1)}; - atlas__HaloExchange__execute_strided_double(&(f.halo_exchange), arrv.data(), &(strides[0]), &(shapes[0]), 2); + atlas__HaloExchange__execute_strided_double(&(f.halo_exchange), arrv.data(), &(strides[1]), &(shapes[1]), 1); switch( parallel::mpi::comm().rank() ) { From 8ad0face342b1fccaf71ede692939886330fac6c Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 24 Nov 2017 17:03:15 +0000 Subject: [PATCH 206/355] ATLAS-138 New ArrayView slice functionality with protected write access --- src/apps/atlas-benchmark.cc | 5 +- src/atlas/array/LocalView.cc | 23 +++-- src/atlas/array/LocalView.h | 61 ++++++------- .../array/gridtools/GridToolsArrayView.h | 85 +++++++------------ src/atlas/array/helpers/ArrayAssigner.h | 9 +- src/atlas/array/helpers/ArraySlicer.h | 77 +++++++++-------- src/atlas/array/native/NativeArrayView.h | 70 ++++----------- .../meshgenerator/StructuredMeshGenerator.cc | 67 ++++++++------- src/tests/array/test_array.cc | 4 +- src/tests/array/test_array_slicer.cc | 42 ++++++++- src/tests/mesh/test_halo.cc | 2 +- 11 files changed, 221 insertions(+), 224 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index ef58f6f39..a52916317 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -80,6 +80,7 @@ using atlas::mesh::IsGhostNode; using namespace eckit::option; using namespace atlas; +using namespace atlas::array; using namespace atlas::grid; using namespace atlas::mesh::actions; using namespace atlas::functionspace; @@ -490,7 +491,7 @@ void AtlasBenchmark::iteration() //---------------------------------------------------------------------------------------------------------------------- template< typename DATA_TYPE > -DATA_TYPE vecnorm( DATA_TYPE vec[], size_t size ) +DATA_TYPE vecnorm( const DATA_TYPE vec[], size_t size ) { DATA_TYPE norm=0; for(size_t j=0; j < size; ++j) @@ -517,7 +518,7 @@ double AtlasBenchmark::result() minval = min(minval,grad(jnode,jlev,LAT)); minval = min(minval,grad(jnode,jlev,ZZ)); // norm += std::pow(vecnorm(grad[jnode][jlev].data(),3),2); - norm += std::pow(vecnorm(grad.at(jnode).at(jlev).data(),3),2); + norm += std::pow(vecnorm( grad.slice(jnode,jlev,Range::all()).data(),3),2); } } } diff --git a/src/atlas/array/LocalView.cc b/src/atlas/array/LocalView.cc index ec0d32840..f751624d5 100644 --- a/src/atlas/array/LocalView.cc +++ b/src/atlas/array/LocalView.cc @@ -20,15 +20,15 @@ namespace array { //------------------------------------------------------------------------------------------------------ -template -void LocalView::assign(const value_type& value) { +template +void LocalView::assign(const value_type& value) { helpers::array_assigner::apply(*this,value); } //------------------------------------------------------------------------------------------------------ -template -void LocalView::dump(std::ostream& os) const { +template +void LocalView::dump(std::ostream& os) const { ASSERT( contiguous() ); const value_type* data_ = data(); os << "size: " << size() << " , values: "; @@ -50,11 +50,16 @@ os << "]"; namespace atlas { namespace array { #define EXPLICIT_TEMPLATE_INSTANTIATION(Rank) \ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ +template class LocalView;\ +template class LocalView;\ +template class LocalView;\ +template class LocalView;\ +template class LocalView;\ +template class LocalView;\ +template class LocalView;\ +template class LocalView;\ +template class LocalView;\ +template class LocalView;\ // For each NDims in [1..9] EXPLICIT_TEMPLATE_INSTANTIATION(1) diff --git a/src/atlas/array/LocalView.h b/src/atlas/array/LocalView.h index 4f9277982..49577dc69 100644 --- a/src/atlas/array/LocalView.h +++ b/src/atlas/array/LocalView.h @@ -45,22 +45,39 @@ #include "atlas/library/config.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/ArrayViewDefs.h" +#include "atlas/array/helpers/ArraySlicer.h" //------------------------------------------------------------------------------------------------------ namespace atlas { namespace array { -template< typename Value, int Rank > +template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > class LocalView { public: // -- Type definitions using value_type = typename remove_const::type; - using Slice = typename std::conditional<(Rank==1), value_type&, LocalView >::type; - static constexpr Intent ACCESS{Intent::ReadWrite}; - static constexpr int RANK{Rank}; + using return_type = typename std::conditional< (AccessMode==Intent::ReadOnly), const value_type, value_type >::type; + + static constexpr Intent ACCESS{AccessMode}; + static constexpr int RANK{Rank}; + +private: + + using slicer_t = typename helpers::ArraySlicer< LocalView >; + using const_slicer_t = typename helpers::ArraySlicer< const LocalView >; + + template< typename ...Args > + struct slice_t { + using type = typename slicer_t::template Slice::type; + }; + + template< typename ...Args > + struct const_slice_t { + using type = typename const_slicer_t::template Slice::type; + }; public: @@ -99,7 +116,7 @@ class LocalView { // -- Access methods template < typename... Ints > - value_type& operator()(Ints... idx) { + return_type& operator()(Ints... idx) { check_bounds(idx...); return data_[index(idx...)]; } @@ -110,10 +127,6 @@ class LocalView { return data_[index(idx...)]; } - Slice at(const size_t i) const { - return Slicer(*this).apply(i); - } - size_t size() const { return size_;} size_t shape(size_t idx) const { return shape_[idx]; } @@ -122,7 +135,7 @@ class LocalView { value_type const* data() const { return data_; } - value_type* data() { return data_; } + return_type* data() { return data_; } bool contiguous() const { return (size_ == shape_[0]*strides_[0] ? true : false); @@ -134,27 +147,17 @@ class LocalView { static constexpr size_t rank() { return Rank; } -private: - -// -- Type definitions + template< typename ...Args > + typename slice_t::type slice(Args... args) { + return slicer_t(*this).apply(args...); + } - template - struct Slicer { - Slicer(LocalView const& lv) : lv_(lv) {} - LocalView const& lv_; - ReturnType apply(const size_t i) const { - return LocalView(lv_.data_ + lv_.strides_[0] * i, lv_.shape_ + 1, lv_.strides_ + 1); - } - }; + template< typename ...Args > + typename const_slice_t::type slice(Args... args) const { + return const_slicer_t(*this).apply(args...); + } - template - struct Slicer { - Slicer(LocalView const& lv) : lv_(lv) {} - LocalView const& lv_; - ReturnType apply(const size_t i) const { - return *(lv_.data_ + lv_.strides_[0] * i); - } - }; +private: // -- Private methods diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 369e22c6e..11959644f 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -27,11 +27,28 @@ namespace array { template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > class ArrayView { public: -// -- Type definitions - using value_type = typename remove_const::type; - using Slice = typename std::conditional<(Rank==1), value_type&, LocalView >::type; + // -- Type definitions + using value_type = typename remove_const::type; + using return_type = typename std::conditional< (AccessMode == Intent::ReadWrite), value_type, value_type const>::type; + + static constexpr Intent ACCESS{AccessMode}; + static constexpr int RANK{Rank}; + using data_view_t = gridtools::data_view_tt; - using return_type = typename std::conditional< (AccessMode == Intent::ReadWrite), value_type, value_type const>::type; + + private: + using slicer_t = typename helpers::ArraySlicer< ArrayView >; + using const_slicer_t = typename helpers::ArraySlicer< const ArrayView >; + + template< typename ...Args > + struct slice_t { + using type = typename slicer_t::template Slice::type; + }; + + template< typename ...Args > + struct const_slice_t { + using type = typename const_slicer_t::template Slice::type; + }; public: @@ -56,36 +73,6 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas return gt_data_view_(c...); } - const Slice operator[](size_t i) const { - return Slicer(*this).apply(i); - } - - Slice operator[](size_t i) { - return Slicer(*this).apply(i); - } - - const Slice at(size_t i) const { - if( i>= shape(0) ) { - throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); - } - return Slicer(*this).apply(i); - } - - Slice at(size_t i) { - if( i>= shape(0) ) { - throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); - } - return Slicer(*this).apply(i); - } - - const Slice slice(size_t i) const { - return Slicer(*this).apply(i); - } - - Slice slice(size_t i) { - return Slicer(*this).apply(i); - } - template ATLAS_HOST_DEVICE size_t shape() const { @@ -125,29 +112,17 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas size_t stride(size_t idx) const { return strides_[idx]; } -private: + template< typename ...Args > + typename slice_t::type slice(Args... args) { + return slicer_t(*this).apply(args...); + } - template - struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; - ReturnType apply(const size_t i) const { - return LocalView( - av_.data()+av_.strides_[0]*i, - av_.shape_+1, - av_.strides_+1 ); - } - }; - - template - struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; - ReturnType apply(const size_t i) const { - return *(const_cast(av_.data()) + av_.strides_[0] * i); - } - }; + template< typename ...Args > + typename const_slice_t::type slice(Args... args) const { + return const_slicer_t(*this).apply(args...); + } +private: data_view_t gt_data_view_; size_t shape_[Rank]; diff --git a/src/atlas/array/helpers/ArrayAssigner.h b/src/atlas/array/helpers/ArrayAssigner.h index 3a4d37d1e..5441cf891 100644 --- a/src/atlas/array/helpers/ArrayAssigner.h +++ b/src/atlas/array/helpers/ArrayAssigner.h @@ -75,7 +75,7 @@ struct array_assigner { return apply( make_host_view(arr), value ); } - static void apply(ArrayView& arr, Value) { + static void apply(ArrayView&, Value) { throw eckit::AssertionFailed("Cannot assign ReadOnly array",Here()); // TODO use SFINAE to disallow at compile time } @@ -99,7 +99,12 @@ struct array_assigner { ASSERT( it = iterable.end() ); } - static void apply(LocalView& arr, Value value) { + static void apply(LocalView&, Value value) { + throw eckit::AssertionFailed("Cannot assign ReadOnly array",Here()); + // TODO use SFINAE to disallow at compile time + } + + static void apply(LocalView& arr, Value value) { array_assigner_impl::apply( arr, value ); // Note: no need to apply variadic pack (idxs...) } diff --git a/src/atlas/array/helpers/ArraySlicer.h b/src/atlas/array/helpers/ArraySlicer.h index 9e529e5da..4e3a34f7f 100644 --- a/src/atlas/array/helpers/ArraySlicer.h +++ b/src/atlas/array/helpers/ArraySlicer.h @@ -12,13 +12,41 @@ #include "atlas/runtime/Log.h" #include "atlas/array/ArrayViewDefs.h" -#include "atlas/array/LocalView.h" #include "atlas/array/Range.h" -//------------------------------------------------------------------------------ - namespace atlas { namespace array { + +template< typename Value, int Rank, Intent AccessMode > +class LocalView; + + +template +struct Reference { + Value& value; + operator Value&() { return value; } + template < typename T > void operator=(const T a) { value = a; } + template < typename T > Reference& operator+(const T a) { value+=a; return *this; } + template < typename T > Reference& operator-(const T a) { value-=a; return *this; } + Reference& operator--() { --value; return *this; } + Reference& operator++() { ++value; return *this; } +}; + + +template +struct get_slice_type { + using type = + typename std::conditional<(Rank==0), + typename std::conditional<(Access==Intent::ReadOnly), + Reference, + Reference + >::type, + LocalView + >::type; +}; + +//------------------------------------------------------------------------------ + namespace helpers { template< int Dim > @@ -68,40 +96,16 @@ ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(8); ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(9); #undef ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION -template -struct Reference { - Value& value; - operator Value&() { return value; } - template < typename T > void operator=(const T a) { value = a; } - template < typename T > Reference& operator+(const T a) { value+=a; return *this; } - template < typename T > Reference& operator-(const T a) { value-=a; return *this; } - Reference& operator--() { --value; return *this; } - Reference& operator++() { ++value; return *this; } -}; -//template -//struct get_slice_type { -// using type = -// typename std::conditional<(Rank==0), -// typename std::conditional<(Access==Intent::ReadOnly), -// const Value&, -// Value& -// >::type, -// LocalView -// >::type; -//}; +template< typename View, bool constness = false > +struct get_access { + static constexpr Intent value{ View::ACCESS }; +}; -template -struct get_slice_type { - using type = - typename std::conditional<(Rank==0), - typename std::conditional<(Access==Intent::ReadOnly), - Reference, - Reference - >::type, - LocalView - >::type; +template< typename View > +struct get_access { + static constexpr Intent value{ Intent::ReadOnly }; }; @@ -121,7 +125,10 @@ class ArraySlicer { template struct Slice { - using type = typename get_slice_type< typename View::value_type, SliceRank::value, View::ACCESS >::type; + using type = typename get_slice_type< + typename View::value_type, + SliceRank::value, + get_access::value>::value >::type; }; template diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 77d5b6d98..c01622879 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -71,21 +71,25 @@ template class // -- Type definitions using value_type = typename remove_const::type; + using return_type = typename std::conditional< (AccessMode == Intent::ReadWrite), value_type, value_type const>::type; + static constexpr Intent ACCESS{AccessMode}; static constexpr int RANK{Rank}; private: using slicer_t = typename helpers::ArraySlicer< ArrayView >; + using const_slicer_t = typename helpers::ArraySlicer< const ArrayView >; - using SliceDepr = typename std::conditional<(Rank==1), value_type&, LocalView >::type; - - -public: template< typename ...Args > - struct Slice { + struct slice_t { using type = typename slicer_t::template Slice::type; }; + template< typename ...Args > + struct const_slice_t { + using type = typename const_slicer_t::template Slice::type; + }; + public: // -- Constructors @@ -110,7 +114,7 @@ template class // -- Access methods template < typename... Idx > - value_type& operator()(Idx... idx) { + return_type& operator()(Idx... idx) { check_bounds(idx...); return data_[index(idx...)]; } @@ -121,35 +125,11 @@ template class return data_[index(idx...)]; } - const SliceDepr operator[](size_t i) const { - return Slicer(*this).apply(i); - } - - SliceDepr operator[](size_t i) { - return Slicer(*this).apply(i); - } - - const SliceDepr at(size_t i) const { - if( i>= shape(0) ) { - throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); - } - return Slicer(*this).apply(i); - } - - SliceDepr at(size_t i) { - if( i>= shape(0) ) { - throw_OutOfRange( "ArrayView::at", 'i', i, shape(0) ); - } - return Slicer(*this).apply(i); - } - template size_t shape() const { return shape(Dim);} template - size_t stride() const { - return stride(Dim); - } + size_t stride() const { return stride(Dim); } size_t size() const { return size_;} @@ -178,10 +158,16 @@ template class void dump(std::ostream& os) const; template< typename ...Args > - typename Slice::type slice(Args... args) { + typename slice_t::type slice(Args... args) { return slicer_t(*this).apply(args...); } + template< typename ...Args > + typename const_slice_t::type slice(Args... args) const { + return const_slicer_t(*this).apply(args...); + } + + private: // -- Private methods @@ -233,26 +219,6 @@ template class } } -// -- Type definitions - - template - struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; - ReturnType apply(const size_t i) const { - return LocalView(av_.data_ + av_.strides_[0] * i, av_.shape_.data() + 1, av_.strides_.data() + 1); - } - }; - - template - struct Slicer { - Slicer(ArrayView const& av) : av_(av) {} - ArrayView const& av_; - ReturnType apply(const size_t i) const { - return *(av_.data_ + av_.strides_[0] * i); - } - }; - // -- Private data value_type *data_; diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index d21da9de0..c44ce333a 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -40,6 +40,7 @@ #define DEBUG_OUTPUT 0 using namespace eckit; +using namespace atlas::array; using atlas::Mesh; using Topology = atlas::mesh::Nodes::Topology; @@ -322,7 +323,7 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co ilat = jlat-region.north; - array::LocalView lat_elems_view = elemview.at(ilat); + auto lat_elems_view = elemview.slice(ilat,Range::all(),Range::all()); latN = jlat; latS = jlat+1; @@ -490,7 +491,7 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co DEBUG_VAR(jelem); #endif - array::LocalView elem = lat_elems_view.at(jelem); + auto elem = lat_elems_view.slice(jelem,Range::all()); if( try_make_quad ) { @@ -499,10 +500,10 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co Log::info() << " " << ipN1 << " " << ipN2 << '\n'; Log::info() << " " << ipS1 << " " << ipS2 << '\n'; #endif - elem.at(0) = ipN1; - elem.at(1) = ipS1; - elem.at(2) = ipS2; - elem.at(3) = ipN2; + elem(0) = ipN1; + elem(1) = ipS1; + elem(2) = ipS2; + elem(3) = ipN2; add_quad = false; int np[] = {pN1, pN2, pS1, pS2}; int cnt_mypart = std::count(np, np+4, mypart); @@ -572,10 +573,10 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co Log::info() << " " << ipN1 << " " << ipN2 << '\n'; Log::info() << " " << ipS1 << '\n'; #endif - elem.at(0) = ipN1; - elem.at(1) = ipS1; - elem.at(2) = -1; - elem.at(3) = ipN2; + elem(0) = ipN1; + elem(1) = ipS1; + elem(2) = -1; + elem(3) = ipN2; add_triag = false; @@ -651,10 +652,10 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co Log::info() << " " << ipN1 << " ("< elem = array::make_view(*region.elems).at(ilat).at(jelem); + const auto elem = array::make_view(*region.elems).slice(ilat,jelem,Range::all()); - if(elem.at(2)>=0 && elem.at(3)>=0) // This is a quad + if(elem(2)>=0 && elem(3)>=0) // This is a quad { - quad_nodes[0] = node_numbering.at( offset_loc.at(ilatN) + elem.at(0) - region.lat_begin.at(jlatN) ); - quad_nodes[1] = node_numbering.at( offset_loc.at(ilatS) + elem.at(1) - region.lat_begin.at(jlatS) ); - quad_nodes[2] = node_numbering.at( offset_loc.at(ilatS) + elem.at(2) - region.lat_begin.at(jlatS) ); - quad_nodes[3] = node_numbering.at( offset_loc.at(ilatN) + elem.at(3) - region.lat_begin.at(jlatN) ); + quad_nodes[0] = node_numbering.at( offset_loc.at(ilatN) + elem(0) - region.lat_begin.at(jlatN) ); + quad_nodes[1] = node_numbering.at( offset_loc.at(ilatS) + elem(1) - region.lat_begin.at(jlatS) ); + quad_nodes[2] = node_numbering.at( offset_loc.at(ilatS) + elem(2) - region.lat_begin.at(jlatS) ); + quad_nodes[3] = node_numbering.at( offset_loc.at(ilatN) + elem(3) - region.lat_begin.at(jlatN) ); if( three_dimensional && periodic_east_west ) { - if (size_t(elem.at(2)) == rg.nx(jlatS)) quad_nodes[2] = node_numbering.at( offset_loc.at(ilatS) ); - if (size_t(elem.at(3)) == rg.nx(jlatN)) quad_nodes[3] = node_numbering.at( offset_loc.at(ilatN) ); + if (size_t(elem(2)) == rg.nx(jlatS)) quad_nodes[2] = node_numbering.at( offset_loc.at(ilatS) ); + if (size_t(elem(3)) == rg.nx(jlatN)) quad_nodes[3] = node_numbering.at( offset_loc.at(ilatN) ); } jcell = quad_begin + jquad++; @@ -1187,26 +1188,26 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons } else // This is a triag { - if(elem.at(3)<0) // This is a triangle pointing up + if(elem(3)<0) // This is a triangle pointing up { - triag_nodes[0] = node_numbering.at( offset_loc.at(ilatN) + elem.at(0) - region.lat_begin.at(jlatN) ); - triag_nodes[1] = node_numbering.at( offset_loc.at(ilatS) + elem.at(1) - region.lat_begin.at(jlatS) ); - triag_nodes[2] = node_numbering.at( offset_loc.at(ilatS) + elem.at(2) - region.lat_begin.at(jlatS) ); + triag_nodes[0] = node_numbering.at( offset_loc.at(ilatN) + elem(0) - region.lat_begin.at(jlatN) ); + triag_nodes[1] = node_numbering.at( offset_loc.at(ilatS) + elem(1) - region.lat_begin.at(jlatS) ); + triag_nodes[2] = node_numbering.at( offset_loc.at(ilatS) + elem(2) - region.lat_begin.at(jlatS) ); if( three_dimensional && periodic_east_west ) { - if (size_t(elem.at(0)) == rg.nx(jlatN)) triag_nodes[0] = node_numbering.at( offset_loc.at(ilatN) ); - if (size_t(elem.at(2)) == rg.nx(jlatS)) triag_nodes[2] = node_numbering.at( offset_loc.at(ilatS) ); + if (size_t(elem(0)) == rg.nx(jlatN)) triag_nodes[0] = node_numbering.at( offset_loc.at(ilatN) ); + if (size_t(elem(2)) == rg.nx(jlatS)) triag_nodes[2] = node_numbering.at( offset_loc.at(ilatS) ); } } else // This is a triangle pointing down { - triag_nodes[0] = node_numbering.at( offset_loc.at(ilatN) + elem.at(0) - region.lat_begin.at(jlatN) ); - triag_nodes[1] = node_numbering.at( offset_loc.at(ilatS) + elem.at(1) - region.lat_begin.at(jlatS) ); - triag_nodes[2] = node_numbering.at( offset_loc.at(ilatN) + elem.at(3) - region.lat_begin.at(jlatN) ); + triag_nodes[0] = node_numbering.at( offset_loc.at(ilatN) + elem(0) - region.lat_begin.at(jlatN) ); + triag_nodes[1] = node_numbering.at( offset_loc.at(ilatS) + elem(1) - region.lat_begin.at(jlatS) ); + triag_nodes[2] = node_numbering.at( offset_loc.at(ilatN) + elem(3) - region.lat_begin.at(jlatN) ); if( three_dimensional && periodic_east_west ) { - if (size_t(elem.at(1)) == rg.nx(jlatS)) triag_nodes[1] = node_numbering.at( offset_loc.at(ilatS) ); - if (size_t(elem.at(3)) == rg.nx(jlatN)) triag_nodes[2] = node_numbering.at( offset_loc.at(ilatN) ); + if (size_t(elem(1)) == rg.nx(jlatS)) triag_nodes[1] = node_numbering.at( offset_loc.at(ilatS) ); + if (size_t(elem(3)) == rg.nx(jlatN)) triag_nodes[2] = node_numbering.at( offset_loc.at(ilatN) ); } } jcell = triag_begin + jtriag++; diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index e01ea3f8d..3e84c4189 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -108,7 +108,7 @@ CASE("test_localview") { // Check values for (size_t i = 0; i < ds->shape(0); ++i) { - LocalView lv = hv.at(i); + LocalView lv = hv.slice(i,Range::all(),Range::all()); for (size_t j = 0; j < lv.shape(0); ++j) { for (size_t k = 0; k < lv.shape(1); ++k) { EXPECT(lv(j, k) == (i * 100) + (j * 10) + (k)); @@ -474,7 +474,7 @@ CASE("test_assign") { EXPECT(hv(1, 2, 3) == 2.5); - auto lv = hv.at(1); + auto lv = hv.slice(1,Range::all(),Range::all()); lv.assign(5.0); EXPECT(hv(0, 2, 3) == 2.5); diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index 2a9ab0e5a..02690cebc 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -292,13 +292,47 @@ CASE( "test_arrayview_slice_type" ) EXPECT( slice4 == 123 ); static_assert( read_only_view.ACCESS == Intent::ReadOnly, "failed" ); - static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); - static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); - static_assert( std::is_same< decltype(slice3), Reference>::value, "failed" ); - static_assert( std::is_same< decltype(slice4), double const& >::value , "failed" ); + static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); + static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); + static_assert( std::is_same< decltype(slice3), Reference >::value, "failed" ); + static_assert( std::is_same< decltype(slice4), double const& >::value , "failed" ); } + { + const auto const_read_write_view = make_view( arr ); + auto read_write_view = make_view(arr); + + auto slice1 = const_read_write_view.slice( Range{0,2}, 2, Range{2,5} ); + + EXPECT( slice1(0,0) == 133 ); + EXPECT( slice1(0,1) == 134 ); + EXPECT( slice1(0,2) == 135 ); + EXPECT( slice1(1,0) == 233 ); + EXPECT( slice1(1,1) == 234 ); + EXPECT( slice1(1,2) == 235 ); + + auto slice2 = const_read_write_view.slice( Range::all(), Range::to(2), Range::from(3) ); + + EXPECT( slice2(0,0,0) == 114 ); + EXPECT( slice2(0,0,1) == 115 ); + EXPECT( slice2(0,1,0) == 124 ); + EXPECT( slice2(0,1,1) == 125 ); + EXPECT( slice2(1,0,0) == 214 ); + EXPECT( slice2(1,0,1) == 215 ); + EXPECT( slice2(1,1,0) == 224 ); + EXPECT( slice2(1,1,1) == 225 ); + + auto slice3 = const_read_write_view.slice( 0, 1, 2 ); + + EXPECT( slice3 == 123 ); + + static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); + static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); + static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); + static_assert( std::is_same< decltype(slice3), Reference >::value, "failed" ); + } + } diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index 7b8431c1a..92255dfe1 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -479,7 +479,7 @@ CASE( "test_t63" ) } std::vector uid(m.nodes().size()); for( size_t j=0; j Date: Fri, 24 Nov 2017 22:32:08 +0000 Subject: [PATCH 207/355] Fixes for Cray broken since 911b19e5 --- src/atlas/trans/Trans.h | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/atlas/trans/Trans.h b/src/atlas/trans/Trans.h index f17517fc8..80ca0ea1a 100644 --- a/src/atlas/trans/Trans.h +++ b/src/atlas/trans/Trans.h @@ -10,10 +10,11 @@ #pragma once +#include + #include "eckit/config/Configuration.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" - #include "eckit/io/Buffer.h" #include "eckit/io/DataHandle.h" @@ -65,11 +66,15 @@ class TransCacheFileEntry : public TransCacheEntry { class Cache { public: - Cache() = default; + Cache() : + legendre_( new EmptyCacheEntry() ), + fft_( new EmptyCacheEntry() ) { + } Cache( const Cache& other ) = default; protected: Cache( const std::shared_ptr& legendre ) : - legendre_(legendre) { + legendre_(legendre), + fft_( new EmptyCacheEntry() ) { } Cache( const std::shared_ptr& legendre, const std::shared_ptr& fft ) : legendre_(legendre), @@ -79,8 +84,8 @@ class Cache { const TransCacheEntry& legendre() const { return *legendre_; } const TransCacheEntry& fft() const { return *fft_; } private: - std::shared_ptr legendre_{ new EmptyCacheEntry() }; - std::shared_ptr fft_{ new EmptyCacheEntry() } ; + std::shared_ptr legendre_; + std::shared_ptr fft_; }; class LegendreCache : public Cache { @@ -236,6 +241,12 @@ class TransBuilderFunctionSpace : public TransFactory { virtual TransImpl* make( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { return new T(cache,gp,sp,config); } + virtual TransImpl* make( const Grid&, int, const eckit::Configuration& ) { + throw eckit::SeriousBug("This function should not be called",Here()); + } + virtual TransImpl* make( const Cache&, const Grid&, int, const eckit::Configuration& ) { + throw eckit::SeriousBug("This function should not be called",Here()); + } public: TransBuilderFunctionSpace(const std::string& name) : TransFactory(name) {} }; @@ -248,6 +259,12 @@ class TransBuilderGrid : public TransFactory { virtual TransImpl* make( const Cache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { return new T(cache,grid,truncation,config); } + virtual TransImpl* make( const FunctionSpace&, const FunctionSpace&, const eckit::Configuration& ) { + throw eckit::SeriousBug("This function should not be called",Here()); + } + virtual TransImpl* make( const Cache&, const FunctionSpace&, const FunctionSpace&, const eckit::Configuration& ) { + throw eckit::SeriousBug("This function should not be called",Here()); + } public: TransBuilderGrid(const std::string& name) : TransFactory(name) {} }; From e4413601b57f74d3a624efee8369baff2cf507dc Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Sat, 25 Nov 2017 22:01:02 +0000 Subject: [PATCH 208/355] Stop using make_storageview in Elements::view --- src/atlas/array/Range.h | 6 +- src/atlas/mesh/Elements.cc | 92 +++++++++++++++++++++++++------ src/atlas/mesh/Elements.h | 15 +++-- src/atlas/output/detail/GmshIO.cc | 6 +- 4 files changed, 93 insertions(+), 26 deletions(-) diff --git a/src/atlas/array/Range.h b/src/atlas/array/Range.h index 8b657bbea..3320c2907 100644 --- a/src/atlas/array/Range.h +++ b/src/atlas/array/Range.h @@ -83,7 +83,11 @@ class Range : public helpers::RangeBase{ public: - Range(int start, int end ) : start_(start), end_(end) {} + template< typename Start, typename End > + Range(Start start, End end ) : + start_( static_cast(start) ), + end_( static_cast(end) ) { + } int start() const { return start_; } int end() const { return end_; } diff --git a/src/atlas/mesh/Elements.cc b/src/atlas/mesh/Elements.cc index be0c9026e..bc5f47329 100644 --- a/src/atlas/mesh/Elements.cc +++ b/src/atlas/mesh/Elements.cc @@ -62,46 +62,106 @@ const std::string& Elements::name() const return hybrid_elements_->element_type(type_idx_).name(); } -template<> array::LocalView Elements::view( const Field& field ) const +template<> array::LocalView Elements::view( const Field& field ) const { - return array::LocalView( array::make_storageview(field).data()+begin(), array::make_shape(size()) ); + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} ); } -template<> array::LocalView Elements::view( const Field& field ) const +template<> array::LocalView Elements::view( const Field& field ) const { - return array::LocalView( array::make_storageview(field).data()+begin(), array::make_shape(size()) ); + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} ); } -template<> array::LocalView Elements::view( const Field& field ) const +template<> array::LocalView Elements::view( const Field& field ) const { - return array::LocalView( array::make_storageview(field).data()+begin(), array::make_shape(size()) ); + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} ); } -template<> array::LocalView Elements::view( const Field& field ) const +template<> array::LocalView Elements::view( const Field& field ) const { - return array::LocalView( array::make_storageview(field).data()+begin(), array::make_shape(size()) ); + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} ); } -template<> array::LocalView Elements::view( const Field& field ) const +template<> array::LocalView Elements::view( const Field& field ) const { - return array::LocalView( array::make_storageview(field).data()+begin(), array::make_shape(size(),field.shape(1)) ); + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); } -template<> array::LocalView Elements::view( const Field& field ) const +template<> array::LocalView Elements::view( const Field& field ) const { - return array::LocalView( array::make_storageview(field).data()+begin(), array::make_shape(size(),field.shape(1)) ); + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); } -template<> array::LocalView Elements::view( const Field& field ) const +template<> array::LocalView Elements::view( const Field& field ) const { - return array::LocalView( array::make_storageview(field).data()+begin(), array::make_shape(size(),field.shape(1)) ); + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); } -template<> array::LocalView Elements::view( const Field& field ) const +template<> array::LocalView Elements::view( const Field& field ) const { - return array::LocalView( array::make_storageview(field).data()+begin(), array::make_shape(size(),field.shape(1)) ); + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +} + +// ---------------------------------------------------------------------------- + +template<> array::LocalView Elements::view( Field& field ) const +{ + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} ); +} + +template<> array::LocalView Elements::view( Field& field ) const +{ + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} ); +} + +template<> array::LocalView Elements::view( Field& field ) const +{ + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} ); +} + +template<> array::LocalView Elements::view( Field& field ) const +{ + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} ); +} + + + +template<> array::LocalView Elements::view( Field& field ) const +{ + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +} + +template<> array::LocalView Elements::view( Field& field ) const +{ + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +} + +template<> array::LocalView Elements::view( Field& field ) const +{ + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +} + +template<> array::LocalView Elements::view( Field& field ) const +{ + return array::make_host_view( field ) + .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); } size_t Elements::add(const size_t nb_elements) diff --git a/src/atlas/mesh/Elements.h b/src/atlas/mesh/Elements.h index f22ea67e9..8b0d48301 100644 --- a/src/atlas/mesh/Elements.h +++ b/src/atlas/mesh/Elements.h @@ -80,7 +80,7 @@ class Elements : public eckit::Owned { /// @brief Access hybrid_elements /// HybridElements can contain more Elements, and holds the data. // const HybridElements& hybrid_elements() const; - + /// @brief Index of Elements in hybrid_elements // size_t type_idx() const; @@ -89,8 +89,8 @@ class Elements : public eckit::Owned { /// @brief End of elements in hybrid_elements size_t end() const; - - + + const Field& field(const std::string& name) const { return hybrid_elements_->field(name); } Field& field(const std::string& name) { return hybrid_elements_->field(name); } bool has_field(const std::string& name) const { return hybrid_elements_->has_field(name); } @@ -110,10 +110,13 @@ class Elements : public eckit::Owned { const Field& halo() const { return hybrid_elements_->halo(); } Field& halo() { return hybrid_elements_->halo(); } - + template - array::LocalView view( const Field& ) const; - + array::LocalView view( const Field& ) const; + + template + array::LocalView view( Field& ) const; + size_t add(const size_t nb_elements); private: diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index 75598d5c2..43cb7117c 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -961,9 +961,9 @@ void GmshIO::write(const Mesh& mesh, const PathName& file_path) const const mesh::BlockConnectivity& node_connectivity = elements.node_connectivity(); - const array::LocalView elems_glb_idx = elements.view( elements.global_index() ); - const array::LocalView elems_partition = elements.view( elements.partition() ); - const array::LocalView elems_halo = elements.view( elements.halo() ); + auto elems_glb_idx = elements.view( elements.global_index() ); + auto elems_partition = elements.view( elements.partition() ); + auto elems_halo = elements.view( elements.halo() ); if( binary ) { From 2efe4a9c305ae76f6813fc6bef084855a7ff3625 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 27 Nov 2017 11:36:26 +0000 Subject: [PATCH 209/355] Stop using make_storageview in a few more places --- src/atlas/mesh/actions/BuildParallelFields.cc | 2 +- src/tests/io/test_pointcloud_io.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index fa9fd6a68..7968da35e 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -791,7 +791,7 @@ Field& build_edges_global_idx( Mesh& mesh ) mesh::HybridElements& edges = mesh.edges(); - array::make_storageview(edges.global_index()).assign(-1); + array::make_view(edges.global_index()).assign(-1); array::ArrayView edge_gidx = array::make_view( edges.global_index() ); const mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); diff --git a/src/tests/io/test_pointcloud_io.cc b/src/tests/io/test_pointcloud_io.cc index a9367807f..b86cfff80 100644 --- a/src/tests/io/test_pointcloud_io.cc +++ b/src/tests/io/test_pointcloud_io.cc @@ -437,8 +437,8 @@ CASE( "write_read_write_field" ) // (data section: guarantee data are from different places, to make checks useful) const Field& field_from_FieldSet(mesh_from_FieldSet.nodes().field("my_super_field")); const Field& field_from_Grid (mesh_from_FieldSet.nodes().field("my_super_field")); - EXPECT( array::make_storageview(field).data() != array::make_storageview(field_from_FieldSet).data() ); - EXPECT( array::make_storageview(field).data() != array::make_storageview(field_from_Grid) .data() ); + EXPECT( field.data() != field_from_FieldSet.data() ); + EXPECT( field.data() != field_from_Grid.data() ); array::ArrayView< double,1 > field_from_FieldSet_data = array::make_view(field_from_FieldSet); array::ArrayView< double,1 > field_from_Grid_data = array::make_view(field_from_Grid ); From d05a346b1bc6cac218cdab4936ab8f8eb07bff16 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 27 Nov 2017 12:33:15 +0000 Subject: [PATCH 210/355] Fix compilation with Cray 8.4 and 8.5 --- src/atlas/functionspace/EdgeColumns.cc | 8 ++++---- src/atlas_f/trans/atlas_Trans_module.F90 | 6 ++++-- src/tests/array/test_array_slicer.cc | 18 +++++++++++++++--- src/tests/parallel/test_haloexchange.cc | 24 ++++++++++++------------ 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index c20d01375..88dd8c54b 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -260,16 +260,16 @@ void EdgeColumns::haloExchange( FieldSet& fieldset ) const for( size_t f=0; f() ) { - halo_exchange().template execute( field.array(), false ); + halo_exchange().execute( field.array(), false ); } else if( field.datatype() == array::DataType::kind() ) { - halo_exchange().template execute( field.array(), false ); + halo_exchange().execute( field.array(), false ); } else if( field.datatype() == array::DataType::kind() ) { - halo_exchange().template execute( field.array(), false ); + halo_exchange().execute( field.array(), false ); } else if( field.datatype() == array::DataType::kind() ) { - halo_exchange().template execute( field.array(), false ); + halo_exchange().execute( field.array(), false ); } else throw eckit::Exception("datatype not supported",Here()); } diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index 857b65524..c4a40aeff 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -479,7 +479,7 @@ subroutine specnorm_r1_scalar(this, spectra, norm, rank) class(atlas_Trans), intent(in) :: this real(c_double), intent(in) :: spectra(:) real(c_double), intent(out) :: norm - integer, optional :: rank + integer, optional :: rank ! MPI rank #ifdef ATLAS_HAVE_TRANS integer :: rank_opt real(c_double) :: norms(1) @@ -500,10 +500,12 @@ subroutine specnorm_r2(this, spectra, norm, rank) class(atlas_Trans), intent(in) :: this real(c_double), intent(in) :: spectra(:,:) real(c_double), intent(inout) :: norm(:) - integer, optional :: rank + integer, optional :: rank ! MPI rank #ifdef 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%c_ptr(), size(spectra,1), spectra_view, norm, rank_opt ) #else diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index 02690cebc..3a2f5d8df 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -254,7 +254,11 @@ CASE( "test_arrayview_slice_type" ) EXPECT( slice3 == 123 ); - static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); + // Following static assert fails somehow for Cray <= 8.5 (8.6 OK)... + // Using runtime EXPECT instead works fine + //static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); + EXPECT( read_write_view.ACCESS == Intent::ReadWrite ); + static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); static_assert( std::is_same< decltype(slice3), Reference >::value, "failed" ); @@ -291,7 +295,11 @@ CASE( "test_arrayview_slice_type" ) EXPECT( slice4 == 123 ); - static_assert( read_only_view.ACCESS == Intent::ReadOnly, "failed" ); + // Following static assert fails somehow for Cray <= 8.5 (8.6 OK)... + // Using runtime EXPECT instead works fine + //static_assert( read_only_view.ACCESS == Intent::ReadOnly, "failed" ); + EXPECT( read_only_view.ACCESS == Intent::ReadOnly ); + static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); static_assert( std::is_same< decltype(slice3), Reference >::value, "failed" ); @@ -327,7 +335,11 @@ CASE( "test_arrayview_slice_type" ) EXPECT( slice3 == 123 ); - static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); + // Following static assert fails somehow for Cray <= 8.5 (8.6 OK)... + // Using runtime EXPECT instead works fine + //static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); + EXPECT( read_write_view.ACCESS == Intent::ReadWrite ); + static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); static_assert( std::is_same< decltype(slice3), Reference >::value, "failed" ); diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 63245f5f7..c866d99a3 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -97,7 +97,7 @@ struct compute_strides { template struct validate { - static bool apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { + static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { std::array strides; strides[Rank-1] = 1; compute_strides::apply(arrv, strides); @@ -161,7 +161,7 @@ void test_rank0_arrview(Fixture& f) { arr.syncHostDevice(); - f.halo_exchange.template execute(arr, f.on_device_); + f.halo_exchange.execute(arr, f.on_device_); arr.syncHostDevice(); @@ -186,7 +186,7 @@ void test_rank1(Fixture& f) { arr.syncHostDevice(); - f.halo_exchange.template execute(arr, f.on_device_); + f.halo_exchange.execute(arr, f.on_device_); arr.syncHostDevice(); @@ -228,7 +228,7 @@ void test_rank1_strided_v1(Fixture& f) { arr->syncHostDevice(); - f.halo_exchange.template execute(*arr, f.on_device_); + f.halo_exchange.execute(*arr, f.on_device_); arr->syncHostDevice(); @@ -268,7 +268,7 @@ void test_rank1_strided_v2(Fixture& f) { #endif } ) ); - f.halo_exchange.template execute(*arr, false); + f.halo_exchange.execute(*arr, false); switch( parallel::mpi::comm().rank() ) { @@ -295,7 +295,7 @@ void test_rank2(Fixture& f) { arr.syncHostDevice(); - f.halo_exchange.template execute(arr, f.on_device_); + f.halo_exchange.execute(arr, f.on_device_); arr.syncHostDevice(); @@ -357,7 +357,7 @@ void test_rank2_l1(Fixture& f) { arr_t.syncHostDevice(); - f.halo_exchange.template execute(*arr, false); + f.halo_exchange.execute(*arr, false); arr_t.syncHostDevice(); @@ -422,7 +422,7 @@ void test_rank2_l2_v2(Fixture& f) { #endif } ) ); - f.halo_exchange.template execute(*arr, f.on_device_); + f.halo_exchange.execute(*arr, f.on_device_); switch( parallel::mpi::comm().rank() ) { @@ -485,7 +485,7 @@ void test_rank2_v2(Fixture& f) { #endif } ) ); - f.halo_exchange.template execute(*arr, f.on_device_); + f.halo_exchange.execute(*arr, f.on_device_); switch( parallel::mpi::comm().rank() ) { @@ -532,7 +532,7 @@ void test_rank0_wrap(Fixture& f) { arr->syncHostDevice(); - f.halo_exchange.template execute(*arr, f.on_device_); + f.halo_exchange.execute(*arr, f.on_device_); arr->syncHostDevice(); @@ -555,7 +555,7 @@ void test_rank1_paralleldim1(Fixture& f) { arrv(1,j) = (size_t(f.part[j]) != parallel::mpi::comm().rank() ? 0 : f.gidx[j]*100); } - f.halo_exchange.template execute(arr, false); + f.halo_exchange.execute(arr, false); switch( parallel::mpi::comm().rank() ) { @@ -580,7 +580,7 @@ void test_rank2_paralleldim2(Fixture& f) { } } - f.halo_exchange.template execute >(arr, false); + f.halo_exchange.execute >(arr, false); switch( parallel::mpi::comm().rank() ) { From 9c1f47f880925791f2d9e5d8a89b5caae504107e Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Tue, 5 Dec 2017 19:10:30 +0000 Subject: [PATCH 211/355] Fix leak in atlas::mesh::MultiBlockConnectivityImpl::~MultiBlockConnectivityImpl --- src/atlas/array/Array.h | 1 + src/atlas/array/native/NativeArray.cc | 2 ++ src/atlas/mesh/Connectivity.cc | 5 ++++- src/atlas/mesh/Connectivity.h | 4 ++-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index 18a702d23..e7883ae9e 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -30,6 +30,7 @@ template class ArrayT_impl; class Array : public eckit::Owned { public: + virtual ~Array(); static Array* create( array::DataType, const ArrayShape& ); diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index 66b3b074b..a54331fd3 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -40,6 +40,8 @@ template Array* Array::wrap( Value* data, const ArraySpec& spec return new ArrayT( new native::WrappedDataStore(data), spec ); } +Array::~Array() {} + Array* Array::create( DataType datatype, const ArrayShape& shape ) { switch( datatype.kind() ) diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index 1931c89dc..8f973bd3c 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -461,7 +461,10 @@ MultiBlockConnectivityImpl::MultiBlockConnectivityImpl(const std::string& name) //------------------------------------------------------------------------------------------------------ -MultiBlockConnectivityImpl::~MultiBlockConnectivityImpl() {} +MultiBlockConnectivityImpl::~MultiBlockConnectivityImpl() { + if (block_displs_) delete block_displs_; + if (block_cols_) delete block_cols_; +} //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 22772556d..8a6d55bbc 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -171,7 +171,7 @@ class IrregularConnectivityImpl // it is compiled it for a GPU kernel IrregularConnectivityImpl(const IrregularConnectivityImpl &other); - ~IrregularConnectivityImpl(); + virtual ~IrregularConnectivityImpl(); //-- Accessors @@ -363,7 +363,7 @@ class MultiBlockConnectivityImpl : public IrregularConnectivityImpl size_t blocks, size_t block_displs[], size_t block_cols[] ); */ - ~MultiBlockConnectivityImpl(); + virtual ~MultiBlockConnectivityImpl(); //-- Accessors From f488356e2718c3d7009ff00bdc5d546abd1a244c Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Tue, 5 Dec 2017 20:10:37 +0000 Subject: [PATCH 212/355] Fix atlas::array::Vector::Vector(size_t N) when N=0 --- src/atlas/array/Vector.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/atlas/array/Vector.h b/src/atlas/array/Vector.h index 666b688d0..75addc6e1 100644 --- a/src/atlas/array/Vector.h +++ b/src/atlas/array/Vector.h @@ -30,8 +30,7 @@ namespace array { template class Vector { public: - Vector() : data_(nullptr), data_gpu_(nullptr), size_(0) {} - Vector(size_t N) : data_(new T[N]), data_gpu_(nullptr), size_(N) {} + Vector(size_t N = 0) : data_(N ? new T[N] : nullptr), data_gpu_(nullptr), size_(N) {} void resize_impl(size_t N) { if( data_gpu_ ) throw eckit::AssertionFailed("we can not resize a vector after has been cloned to device"); From 4ade10b24a6b152008c10715e87dc099a0f914bf Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 11 Dec 2017 13:20:29 +0000 Subject: [PATCH 213/355] ATLAS-140: Global transforms for serial runs --- src/atlas/trans/ifs/TransIFS.cc | 39 ++++++++++++++++----------------- src/tests/trans/test_trans.cc | 19 ++++++++++++++++ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index b95ef34ce..abb04bc39 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -76,6 +76,10 @@ class TransParameters { return config_.getString("write_legendre",""); } + bool global() const { + return config_.getBool("global",false); + } + private: const eckit::Configuration& config_; }; @@ -233,15 +237,10 @@ void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra args.rspvor = vorticity_spectra; args.rspdiv = divergence_spectra; args.rgp = gp_fields; - if( params.scalar_derivatives() ) { - args.lscalarders = true; - } - if( params.wind_EW_derivatives() ) { - args.luvder_EW = true; - } - if( params.vorticity_divergence_fields() ) { - args.lvordivgp = true; - } + args.lglobal = params.global(); + args.lscalarders = params.scalar_derivatives(); + args.luvder_EW = params.wind_EW_derivatives(); + args.lvordivgp = params.vorticity_divergence_fields(); TRANS_CHECK( ::trans_invtrans(&args) ); } @@ -256,9 +255,8 @@ void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra args.nscalar = nb_scalar_fields; args.rspscalar = scalar_spectra; args.rgp = gp_fields; - if( params.scalar_derivatives() ) { - args.lscalarders = true; - } + args.lglobal = params.global(); + args.lscalarders = params.scalar_derivatives(); TRANS_CHECK( ::trans_invtrans(&args) ); } @@ -274,37 +272,38 @@ void TransIFS::invtrans( const int nb_vordiv_fields, const double vorticity_spec args.rspvor = vorticity_spectra; args.rspdiv = divergence_spectra; args.rgp = gp_fields; - if( params.wind_EW_derivatives() ) { - args.luvder_EW = true; - } - if( params.vorticity_divergence_fields() ) { - args.lvordivgp = true; - } + args.lglobal = params.global(); + args.luvder_EW = params.wind_EW_derivatives(); + args.lvordivgp = params.vorticity_divergence_fields(); TRANS_CHECK( ::trans_invtrans(&args) ); } /////////////////////////////////////////////////////////////////////////////// void TransIFS::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], - const eckit::Configuration& ) const + const eckit::Configuration& config ) const { + TransParameters params(config); struct ::DirTrans_t args = new_dirtrans(trans_.get()); args.nscalar = nb_fields; args.rgp = scalar_fields; args.rspscalar = scalar_spectra; + args.lglobal = params.global(); TRANS_CHECK( ::trans_dirtrans(&args) ); } /////////////////////////////////////////////////////////////////////////////// void TransIFS::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], - const eckit::Configuration& ) const + const eckit::Configuration& config ) const { + TransParameters params(config); struct ::DirTrans_t args = new_dirtrans(trans_.get()); args.nvordiv = nb_fields; args.rspvor = vorticity_spectra; args.rspdiv = divergence_spectra; args.rgp = wind_fields; + args.lglobal = params.global(); TRANS_CHECK( ::trans_dirtrans(&args) ); } diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 1078a385e..518e241bb 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -487,6 +487,25 @@ CASE( "test_trans_using_functionspace_StructuredColumns" ) } +CASE( "test_trans_MIR_lonlat" ) +{ + Log::info() << "test_trans_MIR_lonlat" << std::endl; + + Grid grid("L48"); + trans::Trans trans( grid, 47 ); + + // global fields + std::vector spf( trans.spectralCoefficients() ); + std::vector gpf( grid.size() ); + + if( parallel::mpi::comm().size() == 1 ) { + EXPECT_NO_THROW( trans.invtrans( 1, spf.data(), gpf.data(), option::global() ) ); + + EXPECT_NO_THROW( trans.dirtrans( 1, gpf.data(), spf.data(), option::global() ) ); + + } +} + //----------------------------------------------------------------------------- From f50461f7a03aa7f58f4e8b76148b84fd54ad7a03 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 11 Dec 2017 15:24:54 +0000 Subject: [PATCH 214/355] ATLAS-135 multiscalar fields for TransLocal --- src/atlas/trans/local/FourierTransforms.cc | 21 ++++++++++++++------- src/atlas/trans/local/FourierTransforms.h | 11 +++++++++-- src/atlas/trans/local/LegendreTransforms.cc | 20 ++++++++++++-------- src/atlas/trans/local/LegendreTransforms.h | 3 ++- src/atlas/trans/local/TransLocal.cc | 16 +++++++++------- src/tests/trans/test_transgeneral.cc | 6 ++++-- 6 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc index e30b3949d..53280d0e5 100644 --- a/src/atlas/trans/local/FourierTransforms.cc +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -16,19 +16,26 @@ namespace trans { //----------------------------------------------------------------------------- -double invtrans_fourier( +void invtrans_fourier( const size_t trcFT, - const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) - const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) - const double lon ) // longitude in radians (in) + const double lon, // longitude in radians (in) + const int nb_fields, // Number of fields + const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) + const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) + double rgp[] ) // gridpoint { - double result(0); + for( int jfld=0; jfld0 - leg_real[jm] += 2. * spec[2*k] * legpol[k]; - leg_imag[jm] += 2. * spec[2*k+1] * legpol[k]; + for( int jfld=0; jfld0 + leg_real[jm*nb_fields+jfld] += 2. * spec[(2*k )*nb_fields+jfld] * legpol[k]; + leg_imag[jm*nb_fields+jfld] += 2. * spec[(2*k+1)*nb_fields+jfld] * legpol[k]; + } } } // Undo factor 2 for (jm == 0) - leg_real[0] /= 2.; - leg_imag[0] /= 2.; - + for( int jfld=0; jfld legReal(truncation_+1); - std::vector legImag(truncation_+1); + std::vector legReal(nb_fields*(truncation_+1)); + std::vector legImag(nb_fields*(truncation_+1)); // Transform if( grid::StructuredGrid g = grid_ ) { @@ -187,12 +187,13 @@ void TransLocal::invtrans( double trcFT = fourier_truncation( truncation_, lat ); // Legendre transform: - invtrans_legendre( truncation_, trcFT, legPol(lat,j), scalar_spectra, legReal.data(), legImag.data() ); + invtrans_legendre( truncation_, trcFT, legPol(lat,j), nb_fields, scalar_spectra, legReal.data(), legImag.data() ); // Fourier transform: for( size_t i=0; i& zlfpol, // values of associated Legendre functions, size (trc+1)*trc/2 (out) double rspecg[]) // spectral data, size (trc+1)*trc (in) { - trans::invtrans_legendre( trc, trcFT, zlfpol.data(), rspecg, rlegReal.data(), rlegImag.data() ); + trans::invtrans_legendre( trc, trcFT, zlfpol.data(), 1, rspecg, rlegReal.data(), rlegImag.data() ); } //----------------------------------------------------------------------------- @@ -95,7 +95,9 @@ double fourier_transform( array::ArrayView& rlegImag,// values of associated Legendre functions, size (trc+1)*trc/2 (out) double lon) // radians { - return trans::invtrans_fourier( trcFT, rlegReal.data(), rlegImag.data(), lon ); + double gp; + trans::invtrans_fourier( trcFT, lon, 1, rlegReal.data(), rlegImag.data(), &gp ); + return gp; } //----------------------------------------------------------------------------- From be320543d82e15beafbf3c94b12d423618c7dd24 Mon Sep 17 00:00:00 2001 From: cosunae Date: Tue, 12 Dec 2017 10:33:31 +0100 Subject: [PATCH 215/355] fix last merge --- src/atlas/parallel/HaloExchange.h | 6 ++---- src/tests/array/test_array_kernel.cu | 6 ------ 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 7b9565546..ca9267c5c 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -246,9 +246,8 @@ void HaloExchange::pack_send_buffer( const array::ArrayView::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); } else -#else - halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); #endif + halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); } template @@ -262,9 +261,8 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); } else -#else - halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); #endif + halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); } diff --git a/src/tests/array/test_array_kernel.cu b/src/tests/array/test_array_kernel.cu index e74d69261..0cce4f38f 100644 --- a/src/tests/array/test_array_kernel.cu +++ b/src/tests/array/test_array_kernel.cu @@ -9,18 +9,12 @@ */ #include -<<<<<<< HEAD #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" -======= ->>>>>>> escape-develop-0.12 #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "atlas/runtime/Log.h" -#include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" - using namespace atlas::array; using namespace eckit::testing; From 1bfe03f94a710e84f9079ce4873cc34392c2d19f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 15 Dec 2017 17:59:48 +0000 Subject: [PATCH 216/355] Fix missing symbol with GRIDTOOLS_STORAGE=ON --- src/atlas/array/gridtools/GridToolsArray.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 509f20511..c31ca542e 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -268,6 +268,11 @@ Array* Array::create(DataType datatype, const ArrayShape& shape, const ArrayLayo //------------------------------------------------------------------------------ +Array::~Array() { +} + +//------------------------------------------------------------------------------ + template size_t ArrayT::footprint() const { size_t size = sizeof(*this); From 36e0bcd02a09299850bc47a5fa57702c2551d952 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 5 Jan 2018 14:53:36 +0000 Subject: [PATCH 217/355] ATLAS-135 Found source of uninitialised data in Belousov algorithm. For now set to zero. --- src/atlas/trans/local/FourierTransforms.h | 5 -- src/atlas/trans/local/LegendrePolynomials.cc | 7 ++ src/atlas/trans/local/LegendreTransforms.cc | 6 +- src/tests/trans/test_transgeneral.cc | 92 +++++++++++--------- 4 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/atlas/trans/local/FourierTransforms.h b/src/atlas/trans/local/FourierTransforms.h index ff7261e51..d4c503f3b 100644 --- a/src/atlas/trans/local/FourierTransforms.h +++ b/src/atlas/trans/local/FourierTransforms.h @@ -21,11 +21,6 @@ namespace trans { // Author: // Andreas Mueller *ECMWF* // -double invtrans_fourier( - const size_t trcFT, - const double lon, // longitude in radians (in) - const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) - const double rlegImag[]); // values of associated Legendre functions, size (trc+1)*trc/2 (out) void invtrans_fourier( const size_t trcFT, diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index 4b3cc0472..11fd22486 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -89,6 +89,13 @@ void compute_legendre_polynomials( legpol[idxmn(1,jn)] = zdlldn; } +{ +#warning zfn(jn_odd,0) used but uninitialized... Andreas should look at this. Set to zero for now. + for( int jn=1; jn<=trc; jn+=2 ) { + zfn(jn,0) = 0.; + } +} + // odd N for( int jn=1; jn<=trc; jn+=2 ) { double zdlk = 0.5*zfn(jn,0); diff --git a/src/atlas/trans/local/LegendreTransforms.cc b/src/atlas/trans/local/LegendreTransforms.cc index 6f0194245..67a491751 100644 --- a/src/atlas/trans/local/LegendreTransforms.cc +++ b/src/atlas/trans/local/LegendreTransforms.cc @@ -28,8 +28,10 @@ void invtrans_legendre( // Legendre transformation: int k = 0; for( int jm=0; jm<=trcFT; ++jm ) { - leg_real[jm] = 0.; - leg_imag[jm] = 0.; + for( int jfld=0; jfld& zlfpol)// values of associated Legendre functions, size (trc+1)*trc/2 (out) { trans::compute_legendre_polynomials(trc,lat,zlfpol.data()); @@ -81,8 +81,8 @@ void legendre_transform( const size_t trcFT, // truncation for Fourier transformation (in) array::ArrayView& rlegReal,// values of associated Legendre functions, size (trc+1)*trc/2 (out) array::ArrayView& rlegImag,// values of associated Legendre functions, size (trc+1)*trc/2 (out) - array::ArrayView& zlfpol, // values of associated Legendre functions, size (trc+1)*trc/2 (out) - double rspecg[]) // spectral data, size (trc+1)*trc (in) + const array::ArrayView& zlfpol, // values of associated Legendre functions, size (trc+1)*trc/2 (in) + const double rspecg[]) // spectral data, size (trc+1)*trc (in) { trans::invtrans_legendre( trc, trcFT, zlfpol.data(), 1, rspecg, rlegReal.data(), rlegImag.data() ); } @@ -93,11 +93,11 @@ double fourier_transform( const size_t trcFT, array::ArrayView& rlegReal,// values of associated Legendre functions, size (trc+1)*trc/2 (out) array::ArrayView& rlegImag,// values of associated Legendre functions, size (trc+1)*trc/2 (out) - double lon) // radians + const double lon) // radians { - double gp; - trans::invtrans_fourier( trcFT, lon, 1, rlegReal.data(), rlegImag.data(), &gp ); - return gp; + double gp[1]; + trans::invtrans_fourier( trcFT, lon, 1, rlegReal.data(), rlegImag.data(), gp ); + return gp[0]; } //----------------------------------------------------------------------------- @@ -110,9 +110,9 @@ double fourier_transform( double spectral_transform_point( const size_t trc, // truncation (in) const size_t trcFT, // truncation for Fourier transformation (in) - double lon, // longitude in radians (in) - double lat, // latitude in radians (in) - double rspecg[]) // spectral data, size (trc+1)*trc (in) + const double lon, // longitude in radians (in) + const double lat, // latitude in radians (in) + const double rspecg[]) // spectral data, size (trc+1)*trc (in) { int N = (trc+2)*(trc+1)/2; ATLAS_TRACE(); @@ -145,10 +145,10 @@ double spectral_transform_point( void spectral_transform_grid( const size_t trc, // truncation (in) const size_t trcFT, // truncation for Fourier transformation (in) - Grid grid, // call with something like Grid("O32") - double rspecg[], // spectral data, size (trc+1)*trc (in) + const Grid grid, // call with something like Grid("O32") + const double rspecg[], // spectral data, size (trc+1)*trc (in) double rgp[], // resulting grid point data (out) - bool pointwise) // use point function for unstructured mesh for testing purposes + const bool pointwise) // use point function for unstructured mesh for testing purposes { std::ostream& out = Log::info(); // just for debugging int N = (trc+2)*(trc+1)/2; @@ -162,11 +162,10 @@ void spectral_transform_grid( atlas::array::ArrayT rlegImag_(trcFT+1); atlas::array::ArrayView rlegImag = make_view(rlegImag_); - for( int jm=0; jm{ - { 50., 20.}, - { 30., -20.}, - { 179., -89.}, - {-101., 70.} - }); + Grid g = grid::UnstructuredGrid( { + { 50., 20.}, + { 30., -20.}, + { 179., -89.}, + {-101., 70.} + } ); int trc = 47; // truncation @@ -420,9 +428,9 @@ CASE( "test_transgeneral_point" ) } } - +#endif //----------------------------------------------------------------------------- - +#if 1 CASE( "test_transgeneral_unstructured" ) { std::ostream& out = Log::info(); @@ -547,6 +555,10 @@ CASE( "test_transgeneral_with_translib" ) double rms_trans = compute_rms(g.size(), gpg.data(), rgp.data()); double rms_gen = compute_rms(g.size(), rgp.data(), rgp_analytic.data()); + if( rms_gen >= tolerance ) { + ATLAS_DEBUG_VAR(rms_gen); + ATLAS_DEBUG_VAR(tolerance); + } EXPECT( rms_gen < tolerance ); EXPECT( rms_trans < tolerance ); } @@ -570,7 +582,7 @@ CASE( "test_trans_invtrans" ) { trans.invtrans(1,rspec.data(),rgp.data()); } - +#endif //----------------------------------------------------------------------------- } // namespace test From d8ea036ed96943c7dbe2e7ee87f9e9ee510dd330 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 18 Dec 2017 18:05:06 +0000 Subject: [PATCH 218/355] FCKIT-4 Porting atlas_Grid to new fckit/final feature --- src/apps/atlas-numerics-nabla.F90 | 4 +- src/atlas_f/atlas_module.F90 | 2 +- src/atlas_f/grid/atlas_Grid_module.F90 | 181 +++++++++++++-------- src/atlas_f/trans/atlas_Trans_module.F90 | 7 +- src/tests/grid/fctest_griddistribution.F90 | 6 +- 5 files changed, 128 insertions(+), 72 deletions(-) diff --git a/src/apps/atlas-numerics-nabla.F90 b/src/apps/atlas-numerics-nabla.F90 index 5b6dcdcc0..10ec63ac7 100644 --- a/src/apps/atlas-numerics-nabla.F90 +++ b/src/apps/atlas-numerics-nabla.F90 @@ -19,7 +19,7 @@ module atlas_nabla_program_module character(len=1024) :: msg - type(atlas_StructuredGrid) :: grid + type(atlas_Grid) :: grid type(atlas_Mesh) :: mesh type(atlas_mesh_Nodes) :: nodes type(atlas_functionspace_NodeColumns) :: node_columns @@ -245,7 +245,7 @@ subroutine init() if( .not.config%get("radius",RA) ) RA = 1.0 ! Setup - grid = atlas_StructuredGrid(grid_uid) + grid = atlas_Grid(grid_uid) meshgenerator = atlas_MeshGenerator() mesh = meshgenerator%generate(grid) ! second optional argument for atlas_GridDistrubution fvm = atlas_fvm_Method(mesh,config) diff --git a/src/atlas_f/atlas_module.F90 b/src/atlas_f/atlas_module.F90 index 0d86bc2e1..e715737fd 100644 --- a/src/atlas_f/atlas_module.F90 +++ b/src/atlas_f/atlas_module.F90 @@ -96,7 +96,7 @@ module atlas_module use atlas_Mesh_module, only: & & atlas_Mesh use atlas_Grid_module, only: & - & atlas_Grid, & + & atlas_Grid , & & 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 78e843ba5..ac5e43d75 100644 --- a/src/atlas_f/grid/atlas_Grid_module.F90 +++ b/src/atlas_f/grid/atlas_Grid_module.F90 @@ -1,24 +1,29 @@ -module atlas_Grid_module +#include "fckit/defines.h" +module atlas_Grid_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_shared_ptr_module, only: fckit_owned +use fckit_shared_object_module, only: fckit_shared_object, fckit_c_deleter!, fckit_owned +!use fckit_object_module, only: fckit_object implicit none -private :: fckit_refcounted +private :: fckit_shared_object public :: atlas_Grid +#if 1 public :: atlas_StructuredGrid public :: atlas_GaussianGrid public :: atlas_ReducedGaussianGrid public :: atlas_RegularGaussianGrid public :: atlas_RegularLonLatGrid +#endif private !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_Grid +TYPE, extends(fckit_shared_object) :: atlas_Grid ! Purpose : ! ------- @@ -34,16 +39,21 @@ module atlas_Grid_module !------------------------------------------------------------------------------ contains procedure :: size => atlas_Grid__size - procedure, public :: delete => atlas_Grid__delete - procedure, public :: copy => atlas_Grid__copy + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Grid__final_auto +#endif + END TYPE atlas_Grid interface atlas_Grid module procedure atlas_Grid__ctor_id module procedure atlas_Grid__ctor_config + module procedure atlas_Grid__ctor_cptr end interface !------------------------------------------------------------------------------ +#if 1 TYPE, extends(atlas_Grid) :: atlas_StructuredGrid @@ -91,7 +101,6 @@ module atlas_Grid_module !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ - TYPE, extends(atlas_StructuredGrid) :: atlas_GaussianGrid ! Purpose : @@ -188,7 +197,7 @@ module atlas_Grid_module module procedure atlas_grid_RegularLonLat__ctor_int32 module procedure atlas_grid_RegularLonLat__ctor_int64 end interface - +#endif !------------------------------------------------------------------------------ !------------------------------------------------------------------------------ @@ -216,122 +225,181 @@ pure function c_idx_64(f_idx) result(c_idx) c_idx = f_idx - 1_c_long end function +! ----------------------------------------------------------------------------- +! Destructor + +subroutine atlas_Grid__final_auto(this) + type(atlas_Grid) :: this +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ----------------------------------------------------------------------------- ! Constructors -function atlas_Grid__ctor_id(identifier) result(grid) +function atlas_Grid__ctor_id(identifier) result(this) use fckit_c_interop_module, only: c_str use atlas_grid_Structured_c_binding - type(atlas_Grid) :: grid + type(atlas_Grid) :: this character(len=*), intent(in) :: identifier - call grid%reset_c_ptr( atlas__grid__Structured(c_str(identifier)) ) + call this%reset_c_ptr( atlas__grid__Structured(c_str(identifier)), & + fckit_c_deleter(atlas__grid__Structured__delete), & + fckit_owned() ) + call this%return() end function -function atlas_Grid__ctor_config(config) result(grid) +function atlas_Grid__ctor_config(config) result(this) use atlas_grid_Structured_c_binding use atlas_Config_module, only: atlas_Config - type(atlas_Grid) :: grid + type(atlas_Grid) :: this type(atlas_Config), intent(in) :: config - call grid%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()) ) + call this%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()), & + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() +end function + +function atlas_Grid__ctor_cptr(cptr) result(this) + use fckit_c_interop_module, only: c_str + use, intrinsic :: iso_c_binding, only : c_ptr + use atlas_grid_Structured_c_binding + type(atlas_Grid) :: this + type(c_ptr), intent(in) :: cptr + call this%reset_c_ptr( cptr, fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function ! ----------------------------------------------------------------------------- +#if 1 -function atlas_StructuredGrid__ctor_id(identifier) result(grid) +function atlas_StructuredGrid__ctor_id(identifier) result(this) use fckit_c_interop_module, only: c_str use atlas_grid_Structured_c_binding - type(atlas_StructuredGrid) :: grid + type(atlas_StructuredGrid) :: this character(len=*), intent(in) :: identifier - call grid%reset_c_ptr( atlas__grid__Structured(c_str(identifier)) ) + call this%reset_c_ptr( atlas__grid__Structured(c_str(identifier)), & + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function -function atlas_StructuredGrid__ctor_config(config) result(grid) +function atlas_StructuredGrid__ctor_config(config) result(this) use atlas_grid_Structured_c_binding use atlas_Config_module, only: atlas_Config - type(atlas_StructuredGrid) :: grid + type(atlas_StructuredGrid) :: this type(atlas_Config), intent(in) :: config - call grid%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()) ) + call this%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()), & + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function -function atlas_StructuredGrid__ctor_cptr(cptr) result(grid) +function atlas_StructuredGrid__ctor_cptr(cptr) result(this) use fckit_c_interop_module, only: c_str use, intrinsic :: iso_c_binding, only : c_ptr use atlas_grid_Structured_c_binding - type(atlas_StructuredGrid) :: grid + type(atlas_StructuredGrid) :: this type(c_ptr), intent(in) :: cptr - call grid%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr, & + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function !----------------------------------------------------------------------------- -function atlas_GaussianGrid__ctor_id(identifier) result(grid) +function atlas_GaussianGrid__ctor_id(identifier) result(this) use fckit_c_interop_module, only: c_str use atlas_grid_Structured_c_binding - type(atlas_GaussianGrid) :: grid + type(atlas_GaussianGrid) :: this character(len=*), intent(in) :: identifier - call grid%reset_c_ptr( atlas__grid__Structured(c_str(identifier)) ) + call this%reset_c_ptr( atlas__grid__Structured(c_str(identifier)),& + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function ! ----------------------------------------------------------------------------- -function atlas_RegularGaussianGrid__ctor_int32(N) result(grid) +function atlas_RegularGaussianGrid__ctor_int32(N) result(this) use, intrinsic :: iso_c_binding, only: c_int, c_long use atlas_grid_Structured_c_binding - type(atlas_RegularGaussianGrid) :: grid + type(atlas_RegularGaussianGrid) :: this integer(c_int), intent(in) :: N - call grid%reset_c_ptr( atlas__grid__regular__RegularGaussian(int(N,c_long)) ) + call this%reset_c_ptr( atlas__grid__regular__RegularGaussian(int(N,c_long)), & + fckit_c_deleter(atlas__grid__Structured__delete), & + fckit_owned() ) + call this%return() end function -function atlas_RegularGaussianGrid__ctor_int64(N) result(grid) +function atlas_RegularGaussianGrid__ctor_int64(N) result(this) use, intrinsic :: iso_c_binding, only: c_long use atlas_grid_Structured_c_binding - type(atlas_RegularGaussianGrid) :: grid + type(atlas_RegularGaussianGrid) :: this integer(c_long), intent(in) :: N - call grid%reset_c_ptr( atlas__grid__regular__RegularGaussian(int(N,c_long)) ) + call this%reset_c_ptr( atlas__grid__regular__RegularGaussian(int(N,c_long)), & + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function !----------------------------------------------------------------------------- -function atlas_ReducedGaussianGrid__ctor_int32(nx) result(grid) +function atlas_ReducedGaussianGrid__ctor_int32(nx) result(this) use, intrinsic :: iso_c_binding, only: c_int, c_long use atlas_grid_Structured_c_binding - type(atlas_ReducedGaussianGrid) :: grid + type(atlas_ReducedGaussianGrid) :: this integer(c_int), intent(in) :: nx(:) - call grid%reset_c_ptr( & - & atlas__grid__reduced__ReducedGaussian_int( nx, int(size(nx),c_long) ) ) + call this%reset_c_ptr( & + & atlas__grid__reduced__ReducedGaussian_int( nx, int(size(nx),c_long) ), & + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function -function atlas_ReducedGaussianGrid__ctor_int64(nx) result(grid) +function atlas_ReducedGaussianGrid__ctor_int64(nx) result(this) use, intrinsic :: iso_c_binding, only: c_int, c_long use atlas_grid_Structured_c_binding - type(atlas_ReducedGaussianGrid) :: grid + type(atlas_ReducedGaussianGrid) :: this integer(c_long), intent(in) :: nx(:) - call grid%reset_c_ptr( & - & atlas__grid__reduced__ReducedGaussian_long( nx, int(size(nx),c_long) ) ) + call this%reset_c_ptr( & + & atlas__grid__reduced__ReducedGaussian_long( nx, int(size(nx),c_long) ), & + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function !----------------------------------------------------------------------------- -function atlas_grid_RegularLonLat__ctor_int32(nlon,nlat) result(grid) +function atlas_grid_RegularLonLat__ctor_int32(nlon,nlat) result(this) use, intrinsic :: iso_c_binding, only: c_int, c_long use atlas_grid_Structured_c_binding - type(atlas_RegularLonLatGrid) :: grid + type(atlas_RegularLonLatGrid) :: this integer(c_int), intent(in) :: nlon, nlat - call grid%reset_c_ptr( atlas__grid__regular__RegularLonLat(int(nlon,c_long),int(nlat,c_long)) ) + call this%reset_c_ptr( atlas__grid__regular__RegularLonLat(int(nlon,c_long),int(nlat,c_long)), & + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function -function atlas_grid_RegularLonLat__ctor_int64(nlon,nlat) result(grid) +function atlas_grid_RegularLonLat__ctor_int64(nlon,nlat) result(this) use, intrinsic :: iso_c_binding, only: c_long use atlas_grid_Structured_c_binding - type(atlas_RegularLonLatGrid) :: grid + type(atlas_RegularLonLatGrid) :: this integer(c_long), intent(in) :: nlon, nlat - call grid%reset_c_ptr( atlas__grid__regular__RegularLonLat( nlon, nlat ) ) + call this%reset_c_ptr( atlas__grid__regular__RegularLonLat( nlon, nlat ), & + & fckit_c_deleter(atlas__grid__Structured__delete), & + & fckit_owned() ) + call this%return() end function ! ----------------------------------------------------------------------------- ! Structured members - +#endif function atlas_Grid__size(this) result(npts) use, intrinsic :: iso_c_binding, only: c_long use atlas_grid_Structured_c_binding @@ -339,7 +407,7 @@ function atlas_Grid__size(this) result(npts) integer(c_long) :: npts npts = atlas__grid__Structured__size(this%c_ptr()) end function - +#if 1 function Gaussian__N(this) result(N) use, intrinsic :: iso_c_binding, only: c_long use atlas_grid_Structured_c_binding @@ -521,22 +589,7 @@ function Structured__lonlat_64(this, i,j) result(lonlat) integer(c_long) , intent(in) :: i,j call atlas__grid__Structured__lonlat(this%c_ptr(), c_idx(i), c_idx(j), lonlat) end function - -subroutine atlas_Grid__delete(this) - use atlas_grid_Structured_c_binding - class(atlas_Grid), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__grid__Structured__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - - - -subroutine atlas_Grid__copy(this,obj_in) - class(atlas_Grid), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine +#endif ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index c4a40aeff..1f1e2a559 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -215,13 +215,14 @@ function grid( this ) use atlas_trans_c_binding use atlas_grid_module class(atlas_Trans) :: this - type(atlas_StructuredGrid) :: grid + type(atlas_Grid) :: grid #ifdef ATLAS_HAVE_TRANS - grid = atlas_StructuredGrid( atlas__Trans__grid(this%c_ptr()) ) + grid = atlas_Grid( atlas__Trans__grid(this%c_ptr()) ) call grid%return() +#warning here #else THROW_ERROR - call grid%return() + ! call grid%return() #endif end function diff --git a/src/tests/grid/fctest_griddistribution.F90 b/src/tests/grid/fctest_griddistribution.F90 index 97ca007e5..f427d62f8 100644 --- a/src/tests/grid/fctest_griddistribution.F90 +++ b/src/tests/grid/fctest_griddistribution.F90 @@ -80,19 +80,21 @@ griddistribution = atlas_GridDistribution(part, part0=1) - write(msg,*) "owners fort",griddistribution%owners() - call atlas_log%info(msg) + FCTEST_CHECK_EQUAL( grid%owners(), 1 ) meshgenerator = atlas_MeshGenerator() mesh = meshgenerator%generate(grid,griddistribution) call griddistribution%final() + FCTEST_CHECK_EQUAL( grid%owners(), 2 ) + gmsh = atlas_output_Gmsh("testf3.msh") call gmsh%write(mesh) deallocate(part) call mesh%final() + FCTEST_CHECK_EQUAL( grid%owners(), 1 ) call gmsh%final() call grid%final() call meshgenerator%final() From f85ab93549ba9664f1f30877c22ae5c7104ea221 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 18 Dec 2017 23:31:20 +0000 Subject: [PATCH 219/355] FCKIT-4 Port Grid and MeshGenerator --- src/atlas_f/field/atlas_FieldSet_module.F90 | 16 +---- .../atlas_FunctionSpace_module.F90 | 23 ++---- ...functionspace_StructuredColumns_module.F90 | 5 +- .../grid/atlas_GridDistribution_module.F90 | 48 +++++-------- src/atlas_f/grid/atlas_Grid_module.F90 | 71 +++++-------------- .../mesh/atlas_MeshGenerator_module.F90 | 43 ++++------- src/atlas_f/mesh/atlas_Mesh_module.F90 | 40 +++-------- 7 files changed, 73 insertions(+), 173 deletions(-) diff --git a/src/atlas_f/field/atlas_FieldSet_module.F90 b/src/atlas_f/field/atlas_FieldSet_module.F90 index 8ae893f0b..754895003 100644 --- a/src/atlas_f/field/atlas_FieldSet_module.F90 +++ b/src/atlas_f/field/atlas_FieldSet_module.F90 @@ -1,11 +1,11 @@ module atlas_FieldSet_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_FieldSet @@ -16,7 +16,7 @@ module atlas_FieldSet_module !----------------------------- !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_FieldSet +TYPE, extends(fckit_owned_object) :: atlas_FieldSet ! Purpose : ! ------- @@ -42,7 +42,6 @@ module atlas_FieldSet_module procedure, private :: field_by_idx_size_t procedure, public :: add generic :: field => field_by_name, field_by_idx_int, field_by_idx_size_t - procedure, public :: delete END TYPE atlas_FieldSet !------------------------------------------------------------------------------ @@ -80,15 +79,6 @@ function atlas_FieldSet__ctor(name) result(fieldset) call fieldset%return() end function -subroutine delete(this) - use atlas_fieldset_c_binding - class(atlas_FieldSet), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__FieldSet__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - subroutine add(this,field) use atlas_fieldset_c_binding use atlas_Field_module, only: atlas_Field diff --git a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 index e6e6014e8..73dde0f51 100644 --- a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 +++ b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 @@ -1,13 +1,13 @@ module atlas_functionspace_module -use fckit_refcounted_module, only : fckit_refcounted +use fckit_owned_object_module, only : fckit_owned_object use atlas_field_module, only : atlas_Field use atlas_config_module, only : atlas_Config implicit none -private :: fckit_refcounted +private :: fckit_owned_object private :: atlas_Field private :: atlas_Config @@ -16,7 +16,7 @@ module atlas_functionspace_module private !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_FunctionSpace +TYPE, extends(fckit_owned_object) :: atlas_FunctionSpace ! Purpose : ! ------- @@ -35,7 +35,6 @@ module atlas_functionspace_module !------------------------------------------------------------------------------ contains procedure, public :: name => atlas_FunctionSpace__name - procedure, public :: delete => atlas_FunctionSpace__delete procedure, private :: create_field_args procedure, private :: create_field_template @@ -59,22 +58,14 @@ module atlas_functionspace_module contains !======================================================== -function atlas_FunctionSpace__cptr(cptr) result(functionspace) +function atlas_FunctionSpace__cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only : c_ptr - type(atlas_FunctionSpace) :: functionspace + type(atlas_FunctionSpace) :: this type(c_ptr), intent(in) :: cptr - call functionspace%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) + call this%return() end function -subroutine atlas_FunctionSpace__delete(this) - use atlas_functionspace_c_binding - class(atlas_FunctionSpace), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__FunctionSpace__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine atlas_FunctionSpace__delete - function atlas_FunctionSpace__name(this) result(name) use atlas_functionspace_c_binding use fckit_c_interop_module, only : c_ptr_to_string diff --git a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 index 1f0cefd77..0e28ccef1 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 @@ -180,11 +180,12 @@ subroutine set_index(this) this%index(i_min:i_max,j_min:j_max) => index_fptr(:) end subroutine +#warning todo subroutine copy(this,obj_in) - use fckit_refcounted_module, only : fckit_refcounted + use fckit_shared_ptr_module, only : fckit_shared_ptr use fckit_exception_module, only : fckit_exception class(atlas_functionspace_StructuredColumns), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in + class(fckit_shared_ptr), target, intent(in) :: obj_in nullify(this%index) select type( obj_in_concrete => obj_in ) class is (atlas_functionspace_StructuredColumns) diff --git a/src/atlas_f/grid/atlas_GridDistribution_module.F90 b/src/atlas_f/grid/atlas_GridDistribution_module.F90 index 82e8999e0..344255fae 100644 --- a/src/atlas_f/grid/atlas_GridDistribution_module.F90 +++ b/src/atlas_f/grid/atlas_GridDistribution_module.F90 @@ -1,11 +1,12 @@ +#include "fckit/defines.h" module atlas_GridDistribution_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_GridDistribution @@ -17,7 +18,7 @@ module atlas_GridDistribution_module !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_GridDistribution +TYPE, extends(fckit_owned_object) :: atlas_GridDistribution ! Purpose : ! ------- @@ -32,11 +33,9 @@ module atlas_GridDistribution_module !------------------------------------------------------------------------------ contains - - procedure, public :: final => atlas_GridDistribution__final - procedure, public :: delete => atlas_GridDistribution__delete - procedure, public :: copy => atlas_GridDistribution__copy - +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_GridDistribution__final_auto +#endif END TYPE atlas_GridDistribution !------------------------------------------------------------------------------ @@ -57,7 +56,8 @@ function atlas_GridDistribution__cptr( cptr ) result(this) use atlas_distribution_c_binding type(atlas_GridDistribution) :: this type(c_ptr) :: cptr - call this%reset_c_ptr( cptr ); + call this%reset_c_ptr( cptr ) + call this%return() end function function atlas_GridDistribution__ctor( part, part0 ) result(this) @@ -69,32 +69,18 @@ function atlas_GridDistribution__ctor( part, part0 ) result(this) opt_part0 = 0 if( present(part0) ) opt_part0 = part0 npts = size(part) - this = atlas_GridDistribution__cptr( atlas__GridDistribution__new(npts, part, opt_part0) ) + call this%reset_c_ptr( atlas__GridDistribution__new(npts, part, opt_part0) ) call this%return() end function +! ---------------------------------------------------------------------------------------- -subroutine atlas_GridDistribution__final( this ) - use atlas_distribution_c_binding - class(atlas_GridDistribution), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__GridDistribution__delete(this%c_ptr()); - end if - call this%reset_c_ptr() -end subroutine - -subroutine atlas_GridDistribution__delete( this ) - use atlas_distribution_c_binding - class(atlas_GridDistribution), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__GridDistribution__delete(this%c_ptr()); - end if - call this%reset_c_ptr() -end subroutine - -subroutine atlas_GridDistribution__copy(this,obj_in) - class(atlas_GridDistribution), intent(inout) :: this - class(fckit_RefCounted), target, intent(in) :: obj_in +subroutine atlas_GridDistribution__final_auto(this) + type(atlas_GridDistribution) :: this +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) end subroutine ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/grid/atlas_Grid_module.F90 b/src/atlas_f/grid/atlas_Grid_module.F90 index ac5e43d75..7864db9eb 100644 --- a/src/atlas_f/grid/atlas_Grid_module.F90 +++ b/src/atlas_f/grid/atlas_Grid_module.F90 @@ -3,27 +3,23 @@ module atlas_Grid_module -use fckit_shared_ptr_module, only: fckit_owned -use fckit_shared_object_module, only: fckit_shared_object, fckit_c_deleter!, fckit_owned -!use fckit_object_module, only: fckit_object +use fckit_owned_object_module, only: fckit_owned_object implicit none -private :: fckit_shared_object +private :: fckit_owned_object public :: atlas_Grid -#if 1 public :: atlas_StructuredGrid public :: atlas_GaussianGrid public :: atlas_ReducedGaussianGrid public :: atlas_RegularGaussianGrid public :: atlas_RegularLonLatGrid -#endif private !------------------------------------------------------------------------------ -TYPE, extends(fckit_shared_object) :: atlas_Grid +TYPE, extends(fckit_owned_object) :: atlas_Grid ! Purpose : ! ------- @@ -53,7 +49,6 @@ module atlas_Grid_module end interface !------------------------------------------------------------------------------ -#if 1 TYPE, extends(atlas_Grid) :: atlas_StructuredGrid @@ -197,8 +192,7 @@ module atlas_Grid_module module procedure atlas_grid_RegularLonLat__ctor_int32 module procedure atlas_grid_RegularLonLat__ctor_int64 end interface -#endif -!------------------------------------------------------------------------------ + !------------------------------------------------------------------------------ interface c_idx @@ -245,9 +239,7 @@ function atlas_Grid__ctor_id(identifier) result(this) use atlas_grid_Structured_c_binding type(atlas_Grid) :: this character(len=*), intent(in) :: identifier - call this%reset_c_ptr( atlas__grid__Structured(c_str(identifier)), & - fckit_c_deleter(atlas__grid__Structured__delete), & - fckit_owned() ) + call this%reset_c_ptr( atlas__grid__Structured(c_str(identifier)) ) call this%return() end function @@ -256,9 +248,7 @@ function atlas_Grid__ctor_config(config) result(this) use atlas_Config_module, only: atlas_Config type(atlas_Grid) :: this type(atlas_Config), intent(in) :: config - call this%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()), & - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + call this%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()) ) call this%return() end function @@ -268,22 +258,18 @@ function atlas_Grid__ctor_cptr(cptr) result(this) use atlas_grid_Structured_c_binding type(atlas_Grid) :: this type(c_ptr), intent(in) :: cptr - call this%reset_c_ptr( cptr, fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + call this%reset_c_ptr( cptr ) call this%return() end function ! ----------------------------------------------------------------------------- -#if 1 function atlas_StructuredGrid__ctor_id(identifier) result(this) use fckit_c_interop_module, only: c_str use atlas_grid_Structured_c_binding type(atlas_StructuredGrid) :: this character(len=*), intent(in) :: identifier - call this%reset_c_ptr( atlas__grid__Structured(c_str(identifier)), & - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + call this%reset_c_ptr( atlas__grid__Structured(c_str(identifier)) ) call this%return() end function @@ -292,9 +278,7 @@ function atlas_StructuredGrid__ctor_config(config) result(this) use atlas_Config_module, only: atlas_Config type(atlas_StructuredGrid) :: this type(atlas_Config), intent(in) :: config - call this%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()), & - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + call this%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()) ) call this%return() end function @@ -304,9 +288,7 @@ function atlas_StructuredGrid__ctor_cptr(cptr) result(this) use atlas_grid_Structured_c_binding type(atlas_StructuredGrid) :: this type(c_ptr), intent(in) :: cptr - call this%reset_c_ptr( cptr, & - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + call this%reset_c_ptr( cptr ) call this%return() end function @@ -317,9 +299,7 @@ function atlas_GaussianGrid__ctor_id(identifier) result(this) use atlas_grid_Structured_c_binding type(atlas_GaussianGrid) :: this character(len=*), intent(in) :: identifier - call this%reset_c_ptr( atlas__grid__Structured(c_str(identifier)),& - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + call this%reset_c_ptr( atlas__grid__Structured(c_str(identifier)) ) call this%return() end function @@ -330,9 +310,7 @@ function atlas_RegularGaussianGrid__ctor_int32(N) result(this) use atlas_grid_Structured_c_binding type(atlas_RegularGaussianGrid) :: this integer(c_int), intent(in) :: N - call this%reset_c_ptr( atlas__grid__regular__RegularGaussian(int(N,c_long)), & - fckit_c_deleter(atlas__grid__Structured__delete), & - fckit_owned() ) + call this%reset_c_ptr( atlas__grid__regular__RegularGaussian(int(N,c_long)) ) call this%return() end function @@ -341,9 +319,7 @@ function atlas_RegularGaussianGrid__ctor_int64(N) result(this) use atlas_grid_Structured_c_binding type(atlas_RegularGaussianGrid) :: this integer(c_long), intent(in) :: N - call this%reset_c_ptr( atlas__grid__regular__RegularGaussian(int(N,c_long)), & - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + call this%reset_c_ptr( atlas__grid__regular__RegularGaussian(int(N,c_long)) ) call this%return() end function @@ -355,9 +331,7 @@ function atlas_ReducedGaussianGrid__ctor_int32(nx) result(this) type(atlas_ReducedGaussianGrid) :: this integer(c_int), intent(in) :: nx(:) call this%reset_c_ptr( & - & atlas__grid__reduced__ReducedGaussian_int( nx, int(size(nx),c_long) ), & - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + & atlas__grid__reduced__ReducedGaussian_int( nx, int(size(nx),c_long) ) ) call this%return() end function @@ -367,9 +341,7 @@ function atlas_ReducedGaussianGrid__ctor_int64(nx) result(this) type(atlas_ReducedGaussianGrid) :: this integer(c_long), intent(in) :: nx(:) call this%reset_c_ptr( & - & atlas__grid__reduced__ReducedGaussian_long( nx, int(size(nx),c_long) ), & - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + & atlas__grid__reduced__ReducedGaussian_long( nx, int(size(nx),c_long) ) ) call this%return() end function @@ -380,9 +352,7 @@ function atlas_grid_RegularLonLat__ctor_int32(nlon,nlat) result(this) use atlas_grid_Structured_c_binding type(atlas_RegularLonLatGrid) :: this integer(c_int), intent(in) :: nlon, nlat - call this%reset_c_ptr( atlas__grid__regular__RegularLonLat(int(nlon,c_long),int(nlat,c_long)), & - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + call this%reset_c_ptr( atlas__grid__regular__RegularLonLat(int(nlon,c_long),int(nlat,c_long)) ) call this%return() end function @@ -391,15 +361,13 @@ function atlas_grid_RegularLonLat__ctor_int64(nlon,nlat) result(this) use atlas_grid_Structured_c_binding type(atlas_RegularLonLatGrid) :: this integer(c_long), intent(in) :: nlon, nlat - call this%reset_c_ptr( atlas__grid__regular__RegularLonLat( nlon, nlat ), & - & fckit_c_deleter(atlas__grid__Structured__delete), & - & fckit_owned() ) + call this%reset_c_ptr( atlas__grid__regular__RegularLonLat( nlon, nlat ) ) call this%return() end function ! ----------------------------------------------------------------------------- ! Structured members -#endif + function atlas_Grid__size(this) result(npts) use, intrinsic :: iso_c_binding, only: c_long use atlas_grid_Structured_c_binding @@ -407,7 +375,7 @@ function atlas_Grid__size(this) result(npts) integer(c_long) :: npts npts = atlas__grid__Structured__size(this%c_ptr()) end function -#if 1 + function Gaussian__N(this) result(N) use, intrinsic :: iso_c_binding, only: c_long use atlas_grid_Structured_c_binding @@ -589,7 +557,6 @@ function Structured__lonlat_64(this, i,j) result(lonlat) integer(c_long) , intent(in) :: i,j call atlas__grid__Structured__lonlat(this%c_ptr(), c_idx(i), c_idx(j), lonlat) end function -#endif ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 b/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 index 4ed73d2ee..272b42fcd 100644 --- a/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 +++ b/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 @@ -2,11 +2,11 @@ module atlas_MeshGenerator_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_MeshGenerator @@ -17,10 +17,8 @@ module atlas_MeshGenerator_module !-----------------------------! !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_MeshGenerator +TYPE, extends(fckit_owned_object) :: atlas_MeshGenerator contains - procedure, public :: delete => atlas_MeshGenerator__delete - procedure, public :: copy => atlas_MeshGenerator__copy procedure, public :: generate => atlas_MeshGenerator__generate END TYPE atlas_MeshGenerator @@ -37,48 +35,33 @@ module atlas_MeshGenerator_module !======================================================== -function atlas_MeshGenerator__cptr(cptr) result(MeshGenerator) +function atlas_MeshGenerator__cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only: c_ptr - type(atlas_MeshGenerator) :: MeshGenerator + type(atlas_MeshGenerator) :: this type(c_ptr), intent(in) :: cptr - call MeshGenerator%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) + call this%return() end function -function atlas_MeshGenerator__config(config) result(meshgenerator) +function atlas_MeshGenerator__config(config) result(this) use fckit_c_interop_module, only: c_str use atlas_MeshGenerator_c_binding use atlas_Config_module, only: atlas_Config - type(atlas_MeshGenerator) :: meshgenerator + type(atlas_MeshGenerator) :: this type(atlas_Config), intent(in), optional :: config character(len=:), allocatable :: meshgenerator_type if( present(config) ) then if( .not. config%get("type",meshgenerator_type) ) then - allocate(meshgenerator_type, source='structured') + meshgenerator_type='structured' endif - meshgenerator = atlas_MeshGenerator__cptr(atlas__MeshGenerator__create(c_str(meshgenerator_type),config%c_ptr())) + call this%reset_c_ptr( atlas__MeshGenerator__create(c_str(meshgenerator_type),config%c_ptr()) ) else - meshgenerator = atlas_MeshGenerator__cptr(atlas__MeshGenerator__create_noconfig('structured')) + call this%reset_c_ptr( atlas__MeshGenerator__create_noconfig(c_str('structured')) ) endif - call meshgenerator%return() + call this%return() end function - -subroutine atlas_MeshGenerator__delete(this) - use atlas_MeshGenerator_c_binding - class(atlas_MeshGenerator), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__MeshGenerator__delete(this%c_ptr()) - endif - call this%reset_c_ptr() -end subroutine atlas_MeshGenerator__delete - - -subroutine atlas_MeshGenerator__copy(this,obj_in) - class(atlas_MeshGenerator), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - function atlas_MeshGenerator__generate(this,grid,distribution) result(mesh) use atlas_MeshGenerator_c_binding use atlas_Grid_module, only: atlas_Grid diff --git a/src/atlas_f/mesh/atlas_Mesh_module.F90 b/src/atlas_f/mesh/atlas_Mesh_module.F90 index 8011725f9..63284cf50 100644 --- a/src/atlas_f/mesh/atlas_Mesh_module.F90 +++ b/src/atlas_f/mesh/atlas_Mesh_module.F90 @@ -3,11 +3,11 @@ module atlas_Mesh_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_Mesh @@ -17,7 +17,7 @@ module atlas_Mesh_module ! atlas_Mesh ! !----------------------------- -TYPE, extends(fckit_refcounted) :: atlas_Mesh +TYPE, extends(fckit_owned_object) :: atlas_Mesh ! Purpose : ! ------- @@ -36,8 +36,6 @@ module atlas_Mesh_module procedure, public :: nodes => Mesh__nodes procedure, public :: cells => Mesh__cells procedure, public :: edges => Mesh__edges - procedure, public :: delete => atlas_Mesh__delete - procedure, public :: copy => atlas_Mesh__copy procedure, public :: footprint procedure, public :: clone_to_device @@ -55,20 +53,22 @@ module atlas_Mesh_module contains !======================================================== -function atlas_Mesh__cptr(cptr) result(mesh) +function atlas_Mesh__cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only: c_ptr use atlas_mesh_c_binding - type(atlas_Mesh) :: mesh + type(atlas_Mesh) :: this type(c_ptr), intent(in) :: cptr - call mesh%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) + call this%return() end function atlas_Mesh__cptr !------------------------------------------------------------------------------- -function atlas_Mesh__ctor() result(mesh) +function atlas_Mesh__ctor() result(this) use atlas_mesh_c_binding - type(atlas_Mesh) :: mesh - call mesh%reset_c_ptr( atlas__Mesh__new() ) + type(atlas_Mesh) :: this + call this%reset_c_ptr( atlas__Mesh__new() ) + call this%return() end function atlas_Mesh__ctor !------------------------------------------------------------------------------- @@ -108,24 +108,6 @@ function Mesh__edges(this) result(edges) !------------------------------------------------------------------------------- -subroutine atlas_Mesh__delete(this) - use atlas_mesh_c_binding - class(atlas_Mesh), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__Mesh__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine atlas_Mesh__delete - -!------------------------------------------------------------------------------- - -subroutine atlas_Mesh__copy(this,obj_in) - class(atlas_Mesh), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - -!------------------------------------------------------------------------------- - function footprint(this) use, intrinsic :: iso_c_binding, only : c_size_t use atlas_mesh_c_binding From dad85ad329250c0c75fc4fcc8fa10394cd313d14 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 12:08:59 +0000 Subject: [PATCH 220/355] FCKIT-4 Port atlas_Field and workaround gfortran internal compiler error --- .../autogenerated/atlas_Field_module_fypp.F90 | 75 +++++++++---------- src/atlas_f/field/atlas_FieldSet_module.F90 | 1 + src/atlas_f/field/atlas_Field_module.F90 | 29 +++---- src/atlas_f/field/atlas_State_module.F90 | 48 ++++-------- .../atlas_FunctionSpace_module.F90 | 4 - src/atlas_f/grid/atlas_Partitioner_module.F90 | 46 +++--------- 6 files changed, 73 insertions(+), 130 deletions(-) diff --git a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 index 2b9afe4c0..bb234d3db 100644 --- a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 +++ b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 @@ -3,10 +3,16 @@ module atlas_field_module use fckit_refcounted_module, only : fckit_refcounted +use fckit_object_module, only : fckit_object +use fckit_owned_object_module, only : fckit_owned_object +use fckit_shared_object_module, only : fckit_shared_object use atlas_Error_module, only: atlas_code_location, atlas_abort, atlas_throw_outofrange implicit none -private :: fckit_refcounted, atlas_code_location, atlas_abort, atlas_throw_outofrange +private :: fckit_refcounted +private :: fckit_owned_object +private :: fckit_shared_object +private :: atlas_code_location, atlas_abort, atlas_throw_outofrange public :: atlas_Field public :: atlas_real @@ -20,7 +26,7 @@ module atlas_field_module !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_Field +TYPE, extends(fckit_owned_object) :: atlas_Field ! Purpose : ! ------- @@ -55,8 +61,6 @@ module atlas_field_module procedure :: set_levels procedure :: set_functionspace - procedure, public :: delete => atlas_Field__delete - procedure, private :: access_host_data_int32_r1 procedure, private :: access_host_data_int32_r1_shape procedure, private :: access_device_data_int32_r1 @@ -372,7 +376,7 @@ subroutine array_c_to_f_int32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -408,7 +412,7 @@ subroutine array_c_to_f_int64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -444,7 +448,7 @@ subroutine array_c_to_f_real32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -480,7 +484,7 @@ subroutine array_c_to_f_real64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -516,7 +520,7 @@ subroutine array_c_to_f_logical32_r1(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -552,7 +556,7 @@ subroutine array_c_to_f_int32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -588,7 +592,7 @@ subroutine array_c_to_f_int64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -624,7 +628,7 @@ subroutine array_c_to_f_real32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -660,7 +664,7 @@ subroutine array_c_to_f_real64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -696,7 +700,7 @@ subroutine array_c_to_f_logical32_r2(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -732,7 +736,7 @@ subroutine array_c_to_f_int32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -768,7 +772,7 @@ subroutine array_c_to_f_int64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -804,7 +808,7 @@ subroutine array_c_to_f_real32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -840,7 +844,7 @@ subroutine array_c_to_f_real64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -876,7 +880,7 @@ subroutine array_c_to_f_logical32_r3(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -912,7 +916,7 @@ subroutine array_c_to_f_int32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -948,7 +952,7 @@ subroutine array_c_to_f_int64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -984,7 +988,7 @@ subroutine array_c_to_f_real32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -1020,7 +1024,7 @@ subroutine array_c_to_f_real64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -1056,7 +1060,7 @@ subroutine array_c_to_f_logical32_r4(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",171)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -2232,7 +2236,7 @@ integer function atlas_real(kind) else if (kind == c_float) then atlas_real = ATLAS_KIND_REAL32 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",274)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",278)) end if end function @@ -2248,7 +2252,7 @@ integer function atlas_integer(kind) else if (kind == c_long) then atlas_integer = ATLAS_KIND_INT64 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",290)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",294)) end if end if end function @@ -2274,7 +2278,7 @@ function atlas_data_type(kind) else if( kind == ATLAS_KIND_REAL64 ) then atlas_data_type = "real64" else - call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",316)) + call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",320)) endif end function @@ -2285,6 +2289,7 @@ function atlas_Field__cptr(cptr) result(field) type(atlas_Field) :: field type(c_ptr), intent(in) :: cptr call field%reset_c_ptr( cptr ) + call field%return() end function !------------------------------------------------------------------------------- @@ -2910,17 +2915,6 @@ function atlas_Field__wrap_real64_r4(data) result(field) !------------------------------------------------------------------------------- -subroutine atlas_Field__delete(this) - use atlas_field_c_binding - class(atlas_Field), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__Field__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - -!------------------------------------------------------------------------------- - function Field__name(this) result(field_name) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr @@ -2936,9 +2930,10 @@ end function Field__name function Field__functionspace(this) result(functionspace) use atlas_field_c_binding - type(fckit_refcounted) :: functionspace + type(fckit_owned_object) :: functionspace class(atlas_Field), intent(in) :: this call functionspace%reset_c_ptr( atlas__Field__functionspace(this%c_ptr()) ) + call functionspace%return() end function Field__functionspace !------------------------------------------------------------------------------- @@ -3072,7 +3067,7 @@ subroutine rename(this,name) subroutine set_functionspace(this,functionspace) use atlas_field_c_binding class(atlas_Field), intent(inout) :: this - class(fckit_refcounted), intent(in) :: functionspace + class(fckit_owned_object), intent(in) :: functionspace call atlas__field__set_functionspace(this%c_ptr(),functionspace%c_ptr()) end subroutine diff --git a/src/atlas_f/field/atlas_FieldSet_module.F90 b/src/atlas_f/field/atlas_FieldSet_module.F90 index 754895003..1b15cd922 100644 --- a/src/atlas_f/field/atlas_FieldSet_module.F90 +++ b/src/atlas_f/field/atlas_FieldSet_module.F90 @@ -64,6 +64,7 @@ function atlas_FieldSet__cptr(cptr) result(fieldset) type(atlas_FieldSet) :: fieldset type(c_ptr), intent(in) :: cptr call fieldset%reset_c_ptr( cptr ) + call fieldset%return() end function function atlas_FieldSet__ctor(name) result(fieldset) diff --git a/src/atlas_f/field/atlas_Field_module.F90 b/src/atlas_f/field/atlas_Field_module.F90 index 75f1938ae..747625a59 100644 --- a/src/atlas_f/field/atlas_Field_module.F90 +++ b/src/atlas_f/field/atlas_Field_module.F90 @@ -12,10 +12,16 @@ module atlas_field_module use fckit_refcounted_module, only : fckit_refcounted +use fckit_object_module, only : fckit_object +use fckit_owned_object_module, only : fckit_owned_object +use fckit_shared_object_module, only : fckit_shared_object use atlas_Error_module, only: atlas_code_location, atlas_abort, atlas_throw_outofrange implicit none -private :: fckit_refcounted, atlas_code_location, atlas_abort, atlas_throw_outofrange +private :: fckit_refcounted +private :: fckit_owned_object +private :: fckit_shared_object +private :: atlas_code_location, atlas_abort, atlas_throw_outofrange public :: atlas_Field public :: atlas_real @@ -29,7 +35,7 @@ module atlas_field_module !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_Field +TYPE, extends(fckit_owned_object) :: atlas_Field ! Purpose : ! ------- @@ -64,8 +70,6 @@ module atlas_field_module procedure :: set_levels procedure :: set_functionspace - procedure, public :: delete => atlas_Field__delete - #:for rank in ranks #:for dtype in dtypes procedure, private :: access_host_data_${dtype}$_r${rank}$ @@ -324,6 +328,7 @@ function atlas_Field__cptr(cptr) result(field) type(atlas_Field) :: field type(c_ptr), intent(in) :: cptr call field%reset_c_ptr( cptr ) + call field%return() end function !------------------------------------------------------------------------------- @@ -473,17 +478,6 @@ function atlas_Field__wrap_${dtype}$_r${rank}$(data) result(field) !------------------------------------------------------------------------------- -subroutine atlas_Field__delete(this) - use atlas_field_c_binding - class(atlas_Field), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__Field__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - -!------------------------------------------------------------------------------- - function Field__name(this) result(field_name) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr @@ -499,9 +493,10 @@ end function Field__name function Field__functionspace(this) result(functionspace) use atlas_field_c_binding - type(fckit_refcounted) :: functionspace + type(fckit_owned_object) :: functionspace class(atlas_Field), intent(in) :: this call functionspace%reset_c_ptr( atlas__Field__functionspace(this%c_ptr()) ) + call functionspace%return() end function Field__functionspace !------------------------------------------------------------------------------- @@ -635,7 +630,7 @@ subroutine rename(this,name) subroutine set_functionspace(this,functionspace) use atlas_field_c_binding class(atlas_Field), intent(inout) :: this - class(fckit_refcounted), intent(in) :: functionspace + class(fckit_owned_object), intent(in) :: functionspace call atlas__field__set_functionspace(this%c_ptr(),functionspace%c_ptr()) end subroutine diff --git a/src/atlas_f/field/atlas_State_module.F90 b/src/atlas_f/field/atlas_State_module.F90 index a4b6f1a21..61e6ce9ac 100644 --- a/src/atlas_f/field/atlas_State_module.F90 +++ b/src/atlas_f/field/atlas_State_module.F90 @@ -1,11 +1,13 @@ module atlas_State_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object +use atlas_Field_module, only: atlas_Field implicit none -private :: fckit_refcounted +private :: fckit_owned_object +private :: atlas_Field public :: atlas_State @@ -18,7 +20,7 @@ module atlas_State_module ! (C) Copyright 2013-2015 ECMWF. !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_State +TYPE, extends(fckit_owned_object) :: atlas_State ! Purpose : ! ------- @@ -53,9 +55,6 @@ module atlas_State_module procedure, private :: field_by_index => atlas_State__field_by_index generic, public :: field => field_by_name, field_by_index procedure, public :: metadata => atlas_State__metadata - - procedure, public :: delete => atlas_State__delete - procedure, public :: copy => atlas_State__copy END TYPE atlas_State interface atlas_State @@ -72,52 +71,37 @@ module atlas_State_module ! State routines -function atlas_State__new() result(State) +function atlas_State__new() result(this) use atlas_state_c_binding - type(atlas_State) :: State - call State%reset_c_ptr( atlas__State__new() ) + type(atlas_State) :: this + call this%reset_c_ptr( atlas__State__new() ) + call this%return() end function -function atlas_State__generate(generator, params) result(State) +function atlas_State__generate(generator, params) result(this) use fckit_c_interop_module, only: c_str use atlas_state_c_binding use atlas_Config_module, only: atlas_Config - type(atlas_State) :: State + type(atlas_State) :: this character(len=*), intent(in) :: generator class(atlas_Config), intent(in), optional :: params type(atlas_Config) :: p - call State%reset_c_ptr( atlas__State__new() ) + call this%reset_c_ptr( atlas__State__new() ) if( present(params) ) then - call atlas__State__initialize(State%c_ptr(),c_str(generator),params%c_ptr()) + call atlas__State__initialize(this%c_ptr(),c_str(generator),params%c_ptr()) else p = atlas_Config() - call atlas__State__initialize(State%c_ptr(),c_str(generator),p%c_ptr()) + call atlas__State__initialize(this%c_ptr(),c_str(generator),p%c_ptr()) call p%final() endif + call this%return() end function -subroutine atlas_State__delete(this) - use atlas_state_c_binding - class(atlas_State), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__State__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - - -subroutine atlas_State__copy(this,obj_in) - class(atlas_State), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - - subroutine atlas_State__add(this,field) use atlas_state_c_binding - use atlas_Field_module, only: atlas_Field class(atlas_State), intent(inout) :: this class(atlas_Field), intent(in) :: field call atlas__State__add(this%c_ptr(),field%c_ptr()) @@ -153,7 +137,6 @@ function atlas_State__size(this) result(size) function atlas_State__field_by_name(this,name) result(field) use fckit_c_interop_module, only: c_str use atlas_state_c_binding - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_State), intent(inout) :: this character(len=*), intent(in) :: name @@ -163,7 +146,6 @@ function atlas_State__field_by_name(this,name) result(field) function atlas_State__field_by_index(this,index) result(field) use atlas_state_c_binding - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_State), intent(in) :: this integer, intent(in) :: index diff --git a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 index 73dde0f51..d402af058 100644 --- a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 +++ b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 @@ -83,7 +83,6 @@ function atlas_FunctionSpace__name(this) result(name) function create_field_args(this,kind,name,levels,variables,global,owner) result(field) use atlas_functionspace_c_binding use, intrinsic :: iso_c_binding, only : c_int - use atlas_field_module, only : atlas_Field use atlas_config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Functionspace), intent(in) :: this @@ -114,7 +113,6 @@ function create_field_args(this,kind,name,levels,variables,global,owner) result( function create_field_template(this,template,name,global,owner) result(field) use atlas_functionspace_c_binding use, intrinsic :: iso_c_binding, only : c_int - use atlas_field_module, only : atlas_Field use atlas_config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Functionspace), intent(in) :: this @@ -148,7 +146,6 @@ function create_field_template(this,template,name,global,owner) result(field) function deprecated_create_field_1(this,name,kind,levels,vars) result(field) use atlas_functionspace_c_binding use, intrinsic :: iso_c_binding, only : c_int - use atlas_field_module, only : atlas_Field use atlas_config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Functionspace), intent(in) :: this @@ -178,7 +175,6 @@ function deprecated_create_field_1(this,name,kind,levels,vars) result(field) function deprecated_create_field_2(this,require_name,kind,levels) result(field) use atlas_functionspace_c_binding use, intrinsic :: iso_c_binding, only : c_int - use atlas_field_module, only : atlas_Field use atlas_config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Functionspace), intent(in) :: this diff --git a/src/atlas_f/grid/atlas_Partitioner_module.F90 b/src/atlas_f/grid/atlas_Partitioner_module.F90 index 701691ec7..049e527cf 100644 --- a/src/atlas_f/grid/atlas_Partitioner_module.F90 +++ b/src/atlas_f/grid/atlas_Partitioner_module.F90 @@ -1,11 +1,11 @@ module atlas_Partitioner_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_Partitioner public :: atlas_MatchingMeshPartitioner @@ -18,7 +18,7 @@ module atlas_Partitioner_module !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_Partitioner +TYPE, extends(fckit_owned_object) :: atlas_Partitioner ! Purpose : ! ------- @@ -33,11 +33,6 @@ module atlas_Partitioner_module !------------------------------------------------------------------------------ contains - - procedure, public :: final => atlas_Partitioner__final - procedure, public :: delete => atlas_Partitioner__delete - procedure, public :: copy => atlas_Partitioner__copy - procedure, public :: partition END TYPE atlas_Partitioner @@ -64,6 +59,7 @@ function atlas_Partitioner__ctor( config ) result(this) type(atlas_Partitioner) :: this type(atlas_Config) :: config call this%reset_c_ptr( atlas__grid__Partitioner__new( config%c_ptr() ) ) + call this%return() end function function atlas_MatchingMeshPartitioner__ctor( mesh, config ) result(this) @@ -76,36 +72,14 @@ function atlas_MatchingMeshPartitioner__ctor( mesh, config ) result(this) type(atlas_Config) :: opt_config if( present(config) ) then call this%reset_c_ptr( atlas__grid__MatchingMeshPartitioner__new( mesh%c_ptr(), config%c_ptr() ) ) - else - opt_config = atlas_Config() - call this%reset_c_ptr( atlas__grid__MatchingMeshPartitioner__new( mesh%c_ptr(), opt_config%c_ptr() ) ) - call opt_config%final() - endif + else + opt_config = atlas_Config() + call this%reset_c_ptr( atlas__grid__MatchingMeshPartitioner__new( mesh%c_ptr(), opt_config%c_ptr() ) ) + call opt_config%final() + endif + call this%return() end function -subroutine atlas_Partitioner__final( this ) - use atlas_partitioner_c_binding - class(atlas_Partitioner), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__grid__Partitioner__delete(this%c_ptr()); - end if - call this%reset_c_ptr() -end subroutine - -subroutine atlas_Partitioner__delete( this ) - use atlas_partitioner_c_binding - class(atlas_Partitioner), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__grid__Partitioner__delete(this%c_ptr()); - end if - call this%reset_c_ptr() -end subroutine - -subroutine atlas_Partitioner__copy(this,obj_in) - class(atlas_Partitioner), intent(inout) :: this - class(fckit_RefCounted), target, intent(in) :: obj_in -end subroutine - function partition(this,grid) result(distribution) use atlas_partitioner_c_binding use atlas_GridDistribution_module, only : atlas_GridDistribution From 1cf46a653333d7d2e9f77689f96227c7ec26dc86 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 12:10:04 +0000 Subject: [PATCH 221/355] FCKIT-4 Port atlas_Interpolation --- .../atlas_Interpolation_module.F90 | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/atlas_f/interpolation/atlas_Interpolation_module.F90 b/src/atlas_f/interpolation/atlas_Interpolation_module.F90 index 332c8bb34..a5dc37f8a 100644 --- a/src/atlas_f/interpolation/atlas_Interpolation_module.F90 +++ b/src/atlas_f/interpolation/atlas_Interpolation_module.F90 @@ -1,18 +1,18 @@ module atlas_Interpolation_module -use fckit_refcounted_module, only : fckit_refcounted +use fckit_owned_object_module, only : fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_Interpolation private !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_Interpolation +TYPE, extends(fckit_owned_object) :: atlas_Interpolation ! Purpose : ! ------- @@ -27,7 +27,6 @@ module atlas_Interpolation_module !------------------------------------------------------------------------------ contains - procedure, public :: delete procedure, private :: execute_field procedure, private :: execute_fieldset generic, public :: execute => execute_field, execute_fieldset @@ -62,16 +61,6 @@ function atlas_Interpolation__config_funcspace(config,source,target) result(this call this%return() end function -subroutine delete(this) - use atlas_Interpolation_c_binding - class(atlas_Interpolation), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__Interpolation__delete(this%c_ptr()) - endif - call this%reset_c_ptr() -end subroutine - - subroutine execute_field(this,source,target) use atlas_Interpolation_c_binding use atlas_Field_module, only : atlas_Field From 955d80aff171f6fc4dcf0ea4d663e13dcf85c06f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 12:10:36 +0000 Subject: [PATCH 222/355] FCKIT-4 Port atlas_ElementType --- src/atlas_f/mesh/atlas_ElementType_module.F90 | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/atlas_f/mesh/atlas_ElementType_module.F90 b/src/atlas_f/mesh/atlas_ElementType_module.F90 index e33969abb..b215ef3ce 100644 --- a/src/atlas_f/mesh/atlas_ElementType_module.F90 +++ b/src/atlas_f/mesh/atlas_ElementType_module.F90 @@ -1,11 +1,11 @@ module atlas_ElementType_module -use fckit_refcounted_module, only : fckit_refcounted +use fckit_owned_object_module, only : fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_ElementType public :: atlas_Triangle @@ -19,11 +19,9 @@ module atlas_ElementType_module ! atlas_ElementType ! !----------------------------- -type, extends(fckit_refcounted) :: atlas_ElementType +type, extends(fckit_owned_object) :: atlas_ElementType contains ! Public methods - procedure, public :: delete => atlas_ElementType__delete - procedure, public :: nb_nodes procedure, public :: nb_edges procedure, public :: name @@ -51,39 +49,34 @@ module atlas_ElementType_module contains !======================================================== -subroutine atlas_ElementType__delete(this) - use atlas_elementtype_c_binding - class(atlas_ElementType), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__mesh__ElementType__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - function atlas_ElementType__cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only : c_ptr use atlas_elementtype_c_binding type(atlas_ElementType) :: this type(c_ptr) :: cptr call this%reset_c_ptr( cptr ) + call this%return() end function function atlas_Quadrilateral__constructor() result(this) use atlas_elementtype_c_binding type(atlas_ElementType) :: this call this%reset_c_ptr( atlas__mesh__Quadrilateral__create() ) + call this%return() end function function atlas_Triangle__constructor() result(this) use atlas_elementtype_c_binding type(atlas_ElementType) :: this call this%reset_c_ptr( atlas__mesh__Triangle__create() ) + call this%return() end function function atlas_Line__constructor() result(this) use atlas_elementtype_c_binding type(atlas_ElementType) :: this call this%reset_c_ptr( atlas__mesh__Line__create() ) + call this%return() end function function nb_nodes(this) From 82312bcb776ee944a0f3e88dbc46b3b127b10ee8 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 12:11:25 +0000 Subject: [PATCH 223/355] FCKIT-4 Port atlas_Elements --- src/atlas_f/mesh/atlas_Elements_module.F90 | 24 +++++++--------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/atlas_f/mesh/atlas_Elements_module.F90 b/src/atlas_f/mesh/atlas_Elements_module.F90 index 36f6a90cb..9ac479996 100644 --- a/src/atlas_f/mesh/atlas_Elements_module.F90 +++ b/src/atlas_f/mesh/atlas_Elements_module.F90 @@ -1,11 +1,11 @@ module atlas_Elements_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_Elements @@ -15,11 +15,9 @@ module atlas_Elements_module ! atlas_Elements ! !----------------------------- -type, extends(fckit_refcounted) :: atlas_Elements +type, extends(fckit_owned_object) :: atlas_Elements contains ! Public methods - procedure, public :: delete => atlas_Elements__delete - procedure, public :: size => atlas_Elements__size procedure, public :: begin => atlas_Elements__begin procedure, public :: end => atlas_Elements__end @@ -58,22 +56,14 @@ module atlas_Elements_module contains !======================================================== -function atlas_Elements__cptr(cptr) result(elements) +function atlas_Elements__cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only: c_ptr - type(atlas_Elements) :: elements + type(atlas_Elements) :: this type(c_ptr), intent(in) :: cptr - call elements%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) + call this%return() end function -subroutine atlas_Elements__delete(this) - use atlas_elements_c_binding - class(atlas_Elements), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__mesh__Elements__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - function atlas_Elements__size(this) result(val) use, intrinsic :: iso_c_binding, only: c_size_t use atlas_elements_c_binding From 443575b5f6d5d07d36eb9ea6b373d5589246852c Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 12:19:00 +0000 Subject: [PATCH 224/355] FCKIT-4 Port atlas_HybridElements --- .../mesh/atlas_HybridElements_module.F90 | 25 ++++-------------- src/atlas_f/mesh/atlas_mesh_Cells_module.F90 | 2 ++ src/atlas_f/mesh/atlas_mesh_Edges_module.F90 | 2 ++ src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 | 26 ++++--------------- 4 files changed, 14 insertions(+), 41 deletions(-) diff --git a/src/atlas_f/mesh/atlas_HybridElements_module.F90 b/src/atlas_f/mesh/atlas_HybridElements_module.F90 index ce6db56b7..0f336f46c 100644 --- a/src/atlas_f/mesh/atlas_HybridElements_module.F90 +++ b/src/atlas_f/mesh/atlas_HybridElements_module.F90 @@ -1,7 +1,7 @@ module atlas_HybridElements_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object use atlas_Connectivity_module, only: atlas_MultiBlockConnectivity use atlas_Field_module, only: atlas_Field use atlas_ElementType_module, only: atlas_ElementType @@ -9,7 +9,7 @@ module atlas_HybridElements_module implicit none -private :: fckit_refcounted +private :: fckit_owned_object private :: atlas_MultiBlockConnectivity private :: atlas_Field private :: atlas_ElementType @@ -23,13 +23,10 @@ module atlas_HybridElements_module ! atlas_HybridElements ! !----------------------------- -type, extends(fckit_refcounted) :: atlas_HybridElements +type, extends(fckit_owned_object) :: atlas_HybridElements contains ! Public methods - procedure, public :: copy => atlas_HybridElements__copy - procedure, public :: delete => atlas_HybridElements__delete - procedure, public :: size => atlas_HybridElements__size procedure, public :: node_connectivity @@ -79,28 +76,16 @@ function atlas_HybridElements__cptr(cptr) result(this) type(atlas_HybridElements) :: this type(c_ptr), intent(in) :: cptr call this%reset_c_ptr( cptr ) + call this%return() end function function atlas_HybridElements__constructor() result(this) use atlas_hybridelements_c_binding type(atlas_HybridElements) :: this call this%reset_c_ptr( atlas__mesh__HybridElements__create() ) + call this%return() end function -subroutine atlas_HybridElements__delete(this) - use atlas_hybridelements_c_binding - class(atlas_HybridElements), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__mesh__HybridElements__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - -subroutine atlas_HybridElements__copy(this,obj_in) - class(atlas_HybridElements), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - function atlas_HybridElements__size(this) result(val) use, intrinsic :: iso_c_binding use atlas_hybridelements_c_binding diff --git a/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 b/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 index 4ae640779..a4737a950 100644 --- a/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 @@ -30,12 +30,14 @@ function atlas_mesh_cells__cptr(cptr) result(this) type(atlas_mesh_cells) :: this type(c_ptr), intent(in) :: cptr call this%reset_c_ptr( cptr ) + call this%return() end function function atlas_mesh_cells__constructor() result(this) use atlas_hybridelements_c_binding type(atlas_mesh_cells) :: this call this%reset_c_ptr( atlas__mesh__HybridElements__create() ) + call this%return() end function ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 b/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 index cbdb10040..25cdf01b3 100644 --- a/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 @@ -30,12 +30,14 @@ function atlas_mesh_edges__cptr(cptr) result(this) type(atlas_mesh_Edges) :: this type(c_ptr), intent(in) :: cptr call this%reset_c_ptr( cptr ) + call this%return() end function function atlas_mesh_edges__constructor() result(this) use atlas_hybridelements_c_binding type(atlas_mesh_Edges) :: this call this%reset_c_ptr( atlas__mesh__HybridElements__create() ) + call this%return() end function ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 b/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 index 438c54013..4a94611db 100644 --- a/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 @@ -1,11 +1,11 @@ module atlas_mesh_Nodes_module -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_mesh_Nodes @@ -15,7 +15,7 @@ module atlas_mesh_Nodes_module ! atlas_mesh_Nodes ! !----------------------------- -TYPE, extends(fckit_refcounted) :: atlas_mesh_Nodes +TYPE, extends(fckit_owned_object) :: atlas_mesh_Nodes contains procedure, public :: size => atlas_mesh_Nodes__size procedure, public :: resize @@ -47,10 +47,6 @@ module atlas_mesh_Nodes_module procedure, public :: cell_connectivity procedure, public :: connectivity - -procedure, public :: delete => atlas_mesh_Nodes__delete -procedure, public :: copy => atlas_mesh_Nodes__copy - end type interface atlas_mesh_Nodes @@ -68,28 +64,16 @@ function atlas_mesh_Nodes__cptr(cptr) result(this) type(atlas_mesh_Nodes) :: this type(c_ptr), intent(in) :: cptr call this%reset_c_ptr( cptr ) + call this%return() end function function atlas_mesh_Nodes__constructor() result(this) use atlas_nodes_c_binding type(atlas_mesh_Nodes) :: this call this%reset_c_ptr( atlas__mesh__Nodes__create() ) + call this%return() end function -subroutine atlas_mesh_Nodes__delete(this) - use atlas_nodes_c_binding - class(atlas_mesh_Nodes), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__mesh__Nodes__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - -subroutine atlas_mesh_Nodes__copy(this,obj_in) - class(atlas_mesh_Nodes), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - function atlas_mesh_Nodes__size(this) result(val) use, intrinsic :: iso_c_binding, only: c_size_t use atlas_nodes_c_binding From b96f9a1fcbfcd4bb22a62c0dc345b5760ee17b13 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 12:19:30 +0000 Subject: [PATCH 225/355] FCKIT-4 Port atlas_Mesh --- src/atlas_f/mesh/atlas_Mesh_module.F90 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/atlas_f/mesh/atlas_Mesh_module.F90 b/src/atlas_f/mesh/atlas_Mesh_module.F90 index 63284cf50..f51af496e 100644 --- a/src/atlas_f/mesh/atlas_Mesh_module.F90 +++ b/src/atlas_f/mesh/atlas_Mesh_module.F90 @@ -78,8 +78,8 @@ function Mesh__nodes(this) result(nodes) use atlas_mesh_Nodes_module, only: atlas_mesh_Nodes class(atlas_Mesh), intent(in) :: this type(atlas_mesh_Nodes) :: nodes - call nodes%reset_c_ptr( atlas__Mesh__nodes(this%c_ptr()) ) - if( nodes%is_null() ) write(0,*) 'call abort()' + nodes = atlas_mesh_Nodes( atlas__Mesh__nodes(this%c_ptr()) ) + call nodes%return() end function !------------------------------------------------------------------------------- @@ -89,8 +89,7 @@ function Mesh__cells(this) result(cells) use atlas_mesh_Cells_module, only: atlas_mesh_Cells class(atlas_Mesh), intent(in) :: this type(atlas_mesh_Cells) :: cells - cells = atlas_mesh_Cells(atlas__Mesh__cells(this%c_ptr())) - if( cells%is_null() ) write(0,*) 'call abort()' + cells = atlas_mesh_Cells( atlas__Mesh__cells(this%c_ptr()) ) call cells%return() end function @@ -102,7 +101,6 @@ function Mesh__edges(this) result(edges) class(atlas_Mesh), intent(in) :: this type(atlas_mesh_Edges) :: edges edges = atlas_mesh_Edges( atlas__Mesh__Edges(this%c_ptr()) ) - if( edges%is_null() ) write(0,*) 'call abort()' call edges%return() end function From e79f56ab8f66c0dac27df4689121c6e68836182e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 12:20:26 +0000 Subject: [PATCH 226/355] FCKIT-4 Port atlas_f/numerics --- src/atlas_f/numerics/atlas_Method_module.F90 | 38 ++++--------------- src/atlas_f/numerics/atlas_Nabla_module.F90 | 40 ++++++-------------- src/atlas_f/numerics/atlas_fvm_module.F90 | 22 +++++------ 3 files changed, 29 insertions(+), 71 deletions(-) diff --git a/src/atlas_f/numerics/atlas_Method_module.F90 b/src/atlas_f/numerics/atlas_Method_module.F90 index 1af6709a9..cdf4d2915 100644 --- a/src/atlas_f/numerics/atlas_Method_module.F90 +++ b/src/atlas_f/numerics/atlas_Method_module.F90 @@ -1,18 +1,18 @@ module atlas_Method_module -use fckit_refcounted_module, only : fckit_refcounted +use fckit_owned_object_module, only : fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_Method private !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_Method +TYPE, extends(fckit_owned_object) :: atlas_Method ! Purpose : ! ------- @@ -31,8 +31,6 @@ module atlas_Method_module !------------------------------------------------------------------------------ contains procedure, public :: name => atlas_Method__name - procedure, public :: delete => atlas_Method__delete - procedure, public :: copy => atlas_Method__copy #ifdef FORTRAN_SUPPORTS_FINAL final :: atlas_Method__final #endif @@ -47,36 +45,14 @@ module atlas_Method_module contains !======================================================== -function atlas_Method__cptr(cptr) result(Method) +function atlas_Method__cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only : c_ptr - type(atlas_Method) :: Method + type(atlas_Method) :: this type(c_ptr), intent(in) :: cptr - call Method%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) + call this%return() end function -#ifdef FORTRAN_SUPPORTS_FINAL -subroutine atlas_Method__final(this) - type(atlas_Method), intent(inout) :: this - call this%final() -end subroutine -#endif - -subroutine atlas_Method__delete(this) - use atlas_Method_c_binding - class(atlas_Method), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__Method__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine atlas_Method__delete - - -subroutine atlas_Method__copy(this,obj_in) - class(atlas_Method), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - - function atlas_Method__name(this) result(name) use atlas_Method_c_binding use fckit_c_interop_module, only : c_ptr_to_string diff --git a/src/atlas_f/numerics/atlas_Nabla_module.F90 b/src/atlas_f/numerics/atlas_Nabla_module.F90 index a21958060..b7cc6377c 100644 --- a/src/atlas_f/numerics/atlas_Nabla_module.F90 +++ b/src/atlas_f/numerics/atlas_Nabla_module.F90 @@ -1,18 +1,18 @@ module atlas_Nabla_module -use fckit_refcounted_module, only : fckit_refcounted +use fckit_owned_object_module, only : fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_Nabla private !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_Nabla +TYPE, extends(fckit_owned_object) :: atlas_Nabla ! Purpose : ! ------- @@ -27,8 +27,6 @@ module atlas_Nabla_module !------------------------------------------------------------------------------ contains - procedure, public :: delete => atlas_Nabla__delete - procedure, public :: copy => atlas_Nabla__copy procedure, public :: gradient => atlas_Nabla__gradient procedure, public :: divergence => atlas_Nabla__divergence procedure, public :: curl => atlas_Nabla__curl @@ -45,46 +43,32 @@ module atlas_Nabla_module contains !======================================================== -function atlas_Nabla__cptr(cptr) result(nabla) +function atlas_Nabla__cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only: c_ptr - type(atlas_Nabla) :: nabla + type(atlas_Nabla) :: this type(c_ptr), intent(in) :: cptr - call nabla%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) + call this%return() end function -function atlas_Nabla__method_config(method,config) result(nabla) +function atlas_Nabla__method_config(method,config) result(this) use atlas_Nabla_c_binding use atlas_Method_module, only : atlas_Method use atlas_Config_module, only : atlas_Config - type(atlas_Nabla) :: nabla + type(atlas_Nabla) :: this class(atlas_Method), intent(in) :: method type(atlas_Config), intent(in), optional :: config type(atlas_Config) :: opt_config if( present(config) ) then - nabla = atlas_Nabla__cptr(atlas__Nabla__create(method%c_ptr(),config%c_ptr())) + call this%reset_c_ptr( atlas__Nabla__create(method%c_ptr(),config%c_ptr()) ) else opt_config = atlas_Config() - nabla = atlas_Nabla__cptr(atlas__Nabla__create(method%c_ptr(),opt_config%c_ptr())) + call this%reset_c_ptr( atlas__Nabla__create(method%c_ptr(),opt_config%c_ptr()) ) call opt_config%final() endif - call nabla%return() + call this%return() end function -subroutine atlas_Nabla__delete(this) - use atlas_Nabla_c_binding - class(atlas_Nabla), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__Nabla__delete(this%c_ptr()) - endif - call this%reset_c_ptr() -end subroutine atlas_Nabla__delete - -subroutine atlas_Nabla__copy(this,obj_in) - class(atlas_Nabla), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - - subroutine atlas_Nabla__gradient(this,scalar,grad) use atlas_Nabla_c_binding use atlas_Field_module, only : atlas_Field diff --git a/src/atlas_f/numerics/atlas_fvm_module.F90 b/src/atlas_f/numerics/atlas_fvm_module.F90 index 14ded05ca..293fa674e 100644 --- a/src/atlas_f/numerics/atlas_fvm_module.F90 +++ b/src/atlas_f/numerics/atlas_fvm_module.F90 @@ -1,11 +1,11 @@ module atlas_fvm_module -use fckit_refcounted_module, only : fckit_refcounted +use fckit_owned_object_module, only : fckit_owned_object use atlas_Method_module, only : atlas_Method implicit none -private :: fckit_refcounted +private :: fckit_owned_object private :: atlas_Method public :: atlas_fvm_Method @@ -46,31 +46,29 @@ module atlas_fvm_module contains !======================================================== -function atlas_fvm_Method__cptr(cptr) result(method) +function atlas_fvm_Method__cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only : c_ptr - type(atlas_fvm_Method) :: method + type(atlas_fvm_Method) :: this type(c_ptr), intent(in) :: cptr - call method%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) end function -function atlas_fvm_Method__mesh_config(mesh,config) result(method) +function atlas_fvm_Method__mesh_config(mesh,config) result(this) use atlas_fvm_method_c_binding use atlas_Config_module, only : atlas_Config use atlas_Mesh_module, only : atlas_Mesh - type(atlas_fvm_Method) :: method + type(atlas_fvm_Method) :: this type(atlas_Mesh), intent(inout) :: mesh type(atlas_Config), intent(in), optional :: config type(atlas_Config) :: opt_config if( present(config) ) then - method = atlas_fvm_Method__cptr( & - & atlas__numerics__fvm__Method__new(mesh%c_ptr(),config%c_ptr()) ) + call this%reset_c_ptr( atlas__numerics__fvm__Method__new(mesh%c_ptr(),config%c_ptr()) ) else opt_config = atlas_Config() - method = atlas_fvm_Method__cptr( & - & atlas__numerics__fvm__Method__new(mesh%c_ptr(),opt_config%c_ptr()) ) + call this%reset_c_ptr( atlas__numerics__fvm__Method__new(mesh%c_ptr(),opt_config%c_ptr()) ) call opt_config%final() endif - call method%return() + call this%return() end function function node_columns(this) From cd1b0407730080aa48bc786147b61b56c7d38730 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 12:20:53 +0000 Subject: [PATCH 227/355] FCKIT-4 Port atlas_output --- src/atlas_f/output/atlas_output_module.F90 | 38 +++++++--------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/src/atlas_f/output/atlas_output_module.F90 b/src/atlas_f/output/atlas_output_module.F90 index d9132368e..3077a0e73 100644 --- a/src/atlas_f/output/atlas_output_module.F90 +++ b/src/atlas_f/output/atlas_output_module.F90 @@ -4,11 +4,11 @@ module atlas_output_module -use fckit_refcounted_module, only : fckit_refcounted +use fckit_owned_object_module, only : fckit_owned_object implicit none -private :: fckit_refcounted +private :: fckit_owned_object public :: atlas_Output public :: atlas_output_Gmsh @@ -16,7 +16,7 @@ module atlas_output_module private !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_Output +TYPE, extends(fckit_owned_object) :: atlas_Output ! Purpose : ! ------- @@ -30,8 +30,6 @@ module atlas_output_module !------------------------------------------------------------------------------ contains - procedure, public :: delete => atlas_Output__delete - procedure, public :: copy => atlas_Output__copy procedure, private :: write_mesh procedure, private :: write_field_fs procedure, private :: write_field @@ -58,33 +56,19 @@ module atlas_output_module CONTAINS ! ============================================================================= -function atlas_Output__cptr(cptr) result(Output) +function atlas_Output__cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only : c_ptr - type(atlas_Output) :: Output + type(atlas_Output) :: this type(c_ptr), intent(in) :: cptr - call Output%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) + call this%return() end function -subroutine atlas_Output__delete(this) - use atlas_Output_c_binding - class(atlas_Output), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__Output__delete(this%c_ptr()) - endif - call this%reset_c_ptr() -end subroutine atlas_Output__delete - - -subroutine atlas_Output__copy(this,obj_in) - class(atlas_Output), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - -function atlas_output_Gmsh__pathname_mode(file,mode,coordinates,levels,gather) result(output) +function atlas_output_Gmsh__pathname_mode(file,mode,coordinates,levels,gather) result(this) use fckit_c_interop_module, only : c_str use atlas_output_gmsh_c_binding use atlas_Config_module, only : atlas_Config - type(atlas_Output) :: output + type(atlas_Output) :: this character(len=*), intent(in) :: file character(len=1), intent(in), optional :: mode character(len=*), intent(in), optional :: coordinates @@ -98,8 +82,8 @@ function atlas_output_Gmsh__pathname_mode(file,mode,coordinates,levels,gather) r if( present(coordinates) ) call opt_config%set("coordinates",coordinates) if( present(levels) ) call opt_config%set("levels",levels) if( present(gather) ) call opt_config%set("gather",gather) - output = atlas_Output__cptr(atlas__output__Gmsh__create_pathname_mode_config(c_str(file),c_str(opt_mode),opt_config%c_ptr())) - call output%return() + call this%reset_c_ptr( atlas__output__Gmsh__create_pathname_mode_config(c_str(file),c_str(opt_mode),opt_config%c_ptr()) ) + call this%return() call opt_config%final() end function From 8cd87ccf58712388da3ad6ac8b798766bcbe209f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 16:34:33 +0000 Subject: [PATCH 228/355] FCKIT-4 Port functionspaces --- src/atlas/functionspace/FunctionSpace.cc | 9 ++- src/atlas/functionspace/FunctionSpace.h | 2 +- .../autogenerated/atlas_Field_module_fypp.F90 | 64 ++++++++--------- src/atlas_f/field/atlas_Field_module.F90 | 18 ++--- .../atlas_FunctionSpace_module.F90 | 12 ++-- ...atlas_functionspace_EdgeColumns_module.F90 | 44 +++++++----- ...atlas_functionspace_NodeColumns_module.F90 | 6 +- .../atlas_functionspace_Spectral_module.F90 | 13 ++-- ...functionspace_StructuredColumns_module.F90 | 55 +++++--------- src/atlas_f/trans/atlas_Trans_module.F90 | 71 +++++-------------- src/atlas_f/util/atlas_Config_module.F90 | 71 +++++++++++-------- src/tests/array/CMakeLists.txt | 1 - .../functionspace/fctest_functionspace.F90 | 31 +++++--- src/tests/mesh/CMakeLists.txt | 13 ++-- src/tests/util/fctest_parametrisation.F90 | 2 +- 15 files changed, 190 insertions(+), 222 deletions(-) diff --git a/src/atlas/functionspace/FunctionSpace.cc b/src/atlas/functionspace/FunctionSpace.cc index a8e8b337a..ddaf079c5 100644 --- a/src/atlas/functionspace/FunctionSpace.cc +++ b/src/atlas/functionspace/FunctionSpace.cc @@ -38,14 +38,17 @@ extern "C" { ); } -const char* atlas__FunctionSpace__name (FunctionSpaceImpl* This) { +void atlas__FunctionSpace__name( const FunctionSpaceImpl* This, char* &name, int &size ) { ATLAS_ERROR_HANDLING( ASSERT( This ); - return This->type().c_str(); + std::string s = This->type(); + size = s.size()+1; + name = new char[size]; + strcpy(name,s.c_str()); ); - return 0; } + field::FieldImpl* atlas__FunctionSpace__create_field ( const FunctionSpaceImpl* This, const eckit::Configuration* options ) diff --git a/src/atlas/functionspace/FunctionSpace.h b/src/atlas/functionspace/FunctionSpace.h index 856874511..8f893c8dd 100644 --- a/src/atlas/functionspace/FunctionSpace.h +++ b/src/atlas/functionspace/FunctionSpace.h @@ -126,7 +126,7 @@ class NoFunctionSpace : public FunctionSpaceImpl extern "C" { void atlas__FunctionSpace__delete (FunctionSpaceImpl* This); - const char* atlas__FunctionSpace__name (FunctionSpaceImpl* This); + void atlas__FunctionSpace__name( const FunctionSpaceImpl* This, char* &name, int &size ); field::FieldImpl* atlas__FunctionSpace__create_field (const FunctionSpaceImpl* This, const eckit::Configuration* options); field::FieldImpl* atlas__FunctionSpace__create_field_template (const FunctionSpaceImpl* This, const field::FieldImpl* field_template, const eckit::Configuration* options); } diff --git a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 index bb234d3db..116f965e3 100644 --- a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 +++ b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 @@ -2,18 +2,11 @@ module atlas_field_module -use fckit_refcounted_module, only : fckit_refcounted -use fckit_object_module, only : fckit_object use fckit_owned_object_module, only : fckit_owned_object -use fckit_shared_object_module, only : fckit_shared_object use atlas_Error_module, only: atlas_code_location, atlas_abort, atlas_throw_outofrange +use atlas_Config_module, only: atlas_Config implicit none -private :: fckit_refcounted -private :: fckit_owned_object -private :: fckit_shared_object -private :: atlas_code_location, atlas_abort, atlas_throw_outofrange - public :: atlas_Field public :: atlas_real public :: atlas_integer @@ -357,6 +350,10 @@ module atlas_field_module !------------------------------------------------------------------------------- +private :: fckit_owned_object +private :: atlas_code_location, atlas_abort, atlas_throw_outofrange +private :: atlas_Config + !======================================================== contains !======================================================== @@ -376,7 +373,7 @@ subroutine array_c_to_f_int32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -412,7 +409,7 @@ subroutine array_c_to_f_int64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -448,7 +445,7 @@ subroutine array_c_to_f_real32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -484,7 +481,7 @@ subroutine array_c_to_f_real64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -520,7 +517,7 @@ subroutine array_c_to_f_logical32_r1(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -556,7 +553,7 @@ subroutine array_c_to_f_int32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -592,7 +589,7 @@ subroutine array_c_to_f_int64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -628,7 +625,7 @@ subroutine array_c_to_f_real32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -664,7 +661,7 @@ subroutine array_c_to_f_real64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -700,7 +697,7 @@ subroutine array_c_to_f_logical32_r2(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -736,7 +733,7 @@ subroutine array_c_to_f_int32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -772,7 +769,7 @@ subroutine array_c_to_f_int64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -808,7 +805,7 @@ subroutine array_c_to_f_real32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -844,7 +841,7 @@ subroutine array_c_to_f_real64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -880,7 +877,7 @@ subroutine array_c_to_f_logical32_r3(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -916,7 +913,7 @@ subroutine array_c_to_f_int32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -952,7 +949,7 @@ subroutine array_c_to_f_int64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -988,7 +985,7 @@ subroutine array_c_to_f_real32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -1024,7 +1021,7 @@ subroutine array_c_to_f_real64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -1060,7 +1057,7 @@ subroutine array_c_to_f_logical32_r4(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",175)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -2236,7 +2233,7 @@ integer function atlas_real(kind) else if (kind == c_float) then atlas_real = ATLAS_KIND_REAL32 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",278)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",275)) end if end function @@ -2252,7 +2249,7 @@ integer function atlas_integer(kind) else if (kind == c_long) then atlas_integer = ATLAS_KIND_INT64 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",294)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",291)) end if end if end function @@ -2278,7 +2275,7 @@ function atlas_data_type(kind) else if( kind == ATLAS_KIND_REAL64 ) then atlas_data_type = "real64" else - call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",320)) + call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",317)) endif end function @@ -2296,7 +2293,6 @@ function atlas_Field__cptr(cptr) result(field) function atlas_Field__create(params) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Config), intent(in) :: params field = atlas_Field__cptr( atlas__Field__create(params%c_ptr()) ) @@ -2307,7 +2303,6 @@ function atlas_Field__create(params) result(field) function atlas_Field__create_name_kind_shape_int32(name,kind,shape) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config use, intrinsic :: iso_c_binding, only : c_int type(atlas_Field) :: field character(len=*), intent(in) :: name @@ -2332,7 +2327,6 @@ function atlas_Field__create_name_kind_shape_int32(name,kind,shape) result(field function atlas_Field__create_name_kind_shape_int64(name,kind,shape) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config use, intrinsic :: iso_c_binding, only : c_long type(atlas_Field) :: field character(len=*), intent(in) :: name @@ -2357,7 +2351,6 @@ function atlas_Field__create_name_kind_shape_int64(name,kind,shape) result(field function atlas_Field__create_kind_shape_int32(kind,shape) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config use, intrinsic :: iso_c_binding, only : c_int type(atlas_Field) :: field integer(c_int), intent(in) :: kind @@ -2378,7 +2371,6 @@ function atlas_Field__create_kind_shape_int32(kind,shape) result(field) function atlas_Field__create_kind_shape_int64(kind,shape) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config use, intrinsic :: iso_c_binding, only : c_int, c_long type(atlas_Field) :: field integer(c_int), intent(in) :: kind diff --git a/src/atlas_f/field/atlas_Field_module.F90 b/src/atlas_f/field/atlas_Field_module.F90 index 747625a59..13d98c854 100644 --- a/src/atlas_f/field/atlas_Field_module.F90 +++ b/src/atlas_f/field/atlas_Field_module.F90 @@ -11,18 +11,11 @@ module atlas_field_module -use fckit_refcounted_module, only : fckit_refcounted -use fckit_object_module, only : fckit_object use fckit_owned_object_module, only : fckit_owned_object -use fckit_shared_object_module, only : fckit_shared_object use atlas_Error_module, only: atlas_code_location, atlas_abort, atlas_throw_outofrange +use atlas_Config_module, only: atlas_Config implicit none -private :: fckit_refcounted -private :: fckit_owned_object -private :: fckit_shared_object -private :: atlas_code_location, atlas_abort, atlas_throw_outofrange - public :: atlas_Field public :: atlas_real public :: atlas_integer @@ -151,6 +144,10 @@ module atlas_field_module !------------------------------------------------------------------------------- +private :: fckit_owned_object +private :: atlas_code_location, atlas_abort, atlas_throw_outofrange +private :: atlas_Config + !======================================================== contains !======================================================== @@ -335,7 +332,6 @@ function atlas_Field__cptr(cptr) result(field) function atlas_Field__create(params) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Config), intent(in) :: params field = atlas_Field__cptr( atlas__Field__create(params%c_ptr()) ) @@ -346,7 +342,6 @@ function atlas_Field__create(params) result(field) function atlas_Field__create_name_kind_shape_int32(name,kind,shape) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config use, intrinsic :: iso_c_binding, only : c_int type(atlas_Field) :: field character(len=*), intent(in) :: name @@ -371,7 +366,6 @@ function atlas_Field__create_name_kind_shape_int32(name,kind,shape) result(field function atlas_Field__create_name_kind_shape_int64(name,kind,shape) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config use, intrinsic :: iso_c_binding, only : c_long type(atlas_Field) :: field character(len=*), intent(in) :: name @@ -396,7 +390,6 @@ function atlas_Field__create_name_kind_shape_int64(name,kind,shape) result(field function atlas_Field__create_kind_shape_int32(kind,shape) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config use, intrinsic :: iso_c_binding, only : c_int type(atlas_Field) :: field integer(c_int), intent(in) :: kind @@ -417,7 +410,6 @@ function atlas_Field__create_kind_shape_int32(kind,shape) result(field) function atlas_Field__create_kind_shape_int64(kind,shape) result(field) use atlas_field_c_binding - use atlas_Config_module, only : atlas_Config use, intrinsic :: iso_c_binding, only : c_int, c_long type(atlas_Field) :: field integer(c_int), intent(in) :: kind diff --git a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 index d402af058..951c167c5 100644 --- a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 +++ b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 @@ -68,13 +68,15 @@ function atlas_FunctionSpace__cptr(cptr) result(this) function atlas_FunctionSpace__name(this) result(name) use atlas_functionspace_c_binding - use fckit_c_interop_module, only : c_ptr_to_string + use fckit_c_interop_module, only : c_ptr_to_string, c_ptr_free use, intrinsic :: iso_c_binding, only : c_ptr class(atlas_FunctionSpace), intent(in) :: this character(len=:), allocatable :: name type(c_ptr) :: name_c_str - name_c_str = atlas__FunctionSpace__name(this%c_ptr()) + integer :: size + call atlas__FunctionSpace__name(this%c_ptr(), name_c_str, size ) name = c_ptr_to_string(name_c_str) + call c_ptr_free(name_c_str) end function @@ -83,7 +85,6 @@ function atlas_FunctionSpace__name(this) result(name) function create_field_args(this,kind,name,levels,variables,global,owner) result(field) use atlas_functionspace_c_binding use, intrinsic :: iso_c_binding, only : c_int - use atlas_config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Functionspace), intent(in) :: this integer, intent(in) :: kind @@ -104,6 +105,7 @@ function create_field_args(this,kind,name,levels,variables,global,owner) result( if( present(variables) ) call options%set("variables",variables) field = atlas_Field( atlas__FunctionSpace__create_field( this%c_ptr(), options%c_ptr() ) ) + call field%return() call options%final() end function @@ -113,7 +115,6 @@ function create_field_args(this,kind,name,levels,variables,global,owner) result( function create_field_template(this,template,name,global,owner) result(field) use atlas_functionspace_c_binding use, intrinsic :: iso_c_binding, only : c_int - use atlas_config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Functionspace), intent(in) :: this type(atlas_Field), intent(in) :: template @@ -146,7 +147,6 @@ function create_field_template(this,template,name,global,owner) result(field) function deprecated_create_field_1(this,name,kind,levels,vars) result(field) use atlas_functionspace_c_binding use, intrinsic :: iso_c_binding, only : c_int - use atlas_config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Functionspace), intent(in) :: this character(len=*), intent(in) :: name @@ -175,7 +175,6 @@ function deprecated_create_field_1(this,name,kind,levels,vars) result(field) function deprecated_create_field_2(this,require_name,kind,levels) result(field) use atlas_functionspace_c_binding use, intrinsic :: iso_c_binding, only : c_int - use atlas_config_module, only : atlas_Config type(atlas_Field) :: field class(atlas_Functionspace), intent(in) :: this character(len=*), intent(in) :: require_name @@ -192,7 +191,6 @@ function deprecated_create_field_2(this,require_name,kind,levels) result(field) call options%set("levels",levels) field = atlas_Field( atlas__FunctionSpace__create_field( this%c_ptr(), options%c_ptr() ) ) - call options%final() call field%return() diff --git a/src/atlas_f/functionspace/atlas_functionspace_EdgeColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_EdgeColumns_module.F90 index e8089af3f..dc8378191 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_EdgeColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_EdgeColumns_module.F90 @@ -91,28 +91,28 @@ module atlas_functionspace_EdgeColumns_module contains !======================================================== -function constructor__cptr(cptr) result(functionspace) - type(atlas_functionspace_EdgeColumns) :: functionspace +function constructor__cptr(cptr) result(this) + type(atlas_functionspace_EdgeColumns) :: this type(c_ptr), intent(in) :: cptr - call functionspace%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) + call this%return() end function !------------------------------------------------------------------------------ function constructor(mesh,halo,levels) result(this) - use atlas_functionspace_EdgeColumns_c_binding - type(atlas_functionspace_EdgeColumns) :: this - type(atlas_Mesh), intent(inout) :: mesh - integer, intent(in), optional :: halo - integer, intent(in), optional :: levels - type(atlas_Config) :: config - config = atlas_Config() - if( present(halo) ) call config%set("halo",halo) - if( present(levels) ) call config%set("levels",levels) - this = constructor__cptr( & - & atlas__fs__EdgeColumns__new(mesh%c_ptr(),config%c_ptr()) ) - call config%final() - call this%return() + use atlas_functionspace_EdgeColumns_c_binding + type(atlas_functionspace_EdgeColumns) :: this + type(atlas_Mesh), intent(inout) :: mesh + integer, intent(in), optional :: halo + integer, intent(in), optional :: levels + type(atlas_Config) :: config + config = atlas_Config() + if( present(halo) ) call config%set("halo",halo) + if( present(levels) ) call config%set("levels",levels) + call this%reset_c_ptr( atlas__fs__EdgeColumns__new(mesh%c_ptr(),config%c_ptr()) ) + call config%final() + call this%return() end function !------------------------------------------------------------------------------ @@ -140,6 +140,7 @@ function mesh(this) type(atlas_Mesh) :: mesh class(atlas_functionspace_EdgeColumns), intent(in) :: this call mesh%reset_c_ptr( atlas__fs__EdgeColumns__mesh(this%c_ptr()) ) + call mesh%return() end function !------------------------------------------------------------------------------ @@ -149,6 +150,7 @@ function edges(this) type(atlas_mesh_Edges) :: edges class(atlas_functionspace_EdgeColumns), intent(in) :: this call edges%reset_c_ptr( atlas__fs__EdgeColumns__edges(this%c_ptr()) ) + call edges%return() end function !------------------------------------------------------------------------------ @@ -176,15 +178,17 @@ function get_gather(this) result(gather) type(atlas_GatherScatter) :: gather class(atlas_functionspace_EdgeColumns), intent(in) :: this call gather%reset_c_ptr( atlas__fs__EdgeColumns__get_gather(this%c_ptr()) ) +! call gather%return() end function !------------------------------------------------------------------------------ -function get_scatter(this) result(gather) +function get_scatter(this) result(scatter) use atlas_functionspace_EdgeColumns_c_binding - type(atlas_GatherScatter) :: gather + type(atlas_GatherScatter) :: scatter class(atlas_functionspace_EdgeColumns), intent(in) :: this - call gather%reset_c_ptr( atlas__fs__EdgeColumns__get_scatter(this%c_ptr()) ) + call scatter%reset_c_ptr( atlas__fs__EdgeColumns__get_scatter(this%c_ptr()) ) +! call scatter%return() end function !------------------------------------------------------------------------------ @@ -234,6 +238,7 @@ function get_halo_exchange(this) result(halo_exchange) type(atlas_HaloExchange) :: halo_exchange class(atlas_functionspace_EdgeColumns), intent(in) :: this call halo_exchange%reset_c_ptr( atlas__fs__EdgeColumns__get_halo_exchange(this%c_ptr()) ) +! call halo_exchange%return() end function !------------------------------------------------------------------------------ @@ -243,6 +248,7 @@ function get_checksum(this) result(checksum) type(atlas_Checksum) :: checksum class(atlas_functionspace_EdgeColumns), intent(in) :: this call checksum%reset_c_ptr( atlas__fs__EdgeColumns__get_checksum(this%c_ptr()) ) +! call checksum%return() end function !------------------------------------------------------------------------------ diff --git a/src/atlas_f/functionspace/atlas_functionspace_NodeColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_NodeColumns_module.F90 index a0b6a9c4e..8599f2806 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_NodeColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_NodeColumns_module.F90 @@ -226,6 +226,7 @@ function constructor__cptr(cptr) result(this) type(atlas_functionspace_NodeColumns) :: this type(c_ptr), intent(in) :: cptr call this%reset_c_ptr( cptr ) + call this%return() end function !------------------------------------------------------------------------------ @@ -240,8 +241,7 @@ function constructor(mesh,halo,levels) result(this) config = atlas_Config() if( present(halo) ) call config%set("halo",halo) if( present(levels) ) call config%set("levels",levels) - this = constructor__cptr( & - & atlas__NodesFunctionSpace__new(mesh%c_ptr(),config%c_ptr()) ) + call this%reset_c_ptr( atlas__NodesFunctionSpace__new(mesh%c_ptr(),config%c_ptr()) ) call config%final() call this%return() end function @@ -271,6 +271,7 @@ function mesh(this) type(atlas_Mesh) :: mesh class(atlas_functionspace_NodeColumns), intent(in) :: this call mesh%reset_c_ptr( atlas__NodesFunctionSpace__mesh(this%c_ptr()) ) + call mesh%return() end function !------------------------------------------------------------------------------ @@ -280,6 +281,7 @@ function nodes(this) type(atlas_mesh_Nodes) :: nodes class(atlas_functionspace_NodeColumns), intent(in) :: this call nodes%reset_c_ptr( atlas__NodesFunctionSpace__nodes(this%c_ptr()) ) + call nodes%return() end function !------------------------------------------------------------------------------ diff --git a/src/atlas_f/functionspace/atlas_functionspace_Spectral_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_Spectral_module.F90 index 1a6cbc313..0220f3e52 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_Spectral_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_Spectral_module.F90 @@ -70,10 +70,11 @@ module atlas_functionspace_Spectral_module contains !======================================================== -function atlas_functionspace_Spectral__cptr(cptr) result(functionspace) - type(atlas_functionspace_Spectral) :: functionspace +function atlas_functionspace_Spectral__cptr(cptr) result(this) + type(atlas_functionspace_Spectral) :: this type(c_ptr), intent(in) :: cptr - call functionspace%reset_c_ptr( cptr ) + call this%reset_c_ptr( cptr ) + call this%return() end function @@ -96,8 +97,7 @@ function atlas_functionspace_Spectral__config(truncation,levels) result(this) call options%set("truncation",truncation) if( present(levels) ) call options%set("levels",levels) - this = atlas_functionspace_Spectral__cptr( & - & atlas__SpectralFunctionSpace__new__config(options%c_ptr()) ) + call this%reset_c_ptr( atlas__SpectralFunctionSpace__new__config(options%c_ptr()) ) call options%final() call this%return() @@ -114,8 +114,7 @@ function atlas_functionspace_Spectral__trans(trans,levels) result(this) if( present(levels) ) call options%set("levels",levels) - this = atlas_functionspace_Spectral__cptr( & - & atlas__SpectralFunctionSpace__new__trans(trans%c_ptr(), options%c_ptr() ) ) + call this%reset_c_ptr( atlas__SpectralFunctionSpace__new__trans(trans%c_ptr(), options%c_ptr() ) ) call options%final() call this%return() diff --git a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 index 0e28ccef1..1df614cc8 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 @@ -42,6 +42,8 @@ module atlas_functionspace_StructuredColumns_module contains + procedure, public :: shared_ptr_cast + procedure, public :: gather procedure, public :: scatter @@ -53,8 +55,6 @@ module atlas_functionspace_StructuredColumns_module procedure, private :: halo_exchange_field generic, public :: halo_exchange => halo_exchange_fieldset, halo_exchange_field - procedure :: copy - procedure :: j_begin procedure :: j_end procedure :: i_begin @@ -68,10 +68,6 @@ module atlas_functionspace_StructuredColumns_module procedure :: partition procedure :: global_index -#ifdef FORTRAN_SUPPORTS_FINAL - final :: atlas_functionspace_StructuredColumns__final -#endif - procedure, private :: set_index END TYPE atlas_functionspace_StructuredColumns @@ -88,24 +84,26 @@ module atlas_functionspace_StructuredColumns_module contains !======================================================== +function shared_ptr_cast(this) result(success) + class(atlas_functionspace_StructuredColumns) :: this + logical :: success + success = this%fckit_shared_object__shared_ptr_cast() + if( success ) then + call this%set_index() + endif +end function + function StructuredColumns__cptr(cptr) result(this) type(atlas_functionspace_StructuredColumns) :: this type(c_ptr), intent(in) :: cptr call this%reset_c_ptr( cptr ) call this%set_index() + call this%return() end function - -#ifdef FORTRAN_SUPPORTS_FINAL -subroutine StructuredColumns__final(this) - type(atlas_functionspace_StructuredColumns), intent(inout) :: this - call this%final() -end subroutine -#endif - -function StructuredColumns__grid(grid, halo, levels) result(functionspace) +function StructuredColumns__grid(grid, halo, levels) result(this) use atlas_functionspace_StructuredColumns_c_binding - type(atlas_functionspace_StructuredColumns) :: functionspace + type(atlas_functionspace_StructuredColumns) :: this class(atlas_Grid), intent(in) :: grid integer, optional :: halo integer, optional :: levels @@ -113,10 +111,10 @@ function StructuredColumns__grid(grid, halo, levels) result(functionspace) config = atlas_Config() if( present(halo) ) call config%set("halo",halo) if( present(levels) ) call config%set("levels",levels) - functionspace = StructuredColumns__cptr( & - & atlas__functionspace__StructuredColumns__new__grid( grid%c_ptr(), config%c_ptr() ) ) + call this%reset_c_ptr( atlas__functionspace__StructuredColumns__new__grid( grid%c_ptr(), config%c_ptr() ) ) + call this%set_index() call config%final() - call functionspace%return() + call this%return() end function subroutine gather(this,local,global) @@ -180,25 +178,6 @@ subroutine set_index(this) this%index(i_min:i_max,j_min:j_max) => index_fptr(:) end subroutine -#warning todo -subroutine copy(this,obj_in) - use fckit_shared_ptr_module, only : fckit_shared_ptr - use fckit_exception_module, only : fckit_exception - class(atlas_functionspace_StructuredColumns), intent(inout) :: this - class(fckit_shared_ptr), target, intent(in) :: obj_in - nullify(this%index) - select type( obj_in_concrete => obj_in ) - class is (atlas_functionspace_StructuredColumns) - this%index => obj_in_concrete%index - class default - end select - if( .not. associated(this%index) ) then - call fckit_exception%abort("Could not assign StructuredColumns", & - & "atlas_functionspace_StructuredColumns_module.F90",__LINE__) - endif - -end subroutine - function j_begin(this) result(j) use, intrinsic :: iso_c_binding, only : c_int use atlas_functionspace_StructuredColumns_c_binding diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index 1f1e2a559..33b26f8b8 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -5,13 +5,14 @@ module atlas_Trans_module use fckit_object_module, only: fckit_object -use fckit_refcounted_module, only: fckit_refcounted +use fckit_owned_object_module, only: fckit_owned_object +use atlas_config_module, only : atlas_Config +use atlas_field_module, only : atlas_Field +use atlas_fieldset_module, only : atlas_FieldSet +use atlas_grid_module, only : atlas_Grid implicit none -private :: fckit_refcounted -private :: fckit_object - public :: atlas_Trans private @@ -21,7 +22,7 @@ module atlas_Trans_module !----------------------------- !------------------------------------------------------------------------------ -TYPE, extends(fckit_refcounted) :: atlas_Trans +TYPE, extends(fckit_owned_object) :: atlas_Trans ! Purpose : ! ------- @@ -70,9 +71,6 @@ module atlas_Trans_module procedure, private :: specnorm_r2 generic, public :: specnorm => specnorm_r1_scalar, specnorm_r2 - procedure, public :: delete => atlas_Trans__delete - procedure, public :: copy => atlas_Trans__copy - END TYPE atlas_Trans !------------------------------------------------------------------------------ @@ -83,6 +81,13 @@ module atlas_Trans_module !------------------------------------------------------------------------------ +private :: fckit_owned_object +private :: fckit_object +private :: atlas_Config +private :: atlas_Field +private :: atlas_FieldSet +private :: atlas_Grid + !======================================================== contains !======================================================== @@ -99,45 +104,24 @@ subroutine te(file,line) & "ENABLE_TRANS=ON",atlas_code_location(file,line)) end subroutine -function atlas_Trans__ctor( grid, nsmax ) result(trans) +function atlas_Trans__ctor( grid, nsmax ) result(this) use, intrinsic :: iso_c_binding, only: c_null_ptr use atlas_trans_c_binding - use atlas_Grid_module, only: atlas_Grid - type(atlas_Trans) :: trans + type(atlas_Trans) :: this class(atlas_Grid), intent(in) :: grid integer, intent(in), optional :: nsmax #ifdef ATLAS_HAVE_TRANS if( present(nsmax) ) then - call trans%reset_c_ptr( atlas__Trans__new( grid%c_ptr(), nsmax ) ) + call this%reset_c_ptr( atlas__Trans__new( grid%c_ptr(), nsmax ) ) else - call trans%reset_c_ptr( atlas__Trans__new( grid%c_ptr(), 0 ) ) + call this%reset_c_ptr( atlas__Trans__new( grid%c_ptr(), 0 ) ) endif -#else - ! IGNORE - call trans%reset_c_ptr( c_null_ptr ) -#endif -end function atlas_Trans__ctor - - -subroutine atlas_Trans__delete( this ) - use atlas_trans_c_binding - use, intrinsic :: iso_c_binding, only: c_null_ptr - class(atlas_Trans), intent(inout) :: this -#ifdef ATLAS_HAVE_TRANS - call atlas__Trans__delete(this%c_ptr()); #else ! IGNORE call this%reset_c_ptr( c_null_ptr ) #endif -end subroutine - - -subroutine atlas_Trans__copy(this,obj_in) - class(atlas_Trans), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in -end subroutine - - + call this%return() +end function atlas_Trans__ctor function handle( this ) use atlas_trans_c_binding @@ -213,7 +197,6 @@ function nb_gridpoints_global( this ) function grid( this ) use atlas_trans_c_binding - use atlas_grid_module class(atlas_Trans) :: this type(atlas_Grid) :: grid #ifdef ATLAS_HAVE_TRANS @@ -229,9 +212,6 @@ function grid( this ) subroutine dirtrans_fieldset(this, gpfields, spfields, config) use atlas_trans_c_binding - use atlas_fieldset_module, only: atlas_FieldSet - use atlas_field_module, only: atlas_Field - use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_FieldSet), intent(in) :: gpfields class(atlas_FieldSet), intent(inout) :: spfields @@ -261,9 +241,6 @@ end subroutine dirtrans_fieldset subroutine invtrans_fieldset(this, spfields, gpfields, config) use atlas_trans_c_binding - use atlas_fieldset_module, only: atlas_FieldSet - use atlas_field_module, only: atlas_Field - use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_FieldSet), intent(in) :: spfields class(atlas_FieldSet), intent(inout) :: gpfields @@ -292,8 +269,6 @@ end subroutine invtrans_fieldset subroutine dirtrans_field(this, gpfield, spfield, config) use atlas_trans_c_binding - use atlas_field_module, only: atlas_Field - use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_Field), intent(in) :: gpfield class(atlas_Field), intent(inout) :: spfield @@ -322,8 +297,6 @@ end subroutine dirtrans_field subroutine dirtrans_wind2vordiv_field(this, gpwind, spvor, spdiv, config) use atlas_trans_c_binding - use atlas_field_module, only: atlas_Field - use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this type(atlas_Field), intent(in) :: gpwind type(atlas_Field), intent(inout) :: spvor @@ -356,8 +329,6 @@ end subroutine dirtrans_wind2vordiv_field subroutine invtrans_field(this, spfield, gpfield, config) use atlas_trans_c_binding - use atlas_field_module, only: atlas_Field - use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_Field), intent(in) :: spfield class(atlas_Field), intent(inout) :: gpfield @@ -387,8 +358,6 @@ end subroutine invtrans_field subroutine invtrans_vordiv2wind_field(this, spvor, spdiv, gpwind, config) use atlas_trans_c_binding - use atlas_field_module, only: atlas_Field - use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_Field), intent(in) :: spvor class(atlas_Field), intent(in) :: spdiv @@ -421,8 +390,6 @@ end subroutine invtrans_vordiv2wind_field subroutine invtrans_grad_field(this, spfield, gpfield) use atlas_trans_c_binding - use atlas_field_module, only: atlas_Field - use atlas_config_module, only: atlas_Config class(atlas_Trans), intent(in) :: this class(atlas_Field), intent(in) :: spfield class(atlas_Field), intent(inout) :: gpfield diff --git a/src/atlas_f/util/atlas_Config_module.F90 b/src/atlas_f/util/atlas_Config_module.F90 index b886dc444..6245892d3 100644 --- a/src/atlas_f/util/atlas_Config_module.F90 +++ b/src/atlas_f/util/atlas_Config_module.F90 @@ -1,16 +1,15 @@ module atlas_config_module -use fckit_refcounted_fortran_module, only : fckit_refcounted_fortran +use fckit_shared_object_module, only : fckit_shared_object, fckit_c_deleter, fckit_c_nodeleter implicit none -private :: fckit_refcounted_fortran public :: atlas_Config private -TYPE, extends(fckit_refcounted_fortran) :: atlas_Config +TYPE, extends(fckit_shared_object) :: atlas_Config ! Purpose : ! ------- @@ -57,21 +56,24 @@ module atlas_config_module generic :: get => get_config, get_config_list, get_int32, get_logical, get_real32, get_real64, & get_string, get_array_int32, get_array_int64, get_array_real32, get_array_real64 procedure :: json => atlas_Config__json - - procedure, public :: delete => atlas_Config__delete - + END TYPE atlas_Config !------------------------------------------------------------------------------ interface atlas_Config module procedure atlas_Config__ctor + module procedure atlas_Config__ctor_from_cptr module procedure atlas_Config__ctor_from_file module procedure atlas_Config__ctor_from_json end interface !------------------------------------------------------------------------------ +private :: fckit_shared_object +private :: fckit_c_deleter +private :: fckit_c_nodeleter + !======================================================== contains !======================================================== @@ -79,40 +81,51 @@ module atlas_config_module ! ----------------------------------------------------------------------------- ! Config routines -function atlas_Config__ctor() result(Config) +function atlas_Config__ctor() result(this) use atlas_Config_c_binding - type(atlas_Config) :: Config - call Config%reset_c_ptr( atlas__Config__new() ) + type(atlas_Config) :: this + call this%reset_c_ptr( atlas__Config__new(), & + & fckit_c_deleter(atlas__Config__delete) ) + call this%return() end function atlas_Config__ctor -function atlas_Config__ctor_from_json(json) result(Config) +function atlas_Config__ctor_from_cptr(cptr,delete) result(this) + use, intrinsic :: iso_c_binding, only : c_ptr + use atlas_Config_c_binding + type(c_ptr), value :: cptr + type(atlas_Config) :: this + logical, optional :: delete + logical :: opt_delete + opt_delete = .true. + if( present(delete) ) opt_delete = delete + if( opt_delete ) then + call this%reset_c_ptr( cptr, fckit_c_deleter(atlas__Config__delete) ) + else + call this%reset_c_ptr( cptr, fckit_c_nodeleter() ) + endif + call this%return() +end function + +function atlas_Config__ctor_from_json(json) result(this) use fckit_c_interop_module, only : c_str use atlas_Config_c_binding use atlas_JSON_module - type(atlas_Config) :: Config + type(atlas_Config) :: this class(atlas_JSON) :: json - call Config%reset_c_ptr( atlas__Config__new_from_json(c_str(json%str())) ) + call this%reset_c_ptr( atlas__Config__new_from_json(c_str(json%str())) ) + call this%return() end function atlas_Config__ctor_from_json -function atlas_Config__ctor_from_file(path) result(Config) +function atlas_Config__ctor_from_file(path) result(this) use fckit_c_interop_module, only : c_str use atlas_Config_c_binding use atlas_JSON_module - type(atlas_Config) :: Config + type(atlas_Config) :: this class(atlas_PathName), intent(in) :: path - call Config%reset_c_ptr( atlas__Config__new_from_file(c_str(path%str())) ) + call this%reset_c_ptr( atlas__Config__new_from_file(c_str(path%str())) ) + call this%return() end function atlas_Config__ctor_from_file -subroutine atlas_Config__delete(this) - use atlas_Config_c_binding - class(atlas_Config), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__Config__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine atlas_Config__delete - - function atlas_Config__has(this, name) result(value) use fckit_c_interop_module, only : c_str use atlas_Config_c_binding @@ -216,10 +229,8 @@ function atlas_Config__get_config(this, name, value) result(found) character(len=*), intent(in) :: name class(atlas_Config), intent(inout) :: value integer :: found_int - if( value%is_null() ) then - call value%reset_c_ptr( atlas__Config__new() ) - endif - found_int = atlas__Config__get_config(this%c_ptr(), c_str(name), value%c_ptr() ) + value = atlas_Config() + found_int = atlas__Config__get_config( this%c_ptr(), c_str(name), value%c_ptr() ) found = .False. if (found_int == 1) found = .True. end function atlas_Config__get_config @@ -246,7 +257,7 @@ function atlas_Config__get_config_list(this, name, value) result(found) if( allocated(value) ) deallocate(value) allocate(value(value_list_size)) do j=1,value_list_size - call value(j)%reset_c_ptr( value_cptrs(j) ) + value(j) = atlas_Config( value_cptrs(j) ) enddo if( value_list_allocated == 1 ) call c_ptr_free(value_list_cptr) endif diff --git a/src/tests/array/CMakeLists.txt b/src/tests/array/CMakeLists.txt index 4ca1cde69..547e3af19 100644 --- a/src/tests/array/CMakeLists.txt +++ b/src/tests/array/CMakeLists.txt @@ -50,7 +50,6 @@ atlas_add_cuda_test( atlas_add_cuda_test( TARGET atlas_test_svector_kernel - BOOST SOURCES test_svector_kernel.cu LIBS atlas ) diff --git a/src/tests/functionspace/fctest_functionspace.F90 b/src/tests/functionspace/fctest_functionspace.F90 index e25dcad5c..23b6d55d2 100644 --- a/src/tests/functionspace/fctest_functionspace.F90 +++ b/src/tests/functionspace/fctest_functionspace.F90 @@ -41,6 +41,7 @@ module fcta_FunctionSpace_fxt ! ----------------------------------------------------------------------------- TEST( test_nodes ) +#if 1 type(atlas_StructuredGrid) :: grid type(atlas_MeshGenerator) :: meshgenerator type(atlas_Mesh) :: mesh @@ -129,13 +130,14 @@ module fcta_FunctionSpace_fxt call fs%final() call mesh%final() call grid%final() - +#endif END_TEST ! ----------------------------------------------------------------------------- TEST( test_nodescolumns ) +#if 1 type(atlas_StructuredGrid) :: grid type(atlas_MeshGenerator) :: meshgenerator type(atlas_Mesh) :: mesh @@ -228,15 +230,21 @@ module fcta_FunctionSpace_fxt FCTEST_CHECK_EQUAL( field%kind() , atlas_real(c_float) ) call field%final() +FCTEST_CHECK_EQUAL( fs%owners(), 1 ) call fs%final() + +FCTEST_CHECK_EQUAL( mesh%owners(), 1 ) call mesh%final() -call grid%final() +FCTEST_CHECK_EQUAL( grid%owners(), 1 ) +call grid%final() +#endif END_TEST ! ----------------------------------------------------------------------------- TEST( test_collectives ) +#if 1 use fckit_mpi_module type(atlas_StructuredGrid) :: grid type(atlas_MeshGenerator) :: meshgenerator @@ -350,7 +358,7 @@ module fcta_FunctionSpace_fxt call mesh%final() call grid%final() - +#endif END_TEST @@ -360,6 +368,7 @@ module fcta_FunctionSpace_fxt TEST( test_edges ) +#if 1 type(atlas_StructuredGrid) :: grid type(atlas_MeshGenerator) :: meshgenerator type(atlas_Mesh) :: mesh @@ -382,7 +391,6 @@ module fcta_FunctionSpace_fxt FCTEST_CHECK_EQUAL( edges%owners(), 3 ) nb_edges = fs%nb_edges() write(msg,*) "nb_edges = ",nb_edges; call atlas_log%info(msg) - field = fs%create_field(atlas_real(c_float)) FCTEST_CHECK_EQUAL( field%rank() , 1 ) FCTEST_CHECK_EQUAL( field%name() , "" ) @@ -473,10 +481,11 @@ module fcta_FunctionSpace_fxt call edges%final() call mesh%final() call grid%final() - +#endif END_TEST TEST( test_structuredcolumns ) +#if 1 type(atlas_StructuredGrid) :: grid type(atlas_functionspace_StructuredColumns) :: fs type(atlas_functionspace) :: fs_base @@ -491,9 +500,12 @@ module fcta_FunctionSpace_fxt grid = atlas_StructuredGrid("O8") fs = atlas_functionspace_StructuredColumns(grid,halo=2) +write(0,*) __LINE__ field = fs%create_field(name="field",kind=atlas_real(8)) +FCTEST_CHECK_EQUAL( field%owners(), 1 ) field_xy = fs%xy() +FCTEST_CHECK_EQUAL( field_xy%owners(), 2 ) call field%host_data(x) call field_xy%host_data(xy) @@ -510,8 +522,9 @@ module fcta_FunctionSpace_fxt call fs%halo_exchange(field) - +FCTEST_CHECK_EQUAL( field_xy%owners(), 2 ) fs = atlas_functionspace_StructuredColumns(grid,levels=5) + field = fs%create_field(atlas_real(c_float)) FCTEST_CHECK_EQUAL( field%rank() , 2 ) FCTEST_CHECK_EQUAL( field%name() , "" ) @@ -524,12 +537,14 @@ module fcta_FunctionSpace_fxt write(0,*) "after: name = " , fs%name() write(0,*) "after: owners = " , fs%owners() +FCTEST_CHECK_EQUAL( field%owners(), 1 ) call field%final() - - +FCTEST_CHECK_EQUAL( field_xy%owners(), 1 ) call field_xy%final() call fs%final() +call fs_base%final() call grid%final() +#endif END_TEST diff --git a/src/tests/mesh/CMakeLists.txt b/src/tests/mesh/CMakeLists.txt index d684e5443..73a29437e 100644 --- a/src/tests/mesh/CMakeLists.txt +++ b/src/tests/mesh/CMakeLists.txt @@ -61,11 +61,17 @@ ecbuild_add_test( TARGET atlas_test_cgal_mesh_gen_from_points SOURCES test_cgal_mesh_gen_from_points.cc CONDITION HAVE_TESSELATION - LIBS atlas) + LIBS atlas +) + +ecbuild_add_test( + TARGET atlas_test_accumulate_facets + SOURCES test_accumulate_facets.cc + LIBS atlas +) -foreach( test accumulate_facets connectivity elements ll meshgen3d polygon rgg ) +foreach( test connectivity elements ll meshgen3d polygon rgg ) ecbuild_add_test( TARGET atlas_test_${test} - BOOST SOURCES test_${test}.cc LIBS atlas ) @@ -73,7 +79,6 @@ endforeach() atlas_add_cuda_test( TARGET atlas_test_connectivity_kernel - BOOST SOURCES test_connectivity_kernel.cu LIBS atlas ) diff --git a/src/tests/util/fctest_parametrisation.F90 b/src/tests/util/fctest_parametrisation.F90 index 827346b67..d194b8778 100644 --- a/src/tests/util/fctest_parametrisation.F90 +++ b/src/tests/util/fctest_parametrisation.F90 @@ -125,8 +125,8 @@ end module fctest_atlas_Config_fixture do j=1,size(alist) call alist(j)%final() enddo - call anested%final() + call anested%final() ! --------------------------------------------- From d43443c4705544d1829acd26761b9ddc018402d7 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 19 Dec 2017 17:31:00 +0000 Subject: [PATCH 229/355] FCKIT-4 Port atlas_Connectivity --- src/atlas/mesh/Connectivity.cc | 44 +++---- src/atlas/mesh/Connectivity.h | 5 +- .../mesh/atlas_Connectivity_module.F90 | 113 +++++++----------- src/tests/mesh/fctest_connectivity.F90 | 1 + 4 files changed, 61 insertions(+), 102 deletions(-) diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index 8f973bd3c..ffd45b098 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -42,11 +42,8 @@ IrregularConnectivityImpl::IrregularConnectivityImpl(const std::string& name ) : rows_(0), maxcols_(0), mincols_(std::numeric_limits::max()), - ctxt_update_(0), - ctxt_set_(0), - ctxt_delete_(0), + ctxt_(0), callback_update_(0), - callback_set_(0), callback_delete_(0), gpu_clone_(this) { @@ -79,11 +76,8 @@ IrregularConnectivityImpl::IrregularConnectivityImpl( idx_t values[], size_t row counts_view_(array::make_view(*(data_[_counts_]))), missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), rows_(rows), - ctxt_update_(0), - ctxt_set_(0), - ctxt_delete_(0), + ctxt_(0), callback_update_(0), - callback_set_(0), callback_delete_(0), gpu_clone_(this) { @@ -105,9 +99,7 @@ IrregularConnectivityImpl::IrregularConnectivityImpl(const IrregularConnectivity rows_(other.rows_), maxcols_(other.maxcols_), mincols_(other.mincols_), - ctxt_update_(0), - ctxt_set_(0), - ctxt_delete_(0), + ctxt_(0), gpu_clone_(this) {} @@ -156,14 +148,14 @@ void IrregularConnectivityImpl::clear() void IrregularConnectivityImpl::on_delete() { - if( ctxt_delete_ && callback_delete_ ) callback_delete_(ctxt_delete_); + if( ctxt_ && callback_delete_ ) callback_delete_(ctxt_); } //------------------------------------------------------------------------------------------------------ void IrregularConnectivityImpl::on_update() { - if( ctxt_update_ && callback_update_ ) callback_update_(ctxt_update_); + if( ctxt_ && callback_update_ ) callback_update_(ctxt_); } void IrregularConnectivityImpl::resize( size_t old_size, size_t new_size, bool initialize, const idx_t values[], bool fortran_array) @@ -897,11 +889,8 @@ class ConnectivityPrivateAccess ConnectivityPrivateAccess(Connectivity& connectivity) : connectivity_(connectivity) { } - ctxt_t &ctxt_update() { return connectivity_.ctxt_update_; } - ctxt_t &ctxt_set() { return connectivity_.ctxt_set_; } - ctxt_t &ctxt_delete() { return connectivity_.ctxt_delete_; } + ctxt_t &ctxt() { return connectivity_.ctxt_; } callback_t &callback_update() { return connectivity_.callback_update_; } - callback_t &callback_set() { return connectivity_.callback_set_; } callback_t &callback_delete() { return connectivity_.callback_delete_; } // TODO : For now return host-view raw data to Fortran, but this should be @@ -933,32 +922,29 @@ void atlas__Connectivity__delete(Connectivity* This) ATLAS_ERROR_HANDLING(delete This); } -void atlas__connectivity__register_update(Connectivity* This, Connectivity::callback_t callback, Connectivity::ctxt_t ctxt ) +void atlas__connectivity__register_ctxt(Connectivity* This, Connectivity::ctxt_t ctxt ) { ConnectivityPrivateAccess access(*This); - access.ctxt_update() = ctxt; - access.callback_update() = callback; + access.ctxt() = ctxt; } -int atlas__connectivity__ctxt_update(Connectivity* This, Connectivity::ctxt_t* ctxt) +int atlas__connectivity__ctxt(Connectivity* This, Connectivity::ctxt_t* ctxt) { ConnectivityPrivateAccess access(*This); - *ctxt = access.ctxt_update(); - return bool( access.ctxt_update() ); + *ctxt = access.ctxt(); + return bool( access.ctxt() ); } -void atlas__connectivity__register_delete(Connectivity* This, Connectivity::callback_t callback, Connectivity::ctxt_t ctxt ) +void atlas__connectivity__register_update(Connectivity* This, Connectivity::callback_t callback ) { ConnectivityPrivateAccess access(*This); - access.ctxt_delete() = ctxt; - access.callback_delete() = callback; + access.callback_update() = callback; } -int atlas__connectivity__ctxt_delete(Connectivity* This, Connectivity::ctxt_t* ctxt) +void atlas__connectivity__register_delete(Connectivity* This, Connectivity::callback_t callback ) { ConnectivityPrivateAccess access(*This); - *ctxt = access.ctxt_delete(); - return bool( access.ctxt_delete() ); + access.callback_delete() = callback; } void atlas__Connectivity__displs(Connectivity* This, size_t* &displs, size_t &size) diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 8a6d55bbc..14f86d71d 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -301,11 +301,8 @@ class IrregularConnectivityImpl private: friend class ConnectivityPrivateAccess; - ctxt_t ctxt_update_; - ctxt_t ctxt_set_; - ctxt_t ctxt_delete_; + ctxt_t ctxt_; callback_t callback_update_; - callback_t callback_set_; callback_t callback_delete_; array::gridtools::GPUClonable gpu_clone_; diff --git a/src/atlas_f/mesh/atlas_Connectivity_module.F90 b/src/atlas_f/mesh/atlas_Connectivity_module.F90 index 5acb77bc4..a93099bbd 100644 --- a/src/atlas_f/mesh/atlas_Connectivity_module.F90 +++ b/src/atlas_f/mesh/atlas_Connectivity_module.F90 @@ -2,7 +2,7 @@ module atlas_connectivity_module use, intrinsic :: iso_c_binding, only : c_int, c_size_t, c_ptr, c_null_ptr -use fckit_refcounted_module, only : fckit_refcounted +use fckit_owned_object_module, only : fckit_owned_object use fckit_object_module, only : fckit_object implicit none @@ -10,7 +10,7 @@ module atlas_connectivity_module private :: c_int private :: c_size_t private :: c_null_ptr -private :: fckit_refcounted +private :: fckit_owned_object private :: fckit_object public :: atlas_Connectivity @@ -24,13 +24,16 @@ module atlas_connectivity_module ! atlas_Connectivity ! !----------------------------- -type, extends(fckit_refcounted) :: atlas_Connectivity +type, extends(fckit_owned_object) :: atlas_Connectivity ! Public members type( atlas_ConnectivityAccess ), public, pointer :: access => null() contains + procedure, public :: shared_ptr_cast + procedure, public :: set_access + ! Public methods procedure, public :: name => atlas_Connectivity__name procedure, private :: value_args_int => atlas_Connectivity__value_args_int @@ -43,8 +46,6 @@ module atlas_connectivity_module procedure, public :: padded_data => atlas_Connectivity__padded_data procedure, public :: data => atlas_Connectivity__data procedure, public :: row => atlas_Connectivity__row - procedure, public :: copy => atlas_Connectivity__copy - procedure, public :: delete => atlas_Connectivity__delete procedure, public :: missing_value => atlas_Connectivity__missing_value procedure, private :: add_values_args_int => atlas_Connectivity__add_values_args_int procedure, private :: add_values_args_size_t => atlas_Connectivity__add_values_args_size_t @@ -70,7 +71,6 @@ module atlas_connectivity_module type, extends(fckit_object) :: atlas_BlockConnectivity contains - procedure, public :: delete => atlas_BlockConnectivity__delete procedure, public :: rows => atlas_BlockConnectivity__rows procedure, public :: cols => atlas_BlockConnectivity__cols procedure, public :: data => atlas_BlockConnectivity__data @@ -118,30 +118,27 @@ module atlas_connectivity_module ! ---------------------------------------------------------------------------- interface - subroutine atlas__connectivity__register_update(This,funptr,ptr) bind(c,name="atlas__connectivity__register_update") - use, intrinsic :: iso_c_binding, only: c_ptr, c_funptr + subroutine atlas__connectivity__register_ctxt(This,ptr) bind(c,name="atlas__connectivity__register_ctxt") + use, intrinsic :: iso_c_binding, only: c_ptr type(c_ptr), value :: This - type(c_funptr), value :: funptr type(c_ptr), value :: ptr end subroutine - subroutine atlas__connectivity__register_delete(This,funptr,ptr) bind(c,name="atlas__connectivity__register_delete") + subroutine atlas__connectivity__register_update(This,funptr) bind(c,name="atlas__connectivity__register_update") use, intrinsic :: iso_c_binding, only: c_ptr, c_funptr type(c_ptr), value :: This type(c_funptr), value :: funptr - type(c_ptr), value :: ptr end subroutine - function atlas__connectivity__ctxt_update(This,ptr) bind(c,name="atlas__connectivity__ctxt_update") - use, intrinsic :: iso_c_binding, only: c_ptr, c_int - integer(c_int) :: atlas__connectivity__ctxt_update + subroutine atlas__connectivity__register_delete(This,funptr) bind(c,name="atlas__connectivity__register_delete") + use, intrinsic :: iso_c_binding, only: c_ptr, c_funptr type(c_ptr), value :: This - type(c_ptr) :: ptr - end function + type(c_funptr), value :: funptr + end subroutine - function atlas__connectivity__ctxt_delete(This,ptr) bind(c,name="atlas__connectivity__ctxt_delete") + function atlas__connectivity__ctxt(This,ptr) bind(c,name="atlas__connectivity__ctxt") use, intrinsic :: iso_c_binding, only: c_ptr, c_int - integer(c_int) :: atlas__connectivity__ctxt_delete + integer(c_int) :: atlas__connectivity__ctxt type(c_ptr), value :: This type(c_ptr) :: ptr end function @@ -149,6 +146,15 @@ function atlas__connectivity__ctxt_delete(This,ptr) bind(c,name="atlas__connecti end interface contains + +function shared_ptr_cast(this) result(success) + class(atlas_Connectivity) :: this + logical :: success + success = this%fckit_shared_object__shared_ptr_cast() + if( success ) then + call this%set_access() + endif +end function function Connectivity_cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only : c_ptr @@ -156,7 +162,8 @@ function Connectivity_cptr(cptr) result(this) type(atlas_Connectivity) :: this type(c_ptr) :: cptr call this%reset_c_ptr( cptr ) - call setup_access(this) + call this%set_access() + call this%return() end function function Connectivity_constructor(name) result(this) @@ -164,35 +171,14 @@ function Connectivity_constructor(name) result(this) use fckit_c_interop_module, only : c_str type(atlas_Connectivity) :: this character(len=*), intent(in), optional :: name - this = Connectivity_cptr( atlas__Connectivity__create() ) + call this%reset_c_ptr( atlas__Connectivity__create() ) + call this%set_access() if( present(name) ) then call atlas__Connectivity__rename(this%c_ptr(),c_str(name)) endif call this%return() end function -subroutine atlas_Connectivity__delete(this) - use atlas_connectivity_c_binding - class(atlas_Connectivity), intent(inout) :: this - if ( .not. this%is_null() ) then - call atlas__Connectivity__delete(this%c_ptr()) - end if - call this%reset_c_ptr() -end subroutine - -subroutine atlas_Connectivity__copy(this,obj_in) - class(atlas_Connectivity), intent(inout) :: this - class(fckit_refcounted), target, intent(in) :: obj_in - class(atlas_Connectivity), pointer :: obj_in_cast - select type (ptr => obj_in) - type is (atlas_Connectivity) - obj_in_cast => ptr - if( associated( obj_in_cast%access ) ) this%access => obj_in_cast%access - type is (atlas_MultiBlockConnectivity) - obj_in_cast => ptr - if( associated( obj_in_cast%access ) ) this%access => obj_in_cast%access - end select -end subroutine function atlas_Connectivity__name(this) result(name) use, intrinsic :: iso_c_binding, only : c_ptr @@ -367,7 +353,8 @@ function MultiBlockConnectivity_cptr(cptr) result(this) type(atlas_MultiBlockConnectivity) :: this type(c_ptr) :: cptr call this%reset_c_ptr( cptr ) - call setup_access(this) + call this%set_access() + call this%return() end function function MultiBlockConnectivity_constructor(name) result(this) @@ -410,15 +397,6 @@ function BlockConnectivity_cptr(cptr) result(this) call this%reset_c_ptr( cptr ) end function -subroutine atlas_BlockConnectivity__delete(this) - use atlas_connectivity_c_binding - class(atlas_BlockConnectivity), intent(inout) :: this -! if ( .not. this%is_null() ) then -! call atlas__BlockConnectivity__delete(this%c_ptr()) -! end if - call this%reset_c_ptr() -end subroutine - subroutine atlas_BlockConnectivity__data(this,data) use atlas_connectivity_c_binding use, intrinsic :: iso_c_binding, only : c_int, c_ptr, c_size_t, c_f_pointer @@ -457,25 +435,22 @@ function atlas_BlockConnectivity__missing_value(this) result(val) !======================================================== -subroutine setup_access(connectivity) +subroutine set_access(this) use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_f_pointer, c_funloc, c_loc - class(atlas_Connectivity), intent(inout) :: connectivity - type(c_ptr) :: ctxt_update - type(c_ptr) :: ctxt_delete - integer(c_int) :: have_ctxt_update - integer(c_int) :: have_ctxt_delete - have_ctxt_update = atlas__connectivity__ctxt_update(connectivity%c_ptr(),ctxt_update) - if( have_ctxt_update == 1 ) then - call c_f_pointer(ctxt_update,connectivity%access) + class(atlas_Connectivity), intent(inout) :: this + type(c_ptr) :: ctxt + integer(c_int) :: have_ctxt + have_ctxt = atlas__connectivity__ctxt(this%c_ptr(),ctxt) + if( have_ctxt == 1 ) then + call c_f_pointer(ctxt,this%access) else - allocate( connectivity%access ) - call atlas__connectivity__register_update( connectivity%c_ptr(), c_funloc(update_access_c), c_loc(connectivity%access) ) - connectivity%access%connectivity_ptr = connectivity%c_ptr() - call update_access(connectivity%access) - endif - have_ctxt_delete = atlas__connectivity__ctxt_delete(connectivity%c_ptr(),ctxt_delete) - if( have_ctxt_update /= 1 ) then - call atlas__connectivity__register_delete( connectivity%c_ptr(), c_funloc(delete_access_c), c_loc(connectivity%access) ) + allocate( this%access ) + call atlas__connectivity__register_ctxt ( this%c_ptr(), c_loc(this%access) ) + call atlas__connectivity__register_update( this%c_ptr(), c_funloc(update_access_c) ) + call atlas__connectivity__register_delete( this%c_ptr(), c_funloc(delete_access_c) ) + + this%access%connectivity_ptr = this%c_ptr() + call update_access(this%access) endif end subroutine diff --git a/src/tests/mesh/fctest_connectivity.F90 b/src/tests/mesh/fctest_connectivity.F90 index fea8f6070..5cc026b48 100644 --- a/src/tests/mesh/fctest_connectivity.F90 +++ b/src/tests/mesh/fctest_connectivity.F90 @@ -39,6 +39,7 @@ FCTEST_CHECK_EQUAL( connectivity%owners(), 1 ) FCTEST_CHECK_EQUAL(connectivity%name(),"hybrid") + FCTEST_CHECK_EQUAL(connectivity%rows(),0_c_size_t) FCTEST_CHECK_EQUAL(connectivity%missing_value(),0) From e25f8a73002dc13e5195cce6ea7029900414c2ab Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Sun, 24 Dec 2017 14:15:13 +0000 Subject: [PATCH 230/355] FCKIT-4 cosmetic --- src/atlas_f/trans/atlas_Trans_module.F90 | 1 - 1 file changed, 1 deletion(-) diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index 33b26f8b8..0be66e2b6 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -202,7 +202,6 @@ function grid( this ) #ifdef ATLAS_HAVE_TRANS grid = atlas_Grid( atlas__Trans__grid(this%c_ptr()) ) call grid%return() -#warning here #else THROW_ERROR ! call grid%return() From b8a2e4acd0f21d88cbba3c9ba4b0e4769f566ce2 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 4 Jan 2018 13:33:30 +0000 Subject: [PATCH 231/355] FCKIT-4 intel workarounds --- src/atlas/library/defines.h.in | 4 + src/atlas_f/atlas_module.F90 | 3 - .../autogenerated/atlas_Field_module_fypp.F90 | 250 +++++++++--------- src/atlas_f/field/atlas_Field_module.F90 | 14 +- .../atlas_FunctionSpace_module.F90 | 3 +- ...functionspace_StructuredColumns_module.F90 | 18 +- .../mesh/atlas_Connectivity_module.F90 | 21 +- src/atlas_f/output/atlas_output_module.F90 | 29 +- src/atlas_f/trans/atlas_Trans_module.F90 | 53 +++- src/tests/grid/fctest_griddistribution.F90 | 1 - src/tests/grid/fctest_state.F90 | 11 +- src/tests/mesh/fctest_mesh.F90 | 4 +- src/tests/numerics/fctest_fvm_nabla.F90 | 1 + 13 files changed, 236 insertions(+), 176 deletions(-) diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index 71b6455b3..8b46cf86e 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -56,4 +56,8 @@ #define ATLAS_INDEXVIEW_BOUNDS_CHECKING #endif +#define ATLAS_SUPPRESS_UNUSED( X ) \ +associate( unused_ => X ); \ +end associate + #endif \ No newline at end of file diff --git a/src/atlas_f/atlas_module.F90 b/src/atlas_f/atlas_module.F90 index e715737fd..d26b177ce 100644 --- a/src/atlas_f/atlas_module.F90 +++ b/src/atlas_f/atlas_module.F90 @@ -188,12 +188,9 @@ subroutine atlas_init( comm ) use atlas_library_c_binding use iso_fortran_env, only : stdout => output_unit use fckit_main_module, only: fckit_main - use fckit_mpi_module, only : fckit_mpi_comm use atlas_mpi_module, only : atlas_mpi_set_comm integer, intent(in), optional :: comm - type(fckit_mpi_comm) :: world - integer :: output_unit if( .not. fckit_main%ready() ) then call fckit_main%initialise() diff --git a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 index 116f965e3..22406992a 100644 --- a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 +++ b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 @@ -1,3 +1,5 @@ +#include "atlas/atlas_f.h" + module atlas_field_module @@ -366,14 +368,14 @@ subroutine array_c_to_f_int32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - integer(c_int), pointer, intent(out) :: array_fptr(:) + integer(c_int), pointer, intent(inout) :: array_fptr(:) integer(c_int), pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -402,14 +404,14 @@ subroutine array_c_to_f_int64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - integer(c_long), pointer, intent(out) :: array_fptr(:) + integer(c_long), pointer, intent(inout) :: array_fptr(:) integer(c_long), pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -438,14 +440,14 @@ subroutine array_c_to_f_real32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - real(c_float), pointer, intent(out) :: array_fptr(:) + real(c_float), pointer, intent(inout) :: array_fptr(:) real(c_float), pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -474,14 +476,14 @@ subroutine array_c_to_f_real64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - real(c_double), pointer, intent(out) :: array_fptr(:) + real(c_double), pointer, intent(inout) :: array_fptr(:) real(c_double), pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -510,14 +512,14 @@ subroutine array_c_to_f_logical32_r1(array_cptr,rank,shape_cptr,strides_cptr,arr integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - logical, pointer, intent(out) :: array_fptr(:) + logical, pointer, intent(inout) :: array_fptr(:) logical, pointer :: tmp(:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -546,14 +548,14 @@ subroutine array_c_to_f_int32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - integer(c_int), pointer, intent(out) :: array_fptr(:,:) + integer(c_int), pointer, intent(inout) :: array_fptr(:,:) integer(c_int), pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -582,14 +584,14 @@ subroutine array_c_to_f_int64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - integer(c_long), pointer, intent(out) :: array_fptr(:,:) + integer(c_long), pointer, intent(inout) :: array_fptr(:,:) integer(c_long), pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -618,14 +620,14 @@ subroutine array_c_to_f_real32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - real(c_float), pointer, intent(out) :: array_fptr(:,:) + real(c_float), pointer, intent(inout) :: array_fptr(:,:) real(c_float), pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -654,14 +656,14 @@ subroutine array_c_to_f_real64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - real(c_double), pointer, intent(out) :: array_fptr(:,:) + real(c_double), pointer, intent(inout) :: array_fptr(:,:) real(c_double), pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -690,14 +692,14 @@ subroutine array_c_to_f_logical32_r2(array_cptr,rank,shape_cptr,strides_cptr,arr integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - logical, pointer, intent(out) :: array_fptr(:,:) + logical, pointer, intent(inout) :: array_fptr(:,:) logical, pointer :: tmp(:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -726,14 +728,14 @@ subroutine array_c_to_f_int32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - integer(c_int), pointer, intent(out) :: array_fptr(:,:,:) + integer(c_int), pointer, intent(inout) :: array_fptr(:,:,:) integer(c_int), pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -762,14 +764,14 @@ subroutine array_c_to_f_int64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - integer(c_long), pointer, intent(out) :: array_fptr(:,:,:) + integer(c_long), pointer, intent(inout) :: array_fptr(:,:,:) integer(c_long), pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -798,14 +800,14 @@ subroutine array_c_to_f_real32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - real(c_float), pointer, intent(out) :: array_fptr(:,:,:) + real(c_float), pointer, intent(inout) :: array_fptr(:,:,:) real(c_float), pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -834,14 +836,14 @@ subroutine array_c_to_f_real64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - real(c_double), pointer, intent(out) :: array_fptr(:,:,:) + real(c_double), pointer, intent(inout) :: array_fptr(:,:,:) real(c_double), pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -870,14 +872,14 @@ subroutine array_c_to_f_logical32_r3(array_cptr,rank,shape_cptr,strides_cptr,arr integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - logical, pointer, intent(out) :: array_fptr(:,:,:) + logical, pointer, intent(inout) :: array_fptr(:,:,:) logical, pointer :: tmp(:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -906,14 +908,14 @@ subroutine array_c_to_f_int32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - integer(c_int), pointer, intent(out) :: array_fptr(:,:,:,:) + integer(c_int), pointer, intent(inout) :: array_fptr(:,:,:,:) integer(c_int), pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -942,14 +944,14 @@ subroutine array_c_to_f_int64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - integer(c_long), pointer, intent(out) :: array_fptr(:,:,:,:) + integer(c_long), pointer, intent(inout) :: array_fptr(:,:,:,:) integer(c_long), pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -978,14 +980,14 @@ subroutine array_c_to_f_real32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - real(c_float), pointer, intent(out) :: array_fptr(:,:,:,:) + real(c_float), pointer, intent(inout) :: array_fptr(:,:,:,:) real(c_float), pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -1014,14 +1016,14 @@ subroutine array_c_to_f_real64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - real(c_double), pointer, intent(out) :: array_fptr(:,:,:,:) + real(c_double), pointer, intent(inout) :: array_fptr(:,:,:,:) real(c_double), pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -1050,14 +1052,14 @@ subroutine array_c_to_f_logical32_r4(array_cptr,rank,shape_cptr,strides_cptr,arr integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - logical, pointer, intent(out) :: array_fptr(:,:,:,:) + logical, pointer, intent(inout) :: array_fptr(:,:,:,:) logical, pointer :: tmp(:,:,:,:) integer, pointer :: shape(:) integer, pointer :: strides(:) integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",172)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -1082,7 +1084,7 @@ subroutine access_host_data_int32_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:) + integer(c_int), pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1095,7 +1097,7 @@ subroutine access_device_data_int32_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:) + integer(c_int), pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1110,7 +1112,7 @@ subroutine access_host_data_int64_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:) + integer(c_long), pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1123,7 +1125,7 @@ subroutine access_device_data_int64_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:) + integer(c_long), pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1138,7 +1140,7 @@ subroutine access_host_data_real32_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:) + real(c_float), pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1151,7 +1153,7 @@ subroutine access_device_data_real32_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:) + real(c_float), pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1166,7 +1168,7 @@ subroutine access_host_data_real64_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:) + real(c_double), pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1179,7 +1181,7 @@ subroutine access_device_data_real64_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:) + real(c_double), pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1194,7 +1196,7 @@ subroutine access_host_data_logical32_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:) + logical, pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1207,7 +1209,7 @@ subroutine access_device_data_logical32_r1(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:) + logical, pointer, intent(inout) :: field(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1222,7 +1224,7 @@ subroutine access_host_data_int32_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:) + integer(c_int), pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1235,7 +1237,7 @@ subroutine access_device_data_int32_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:) + integer(c_int), pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1250,7 +1252,7 @@ subroutine access_host_data_int64_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:) + integer(c_long), pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1263,7 +1265,7 @@ subroutine access_device_data_int64_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:) + integer(c_long), pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1278,7 +1280,7 @@ subroutine access_host_data_real32_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:) + real(c_float), pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1291,7 +1293,7 @@ subroutine access_device_data_real32_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:) + real(c_float), pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1306,7 +1308,7 @@ subroutine access_host_data_real64_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:) + real(c_double), pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1319,7 +1321,7 @@ subroutine access_device_data_real64_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:) + real(c_double), pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1334,7 +1336,7 @@ subroutine access_host_data_logical32_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:) + logical, pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1347,7 +1349,7 @@ subroutine access_device_data_logical32_r2(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:) + logical, pointer, intent(inout) :: field(:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1362,7 +1364,7 @@ subroutine access_host_data_int32_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:,:) + integer(c_int), pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1375,7 +1377,7 @@ subroutine access_device_data_int32_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:,:) + integer(c_int), pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1390,7 +1392,7 @@ subroutine access_host_data_int64_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:,:) + integer(c_long), pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1403,7 +1405,7 @@ subroutine access_device_data_int64_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:,:) + integer(c_long), pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1418,7 +1420,7 @@ subroutine access_host_data_real32_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:,:) + real(c_float), pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1431,7 +1433,7 @@ subroutine access_device_data_real32_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:,:) + real(c_float), pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1446,7 +1448,7 @@ subroutine access_host_data_real64_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:,:) + real(c_double), pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1459,7 +1461,7 @@ subroutine access_device_data_real64_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:,:) + real(c_double), pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1474,7 +1476,7 @@ subroutine access_host_data_logical32_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:,:) + logical, pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1487,7 +1489,7 @@ subroutine access_device_data_logical32_r3(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:,:) + logical, pointer, intent(inout) :: field(:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1502,7 +1504,7 @@ subroutine access_host_data_int32_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:,:,:) + integer(c_int), pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1515,7 +1517,7 @@ subroutine access_device_data_int32_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:,:,:) + integer(c_int), pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1530,7 +1532,7 @@ subroutine access_host_data_int64_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:,:,:) + integer(c_long), pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1543,7 +1545,7 @@ subroutine access_device_data_int64_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:,:,:) + integer(c_long), pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1558,7 +1560,7 @@ subroutine access_host_data_real32_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:,:,:) + real(c_float), pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1571,7 +1573,7 @@ subroutine access_device_data_real32_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:,:,:) + real(c_float), pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1586,7 +1588,7 @@ subroutine access_host_data_real64_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:,:,:) + real(c_double), pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1599,7 +1601,7 @@ subroutine access_device_data_real64_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:,:,:) + real(c_double), pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1614,7 +1616,7 @@ subroutine access_host_data_logical32_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:,:,:) + logical, pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1627,7 +1629,7 @@ subroutine access_device_data_logical32_r4(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:,:,:) + logical, pointer, intent(inout) :: field(:,:,:,:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -1642,7 +1644,7 @@ subroutine access_host_data_int32_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:) + integer(c_int), pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1656,7 +1658,7 @@ subroutine access_device_data_int32_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:) + integer(c_int), pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1671,7 +1673,7 @@ subroutine access_host_data_int64_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:) + integer(c_long), pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1685,7 +1687,7 @@ subroutine access_device_data_int64_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:) + integer(c_long), pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1700,7 +1702,7 @@ subroutine access_host_data_real32_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:) + real(c_float), pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1714,7 +1716,7 @@ subroutine access_device_data_real32_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:) + real(c_float), pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1729,7 +1731,7 @@ subroutine access_host_data_real64_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:) + real(c_double), pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1743,7 +1745,7 @@ subroutine access_device_data_real64_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:) + real(c_double), pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1758,7 +1760,7 @@ subroutine access_host_data_logical32_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:) + logical, pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1772,7 +1774,7 @@ subroutine access_device_data_logical32_r1_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:) + logical, pointer, intent(inout) :: field(:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1787,7 +1789,7 @@ subroutine access_host_data_int32_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:) + integer(c_int), pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1801,7 +1803,7 @@ subroutine access_device_data_int32_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:) + integer(c_int), pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1816,7 +1818,7 @@ subroutine access_host_data_int64_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:) + integer(c_long), pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1830,7 +1832,7 @@ subroutine access_device_data_int64_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:) + integer(c_long), pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1845,7 +1847,7 @@ subroutine access_host_data_real32_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:) + real(c_float), pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1859,7 +1861,7 @@ subroutine access_device_data_real32_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:) + real(c_float), pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1874,7 +1876,7 @@ subroutine access_host_data_real64_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:) + real(c_double), pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1888,7 +1890,7 @@ subroutine access_device_data_real64_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:) + real(c_double), pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1903,7 +1905,7 @@ subroutine access_host_data_logical32_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:) + logical, pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1917,7 +1919,7 @@ subroutine access_device_data_logical32_r2_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:) + logical, pointer, intent(inout) :: field(:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1932,7 +1934,7 @@ subroutine access_host_data_int32_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:,:) + integer(c_int), pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1946,7 +1948,7 @@ subroutine access_device_data_int32_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:,:) + integer(c_int), pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1961,7 +1963,7 @@ subroutine access_host_data_int64_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:,:) + integer(c_long), pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1975,7 +1977,7 @@ subroutine access_device_data_int64_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:,:) + integer(c_long), pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -1990,7 +1992,7 @@ subroutine access_host_data_real32_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:,:) + real(c_float), pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2004,7 +2006,7 @@ subroutine access_device_data_real32_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:,:) + real(c_float), pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2019,7 +2021,7 @@ subroutine access_host_data_real64_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:,:) + real(c_double), pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2033,7 +2035,7 @@ subroutine access_device_data_real64_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:,:) + real(c_double), pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2048,7 +2050,7 @@ subroutine access_host_data_logical32_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:,:) + logical, pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2062,7 +2064,7 @@ subroutine access_device_data_logical32_r3_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:,:) + logical, pointer, intent(inout) :: field(:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2077,7 +2079,7 @@ subroutine access_host_data_int32_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:,:,:) + integer(c_int), pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2091,7 +2093,7 @@ subroutine access_device_data_int32_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_int), pointer, intent(out) :: field(:,:,:,:) + integer(c_int), pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2106,7 +2108,7 @@ subroutine access_host_data_int64_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:,:,:) + integer(c_long), pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2120,7 +2122,7 @@ subroutine access_device_data_int64_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - integer(c_long), pointer, intent(out) :: field(:,:,:,:) + integer(c_long), pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2135,7 +2137,7 @@ subroutine access_host_data_real32_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:,:,:) + real(c_float), pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2149,7 +2151,7 @@ subroutine access_device_data_real32_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_float), pointer, intent(out) :: field(:,:,:,:) + real(c_float), pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2164,7 +2166,7 @@ subroutine access_host_data_real64_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:,:,:) + real(c_double), pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2178,7 +2180,7 @@ subroutine access_device_data_real64_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - real(c_double), pointer, intent(out) :: field(:,:,:,:) + real(c_double), pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2193,7 +2195,7 @@ subroutine access_host_data_logical32_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:,:,:) + logical, pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2207,7 +2209,7 @@ subroutine access_device_data_logical32_r4_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - logical, pointer, intent(out) :: field(:,:,:,:) + logical, pointer, intent(inout) :: field(:,:,:,:) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -2221,6 +2223,7 @@ subroutine access_device_data_logical32_r4_shape(this, field, shape) subroutine dummy(this) use atlas_field_c_binding class(atlas_Field), intent(in) :: this + ATLAS_SUPPRESS_UNUSED(this) end subroutine !------------------------------------------------------------------------------- @@ -2233,7 +2236,7 @@ integer function atlas_real(kind) else if (kind == c_float) then atlas_real = ATLAS_KIND_REAL32 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",275)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",278)) end if end function @@ -2249,7 +2252,7 @@ integer function atlas_integer(kind) else if (kind == c_long) then atlas_integer = ATLAS_KIND_INT64 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",291)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",294)) end if end if end function @@ -2259,6 +2262,7 @@ integer function atlas_integer(kind) integer function atlas_logical(kind) integer, optional :: kind atlas_logical = ATLAS_KIND_INT32 + ATLAS_SUPPRESS_UNUSED(kind) end function !------------------------------------------------------------------------------- @@ -2275,7 +2279,7 @@ function atlas_data_type(kind) else if( kind == ATLAS_KIND_REAL64 ) then atlas_data_type = "real64" else - call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",317)) + call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",321)) endif end function diff --git a/src/atlas_f/field/atlas_Field_module.F90 b/src/atlas_f/field/atlas_Field_module.F90 index 13d98c854..9f2a06f58 100644 --- a/src/atlas_f/field/atlas_Field_module.F90 +++ b/src/atlas_f/field/atlas_Field_module.F90 @@ -1,3 +1,5 @@ +#include "atlas/atlas_f.h" + #:setvar ranks [1,2,3,4] #:setvar dim ['',':',':,:',':,:,:',':,:,:,:',':,:,:,:,:'] #:setvar ftypes ['integer(c_int)','integer(c_long)','real(c_float)','real(c_double)', 'logical'] @@ -162,7 +164,7 @@ subroutine array_c_to_f_${dtype}$_r${rank}$(array_cptr,rank,shape_cptr,strides_c integer(c_int), intent(in) :: rank type(c_ptr), intent(in) :: shape_cptr type(c_ptr), intent(in) :: strides_cptr - ${ftype}$, pointer, intent(out) :: array_fptr(${dim[rank]}$) + ${ftype}$, pointer, intent(inout) :: array_fptr(${dim[rank]}$) ${ftype}$, pointer :: tmp(${dim[rank]}$) integer, pointer :: shape(:) integer, pointer :: strides(:) @@ -198,7 +200,7 @@ subroutine access_host_data_${dtype}$_r${rank}$(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - ${ftype}$, pointer, intent(out) :: field(${dim[rank]}$) + ${ftype}$, pointer, intent(inout) :: field(${dim[rank]}$) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -211,7 +213,7 @@ subroutine access_device_data_${dtype}$_r${rank}$(this, field) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double class(atlas_Field), intent(in) :: this - ${ftype}$, pointer, intent(out) :: field(${dim[rank]}$) + ${ftype}$, pointer, intent(inout) :: field(${dim[rank]}$) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr type(c_ptr) :: strides_cptr @@ -230,7 +232,7 @@ subroutine access_host_data_${dtype}$_r${rank}$_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - ${ftype}$, pointer, intent(out) :: field(${dim[rank]}$) + ${ftype}$, pointer, intent(inout) :: field(${dim[rank]}$) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -244,7 +246,7 @@ subroutine access_device_data_${dtype}$_r${rank}$_shape(this, field, shape) use atlas_field_c_binding use, intrinsic :: iso_c_binding, only : c_ptr, c_int, c_long, c_float, c_double, c_f_pointer class(atlas_Field), intent(in) :: this - ${ftype}$, pointer, intent(out) :: field(${dim[rank]}$) + ${ftype}$, pointer, intent(inout) :: field(${dim[rank]}$) integer(c_int), intent(in) :: shape(:) type(c_ptr) :: field_cptr type(c_ptr) :: shape_cptr @@ -260,6 +262,7 @@ subroutine access_device_data_${dtype}$_r${rank}$_shape(this, field, shape) subroutine dummy(this) use atlas_field_c_binding class(atlas_Field), intent(in) :: this + ATLAS_SUPPRESS_UNUSED(this) end subroutine !------------------------------------------------------------------------------- @@ -298,6 +301,7 @@ integer function atlas_integer(kind) integer function atlas_logical(kind) integer, optional :: kind atlas_logical = ATLAS_KIND_INT32 + ATLAS_SUPPRESS_UNUSED(kind) end function !------------------------------------------------------------------------------- diff --git a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 index 951c167c5..c71cfb289 100644 --- a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 +++ b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_functionspace_module @@ -181,8 +182,6 @@ function deprecated_create_field_2(this,require_name,kind,levels) result(field) integer, intent(in) :: kind integer(c_int), intent(in) :: levels - integer(c_int) :: opt_variables - type(atlas_Config) :: options options = atlas_Config() diff --git a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 index 1df614cc8..58f0b93ae 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_functionspace_StructuredColumns_module @@ -8,6 +9,7 @@ module atlas_functionspace_StructuredColumns_module use atlas_FieldSet_module, only: atlas_FieldSet use atlas_Grid_module, only: atlas_Grid use atlas_Config_module, only: atlas_Config +use fckit_owned_object_module, only : fckit_owned_object implicit none @@ -18,6 +20,7 @@ module atlas_functionspace_StructuredColumns_module private :: atlas_FieldSet private :: atlas_Grid private :: atlas_Config +private :: fckit_owned_object public :: atlas_functionspace_StructuredColumns @@ -42,7 +45,7 @@ module atlas_functionspace_StructuredColumns_module contains - procedure, public :: shared_ptr_cast + procedure, public :: assignment_operator_hook procedure, public :: gather procedure, public :: scatter @@ -84,14 +87,12 @@ module atlas_functionspace_StructuredColumns_module contains !======================================================== -function shared_ptr_cast(this) result(success) +subroutine assignment_operator_hook(this,other) class(atlas_functionspace_StructuredColumns) :: this - logical :: success - success = this%fckit_shared_object__shared_ptr_cast() - if( success ) then - call this%set_index() - endif -end function + class(fckit_owned_object) :: other + call this%set_index() + ATLAS_SUPPRESS_UNUSED(other) +end subroutine function StructuredColumns__cptr(cptr) result(this) type(atlas_functionspace_StructuredColumns) :: this @@ -169,7 +170,6 @@ subroutine set_index(this) type(c_ptr) :: index_cptr integer(c_int), pointer :: index_fptr(:) integer(c_int) :: i_min, i_max, j_min, j_max - integer(c_int) :: size integer(c_int) :: ni, nj call atlas__fs__StructuredColumns__index_host( this%c_ptr(), index_cptr, i_min, i_max, j_min, j_max ) ni = i_max-i_min+1; diff --git a/src/atlas_f/mesh/atlas_Connectivity_module.F90 b/src/atlas_f/mesh/atlas_Connectivity_module.F90 index a93099bbd..85b13684c 100644 --- a/src/atlas_f/mesh/atlas_Connectivity_module.F90 +++ b/src/atlas_f/mesh/atlas_Connectivity_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_connectivity_module @@ -31,7 +32,7 @@ module atlas_connectivity_module contains - procedure, public :: shared_ptr_cast + procedure, public :: assignment_operator_hook procedure, public :: set_access ! Public methods @@ -147,14 +148,12 @@ function atlas__connectivity__ctxt(This,ptr) bind(c,name="atlas__connectivity__c contains -function shared_ptr_cast(this) result(success) +subroutine assignment_operator_hook(this,other) class(atlas_Connectivity) :: this - logical :: success - success = this%fckit_shared_object__shared_ptr_cast() - if( success ) then - call this%set_access() - endif -end function + class(fckit_owned_object) :: other + call this%set_access() + ATLAS_SUPPRESS_UNUSED(other) +end subroutine function Connectivity_cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only : c_ptr @@ -262,7 +261,7 @@ subroutine atlas_Connectivity__padded_data(this, padded, cols) use, intrinsic :: iso_c_binding, only : c_int, c_size_t class(atlas_Connectivity), intent(inout) :: this integer(c_int), pointer, intent(inout) :: padded(:,:) - integer(c_size_t), pointer, intent(out), optional :: cols(:) + integer(c_size_t), pointer, intent(inout), optional :: cols(:) if( .not. associated(this%access%padded_) ) call update_padded(this%access) padded => this%access%padded_ if( present(cols) ) cols => this%access%cols @@ -301,7 +300,7 @@ subroutine atlas_Connectivity__row(this, row_idx, row, cols) use, intrinsic :: iso_c_binding, only : c_int class(atlas_Connectivity), intent(in) :: this integer(c_int), intent(in) :: row_idx - integer(c_int), pointer, intent(out) :: row(:) + integer(c_int), pointer, intent(inout) :: row(:) integer(c_int), intent(out) :: cols row => this%access%values_(this%access%displs_(row_idx)+1:this%access%displs_(row_idx+1)+1) cols = this%access%cols(row_idx) @@ -401,7 +400,7 @@ subroutine atlas_BlockConnectivity__data(this,data) use atlas_connectivity_c_binding use, intrinsic :: iso_c_binding, only : c_int, c_ptr, c_size_t, c_f_pointer class(atlas_BlockConnectivity), intent(in) :: this - integer(c_int), pointer, intent(out) :: data(:,:) + integer(c_int), pointer, intent(inout) :: data(:,:) type(c_ptr) :: data_cptr integer(c_size_t) :: rows integer(c_size_t) :: cols diff --git a/src/atlas_f/output/atlas_output_module.F90 b/src/atlas_f/output/atlas_output_module.F90 index 3077a0e73..67d7e7f34 100644 --- a/src/atlas_f/output/atlas_output_module.F90 +++ b/src/atlas_f/output/atlas_output_module.F90 @@ -5,11 +5,14 @@ module atlas_output_module use fckit_owned_object_module, only : fckit_owned_object +use atlas_Config_module, only : atlas_Config +use atlas_FunctionSpace_module, only: atlas_FunctionSpace +use atlas_FieldSet_module, only: atlas_FieldSet +use atlas_Field_module, only: atlas_Field +use atlas_Mesh_module, only: atlas_Mesh implicit none -private :: fckit_owned_object - public :: atlas_Output public :: atlas_output_Gmsh @@ -52,6 +55,15 @@ module atlas_output_module module procedure atlas_output_Gmsh__pathname_mode end interface +!------------------------------------------------------------------------------ + +private :: fckit_owned_object +private :: atlas_Config +private :: atlas_FunctionSpace +private :: atlas_FieldSet +private :: atlas_Field +private :: atlas_Mesh + ! ============================================================================= CONTAINS ! ============================================================================= @@ -67,7 +79,6 @@ function atlas_Output__cptr(cptr) result(this) function atlas_output_Gmsh__pathname_mode(file,mode,coordinates,levels,gather) result(this) use fckit_c_interop_module, only : c_str use atlas_output_gmsh_c_binding - use atlas_Config_module, only : atlas_Config type(atlas_Output) :: this character(len=*), intent(in) :: file character(len=1), intent(in), optional :: mode @@ -89,8 +100,6 @@ function atlas_output_Gmsh__pathname_mode(file,mode,coordinates,levels,gather) r subroutine write_mesh(this,mesh,config) use atlas_output_c_binding - use atlas_Config_module, only : atlas_Config - use atlas_Mesh_module, only: atlas_Mesh class(atlas_Output), intent(in) :: this type(atlas_Mesh), intent(in) :: mesh type(atlas_Config), intent(in), optional :: config @@ -106,9 +115,6 @@ subroutine write_mesh(this,mesh,config) subroutine write_field_fs(this,field,functionspace,config) use atlas_output_c_binding - use atlas_Config_module, only : atlas_Config - use atlas_Field_module, only: atlas_Field - use atlas_FunctionSpace_module, only: atlas_FunctionSpace class(atlas_Output), intent(in) :: this type(atlas_Field), intent(in) :: field class(atlas_FunctionSpace), intent(in) :: functionspace @@ -125,9 +131,6 @@ subroutine write_field_fs(this,field,functionspace,config) subroutine write_fieldset_fs(this,fieldset,functionspace,config) use atlas_output_c_binding - use atlas_Config_module, only : atlas_Config - use atlas_FunctionSpace_module, only: atlas_FunctionSpace - use atlas_FieldSet_module, only: atlas_FieldSet class(atlas_Output), intent(in) :: this type(atlas_FieldSet), intent(in) :: fieldset class(atlas_FunctionSpace), intent(in) :: functionspace @@ -145,8 +148,6 @@ subroutine write_fieldset_fs(this,fieldset,functionspace,config) subroutine write_field(this,field,config) use atlas_output_c_binding - use atlas_Config_module, only : atlas_Config - use atlas_Field_module, only: atlas_Field class(atlas_Output), intent(in) :: this type(atlas_Field), intent(in) :: field type(atlas_Config), intent(in), optional :: config @@ -163,8 +164,6 @@ subroutine write_field(this,field,config) subroutine write_fieldset(this,fieldset,config) use atlas_output_c_binding - use atlas_Config_module, only : atlas_Config - use atlas_FieldSet_module, only: atlas_FieldSet class(atlas_Output), intent(in) :: this type(atlas_FieldSet), intent(in) :: fieldset type(atlas_Config), intent(in), optional :: config diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index 0be66e2b6..104ce9717 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -119,6 +119,8 @@ function atlas_Trans__ctor( grid, nsmax ) result(this) #else ! IGNORE call this%reset_c_ptr( c_null_ptr ) + ATLAS_SUPPRESS_UNUSED( grid ) + ATLAS_SUPPRESS_UNUSED( nsmax ) #endif call this%return() end function atlas_Trans__ctor @@ -132,6 +134,7 @@ function handle( this ) #else THROW_ERROR handle = 0 + ATLAS_SUPPRESS_UNUSED( this ) #endif end function @@ -144,6 +147,7 @@ function truncation( this ) #else THROW_ERROR truncation = 0 + ATLAS_SUPPRESS_UNUSED( this ) #endif end function @@ -156,6 +160,7 @@ function nb_spectral_coefficients( this ) #else THROW_ERROR nb_spectral_coefficients = 0 + ATLAS_SUPPRESS_UNUSED( this ) #endif end function @@ -168,6 +173,7 @@ function nb_spectral_coefficients_global( this ) #else THROW_ERROR nb_spectral_coefficients_global = 0 + ATLAS_SUPPRESS_UNUSED( this ) #endif end function @@ -180,6 +186,7 @@ function nb_gridpoints( this ) #else THROW_ERROR nb_gridpoints = 0 + ATLAS_SUPPRESS_UNUSED( this ) #endif end function @@ -192,6 +199,7 @@ function nb_gridpoints_global( this ) #else THROW_ERROR nb_gridpoints_global = 0 + ATLAS_SUPPRESS_UNUSED( this ) #endif end function @@ -204,7 +212,8 @@ function grid( this ) call grid%return() #else THROW_ERROR - ! call grid%return() + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( grid ) #endif end function @@ -234,6 +243,10 @@ subroutine dirtrans_fieldset(this, gpfields, spfields, config) endif #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( gpfields ) + ATLAS_SUPPRESS_UNUSED( spfields ) + ATLAS_SUPPRESS_UNUSED( config ) #endif end subroutine dirtrans_fieldset @@ -263,6 +276,10 @@ subroutine invtrans_fieldset(this, spfields, gpfields, config) endif #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( spfields ) + ATLAS_SUPPRESS_UNUSED( gpfields ) + ATLAS_SUPPRESS_UNUSED( config ) #endif end subroutine invtrans_fieldset @@ -291,6 +308,10 @@ subroutine dirtrans_field(this, gpfield, spfield, config) endif #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( gpfield ) + ATLAS_SUPPRESS_UNUSED( spfield ) + ATLAS_SUPPRESS_UNUSED( config ) #endif end subroutine dirtrans_field @@ -321,6 +342,11 @@ subroutine dirtrans_wind2vordiv_field(this, gpwind, spvor, spdiv, config) endif #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( gpwind ) + ATLAS_SUPPRESS_UNUSED( spvor ) + ATLAS_SUPPRESS_UNUSED( spdiv ) + ATLAS_SUPPRESS_UNUSED( config ) #endif end subroutine dirtrans_wind2vordiv_field @@ -351,6 +377,10 @@ subroutine invtrans_field(this, spfield, gpfield, config) endif #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( spfield ) + ATLAS_SUPPRESS_UNUSED( gpfield ) + ATLAS_SUPPRESS_UNUSED( config ) #endif end subroutine invtrans_field @@ -382,6 +412,11 @@ subroutine invtrans_vordiv2wind_field(this, spvor, spdiv, gpwind, config) endif #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( spvor ) + ATLAS_SUPPRESS_UNUSED( spdiv ) + ATLAS_SUPPRESS_UNUSED( gpwind ) + ATLAS_SUPPRESS_UNUSED( config ) #endif end subroutine invtrans_vordiv2wind_field @@ -402,6 +437,9 @@ subroutine invtrans_grad_field(this, spfield, gpfield) call config%final() #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( spfield ) + ATLAS_SUPPRESS_UNUSED( gpfield ) #endif end subroutine invtrans_grad_field @@ -417,6 +455,9 @@ subroutine gathspec_r1(this, local, global) call atlas__Trans__gathspec(this%c_ptr(), 1, (/1/), local, global ) #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( local ) + ATLAS_SUPPRESS_UNUSED( global ) #endif end subroutine gathspec_r1 @@ -436,6 +477,9 @@ subroutine gathspec_r2(this, local, global) call atlas__Trans__gathspec(this%c_ptr(), size(local,1), destination, local_view, global_view ) #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( local ) + ATLAS_SUPPRESS_UNUSED( global ) #endif end subroutine gathspec_r2 @@ -457,6 +501,9 @@ subroutine specnorm_r1_scalar(this, spectra, norm, rank) #else norm=0 THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( spectra ) + ATLAS_SUPPRESS_UNUSED( rank ) #endif end subroutine @@ -477,6 +524,10 @@ subroutine specnorm_r2(this, spectra, norm, rank) call atlas__Trans__specnorm(this%c_ptr(), size(spectra,1), spectra_view, norm, rank_opt ) #else THROW_ERROR + ATLAS_SUPPRESS_UNUSED( this ) + ATLAS_SUPPRESS_UNUSED( spectra ) + ATLAS_SUPPRESS_UNUSED( norm ) + ATLAS_SUPPRESS_UNUSED( rank ) #endif end subroutine diff --git a/src/tests/grid/fctest_griddistribution.F90 b/src/tests/grid/fctest_griddistribution.F90 index f427d62f8..274b973f5 100644 --- a/src/tests/grid/fctest_griddistribution.F90 +++ b/src/tests/grid/fctest_griddistribution.F90 @@ -61,7 +61,6 @@ type(atlas_Output) :: gmsh type(atlas_MeshGenerator) :: meshgenerator type(atlas_GridDistribution) :: griddistribution - character(len=1024) :: msg integer, allocatable :: part(:) integer :: jnode diff --git a/src/tests/grid/fctest_state.F90 b/src/tests/grid/fctest_state.F90 index 02537b75c..0d0d8e9ad 100644 --- a/src/tests/grid/fctest_state.F90 +++ b/src/tests/grid/fctest_state.F90 @@ -43,6 +43,7 @@ end module fctest_atlas_State_Fixture ! ----------------------------------------------------------------------------- TEST( test_state_fields ) +#if 1 type(atlas_State) :: state type(atlas_Field) :: temperature_field type(atlas_Field) :: pressure_field @@ -63,11 +64,13 @@ end module fctest_atlas_State_Fixture ! Check how many fields we have write(msg,'(A,I0,A)') "The state contains ",state%size()," fields."; call atlas_log%info(msg) +FCTEST_CHECK_EQUAL( state%size(), 2 ) ! Check if wind field exists if( .not. state%has("wind") ) then write(msg,'(A)') "The state does not contain the wind field"; call atlas_log%info(msg) endif +FCTEST_CHECK( .not. state%has("wind") ) ! Print existing fields info write(msg,'(A)') "The state contains the fields:"; call atlas_log%info(msg) @@ -101,13 +104,14 @@ end module fctest_atlas_State_Fixture ! Delete the state call state%final() - +#endif END_TEST ! ----------------------------------------------------------------------------- TEST( test_state_factory ) +#if 1 type(atlas_State) :: state ! Create a new state @@ -115,12 +119,13 @@ end module fctest_atlas_State_Fixture ! Delete the state call state%final() - +#endif END_TEST ! ----------------------------------------------------------------------------- TEST( test_state_metadata ) +#if 1 type(atlas_State) :: state type(atlas_Metadata) :: state_metadata @@ -134,7 +139,7 @@ end module fctest_atlas_State_Fixture ! Delete the state call state%final() - +#endif END_TEST ! ----------------------------------------------------------------------------- diff --git a/src/tests/mesh/fctest_mesh.F90 b/src/tests/mesh/fctest_mesh.F90 index abfaa22f3..dbe875a5e 100644 --- a/src/tests/mesh/fctest_mesh.F90 +++ b/src/tests/mesh/fctest_mesh.F90 @@ -298,6 +298,7 @@ end module fcta_Mesh_fixture TEST( test_fv ) implicit none + type(atlas_StructuredGrid) :: grid type(atlas_Mesh) :: mesh type(atlas_MeshGenerator) :: meshgenerator @@ -361,14 +362,11 @@ end module fcta_Mesh_fixture node_to_node = nodes%connectivity("node") node_to_edge = nodes%connectivity("edge") - - write(0,*) "mesh.footprint (bytes) = ", mesh%footprint() call node_to_node%final() call mesh%final() call grid%final() call nodes_fs%final() - END_TEST diff --git a/src/tests/numerics/fctest_fvm_nabla.F90 b/src/tests/numerics/fctest_fvm_nabla.F90 index ec058386f..cf34e796d 100644 --- a/src/tests/numerics/fctest_fvm_nabla.F90 +++ b/src/tests/numerics/fctest_fvm_nabla.F90 @@ -255,6 +255,7 @@ SUBROUTINE FV_GRADIENT(PVAR,PGRAD) INODES = SIZE(ZLONLAT)/2 !$OMP PARALLEL DO SCHEDULE(STATIC) PRIVATE(JNODE,JLEV,JEDGE,IEDGE,ZSIGN,ZMETRIC_X,ZMETRIC_Y,INODE2EDGE,INODE2EDGE_SIZE) DO JNODE=1,INODES + DO JLEV=1,NFLEVG PGRAD(1,JLEV,JNODE) = 0.0 PGRAD(2,JLEV,JNODE) = 0.0 From b6745f52bad696e5d36488bd8f26f4e11c394773 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 8 Jan 2018 16:16:02 +0000 Subject: [PATCH 232/355] FCKIT-4 PGI workarounds --- ..._functionspace_StructuredColumns_module.F90 | 8 +++++++- src/atlas_f/mesh/atlas_Connectivity_module.F90 | 18 ++++++++++++++++-- src/atlas_f/util/atlas_Config_module.F90 | 2 +- src/tests/mesh/fctest_connectivity.F90 | 4 ++-- src/tests/util/fctest_parametrisation.F90 | 1 + 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 index 58f0b93ae..93ac3a76b 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 @@ -102,6 +102,12 @@ function StructuredColumns__cptr(cptr) result(this) call this%return() end function +function empty_config() result(config) + type(atlas_Config) :: config + config = atlas_Config() + call config%return() +end function + function StructuredColumns__grid(grid, halo, levels) result(this) use atlas_functionspace_StructuredColumns_c_binding type(atlas_functionspace_StructuredColumns) :: this @@ -109,7 +115,7 @@ function StructuredColumns__grid(grid, halo, levels) result(this) integer, optional :: halo integer, optional :: levels type(atlas_Config) :: config - config = atlas_Config() + config = empty_config() ! Due to PGI compiler bug, we have to do this instead of "config = atlas_Config()"" if( present(halo) ) call config%set("halo",halo) if( present(levels) ) call config%set("levels",levels) call this%reset_c_ptr( atlas__functionspace__StructuredColumns__new__grid( grid%c_ptr(), config%c_ptr() ) ) diff --git a/src/atlas_f/mesh/atlas_Connectivity_module.F90 b/src/atlas_f/mesh/atlas_Connectivity_module.F90 index 85b13684c..57692472d 100644 --- a/src/atlas_f/mesh/atlas_Connectivity_module.F90 +++ b/src/atlas_f/mesh/atlas_Connectivity_module.F90 @@ -64,6 +64,10 @@ module atlas_connectivity_module ! Public methods procedure, public :: blocks => atlas_MultiBlockConnectivity__blocks procedure, public :: block => atlas_MultiBlockConnectivity__block + +! PGI compiler bug won't accept "assignment_operator_hook" from atlas_Connectivity parent class... grrr + procedure, public :: assignment_operator_hook => atlas_MultiBlockConnectivity__assignment_operator_hook + end type !----------------------------! @@ -155,6 +159,16 @@ subroutine assignment_operator_hook(this,other) ATLAS_SUPPRESS_UNUSED(other) end subroutine +! Following routine is exact copy of "assignment_operator_hook" above, because of bug in PGI compiler (17.7) +! Without it, wrongly the "fckit_owned_object::assignment_operator_hook" is used instead of +! "atlas_Connectivity::assignment_operator_hook". +subroutine atlas_MultiBlockConnectivity__assignment_operator_hook(this,other) + class(atlas_MultiBlockConnectivity) :: this + class(fckit_owned_object) :: other + call this%set_access() + ATLAS_SUPPRESS_UNUSED(other) +end subroutine + function Connectivity_cptr(cptr) result(this) use, intrinsic :: iso_c_binding, only : c_ptr use atlas_connectivity_c_binding @@ -361,8 +375,8 @@ function MultiBlockConnectivity_constructor(name) result(this) use fckit_c_interop_module type(atlas_MultiBlockConnectivity) :: this character(len=*), intent(in), optional :: name - this = MultiBlockConnectivity_cptr( atlas__MultiBlockConnectivity__create() ) - + call this%reset_c_ptr( atlas__MultiBlockConnectivity__create() ) + call this%set_access() if( present(name) ) then call atlas__Connectivity__rename(this%c_ptr(),c_str(name)) endif diff --git a/src/atlas_f/util/atlas_Config_module.F90 b/src/atlas_f/util/atlas_Config_module.F90 index 6245892d3..13f196fd8 100644 --- a/src/atlas_f/util/atlas_Config_module.F90 +++ b/src/atlas_f/util/atlas_Config_module.F90 @@ -156,7 +156,7 @@ subroutine atlas_Config__set_config_list(this, name, value) use atlas_Config_c_binding class(atlas_Config), intent(inout) :: this character(len=*), intent(in) :: name - class(atlas_Config), intent(in) :: value(:) + type(atlas_Config), intent(in) :: value(:) !PGI (17.7) compiler bug when "type" replaced with "class" type(c_ptr), target :: value_cptrs(size(value)) integer :: j if( size(value) > 0 ) then diff --git a/src/tests/mesh/fctest_connectivity.F90 b/src/tests/mesh/fctest_connectivity.F90 index 5cc026b48..473d780eb 100644 --- a/src/tests/mesh/fctest_connectivity.F90 +++ b/src/tests/mesh/fctest_connectivity.F90 @@ -23,6 +23,7 @@ END_TESTSUITE_INIT TEST( test_connectivity ) +#if 1 use fckit_module use atlas_connectivity_module use, intrinsic :: iso_c_binding @@ -158,7 +159,7 @@ FCTEST_CHECK_EQUAL(row(3),14) call connectivity%final() - +#endif END_TEST ! ----------------------------------------------------------------------------- @@ -181,7 +182,6 @@ multiblock = atlas_MultiBlockConnectivity() FCTEST_CHECK_EQUAL( multiblock%owners(), 1 ) - FCTEST_CHECK_EQUAL(multiblock%name(),"") FCTEST_CHECK_EQUAL(multiblock%rows(),0_c_size_t) FCTEST_CHECK_EQUAL(multiblock%blocks(),0_c_size_t) diff --git a/src/tests/util/fctest_parametrisation.F90 b/src/tests/util/fctest_parametrisation.F90 index d194b8778..d65118ad5 100644 --- a/src/tests/util/fctest_parametrisation.F90 +++ b/src/tests/util/fctest_parametrisation.F90 @@ -80,6 +80,7 @@ end module fctest_atlas_Config_fixture call list(j)%set("l1",21) call list(j)%set("l2",22) enddo + call nested%set("list",list) do j=1,2 call list(j)%final() From a4c7bf0126c328a810269915f8b7270e4b0ea0c2 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 9 Jan 2018 09:03:01 +0000 Subject: [PATCH 233/355] FCKIT-4 Cray supports FINAL --- src/atlas/library/defines.h.in | 8 -- src/atlas_f/CMakeLists.txt | 14 +- src/atlas_f/atlas_f.h.in | 20 +++ src/atlas_f/atlas_module.F90 | 2 - .../autogenerated/atlas_Field_module_fypp.F90 | 67 ++++++---- src/atlas_f/field/atlas_FieldSet_module.F90 | 22 +++- src/atlas_f/field/atlas_Field_module.F90 | 21 ++- src/atlas_f/field/atlas_State_module.F90 | 18 +++ .../atlas_FunctionSpace_module.F90 | 16 +++ ...atlas_functionspace_EdgeColumns_module.F90 | 28 ++-- ...atlas_functionspace_NodeColumns_module.F90 | 27 ++-- .../atlas_functionspace_Spectral_module.F90 | 26 ++-- ...functionspace_StructuredColumns_module.F90 | 18 ++- .../grid/atlas_GridDistribution_module.F90 | 5 +- src/atlas_f/grid/atlas_Grid_module.F90 | 67 +++++++++- src/atlas_f/grid/atlas_Partitioner_module.F90 | 18 +++ .../atlas_Interpolation_module.F90 | 18 +++ .../mesh/atlas_Connectivity_module.F90 | 40 +++++- src/atlas_f/mesh/atlas_ElementType_module.F90 | 17 ++- src/atlas_f/mesh/atlas_Elements_module.F90 | 17 +++ .../mesh/atlas_HybridElements_module.F90 | 18 +++ .../mesh/atlas_MeshGenerator_module.F90 | 17 ++- src/atlas_f/mesh/atlas_Mesh_module.F90 | 17 ++- src/atlas_f/mesh/atlas_mesh_Cells_module.F90 | 17 +++ src/atlas_f/mesh/atlas_mesh_Edges_module.F90 | 17 +++ src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 | 17 +++ .../mesh/atlas_mesh_actions_module.F90 | 2 - src/atlas_f/numerics/atlas_Method_module.F90 | 20 ++- src/atlas_f/numerics/atlas_Nabla_module.F90 | 17 +++ src/atlas_f/numerics/atlas_fvm_module.F90 | 17 +++ src/atlas_f/output/atlas_output_module.F90 | 19 ++- .../parallel/atlas_Checksum_module.F90 | 18 +++ .../parallel/atlas_GatherScatter_module.F90 | 18 ++- .../parallel/atlas_HaloExchange_module.F90 | 18 +++ src/atlas_f/trans/atlas_Trans_module.F90 | 122 ++++++++++-------- src/atlas_f/util/atlas_Config_module.F90 | 16 +++ src/atlas_f/util/atlas_Error_module.F90 | 2 + src/atlas_f/util/atlas_JSON_module.F90 | 2 + src/atlas_f/util/atlas_Metadata_module.F90 | 18 +++ src/atlas_f/util/atlas_kinds_module.F90 | 2 - src/tests/grid/fctest_griddistribution.F90 | 2 + 41 files changed, 705 insertions(+), 160 deletions(-) create mode 100644 src/atlas_f/atlas_f.h.in diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index 8b46cf86e..0bf921b37 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -1,10 +1,6 @@ #ifndef atlas_library_defines_h #define atlas_library_defines_h -#if 0 -// Do not use cmakedefine as this file needs to be included by fortran as well -#endif - #if @CGAL_FOUND@ #define CGAL_FOUND #endif @@ -56,8 +52,4 @@ #define ATLAS_INDEXVIEW_BOUNDS_CHECKING #endif -#define ATLAS_SUPPRESS_UNUSED( X ) \ -associate( unused_ => X ); \ -end associate - #endif \ No newline at end of file diff --git a/src/atlas_f/CMakeLists.txt b/src/atlas_f/CMakeLists.txt index 9b32d970c..00a51bd38 100644 --- a/src/atlas_f/CMakeLists.txt +++ b/src/atlas_f/CMakeLists.txt @@ -1,17 +1,5 @@ -### fortranize function - -function( fortranize file ) - unset( result ) - file( STRINGS "${file}" lines ) - foreach( i IN LISTS lines ) - string( REGEX REPLACE "^/\\* (#undef .*) \\*/$" "! \\1" i "${i}" ) - set( result "${result}${i}\n" ) - endforeach() - file( WRITE "${file}" "${result}" ) -endfunction() - -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../atlas/library/defines.h.in +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/atlas_f.h.in ${CMAKE_CURRENT_BINARY_DIR}/../atlas/atlas_f.h ) install( FILES diff --git a/src/atlas_f/atlas_f.h.in b/src/atlas_f/atlas_f.h.in new file mode 100644 index 000000000..afdde83ec --- /dev/null +++ b/src/atlas_f/atlas_f.h.in @@ -0,0 +1,20 @@ +#ifndef atlas_f_h +#define atlas_f_h + +#include "fckit/defines.h" + +#if @ATLAS_HAVE_OMP@ +#define ATLAS_HAVE_OMP +#endif + +#if @ATLAS_HAVE_TRANS@ +#define ATLAS_HAVE_TRANS +#endif + +#if @ATLAS_HAVE_ACC@ +#define ATLAS_HAVE_ACC +#endif + +#define ATLAS_BITS_GLOBAL @ATLAS_BITS_GLOBAL@ + +#endif \ No newline at end of file diff --git a/src/atlas_f/atlas_module.F90 b/src/atlas_f/atlas_module.F90 index d26b177ce..813317503 100644 --- a/src/atlas_f/atlas_module.F90 +++ b/src/atlas_f/atlas_module.F90 @@ -1,5 +1,3 @@ -! (C) Copyright 2013-2015 ECMWF. - #include "atlas/atlas_f.h" module atlas_module diff --git a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 index 22406992a..2732fc494 100644 --- a/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 +++ b/src/atlas_f/autogenerated/atlas_Field_module_fypp.F90 @@ -274,6 +274,10 @@ module atlas_field_module procedure, private :: dummy +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Field__final_auto +#endif + END TYPE atlas_Field interface atlas_Field @@ -375,7 +379,7 @@ subroutine array_c_to_f_int32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -411,7 +415,7 @@ subroutine array_c_to_f_int64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -447,7 +451,7 @@ subroutine array_c_to_f_real32_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -483,7 +487,7 @@ subroutine array_c_to_f_real64_r1(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -519,7 +523,7 @@ subroutine array_c_to_f_logical32_r1(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(1) integer :: j - if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 1 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -555,7 +559,7 @@ subroutine array_c_to_f_int32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -591,7 +595,7 @@ subroutine array_c_to_f_int64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -627,7 +631,7 @@ subroutine array_c_to_f_real32_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -663,7 +667,7 @@ subroutine array_c_to_f_real64_r2(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -699,7 +703,7 @@ subroutine array_c_to_f_logical32_r2(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(2) integer :: j - if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 2 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -735,7 +739,7 @@ subroutine array_c_to_f_int32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -771,7 +775,7 @@ subroutine array_c_to_f_int64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -807,7 +811,7 @@ subroutine array_c_to_f_real32_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -843,7 +847,7 @@ subroutine array_c_to_f_real64_r3(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -879,7 +883,7 @@ subroutine array_c_to_f_logical32_r3(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(3) integer :: j - if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 3 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -915,7 +919,7 @@ subroutine array_c_to_f_int32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -951,7 +955,7 @@ subroutine array_c_to_f_int64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_f integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -987,7 +991,7 @@ subroutine array_c_to_f_real32_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -1023,7 +1027,7 @@ subroutine array_c_to_f_real64_r4(array_cptr,rank,shape_cptr,strides_cptr,array_ integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -1059,7 +1063,7 @@ subroutine array_c_to_f_logical32_r4(array_cptr,rank,shape_cptr,strides_cptr,arr integer :: eshape(4) integer :: j - if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",174)) + if( rank /= 4 ) call atlas_abort("Rank mismatch",atlas_code_location("atlas_Field_module.F90",178)) call c_f_pointer ( shape_cptr, shape , [rank] ) call c_f_pointer ( strides_cptr, strides , [rank] ) @@ -2223,7 +2227,7 @@ subroutine access_device_data_logical32_r4_shape(this, field, shape) subroutine dummy(this) use atlas_field_c_binding class(atlas_Field), intent(in) :: this - ATLAS_SUPPRESS_UNUSED(this) + FCKIT_SUPPRESS_UNUSED(this) end subroutine !------------------------------------------------------------------------------- @@ -2236,7 +2240,7 @@ integer function atlas_real(kind) else if (kind == c_float) then atlas_real = ATLAS_KIND_REAL32 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",278)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",282)) end if end function @@ -2252,7 +2256,7 @@ integer function atlas_integer(kind) else if (kind == c_long) then atlas_integer = ATLAS_KIND_INT64 else - call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",294)) + call atlas_abort("Unsupported real kind",atlas_code_location("atlas_Field_module.F90",298)) end if end if end function @@ -2262,7 +2266,7 @@ integer function atlas_integer(kind) integer function atlas_logical(kind) integer, optional :: kind atlas_logical = ATLAS_KIND_INT32 - ATLAS_SUPPRESS_UNUSED(kind) + FCKIT_SUPPRESS_UNUSED(kind) end function !------------------------------------------------------------------------------- @@ -2279,7 +2283,7 @@ function atlas_data_type(kind) else if( kind == ATLAS_KIND_REAL64 ) then atlas_data_type = "real64" else - call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",321)) + call atlas_abort("cannot convert kind to data_type",atlas_code_location("atlas_Field_module.F90",325)) endif end function @@ -3119,5 +3123,18 @@ subroutine sync_host_device(this) !------------------------------------------------------------------------------- +subroutine atlas_Field__final_auto(this) + type(atlas_Field) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Field__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + +!------------------------------------------------------------------------------- + end module atlas_field_module diff --git a/src/atlas_f/field/atlas_FieldSet_module.F90 b/src/atlas_f/field/atlas_FieldSet_module.F90 index 1b15cd922..20fe3b816 100644 --- a/src/atlas_f/field/atlas_FieldSet_module.F90 +++ b/src/atlas_f/field/atlas_FieldSet_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_FieldSet_module @@ -11,10 +12,6 @@ module atlas_FieldSet_module private -!----------------------------- -! atlas_Mesh ! -!----------------------------- - !------------------------------------------------------------------------------ TYPE, extends(fckit_owned_object) :: atlas_FieldSet @@ -42,6 +39,10 @@ module atlas_FieldSet_module procedure, private :: field_by_idx_size_t procedure, public :: add generic :: field => field_by_name, field_by_idx_int, field_by_idx_size_t + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_FieldSet__final_auto +#endif END TYPE atlas_FieldSet !------------------------------------------------------------------------------ @@ -145,6 +146,19 @@ function field_by_idx_int(this,idx) result(field) call field%return() end function +!------------------------------------------------------------------------------- + +subroutine atlas_FieldSet__final_auto(this) + type(atlas_FieldSet) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_FieldSet__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ---------------------------------------------------------------------------------------- end module atlas_FieldSet_module diff --git a/src/atlas_f/field/atlas_Field_module.F90 b/src/atlas_f/field/atlas_Field_module.F90 index 9f2a06f58..8c3a925d5 100644 --- a/src/atlas_f/field/atlas_Field_module.F90 +++ b/src/atlas_f/field/atlas_Field_module.F90 @@ -109,6 +109,10 @@ module atlas_field_module procedure, private :: dummy +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Field__final_auto +#endif + END TYPE atlas_Field interface atlas_Field @@ -262,7 +266,7 @@ subroutine access_device_data_${dtype}$_r${rank}$_shape(this, field, shape) subroutine dummy(this) use atlas_field_c_binding class(atlas_Field), intent(in) :: this - ATLAS_SUPPRESS_UNUSED(this) + FCKIT_SUPPRESS_UNUSED(this) end subroutine !------------------------------------------------------------------------------- @@ -301,7 +305,7 @@ integer function atlas_integer(kind) integer function atlas_logical(kind) integer, optional :: kind atlas_logical = ATLAS_KIND_INT32 - ATLAS_SUPPRESS_UNUSED(kind) + FCKIT_SUPPRESS_UNUSED(kind) end function !------------------------------------------------------------------------------- @@ -682,5 +686,18 @@ subroutine sync_host_device(this) !------------------------------------------------------------------------------- +subroutine atlas_Field__final_auto(this) + type(atlas_Field) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Field__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + +!------------------------------------------------------------------------------- + end module atlas_field_module diff --git a/src/atlas_f/field/atlas_State_module.F90 b/src/atlas_f/field/atlas_State_module.F90 index 61e6ce9ac..6df192be7 100644 --- a/src/atlas_f/field/atlas_State_module.F90 +++ b/src/atlas_f/field/atlas_State_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_State_module @@ -55,6 +56,10 @@ module atlas_State_module procedure, private :: field_by_index => atlas_State__field_by_index generic, public :: field => field_by_name, field_by_index procedure, public :: metadata => atlas_State__metadata + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_State__final_auto +#endif END TYPE atlas_State interface atlas_State @@ -161,6 +166,19 @@ function atlas_State__metadata(this) result(metadata) call metadata%reset_c_ptr( atlas__State__metadata(this%c_ptr()) ) end function +!------------------------------------------------------------------------------- + +subroutine atlas_State__final_auto(this) + type(atlas_State) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_State__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ---------------------------------------------------------------------------------------- end module atlas_State_module diff --git a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 index c71cfb289..317549235 100644 --- a/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 +++ b/src/atlas_f/functionspace/atlas_FunctionSpace_module.F90 @@ -48,6 +48,9 @@ module atlas_functionspace_module & deprecated_create_field_1, & & deprecated_create_field_2 +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_FunctionSpace__final_auto +#endif END TYPE atlas_FunctionSpace @@ -195,6 +198,19 @@ function deprecated_create_field_2(this,require_name,kind,levels) result(field) call field%return() end function +!------------------------------------------------------------------------------- + +subroutine atlas_FunctionSpace__final_auto(this) + type(atlas_FunctionSpace) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_FunctionSpace__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + !------------------------------------------------------------------------------ diff --git a/src/atlas_f/functionspace/atlas_functionspace_EdgeColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_EdgeColumns_module.F90 index dc8378191..79da9df52 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_EdgeColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_EdgeColumns_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_functionspace_EdgeColumns_module @@ -73,11 +74,10 @@ module atlas_functionspace_EdgeColumns_module generic, public :: checksum => checksum_field, checksum_fieldset procedure, public :: get_checksum -#ifdef FORTRAN_SUPPORTS_FINAL - final :: atlas_functionspace_EdgeColumns__final +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_functionspace_EdgeColumns__final_auto #endif - END TYPE atlas_functionspace_EdgeColumns interface atlas_functionspace_EdgeColumns @@ -117,15 +117,6 @@ function constructor(mesh,halo,levels) result(this) !------------------------------------------------------------------------------ -#ifdef FORTRAN_SUPPORTS_FINAL -subroutine atlas_functionspace_EdgeColumns__final(this) - type(atlas_functionspace_EdgeColumns), intent(inout) :: this - call this%final() -end subroutine -#endif - -!------------------------------------------------------------------------------ - function nb_edges(this) use atlas_functionspace_EdgeColumns_c_binding integer :: nb_edges @@ -281,6 +272,19 @@ function checksum_field(this,field) result(checksum) if( checksum_allocated == 1 ) call c_ptr_free(checksum_cptr) end function +!------------------------------------------------------------------------------- + +subroutine atlas_functionspace_EdgeColumns__final_auto(this) + type(atlas_functionspace_EdgeColumns) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_functionspace_EdgeColumns__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + !------------------------------------------------------------------------------ end module atlas_functionspace_EdgeColumns_module diff --git a/src/atlas_f/functionspace/atlas_functionspace_NodeColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_NodeColumns_module.F90 index 8599f2806..1cbc9d74d 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_NodeColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_NodeColumns_module.F90 @@ -201,11 +201,10 @@ module atlas_functionspace_NodeColumns_module procedure, public :: mean_and_standard_deviation_per_level => & & mean_and_stddev_per_level -#ifdef FORTRAN_SUPPORTS_FINAL - final :: atlas_functionspace_NodeColumns__final +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_functionspace_NodeColumns__final_auto #endif - END TYPE atlas_functionspace_NodeColumns interface atlas_functionspace_NodeColumns @@ -248,15 +247,6 @@ function constructor(mesh,halo,levels) result(this) !------------------------------------------------------------------------------ -#ifdef FORTRAN_SUPPORTS_FINAL -subroutine atlas_functionspace_NodeColumns__final(this) - type(atlas_functionspace_NodeColumns), intent(inout) :: this - call this%final() -end subroutine -#endif - -!------------------------------------------------------------------------------ - function nb_nodes(this) use atlas_functionspace_NodeColumns_c_binding integer :: nb_nodes @@ -1950,6 +1940,19 @@ subroutine mean_and_stddev_per_level(this,field,mean,stddev,N) if( present(N) ) N = opt_N end subroutine +!------------------------------------------------------------------------------- + +subroutine atlas_functionspace_NodeColumns__final_auto(this) + type(atlas_functionspace_NodeColumns) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_functionspace_NodeColumns__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + !------------------------------------------------------------------------------ end module atlas_functionspace_NodeColumns_module diff --git a/src/atlas_f/functionspace/atlas_functionspace_Spectral_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_Spectral_module.F90 index 0220f3e52..ff71373be 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_Spectral_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_Spectral_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_functionspace_Spectral_module @@ -52,8 +53,8 @@ module atlas_functionspace_Spectral_module procedure, private :: norm_array generic, public :: norm => norm_scalar, norm_array -#ifdef FORTRAN_SUPPORTS_FINAL - final :: atlas_functionspace_Spectral__final +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_functionspace_Spectral__final_auto #endif END TYPE atlas_functionspace_Spectral @@ -77,14 +78,6 @@ function atlas_functionspace_Spectral__cptr(cptr) result(this) call this%return() end function - -#ifdef FORTRAN_SUPPORTS_FINAL -subroutine atlas_functionspace_Spectral__final(this) - type(atlas_functionspace_Spectral), intent(inout) :: this - call this%final() -end subroutine -#endif - function atlas_functionspace_Spectral__config(truncation,levels) result(this) use atlas_functionspace_spectral_c_binding type(atlas_functionspace_Spectral) :: this @@ -180,5 +173,18 @@ subroutine norm_array(this,field,norm,rank) call atlas__SpectralFunctionSpace__norm(this%c_ptr(),field%c_ptr(),norm,opt_rank) end subroutine +!------------------------------------------------------------------------------- + +subroutine atlas_functionspace_Spectral__final_auto(this) + type(atlas_functionspace_Spectral) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_functionspace_Spectral__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + end module atlas_functionspace_Spectral_module diff --git a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 index 93ac3a76b..90068f801 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 @@ -73,6 +73,10 @@ module atlas_functionspace_StructuredColumns_module procedure, private :: set_index +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_functionspace_StructuredColumns__final_auto +#endif + END TYPE atlas_functionspace_StructuredColumns interface atlas_functionspace_StructuredColumns @@ -91,7 +95,7 @@ subroutine assignment_operator_hook(this,other) class(atlas_functionspace_StructuredColumns) :: this class(fckit_owned_object) :: other call this%set_index() - ATLAS_SUPPRESS_UNUSED(other) + FCKIT_SUPPRESS_UNUSED(other) end subroutine function StructuredColumns__cptr(cptr) result(this) @@ -294,6 +298,18 @@ subroutine halo_exchange_field(this,field) call atlas__fs__StructuredColumns__halo_exchange_field(this%c_ptr(),field%c_ptr()) end subroutine +!------------------------------------------------------------------------------- + +subroutine atlas_functionspace_StructuredColumns__final_auto(this) + type(atlas_functionspace_StructuredColumns) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_functionspace_StructuredColumns__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine end module atlas_functionspace_StructuredColumns_module diff --git a/src/atlas_f/grid/atlas_GridDistribution_module.F90 b/src/atlas_f/grid/atlas_GridDistribution_module.F90 index 344255fae..8b8e533e8 100644 --- a/src/atlas_f/grid/atlas_GridDistribution_module.F90 +++ b/src/atlas_f/grid/atlas_GridDistribution_module.F90 @@ -1,4 +1,4 @@ -#include "fckit/defines.h" +#include "atlas/atlas_f.h" module atlas_GridDistribution_module @@ -77,6 +77,9 @@ function atlas_GridDistribution__ctor( part, part0 ) result(this) subroutine atlas_GridDistribution__final_auto(this) type(atlas_GridDistribution) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_GridDistribution__final_auto" +#endif #if FCKIT_FINAL_NOT_PROPAGATING call this%final() #endif diff --git a/src/atlas_f/grid/atlas_Grid_module.F90 b/src/atlas_f/grid/atlas_Grid_module.F90 index 7864db9eb..fd85904dc 100644 --- a/src/atlas_f/grid/atlas_Grid_module.F90 +++ b/src/atlas_f/grid/atlas_Grid_module.F90 @@ -1,5 +1,4 @@ - -#include "fckit/defines.h" +#include "atlas/atlas_f.h" module atlas_Grid_module @@ -86,6 +85,11 @@ module atlas_Grid_module procedure, private :: lonlat_64 => Structured__lonlat_64 generic :: lonlat => lonlat_32, lonlat_64 procedure :: reduced => Structured__reduced + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_StructuredGrid__final_auto +#endif + END TYPE atlas_StructuredGrid interface atlas_StructuredGrid @@ -112,6 +116,11 @@ module atlas_Grid_module !------------------------------------------------------------------------------ contains procedure :: N => Gaussian__N + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_GaussianGrid__final_auto +#endif + END TYPE atlas_GaussianGrid interface atlas_GaussianGrid @@ -137,6 +146,11 @@ module atlas_Grid_module !------------------------------------------------------------------------------ contains procedure :: N => ReducedGaussian__N + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_ReducedGaussianGrid__final_auto +#endif + END TYPE atlas_ReducedGaussianGrid interface atlas_ReducedGaussianGrid @@ -162,6 +176,11 @@ module atlas_Grid_module !------------------------------------------------------------------------------ contains procedure :: N => RegularGaussian__N + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_RegularGaussianGrid__final_auto +#endif + END TYPE atlas_RegularGaussianGrid interface atlas_RegularGaussianGrid @@ -186,6 +205,9 @@ module atlas_Grid_module !------------------------------------------------------------------------------ contains +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_RegularLonLatGrid__final_auto +#endif END TYPE atlas_RegularLonLatGrid interface atlas_RegularLonLatGrid @@ -230,6 +252,47 @@ subroutine atlas_Grid__final_auto(this) FCKIT_SUPPRESS_UNUSED( this ) end subroutine +subroutine atlas_StructuredGrid__final_auto(this) + type(atlas_StructuredGrid) :: this +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + +subroutine atlas_GaussianGrid__final_auto(this) + type(atlas_GaussianGrid) :: this +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + +subroutine atlas_ReducedGaussianGrid__final_auto(this) + type(atlas_ReducedGaussianGrid) :: this +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + +subroutine atlas_RegularLonLatGrid__final_auto(this) + type(atlas_RegularLonLatGrid) :: this +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + +subroutine atlas_RegularGaussianGrid__final_auto(this) + type(atlas_RegularGaussianGrid) :: this +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + + ! ----------------------------------------------------------------------------- ! Constructors diff --git a/src/atlas_f/grid/atlas_Partitioner_module.F90 b/src/atlas_f/grid/atlas_Partitioner_module.F90 index 049e527cf..ebd629f34 100644 --- a/src/atlas_f/grid/atlas_Partitioner_module.F90 +++ b/src/atlas_f/grid/atlas_Partitioner_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_Partitioner_module @@ -35,6 +36,10 @@ module atlas_Partitioner_module contains procedure, public :: partition +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Partitioner__final_auto +#endif + END TYPE atlas_Partitioner !------------------------------------------------------------------------------ @@ -91,6 +96,19 @@ function partition(this,grid) result(distribution) call distribution%return() end function +!------------------------------------------------------------------------------- + +subroutine atlas_Partitioner__final_auto(this) + type(atlas_Partitioner) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Partitioner__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ---------------------------------------------------------------------------------------- end module atlas_Partitioner_module diff --git a/src/atlas_f/interpolation/atlas_Interpolation_module.F90 b/src/atlas_f/interpolation/atlas_Interpolation_module.F90 index a5dc37f8a..4faa90f01 100644 --- a/src/atlas_f/interpolation/atlas_Interpolation_module.F90 +++ b/src/atlas_f/interpolation/atlas_Interpolation_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_Interpolation_module @@ -31,6 +32,10 @@ module atlas_Interpolation_module procedure, private :: execute_fieldset generic, public :: execute => execute_field, execute_fieldset +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Interpolation__final_auto +#endif + END TYPE atlas_Interpolation interface atlas_Interpolation @@ -79,6 +84,19 @@ subroutine execute_fieldset(this,source,target) call atlas__Interpolation__execute_fieldset(this%c_ptr(),source%c_ptr(),target%c_ptr()) end subroutine +!------------------------------------------------------------------------------- + +subroutine atlas_Interpolation__final_auto(this) + type(atlas_Interpolation) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Interpolation__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ----------------------------------------------------------------------------- end module atlas_Interpolation_module diff --git a/src/atlas_f/mesh/atlas_Connectivity_module.F90 b/src/atlas_f/mesh/atlas_Connectivity_module.F90 index 57692472d..c3b477694 100644 --- a/src/atlas_f/mesh/atlas_Connectivity_module.F90 +++ b/src/atlas_f/mesh/atlas_Connectivity_module.F90 @@ -53,6 +53,11 @@ module atlas_connectivity_module procedure, private :: add_missing_args_int => atlas_Connectivity__add_missing_args_int procedure, private :: add_missing_args_size_t => atlas_Connectivity__add_missing_args_size_t generic, public :: add => add_values_args_int, add_values_args_size_t, add_missing_args_int, add_missing_args_size_t + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Connectivity__final_auto +#endif + end type !--------------------------------------- @@ -68,6 +73,10 @@ module atlas_connectivity_module ! PGI compiler bug won't accept "assignment_operator_hook" from atlas_Connectivity parent class... grrr procedure, public :: assignment_operator_hook => atlas_MultiBlockConnectivity__assignment_operator_hook +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_MultiBlockConnectivity__final_auto +#endif + end type !----------------------------! @@ -156,7 +165,7 @@ subroutine assignment_operator_hook(this,other) class(atlas_Connectivity) :: this class(fckit_owned_object) :: other call this%set_access() - ATLAS_SUPPRESS_UNUSED(other) + FCKIT_SUPPRESS_UNUSED(other) end subroutine ! Following routine is exact copy of "assignment_operator_hook" above, because of bug in PGI compiler (17.7) @@ -166,7 +175,7 @@ subroutine atlas_MultiBlockConnectivity__assignment_operator_hook(this,other) class(atlas_MultiBlockConnectivity) :: this class(fckit_owned_object) :: other call this%set_access() - ATLAS_SUPPRESS_UNUSED(other) + FCKIT_SUPPRESS_UNUSED(other) end subroutine function Connectivity_cptr(cptr) result(this) @@ -539,6 +548,33 @@ subroutine delete_access(this) if( associated( this%padded_) ) deallocate(this%padded_) end subroutine +!------------------------------------------------------------------------------- + +subroutine atlas_Connectivity__final_auto(this) + type(atlas_Connectivity) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Connectivity__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + +!------------------------------------------------------------------------------- + +subroutine atlas_MultiBlockConnectivity__final_auto(this) + type(atlas_MultiBlockConnectivity) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_MultiBlockConnectivity__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + +!------------------------------------------------------------------------------- end module atlas_connectivity_module diff --git a/src/atlas_f/mesh/atlas_ElementType_module.F90 b/src/atlas_f/mesh/atlas_ElementType_module.F90 index b215ef3ce..d7582d213 100644 --- a/src/atlas_f/mesh/atlas_ElementType_module.F90 +++ b/src/atlas_f/mesh/atlas_ElementType_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_ElementType_module @@ -26,7 +27,9 @@ module atlas_ElementType_module procedure, public :: nb_edges procedure, public :: name procedure, public :: parametric - +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_ElementType__final_auto +#endif end type interface atlas_ElementType @@ -120,6 +123,18 @@ function parametric(this) endif end function +!------------------------------------------------------------------------------- + +subroutine atlas_ElementType__final_auto(this) + type(atlas_ElementType) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_ElementType__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine end module atlas_ElementType_module diff --git a/src/atlas_f/mesh/atlas_Elements_module.F90 b/src/atlas_f/mesh/atlas_Elements_module.F90 index 9ac479996..56468caea 100644 --- a/src/atlas_f/mesh/atlas_Elements_module.F90 +++ b/src/atlas_f/mesh/atlas_Elements_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_Elements_module @@ -45,6 +46,9 @@ module atlas_Elements_module procedure, private :: add_elements_size_t procedure, private :: add_elements_int +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Elements__final_auto +#endif end type interface atlas_Elements @@ -234,4 +238,17 @@ function atlas_Elements__end(this) result(val) val = atlas__mesh__Elements__end(this%c_ptr()) end function +!------------------------------------------------------------------------------- + +subroutine atlas_Elements__final_auto(this) + type(atlas_Elements) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Elements__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + end module atlas_Elements_module diff --git a/src/atlas_f/mesh/atlas_HybridElements_module.F90 b/src/atlas_f/mesh/atlas_HybridElements_module.F90 index 0f336f46c..b445f2b84 100644 --- a/src/atlas_f/mesh/atlas_HybridElements_module.F90 +++ b/src/atlas_f/mesh/atlas_HybridElements_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_HybridElements_module @@ -59,6 +60,10 @@ module atlas_HybridElements_module procedure, private :: elements_int procedure, private :: elements_size_t +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_HybridElements__final_auto +#endif + end type interface atlas_HybridElements @@ -260,5 +265,18 @@ function elements_int(this,idx) result(elements) call elements%return() end function +!------------------------------------------------------------------------------- + +subroutine atlas_HybridElements__final_auto(this) + type(atlas_HybridElements) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_HybridElements__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + end module atlas_HybridElements_module diff --git a/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 b/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 index 272b42fcd..289661d25 100644 --- a/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 +++ b/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_MeshGenerator_module @@ -20,6 +21,10 @@ module atlas_MeshGenerator_module TYPE, extends(fckit_owned_object) :: atlas_MeshGenerator contains procedure, public :: generate => atlas_MeshGenerator__generate +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_MeshGenerator__final_auto +#endif + END TYPE atlas_MeshGenerator interface atlas_MeshGenerator @@ -80,8 +85,18 @@ function atlas_MeshGenerator__generate(this,grid,distribution) result(mesh) call mesh%return() end function +!------------------------------------------------------------------------------- -! ----------------------------------------------------------------------------- +subroutine atlas_MeshGenerator__final_auto(this) + type(atlas_MeshGenerator) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_MeshGenerator__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/mesh/atlas_Mesh_module.F90 b/src/atlas_f/mesh/atlas_Mesh_module.F90 index f51af496e..027033744 100644 --- a/src/atlas_f/mesh/atlas_Mesh_module.F90 +++ b/src/atlas_f/mesh/atlas_Mesh_module.F90 @@ -1,4 +1,3 @@ - #include "atlas/atlas_f.h" module atlas_Mesh_module @@ -42,6 +41,9 @@ module atlas_Mesh_module procedure, public :: clone_from_device procedure, public :: sync_host_device +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Mesh__final_auto +#endif END TYPE atlas_Mesh interface atlas_Mesh @@ -140,4 +142,17 @@ subroutine sync_host_device(this) !------------------------------------------------------------------------------- +subroutine atlas_Mesh__final_auto(this) + type(atlas_Mesh) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Mesh__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + +!------------------------------------------------------------------------------- + end module atlas_Mesh_module diff --git a/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 b/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 index a4737a950..b9c32ce98 100644 --- a/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_mesh_cells_module @@ -13,6 +14,9 @@ module atlas_mesh_cells_module type, extends(atlas_HybridElements) :: atlas_mesh_cells contains +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_mesh_Cells__final_auto +#endif end type interface atlas_mesh_cells @@ -40,6 +44,19 @@ function atlas_mesh_cells__constructor() result(this) call this%return() end function +!------------------------------------------------------------------------------- + +subroutine atlas_mesh_Cells__final_auto(this) + type(atlas_mesh_Cells) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_mesh_Cells__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ---------------------------------------------------------------------------------------- end module atlas_mesh_cells_module diff --git a/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 b/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 index 25cdf01b3..f3a78f518 100644 --- a/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_mesh_Edges_module @@ -13,6 +14,9 @@ module atlas_mesh_Edges_module type, extends(atlas_HybridElements) :: atlas_mesh_Edges contains +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_mesh_Edges__final_auto +#endif end type interface atlas_mesh_Edges @@ -40,6 +44,19 @@ function atlas_mesh_edges__constructor() result(this) call this%return() end function +!------------------------------------------------------------------------------- + +subroutine atlas_mesh_Edges__final_auto(this) + type(atlas_mesh_Edges) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_mesh_Edges__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ---------------------------------------------------------------------------------------- end module atlas_mesh_Edges_module diff --git a/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 b/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 index 4a94611db..61c198de3 100644 --- a/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_mesh_Nodes_module @@ -47,6 +48,10 @@ module atlas_mesh_Nodes_module procedure, public :: cell_connectivity procedure, public :: connectivity + +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_mesh_Nodes__final_auto +#endif end type interface atlas_mesh_Nodes @@ -278,6 +283,18 @@ function str(this) call c_ptr_free(str_cptr) end function +!------------------------------------------------------------------------------- + +subroutine atlas_mesh_Nodes__final_auto(this) + type(atlas_mesh_Nodes) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_mesh_Nodes__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/mesh/atlas_mesh_actions_module.F90 b/src/atlas_f/mesh/atlas_mesh_actions_module.F90 index 7ac8efe6b..a99016f31 100644 --- a/src/atlas_f/mesh/atlas_mesh_actions_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_actions_module.F90 @@ -1,5 +1,3 @@ -! (C) Copyright 2013-2015 ECMWF. - #include "atlas/atlas_f.h" module atlas_mesh_actions_module diff --git a/src/atlas_f/numerics/atlas_Method_module.F90 b/src/atlas_f/numerics/atlas_Method_module.F90 index cdf4d2915..d218fd3e7 100644 --- a/src/atlas_f/numerics/atlas_Method_module.F90 +++ b/src/atlas_f/numerics/atlas_Method_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_Method_module @@ -31,10 +32,9 @@ module atlas_Method_module !------------------------------------------------------------------------------ contains procedure, public :: name => atlas_Method__name -#ifdef FORTRAN_SUPPORTS_FINAL - final :: atlas_Method__final +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Method__final_auto #endif - END TYPE atlas_Method interface atlas_Method @@ -64,5 +64,19 @@ function atlas_Method__name(this) result(name) name = c_ptr_to_string(name_c_str) end function +!------------------------------------------------------------------------------- + +subroutine atlas_Method__final_auto(this) + type(atlas_Method) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Method__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + + end module atlas_Method_module diff --git a/src/atlas_f/numerics/atlas_Nabla_module.F90 b/src/atlas_f/numerics/atlas_Nabla_module.F90 index b7cc6377c..3f34c1845 100644 --- a/src/atlas_f/numerics/atlas_Nabla_module.F90 +++ b/src/atlas_f/numerics/atlas_Nabla_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_Nabla_module @@ -32,6 +33,9 @@ module atlas_Nabla_module procedure, public :: curl => atlas_Nabla__curl procedure, public :: laplacian => atlas_Nabla__laplacian +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Nabla__final_auto +#endif END TYPE atlas_Nabla interface atlas_Nabla @@ -106,6 +110,19 @@ subroutine atlas_Nabla__laplacian(this,scalar,lapl) call atlas__Nabla__laplacian(this%c_ptr(),scalar%c_ptr(),lapl%c_ptr()) end subroutine +!------------------------------------------------------------------------------- + +subroutine atlas_Nabla__final_auto(this) + type(atlas_Nabla) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Nabla__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ----------------------------------------------------------------------------- end module atlas_Nabla_module diff --git a/src/atlas_f/numerics/atlas_fvm_module.F90 b/src/atlas_f/numerics/atlas_fvm_module.F90 index 293fa674e..4c1ae680b 100644 --- a/src/atlas_f/numerics/atlas_fvm_module.F90 +++ b/src/atlas_f/numerics/atlas_fvm_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_fvm_module @@ -35,6 +36,10 @@ module atlas_fvm_module procedure, public :: node_columns procedure, public :: edge_columns +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_fvm_Method__final_auto +#endif + END TYPE atlas_fvm_Method interface atlas_fvm_Method @@ -91,6 +96,18 @@ function edge_columns(this) call edge_columns%return() end function +!------------------------------------------------------------------------------- + +subroutine atlas_fvm_Method__final_auto(this) + type(atlas_fvm_Method) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_fvm_Method__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine end module atlas_fvm_module diff --git a/src/atlas_f/output/atlas_output_module.F90 b/src/atlas_f/output/atlas_output_module.F90 index 67d7e7f34..28e461277 100644 --- a/src/atlas_f/output/atlas_output_module.F90 +++ b/src/atlas_f/output/atlas_output_module.F90 @@ -1,5 +1,3 @@ -! (C) Copyright 2013-2016 ECMWF. - #include "atlas/atlas_f.h" module atlas_output_module @@ -45,6 +43,10 @@ module atlas_output_module & write_field, & & write_fieldset +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Output__final_auto +#endif + END TYPE atlas_Output interface atlas_Output @@ -177,4 +179,17 @@ subroutine write_fieldset(this,fieldset,config) endif end subroutine +!------------------------------------------------------------------------------- + +subroutine atlas_Output__final_auto(this) + type(atlas_Output) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Output__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + end module atlas_output_module diff --git a/src/atlas_f/parallel/atlas_Checksum_module.F90 b/src/atlas_f/parallel/atlas_Checksum_module.F90 index 5aa2b68dd..24dbfb583 100644 --- a/src/atlas_f/parallel/atlas_Checksum_module.F90 +++ b/src/atlas_f/parallel/atlas_Checksum_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_checksum_module @@ -61,6 +62,10 @@ module atlas_checksum_module procedure, public :: delete => atlas_Checksum__delete +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Checksum__final_auto +#endif + END TYPE atlas_Checksum !------------------------------------------------------------------------------ @@ -249,6 +254,19 @@ function Checksum__execute_real64_r3(this, loc_field_data) result(checksum) checksum = c_str_to_string(checksum_c_str) end function Checksum__execute_real64_r3 +!------------------------------------------------------------------------------- + +subroutine atlas_Checksum__final_auto(this) + type(atlas_Checksum) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Checksum__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ----------------------------------------------------------------------------- end module atlas_checksum_module diff --git a/src/atlas_f/parallel/atlas_GatherScatter_module.F90 b/src/atlas_f/parallel/atlas_GatherScatter_module.F90 index 2c20b7f11..21cbc9ce1 100644 --- a/src/atlas_f/parallel/atlas_GatherScatter_module.F90 +++ b/src/atlas_f/parallel/atlas_GatherScatter_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_gatherscatter_module @@ -86,6 +87,10 @@ module atlas_gatherscatter_module procedure, public :: delete => atlas_GatherScatter__delete +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_GatherScatter__final_auto +#endif + END TYPE atlas_GatherScatter !------------------------------------------------------------------------------ @@ -602,8 +607,19 @@ subroutine GatherScatter__scatter_real64_r3_r3(this, glb_field_data, loc_field_d & lview, lstrides, lextents, lrank ) end subroutine GatherScatter__scatter_real64_r3_r3 +!------------------------------------------------------------------------------- + +subroutine atlas_GatherScatter__final_auto(this) + type(atlas_GatherScatter) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_GatherScatter__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine ! ----------------------------------------------------------------------------- end module atlas_gatherscatter_module - diff --git a/src/atlas_f/parallel/atlas_HaloExchange_module.F90 b/src/atlas_f/parallel/atlas_HaloExchange_module.F90 index 7d9d76d9c..9555a19c1 100644 --- a/src/atlas_f/parallel/atlas_HaloExchange_module.F90 +++ b/src/atlas_f/parallel/atlas_HaloExchange_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_haloexchange_module @@ -66,6 +67,10 @@ module atlas_haloexchange_module procedure, public :: delete => atlas_HaloExchange__delete +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_HaloExchange__final_auto +#endif + END TYPE atlas_HaloExchange !------------------------------------------------------------------------------ @@ -273,6 +278,19 @@ subroutine HaloExchange__execute_real64_r4(this, field_data) & strides, extents, rank ) end subroutine HaloExchange__execute_real64_r4 +!------------------------------------------------------------------------------- + +subroutine atlas_HaloExchange__final_auto(this) + type(atlas_HaloExchange) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_HaloExchange__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + ! ----------------------------------------------------------------------------- end module atlas_haloexchange_module diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index 104ce9717..ff0c0e92e 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -1,4 +1,3 @@ - #include "atlas/atlas_f.h" module atlas_Trans_module @@ -71,6 +70,10 @@ module atlas_Trans_module procedure, private :: specnorm_r2 generic, public :: specnorm => specnorm_r1_scalar, specnorm_r2 +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Trans__final_auto +#endif + END TYPE atlas_Trans !------------------------------------------------------------------------------ @@ -119,8 +122,8 @@ function atlas_Trans__ctor( grid, nsmax ) result(this) #else ! IGNORE call this%reset_c_ptr( c_null_ptr ) - ATLAS_SUPPRESS_UNUSED( grid ) - ATLAS_SUPPRESS_UNUSED( nsmax ) + FCKIT_SUPPRESS_UNUSED( grid ) + FCKIT_SUPPRESS_UNUSED( nsmax ) #endif call this%return() end function atlas_Trans__ctor @@ -134,7 +137,7 @@ function handle( this ) #else THROW_ERROR handle = 0 - ATLAS_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( this ) #endif end function @@ -147,7 +150,7 @@ function truncation( this ) #else THROW_ERROR truncation = 0 - ATLAS_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( this ) #endif end function @@ -160,7 +163,7 @@ function nb_spectral_coefficients( this ) #else THROW_ERROR nb_spectral_coefficients = 0 - ATLAS_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( this ) #endif end function @@ -173,7 +176,7 @@ function nb_spectral_coefficients_global( this ) #else THROW_ERROR nb_spectral_coefficients_global = 0 - ATLAS_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( this ) #endif end function @@ -186,7 +189,7 @@ function nb_gridpoints( this ) #else THROW_ERROR nb_gridpoints = 0 - ATLAS_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( this ) #endif end function @@ -199,7 +202,7 @@ function nb_gridpoints_global( this ) #else THROW_ERROR nb_gridpoints_global = 0 - ATLAS_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( this ) #endif end function @@ -212,8 +215,8 @@ function grid( this ) call grid%return() #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( grid ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( grid ) #endif end function @@ -243,10 +246,10 @@ subroutine dirtrans_fieldset(this, gpfields, spfields, config) endif #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( gpfields ) - ATLAS_SUPPRESS_UNUSED( spfields ) - ATLAS_SUPPRESS_UNUSED( config ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( gpfields ) + FCKIT_SUPPRESS_UNUSED( spfields ) + FCKIT_SUPPRESS_UNUSED( config ) #endif end subroutine dirtrans_fieldset @@ -276,10 +279,10 @@ subroutine invtrans_fieldset(this, spfields, gpfields, config) endif #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( spfields ) - ATLAS_SUPPRESS_UNUSED( gpfields ) - ATLAS_SUPPRESS_UNUSED( config ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( spfields ) + FCKIT_SUPPRESS_UNUSED( gpfields ) + FCKIT_SUPPRESS_UNUSED( config ) #endif end subroutine invtrans_fieldset @@ -308,10 +311,10 @@ subroutine dirtrans_field(this, gpfield, spfield, config) endif #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( gpfield ) - ATLAS_SUPPRESS_UNUSED( spfield ) - ATLAS_SUPPRESS_UNUSED( config ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( gpfield ) + FCKIT_SUPPRESS_UNUSED( spfield ) + FCKIT_SUPPRESS_UNUSED( config ) #endif end subroutine dirtrans_field @@ -342,11 +345,11 @@ subroutine dirtrans_wind2vordiv_field(this, gpwind, spvor, spdiv, config) endif #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( gpwind ) - ATLAS_SUPPRESS_UNUSED( spvor ) - ATLAS_SUPPRESS_UNUSED( spdiv ) - ATLAS_SUPPRESS_UNUSED( config ) + 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 @@ -377,10 +380,10 @@ subroutine invtrans_field(this, spfield, gpfield, config) endif #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( spfield ) - ATLAS_SUPPRESS_UNUSED( gpfield ) - ATLAS_SUPPRESS_UNUSED( config ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( spfield ) + FCKIT_SUPPRESS_UNUSED( gpfield ) + FCKIT_SUPPRESS_UNUSED( config ) #endif end subroutine invtrans_field @@ -412,11 +415,11 @@ subroutine invtrans_vordiv2wind_field(this, spvor, spdiv, gpwind, config) endif #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( spvor ) - ATLAS_SUPPRESS_UNUSED( spdiv ) - ATLAS_SUPPRESS_UNUSED( gpwind ) - ATLAS_SUPPRESS_UNUSED( config ) + 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 @@ -437,9 +440,9 @@ subroutine invtrans_grad_field(this, spfield, gpfield) call config%final() #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( spfield ) - ATLAS_SUPPRESS_UNUSED( gpfield ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( spfield ) + FCKIT_SUPPRESS_UNUSED( gpfield ) #endif end subroutine invtrans_grad_field @@ -455,9 +458,9 @@ subroutine gathspec_r1(this, local, global) call atlas__Trans__gathspec(this%c_ptr(), 1, (/1/), local, global ) #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( local ) - ATLAS_SUPPRESS_UNUSED( global ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( local ) + FCKIT_SUPPRESS_UNUSED( global ) #endif end subroutine gathspec_r1 @@ -477,9 +480,9 @@ subroutine gathspec_r2(this, local, global) call atlas__Trans__gathspec(this%c_ptr(), size(local,1), destination, local_view, global_view ) #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( local ) - ATLAS_SUPPRESS_UNUSED( global ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( local ) + FCKIT_SUPPRESS_UNUSED( global ) #endif end subroutine gathspec_r2 @@ -501,9 +504,9 @@ subroutine specnorm_r1_scalar(this, spectra, norm, rank) #else norm=0 THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( spectra ) - ATLAS_SUPPRESS_UNUSED( rank ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( spectra ) + FCKIT_SUPPRESS_UNUSED( rank ) #endif end subroutine @@ -524,11 +527,24 @@ subroutine specnorm_r2(this, spectra, norm, rank) call atlas__Trans__specnorm(this%c_ptr(), size(spectra,1), spectra_view, norm, rank_opt ) #else THROW_ERROR - ATLAS_SUPPRESS_UNUSED( this ) - ATLAS_SUPPRESS_UNUSED( spectra ) - ATLAS_SUPPRESS_UNUSED( norm ) - ATLAS_SUPPRESS_UNUSED( rank ) + FCKIT_SUPPRESS_UNUSED( this ) + FCKIT_SUPPRESS_UNUSED( spectra ) + FCKIT_SUPPRESS_UNUSED( norm ) + FCKIT_SUPPRESS_UNUSED( rank ) +#endif +end subroutine + +!------------------------------------------------------------------------------- + +subroutine atlas_Trans__final_auto(this) + type(atlas_Trans) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Trans__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() #endif + FCKIT_SUPPRESS_UNUSED( this ) end subroutine ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/util/atlas_Config_module.F90 b/src/atlas_f/util/atlas_Config_module.F90 index 13f196fd8..d95481e2c 100644 --- a/src/atlas_f/util/atlas_Config_module.F90 +++ b/src/atlas_f/util/atlas_Config_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_config_module @@ -57,6 +58,10 @@ module atlas_config_module get_string, get_array_int32, get_array_int64, get_array_real32, get_array_real64 procedure :: json => atlas_Config__json +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Config__final_auto +#endif + END TYPE atlas_Config !------------------------------------------------------------------------------ @@ -81,6 +86,17 @@ module atlas_config_module ! ----------------------------------------------------------------------------- ! Config routines +subroutine atlas_Config__final_auto(this) + type(atlas_Config), intent(inout) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Config__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + function atlas_Config__ctor() result(this) use atlas_Config_c_binding type(atlas_Config) :: this diff --git a/src/atlas_f/util/atlas_Error_module.F90 b/src/atlas_f/util/atlas_Error_module.F90 index bfa9e7689..a59096507 100644 --- a/src/atlas_f/util/atlas_Error_module.F90 +++ b/src/atlas_f/util/atlas_Error_module.F90 @@ -1,3 +1,5 @@ +#include "fckit/defines.h" +#include "atlas/atlas_f.h" module atlas_Error_module diff --git a/src/atlas_f/util/atlas_JSON_module.F90 b/src/atlas_f/util/atlas_JSON_module.F90 index e5b427250..4b9cde563 100644 --- a/src/atlas_f/util/atlas_JSON_module.F90 +++ b/src/atlas_f/util/atlas_JSON_module.F90 @@ -1,3 +1,5 @@ +#include "fckit/defines.h" +#include "atlas/atlas_f.h" module atlas_JSON_module diff --git a/src/atlas_f/util/atlas_Metadata_module.F90 b/src/atlas_f/util/atlas_Metadata_module.F90 index a7d394442..8310dfc44 100644 --- a/src/atlas_f/util/atlas_Metadata_module.F90 +++ b/src/atlas_f/util/atlas_Metadata_module.F90 @@ -1,3 +1,4 @@ +#include "atlas/atlas_f.h" module atlas_metadata_module @@ -62,6 +63,10 @@ module atlas_metadata_module procedure, public :: delete => atlas_Metadata__delete +#if FCKIT_FINAL_NOT_INHERITING + final :: atlas_Metadata__final_auto +#endif + END TYPE atlas_Metadata !------------------------------------------------------------------------------ @@ -362,5 +367,18 @@ function Metadata__json(this) result(json) if( json_allocated == 1 ) call c_ptr_free(json_cptr) end function Metadata__json +!------------------------------------------------------------------------------- + +subroutine atlas_Metadata__final_auto(this) + type(atlas_Metadata) :: this +#if FCKIT_FINAL_DEBUGGING + write(0,*) "atlas_Metadata__final_auto" +#endif +#if FCKIT_FINAL_NOT_PROPAGATING + call this%final() +#endif + FCKIT_SUPPRESS_UNUSED( this ) +end subroutine + end module atlas_metadata_module diff --git a/src/atlas_f/util/atlas_kinds_module.F90 b/src/atlas_f/util/atlas_kinds_module.F90 index 95cf8e79b..821939d83 100644 --- a/src/atlas_f/util/atlas_kinds_module.F90 +++ b/src/atlas_f/util/atlas_kinds_module.F90 @@ -1,5 +1,3 @@ -! (C) Copyright 2013-2015 ECMWF. - #include "atlas/atlas_f.h" module atlas_kinds_module diff --git a/src/tests/grid/fctest_griddistribution.F90 b/src/tests/grid/fctest_griddistribution.F90 index 274b973f5..852f2cdd8 100644 --- a/src/tests/grid/fctest_griddistribution.F90 +++ b/src/tests/grid/fctest_griddistribution.F90 @@ -83,6 +83,8 @@ meshgenerator = atlas_MeshGenerator() mesh = meshgenerator%generate(grid,griddistribution) + FCTEST_CHECK_EQUAL( mesh%owners(), 1 ) + call griddistribution%final() FCTEST_CHECK_EQUAL( grid%owners(), 2 ) From 7468e0b33cf38cc9de3eb9affc1d580046da7bb0 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 9 Jan 2018 12:15:53 +0000 Subject: [PATCH 234/355] Rename fckit/defines.h to fckit/fckit.h --- src/atlas_f/atlas_f.h.in | 2 +- src/atlas_f/util/atlas_Error_module.F90 | 1 - src/atlas_f/util/atlas_JSON_module.F90 | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/atlas_f/atlas_f.h.in b/src/atlas_f/atlas_f.h.in index afdde83ec..2c26875ba 100644 --- a/src/atlas_f/atlas_f.h.in +++ b/src/atlas_f/atlas_f.h.in @@ -1,7 +1,7 @@ #ifndef atlas_f_h #define atlas_f_h -#include "fckit/defines.h" +#include "fckit/fckit.h" #if @ATLAS_HAVE_OMP@ #define ATLAS_HAVE_OMP diff --git a/src/atlas_f/util/atlas_Error_module.F90 b/src/atlas_f/util/atlas_Error_module.F90 index a59096507..4daa7a0e4 100644 --- a/src/atlas_f/util/atlas_Error_module.F90 +++ b/src/atlas_f/util/atlas_Error_module.F90 @@ -1,4 +1,3 @@ -#include "fckit/defines.h" #include "atlas/atlas_f.h" module atlas_Error_module diff --git a/src/atlas_f/util/atlas_JSON_module.F90 b/src/atlas_f/util/atlas_JSON_module.F90 index 4b9cde563..6b03183b7 100644 --- a/src/atlas_f/util/atlas_JSON_module.F90 +++ b/src/atlas_f/util/atlas_JSON_module.F90 @@ -1,4 +1,3 @@ -#include "fckit/defines.h" #include "atlas/atlas_f.h" module atlas_JSON_module From a2a77167fabe5283720a2a888039d6c84217d868 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 11 Jan 2018 10:26:18 +0000 Subject: [PATCH 235/355] FINAL-4 cosmetics --- src/atlas/util/Metadata.cc | 59 +++++++++++++++---- .../grid/atlas_GridDistribution_module.F90 | 11 +++- src/atlas_f/grid/atlas_Grid_module.F90 | 12 ++-- src/atlas_f/mesh/atlas_Mesh_module.F90 | 14 +++-- src/atlas_f/mesh/atlas_mesh_Cells_module.F90 | 3 +- src/atlas_f/mesh/atlas_mesh_Edges_module.F90 | 2 +- src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 | 30 +++------- src/atlas_f/output/atlas_output_module.F90 | 3 +- src/atlas_f/util/atlas_Metadata_module.F90 | 7 ++- src/tests/util/fctest_metadata.F90 | 5 +- 10 files changed, 93 insertions(+), 53 deletions(-) diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index 9a131921f..3443f7ef2 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -165,27 +165,43 @@ void atlas__Metadata__delete (Metadata* This) { void atlas__Metadata__set_int (Metadata* This, const char* name, int value) { - ATLAS_ERROR_HANDLING( This->set( std::string(name), long(value) ) ); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + This->set( std::string(name), long(value) ) + ); } void atlas__Metadata__set_long (Metadata* This, const char* name, long value) { - ATLAS_ERROR_HANDLING( This->set( std::string(name), value ) ); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + This->set( std::string(name), value ); + ); } void atlas__Metadata__set_float (Metadata* This, const char* name, float value) { - ATLAS_ERROR_HANDLING( This->set( std::string(name), double(value) ) ); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + This->set( std::string(name), double(value) ); + ); } void atlas__Metadata__set_double (Metadata* This, const char* name, double value) { - ATLAS_ERROR_HANDLING( This->set( std::string(name), value ) ); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + This->set( std::string(name), value ); + ); } void atlas__Metadata__set_string (Metadata* This, const char* name, const char* value) { - ATLAS_ERROR_HANDLING( This->set( std::string(name), std::string(value) ) ); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + This->set( std::string(name), std::string(value) ); + ); } void atlas__Metadata__set_array_int (Metadata* This, const char* name, int value[], int size) { ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); std::vector v; v.assign(value,value+size); This->set( std::string(name), v ); @@ -194,6 +210,7 @@ void atlas__Metadata__set_array_int (Metadata* This, const char* name, int value void atlas__Metadata__set_array_long (Metadata* This, const char* name, long value[], int size) { ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); std::vector v; v.assign(value,value+size); This->set( std::string(name), v ); @@ -202,6 +219,7 @@ void atlas__Metadata__set_array_long (Metadata* This, const char* name, long val void atlas__Metadata__set_array_float (Metadata* This, const char* name, float value[], int size) { ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); std::vector v; v.assign(value,value+size); This->set( std::string(name), v ); @@ -210,6 +228,7 @@ void atlas__Metadata__set_array_float (Metadata* This, const char* name, float v void atlas__Metadata__set_array_double (Metadata* This, const char* name, double value[], int size) { ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); std::vector v; v.assign(value,value+size); This->set( std::string(name), v ); @@ -217,27 +236,40 @@ void atlas__Metadata__set_array_double (Metadata* This, const char* name, double } int atlas__Metadata__get_int (Metadata* This, const char* name) { - ATLAS_ERROR_HANDLING( return This->get( std::string(name) ) ); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + return This->get( std::string(name) ) + ); return 0; } long atlas__Metadata__get_long (Metadata* This, const char* name) { - ATLAS_ERROR_HANDLING( return This->get( std::string(name) ) ); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + return This->get( std::string(name) ); + ); return 0; } float atlas__Metadata__get_float (Metadata* This, const char* name) { - ATLAS_ERROR_HANDLING( return This->get( std::string(name) ) ); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + return This->get( std::string(name) ); + ); return 0; } double atlas__Metadata__get_double (Metadata* This, const char* name) { - ATLAS_ERROR_HANDLING( return This->get( std::string(name) ) ); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + return This->get( std::string(name) ); + ); return 0; } void atlas__Metadata__get_string( Metadata* This, const char* name, char* output_str, int max_len ) { ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); std::string s = This->get( std::string(name) ); if(s.size() > size_t(max_len)) { @@ -254,6 +286,7 @@ void atlas__Metadata__get_string( Metadata* This, const char* name, char* output void atlas__Metadata__get_array_int (Metadata* This, const char* name, int* &value, int& size, int& allocated) { ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); std::vector v = This->get< std::vector >( std::string(name ) ); size = v.size(); value = new int[size]; @@ -264,6 +297,7 @@ void atlas__Metadata__get_array_int (Metadata* This, const char* name, int* &val void atlas__Metadata__get_array_long (Metadata* This, const char* name, long* &value, int& size, int& allocated) { ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); std::vector v = This->get< std::vector >( std::string(name ) ); size = v.size(); value = new long[size]; @@ -274,6 +308,7 @@ void atlas__Metadata__get_array_long (Metadata* This, const char* name, long* &v void atlas__Metadata__get_array_float (Metadata* This, const char* name, float* &value, int& size, int& allocated) { ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); std::vector v = This->get< std::vector >( std::string(name ) ); size = v.size(); value = new float[size]; @@ -284,6 +319,7 @@ void atlas__Metadata__get_array_float (Metadata* This, const char* name, float* void atlas__Metadata__get_array_double (Metadata* This, const char* name, double* &value, int& size, int& allocated) { ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); std::vector v = This->get< std::vector >( std::string(name ) ); size = v.size(); value = new double[size]; @@ -294,7 +330,10 @@ void atlas__Metadata__get_array_double (Metadata* This, const char* name, double int atlas__Metadata__has (Metadata* This, const char* name) { - ATLAS_ERROR_HANDLING( return This->has( std::string(name) )); + ATLAS_ERROR_HANDLING( + ASSERT( This != NULL ); + return This->has( std::string(name) ); + ); return 0; } diff --git a/src/atlas_f/grid/atlas_GridDistribution_module.F90 b/src/atlas_f/grid/atlas_GridDistribution_module.F90 index 8b8e533e8..881c792f5 100644 --- a/src/atlas_f/grid/atlas_GridDistribution_module.F90 +++ b/src/atlas_f/grid/atlas_GridDistribution_module.F90 @@ -3,11 +3,10 @@ module atlas_GridDistribution_module use fckit_owned_object_module, only: fckit_owned_object +use, intrinsic :: iso_c_binding, only : c_ptr implicit none -private :: fckit_owned_object - public :: atlas_GridDistribution private @@ -45,6 +44,9 @@ module atlas_GridDistribution_module module procedure atlas_GridDistribution__ctor end interface +private :: c_ptr +private :: fckit_owned_object + !======================================================== contains !======================================================== @@ -52,12 +54,13 @@ module atlas_GridDistribution_module ! GridDistribution routines function atlas_GridDistribution__cptr( cptr ) result(this) - use, intrinsic :: iso_c_binding, only : c_ptr use atlas_distribution_c_binding type(atlas_GridDistribution) :: this type(c_ptr) :: cptr +write(0,*) "atlas_GridDistribution__cptr" call this%reset_c_ptr( cptr ) call this%return() +write(0,*) "atlas_GridDistribution__cptr done" end function function atlas_GridDistribution__ctor( part, part0 ) result(this) @@ -66,11 +69,13 @@ function atlas_GridDistribution__ctor( part, part0 ) result(this) integer, intent(in) :: part(:) integer, intent(in), optional :: part0 integer:: npts, opt_part0 + write(0,*) "atlas_GridDistribution__ctor" opt_part0 = 0 if( present(part0) ) opt_part0 = part0 npts = size(part) call this%reset_c_ptr( atlas__GridDistribution__new(npts, part, opt_part0) ) call this%return() + write(0,*) "atlas_GridDistribution__ctor done" end function ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/grid/atlas_Grid_module.F90 b/src/atlas_f/grid/atlas_Grid_module.F90 index fd85904dc..1db0f1cab 100644 --- a/src/atlas_f/grid/atlas_Grid_module.F90 +++ b/src/atlas_f/grid/atlas_Grid_module.F90 @@ -3,10 +3,14 @@ module atlas_Grid_module use fckit_owned_object_module, only: fckit_owned_object +use atlas_Config_module, only: atlas_Config +use, intrinsic :: iso_c_binding, only : c_ptr implicit none private :: fckit_owned_object +private :: atlas_Config +private :: c_ptr public :: atlas_Grid public :: atlas_StructuredGrid @@ -308,7 +312,6 @@ function atlas_Grid__ctor_id(identifier) result(this) function atlas_Grid__ctor_config(config) result(this) use atlas_grid_Structured_c_binding - use atlas_Config_module, only: atlas_Config type(atlas_Grid) :: this type(atlas_Config), intent(in) :: config call this%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()) ) @@ -317,7 +320,6 @@ function atlas_Grid__ctor_config(config) result(this) function atlas_Grid__ctor_cptr(cptr) result(this) use fckit_c_interop_module, only: c_str - use, intrinsic :: iso_c_binding, only : c_ptr use atlas_grid_Structured_c_binding type(atlas_Grid) :: this type(c_ptr), intent(in) :: cptr @@ -338,7 +340,6 @@ function atlas_StructuredGrid__ctor_id(identifier) result(this) function atlas_StructuredGrid__ctor_config(config) result(this) use atlas_grid_Structured_c_binding - use atlas_Config_module, only: atlas_Config type(atlas_StructuredGrid) :: this type(atlas_Config), intent(in) :: config call this%reset_c_ptr( atlas__grid__Structured__config(config%c_ptr()) ) @@ -347,7 +348,6 @@ function atlas_StructuredGrid__ctor_config(config) result(this) function atlas_StructuredGrid__ctor_cptr(cptr) result(this) use fckit_c_interop_module, only: c_str - use, intrinsic :: iso_c_binding, only : c_ptr use atlas_grid_Structured_c_binding type(atlas_StructuredGrid) :: this type(c_ptr), intent(in) :: cptr @@ -503,7 +503,7 @@ function Structured__reduced(this) result(reduced) function Structured__nx_array(this) result(nx) use atlas_grid_Structured_c_binding - use, intrinsic :: iso_c_binding , only : c_long, c_ptr, c_size_t, c_f_pointer + use, intrinsic :: iso_c_binding , only : c_long, c_size_t, c_f_pointer class(atlas_StructuredGrid), intent(in) :: this integer(c_long), pointer :: nx(:) type (c_ptr) :: nx_c_ptr @@ -557,7 +557,7 @@ function Structured__y_64(this, j) result(y) function Structured__y_array(this) result(y) use atlas_grid_Structured_c_binding - use, intrinsic :: iso_c_binding , only : c_double, c_ptr, c_size_t, c_f_pointer + use, intrinsic :: iso_c_binding , only : c_double, c_size_t, c_f_pointer class(atlas_StructuredGrid), intent(in) :: this real (c_double) , pointer :: y(:) type (c_ptr) :: y_c_ptr diff --git a/src/atlas_f/mesh/atlas_Mesh_module.F90 b/src/atlas_f/mesh/atlas_Mesh_module.F90 index 027033744..81c1bcaf6 100644 --- a/src/atlas_f/mesh/atlas_Mesh_module.F90 +++ b/src/atlas_f/mesh/atlas_Mesh_module.F90 @@ -3,10 +3,19 @@ module atlas_Mesh_module use fckit_owned_object_module, only: fckit_owned_object +use atlas_mesh_Cells_module, only: atlas_mesh_Cells +use atlas_mesh_Nodes_module, only: atlas_mesh_Nodes +use atlas_mesh_Edges_module, only: atlas_mesh_Edges +use, intrinsic :: iso_c_binding, only : c_size_t, c_ptr implicit none private :: fckit_owned_object +private :: atlas_mesh_Cells +private :: atlas_mesh_Nodes +private :: atlas_mesh_Edges +private :: c_size_t +private :: c_ptr public :: atlas_Mesh @@ -56,7 +65,6 @@ module atlas_Mesh_module !======================================================== function atlas_Mesh__cptr(cptr) result(this) - use, intrinsic :: iso_c_binding, only: c_ptr use atlas_mesh_c_binding type(atlas_Mesh) :: this type(c_ptr), intent(in) :: cptr @@ -77,7 +85,6 @@ end function atlas_Mesh__ctor function Mesh__nodes(this) result(nodes) use atlas_mesh_c_binding - use atlas_mesh_Nodes_module, only: atlas_mesh_Nodes class(atlas_Mesh), intent(in) :: this type(atlas_mesh_Nodes) :: nodes nodes = atlas_mesh_Nodes( atlas__Mesh__nodes(this%c_ptr()) ) @@ -88,7 +95,6 @@ function Mesh__nodes(this) result(nodes) function Mesh__cells(this) result(cells) use atlas_mesh_c_binding - use atlas_mesh_Cells_module, only: atlas_mesh_Cells class(atlas_Mesh), intent(in) :: this type(atlas_mesh_Cells) :: cells cells = atlas_mesh_Cells( atlas__Mesh__cells(this%c_ptr()) ) @@ -99,7 +105,6 @@ function Mesh__cells(this) result(cells) function Mesh__edges(this) result(edges) use atlas_mesh_c_binding - use atlas_mesh_Edges_module, only: atlas_mesh_Edges class(atlas_Mesh), intent(in) :: this type(atlas_mesh_Edges) :: edges edges = atlas_mesh_Edges( atlas__Mesh__Edges(this%c_ptr()) ) @@ -109,7 +114,6 @@ function Mesh__edges(this) result(edges) !------------------------------------------------------------------------------- function footprint(this) - use, intrinsic :: iso_c_binding, only : c_size_t use atlas_mesh_c_binding integer(c_size_t) :: footprint class(atlas_Mesh) :: this diff --git a/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 b/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 index b9c32ce98..0b1308aee 100644 --- a/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_Cells_module.F90 @@ -2,11 +2,13 @@ module atlas_mesh_cells_module +use, intrinsic :: iso_c_binding, only: c_ptr use atlas_HybridElements_module, only: atlas_HybridElements implicit none private :: atlas_HybridElements +private :: c_ptr public :: atlas_mesh_cells @@ -30,7 +32,6 @@ module atlas_mesh_cells_module function atlas_mesh_cells__cptr(cptr) result(this) use atlas_hybridelements_c_binding - use, intrinsic :: iso_c_binding, only: c_ptr type(atlas_mesh_cells) :: this type(c_ptr), intent(in) :: cptr call this%reset_c_ptr( cptr ) diff --git a/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 b/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 index f3a78f518..2b4f3f92d 100644 --- a/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_Edges_module.F90 @@ -2,6 +2,7 @@ module atlas_mesh_Edges_module +use, intrinsic :: iso_c_binding, only: c_ptr use atlas_HybridElements_module, only: atlas_HybridElements implicit none @@ -29,7 +30,6 @@ module atlas_mesh_Edges_module !======================================================== function atlas_mesh_edges__cptr(cptr) result(this) - use, intrinsic :: iso_c_binding, only: c_ptr use atlas_hybridelements_c_binding type(atlas_mesh_Edges) :: this type(c_ptr), intent(in) :: cptr diff --git a/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 b/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 index 61c198de3..92a752693 100644 --- a/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 +++ b/src/atlas_f/mesh/atlas_mesh_Nodes_module.F90 @@ -2,12 +2,19 @@ module atlas_mesh_Nodes_module +use, intrinsic :: iso_c_binding, only: c_ptr, c_size_t, c_int use fckit_owned_object_module, only: fckit_owned_object +use atlas_Metadata_module, only: atlas_Metadata +use atlas_Field_module, only: atlas_Field +use atlas_Connectivity_module, only: atlas_Connectivity implicit none private :: fckit_owned_object - +private :: c_ptr, c_size_t, c_int +private :: atlas_Metadata +private :: atlas_Field +private :: atlas_Connectivity public :: atlas_mesh_Nodes private @@ -64,7 +71,6 @@ module atlas_mesh_Nodes_module !======================================================== function atlas_mesh_Nodes__cptr(cptr) result(this) - use, intrinsic :: iso_c_binding, only : c_ptr use atlas_nodes_c_binding type(atlas_mesh_Nodes) :: this type(c_ptr), intent(in) :: cptr @@ -80,7 +86,6 @@ function atlas_mesh_Nodes__constructor() result(this) end function function atlas_mesh_Nodes__size(this) result(val) - use, intrinsic :: iso_c_binding, only: c_size_t use atlas_nodes_c_binding integer(c_size_t) :: val class(atlas_mesh_Nodes), intent(in) :: this @@ -99,7 +104,6 @@ function edge_connectivity(this) result(connectivity) function cell_connectivity(this) result(connectivity) use atlas_nodes_c_binding - use atlas_Connectivity_module, only: atlas_Connectivity class(atlas_mesh_Nodes), intent(in) :: this type(atlas_Connectivity) :: connectivity connectivity = atlas_Connectivity( & @@ -110,7 +114,6 @@ function cell_connectivity(this) result(connectivity) function connectivity(this,name) use atlas_nodes_c_binding use fckit_c_interop_module, only: c_str - use atlas_Connectivity_module, only: atlas_Connectivity type(atlas_Connectivity) :: connectivity class(atlas_mesh_Nodes), intent(in) :: this character(len=*), intent(in) :: name @@ -121,7 +124,6 @@ function connectivity(this,name) subroutine add_connectivity(this,connectivity) use atlas_nodes_c_binding - use atlas_Connectivity_module, only: atlas_Connectivity class(atlas_mesh_Nodes), intent(inout) :: this type(atlas_Connectivity), intent(in) :: connectivity call atlas__mesh__Nodes__add_connectivity(this%c_ptr(), connectivity%c_ptr()) @@ -130,7 +132,6 @@ subroutine add_connectivity(this,connectivity) subroutine add_field(this,field) use atlas_nodes_c_binding - use atlas_Field_module, only: atlas_Field class(atlas_mesh_Nodes), intent(inout) :: this type(atlas_Field), intent(in) :: field call atlas__mesh__Nodes__add_field(this%c_ptr(), field%c_ptr()) @@ -146,7 +147,6 @@ subroutine remove_field(this,name) function nb_fields(this) result(val) use atlas_nodes_c_binding - use, intrinsic :: iso_c_binding, only: c_size_t integer(c_size_t) :: val class(atlas_mesh_Nodes), intent(in) :: this val = atlas__mesh__Nodes__nb_fields(this%c_ptr()) @@ -168,7 +168,6 @@ function has_field(this,name) result(val) function field_by_name(this,name) result(field) use atlas_nodes_c_binding use fckit_c_interop_module, only: c_str - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_mesh_Nodes), intent(in) :: this character(len=*), intent(in) :: name @@ -178,8 +177,6 @@ function field_by_name(this,name) result(field) function field_by_idx_size_t(this,idx) result(field) use atlas_nodes_c_binding - use, intrinsic :: iso_c_binding, only: c_size_t - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_mesh_Nodes), intent(in) :: this integer(c_size_t), intent(in) :: idx @@ -190,7 +187,6 @@ function field_by_idx_size_t(this,idx) result(field) function field_by_idx_int(this,idx) result(field) use atlas_nodes_c_binding use, intrinsic :: iso_c_binding, only: c_size_t, c_int - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_mesh_Nodes), intent(in) :: this integer(c_int), intent(in) :: idx @@ -200,7 +196,6 @@ function field_by_idx_int(this,idx) result(field) function xy(this) result(field) use atlas_nodes_c_binding - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_mesh_Nodes), intent(in) :: this field = atlas_Field( atlas__mesh__Nodes__xy(this%c_ptr()) ) @@ -209,7 +204,6 @@ function xy(this) result(field) function lonlat(this) result(field) use atlas_nodes_c_binding - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_mesh_Nodes), intent(in) :: this field = atlas_Field( atlas__mesh__Nodes__lonlat(this%c_ptr()) ) @@ -218,7 +212,6 @@ function lonlat(this) result(field) function global_index(this) result(field) use atlas_nodes_c_binding - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_mesh_Nodes), intent(in) :: this field = atlas_Field( atlas__mesh__Nodes__global_index(this%c_ptr()) ) @@ -227,7 +220,6 @@ function global_index(this) result(field) function remote_index(this) result(field) use atlas_nodes_c_binding - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_mesh_Nodes), intent(in) :: this field = atlas_Field( atlas__mesh__Nodes__remote_index(this%c_ptr()) ) @@ -236,7 +228,6 @@ function remote_index(this) result(field) function partition(this) result(field) use atlas_nodes_c_binding - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_mesh_Nodes), intent(in) :: this field = atlas_Field( atlas__mesh__Nodes__partition(this%c_ptr()) ) @@ -245,7 +236,6 @@ function partition(this) result(field) function ghost(this) result(field) use atlas_nodes_c_binding - use atlas_Field_module, only: atlas_Field type(atlas_Field) :: field class(atlas_mesh_Nodes), intent(in) :: this field = atlas_Field( atlas__mesh__Nodes__ghost(this%c_ptr()) ) @@ -254,7 +244,6 @@ function ghost(this) result(field) function metadata(this) use atlas_nodes_c_binding - use atlas_Metadata_module, only: atlas_Metadata type(atlas_Metadata) :: metadata class(atlas_mesh_Nodes), intent(in) :: this call metadata%reset_c_ptr( atlas__mesh__Nodes__metadata(this%c_ptr()) ) @@ -262,7 +251,6 @@ function metadata(this) subroutine resize(this,size) use atlas_nodes_c_binding - use, intrinsic :: iso_c_binding, only: c_size_t class(atlas_mesh_Nodes), intent(in) :: this integer(c_size_t), intent(in) :: size call atlas__mesh__Nodes__resize(this%c_ptr(),size) @@ -271,8 +259,6 @@ subroutine resize(this,size) function str(this) use atlas_nodes_c_binding use fckit_c_interop_module, only: c_ptr_to_string, c_ptr_free - - use, intrinsic :: iso_c_binding, only: c_ptr, c_int character(len=:), allocatable :: str class(atlas_mesh_Nodes), intent(in) :: this type(c_ptr) :: str_cptr diff --git a/src/atlas_f/output/atlas_output_module.F90 b/src/atlas_f/output/atlas_output_module.F90 index 28e461277..df39c101c 100644 --- a/src/atlas_f/output/atlas_output_module.F90 +++ b/src/atlas_f/output/atlas_output_module.F90 @@ -8,6 +8,7 @@ module atlas_output_module use atlas_FieldSet_module, only: atlas_FieldSet use atlas_Field_module, only: atlas_Field use atlas_Mesh_module, only: atlas_Mesh + use, intrinsic :: iso_c_binding, only : c_ptr implicit none @@ -65,13 +66,13 @@ module atlas_output_module private :: atlas_FieldSet private :: atlas_Field private :: atlas_Mesh +private :: c_ptr ! ============================================================================= CONTAINS ! ============================================================================= function atlas_Output__cptr(cptr) result(this) - use, intrinsic :: iso_c_binding, only : c_ptr type(atlas_Output) :: this type(c_ptr), intent(in) :: cptr call this%reset_c_ptr( cptr ) diff --git a/src/atlas_f/util/atlas_Metadata_module.F90 b/src/atlas_f/util/atlas_Metadata_module.F90 index 8310dfc44..69b0a60c9 100644 --- a/src/atlas_f/util/atlas_Metadata_module.F90 +++ b/src/atlas_f/util/atlas_Metadata_module.F90 @@ -86,10 +86,11 @@ module atlas_metadata_module ! ----------------------------------------------------------------------------- ! Metadata routines -function atlas_Metadata__ctor() result(metadata) +function atlas_Metadata__ctor() result(this) use atlas_metadata_c_binding - type(atlas_Metadata) :: metadata - call metadata%reset_c_ptr( atlas__Metadata__new() ) + use fckit_c_interop_module + type(atlas_Metadata) :: this + call this%reset_c_ptr( atlas__Metadata__new() ) end function atlas_Metadata__ctor subroutine atlas_Metadata__delete(this) diff --git a/src/tests/util/fctest_metadata.F90 b/src/tests/util/fctest_metadata.F90 index bd53fa2af..df31ac073 100644 --- a/src/tests/util/fctest_metadata.F90 +++ b/src/tests/util/fctest_metadata.F90 @@ -40,6 +40,7 @@ end module fcta_Metadata_fixture TEST( test_metadata ) use fckit_log_module +use fckit_c_interop_module implicit none integer(c_int) :: intval @@ -49,13 +50,15 @@ end module fcta_Metadata_fixture character(len=:), allocatable :: string integer(c_int), allocatable :: arr_int32(:) real(c_float), allocatable :: arr_real32(:) - type(atlas_Metadata) metadata + type(atlas_Metadata) :: metadata type(fckit_logchannel) :: info write(*,*) "test_metadata starting" metadata = atlas_Metadata() + write(0,*) "metadata%c_ptr() = ", c_ptr_to_loc(metadata%c_ptr()) + call metadata%set("true",.True.) call metadata%set("false",.False.) call metadata%set("int",20) From e8992196712baeb881442adc6c6ae3a0df5a1716 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jan 2018 12:08:05 +0000 Subject: [PATCH 236/355] ATLAS-141 Fix static linking --- src/atlas/grid/detail/grid/Gaussian.cc | 12 +++++++++- src/atlas/grid/detail/grid/GridBuilder.cc | 11 ++++++++++ src/atlas/grid/detail/grid/LonLat.cc | 22 +++++++++++++++++++ src/atlas/grid/detail/grid/Regional.cc | 16 ++++++++++++++ .../interpolation/method/FiniteElement.h | 7 +----- .../interpolation/method/KNearestNeighbours.h | 7 +----- src/atlas/interpolation/method/Method.cc | 18 +++++++++++++++ .../interpolation/method/NearestNeighbour.h | 7 +----- src/atlas/interpolation/method/PointIndex3.h | 7 +----- src/atlas_f/CMakeLists.txt | 1 - 10 files changed, 82 insertions(+), 26 deletions(-) diff --git a/src/atlas/grid/detail/grid/Gaussian.cc b/src/atlas/grid/detail/grid/Gaussian.cc index 983b4917a..08062bb47 100644 --- a/src/atlas/grid/detail/grid/Gaussian.cc +++ b/src/atlas/grid/detail/grid/Gaussian.cc @@ -96,6 +96,8 @@ static class classic_gaussian : public GridBuilder { return new StructuredGrid::grid_t( "N"+std::to_string(N), xspace(nx) , yspace(config), projection(config), domain(config) ); } + void force_link() {} + } classic_gaussian_; //--------------------------------------------------------------------------------------------------------------------- @@ -139,6 +141,8 @@ static class octahedral_gaussian : GridBuilder { return new StructuredGrid::grid_t( "O"+std::to_string(N), xspace(nx) , yspace(config), projection(config), domain(config) ); } + void force_link() {} + } octahedral_gaussian_; //--------------------------------------------------------------------------------------------------------------------- @@ -173,10 +177,10 @@ static class regular_gaussian : GridBuilder { return new StructuredGrid::grid_t( "F"+std::to_string(N), xspace(nx) , yspace(config), projection(config), domain(config) ); } + void force_link() {} } regular_gaussian_; - //--------------------------------------------------------------------------------------------------------------------- } // anonymous namespace @@ -184,6 +188,12 @@ static class regular_gaussian : GridBuilder { namespace detail { namespace grid { +void force_link_Gaussian() { + regular_gaussian_.force_link(); + classic_gaussian_.force_link(); + octahedral_gaussian_.force_link(); +} + StructuredGrid::grid_t* reduced_gaussian( const std::vector& nx ) { Grid::Config yspace; diff --git a/src/atlas/grid/detail/grid/GridBuilder.cc b/src/atlas/grid/detail/grid/GridBuilder.cc index 50fb2c4c4..4730af652 100644 --- a/src/atlas/grid/detail/grid/GridBuilder.cc +++ b/src/atlas/grid/detail/grid/GridBuilder.cc @@ -111,7 +111,18 @@ static void init() { //--------------------------------------------------------------------------------------------------------------------- +namespace detail { +namespace grid { +void force_link_Gaussian(); +void force_link_LonLat(); +void force_link_Regional(); +} +} + const GridBuilder::Registry& GridBuilder::nameRegistry() { + detail::grid::force_link_Gaussian(); + detail::grid::force_link_LonLat(); + detail::grid::force_link_Regional(); return *named_grids; } diff --git a/src/atlas/grid/detail/grid/LonLat.cc b/src/atlas/grid/detail/grid/LonLat.cc index 3c15b9483..3b561717f 100644 --- a/src/atlas/grid/detail/grid/LonLat.cc +++ b/src/atlas/grid/detail/grid/LonLat.cc @@ -147,6 +147,8 @@ static class regular_lonlat : public GridBuilder { return create_lonlat( config, Shift(false,false) ); } + void force_link() {} + } regular_lonlat_; //--------------------------------------------------------------------------------------------------------------------- @@ -190,6 +192,8 @@ static class shifted_lonlat : public GridBuilder { return create_lonlat( config, Shift(true,true) ); } + void force_link() {} + } shifted_lonlat_; //--------------------------------------------------------------------------------------------------------------------- @@ -233,6 +237,8 @@ static class shifted_lon : public GridBuilder { return create_lonlat( config, Shift(true,false) ); } + void force_link() {} + } shifted_lon_; @@ -277,10 +283,26 @@ static class shifted_lat : public GridBuilder { return create_lonlat( config, Shift(false,true) ); } + void force_link() {} + } shifted_lat_; //--------------------------------------------------------------------------------------------------------------------- } // anonymous namespace + +namespace detail { +namespace grid { + +void force_link_LonLat() { + regular_lonlat_.force_link(); + shifted_lonlat_.force_link(); + shifted_lon_.force_link(); + shifted_lat_.force_link(); +} + +} +} + } // namespace grid } // namespace atlas diff --git a/src/atlas/grid/detail/grid/Regional.cc b/src/atlas/grid/detail/grid/Regional.cc index 4156d6545..7d109d95c 100644 --- a/src/atlas/grid/detail/grid/Regional.cc +++ b/src/atlas/grid/detail/grid/Regional.cc @@ -238,6 +238,8 @@ static class regional : public GridBuilder { } + void force_link() {} + } regional_; @@ -288,11 +290,25 @@ static class zonal_band : public GridBuilder { } + void force_link() {} + } zonal_band_; } // anonymous + +namespace detail { +namespace grid { + +void force_link_Regional() { + regional_.force_link(); + zonal_band_.force_link(); +} + +} +} + } // namespace grid } // namespace atlas diff --git a/src/atlas/interpolation/method/FiniteElement.h b/src/atlas/interpolation/method/FiniteElement.h index f5c94e358..02b9fc414 100644 --- a/src/atlas/interpolation/method/FiniteElement.h +++ b/src/atlas/interpolation/method/FiniteElement.h @@ -8,9 +8,7 @@ * does it submit to any jurisdiction. */ - -#ifndef atlas_interpolation_method_FiniteElement_h -#define atlas_interpolation_method_FiniteElement_h +#pragma once #include "atlas/interpolation/method/Method.h" @@ -74,6 +72,3 @@ class FiniteElement : public Method { } // method } // interpolation } // atlas - - -#endif diff --git a/src/atlas/interpolation/method/KNearestNeighbours.h b/src/atlas/interpolation/method/KNearestNeighbours.h index b7285a517..fb514c856 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.h +++ b/src/atlas/interpolation/method/KNearestNeighbours.h @@ -8,9 +8,7 @@ * does it submit to any jurisdiction. */ - -#ifndef atlas_interpolation_method_KNearestNeighbours_h -#define atlas_interpolation_method_KNearestNeighbours_h +#pragma once #include "atlas/interpolation/method/KNearestNeighboursBase.h" @@ -44,6 +42,3 @@ class KNearestNeighbours : public KNearestNeighboursBase { } // method } // interpolation } // atlas - - -#endif diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index 19d88842f..099b97475 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -24,6 +24,11 @@ #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" +// for static linking +#include "FiniteElement.h" +#include "KNearestNeighbours.h" +#include "NearestNeighbour.h" + namespace atlas { namespace interpolation { @@ -41,6 +46,17 @@ static void init() { m = new MethodFactoryMap_t(); } +template void load_builder() { MethodBuilder("tmp"); } + +struct force_link { + force_link() + { + load_builder(); + load_builder(); + load_builder(); + } +}; + } // (anonymous namespace) @@ -69,6 +85,8 @@ Method* MethodFactory::build(const std::string& name, const Method::Config& conf pthread_once(&once, init); eckit::AutoLock lock(local_mutex); + force_link(); + MethodFactoryMap_t::const_iterator j = m->find(name); if (j == m->end()) { eckit::Log::error() << "MethodFactory '" << name << "' not found." << std::endl; diff --git a/src/atlas/interpolation/method/NearestNeighbour.h b/src/atlas/interpolation/method/NearestNeighbour.h index 9e87e74c4..b50e23ea0 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.h +++ b/src/atlas/interpolation/method/NearestNeighbour.h @@ -8,9 +8,7 @@ * does it submit to any jurisdiction. */ - -#ifndef atlas_interpolation_method_NearestNeighbour_h -#define atlas_interpolation_method_NearestNeighbour_h +#pragma once #include "atlas/interpolation/method/KNearestNeighboursBase.h" @@ -42,6 +40,3 @@ class NearestNeighbour : public KNearestNeighboursBase { } // method } // interpolation } // atlas - - -#endif diff --git a/src/atlas/interpolation/method/PointIndex3.h b/src/atlas/interpolation/method/PointIndex3.h index 12cb72450..e79175fc9 100644 --- a/src/atlas/interpolation/method/PointIndex3.h +++ b/src/atlas/interpolation/method/PointIndex3.h @@ -8,9 +8,7 @@ * does it submit to any jurisdiction. */ - -#ifndef atlas_interpolation_method_PointIndex3_h -#define atlas_interpolation_method_PointIndex3_h +#pragma once #include "eckit/container/KDMapped.h" #include "eckit/container/KDMemory.h" @@ -79,6 +77,3 @@ ElemIndex3* create_element_centre_index(const Mesh& mesh); } // namespace method } // namespace interpolation } // namespace atlas - - -#endif diff --git a/src/atlas_f/CMakeLists.txt b/src/atlas_f/CMakeLists.txt index 00a51bd38..adb1b1f43 100644 --- a/src/atlas_f/CMakeLists.txt +++ b/src/atlas_f/CMakeLists.txt @@ -159,7 +159,6 @@ preprocess_fypp( atlas_f_src field/atlas_Field_module.F90 ) ## gridtools_storage_files ## add_custom_target( pre_processed_files SOURCES field/atlas_Field_module.F90 ) - ecbuild_debug_var( atlas_f_src ) ### atlas fortran lib From 6532dd37a627c3f654d71a7366bd6507aba5ab14 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 12 Jan 2018 16:49:34 +0000 Subject: [PATCH 237/355] Require fckit 0.5 --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1296d3457..754f750e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,8 @@ ecbuild_find_python() ecbuild_add_option( FEATURE FORTRAN DESCRIPTION "Provide Fortran bindings" - REQUIRED_PACKAGES "PROJECT fckit VERSION 0.4" ) + REQUIRED_PACKAGES "PROJECT fckit VERSION 0.5" ) + if( ATLAS_HAVE_FORTRAN ) if( FCKIT_HAVE_ECKIT ) From fc8336a4380a0a865e4525e0cbee3760e4a2adc8 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 12 Jan 2018 19:03:41 +0000 Subject: [PATCH 238/355] Move atlas::mesh::detail::Polygon to atlas::util::Polygon, split atlas::mesh::detail::PolygonCoordinates into atlas::util::LonLatPolygon and atlas::util::SphericalPolygon --- src/atlas/CMakeLists.txt | 10 +- .../MatchingMeshPartitionerLonLatPolygon.cc | 6 +- ...MatchingMeshPartitionerSphericalPolygon.cc | 6 +- src/atlas/mesh/PartitionPolygon.cc | 10 +- src/atlas/mesh/PartitionPolygon.h | 4 +- src/atlas/mesh/detail/PartitionGraph.cc | 2 +- src/atlas/mesh/detail/PolygonCoordinates.cc | 201 ------------------ src/atlas/mesh/detail/PolygonCoordinates.h | 83 -------- src/atlas/{mesh/detail => util}/Polygon.cc | 0 src/atlas/{mesh/detail => util}/Polygon.h | 47 +++- src/tests/mesh/CMakeLists.txt | 2 +- src/tests/util/CMakeLists.txt | 24 +-- src/tests/{mesh => util}/test_polygon.cc | 14 +- 13 files changed, 77 insertions(+), 332 deletions(-) delete mode 100644 src/atlas/mesh/detail/PolygonCoordinates.cc delete mode 100644 src/atlas/mesh/detail/PolygonCoordinates.h rename src/atlas/{mesh/detail => util}/Polygon.cc (100%) rename src/atlas/{mesh/detail => util}/Polygon.h (67%) rename src/tests/{mesh => util}/test_polygon.cc (92%) diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index b4a409ee0..03d1be02f 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -226,10 +226,6 @@ mesh/detail/MeshIntf.cc mesh/detail/MeshIntf.h mesh/detail/PartitionGraph.cc mesh/detail/PartitionGraph.h -mesh/detail/Polygon.cc -mesh/detail/Polygon.h -mesh/detail/PolygonCoordinates.cc -mesh/detail/PolygonCoordinates.h mesh/actions/ExtendNodesGlobal.h mesh/actions/ExtendNodesGlobal.cc @@ -455,10 +451,16 @@ util/Earth.cc util/Earth.h util/GaussianLatitudes.cc util/GaussianLatitudes.h +util/LonLatPolygon.cc +util/LonLatPolygon.h util/Metadata.cc util/Metadata.h +util/Polygon.cc +util/Polygon.h util/Rotation.cc util/Rotation.h +util/SphericalPolygon.cc +util/SphericalPolygon.h util/detail/BlackMagic.h ) diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc index ec37187f5..b3a8e2e78 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc @@ -16,9 +16,9 @@ #include "eckit/log/ProgressTimer.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/detail/PolygonCoordinates.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" +#include "atlas/util/LonLatPolygon.h" namespace atlas { namespace grid { @@ -44,7 +44,7 @@ void MatchingMeshPartitionerLonLatPolygon::partition( const Grid& grid, int part bool includesNorthPole = (mpi_rank == 0); bool includesSouthPole = (mpi_rank == mpi_size - 1); - const mesh::detail::PolygonCoordinates poly( + const util::LonLatPolygon poly( prePartitionedMesh_.polygon(0), prePartitionedMesh_.nodes().lonlat(), includesNorthPole, @@ -58,7 +58,7 @@ void MatchingMeshPartitionerLonLatPolygon::partition( const Grid& grid, int part for (const PointXY Pxy : grid.xy()) { ++timer; const PointLonLat P = grid.projection().lonlat(Pxy); - partitioning[i++] = poly.containsPointInLonLatGeometry(P) ? mpi_rank : -1; + partitioning[i++] = poly.contains(P) ? mpi_rank : -1; } } diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc index d95838f34..b2b9bef05 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc @@ -15,9 +15,9 @@ #include "eckit/log/ProgressTimer.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/detail/PolygonCoordinates.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" +#include "atlas/util/SphericalPolygon.h" namespace atlas { namespace grid { @@ -43,7 +43,7 @@ void MatchingMeshPartitionerSphericalPolygon::partition( const Grid& grid, int p bool includesNorthPole = (mpi_rank == 0); bool includesSouthPole = (mpi_rank == mpi_size - 1); - const mesh::detail::PolygonCoordinates poly( + const util::SphericalPolygon poly( prePartitionedMesh_.polygon(0), prePartitionedMesh_.nodes().lonlat(), includesNorthPole, @@ -57,7 +57,7 @@ void MatchingMeshPartitionerSphericalPolygon::partition( const Grid& grid, int p for (const PointXY Pxy : grid.xy()) { ++timer; const PointLonLat P = grid.projection().lonlat(Pxy); - partitioning[i++] = poly.containsPointInSphericalGeometry(P) ? mpi_rank : -1; + partitioning[i++] = poly.contains(P) ? mpi_rank : -1; } } diff --git a/src/atlas/mesh/PartitionPolygon.cc b/src/atlas/mesh/PartitionPolygon.cc index 96911903c..469ddcf3e 100644 --- a/src/atlas/mesh/PartitionPolygon.cc +++ b/src/atlas/mesh/PartitionPolygon.cc @@ -28,10 +28,10 @@ namespace atlas { namespace mesh { namespace { -detail::Polygon::edge_set_t compute_edges(const detail::MeshImpl& mesh, size_t halo) { +util::Polygon::edge_set_t compute_edges(const detail::MeshImpl& mesh, size_t halo) { // extract partition boundary edges by always attempting first to` // remove a reversed edge from a neighbouring element, if any - detail::Polygon::edge_set_t edges; + util::Polygon::edge_set_t edges; for (size_t t = 0; t < mesh.cells().nb_types(); ++t) { const Elements& elements = mesh.cells().elements(t); @@ -44,7 +44,7 @@ detail::Polygon::edge_set_t compute_edges(const detail::MeshImpl& mesh, size_t h for (size_t j = 0; j < elements.size(); ++j) { if (field_patch(j) == 0 && field_halo(j) <= halo ) { for (size_t k = 0; k < nb_nodes; ++k) { - detail::Polygon::edge_t edge( conn(j,k), conn(j, (k+1) % nb_nodes)); + util::Polygon::edge_t edge( conn(j,k), conn(j, (k+1) % nb_nodes)); if (!edges.erase(edge.reverse())) { edges.insert(edge); } @@ -57,7 +57,7 @@ detail::Polygon::edge_set_t compute_edges(const detail::MeshImpl& mesh, size_t h } PartitionPolygon::PartitionPolygon(const detail::MeshImpl& mesh, size_t halo) : - detail::Polygon( compute_edges(mesh,halo) ), + util::Polygon( compute_edges(mesh,halo) ), mesh_(mesh), halo_(halo) { } @@ -151,7 +151,7 @@ void PartitionPolygon::print(std::ostream& out) const { out << "polygon:{" << "halo:" << halo_ << ",size:" << size() - << ",nodes:" << static_cast(*this) + << ",nodes:" << static_cast(*this) << "}"; } diff --git a/src/atlas/mesh/PartitionPolygon.h b/src/atlas/mesh/PartitionPolygon.h index 40faacc6c..1fc38bc55 100644 --- a/src/atlas/mesh/PartitionPolygon.h +++ b/src/atlas/mesh/PartitionPolygon.h @@ -18,8 +18,8 @@ #include "eckit/memory/Owned.h" #include "atlas/library/config.h" #include "atlas/mesh/detail/MeshImpl.h" -#include "atlas/mesh/detail/Polygon.h" #include "atlas/util/Config.h" +#include "atlas/util/Polygon.h" namespace atlas { namespace mesh { @@ -27,7 +27,7 @@ namespace mesh { /** * @brief Polygon class that holds the boundary of a mesh partition */ -class PartitionPolygon : public detail::Polygon, public eckit::Owned { +class PartitionPolygon : public util::Polygon, public eckit::Owned { public: // methods diff --git a/src/atlas/mesh/detail/PartitionGraph.cc b/src/atlas/mesh/detail/PartitionGraph.cc index a63b75f6f..ae0cd877a 100644 --- a/src/atlas/mesh/detail/PartitionGraph.cc +++ b/src/atlas/mesh/detail/PartitionGraph.cc @@ -34,7 +34,7 @@ PartitionGraph* build_partition_graph(const MeshImpl& mesh ) { const eckit::mpi::Comm& comm = parallel::mpi::comm(); const int mpi_size = int(comm.size()); - const Polygon& poly = mesh.polygon(); + const util::Polygon& poly = mesh.polygon(); std::vector< double > polygon; polygon.reserve(poly.size()*2); diff --git a/src/atlas/mesh/detail/PolygonCoordinates.cc b/src/atlas/mesh/detail/PolygonCoordinates.cc deleted file mode 100644 index acaf5c7f8..000000000 --- a/src/atlas/mesh/detail/PolygonCoordinates.cc +++ /dev/null @@ -1,201 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 "atlas/mesh/detail/PolygonCoordinates.h" - -#include -#include -#include -#include -#include "eckit/exception/Exceptions.h" -#include "eckit/types/FloatCompare.h" -#include "atlas/mesh/Nodes.h" -#include "atlas/mesh/detail/Polygon.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/parallel/mpi/mpi.h" - -namespace atlas { -namespace mesh { -namespace detail { - - -//------------------------------------------------------------------------------------------------------ - - -namespace { - - -double cross_product_analog(const PointLonLat& A, const PointLonLat& B, const PointLonLat& C) { - return (A.lon() - C.lon()) * (B.lat() - C.lat()) - - (A.lat() - C.lat()) * (B.lon() - C.lon()); -} - - -} // (anonymous) - - -//------------------------------------------------------------------------------------------------------ - - -PolygonCoordinates::PolygonCoordinates( - const Polygon& poly, - const atlas::Field& lonlat, - bool includesNorthPole, - bool includesSouthPole, - bool removeAlignedPoints ) : - includesNorthPole_(includesNorthPole), - includesSouthPole_(includesSouthPole) { - - ASSERT(poly.size() > 2); - ASSERT(poly.front() == poly.back()); - - // Point coordinates - // - use a bounding box to quickly discard points, - // - except when that is above/below bounding box but poles should be included - - coordinates_.clear(); - coordinates_.reserve(poly.size()); - - auto ll = array::make_view< double, 2 >(lonlat); - coordinatesMin_ = PointLonLat(ll(poly[0], LON), ll(poly[0], LAT)); - coordinatesMax_ = coordinatesMin_; - - for (size_t i = 0; i < poly.size(); ++i) { - - PointLonLat A(ll(poly[i], LON), ll(poly[i], LAT)); - coordinatesMin_ = PointLonLat::componentsMin(coordinatesMin_, A); - coordinatesMax_ = PointLonLat::componentsMax(coordinatesMax_, A); - - // if new point is aligned with existing edge (cross product ~= 0) make the edge longer - if ((coordinates_.size() >= 2) && removeAlignedPoints) { - const PointLonLat& B = coordinates_.back(); - const PointLonLat& C = coordinates_[coordinates_.size() - 2]; - if (eckit::types::is_approximately_equal( 0., cross_product_analog(A, B, C) )) { - coordinates_.back() = A; - continue; - } - } - - coordinates_.push_back(A); - } - - ASSERT(coordinates_.size() == poly.size()); -} - - -PolygonCoordinates::PolygonCoordinates( - const std::vector& points, - bool includesNorthPole, - bool includesSouthPole ) : - coordinates_(points), - includesNorthPole_(includesNorthPole), - includesSouthPole_(includesSouthPole) { - - ASSERT(coordinates_.size() > 2); - ASSERT(eckit::geometry::points_equal(coordinates_.front(), coordinates_.back())); - - coordinatesMin_ = coordinates_.front(); - coordinatesMax_ = coordinatesMin_; - for (const PointLonLat& P : coordinates_) { - coordinatesMin_ = PointLonLat::componentsMin(coordinatesMin_, P); - coordinatesMax_ = PointLonLat::componentsMax(coordinatesMax_, P); - } -} - - -bool PolygonCoordinates::containsPointInLonLatGeometry(const PointLonLat& P) const { - ASSERT(coordinates_.size() >= 2); - - // check first bounding box - if (coordinatesMin_.lon() <= P.lon() && P.lon() < coordinatesMax_.lon() - && coordinatesMin_.lat() <= P.lat() && P.lat() < coordinatesMax_.lat()) { - - // winding number - int wn = 0; - - // loop on polygon edges - for (size_t i = 1; i < coordinates_.size(); ++i) { - const PointLonLat& A = coordinates_[i-1]; - const PointLonLat& B = coordinates_[ i ]; - - // check point-edge side and direction, using 2D-analog cross-product; - // tests if P is left|on|right of a directed A-B infinite line, by intersecting either: - // - "up" on upward crossing & P left of edge, or - // - "down" on downward crossing & P right of edge - const bool APB = (A.lat() <= P.lat() && P.lat() < B.lat()); - const bool BPA = (B.lat() <= P.lat() && P.lat() < A.lat()); - - if (APB != BPA) { - const double side = cross_product_analog(P, A, B); - if (APB && side > 0) { - ++wn; - } else if (BPA && side < 0) { - --wn; - } - } - } - - // wn == 0 only when P is outside - return wn != 0; - } - - return ((includesNorthPole_ && P.lat() >= coordinatesMax_.lat()) - || (includesSouthPole_ && P.lat() < coordinatesMin_.lat())); -} - - -bool PolygonCoordinates::containsPointInSphericalGeometry(const PointLonLat& P) const { - ASSERT(coordinates_.size() >= 2); - - // check first bounding box - if (coordinatesMin_.lon() <= P.lon() && P.lon() < coordinatesMax_.lon() - && coordinatesMin_.lat() <= P.lat() && P.lat() < coordinatesMax_.lat()) { - - // winding number - int wn = 0; - - // loop on polygon edges - for (size_t i = 1; i < coordinates_.size(); ++i) { - const PointLonLat& A = coordinates_[i-1]; - const PointLonLat& B = coordinates_[ i ]; - - // test if P is on/above/below of a great circle containing A,B - const bool APB = (A.lon() <= P.lon() && P.lon() < B.lon()); - const bool BPA = (B.lon() <= P.lon() && P.lon() < A.lon()); - - if (APB != BPA) { - PointLonLat p(P.lon(), std::numeric_limits::quiet_NaN()); - util::Earth::greatCircleLatitudeGivenLongitude(A, B, p); - - ASSERT(!std::isnan(p.lat())); - if (eckit::types::is_approximately_equal(P.lat(), p.lat())) { - return true; - } - - wn += (P.lat() > p.lat() ? -1:1) * (APB ? -1:1); - } - } - - // wn == 0 only when P is outside - return wn != 0; - } - - return ((includesNorthPole_ && P.lat() >= coordinatesMax_.lat()) - || (includesSouthPole_ && P.lat() < coordinatesMin_.lat())); -} - - -//------------------------------------------------------------------------------------------------------ - - -} // detail -} // mesh -} // atlas - diff --git a/src/atlas/mesh/detail/PolygonCoordinates.h b/src/atlas/mesh/detail/PolygonCoordinates.h deleted file mode 100644 index 578d56129..000000000 --- a/src/atlas/mesh/detail/PolygonCoordinates.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 Pedro Maciel -/// @author Willem Deconinck -/// @date September 2017 - -#pragma once - -#include -#include -#include "atlas/util/Point.h" - - -namespace atlas { -class Field; -namespace mesh { -namespace detail { -class Polygon; -} -} -} - -namespace atlas { -namespace mesh { -namespace detail { - -//------------------------------------------------------------------------------------------------------ - -class PolygonCoordinates { -public: - - // -- Constructors - - PolygonCoordinates(const Polygon&, const atlas::Field& lonlat, bool includesNorthPole, bool includesSouthPole, bool removeAlignedPoints=false); - - PolygonCoordinates(const std::vector& points, bool includesNorthPole, bool includesSouthPole); - - // -- Methods - - /* - * Point-in-partition test based on winding number for a point in a polygon - * @note reference Inclusion of a Point in a PolygonCoordinates - * @param[in] points vertex points of a polygon (closed, where poly.front() == poly.back()) - * @param[in] P given point - * @return if point is in partition - */ - bool containsPointInLonLatGeometry(const PointLonLat&) const; - - /* - * Point-in-partition test based on winding number for a point in a polygon - * @note reference Inclusion of a Point in a PolygonCoordinates - * @param[in] points vertex points of a polygon (closed, where poly.front() == poly.back()) - * @param[in] P given point - * @return if point is in partition - */ - bool containsPointInSphericalGeometry(const PointLonLat&) const; - -private: - - // -- Members - - PointLonLat coordinatesMin_; - PointLonLat coordinatesMax_; - std::vector< PointLonLat > coordinates_; - const bool includesNorthPole_; - const bool includesSouthPole_; - -}; - -//------------------------------------------------------------------------------------------------------ - -} // detail -} // mesh -} // atlas - diff --git a/src/atlas/mesh/detail/Polygon.cc b/src/atlas/util/Polygon.cc similarity index 100% rename from src/atlas/mesh/detail/Polygon.cc rename to src/atlas/util/Polygon.cc diff --git a/src/atlas/mesh/detail/Polygon.h b/src/atlas/util/Polygon.h similarity index 67% rename from src/atlas/mesh/detail/Polygon.h rename to src/atlas/util/Polygon.h index f2e980341..95f70d84c 100644 --- a/src/atlas/mesh/detail/Polygon.h +++ b/src/atlas/util/Polygon.h @@ -19,10 +19,14 @@ #include #include #include "atlas/library/config.h" +#include "atlas/util/Point.h" namespace atlas { -namespace mesh { -namespace detail { +class Field; +} + +namespace atlas { +namespace util { //------------------------------------------------------------------------------------------------------ @@ -83,7 +87,42 @@ class Polygon : public std::vector { //------------------------------------------------------------------------------------------------------ -} // detail -} // mesh +class PolygonCoordinates { +public: + + // -- Constructors + + PolygonCoordinates(const Polygon&, const atlas::Field& lonlat, bool includesNorthPole, bool includesSouthPole, bool removeAlignedPoints); + + PolygonCoordinates(const std::vector& points, bool includesNorthPole, bool includesSouthPole); + + // -- Destructor + + virtual ~PolygonCoordinates(); + + // -- Methods + + /* + * Point-in-partition test + * @param[in] P given point + * @return if point is in polygon + */ + virtual bool contains(const PointLonLat& P) const = 0; + +protected: + + // -- Members + + PointLonLat coordinatesMin_; + PointLonLat coordinatesMax_; + std::vector< PointLonLat > coordinates_; + const bool includesNorthPole_; + const bool includesSouthPole_; + +}; + +//------------------------------------------------------------------------------------------------------ + +} // util } // atlas diff --git a/src/tests/mesh/CMakeLists.txt b/src/tests/mesh/CMakeLists.txt index d684e5443..71946a8bd 100644 --- a/src/tests/mesh/CMakeLists.txt +++ b/src/tests/mesh/CMakeLists.txt @@ -63,7 +63,7 @@ ecbuild_add_test( CONDITION HAVE_TESSELATION LIBS atlas) -foreach( test accumulate_facets connectivity elements ll meshgen3d polygon rgg ) +foreach( test accumulate_facets connectivity elements ll meshgen3d rgg ) ecbuild_add_test( TARGET atlas_test_${test} BOOST SOURCES test_${test}.cc diff --git a/src/tests/util/CMakeLists.txt b/src/tests/util/CMakeLists.txt index c98e0f84e..382fbeff2 100644 --- a/src/tests/util/CMakeLists.txt +++ b/src/tests/util/CMakeLists.txt @@ -36,15 +36,12 @@ if( HAVE_FCTEST ) endif() -ecbuild_add_test( TARGET atlas_test_flags - SOURCES test_flags.cc - LIBS atlas -) - -ecbuild_add_test( TARGET atlas_test_indexview - SOURCES test_indexview.cc - LIBS atlas -) +foreach( test earth flags footprint indexview polygon ) + ecbuild_add_test( TARGET atlas_test_${test} + SOURCES test_${test}.cc + LIBS atlas + ) +endforeach() ecbuild_add_test( TARGET atlas_test_vector SOURCES test_vector.cc @@ -59,12 +56,3 @@ ecbuild_add_test( TARGET atlas_test_metadata LIBS atlas ) -ecbuild_add_test( TARGET atlas_test_footprint - SOURCES test_footprint.cc - LIBS atlas -) - -ecbuild_add_test( TARGET atlas_test_earth - SOURCES test_earth.cc - LIBS atlas -) diff --git a/src/tests/mesh/test_polygon.cc b/src/tests/util/test_polygon.cc similarity index 92% rename from src/tests/mesh/test_polygon.cc rename to src/tests/util/test_polygon.cc index b747652e8..a5d686452 100644 --- a/src/tests/mesh/test_polygon.cc +++ b/src/tests/util/test_polygon.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (C) Copyright 1996-2018 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. @@ -12,8 +12,7 @@ #include #include #include "eckit/testing/Test.h" -#include "atlas/mesh/detail/Polygon.h" -#include "atlas/mesh/detail/PolygonCoordinates.h" +#include "atlas/util/SphericalPolygon.h" #include "atlas/util/Point.h" #include "tests/AtlasTestEnvironment.h" @@ -25,11 +24,11 @@ namespace test { CASE( "test_polygon_something" ) { - using mesh::detail::PolygonCoordinates; + using util::SphericalPolygon; using p = PointLonLat; typedef std::pair point_inside_t; - PolygonCoordinates poly( + SphericalPolygon poly( std::vector { p(122.143, 35.9951), p(120, 30.4576), @@ -114,7 +113,7 @@ CASE( "test_polygon_something" ) false, false ); - // test som partitioning points that (approximately) exist in lon-lat polygon, but not in a spherical polygon + // test some partitioning points that (approximately) exist in lon-lat polygon, but not in a spherical polygon for (auto P : std::vector { point_inside_t(p(118.8, 26.9135), true), point_inside_t(p(118.8, 19.3822), false), @@ -125,7 +124,8 @@ CASE( "test_polygon_something" ) point_inside_t(p(118.8, -32.0080), false), point_inside_t(p(118.8, -35.9951), true) }) { - EXPECT( poly.containsPointInSphericalGeometry(P.first) == P.second ); + // 'contains' uses spherical geometry + EXPECT( poly.contains(P.first) == P.second ); } } From c071a358f0d0e9ffec187260f3427c8e03276994 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 12 Jan 2018 19:03:56 +0000 Subject: [PATCH 239/355] Move atlas::mesh::detail::Polygon to atlas::util::Polygon, split atlas::mesh::detail::PolygonCoordinates into atlas::util::LonLatPolygon and atlas::util::SphericalPolygon --- src/atlas/util/LonLatPolygon.cc | 105 +++++++++++++++++++++++++++++ src/atlas/util/LonLatPolygon.h | 47 +++++++++++++ src/atlas/util/Polygon.cc | 101 +++++++++++++++++++++++++-- src/atlas/util/Polygon.h | 2 +- src/atlas/util/SphericalPolygon.cc | 90 +++++++++++++++++++++++++ src/atlas/util/SphericalPolygon.h | 47 +++++++++++++ 6 files changed, 385 insertions(+), 7 deletions(-) create mode 100644 src/atlas/util/LonLatPolygon.cc create mode 100644 src/atlas/util/LonLatPolygon.h create mode 100644 src/atlas/util/SphericalPolygon.cc create mode 100644 src/atlas/util/SphericalPolygon.h diff --git a/src/atlas/util/LonLatPolygon.cc b/src/atlas/util/LonLatPolygon.cc new file mode 100644 index 000000000..6a3fe1ee4 --- /dev/null +++ b/src/atlas/util/LonLatPolygon.cc @@ -0,0 +1,105 @@ +/* + * (C) Copyright 1996-2018 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 "atlas/util/LonLatPolygon.h" + +#include +#include +#include +#include +#include "atlas/util/CoordinateEnums.h" + +namespace atlas { +namespace util { + + +//------------------------------------------------------------------------------------------------------ + + +namespace { + + +double cross_product_analog(const PointLonLat& A, const PointLonLat& B, const PointLonLat& C) { + return (A.lon() - C.lon()) * (B.lat() - C.lat()) + - (A.lat() - C.lat()) * (B.lon() - C.lon()); +} + + +} // (anonymous) + + +//------------------------------------------------------------------------------------------------------ + + +LonLatPolygon::LonLatPolygon( + const Polygon& poly, + const atlas::Field& lonlat, + bool includesNorthPole, + bool includesSouthPole, + bool removeAlignedPoints ) : + PolygonCoordinates(poly, lonlat, includesNorthPole, includesSouthPole, removeAlignedPoints) { +} + + +LonLatPolygon::LonLatPolygon( + const std::vector& points, + bool includesNorthPole, + bool includesSouthPole ) : + PolygonCoordinates(points, includesNorthPole, includesSouthPole) { +} + + +bool LonLatPolygon::contains(const PointLonLat& P) const { + ASSERT(coordinates_.size() >= 2); + + // check first bounding box + if (coordinatesMin_.lon() <= P.lon() && P.lon() < coordinatesMax_.lon() + && coordinatesMin_.lat() <= P.lat() && P.lat() < coordinatesMax_.lat()) { + + // winding number + int wn = 0; + + // loop on polygon edges + for (size_t i = 1; i < coordinates_.size(); ++i) { + const PointLonLat& A = coordinates_[i-1]; + const PointLonLat& B = coordinates_[ i ]; + + // check point-edge side and direction, using 2D-analog cross-product; + // tests if P is left|on|right of a directed A-B infinite line, by intersecting either: + // - "up" on upward crossing & P left of edge, or + // - "down" on downward crossing & P right of edge + const bool APB = (A.lat() <= P.lat() && P.lat() < B.lat()); + const bool BPA = (B.lat() <= P.lat() && P.lat() < A.lat()); + + if (APB != BPA) { + const double side = cross_product_analog(P, A, B); + if (APB && side > 0) { + ++wn; + } else if (BPA && side < 0) { + --wn; + } + } + } + + // wn == 0 only when P is outside + return wn != 0; + } + + return ((includesNorthPole_ && P.lat() >= coordinatesMax_.lat()) + || (includesSouthPole_ && P.lat() < coordinatesMin_.lat())); +} + + +//------------------------------------------------------------------------------------------------------ + + +} // util +} // atlas + diff --git a/src/atlas/util/LonLatPolygon.h b/src/atlas/util/LonLatPolygon.h new file mode 100644 index 000000000..800bc1c67 --- /dev/null +++ b/src/atlas/util/LonLatPolygon.h @@ -0,0 +1,47 @@ +/* + * (C) Copyright 1996-2018 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 +#include "atlas/util/Polygon.h" + +namespace atlas { +namespace util { + +//------------------------------------------------------------------------------------------------------ + +class LonLatPolygon : public PolygonCoordinates { +public: + + // -- Constructors + + LonLatPolygon(const Polygon&, const atlas::Field& lonlat, bool includesNorthPole, bool includesSouthPole, bool removeAlignedPoints = true); + + LonLatPolygon(const std::vector& points, bool includesNorthPole, bool includesSouthPole); + + // -- Overridden methods + + /* + * Point-in-partition test based on winding number for a point in a polygon + * @note reference Inclusion of a Point in a Polygon + * @param[in] points vertex points of a polygon (closed, where poly.front() == poly.back()) + * @param[in] P given point + * @return if point is in partition + */ + bool contains(const PointLonLat&) const; + +}; + +//------------------------------------------------------------------------------------------------------ + +} // util +} // atlas + diff --git a/src/atlas/util/Polygon.cc b/src/atlas/util/Polygon.cc index 08215401c..3bcaa9a13 100644 --- a/src/atlas/util/Polygon.cc +++ b/src/atlas/util/Polygon.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (C) Copyright 1996-2018 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. @@ -8,18 +8,34 @@ * does it submit to any jurisdiction. */ -#include "atlas/mesh/detail/Polygon.h" +#include "atlas/util/Polygon.h" #include +#include #include #include #include "eckit/exception/Exceptions.h" #include "eckit/types/FloatCompare.h" +#include "atlas/mesh/Nodes.h" #include "atlas/util/CoordinateEnums.h" namespace atlas { -namespace mesh { -namespace detail { +namespace util { + +namespace { + + +//------------------------------------------------------------------------------------------------------ + + +double cross_product_analog(const PointLonLat& A, const PointLonLat& B, const PointLonLat& C) { + return (A.lon() - C.lon()) * (B.lat() - C.lat()) + - (A.lat() - C.lat()) * (B.lon() - C.lon()); +} + + +} // (anonymous) + //------------------------------------------------------------------------------------------------------ @@ -101,7 +117,80 @@ void Polygon::print(std::ostream& s) const { //------------------------------------------------------------------------------------------------------ -} // detail -} // mesh + +PolygonCoordinates::PolygonCoordinates( + const Polygon& poly, + const atlas::Field& lonlat, + bool includesNorthPole, + bool includesSouthPole, + bool removeAlignedPoints ) : + includesNorthPole_(includesNorthPole), + includesSouthPole_(includesSouthPole) { + + ASSERT(poly.size() > 2); + ASSERT(poly.front() == poly.back()); + + // Point coordinates + // - use a bounding box to quickly discard points, + // - except when that is above/below bounding box but poles should be included + + coordinates_.clear(); + coordinates_.reserve(poly.size()); + + auto ll = array::make_view< double, 2 >(lonlat); + coordinatesMin_ = PointLonLat(ll(poly[0], LON), ll(poly[0], LAT)); + coordinatesMax_ = coordinatesMin_; + + for (size_t i = 0; i < poly.size(); ++i) { + + PointLonLat A(ll(poly[i], LON), ll(poly[i], LAT)); + coordinatesMin_ = PointLonLat::componentsMin(coordinatesMin_, A); + coordinatesMax_ = PointLonLat::componentsMax(coordinatesMax_, A); + + // if new point is aligned with existing edge (cross product ~= 0) make the edge longer + if ((coordinates_.size() >= 2) && removeAlignedPoints) { + const PointLonLat& B = coordinates_.back(); + const PointLonLat& C = coordinates_[coordinates_.size() - 2]; + if (eckit::types::is_approximately_equal( 0., cross_product_analog(A, B, C) )) { + coordinates_.back() = A; + continue; + } + } + + coordinates_.push_back(A); + } + + ASSERT(coordinates_.size() == poly.size()); +} + + +PolygonCoordinates::PolygonCoordinates( + const std::vector& points, + bool includesNorthPole, + bool includesSouthPole ) : + coordinates_(points), + includesNorthPole_(includesNorthPole), + includesSouthPole_(includesSouthPole) { + + ASSERT(coordinates_.size() > 2); + ASSERT(eckit::geometry::points_equal(coordinates_.front(), coordinates_.back())); + + coordinatesMin_ = coordinates_.front(); + coordinatesMax_ = coordinatesMin_; + for (const PointLonLat& P : coordinates_) { + coordinatesMin_ = PointLonLat::componentsMin(coordinatesMin_, P); + coordinatesMax_ = PointLonLat::componentsMax(coordinatesMax_, P); + } +} + + +PolygonCoordinates::~PolygonCoordinates() { +} + + +//------------------------------------------------------------------------------------------------------ + + +} // util } // atlas diff --git a/src/atlas/util/Polygon.h b/src/atlas/util/Polygon.h index 95f70d84c..86bb0a871 100644 --- a/src/atlas/util/Polygon.h +++ b/src/atlas/util/Polygon.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (C) Copyright 1996-2018 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. diff --git a/src/atlas/util/SphericalPolygon.cc b/src/atlas/util/SphericalPolygon.cc new file mode 100644 index 000000000..545a55b5f --- /dev/null +++ b/src/atlas/util/SphericalPolygon.cc @@ -0,0 +1,90 @@ +/* + * (C) Copyright 1996-2018 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 "atlas/util/SphericalPolygon.h" + +#include +#include +#include +#include +#include "eckit/types/FloatCompare.h" +#include "atlas/util/CoordinateEnums.h" + +namespace atlas { +namespace util { + + +//------------------------------------------------------------------------------------------------------ + + +SphericalPolygon::SphericalPolygon( + const Polygon& poly, + const atlas::Field& lonlat, + bool includesNorthPole, + bool includesSouthPole ) : + PolygonCoordinates(poly, lonlat, includesNorthPole, includesSouthPole, false) { +} + + +SphericalPolygon::SphericalPolygon( + const std::vector& points, + bool includesNorthPole, + bool includesSouthPole ) : + PolygonCoordinates(points, includesNorthPole, includesSouthPole) { +} + + +bool SphericalPolygon::contains(const PointLonLat& P) const { + ASSERT(coordinates_.size() >= 2); + + // check first bounding box + if (coordinatesMin_.lon() <= P.lon() && P.lon() < coordinatesMax_.lon() + && coordinatesMin_.lat() <= P.lat() && P.lat() < coordinatesMax_.lat()) { + + // winding number + int wn = 0; + + // loop on polygon edges + for (size_t i = 1; i < coordinates_.size(); ++i) { + const PointLonLat& A = coordinates_[i-1]; + const PointLonLat& B = coordinates_[ i ]; + + // test if P is on/above/below of a great circle containing A,B + const bool APB = (A.lon() <= P.lon() && P.lon() < B.lon()); + const bool BPA = (B.lon() <= P.lon() && P.lon() < A.lon()); + + if (APB != BPA) { + PointLonLat p(P.lon(), std::numeric_limits::quiet_NaN()); + util::Earth::greatCircleLatitudeGivenLongitude(A, B, p); + + ASSERT(!std::isnan(p.lat())); + if (eckit::types::is_approximately_equal(P.lat(), p.lat())) { + return true; + } + + wn += (P.lat() > p.lat() ? -1:1) * (APB ? -1:1); + } + } + + // wn == 0 only when P is outside + return wn != 0; + } + + return ((includesNorthPole_ && P.lat() >= coordinatesMax_.lat()) + || (includesSouthPole_ && P.lat() < coordinatesMin_.lat())); +} + + +//------------------------------------------------------------------------------------------------------ + + +} // util +} // atlas + diff --git a/src/atlas/util/SphericalPolygon.h b/src/atlas/util/SphericalPolygon.h new file mode 100644 index 000000000..2e4a675f4 --- /dev/null +++ b/src/atlas/util/SphericalPolygon.h @@ -0,0 +1,47 @@ +/* + * (C) Copyright 1996-2018 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 +#include "atlas/util/Polygon.h" + +namespace atlas { +namespace util { + +//------------------------------------------------------------------------------------------------------ + +class SphericalPolygon : public PolygonCoordinates { +public: + + // -- Constructors + + SphericalPolygon(const Polygon&, const atlas::Field& lonlat, bool includesNorthPole, bool includesSouthPole); + + SphericalPolygon(const std::vector& points, bool includesNorthPole, bool includesSouthPole); + + // -- Overridden methods + + /* + * Point-in-partition test based on winding number for a point in a polygon + * @note reference Inclusion of a Point in a Polygon + * @param[in] points vertex points of a polygon (closed, where poly.front() == poly.back()) + * @param[in] P given point + * @return if point is in partition + */ + bool contains(const PointLonLat&) const; + +}; + +//------------------------------------------------------------------------------------------------------ + +} // util +} // atlas + From dcbf18ca5449562bd646fb6711c176b22314b5d7 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Fri, 12 Jan 2018 19:07:26 +0000 Subject: [PATCH 240/355] Corrected documentation --- src/atlas/util/LonLatPolygon.h | 7 +++---- src/atlas/util/SphericalPolygon.h | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/atlas/util/LonLatPolygon.h b/src/atlas/util/LonLatPolygon.h index 800bc1c67..467e89de8 100644 --- a/src/atlas/util/LonLatPolygon.h +++ b/src/atlas/util/LonLatPolygon.h @@ -30,13 +30,12 @@ class LonLatPolygon : public PolygonCoordinates { // -- Overridden methods /* - * Point-in-partition test based on winding number for a point in a polygon + * Point-in-polygon test based on winding number * @note reference Inclusion of a Point in a Polygon - * @param[in] points vertex points of a polygon (closed, where poly.front() == poly.back()) * @param[in] P given point - * @return if point is in partition + * @return if point is in polygon */ - bool contains(const PointLonLat&) const; + bool contains(const PointLonLat& P) const; }; diff --git a/src/atlas/util/SphericalPolygon.h b/src/atlas/util/SphericalPolygon.h index 2e4a675f4..6926b0689 100644 --- a/src/atlas/util/SphericalPolygon.h +++ b/src/atlas/util/SphericalPolygon.h @@ -30,13 +30,12 @@ class SphericalPolygon : public PolygonCoordinates { // -- Overridden methods /* - * Point-in-partition test based on winding number for a point in a polygon + * Point-in-polygon test based on winding number * @note reference Inclusion of a Point in a Polygon - * @param[in] points vertex points of a polygon (closed, where poly.front() == poly.back()) * @param[in] P given point - * @return if point is in partition + * @return if point is in polygon */ - bool contains(const PointLonLat&) const; + bool contains(const PointLonLat& P) const; }; From ff8893bb44da1ea9eecc9b20728698c8609459ee Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 15 Jan 2018 09:06:23 +0000 Subject: [PATCH 241/355] FCKIT-4 Shorten symbol name --- .../atlas_functionspace_StructuredColumns_module.F90 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 index 90068f801..895433876 100644 --- a/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 +++ b/src/atlas_f/functionspace/atlas_functionspace_StructuredColumns_module.F90 @@ -74,7 +74,7 @@ module atlas_functionspace_StructuredColumns_module procedure, private :: set_index #if FCKIT_FINAL_NOT_INHERITING - final :: atlas_functionspace_StructuredColumns__final_auto + final :: StructuredColumns__final_auto #endif END TYPE atlas_functionspace_StructuredColumns @@ -300,7 +300,7 @@ subroutine halo_exchange_field(this,field) !------------------------------------------------------------------------------- -subroutine atlas_functionspace_StructuredColumns__final_auto(this) +subroutine StructuredColumns__final_auto(this) type(atlas_functionspace_StructuredColumns) :: this #if FCKIT_FINAL_DEBUGGING write(0,*) "atlas_functionspace_StructuredColumns__final_auto" From 149e5064194ba4aa8e38160b5d3386f260060ef6 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Mon, 15 Jan 2018 16:04:20 +0000 Subject: [PATCH 242/355] Moved "include North/South pole" logic to MatchingMeshPartitioner* as it is connected to mesh partition rather than polygon --- .../MatchingMeshPartitionerLonLatPolygon.cc | 10 +-- ...MatchingMeshPartitionerSphericalPolygon.cc | 10 +-- src/atlas/util/LonLatPolygon.cc | 69 +++++++++---------- src/atlas/util/LonLatPolygon.h | 4 +- src/atlas/util/Polygon.cc | 25 +++---- src/atlas/util/Polygon.h | 9 +-- src/atlas/util/SphericalPolygon.cc | 62 +++++++---------- src/atlas/util/SphericalPolygon.h | 4 +- src/tests/util/test_polygon.cc | 4 +- 9 files changed, 92 insertions(+), 105 deletions(-) diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc index b3a8e2e78..97aa2a52b 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc @@ -46,9 +46,7 @@ void MatchingMeshPartitionerLonLatPolygon::partition( const Grid& grid, int part const util::LonLatPolygon poly( prePartitionedMesh_.polygon(0), - prePartitionedMesh_.nodes().lonlat(), - includesNorthPole, - includesSouthPole ); + prePartitionedMesh_.nodes().lonlat() ); { eckit::ProgressTimer timer("Partitioning", grid.size(), "point", @@ -58,7 +56,11 @@ void MatchingMeshPartitionerLonLatPolygon::partition( const Grid& grid, int part for (const PointXY Pxy : grid.xy()) { ++timer; const PointLonLat P = grid.projection().lonlat(Pxy); - partitioning[i++] = poly.contains(P) ? mpi_rank : -1; + const bool atThePole = + (includesNorthPole && P.lat() >= poly.coordinatesMax().lat()) || + (includesSouthPole && P.lat() < poly.coordinatesMin().lat()); + + partitioning[i++] = atThePole || poly.contains(P) ? mpi_rank : -1; } } diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc index b2b9bef05..f656481e6 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc @@ -45,9 +45,7 @@ void MatchingMeshPartitionerSphericalPolygon::partition( const Grid& grid, int p const util::SphericalPolygon poly( prePartitionedMesh_.polygon(0), - prePartitionedMesh_.nodes().lonlat(), - includesNorthPole, - includesSouthPole ); + prePartitionedMesh_.nodes().lonlat() ); { eckit::ProgressTimer timer("Partitioning", grid.size(), "point", @@ -57,7 +55,11 @@ void MatchingMeshPartitionerSphericalPolygon::partition( const Grid& grid, int p for (const PointXY Pxy : grid.xy()) { ++timer; const PointLonLat P = grid.projection().lonlat(Pxy); - partitioning[i++] = poly.contains(P) ? mpi_rank : -1; + const bool atThePole = + (includesNorthPole && P.lat() >= poly.coordinatesMax().lat()) || + (includesSouthPole && P.lat() < poly.coordinatesMin().lat()); + + partitioning[i++] = atThePole || poly.contains(P) ? mpi_rank : -1; } } diff --git a/src/atlas/util/LonLatPolygon.cc b/src/atlas/util/LonLatPolygon.cc index 6a3fe1ee4..d8f5c88d9 100644 --- a/src/atlas/util/LonLatPolygon.cc +++ b/src/atlas/util/LonLatPolygon.cc @@ -41,18 +41,13 @@ double cross_product_analog(const PointLonLat& A, const PointLonLat& B, const Po LonLatPolygon::LonLatPolygon( const Polygon& poly, const atlas::Field& lonlat, - bool includesNorthPole, - bool includesSouthPole, bool removeAlignedPoints ) : - PolygonCoordinates(poly, lonlat, includesNorthPole, includesSouthPole, removeAlignedPoints) { + PolygonCoordinates(poly, lonlat, removeAlignedPoints) { } -LonLatPolygon::LonLatPolygon( - const std::vector& points, - bool includesNorthPole, - bool includesSouthPole ) : - PolygonCoordinates(points, includesNorthPole, includesSouthPole) { +LonLatPolygon::LonLatPolygon(const std::vector& points ) : + PolygonCoordinates(points) { } @@ -60,40 +55,38 @@ bool LonLatPolygon::contains(const PointLonLat& P) const { ASSERT(coordinates_.size() >= 2); // check first bounding box - if (coordinatesMin_.lon() <= P.lon() && P.lon() < coordinatesMax_.lon() - && coordinatesMin_.lat() <= P.lat() && P.lat() < coordinatesMax_.lat()) { - - // winding number - int wn = 0; - - // loop on polygon edges - for (size_t i = 1; i < coordinates_.size(); ++i) { - const PointLonLat& A = coordinates_[i-1]; - const PointLonLat& B = coordinates_[ i ]; - - // check point-edge side and direction, using 2D-analog cross-product; - // tests if P is left|on|right of a directed A-B infinite line, by intersecting either: - // - "up" on upward crossing & P left of edge, or - // - "down" on downward crossing & P right of edge - const bool APB = (A.lat() <= P.lat() && P.lat() < B.lat()); - const bool BPA = (B.lat() <= P.lat() && P.lat() < A.lat()); - - if (APB != BPA) { - const double side = cross_product_analog(P, A, B); - if (APB && side > 0) { - ++wn; - } else if (BPA && side < 0) { - --wn; - } + if (coordinatesMax_.lon() <= P.lon() || P.lon() < coordinatesMin_.lon() || + coordinatesMax_.lat() <= P.lat() || P.lat() < coordinatesMin_.lat() ) { + return false; + } + + // winding number + int wn = 0; + + // loop on polygon edges + for (size_t i = 1; i < coordinates_.size(); ++i) { + const PointLonLat& A = coordinates_[i-1]; + const PointLonLat& B = coordinates_[ i ]; + + // check point-edge side and direction, using 2D-analog cross-product; + // tests if P is left|on|right of a directed A-B infinite line, by intersecting either: + // - "up" on upward crossing & P left of edge, or + // - "down" on downward crossing & P right of edge + const bool APB = (A.lat() <= P.lat() && P.lat() < B.lat()); + const bool BPA = (B.lat() <= P.lat() && P.lat() < A.lat()); + + if (APB != BPA) { + const double side = cross_product_analog(P, A, B); + if (APB && side > 0) { + ++wn; + } else if (BPA && side < 0) { + --wn; } } - - // wn == 0 only when P is outside - return wn != 0; } - return ((includesNorthPole_ && P.lat() >= coordinatesMax_.lat()) - || (includesSouthPole_ && P.lat() < coordinatesMin_.lat())); + // wn == 0 only when P is outside + return wn != 0; } diff --git a/src/atlas/util/LonLatPolygon.h b/src/atlas/util/LonLatPolygon.h index 467e89de8..c0455f962 100644 --- a/src/atlas/util/LonLatPolygon.h +++ b/src/atlas/util/LonLatPolygon.h @@ -23,9 +23,9 @@ class LonLatPolygon : public PolygonCoordinates { // -- Constructors - LonLatPolygon(const Polygon&, const atlas::Field& lonlat, bool includesNorthPole, bool includesSouthPole, bool removeAlignedPoints = true); + LonLatPolygon(const Polygon&, const atlas::Field& lonlat, bool removeAlignedPoints = true); - LonLatPolygon(const std::vector& points, bool includesNorthPole, bool includesSouthPole); + LonLatPolygon(const std::vector& points); // -- Overridden methods diff --git a/src/atlas/util/Polygon.cc b/src/atlas/util/Polygon.cc index 3bcaa9a13..3997853ed 100644 --- a/src/atlas/util/Polygon.cc +++ b/src/atlas/util/Polygon.cc @@ -121,11 +121,7 @@ void Polygon::print(std::ostream& s) const { PolygonCoordinates::PolygonCoordinates( const Polygon& poly, const atlas::Field& lonlat, - bool includesNorthPole, - bool includesSouthPole, - bool removeAlignedPoints ) : - includesNorthPole_(includesNorthPole), - includesSouthPole_(includesSouthPole) { + bool removeAlignedPoints ) { ASSERT(poly.size() > 2); ASSERT(poly.front() == poly.back()); @@ -164,13 +160,8 @@ PolygonCoordinates::PolygonCoordinates( } -PolygonCoordinates::PolygonCoordinates( - const std::vector& points, - bool includesNorthPole, - bool includesSouthPole ) : - coordinates_(points), - includesNorthPole_(includesNorthPole), - includesSouthPole_(includesSouthPole) { +PolygonCoordinates::PolygonCoordinates(const std::vector& points) : + coordinates_(points) { ASSERT(coordinates_.size() > 2); ASSERT(eckit::geometry::points_equal(coordinates_.front(), coordinates_.back())); @@ -188,6 +179,16 @@ PolygonCoordinates::~PolygonCoordinates() { } +const PointLonLat& PolygonCoordinates::coordinatesMax() const { + return coordinatesMax_; +} + + +const PointLonLat& PolygonCoordinates::coordinatesMin() const { + return coordinatesMin_; +} + + //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/util/Polygon.h b/src/atlas/util/Polygon.h index 86bb0a871..4498909e9 100644 --- a/src/atlas/util/Polygon.h +++ b/src/atlas/util/Polygon.h @@ -92,9 +92,9 @@ class PolygonCoordinates { // -- Constructors - PolygonCoordinates(const Polygon&, const atlas::Field& lonlat, bool includesNorthPole, bool includesSouthPole, bool removeAlignedPoints); + PolygonCoordinates(const Polygon&, const atlas::Field& lonlat, bool removeAlignedPoints); - PolygonCoordinates(const std::vector& points, bool includesNorthPole, bool includesSouthPole); + PolygonCoordinates(const std::vector& points); // -- Destructor @@ -109,6 +109,9 @@ class PolygonCoordinates { */ virtual bool contains(const PointLonLat& P) const = 0; + const PointLonLat& coordinatesMax() const; + const PointLonLat& coordinatesMin() const; + protected: // -- Members @@ -116,8 +119,6 @@ class PolygonCoordinates { PointLonLat coordinatesMin_; PointLonLat coordinatesMax_; std::vector< PointLonLat > coordinates_; - const bool includesNorthPole_; - const bool includesSouthPole_; }; diff --git a/src/atlas/util/SphericalPolygon.cc b/src/atlas/util/SphericalPolygon.cc index 545a55b5f..a90d50689 100644 --- a/src/atlas/util/SphericalPolygon.cc +++ b/src/atlas/util/SphericalPolygon.cc @@ -24,20 +24,13 @@ namespace util { //------------------------------------------------------------------------------------------------------ -SphericalPolygon::SphericalPolygon( - const Polygon& poly, - const atlas::Field& lonlat, - bool includesNorthPole, - bool includesSouthPole ) : - PolygonCoordinates(poly, lonlat, includesNorthPole, includesSouthPole, false) { +SphericalPolygon::SphericalPolygon( const Polygon& poly, const atlas::Field& lonlat) : + PolygonCoordinates(poly, lonlat, false) { } -SphericalPolygon::SphericalPolygon( - const std::vector& points, - bool includesNorthPole, - bool includesSouthPole ) : - PolygonCoordinates(points, includesNorthPole, includesSouthPole) { +SphericalPolygon::SphericalPolygon(const std::vector& points) : + PolygonCoordinates(points) { } @@ -45,40 +38,37 @@ bool SphericalPolygon::contains(const PointLonLat& P) const { ASSERT(coordinates_.size() >= 2); // check first bounding box - if (coordinatesMin_.lon() <= P.lon() && P.lon() < coordinatesMax_.lon() - && coordinatesMin_.lat() <= P.lat() && P.lat() < coordinatesMax_.lat()) { - - // winding number - int wn = 0; + if (coordinatesMax_.lon() <= P.lon() || P.lon() < coordinatesMin_.lon()) { + return false; + } - // loop on polygon edges - for (size_t i = 1; i < coordinates_.size(); ++i) { - const PointLonLat& A = coordinates_[i-1]; - const PointLonLat& B = coordinates_[ i ]; + // winding number + int wn = 0; - // test if P is on/above/below of a great circle containing A,B - const bool APB = (A.lon() <= P.lon() && P.lon() < B.lon()); - const bool BPA = (B.lon() <= P.lon() && P.lon() < A.lon()); + // loop on polygon edges + for (size_t i = 1; i < coordinates_.size(); ++i) { + const PointLonLat& A = coordinates_[i-1]; + const PointLonLat& B = coordinates_[ i ]; - if (APB != BPA) { - PointLonLat p(P.lon(), std::numeric_limits::quiet_NaN()); - util::Earth::greatCircleLatitudeGivenLongitude(A, B, p); + // test if P is on/above/below of a great circle containing A,B + const bool APB = (A.lon() <= P.lon() && P.lon() < B.lon()); + const bool BPA = (B.lon() <= P.lon() && P.lon() < A.lon()); - ASSERT(!std::isnan(p.lat())); - if (eckit::types::is_approximately_equal(P.lat(), p.lat())) { - return true; - } + if (APB != BPA) { + PointLonLat p(P.lon(), std::numeric_limits::quiet_NaN()); + util::Earth::greatCircleLatitudeGivenLongitude(A, B, p); - wn += (P.lat() > p.lat() ? -1:1) * (APB ? -1:1); + ASSERT(!std::isnan(p.lat())); + if (eckit::types::is_approximately_equal(P.lat(), p.lat())) { + return true; } - } - // wn == 0 only when P is outside - return wn != 0; + wn += (P.lat() > p.lat() ? -1:1) * (APB ? -1:1); + } } - return ((includesNorthPole_ && P.lat() >= coordinatesMax_.lat()) - || (includesSouthPole_ && P.lat() < coordinatesMin_.lat())); + // wn == 0 only when P is outside + return wn != 0; } diff --git a/src/atlas/util/SphericalPolygon.h b/src/atlas/util/SphericalPolygon.h index 6926b0689..fee3c9e91 100644 --- a/src/atlas/util/SphericalPolygon.h +++ b/src/atlas/util/SphericalPolygon.h @@ -23,9 +23,9 @@ class SphericalPolygon : public PolygonCoordinates { // -- Constructors - SphericalPolygon(const Polygon&, const atlas::Field& lonlat, bool includesNorthPole, bool includesSouthPole); + SphericalPolygon(const Polygon&, const atlas::Field& lonlat); - SphericalPolygon(const std::vector& points, bool includesNorthPole, bool includesSouthPole); + SphericalPolygon(const std::vector& points); // -- Overridden methods diff --git a/src/tests/util/test_polygon.cc b/src/tests/util/test_polygon.cc index a5d686452..693243aeb 100644 --- a/src/tests/util/test_polygon.cc +++ b/src/tests/util/test_polygon.cc @@ -109,9 +109,7 @@ CASE( "test_polygon_something" ) p(135, 35.9951), p(128.571, 35.9951), p(122.143, 35.9951) - }, - false, - false ); + } ); // test some partitioning points that (approximately) exist in lon-lat polygon, but not in a spherical polygon for (auto P : std::vector { From 5de69d528bf15fbdb03f067aa7632d82d9a25ce9 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 15 Jan 2018 18:10:17 +0000 Subject: [PATCH 243/355] FCKIT-4 Fix pgi/16.7 without final --- src/atlas_f/grid/atlas_GridDistribution_module.F90 | 4 ---- src/atlas_f/mesh/atlas_MeshGenerator_module.F90 | 2 +- src/tests/mesh/fctest_mesh.F90 | 13 +++++++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/atlas_f/grid/atlas_GridDistribution_module.F90 b/src/atlas_f/grid/atlas_GridDistribution_module.F90 index 881c792f5..fe7254cd9 100644 --- a/src/atlas_f/grid/atlas_GridDistribution_module.F90 +++ b/src/atlas_f/grid/atlas_GridDistribution_module.F90 @@ -57,10 +57,8 @@ function atlas_GridDistribution__cptr( cptr ) result(this) use atlas_distribution_c_binding type(atlas_GridDistribution) :: this type(c_ptr) :: cptr -write(0,*) "atlas_GridDistribution__cptr" call this%reset_c_ptr( cptr ) call this%return() -write(0,*) "atlas_GridDistribution__cptr done" end function function atlas_GridDistribution__ctor( part, part0 ) result(this) @@ -69,13 +67,11 @@ function atlas_GridDistribution__ctor( part, part0 ) result(this) integer, intent(in) :: part(:) integer, intent(in), optional :: part0 integer:: npts, opt_part0 - write(0,*) "atlas_GridDistribution__ctor" opt_part0 = 0 if( present(part0) ) opt_part0 = part0 npts = size(part) call this%reset_c_ptr( atlas__GridDistribution__new(npts, part, opt_part0) ) call this%return() - write(0,*) "atlas_GridDistribution__ctor done" end function ! ---------------------------------------------------------------------------------------- diff --git a/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 b/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 index 289661d25..85e018aec 100644 --- a/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 +++ b/src/atlas_f/mesh/atlas_MeshGenerator_module.F90 @@ -76,7 +76,7 @@ function atlas_MeshGenerator__generate(this,grid,distribution) result(mesh) class(atlas_MeshGenerator), intent(in) :: this class(atlas_Grid), intent(in) :: grid class(atlas_GridDistribution), intent(in), optional :: distribution - + call mesh%reset_c_ptr() ! Somehow needed with PGI/16.7 and build-type "bit" if( present(distribution) ) then mesh = atlas_Mesh( atlas__MeshGenerator__generate__grid_griddist(this%c_ptr(),grid%c_ptr(),distribution%c_ptr()) ) else diff --git a/src/tests/mesh/fctest_mesh.F90 b/src/tests/mesh/fctest_mesh.F90 index dbe875a5e..1e9fee7d8 100644 --- a/src/tests/mesh/fctest_mesh.F90 +++ b/src/tests/mesh/fctest_mesh.F90 @@ -319,21 +319,31 @@ end module fcta_Mesh_fixture allocate(nloen(36)) nloen(1:32) = 64 + write(0,*) "test_fv" + ! Create a new Reduced Gaussian Grid based on a nloen array call atlas_log%info("Creating grid") grid = atlas_ReducedGaussianGrid( nloen(1:32) ) + FCTEST_CHECK_EQUAL( grid%owners(), 1 ) ! Grid distribution: all points belong to partition 1 allocate( part(grid%size()) ) part(:) = 1 griddistribution = atlas_GridDistribution(part, part0=1) + FCTEST_CHECK_EQUAL( griddistribution%owners(), 1 ) ! Generate mesh with given grid and distribution meshgenerator = atlas_MeshGenerator() + FCTEST_CHECK_EQUAL( meshgenerator%owners(), 1 ) + + write(0,*) " + mesh = meshgenerator%generate(grid,griddistribution)" + write(0,*) "mesh%is_null()",mesh%is_null() mesh = meshgenerator%generate(grid,griddistribution) + write(0,*) " + call griddistribution%final()" call griddistribution%final() ! Generate nodes function-space, with a given halo_size + write(0,*) " + nodes_fs = atlas_functionspace_NodeColumns(mesh,halo_size)" nodes_fs = atlas_functionspace_NodeColumns(mesh,halo_size) ! Create edge elements from surface elements @@ -367,6 +377,9 @@ end module fcta_Mesh_fixture call mesh%final() call grid%final() call nodes_fs%final() + + write(0,*) "end test_fv" + END_TEST From 97f31fe1ce48c1c5df37e18bb684841eeaecec53 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Wed, 17 Jan 2018 11:33:51 +0000 Subject: [PATCH 244/355] ATLAS-135 confirmed that initialising values with zero was correct. Removed warning and moved initialisation into next loop --- src/atlas/trans/local/LegendrePolynomials.cc | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index 11fd22486..299422e6e 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -89,16 +89,10 @@ void compute_legendre_polynomials( legpol[idxmn(1,jn)] = zdlldn; } -{ -#warning zfn(jn_odd,0) used but uninitialized... Andreas should look at this. Set to zero for now. - for( int jn=1; jn<=trc; jn+=2 ) { - zfn(jn,0) = 0.; - } -} - // odd N for( int jn=1; jn<=trc; jn+=2 ) { - double zdlk = 0.5*zfn(jn,0); + zfn(jn,0) = 0.; + double zdlk = 0.; double zdlldn = 0.0; // represented by only even k for (int jk=1; jk<=jn; jk+=2 ) { From fcb1bee58600d72cb212ffa669073ccec1f45f15 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Wed, 17 Jan 2018 17:01:51 +0000 Subject: [PATCH 245/355] ATLAS-135 first compiling version with vd2uv in translocal --- src/atlas/trans/local/TransLocal.cc | 147 +++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 1 deletion(-) diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 571284ef4..ce9a153a6 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -17,6 +17,7 @@ #include "atlas/trans/local/FourierTransforms.h" #include "atlas/trans/local/LegendreTransforms.h" #include "atlas/trans/local/LegendrePolynomials.h" +#include "atlas/util/Earth.h" namespace atlas { namespace trans { @@ -226,6 +227,142 @@ void TransLocal::invtrans( NOTIMP; } +// -------------------------------------------------------------------------------------------------------------------- +void prfi1b( + const int truncation, + const int km, // zonal wavenumber + const int nb_fields, // number of fields + const double rspec[], // spectral data + double pia[]) // spectral components in data layout of trans library +{ + int ilcm = truncation-km, ioff = (2*truncation-km+1)*km, nlei1 = truncation+4+(truncation+4+1)%2; + for( int j=0; j<=ilcm; ++j ) { + int inm = ioff+(ilcm-j)*2; + for( int jfld=0; jfld Date: Mon, 15 Jan 2018 18:10:57 +0000 Subject: [PATCH 246/355] ATLAS-142 Recognise CUDA backend with atlas --info --- src/atlas/library/Library.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index b4da407b5..2b6bc86c0 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -215,12 +215,10 @@ void Library::Information::print( std::ostream& out ) const { #endif std::string array_data_store = "Native"; #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE -#if GRIDTOOLS_STORAGE_BACKEND_CUDA + array_data_store = "Gridtools-host"; +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA array_data_store = "GridTools-CUDA"; #endif -#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST - array_data_store = "GridTools-host"; -#endif #endif out << " Features:" << '\n' << " Fortran : " << str(feature_fortran) << '\n' From 0d79c339d47bc6d815ae71de3f313d9d32e52c8f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 15 Jan 2018 18:11:54 +0000 Subject: [PATCH 247/355] ATLAS-142 Fix test_array and test_connectivity_kernel with GT-CUDA backend --- src/tests/array/test_array.cc | 16 +++++++--------- src/tests/mesh/test_connectivity_kernel.cu | 18 ++++++++++++++++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 3e84c4189..5ba0f35c7 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -250,9 +250,10 @@ CASE("test_copy_gt_ctr") { EXPECT(hv2(1, 1) == 7); auto dims = hv.data_view().storage_info().dims(); + ATLAS_DEBUG_VAR(dims[0]); + ATLAS_DEBUG_VAR(dims[1]); EXPECT(dims[0] == 3); - EXPECT(dims[1] == 2); - + if( NOT_PADDED ) EXPECT(dims[1] == 2); delete ds; } #endif @@ -553,7 +554,7 @@ CASE("test_wrap") { array::ArrayT arr_t(3,2); EXPECT(arr_t.shape(0) == 3); - 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); @@ -568,19 +569,16 @@ CASE("test_wrap") { } eckit::SharedPtr arr ( array::Array::wrap(arrv_t.data(), - array::ArraySpec{array::make_shape(3), array::make_strides(2) } ) ); + array::ArraySpec{array::make_shape(3), array::make_strides(arr_t.stride(0) ) } ) ); EXPECT(arr->shape(0) == 3); - EXPECT(arr->stride(0) == 2); + EXPECT(arr->stride(0) == arr_t.stride(0) ); EXPECT(arr->rank() == 1); auto view = make_host_view(*arr); EXPECT(view.shape(0) == 3); -// TODO fix this -#ifndef ATLAS_HAVE_GRIDTOOLS_STORAGE - EXPECT(view.stride(0) == 2); -#endif + EXPECT(view.stride(0) == arr_t.stride(0) ); EXPECT(view.rank() == 1); EXPECT(view(0) == -1); diff --git a/src/tests/mesh/test_connectivity_kernel.cu b/src/tests/mesh/test_connectivity_kernel.cu index 22ad7c019..60ef850d5 100644 --- a/src/tests/mesh/test_connectivity_kernel.cu +++ b/src/tests/mesh/test_connectivity_kernel.cu @@ -97,6 +97,18 @@ CASE( "test_block_connectivity" ) idx_t vals2[12] = {2,3,9,34,356,86,3,24,84,45,2,2}; conn.add(2,5, vals2); + + EXPECT(conn(0,0) == 2); + EXPECT(conn(0,1) == 3); + EXPECT(conn(0,2) == 9); + EXPECT(conn(0,3) == 34); + EXPECT(conn(0,4) == 356); + EXPECT(conn(1,0) == 86); + EXPECT(conn(1,1) == 3); + EXPECT(conn(1,2) == 24); + EXPECT(conn(1,3) == 84); + EXPECT(conn(1,4) == 45); + conn.cloneToDevice(); EXPECT( !conn.deviceNeedsUpdate() ); @@ -123,6 +135,8 @@ CASE( "test_irregular_connectivity" ) bool from_fortran = true; conn.add(2, 3, vals, from_fortran); + EXPECT(conn(0,0) == 1 IN_FORTRAN); + bool* result; cudaMallocManaged(&result, sizeof(bool)); *result = true; @@ -154,7 +168,7 @@ CASE( "test_multiblock_connectivity" ) bool from_fortran = true; conn.add(2, 3, vals, from_fortran); - EXPECT(conn.block(0)(0,0) == 1); + EXPECT(conn.block(0)(0,0) == 1 IN_FORTRAN); bool* result; cudaMallocManaged(&result, sizeof(bool)); *result = true; @@ -171,7 +185,7 @@ CASE( "test_multiblock_connectivity" ) // copy back, although not strickly needed since the gpu copy does not modify values, // but for the sake of testing it conn.cloneFromDevice(); - EXPECT(conn.block(0)(0,0) == 1); + EXPECT(conn.block(0)(0,0) == 1 IN_FORTRAN); } From 1e7b0e01d8b3dd91d7e43efea648029d8c4db222 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 15 Jan 2018 18:12:28 +0000 Subject: [PATCH 248/355] ATLAS-142 Work on GmshIO with GT-CUDA backend --- src/atlas/output/detail/GmshIO.cc | 231 ++++++++++++++++-------------- 1 file changed, 121 insertions(+), 110 deletions(-) diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index 43cb7117c..ee4ab0b44 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -113,23 +113,19 @@ void write_field_nodes(const Metadata& gmsh_options, const functionspace::NodeCo bool binary( !gmsh_options.get("ascii") ); size_t nlev = std::max(1,field.levels()); size_t ndata = std::min(function_space.nb_nodes(),field.shape(0)); - size_t nvars = field.stride(0)/nlev; + size_t nvars = std::max(1,field.variables()); //field.stride(0)/nlev; array::ArrayView gidx = array::make_view( function_space.nodes().global_index() ); - array::LocalView data ( field.data(), - array::make_shape(field.shape(0),field.stride(0)) ); Field gidx_glb; - Field data_glb; + Field field_glb; if( gather ) { gidx_glb = function_space.createField( option::name("gidx_glb") | option::levels(false) | option::global() ); function_space.gather(function_space.nodes().global_index(),gidx_glb); gidx = array::make_view( gidx_glb ); - data_glb = function_space.createField( option::name("glb_field") | option::levels(field.levels()) | option::variables( field.variables() ) | option::global() ); - function_space.gather(field,data_glb); - data = array::LocalView( data_glb.data(), - array::make_shape(data_glb.shape(0),data_glb.stride(0)) ); - ndata = std::min(function_space.nb_nodes_global(),data.shape(0)); + field_glb = function_space.createField( field, option::global() ); + function_space.gather(field,field_glb); + ndata = std::min(function_space.nb_nodes_global(),field_glb.shape(0)); } std::vector lev; @@ -168,123 +164,138 @@ void write_field_nodes(const Metadata& gmsh_options, const functionspace::NodeCo out << ndata << "\n"; out << atlas::parallel::mpi::comm().rank() << "\n"; - if( binary ) + { - if( nvars == 1) - { - double value; - for(size_t n = 0; n < ndata; ++n) - { - out.write(reinterpret_cast(&gidx(n)),sizeof(int)); - value = data(n,jlev*nvars+0); - out.write(reinterpret_cast(&value),sizeof(double)); - } - } - else if( nvars <= 3 ) - { - double value[3] = {0,0,0}; - for(size_t n = 0; n < ndata; ++n) - { - out.write(reinterpret_cast(&gidx(n)),sizeof(int)); - for(size_t v=0; v < nvars; ++v) - value[v] = data(n,jlev*nvars+v); - out.write(reinterpret_cast(&value),sizeof(double)*3); - } - } - else if( nvars <= 9 ) - { - double value[9] = { - 0,0,0, - 0,0,0, - 0,0,0 - }; - if( nvars == 4 ) - { - for(size_t n = 0; n < ndata; ++n) + if( field.levels() ) { + if( field.variables() ) { + auto data = gather ? array::make_view( field_glb ) : array::make_view( field ); + if( nvars == 1) { - out.write(reinterpret_cast(&gidx(n)),sizeof(int)); - for( int i=0; i<2; ++i ) + for( size_t n = 0; n < ndata; ++n ) { - for( int j=0; j<2; ++j ) - { - value[i*3+j] = data(n,jlev*nvars+i*2+j); - } + ASSERT( jlev*nvars < data.shape(1) ); + ASSERT( n < gidx.shape(0) ); + out << gidx(n) << " " << data(n,jlev,0) << "\n"; } - out.write(reinterpret_cast(&value),sizeof(double)*9); } - } - if( nvars == 9 ) - { - for(size_t n = 0; n < ndata; ++n) + else if( nvars <= 3 ) { - out.write(reinterpret_cast(&gidx(n)),sizeof(int)); - for( int i=0; i<3; ++i ) + std::vector data_vec(3,0.); + for( size_t n = 0; n < ndata; ++n ) { - for( int j=0; j<3; ++j ) - { - value[i*3+j] = data(n,jlev*nvars+i*3+j); - } + out << gidx(n); + for(size_t v=0; v < nvars; ++v) + data_vec[v] = data(n,jlev,v); + for( int v=0; v<3; ++v) + out << " " << data_vec[v]; + out << "\n"; } - out.write(reinterpret_cast(&value),sizeof(double)*9); } - } - } - out << "\n"; - } - else - { - if( nvars == 1) - { - for( size_t n = 0; n < ndata; ++n ) - { - ASSERT( jlev*nvars < data.shape(1) ); - ASSERT( n < gidx.shape(0) ); - out << gidx(n) << " " << data(n,jlev*nvars+0) << "\n"; - } - } - else if( nvars <= 3 ) - { - std::vector data_vec(3,0.); - for( size_t n = 0; n < ndata; ++n ) - { - out << gidx(n); - for(size_t v=0; v < nvars; ++v) - data_vec[v] = data(n,jlev*nvars+v); - for( int v=0; v<3; ++v) - out << " " << data_vec[v]; - out << "\n"; - } - } - else if( nvars <= 9 ) - { - std::vector data_vec(9,0.); + else if( nvars <= 9 ) + { + std::vector data_vec(9,0.); - if( nvars == 4 ) - { - for( size_t n = 0; n < ndata; ++n ) { - for( int i=0; i<2; ++i ) { - for( int j=0; j<2; ++j ) { - data_vec[i*3+j] = data(n,jlev*nvars+i*2+j); + if( nvars == 4 ) + { + for( size_t n = 0; n < ndata; ++n ) { + for( int i=0; i<2; ++i ) { + for( int j=0; j<2; ++j ) { + data_vec[i*3+j] = data(n,jlev,i*2+j); + } + } + out << gidx(n); + for( int v=0; v<9; ++v) + out << " " << data_vec[v]; + out << "\n"; + } + } + if( nvars == 9 ) + { + for( size_t n = 0; n < ndata; ++n ) { + for( int i=0; i<3; ++i ) { + for( int j=0; j<3; ++j ) { + data_vec[i*3+j] = data(n,jlev,i*2+j); + } + } + out << gidx(n); + for( int v=0; v<9; ++v) + out << " " << data_vec[v]; + out << "\n"; } } - out << gidx(n); - for( int v=0; v<9; ++v) - out << " " << data_vec[v]; - out << "\n"; + } + } else { + auto data = gather ? array::make_view( field_glb ) : array::make_view( field ); + for( size_t n = 0; n < ndata; ++n ) + { + ASSERT( jlev*nvars < data.shape(1) ); + ASSERT( n < gidx.shape(0) ); + out << gidx(n) << " " << data(n,jlev) << "\n"; } } - if( nvars == 9 ) - { - for( size_t n = 0; n < ndata; ++n ) { - for( int i=0; i<2; ++i ) { - for( int j=0; j<2; ++j ) { - data_vec[i*3+j] = data(n,jlev*nvars+i*2+j); + } else { + if( field.variables() ) { + auto data = gather ? array::make_view( field_glb ) : array::make_view( field ); + if( nvars == 1) + { + for( size_t n = 0; n < ndata; ++n ) + { + ASSERT( n < gidx.shape(0) ); + out << gidx(n) << " " << data(n,0) << "\n"; + } + } + else if( nvars <= 3 ) + { + std::vector data_vec(3,0.); + for( size_t n = 0; n < ndata; ++n ) + { + out << gidx(n); + for(size_t v=0; v < nvars; ++v) + data_vec[v] = data(n,v); + for( int v=0; v<3; ++v) + out << " " << data_vec[v]; + out << "\n"; + } + } + else if( nvars <= 9 ) + { + std::vector data_vec(9,0.); + + if( nvars == 4 ) + { + for( size_t n = 0; n < ndata; ++n ) { + for( int i=0; i<2; ++i ) { + for( int j=0; j<2; ++j ) { + data_vec[i*3+j] = data(n,i*2+j); + } + } + out << gidx(n); + for( int v=0; v<9; ++v) + out << " " << data_vec[v]; + out << "\n"; + } + } + if( nvars == 9 ) + { + for( size_t n = 0; n < ndata; ++n ) { + for( int i=0; i<3; ++i ) { + for( int j=0; j<3; ++j ) { + data_vec[i*3+j] = data(n,i*2+j); + } + } + out << gidx(n); + for( int v=0; v<9; ++v) + out << " " << data_vec[v]; + out << "\n"; } } - out << gidx(n); - for( int v=0; v<9; ++v) - out << " " << data_vec[v]; - out << "\n"; + } + } else { + auto data = gather ? array::make_view( field_glb ) : array::make_view( field ); + for( size_t n = 0; n < ndata; ++n ) + { + ASSERT( n < gidx.shape(0) ); + out << gidx(n) << " " << data(n) << "\n"; } } } From 90aa25d3ff0f1ff67e1c5cb6249e46273cb8bc2b Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 17 Jan 2018 08:47:20 +0000 Subject: [PATCH 249/355] ATLAS-138 Slicer can insert a dummy index to be ignored --- src/atlas/array/Range.h | 24 +++-- src/atlas/array/helpers/ArraySlicer.h | 144 ++++++++++++++++---------- src/tests/array/test_array_slicer.cc | 24 ++++- 3 files changed, 132 insertions(+), 60 deletions(-) diff --git a/src/atlas/array/Range.h b/src/atlas/array/Range.h index 3320c2907..734235fb1 100644 --- a/src/atlas/array/Range.h +++ b/src/atlas/array/Range.h @@ -34,6 +34,9 @@ class RangeFrom : public RangeBase { template < int Dim, typename View > int end(const View& view) const { return view.shape(Dim); } + template < typename View > + int end(const View& view, int i) const { return view.shape(i); } + private: int start_; }; @@ -61,6 +64,13 @@ class RangeAll : public RangeBase { template < int Dim, typename View > int end(const View& view) const { return view.shape(Dim); } + + template < typename View > + int end(const View& view, int i) const { return view.shape(i); } + +}; + +class RangeDummy : public RangeBase { }; //------------------------------------------------------------------------------ @@ -71,15 +81,17 @@ class RangeAll : public RangeBase { class Range : public helpers::RangeBase{ private: - using From = helpers::RangeFrom; - using To = helpers::RangeTo; - using All = helpers::RangeAll; + using From = helpers::RangeFrom; + using To = helpers::RangeTo; + using All = helpers::RangeAll; + using Dummy = helpers::RangeDummy; public: - static From from(int start) { return From(start); } - static To to(int end) { return To(end); } - static All all() { return All(); } + static From from(int start) { return From(start); } + static To to(int end) { return To(end); } + static All all() { return All(); } + static Dummy dummy() { return Dummy(); } public: diff --git a/src/atlas/array/helpers/ArraySlicer.h b/src/atlas/array/helpers/ArraySlicer.h index 4e3a34f7f..861fb927a 100644 --- a/src/atlas/array/helpers/ArraySlicer.h +++ b/src/atlas/array/helpers/ArraySlicer.h @@ -96,6 +96,10 @@ ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(8); ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(9); #undef ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION +template +struct SliceRank { + static constexpr int value{ SliceRank_impl::value }; +}; template< typename View, bool constness = false > @@ -118,11 +122,6 @@ class ArraySlicer { view_(view) { } - template - struct SliceRank { - static constexpr int value{ SliceRank_impl::value }; - }; - template struct Slice { using type = typename get_slice_type< @@ -165,120 +164,159 @@ class ArraySlicer { }; template< typename Int > - static int start( Int idx ) { - return idx; + static int offset_part( View& view, int& i_view, Int idx ) { + return idx * view.stride(i_view++); + } + + static int offset_part( View& view, int& i_view, Range range ) { + return range.start() * view.stride(i_view++); } - static int start( Range range ) { - return range.start(); + static int offset_part( View& view, int& i_view, RangeAll range ) { + return range.start() * view.stride(i_view++); } - static int start( RangeAll range ) { - return range.start(); + static int offset_part( View& view, int& i_view, RangeTo range ) { + return range.start() * view.stride(i_view++); } - static int start( RangeTo range ) { - return range.start(); + static int offset_part( View& view, int& i_view, RangeFrom range ) { + return range.start() * view.stride(i_view++); } - static int start( RangeFrom range ) { - return range.start(); + static int offset_part( View& , int& /*i_view*/, RangeDummy ) { + return 0; } template < int Dim, typename Int, typename... Ints > - static constexpr int offset_part(View& view, const Int idx, const Ints... next_idx) { - return start(idx)*view.stride(Dim) + offset_part( view, next_idx... ); + static int offset_remaining(View& view, int& i_view, const Int idx, const Ints... next_idx) { + return offset_part(view,i_view,idx) + offset_remaining( view, i_view, next_idx... ); } template < int Dim, typename Int > - static constexpr int offset_part(View& view, const Int last_idx) { - return start(last_idx)*view.stride(Dim); + static int offset_remaining(View& view, int& i_view, const Int last_idx) { + return offset_part(view,i_view,last_idx); } template < typename... Args > - static constexpr int offset(View& view, const Args... args) { - return offset_part<0>(view,args...); + static int offset(View& view, const Args... args) { + int i_view(0); + return offset_remaining<0>(view,i_view,args...); } template< int Dim, typename Shape, typename Int > - static void update_shape( View&, Shape&, int& /*i*/, const Int& /*index*/ ){ + static void update_shape( View&, Shape&, int& i_view, int& /*i_slice*/, const Int& /*index*/ ){ // do nothing + ++i_view; } template< int Dim, typename Shape > - static void update_shape( View&, Shape& shape, int& i, const Range range ){ - shape[i++] = range.end()-range.start(); + static void update_shape( View&, Shape& shape, int& i_view, int& i_slice, const Range range ){ + shape[i_slice] = range.end()-range.start(); + ++i_slice; + ++i_view; } template< int Dim, typename Shape > - static void update_shape( View& view, Shape& shape, int& i, const RangeAll range ){ - shape[i++] = range.end(view)-range.start(); + static void update_shape( View& view, Shape& shape, int& i_view, int& i_slice, const RangeAll range ){ + shape[i_slice] = range.end(view,i_view)-range.start(); + ++i_slice; + ++i_view; } template< int Dim, typename Shape > - static void update_shape( View& view, Shape& shape, int& i, const RangeFrom range ){ - shape[i++] = range.end(view)-range.start(); + static void update_shape( View& view, Shape& shape, int& i_view, int& i_slice, const RangeFrom range ){ + shape[i_slice] = range.end(view,i_view)-range.start(); + ++i_slice; + ++i_view; } template< int Dim, typename Shape > - static void update_shape( View&, Shape& shape, int& i, const RangeTo range ){ - shape[i++] = range.end()-range.start(); + static void update_shape( View&, Shape& shape, int& i_view, int& i_slice, const RangeTo range ){ + shape[i_slice] = range.end()-range.start(); + ++i_slice; + ++i_view; + } + + template< int Dim, typename Shape > + static void update_shape( View&, Shape& shape, int& /*i_view*/, int& i_slice, const RangeDummy ){ + shape[i_slice] = 1; + ++i_slice; + // no update of i_view for dummy-dimension } template< int Dim, typename Shape, typename Int, typename... Ints > - static void shape_part( View& view, Shape& shape, int& i, const Int idx, const Ints... next_idx ) { - update_shape(view,shape,i,idx); - shape_part(view,shape,i,next_idx...); + static void shape_part( View& view, Shape& shape, int& i_view, int& i_slice, const Int idx, const Ints... next_idx ) { + update_shape(view,shape,i_view,i_slice,idx); + shape_part(view,shape,i_view,i_slice,next_idx...); } template< int Dim, typename Shape, typename Int > - static void shape_part( View& view, Shape& shape, int& i, const Int idx) { - update_shape(view,shape,i,idx); + static void shape_part( View& view, Shape& shape, int& i_view, int& i_slice, const Int idx) { + update_shape(view,shape,i_view,i_slice,idx); } template< typename... Args > static typename array::type shape( View& view, const Args... args ) { typename array::type result; - int i(0); - shape_part<0>(view,result,i,args...); + int i_slice(0); + int i_view(0); + shape_part<0>(view,result,i_view,i_slice,args...); + ASSERT( i_view == view.rank() ); return result; } template - static void update_strides( View&, Strides&, int& /*i*/, const Int& /*idx*/) { + static void update_strides( View&, Strides&, int& i_view, int& /*i_slice*/, const Int& /*idx*/) { // do nothing + ++i_view; } template - static void update_strides( View& view, Strides& strides, int& i, const Range& /*range*/ ) { - strides[i++] = view.stride(Dim); + static void update_strides( View& view, Strides& strides, int& i_view, int& i_slice, const Range& /*range*/ ) { + strides[i_slice] = view.stride(i_view); + ++i_slice; + ++i_view; + } + template + static void update_strides( View& view, Strides& strides, int& i_view, int& i_slice, const RangeFrom& /*range*/ ) { + strides[i_slice] = view.stride(i_view); + ++i_slice; + ++i_view; } template - static void update_strides( View& view, Strides& strides, int& i, const RangeFrom& /*range*/ ) { - strides[i++] = view.stride(Dim); + static void update_strides( View& view, Strides& strides, int& i_view, int& i_slice, const RangeTo& /*range*/ ) { + strides[i_slice] = view.stride(i_view); + ++i_slice; + ++i_view; } template - static void update_strides( View& view, Strides& strides, int& i, const RangeTo& /*range*/ ) { - strides[i++] = view.stride(Dim); + static void update_strides( View& view, Strides& strides, int& i_view, int& i_slice, const RangeAll& /*range*/ ) { + strides[i_slice] = view.stride(i_view); + ++i_slice; + ++i_view; } template - static void update_strides( View& view, Strides& strides, int& i, const RangeAll& /*range*/ ) { - strides[i++] = view.stride(Dim); + static void update_strides( View& view, Strides& strides, int& /*i_view*/, int& i_slice, const RangeDummy& /*range*/ ) { + strides[i_slice] = 0; + ++i_slice; } template< int Dim, typename Strides, typename Int, typename... Ints > - static void strides_part( View& view, Strides& strides, int& i, const Int idx, const Ints... next_idx ) { - update_strides(view,strides,i,idx); - strides_part(view,strides,i,next_idx...); + static void strides_part( View& view, Strides& strides, int& i_view, int& i_slice, const Int idx, const Ints... next_idx ) { + update_strides(view,strides,i_view,i_slice,idx); + strides_part(view,strides,i_view,i_slice,next_idx...); } template< int Dim, typename Strides, typename Int > - static void strides_part( View& view, Strides& strides, int& i, const Int idx) { - update_strides(view,strides,i,idx); + static void strides_part( View& view, Strides& strides, int& i_view, int& i_slice, const Int idx) { + update_strides(view,strides,i_view,i_slice,idx); } template< typename... Args > static typename array::type strides(View& view, const Args... args ) { typename array::type result; - int i(0); - strides_part<0>(view,result,i,args...); + int i_slice(0); + int i_view(0); + strides_part<0>(view,result,i_view,i_slice,args...); + ASSERT( i_view == view.rank() ); return result; } diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index 3a2f5d8df..f27d1592b 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -61,7 +61,6 @@ CASE( "test_SliceRank" ){ static_assert( SliceRank_impl<3,Range,int ,Range>::value == 2, "failed" ); static_assert( SliceRank_impl<3,int ,int ,Range>::value == 1, "failed" ); static_assert( SliceRank_impl<3,int ,Range,Range>::value == 2, "failed" ); - } #if 1 @@ -101,6 +100,16 @@ CASE( "test_array_slicer_1d" ) static_assert( std::is_same< decltype(slice) , Reference >::value, "failed" ); } + { + auto slice = slicer.apply(Range::all(),Range::dummy()); + static_assert( std::is_same< decltype(slice) , LocalView >::value, "failed" ); + EXPECT( slice.rank() == 2 ); + EXPECT( slice.shape(0) == 10 ); + EXPECT( slice.shape(1) == 1 ); + EXPECT( slice(0,0) == 0 ); + EXPECT( slice(1,0) == 1 ); + } + } #endif CASE( "test_array_slicer_2d" ) @@ -129,6 +138,19 @@ CASE( "test_array_slicer_2d" ) //static_assert( std::is_same< decltype(slice) , double& >::value, "failed" ); } + { + auto slice = slicer.apply(Range{0,2},Range::dummy(),Range{1,3}); + static_assert( std::is_same< decltype(slice) , LocalView >::value, "failed" ); + EXPECT( slice.rank() == 3 ); + EXPECT( slice.shape(0) == 2 ); + EXPECT( slice.shape(1) == 1 ); + EXPECT( slice.shape(2) == 2 ); + EXPECT( slice(0,0,0) == 12 ); + EXPECT( slice(0,0,1) == 13 ); + EXPECT( slice(1,0,0) == 22 ); + EXPECT( slice(1,0,1) == 23 ); + } + } CASE( "test_array_slicer_3d" ) From ee38a8eb2ef0c1c806c85801e57604d496d304aa Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 17 Jan 2018 08:49:00 +0000 Subject: [PATCH 250/355] ATLAS-142 fvm::Nabla works with GT-cuda backend --- src/atlas/field/detail/FieldImpl.cc | 2 + src/atlas/mesh/Nodes.cc | 2 + src/atlas/numerics/fvm/Nabla.cc | 129 +++++++++++++--------------- 3 files changed, 63 insertions(+), 70 deletions(-) diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index 138c31939..92c72b914 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -69,6 +69,7 @@ FieldImpl::FieldImpl( array_->attach(); rename(name); set_levels(0); + set_variables(0); } @@ -78,6 +79,7 @@ FieldImpl::FieldImpl(const std::string& name, array::Array* array) array_->attach(); rename(name); set_levels(0); + set_variables(0); } FieldImpl::~FieldImpl() diff --git a/src/atlas/mesh/Nodes.cc b/src/atlas/mesh/Nodes.cc index db53be181..7cb8a18e8 100644 --- a/src/atlas/mesh/Nodes.cc +++ b/src/atlas/mesh/Nodes.cc @@ -30,7 +30,9 @@ Nodes::Nodes(): size_(0) remote_index_ = add( Field("remote_idx", make_datatype(), make_shape(size())) ); partition_ = add( Field("partition", make_datatype(), make_shape(size())) ); xy_ = add( Field("xy", make_datatype(), make_shape(size(),2)) ); + xy_.set_variables(2); lonlat_ = add( Field("lonlat", make_datatype(), make_shape(size(),2)) ); + lonlat_.set_variables(2); ghost_ = add( Field("ghost", make_datatype(), make_shape(size())) ); edge_connectivity_ = &add( new Connectivity("edge") ); diff --git a/src/atlas/numerics/fvm/Nabla.cc b/src/atlas/numerics/fvm/Nabla.cc index 82a1e6a3c..e708a804c 100644 --- a/src/atlas/numerics/fvm/Nabla.cc +++ b/src/atlas/numerics/fvm/Nabla.cc @@ -25,6 +25,7 @@ // ======================================================= using Topology = atlas::mesh::Nodes::Topology; +using Range = atlas::array::Range; namespace atlas { namespace numerics { @@ -76,23 +77,10 @@ void Nabla::setup() void Nabla::gradient(const Field &field, Field &grad_field) const { - if( field.levels() ) - { - if( field.rank() == 2 ) - return gradient_of_scalar(field,grad_field); - if( field.rank() == 3 && field.shape(2) == 1 ) - return gradient_of_scalar(field,grad_field); - if( field.rank() == 3 && field.shape(2) > 1 ) - return gradient_of_vector(field,grad_field); - } - else - { - if( field.rank() == 1 ) - return gradient_of_scalar(field,grad_field); - if( field.rank() == 2 && field.shape(1) == 1 ) - return gradient_of_scalar(field,grad_field); - if( field.rank() == 2 && field.shape(1) > 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); } throw eckit::SeriousBug("Cannot figure out if field is a scalar or vector field",Here()); } @@ -112,22 +100,21 @@ void Nabla::gradient_of_scalar(const Field& scalar_field, Field& grad_field) con if( (grad_field.levels() ? grad_field.levels() : 1) != nlev ) throw eckit::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()) + : array::make_view( scalar_field ).slice(Range::all(),Range::dummy()); + auto grad = grad_field.levels() ? array::make_view( grad_field ).slice(Range::all(),Range::all(),Range::all()) + : array::make_view( grad_field ).slice(Range::all(),Range::dummy(),Range::all()); - const array::LocalView scalar ( array::make_storageview(scalar_field).data(), - array::make_shape(nnodes,nlev) ); - array::LocalView grad ( array::make_storageview(grad_field).data(), - array::make_shape(nnodes,nlev,2) ); - - const array::ArrayView lonlat_deg = array::make_view( nodes.lonlat() ); - const array::ArrayView dual_volumes = array::make_view( nodes.field("dual_volumes") ); - const array::ArrayView dual_normals = array::make_view( edges.field("dual_normals") ); - const array::ArrayView node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); + const auto lonlat_deg = array::make_view( nodes.lonlat() ); + const auto dual_volumes = array::make_view( nodes.field("dual_volumes") ); + const auto dual_normals = array::make_view( edges.field("dual_normals") ); + const auto node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); const mesh::Connectivity& node2edge = nodes.edge_connectivity(); const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); array::ArrayT avgS_arr( nedges,nlev,2ul ); - array::ArrayView avgS = array::make_view(avgS_arr); + auto avgS = array::make_view(avgS_arr); const double scale = deg2rad*deg2rad*radius; @@ -192,11 +179,10 @@ void Nabla::gradient_of_vector(const Field &vector_field, Field &grad_field) con if( vector_field.levels() != nlev ) throw eckit::AssertionFailed("gradient field should have same number of levels",Here()); - - const array::LocalView vector ( array::make_storageview(vector_field).data(), - array::make_shape(nnodes,nlev,2) ); - array::LocalView grad ( array::make_storageview(grad_field).data(), - array::make_shape(nnodes,nlev,2,2) ); + const auto vector = vector_field.levels() ? array::make_view( vector_field ).slice(Range::all(),Range::all(),Range::all()) + : array::make_view( vector_field ).slice(Range::all(),Range::dummy(),Range::all()); + auto grad = grad_field.levels() ? array::make_view( grad_field ).slice(Range::all(),Range::all(),Range::all()) + : array::make_view( grad_field ).slice(Range::all(),Range::dummy(),Range::all()); const array::ArrayView lonlat_deg = array::make_view( nodes.lonlat() ); const array::ArrayView dual_volumes = array::make_view( nodes.field("dual_volumes") ); @@ -207,11 +193,13 @@ void Nabla::gradient_of_vector(const Field &vector_field, Field &grad_field) con const mesh::Connectivity& node2edge = nodes.edge_connectivity(); const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); - array::ArrayT avgS_arr( nedges,nlev,2ul,2ul ); - array::ArrayView avgS = array::make_view(avgS_arr); + array::ArrayT avgS_arr( nedges,nlev,4ul ); + array::ArrayView avgS = array::make_view(avgS_arr); const double scale = deg2rad*deg2rad*radius; + enum { LONdLON = 0, LONdLAT = 1, LATdLON = 2, LATdLAT = 3 }; + atlas_omp_parallel { atlas_omp_for( size_t jedge=0; jedge vector ( array::make_storageview(vector_field).data(), - array::make_shape(nnodes,nlev,2) ); - array::LocalView div ( array::make_storageview(div_field).data(), - array::make_shape(nnodes,nlev) ); + const auto vector = vector_field.levels() ? array::make_view( vector_field ).slice(Range::all(),Range::all(),Range::all()) + : array::make_view( vector_field ).slice(Range::all(),Range::dummy(),Range::all()); + auto div = div_field.levels() ? array::make_view( div_field ).slice(Range::all(),Range::all()) + : array::make_view( div_field ).slice(Range::all(),Range::dummy()); - const array::ArrayView lonlat_deg = array::make_view( nodes.lonlat() ); - const array::ArrayView dual_volumes = array::make_view( nodes.field("dual_volumes") ); - const array::ArrayView dual_normals = array::make_view( edges.field("dual_normals") ); - const array::ArrayView edge_is_pole = array::make_view( edges.field("is_pole_edge") ); - const array::ArrayView node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); + const auto lonlat_deg = array::make_view( nodes.lonlat() ); + const auto dual_volumes = array::make_view( nodes.field("dual_volumes") ); + const auto dual_normals = array::make_view( edges.field("dual_normals") ); + const auto edge_is_pole = array::make_view( edges.field("is_pole_edge") ); + const auto node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); const mesh::Connectivity& node2edge = nodes.edge_connectivity(); const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); @@ -385,16 +373,17 @@ void Nabla::curl(const Field& vector_field, Field& curl_field) const if( curl_field.levels() != nlev ) throw eckit::AssertionFailed("curl field should have same number of levels",Here()); - const array::LocalView vector ( array::make_storageview(vector_field).data(), - array::make_shape(nnodes,nlev,2) ); - array::LocalView curl ( array::make_storageview(curl_field).data(), - array::make_shape(nnodes,nlev) ); - const array::ArrayView lonlat_deg = array::make_view( nodes.lonlat() ); - const array::ArrayView dual_volumes = array::make_view( nodes.field("dual_volumes") ); - const array::ArrayView dual_normals = array::make_view( edges.field("dual_normals") ); - const array::ArrayView edge_is_pole = array::make_view( edges.field("is_pole_edge") ); - const array::ArrayView node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); + const auto vector = vector_field.levels() ? array::make_view( vector_field ).slice(Range::all(),Range::all(),Range::all()) + : array::make_view( vector_field ).slice(Range::all(),Range::dummy(),Range::all()); + auto curl = curl_field.levels() ? array::make_view( curl_field ).slice(Range::all(),Range::all()) + : array::make_view( curl_field ).slice(Range::all(),Range::dummy()); + + const auto lonlat_deg = array::make_view( nodes.lonlat() ); + const auto dual_volumes = array::make_view( nodes.field("dual_volumes") ); + const auto dual_normals = array::make_view( edges.field("dual_normals") ); + const auto edge_is_pole = array::make_view( edges.field("is_pole_edge") ); + const auto node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); const mesh::Connectivity& node2edge = nodes.edge_connectivity(); const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); From f8ce713e830d82855e4431f1d3a5059f6a91bb99 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 17 Jan 2018 11:52:19 +0000 Subject: [PATCH 251/355] ATLAS-142 NodeColumns statistics not using make_storageview --- src/atlas/functionspace/NodeColumns.cc | 159 ++++++++++-------- src/tests/functionspace/test_functionspace.cc | 28 +-- src/tests/numerics/fctest_fvm_nabla.F90 | 23 ++- 3 files changed, 117 insertions(+), 93 deletions(-) diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 0b0778fa1..813fc287e 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -29,7 +29,6 @@ #include "atlas/parallel/Checksum.h" #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/ErrorHandling.h" -#include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" #undef atlas_omp_critical_ordered #define atlas_omp_critical_ordered atlas_omp_critical @@ -50,40 +49,53 @@ namespace { template array::LocalView make_leveled_view(const Field &field) { - if( field.levels() ) - return array::LocalView ( array::make_storageview(field).data(), - array::make_shape(field.shape(0),field.shape(1),field.stride(1)) ); - else - return array::LocalView ( array::make_storageview(field).data(), - array::make_shape(field.shape(0),1,field.stride(0)) ); + using namespace array; + if( field.levels() ) { + 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() ); + } + } + else { + if( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); + } else { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + } + } } template -array::LocalView surface_view(const Field &field) +array::LocalView make_leveled_scalar_view(const Field &field) { - return array::LocalView ( array::make_storageview(field).data(), - array::make_shape(field.shape(0),field.stride(0)) ); + using namespace array; + if( field.levels() ) + return make_view( field ).slice( Range::all(), Range::all() ); + else + return make_view( field ).slice( Range::all(), Range::dummy() ); } template -array::LocalView make_leveled_scalar_view(const Field &field) +array::LocalView make_surface_view(const Field &field) { - if( field.levels() ) - return array::LocalView ( array::make_storageview(field).data(), - array::make_shape(field.shape(0),field.shape(1)) ); + using namespace array; + if( field.variables() ) + return make_view( field ).slice( Range::all(), Range::all() ); else - return array::LocalView ( array::make_storageview(field).data(), - array::make_shape(field.shape(0),1) ); + return make_view( field ).slice( Range::all(), Range::dummy() ); } template -array::LocalView make_surface_scalar_view(const Field &field) +array::LocalView make_per_level_view(const Field &field) { - return array::LocalView ( array::make_storageview(field).data(), - array::make_shape(field.size()) ); + using namespace array; + if( field.rank() == 2 ) + return make_view( field ).slice( Range::all(), Range::all() ); + else + return make_view( field ).slice( Range::all(), Range::dummy() ); } - } NodeColumns::NodeColumns( Mesh mesh ) : @@ -726,11 +738,9 @@ void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& s shape.push_back(field.shape(j)); sum.resize(shape); - const array::LocalView arr = make_leveled_view(field); + auto arr = make_leveled_view(field); - array::LocalView sum_per_level( - array::make_storageview(sum).data(), - array::make_shape(sum.shape(0),sum.stride(0)) ); + auto sum_per_level = make_per_level_view( sum ); for( size_t l=0; l(global).data(), - array::make_storageview(global).data()+global.size(),0.); - + result = 0; + auto glb = array::make_view( global ); + for( size_t jnode=0; jnode arr = make_leveled_scalar_view(field); - Field surface_field = fs.createField(option::name("surface")); - array::LocalView surface = make_surface_scalar_view( surface_field ); + Field surface_field = fs.createField(option::name("surface") | option::levels(false)); + auto surface = array::make_view( surface_field ); for( size_t n=0; n(option::name("global")|option::variables(field.variables())|option::levels(field.levels())| option::global() ); + Field global = fs.createField( field, option::name("global")|option::global() ); fs.gather(field,global); if( parallel::mpi::comm().rank() == 0 ) { - const array::LocalView glb( array::make_storageview(global).data(), - array::make_shape(global.shape(0),global.stride(0)) ); + const auto glb = make_surface_view( global ); for( size_t n=0; n arr = make_leveled_view(field); + const auto arr = make_leveled_view(field); - Field surface_field = fs.createField(option::name("surface")|option::variables(nvar)); - array::LocalView surface = surface_view( surface_field ); + Field surface_field = fs.createField(option::name("surface")|option::variables(nvar)|option::levels(false)); + auto surface = make_surface_view( surface_field ); for( size_t n=0; n sum ( array::make_storageview(sumfield).data(), - array::make_shape(sumfield.shape(0),sumfield.stride(0)) ); + auto sum = make_per_level_view( sumfield ); for( size_t l=0; l(sumfield).data(),sumfield.size(),root); + std::vector sum_array(sumfield.size()); + if( parallel::mpi::comm().rank() == root ) { + size_t c(0); + for( size_t l=0; l min( - array::make_storageview(min_field).data(), - array::make_shape(min_field.shape(0),min_field.stride(0)) ); + auto min = make_per_level_view( min_field ); for( size_t l=0; l max ( - array::make_storageview(max_field).data(), - array::make_shape(max_field.shape(0),max_field.stride(0)) ); + auto max = make_per_level_view( max_field ); for( size_t l=0; l min( - array::make_storageview(min_field).data(), - array::make_shape(min_field.shape(0),min_field.stride(0)) ); + auto min = make_per_level_view( min_field ); + auto glb_idx = make_per_level_view( glb_idx_field ); for( size_t l=0; l glb_idx( - array::make_storageview(glb_idx_field).data(), - array::make_shape(glb_idx_field.shape(0),glb_idx_field.stride(0)) ); - - atlas_omp_parallel { array::ArrayT min_private(min.shape(0),min.shape(1)); @@ -1708,9 +1721,8 @@ void dispatch_maximum_and_location_per_level( const NodeColumns& fs, const Field max_field.resize(shape); glb_idx_field.resize(shape); const size_t nvar = arr.shape(2); - array::LocalView max( - array::make_storageview(max_field).data(), - array::make_shape(max_field.shape(0),max_field.stride(0)) ); + auto max = make_per_level_view( max_field ); + auto glb_idx = make_per_level_view( glb_idx_field ); for( size_t l=0; l glb_idx( - array::make_storageview(glb_idx_field).data(), - array::make_shape(glb_idx_field.shape(0),glb_idx_field.stride(0)) ); - atlas_omp_parallel { array::ArrayT max_private(max.shape(0),max.shape(1)); @@ -1826,9 +1834,11 @@ template< typename T > void dispatch_mean_per_level( const NodeColumns& fs, const Field& field, Field& mean, size_t& N ) { dispatch_sum_per_level(fs,field,mean,N); - T* rawdata = array::make_storageview(mean).data(); - for( size_t j=0; j(N); + auto view = make_per_level_view( mean ); + for( size_t l=0; l(N); + } } } @@ -1901,9 +1911,9 @@ void dispatch_mean_and_standard_deviation_per_level( const NodeColumns& fs, cons { dispatch_mean_per_level(fs,field,mean,N); Field squared_diff_field = fs.createField(option::name("sqr_diff")|option::levels(field.levels())|option::variables(field.variables())); - array::LocalView squared_diff = make_leveled_view( squared_diff_field ); - array::LocalView values = make_leveled_view( field ); - array::LocalView mu( array::make_storageview(mean).data(), array::make_shape(values.shape(1),values.shape(2)) ); + auto squared_diff = make_leveled_view( squared_diff_field ); + auto values = make_leveled_view( field ); + auto mu = make_per_level_view( mean ); const size_t npts = values.shape(0); atlas_omp_parallel_for( size_t n=0; n(fs,squared_diff_field,stddev,N); - T* sigma = array::make_storageview(stddev).data(); - const size_t size = stddev.size(); - atlas_omp_parallel_for( size_t j=0; j( stddev ); + atlas_omp_for( size_t l=0; l(), array::make_shape(nb_levels) ); fs.maximumPerLevel(field,max_per_level); - max_per_level.dump(Log::info()); + //max_per_level.dump(Log::info()); fs.minimumPerLevel(field,min_per_level); - min_per_level.dump(Log::info()); + //min_per_level.dump(Log::info()); fs.sumPerLevel(field,sum_per_level,N); - sum_per_level.dump(Log::info()); + //sum_per_level.dump(Log::info()); fs.meanPerLevel(field,mean_per_level,N); - mean_per_level.dump(Log::info()); + //mean_per_level.dump(Log::info()); fs.meanAndStandardDeviationPerLevel(field,mean_per_level,stddev_per_level,N); - mean_per_level.dump(Log::info()); - stddev_per_level.dump(Log::info()); + //mean_per_level.dump(Log::info()); + //stddev_per_level.dump(Log::info()); fs.orderIndependentSumPerLevel(field,sum_per_level,N); - sum_per_level.dump(Log::info()); + //sum_per_level.dump(Log::info()); } @@ -461,23 +461,23 @@ CASE( "test_functionspace_NodeColumns" ) Field gidx_per_level ( "gidx", array::make_datatype(), array::make_shape(nb_levels,nvar) ); fs.maximumPerLevel(field,max_per_level); - max_per_level.dump(Log::info()); + //max_per_level.dump(Log::info()); fs.minimumPerLevel(field,min_per_level); - min_per_level.dump(Log::info()); + //min_per_level.dump(Log::info()); fs.sumPerLevel(field,sum_per_level,N); - sum_per_level.dump(Log::info()); + //sum_per_level.dump(Log::info()); fs.meanPerLevel(field,mean_per_level,N); - mean_per_level.dump(Log::info()); + //mean_per_level.dump(Log::info()); fs.meanAndStandardDeviationPerLevel(field,mean_per_level,stddev_per_level,N); - mean_per_level.dump(Log::info()); - stddev_per_level.dump(Log::info()); + //mean_per_level.dump(Log::info()); + //stddev_per_level.dump(Log::info()); fs.orderIndependentSumPerLevel(field,sum_per_level,N); - sum_per_level.dump(Log::info()); + //sum_per_level.dump(Log::info()); } diff --git a/src/tests/numerics/fctest_fvm_nabla.F90 b/src/tests/numerics/fctest_fvm_nabla.F90 index cf34e796d..4d38cc029 100644 --- a/src/tests/numerics/fctest_fvm_nabla.F90 +++ b/src/tests/numerics/fctest_fvm_nabla.F90 @@ -366,9 +366,12 @@ end module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture TEST( test_nabla ) type(timer_type) :: timer; integer :: jiter, niter -real(c_double) :: norm_native -real(c_double) :: norm_fortran -real(c_double) :: checked_value = 0.13215712584 +real(c_double), allocatable :: norm_native(:) +real(c_double), allocatable :: norm_fortran(:) +real(c_double) :: checked_value_X = 1.7893197319163668E-016 +real(c_double) :: checked_value_Y = -1.0547670904632068E-006 + +type(atlas_Output) :: gmsh call node_columns%halo_exchange(varfield) @@ -379,11 +382,14 @@ end module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture do jiter = 1,niter call nabla%gradient(varfield,gradfield) enddo + write(0,*) "time elapsed: ", timer%elapsed() +call node_columns%halo_exchange(gradfield) call node_columns%mean(gradfield,norm_native) write(0,*) "mean : ", norm_native -FCTEST_CHECK_CLOSE( norm_native, checked_value, 1.e-6_c_double ) +FCTEST_CHECK_CLOSE( norm_native(1), checked_value_X, 1.e-12_c_double ) +FCTEST_CHECK_CLOSE( norm_native(2), checked_value_Y, 1.e-12_c_double ) write(0,*) "" @@ -392,12 +398,19 @@ end module fctest_atlas_nabla_EdgeBasedFiniteVolume_Fixture do jiter = 1,niter CALL FV_GRADIENT(var,grad) enddo + write(0,*) "time elapsed: ", timer%elapsed() +call node_columns%halo_exchange(gradfield) call node_columns%mean(gradfield,norm_fortran) write(0,*) "mean : ", norm_fortran -FCTEST_CHECK_CLOSE( norm_fortran, checked_value, 1.e-6_c_double ) +FCTEST_CHECK_CLOSE( norm_native(1), checked_value_X, 1.e-12_c_double ) +FCTEST_CHECK_CLOSE( norm_native(2), checked_value_Y, 1.e-12_c_double ) +gmsh = atlas_output_Gmsh("out_atlas_fctest_fvm_nabla.msh", levels=[10]) +call gmsh%write( mesh ) +call gmsh%write( varfield ) +call gmsh%write( gradfield ) END_TEST ! ----------------------------------------------------------------------------- From 2e14a4356333df8e668f934401e6524259bee89b Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 17 Jan 2018 14:36:46 +0000 Subject: [PATCH 252/355] ATLAS-142 Fix nodecolumns statistics --- src/atlas/functionspace/NodeColumns.cc | 23 +++++++++++-------- src/atlas/functionspace/StructuredColumns.cc | 21 ++++++++++++----- src/tests/functionspace/test_functionspace.cc | 8 +++---- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 813fc287e..27822408b 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -834,8 +834,9 @@ void dispatch_order_independent_sum( const NodeColumns& fs , const Field& field, auto surface = array::make_view( surface_field ); for( size_t n=0; n void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) { - size_t nvar = field.stride(0); + size_t nvar = field.variables(); result.resize(nvar); for( size_t j=0; j(field); Field surface_field = fs.createField(option::name("surface")|option::variables(nvar)|option::levels(false)); auto surface = make_surface_view( surface_field ); + atlas_omp_for( size_t n=0; n( min_field ); for( size_t l=0; l( max_field ); for( size_t l=0; l array::LocalView make_leveled_view(const Field &field) { - if( field.levels() ) - return array::LocalView ( array::make_storageview(field).data(), - array::make_shape(field.shape(0),field.shape(1),field.stride(1)) ); - else - return array::LocalView ( array::make_storageview(field).data(), - array::make_shape(field.shape(0),1,field.stride(0)) ); + using namespace array; + if( field.levels() ) { + 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() ); + } + } + else { + if( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); + } else { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + } + } } template diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index f1699edce..72e9b9fd3 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -282,11 +282,11 @@ CASE( "test_functionspace_NodeColumns" ) auto vec_arr = array::make_view( field ); vec_arr.assign( parallel::mpi::comm().rank()+1 ); fs.maximum(field, max); - std::vector check_max(field.stride(0), parallel::mpi::comm().size()); + std::vector check_max(field.variables(), parallel::mpi::comm().size()); EXPECT( max == check_max ); fs.minimum(field,min); - std::vector check_min(field.stride(0), 1); + std::vector check_min(field.variables(), 1); EXPECT( min == check_min ); fs.maximumAndLocation(field,max, gidx_max); @@ -404,7 +404,7 @@ CASE( "test_functionspace_NodeColumns" ) if(1) { const Field& field = columns_vector_field; const functionspace::NodeColumns fs = nodes_fs; - size_t nvar = field.stride(1); + size_t nvar = field.variables(); std::vector max; std::vector min; std::vector sum; @@ -434,7 +434,7 @@ CASE( "test_functionspace_NodeColumns" ) Log::info() << "global index for minimum: " << gidx_min << std::endl; fs.orderIndependentSum(field,sum,N); - Log::info() << "sum: " << sum << std::endl; + Log::info() << "oisum: " << sum << std::endl; Log::info() << "N: " << N << std::endl; fs.mean(field,mean,N); From f8763128218b72d2ed4b6b7a04e212be77633491 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 18 Jan 2018 17:02:52 +0000 Subject: [PATCH 253/355] ATLAS-142 gather/scatter working with cuda-gt backend --- src/atlas/functionspace/EdgeColumns.cc | 58 ++++++--- src/atlas/functionspace/NodeColumns.cc | 33 ++--- src/atlas/functionspace/StructuredColumns.cc | 110 ++++++++-------- src/atlas/parallel/GatherScatter.h | 39 +++++- .../functionspace/test_structuredcolumns.cc | 5 +- src/tests/parallel/test_gather.cc | 123 +++++++++++++----- 6 files changed, 242 insertions(+), 126 deletions(-) diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 88dd8c54b..74336700e 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -41,6 +41,29 @@ namespace atlas { namespace functionspace { namespace detail { +namespace { +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() ); + } else { + return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); + } + } + else { + if( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); + } else { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + } + } +} +} + + void EdgeColumns::set_field_metadata(const eckit::Configuration& config, Field& field) const { field.set_functionspace(this); @@ -298,28 +321,29 @@ void EdgeColumns::gather( const FieldSet& local_fieldset, FieldSet& global_field size_t root(0); glb.metadata().get("owner",root); if ( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } else throw eckit::Exception("datatype not supported",Here()); } } + void EdgeColumns::gather( const Field& local, Field& global ) const { FieldSet local_fields; @@ -349,27 +373,29 @@ void EdgeColumns::scatter( const FieldSet& global_fieldset, FieldSet& local_fiel const size_t nb_fields = 1; size_t root(0); glb.metadata().get("owner",root); + if ( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } else throw eckit::Exception("datatype not supported",Here()); + glb.metadata().broadcast(loc.metadata(),root); loc.metadata().set("global",false); } diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 27822408b..039b1c9a0 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -420,28 +420,29 @@ void NodeColumns::gather( const FieldSet& local_fieldset, FieldSet& global_field glb.metadata().get("owner",root); if ( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather().gather( &loc_field, &glb_field, nb_fields, root ); } else throw eckit::Exception("datatype not supported",Here()); } } + void NodeColumns::gather( const Field& local, Field& global ) const { FieldSet local_fields; @@ -473,23 +474,23 @@ void NodeColumns::scatter( const FieldSet& global_fieldset, FieldSet& local_fiel glb.metadata().get("owner",root); if ( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); scatter().scatter( &glb_field, &loc_field, nb_fields, root ); } else throw eckit::Exception("datatype not supported",Here()); diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 98a5b6f75..845aba7c1 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -39,6 +39,44 @@ namespace detail { namespace { +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() ); + } else { + return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); + } + } + else { + if( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); + } else { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + } + } +} + +template +std::string checksum_3d_field(const parallel::Checksum& checksum, const Field& field ) +{ + array::LocalView values = make_leveled_view(field); + array::ArrayT surface_field( values.shape(0), values.shape(2) ); + array::ArrayView surface = array::make_view(surface_field); + const size_t npts = values.shape(0); + atlas_omp_for( size_t n=0; n() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); } else throw eckit::Exception("datatype not supported",Here()); @@ -707,23 +745,23 @@ void StructuredColumns::scatter( glb.metadata().get("owner",root); if ( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); } else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( array::make_storageview(glb).data(),glb.stride(0)); - parallel::Field loc_field( array::make_storageview(loc).data(),loc.stride(0)); + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); } else throw eckit::Exception("datatype not supported",Here()); @@ -751,46 +789,6 @@ void StructuredColumns::scatter( } // ---------------------------------------------------------------------------- -namespace { - -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() ); - } else { - return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); - } - } - else { - if( field.variables() ) { - return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); - } else { - return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); - } - } -} - -template -std::string checksum_3d_field(const parallel::Checksum& checksum, const Field& field ) -{ - array::LocalView values = make_leveled_view(field); - array::ArrayT surface_field( values.shape(0), values.shape(2) ); - array::ArrayView surface = array::make_view(surface_field); - const size_t npts = values.shape(0); - atlas_omp_for( size_t n=0; n(arr.data()); - var_rank = std::max(1,(int)arr.rank()-1); + var_rank = RANK; var_strides.resize(var_rank); var_shape.resize(var_rank); if( arr.rank()>1 ) { - size_t stride=1; - for( int j=RANK-1; j>0; --j ) { - var_strides[j-1] = stride; - var_shape[j-1] = arr.shape(j); - stride *= var_shape[j-1]; + var_strides[0] = arr.stride(0); + var_shape[0] = 1; + for( int j=1; j + Field( const array::LocalView& arr ) + { + data = const_cast(arr.data()); + + var_rank = RANK; + var_strides.resize(var_rank); + var_shape.resize(var_rank); + + if( arr.rank()>1 ) + { + var_strides[0] = arr.stride(0); + var_shape[0] = 1; + for( int j=1; j(loc).data(), loc_strides, loc_extents, 1, - make_storageview(glb).data(), glb_strides, glb_extents, 1, f.root ); + size_t loc_strides[] = {loc.stride(0),loc.stride(1)}; + size_t loc_extents[] = {1,loc.shape(1)}; + size_t glb_strides[] = {glb.stride(0),glb.stride(1)}; + size_t glb_extents[] = {1,glb.shape(1)}; + + f.gather_scatter.gather( loc.data(), loc_strides, loc_extents, 2, + glb.data(), glb_strides, glb_extents, 2, f.root ); } if( parallel::mpi::comm().rank() == f.root ) { + auto glbv = array::make_view(glb); POD glb_c[] = { 10,100, 20,200, 30,300, 40,400, 50,500, 60,600, 70,700, 80,800, 90,900 }; - EXPECT(make_view(make_storageview(glb).data(),make_storageview(glb).data()+2*f.Ng()) == make_view(glb_c,glb_c+2*f.Ng())); + size_t c(0); + for( size_t i=0; i(loc).data(), loc_strides, loc_extents, 1, - make_storageview(glb1).data(), glb_strides, glb_extents, 1, f.root ); + size_t loc_strides[] = {loc.stride(0),2}; + size_t loc_extents[] = {1,1}; + size_t glb_strides[] = {glb1.stride(0),glb1.stride(1)}; + size_t glb_extents[] = {1,glb1.shape(1)}; + + f.gather_scatter.gather( loc.data(), loc_strides, loc_extents, 2, + glb1.data(), glb_strides, glb_extents, 2, f.root ); } if( parallel::mpi::comm().rank() == f.root ) { + auto glbv = array::make_view(glb1); POD glb1_c[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90 }; - EXPECT(make_view(make_storageview(glb1).data(),make_storageview(glb1).data()+f.Ng()) == make_view(glb1_c,glb1_c+f.Ng())); + size_t c(0); + for( size_t i=0; i(loc).data()+1, loc_strides, loc_extents, 1, - make_storageview(glb2).data(), glb_strides, glb_extents, 1, f.root ); + size_t loc_strides[] = {loc.stride(0),2}; + size_t loc_extents[] = {1,1}; + size_t glb_strides[] = {glb2.stride(0),glb2.stride(1)}; + size_t glb_extents[] = {1,glb2.shape(2)}; + f.gather_scatter.gather( loc.data()+1, loc_strides, loc_extents, 1, + glb2.data(), glb_strides, glb_extents, 1, f.root ); } if( parallel::mpi::comm().rank() == f.root ) { + auto glbv = array::make_view(glb2); POD glb2_c[] = { 100, 200, 300, 400, 500, 600, 700, 800, 900 }; - EXPECT(make_view(make_storageview(glb2).data(),make_storageview(glb2).data()+f.Ng()) == make_view(glb2_c,glb2_c+f.Ng())); + size_t c(0); + for( size_t i=0; i(glb).data(),make_storageview(glb).data()+2*f.Ng()) == make_view(glb_c,glb_c+2*f.Ng())); + + auto glbv = array::make_view(glb); + size_t c(0); + for( size_t i=0; i(glb).data(),make_storageview(glb).data()+2*f.Ng()) == make_view(glb_c,glb_c+2*f.Ng())); } } } @@ -624,7 +654,14 @@ CASE("test_gather") { -7,7, -70,70, -700,700, -8,8, -80,80, -800,800, -9,9, -90,90, -900,900 }; - EXPECT(make_view(make_storageview(glb).data(),make_storageview(glb).data()+6*f.Ng()) == make_view(glb_c,glb_c+6*f.Ng())); + size_t c(0); + for( size_t i=0; i(glb).data(); - for( int j=0; j(loc).data(),make_storageview(loc).data()+f.Nl*6) == make_view(loc_c,loc_c+f.Nl*6)); + + size_t c(0); + for( size_t i=0; i(loc).data(),make_storageview(loc).data()+f.Nl*6) == make_view(loc_c,loc_c+f.Nl*6)); + size_t c(0); + for( size_t i=0; i(loc).data(),make_storageview(loc).data()+f.Nl*6) == make_view(loc_c,loc_c+f.Nl*6)); - break; } + size_t c(0); + for( size_t i=0; i Date: Thu, 18 Jan 2018 18:36:18 +0000 Subject: [PATCH 254/355] ATLAS-142 Removed occurence of StorageView everywhere --- src/atlas/CMakeLists.txt | 3 - src/atlas/array.h | 1 - src/atlas/array/MakeView.h | 1 - src/atlas/array/StorageView.h | 17 ------ .../array/gridtools/GridToolsMakeView.cc | 41 ------------- .../array/gridtools/GridToolsStorageView.h | 60 ------------------- src/atlas/array/native/NativeMakeView.cc | 42 ------------- src/atlas/array/native/NativeStorageView.h | 52 ---------------- src/atlas/array_fwd.h | 15 ----- src/tests/array/test_array.cc | 13 ---- src/tests/mesh/test_elements.cc | 3 - src/tests/parallel/test_gather.cc | 35 ++++++----- 12 files changed, 17 insertions(+), 266 deletions(-) delete mode 100644 src/atlas/array/StorageView.h delete mode 100644 src/atlas/array/gridtools/GridToolsStorageView.h delete mode 100644 src/atlas/array/native/NativeStorageView.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 03d1be02f..4fdd6f6b0 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -390,7 +390,6 @@ array/IndexView.h array/LocalView.cc array/LocalView.h array/Range.h -array/StorageView.h array/Vector.h array/helpers/ArrayInitializer.h array/helpers/ArrayAssigner.h @@ -413,7 +412,6 @@ array/gridtools/GridToolsIndexView.cc array/gridtools/GridToolsIndexView.h array/gridtools/GridToolsMakeView.cc array/gridtools/GridToolsMakeView.h -array/gridtools/GridToolsStorageView.h array/gridtools/GridToolsTraits.h ) else() @@ -425,7 +423,6 @@ array/native/NativeDataStore.h array/native/NativeIndexView.cc array/native/NativeIndexView.h array/native/NativeMakeView.cc -array/native/NativeStorageView.h ) endif() diff --git a/src/atlas/array.h b/src/atlas/array.h index 9f49a3713..ad428372e 100644 --- a/src/atlas/array.h +++ b/src/atlas/array.h @@ -21,7 +21,6 @@ #include "atlas/array/DataType.h" #include "atlas/array/LocalView.h" #include "atlas/array/MakeView.h" -#include "atlas/array/StorageView.h" #include "atlas/array/Table.h" //#include "atlas/array/TableView.h" diff --git a/src/atlas/array/MakeView.h b/src/atlas/array/MakeView.h index b8aa9e24f..7e5381bae 100644 --- a/src/atlas/array/MakeView.h +++ b/src/atlas/array/MakeView.h @@ -3,4 +3,3 @@ #include "atlas/array_fwd.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" -#include "atlas/array/StorageView.h" diff --git a/src/atlas/array/StorageView.h b/src/atlas/array/StorageView.h deleted file mode 100644 index ae4247e71..000000000 --- a/src/atlas/array/StorageView.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * (C) Copyright 1996-2016 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/library/config.h" -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE -#include "atlas/array/gridtools/GridToolsStorageView.h" -#else -#include "atlas/array/native/NativeStorageView.h" -#endif diff --git a/src/atlas/array/gridtools/GridToolsMakeView.cc b/src/atlas/array/gridtools/GridToolsMakeView.cc index 56eb54f5a..1ba618127 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.cc +++ b/src/atlas/array/gridtools/GridToolsMakeView.cc @@ -4,7 +4,6 @@ #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" -#include "atlas/array/StorageView.h" #include "atlas/library/config.h" #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE @@ -68,15 +67,6 @@ make_host_view(const Array& array) { return ArrayView(gridtools::make_gt_host_view(array), array); } -template -StorageView -make_host_storageview(const Array& array) { - typedef gridtools::storage_traits::storage_info_t<0, 1> storage_info_ty; - typedef gridtools::storage_traits::data_store_t data_store_t; - data_store_t* ds = reinterpret_cast(const_cast(array.storage())); - return StorageView(::gridtools::make_host_view(*ds),array.size(),array.contiguous()); -} - template ArrayView make_device_view(const Array& array) { @@ -84,13 +74,6 @@ make_device_view(const Array& array) { return ArrayView(gridtools::make_gt_device_view(array), array); } - -template -StorageView -make_device_storageview(const Array& array) { - return StorageView(gridtools::make_gt_device_view(array),array.size(),array.contiguous()); -} - template IndexView make_host_indexview(const Array& array) { @@ -119,12 +102,6 @@ make_view(const Array& array) { return make_host_view(array); } -template -StorageView -make_storageview(const Array& array) { - return make_host_storageview(array); -} - } } @@ -196,24 +173,6 @@ namespace gridtools { \ template data_view_tt make_gt_device_view(const Array& array);\ } -template StorageView make_storageview(const Array&); -template StorageView make_storageview(const Array&); -template StorageView make_storageview(const Array&); -template StorageView make_storageview(const Array&); -template StorageView make_storageview(const Array&); - -template StorageView make_host_storageview(const Array&); -template StorageView make_host_storageview(const Array&); -template StorageView make_host_storageview(const Array&); -template StorageView make_host_storageview(const Array&); -template StorageView make_host_storageview(const Array&); - -template StorageView make_device_storageview(const Array&); -template StorageView make_device_storageview(const Array&); -template StorageView make_device_storageview(const Array&); -template StorageView make_device_storageview(const Array&); -template StorageView make_device_storageview(const Array&); - // For each Rank in [1..9] EXPLICIT_TEMPLATE_INSTANTIATION(1) EXPLICIT_TEMPLATE_INSTANTIATION(2) diff --git a/src/atlas/array/gridtools/GridToolsStorageView.h b/src/atlas/array/gridtools/GridToolsStorageView.h deleted file mode 100644 index feea2f348..000000000 --- a/src/atlas/array/gridtools/GridToolsStorageView.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * (C) Copyright 1996-2016 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/array/gridtools/GridToolsTraits.h" - -//------------------------------------------------------------------------------------------------------ - -namespace atlas { -namespace array { - -//------------------------------------------------------------------------------------------------------ - -template< typename Value > -class StorageView -{ -public: - - using storage_view_t = gridtools::data_view_tt; - -public: - - StorageView(storage_view_t storage_view, size_t size, bool contiguous = true) : - gt_storage_view_(storage_view), - size_(size), - contiguous_(contiguous) - {} - - Value* data() { return gt_storage_view_.data(); } - - size_t size() { return size_; } - - bool contiguous() const { return contiguous_; } - - void assign(const Value& value) { - ASSERT( contiguous() ); - Value* raw_data = data(); - for( size_t j=0; j( (Value*)(array.storage()),array.shape().data() ); } - -template -StorageView -make_host_storageview(const Array& array) { - return StorageView(const_cast(array).storage(),array.size(),array.contiguous()); -} - - -template -StorageView -make_device_storageview(const Array& array) { - return make_host_storageview(array); -} - - template IndexView make_indexview(const Array& array) { @@ -72,7 +56,6 @@ make_indexview(const Array& array) { return make_host_indexview(array); } - template ArrayView make_view(const Array& array) { @@ -80,13 +63,6 @@ make_view(const Array& array) { return make_host_view(array); } - -template -StorageView -make_storageview(const Array& array) { - return make_host_storageview(array); -} - // -------------------------------------------------------------------------------------------- } // namespace array @@ -141,24 +117,6 @@ template IndexView make_host_indexview(const Arr template IndexView make_host_indexview(const Array&);\ template IndexView make_host_indexview(const Array&);\ -template StorageView make_storageview(const Array&); -template StorageView make_storageview(const Array&); -template StorageView make_storageview(const Array&); -template StorageView make_storageview(const Array&); -template StorageView make_storageview(const Array&); - -template StorageView make_host_storageview(const Array&); -template StorageView make_host_storageview(const Array&); -template StorageView make_host_storageview(const Array&); -template StorageView make_host_storageview(const Array&); -template StorageView make_host_storageview(const Array&); - -template StorageView make_device_storageview(const Array&); -template StorageView make_device_storageview(const Array&); -template StorageView make_device_storageview(const Array&); -template StorageView make_device_storageview(const Array&); -template StorageView make_device_storageview(const Array&); - // For each Rank in [1..9] EXPLICIT_TEMPLATE_INSTANTIATION(1) EXPLICIT_TEMPLATE_INSTANTIATION(2) diff --git a/src/atlas/array/native/NativeStorageView.h b/src/atlas/array/native/NativeStorageView.h deleted file mode 100644 index 2694941f2..000000000 --- a/src/atlas/array/native/NativeStorageView.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * (C) Copyright 1996-2016 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 - -//------------------------------------------------------------------------------------------------------ - -namespace atlas { -namespace array { - -//------------------------------------------------------------------------------------------------------ - -template< typename Value > -class StorageView { - typedef void* storage_view_t; -public: - StorageView(storage_view_t storage_view, size_t size, bool contiguous = true) : - native_storage_view_(storage_view), - size_(size), - contiguous_(contiguous) - {} - - Value* data() { return (Value*) native_storage_view_; } - - size_t size() { return size_; } - - bool contiguous() const { return contiguous_; } - - void assign(const Value& value) { - ASSERT( contiguous() ); - Value* raw_data = data(); - for( size_t j=0; j class ArrayT; -template -class StorageView; - template class ArrayView; @@ -54,18 +51,6 @@ template make_host_indexview(const Array& array); -template -StorageView -make_storageview(const Array& array); - -template -StorageView -make_host_storageview(const Array& array); - -template -StorageView -make_device_storageview(const Array& array); - class Table; template diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 5ba0f35c7..392592746 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -454,19 +454,6 @@ CASE("test_wrap_storage") { } } -CASE("test_storageview") { - Array* ds = Array::create(2ul, 3ul, 4ul); - auto hv = make_host_view(*ds); - - EXPECT(hv.size() == 2 * 3 * 4); - - auto sv = make_storageview(*ds); - - EXPECT(sv.size() == 2 * 3 * 4); - - delete ds; -} - CASE("test_assign") { Array* ds = Array::create(2ul, 3ul, 4ul); auto hv = make_host_view(*ds); diff --git a/src/tests/mesh/test_elements.cc b/src/tests/mesh/test_elements.cc index 4071dd4a8..aa663e4fa 100644 --- a/src/tests/mesh/test_elements.cc +++ b/src/tests/mesh/test_elements.cc @@ -280,9 +280,6 @@ CASE( "block_connectivity" ) } -#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA -#warning TODO: gridtools storage cuda backend cannot allocate zero elements -#endif CASE( "zero_elements" ) { HybridElements hybrid_elements; diff --git a/src/tests/parallel/test_gather.cc b/src/tests/parallel/test_gather.cc index 2b3799b05..f4def99a6 100644 --- a/src/tests/parallel/test_gather.cc +++ b/src/tests/parallel/test_gather.cc @@ -20,8 +20,6 @@ #include "atlas/array/MakeView.h" #include "atlas/parallel/GatherScatter.h" -using atlas::array::make_storageview; - #include "tests/AtlasTestEnvironment.h" #include "eckit/testing/Test.h" @@ -224,7 +222,7 @@ CASE("test_gather") { size_t glb_rank = 2; size_t glb_mpl_idxpos[] = {0}; size_t glb_mpl_rank = 1; - parallel::detail::MPL_ArrayView lview(make_storageview(loc).data(),loc_strides,loc_extents,loc_rank,loc_mpl_idxpos,loc_mpl_rank); + parallel::detail::MPL_ArrayView lview(loc.data(),loc_strides,loc_extents,loc_rank,loc_mpl_idxpos,loc_mpl_rank); parallel::detail::MPL_ArrayView gview(glb.data(),glb_strides,glb_extents,glb_rank,glb_mpl_idxpos,glb_mpl_rank); EXPECT(lview.var_rank() == 1); @@ -241,14 +239,14 @@ CASE("test_gather") { EXPECT(gview.mpl_stride(0) == 2); EXPECT(gview.mpl_shape(0) == f.Ng()); - f.gather_scatter.gather( make_storageview(loc).data(), loc_strides, loc_extents, loc_rank, loc_mpl_idxpos, loc_mpl_rank, - make_storageview(glb).data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, + f.gather_scatter.gather( loc.data(), loc_strides, loc_extents, loc_rank, loc_mpl_idxpos, loc_mpl_rank, + glb.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); if( parallel::mpi::comm().rank() == f.root ) { POD glb_c[] = { 10,100, 20,200, 30,300, 40,400, 50,500, 60,600, 70,700, 80,800, 90,900 }; - EXPECT(make_view(make_storageview(glb).data(),make_storageview(glb).data()+2*f.Ng()) == make_view(glb_c,glb_c+2*f.Ng())); + EXPECT(make_view(glb.data(),glb.data()+2*f.Ng()) == make_view(glb_c,glb_c+2*f.Ng())); } } #endif @@ -266,7 +264,7 @@ CASE("test_gather") { size_t glb_rank = 1; size_t glb_mpl_idxpos[] = {0}; size_t glb_mpl_rank = 1; - parallel::detail::MPL_ArrayView lview(make_storageview(loc).data(),loc_strides,loc_extents,loc_rank,loc_mpl_idxpos,loc_mpl_rank); + parallel::detail::MPL_ArrayView lview(loc.data(),loc_strides,loc_extents,loc_rank,loc_mpl_idxpos,loc_mpl_rank); EXPECT(lview.var_rank() == 1); EXPECT(lview.var_stride(0) == 2); EXPECT(lview.var_shape(0) == 1); @@ -274,7 +272,7 @@ CASE("test_gather") { EXPECT(lview.mpl_stride(0) == 2); EXPECT(lview.mpl_shape(0) == f.Nl); - parallel::detail::MPL_ArrayView gview(make_storageview(glb1).data(),glb_strides,glb_extents,glb_rank,glb_mpl_idxpos,glb_mpl_rank); + parallel::detail::MPL_ArrayView gview(glb1.data(),glb_strides,glb_extents,glb_rank,glb_mpl_idxpos,glb_mpl_rank); EXPECT(gview.var_rank() == 1); EXPECT(gview.var_stride(0) == 1); EXPECT(gview.var_shape(0) == 1); @@ -282,13 +280,13 @@ CASE("test_gather") { EXPECT(gview.mpl_stride(0) == 1); EXPECT(gview.mpl_shape(0) == f.Ng()); - f.gather_scatter.gather( make_storageview(loc).data(), loc_strides, loc_extents, loc_rank, loc_mpl_idxpos, loc_mpl_rank, - make_storageview(glb1).data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, + f.gather_scatter.gather( loc.data(), loc_strides, loc_extents, loc_rank, loc_mpl_idxpos, loc_mpl_rank, + glb1.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); if( parallel::mpi::comm().rank() == f.root ) { POD glb1_c[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90 }; - EXPECT(make_view(make_storageview(glb1).data(),make_storageview(glb1).data()+f.Ng()) == make_view( glb1_c,glb1_c+f.Ng())); + EXPECT(make_view(glb1.data(),glb1.data()+f.Ng()) == make_view( glb1_c,glb1_c+f.Ng())); } } #endif @@ -306,14 +304,14 @@ CASE("test_gather") { size_t glb_rank = 1; size_t glb_mpl_idxpos[] = {0}; size_t glb_mpl_rank = 1; - f.gather_scatter.gather( make_storageview(loc).data()+1, loc_strides, loc_extents, loc_rank, loc_mpl_idxpos, loc_mpl_rank, - make_storageview(glb2).data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, + f.gather_scatter.gather( loc.data()+1, loc_strides, loc_extents, loc_rank, loc_mpl_idxpos, loc_mpl_rank, + glb2.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); } if( parallel::mpi::comm().rank() == f.root ) { POD glb2_c[] = { 100, 200, 300, 400, 500, 600, 700, 800, 900 }; - EXPECT(make_view(make_storageview(glb2).data(),make_storageview(glb2).data()+f.Ng()) == make_view(glb2_c,glb2_c+f.Ng())); + EXPECT(make_view(glb2.data(),glb2.data()+f.Ng()) == make_view(glb2_c,glb2_c+f.Ng())); } #endif } @@ -356,8 +354,8 @@ CASE("test_gather") { size_t glb_rank = 3; size_t glb_mpl_idxpos[] = {0}; size_t glb_mpl_rank = 1; - f.gather_scatter.gather( make_storageview(loc).data(), loc_strides, loc_extents, loc_rank, loc_mpl_idxpos, loc_mpl_rank, - make_storageview(glb).data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, + f.gather_scatter.gather( loc.data(), loc_strides, loc_extents, loc_rank, loc_mpl_idxpos, loc_mpl_rank, + glb.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); } if( parallel::mpi::comm().rank() == f.root ) @@ -570,7 +568,9 @@ CASE("test_gather") { 70, 80, 90 }; - EXPECT( make_view(make_storageview(glb).data(),make_storageview(glb).data()+f.Ng()) == make_view( glb_c,glb_c+f.Ng())); + for( size_t n=0; n(glb).data(),make_storageview(glb).data()+2*f.Ng()) == make_view(glb_c,glb_c+2*f.Ng())); } } } From cfca02b08848cf7bd13439ba1cd05b8d039bb67f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 18 Jan 2018 18:46:20 +0000 Subject: [PATCH 255/355] atlas --info displays if MPI feature is available --- src/atlas/library/Library.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 2b6bc86c0..65b316b68 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -16,6 +16,7 @@ #include "transi/version.h" #endif +#include "eckit/eckit_config.h" #include "eckit/runtime/Main.h" #include "eckit/log/Log.h" #include "eckit/filesystem/PathName.h" @@ -198,9 +199,13 @@ void Library::Information::print( std::ostream& out ) const { bool feature_Trans(false); bool feature_Tesselation(false); bool feature_BoundsChecking(false); + bool feature_MPI(false); #ifdef ATLAS_HAVE_FORTRAN feature_fortran = true; #endif +#ifdef ECKIT_HAVE_MPI + feature_MPI = true; +#endif #ifdef ATLAS_HAVE_OMP feature_OpenMP = true; #endif @@ -222,6 +227,7 @@ void Library::Information::print( std::ostream& out ) const { #endif out << " Features:" << '\n' << " Fortran : " << str(feature_fortran) << '\n' + << " MPI : " << str(feature_MPI) << '\n' << " OpenMP : " << str(feature_OpenMP) << '\n' << " BoundsChecking : " << str(feature_BoundsChecking) << '\n' << " Trans : " << str(feature_Trans) << '\n' From 93443de84ecca9aa9b81bcb0e44bf02cfd3337c1 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 19 Jan 2018 10:27:49 +0000 Subject: [PATCH 256/355] Linking of documentation examples with PGI --- doc/user-guide/core-functionalities/fields/CMakeLists.txt | 2 ++ .../core-functionalities/functionspace/CMakeLists.txt | 1 + .../core-functionalities/global-grids/Structured/CMakeLists.txt | 1 + doc/user-guide/core-functionalities/meshes/CMakeLists.txt | 1 + doc/user-guide/getting-started/installation/CMakeLists.txt | 1 + 5 files changed, 6 insertions(+) diff --git a/doc/user-guide/core-functionalities/fields/CMakeLists.txt b/doc/user-guide/core-functionalities/fields/CMakeLists.txt index 95080a48a..32a362cb2 100644 --- a/doc/user-guide/core-functionalities/fields/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/fields/CMakeLists.txt @@ -20,12 +20,14 @@ ecbuild_add_executable( TARGET atlas_f-fields SOURCES fields.F90 LIBS atlas_f + LINKER_LANGUAGE Fortran NOINSTALL ) ecbuild_add_executable( TARGET atlas_f-fields-on-grid SOURCES fields-on-grid.F90 LIBS atlas_f + LINKER_LANGUAGE Fortran NOINSTALL ) set_target_properties(atlas_f-fields diff --git a/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt b/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt index 397b0f3be..c210a89a1 100644 --- a/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt @@ -20,6 +20,7 @@ ecbuild_add_executable( TARGET atlas_f-NodeColumns SOURCES NodeColumns.F90 LIBS atlas_f + LINKER_LANGUAGE Fortran NOINSTALL ) set_target_properties(atlas_f-NodeColumns diff --git a/doc/user-guide/core-functionalities/global-grids/Structured/CMakeLists.txt b/doc/user-guide/core-functionalities/global-grids/Structured/CMakeLists.txt index a89cbf329..d933a1c88 100644 --- a/doc/user-guide/core-functionalities/global-grids/Structured/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/global-grids/Structured/CMakeLists.txt @@ -13,6 +13,7 @@ ecbuild_add_executable( TARGET atlas_f-global-grids-Structured SOURCES global-grids-Structured.F90 LIBS atlas_f + LINKER_LANGUAGE Fortran NOINSTALL ) set_target_properties(atlas_f-global-grids-Structured diff --git a/doc/user-guide/core-functionalities/meshes/CMakeLists.txt b/doc/user-guide/core-functionalities/meshes/CMakeLists.txt index 1a68b97de..2208b2f35 100644 --- a/doc/user-guide/core-functionalities/meshes/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/meshes/CMakeLists.txt @@ -13,6 +13,7 @@ ecbuild_add_executable( TARGET atlas_f-meshes-Structured SOURCES meshes-Structured.F90 LIBS atlas_f + LINKER_LANGUAGE Fortran NOINSTALL ) set_target_properties(atlas_f-meshes-Structured diff --git a/doc/user-guide/getting-started/installation/CMakeLists.txt b/doc/user-guide/getting-started/installation/CMakeLists.txt index 8ede27aea..0600b096a 100644 --- a/doc/user-guide/getting-started/installation/CMakeLists.txt +++ b/doc/user-guide/getting-started/installation/CMakeLists.txt @@ -9,6 +9,7 @@ set_target_properties( atlas_c-hello-world if( ATLAS_HAVE_FORTRAN ) ecbuild_add_executable( + LINKER_LANGUAGE Fortran TARGET atlas_f-hello-world SOURCES hello-world.F90 LIBS atlas_f From 32aa87b730fafe7061362b39086fd989f488ea06 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 19 Jan 2018 10:28:32 +0000 Subject: [PATCH 257/355] ATLAS-142 Streamline GmshIO for StructuredColumns with NodeColumns --- src/atlas/output/detail/GmshIO.cc | 493 ++++++++++++------------------ 1 file changed, 193 insertions(+), 300 deletions(-) diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index ee4ab0b44..d1ba5222c 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -101,19 +101,153 @@ void write_header_binary(std::ostream& out) } // ---------------------------------------------------------------------------- +namespace { // anonymous +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() ); + } 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() ); + } else { + return make_view( field ).slice( Range::to(ndata), Range::dummy() ); + } + } +} + +template< typename DATATYPE > +void write_level( std::ostream& out, const array::ArrayView gidx, const array::LocalView data ) { + int ndata = data.shape(0); + int nvars = data.shape(1); + if( nvars == 1) + { + for( size_t n = 0; n < ndata; ++n ) + { + out << gidx(n) << " " << data(n,0) << "\n"; + } + } + else if( nvars <= 3 ) + { + std::vector data_vec(3,0.); + for( size_t n = 0; n < ndata; ++n ) + { + out << gidx(n); + for(size_t v=0; v < nvars; ++v) + data_vec[v] = data(n,v); + for( int v=0; v<3; ++v) + out << " " << data_vec[v]; + out << "\n"; + } + } + else if( nvars <= 9 ) + { + std::vector data_vec(9,0.); + if( nvars == 4 ) + { + for( size_t n = 0; n < ndata; ++n ) { + for( int i=0; i<2; ++i ) { + for( int j=0; j<2; ++j ) { + data_vec[i*3+j] = data(n,i*2+j); + } + } + out << gidx(n); + for( int v=0; v<9; ++v) + out << " " << data_vec[v]; + out << "\n"; + } + } + else if( nvars == 9 ) + { + for( size_t n = 0; n < ndata; ++n ) { + for( int i=0; i<3; ++i ) { + for( int j=0; j<3; ++j ) { + data_vec[i*3+j] = data(n,i*2+j); + } + } + out << gidx(n); + for( int v=0; v<9; ++v) + out << " " << data_vec[v]; + out << "\n"; + } + } + else + { + NOTIMP; + } + } + else + { + NOTIMP; + } +} + +std::vector get_levels( int nlev, const Metadata& gmsh_options ) { + std::vector lev; + std::vector gmsh_levels; + gmsh_options.get("levels",gmsh_levels); + if( gmsh_levels.empty() || nlev == 1 ) + { + lev.resize(nlev); + for (size_t ilev=0; ilev < nlev; ++ilev) + lev[ilev] = ilev; + } + else + { + lev = gmsh_levels; + } + return lev; +} + +std::string field_lev( const Field& field, int jlev ) { + if( field.levels() ) { + char str[6] = {0, 0, 0, 0, 0, 0}; + std::sprintf(str, "[%03lu]",jlev); + return std::string(str); + } else { + return std::string(); + } +} + +double field_time( const Field& field ) { + return field.metadata().has("time") ? field.metadata().get("time") : 0.; +} + +int field_step( const Field& field ) { + return field.metadata().has("step") ? field.metadata().get("step") : 0 ; +} + +int field_vars( int nvars ) { + if ( nvars == 1 ) return nvars; + else if( nvars <= 3 ) return 3; + else if( nvars <= 9 ) return 9; + else return nvars; +} + +} // namespace anonymous // ---------------------------------------------------------------------------- template< typename DATATYPE > -void write_field_nodes(const Metadata& gmsh_options, const functionspace::NodeColumns& function_space, const Field& field, std::ostream& out) +void write_field_nodes( + const Metadata& gmsh_options, + const functionspace::NodeColumns& function_space, + const Field& field, + std::ostream& out) { - Log::debug() << "writing field " << field.name() << " defined in NodeColumns..." << std::endl; + Log::debug() << "writing NodeColumns field " << field.name() << " defined in NodeColumns..." << std::endl; - bool gather( gmsh_options.get("gather") ); + bool gather( gmsh_options.get("gather") && atlas::parallel::mpi::comm().size() > 1 ); bool binary( !gmsh_options.get("ascii") ); size_t nlev = std::max(1,field.levels()); size_t ndata = std::min(function_space.nb_nodes(),field.shape(0)); - size_t nvars = std::max(1,field.variables()); //field.stride(0)/nlev; + size_t nvars = std::max(1,field.variables()); array::ArrayView gidx = array::make_view( function_space.nodes().global_index() ); Field gidx_glb; Field field_glb; @@ -128,178 +262,24 @@ void write_field_nodes(const Metadata& gmsh_options, const functionspace::NodeCo ndata = std::min(function_space.nb_nodes_global(),field_glb.shape(0)); } - std::vector lev; - std::vector gmsh_levels; - gmsh_options.get("levels",gmsh_levels); - if( gmsh_levels.empty() || nlev == 1 ) - { - lev.resize(nlev); - for (size_t ilev=0; ilev < nlev; ++ilev) - lev[ilev] = ilev; - } - else - { - lev = gmsh_levels; - } + std::vector lev = get_levels( nlev, gmsh_options ); for (size_t ilev=0; ilev < lev.size(); ++ilev) { size_t jlev = lev[ilev]; if( ( gather && atlas::parallel::mpi::comm().rank() == 0 ) || !gather ) { - char field_lev[6] = {0, 0, 0, 0, 0, 0}; - if( field.levels() ) - std::sprintf(field_lev, "[%03lu]",jlev); - double time = field.metadata().has("time") ? field.metadata().get("time") : 0.; - int step = field.metadata().has("step") ? field.metadata().get("step") : 0 ; out << "$NodeData\n"; out << "1\n"; - out << "\"" << field.name() << field_lev << "\"\n"; + out << "\"" << field.name() << field_lev(field,jlev) << "\"\n"; out << "1\n"; - out << time << "\n"; + out << field_time(field) << "\n"; out << "4\n"; - out << step << "\n"; - if ( nvars == 1 ) out << nvars << "\n"; - else if( nvars <= 3 ) out << 3 << "\n"; - else if( nvars <= 9 ) out << 9 << "\n"; + out << field_step(field) << "\n"; + out << field_vars(nvars) << "\n"; out << ndata << "\n"; out << atlas::parallel::mpi::comm().rank() << "\n"; - - - { - if( field.levels() ) { - if( field.variables() ) { - auto data = gather ? array::make_view( field_glb ) : array::make_view( field ); - if( nvars == 1) - { - for( size_t n = 0; n < ndata; ++n ) - { - ASSERT( jlev*nvars < data.shape(1) ); - ASSERT( n < gidx.shape(0) ); - out << gidx(n) << " " << data(n,jlev,0) << "\n"; - } - } - else if( nvars <= 3 ) - { - std::vector data_vec(3,0.); - for( size_t n = 0; n < ndata; ++n ) - { - out << gidx(n); - for(size_t v=0; v < nvars; ++v) - data_vec[v] = data(n,jlev,v); - for( int v=0; v<3; ++v) - out << " " << data_vec[v]; - out << "\n"; - } - } - else if( nvars <= 9 ) - { - std::vector data_vec(9,0.); - - if( nvars == 4 ) - { - for( size_t n = 0; n < ndata; ++n ) { - for( int i=0; i<2; ++i ) { - for( int j=0; j<2; ++j ) { - data_vec[i*3+j] = data(n,jlev,i*2+j); - } - } - out << gidx(n); - for( int v=0; v<9; ++v) - out << " " << data_vec[v]; - out << "\n"; - } - } - if( nvars == 9 ) - { - for( size_t n = 0; n < ndata; ++n ) { - for( int i=0; i<3; ++i ) { - for( int j=0; j<3; ++j ) { - data_vec[i*3+j] = data(n,jlev,i*2+j); - } - } - out << gidx(n); - for( int v=0; v<9; ++v) - out << " " << data_vec[v]; - out << "\n"; - } - } - } - } else { - auto data = gather ? array::make_view( field_glb ) : array::make_view( field ); - for( size_t n = 0; n < ndata; ++n ) - { - ASSERT( jlev*nvars < data.shape(1) ); - ASSERT( n < gidx.shape(0) ); - out << gidx(n) << " " << data(n,jlev) << "\n"; - } - } - } else { - if( field.variables() ) { - auto data = gather ? array::make_view( field_glb ) : array::make_view( field ); - if( nvars == 1) - { - for( size_t n = 0; n < ndata; ++n ) - { - ASSERT( n < gidx.shape(0) ); - out << gidx(n) << " " << data(n,0) << "\n"; - } - } - else if( nvars <= 3 ) - { - std::vector data_vec(3,0.); - for( size_t n = 0; n < ndata; ++n ) - { - out << gidx(n); - for(size_t v=0; v < nvars; ++v) - data_vec[v] = data(n,v); - for( int v=0; v<3; ++v) - out << " " << data_vec[v]; - out << "\n"; - } - } - else if( nvars <= 9 ) - { - std::vector data_vec(9,0.); - - if( nvars == 4 ) - { - for( size_t n = 0; n < ndata; ++n ) { - for( int i=0; i<2; ++i ) { - for( int j=0; j<2; ++j ) { - data_vec[i*3+j] = data(n,i*2+j); - } - } - out << gidx(n); - for( int v=0; v<9; ++v) - out << " " << data_vec[v]; - out << "\n"; - } - } - if( nvars == 9 ) - { - for( size_t n = 0; n < ndata; ++n ) { - for( int i=0; i<3; ++i ) { - for( int j=0; j<3; ++j ) { - data_vec[i*3+j] = data(n,i*2+j); - } - } - out << gidx(n); - for( int v=0; v<9; ++v) - out << " " << data_vec[v]; - out << "\n"; - } - } - } - } else { - auto data = gather ? array::make_view( field_glb ) : array::make_view( field ); - for( size_t n = 0; n < ndata; ++n ) - { - ASSERT( n < gidx.shape(0) ); - out << gidx(n) << " " << data(n) << "\n"; - } - } - } - } + auto data = gather ? make_level_view( field_glb, ndata, jlev ) : make_level_view( field, ndata, jlev ); + write_level( out, gidx, data ); out << "$EndNodeData\n"; } } @@ -311,151 +291,64 @@ void write_field_nodes(const Metadata& gmsh_options, const functionspace::NodeCo // ---------------------------------------------------------------------------- template< typename DATATYPE > void write_field_nodes( - const Metadata& gmsh_options, + const Metadata& gmsh_options, const functionspace::StructuredColumns& function_space, - const Field& field, - std::ostream& out) + const Field& field, + std::ostream& out) { - Log::debug() << "writing field " << field.name() << "..." << std::endl; - //bool gather(gmsh_options.get("gather")); - bool binary(!gmsh_options.get("ascii")); - - size_t nlev = std::max(1,field.levels()); - size_t nvars = field.stride(0) / nlev; + Log::debug() << "writing StructuredColumns field " << field.name() << "..." << std::endl; - array::LocalView data( - field.data(), - array::make_shape(field.shape(0),field.stride(0)) ); - - Field gidx_glb; - Field field_glb; + bool gather( gmsh_options.get("gather") && atlas::parallel::mpi::comm().size() > 1 ); + bool binary( !gmsh_options.get("ascii") ); + size_t nlev = std::max(1,field.levels()); + size_t ndata = std::min(function_space.sizeOwned(),field.shape(0)); + size_t nvars = std::max(1,field.variables()); + auto gidx = array::make_view( function_space.global_index() ); + Field gidx_glb; + Field field_glb; + if( gather ) + { + gidx_glb = function_space.createField( function_space.global_index(), option::name("gidx_glb") | option::global() ); + function_space.gather(function_space.global_index(),gidx_glb); + gidx = array::make_view( gidx_glb ); - if( atlas::parallel::mpi::comm().size() > 1 ) - { - field_glb = function_space.createField( - option::name("glb_field") | - option::global() ); - function_space.gather(field, field_glb); - data = array::LocalView( - field_glb.data(), - array::make_shape(field_glb.shape(0),field_glb.stride(0)) ); - } + field_glb = function_space.createField( field, option::global() ); + function_space.gather(field,field_glb); + ndata = field_glb.shape(0); + } - size_t ndata = data.shape(0); - std::vector lev; - std::vector gmsh_levels; - gmsh_options.get("levels", gmsh_levels); + std::vector lev = get_levels(nlev,gmsh_options); + for (size_t ilev = 0; ilev < lev.size(); ++ilev) + { + size_t jlev = lev[ilev]; + char field_lev[6] = {0, 0, 0, 0, 0, 0}; - if (gmsh_levels.empty() || nlev == 1) - { - lev.resize(nlev); - for (size_t ilev=0; ilev < nlev; ++ilev) - { - lev[ilev] = ilev; - } - } - else - { - lev = gmsh_levels; - } + if (field.levels()) + { + std::sprintf(field_lev, "[%03lu]", jlev); + } - if (atlas::parallel::mpi::comm().rank() == 0) - { - for (size_t ilev = 0; ilev < lev.size(); ++ilev) - { - size_t jlev = lev[ilev]; - char field_lev[6] = {0, 0, 0, 0, 0, 0}; + double time = field.metadata().has("time") ? + field.metadata().get("time") : 0.; - if (field.levels()) - { - std::sprintf(field_lev, "[%03lu]", jlev); - } + int step = field.metadata().has("step") ? + field.metadata().get("step") : 0 ; - double time = field.metadata().has("time") ? - field.metadata().get("time") : 0.; - - int step = field.metadata().has("step") ? - field.metadata().get("step") : 0 ; - - out << "$NodeData\n"; - out << "1\n"; - out << "\"" << field.name() << field_lev << "\"\n"; - out << "1\n"; - out << time << "\n"; - out << "4\n"; - out << step << "\n"; - if ( nvars == 1 ) out << nvars << "\n"; - else if( nvars <= 3 ) out << 3 << "\n"; - out << ndata << "\n"; - out << atlas::parallel::mpi::comm().rank() << "\n"; - - if (binary) - { - if (nvars == 1) - { - double value; - for (size_t n = 0; n < ndata; ++n) - { - out.write(reinterpret_cast(n+1), - sizeof(int)); - - value = data(n,jlev*nvars+0); - - out.write(reinterpret_cast(&value), - sizeof(double)); - } - } - else if (nvars <= 3) - { - double value[3] = {0,0,0}; - for (size_t n = 0; n < ndata; ++n) - { - out.write(reinterpret_cast(n+1), - sizeof(int)); - for (size_t v = 0; v < nvars; ++v) - { - value[v] = data(n,jlev*nvars+v); - } - out.write(reinterpret_cast(&value), - sizeof(double)*3); - } - } - out << "\n"; - } - else - { - ASSERT(jlev*nvars <= data.shape(1)); - if (nvars == 1) - { - for (size_t n = 0; n < ndata; ++n) - { - ASSERT(n < data.shape(0)); - out << n+1 << " " - << data(n, jlev*nvars+0) << "\n"; - } - } - else if (nvars <= 3) - { - std::vector data_vec(3,0.); - for (size_t n = 0; n < ndata; ++n) - { - out << n+1; - for (size_t v = 0; v < nvars; ++v) - { - data_vec[v] = data(n, jlev*nvars+v); - } - for (int v = 0; v < 3; ++v) - { - out << " " << data_vec[v]; - } - out << "\n"; - } - } - } - out << "$EndNodeData\n"; - } - } + out << "$NodeData\n"; + out << "1\n"; + out << "\"" << field.name() << field_lev << "\"\n"; + out << "1\n"; + out << field_time(field) << "\n"; + out << "4\n"; + out << field_step(field) << "\n"; + out << field_vars(nvars) << "\n"; + out << ndata << "\n"; + out << atlas::parallel::mpi::comm().rank() << "\n"; + auto data = gather ? make_level_view( field_glb, ndata, jlev ) : make_level_view( field, ndata, jlev ); + write_level( out, gidx, data ); + out << "$EndNodeData\n"; + } } // ---------------------------------------------------------------------------- From 988a5bfb37e5b355e47c92d8393df63efe6a6d88 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 22 Jan 2018 09:10:43 +0000 Subject: [PATCH 258/355] ATLAS-143 Automatic tracing of tests --- src/tests/AtlasTestEnvironment.h | 34 +++++++++++++++++++ src/tests/array/test_array.cc | 2 -- src/tests/array/test_array_kernel.cu | 2 -- src/tests/array/test_array_slicer.cc | 2 -- src/tests/array/test_array_view_util.cc | 2 -- src/tests/array/test_svector.cc | 2 -- src/tests/array/test_svector_kernel.cu | 7 ++-- src/tests/array/test_table.cc | 2 -- src/tests/array/test_vector_kernel.cu | 2 -- src/tests/functionspace/test_functionspace.cc | 2 -- src/tests/functionspace/test_pointcloud.cc | 2 -- .../functionspace/test_structuredcolumns.cc | 2 -- src/tests/grid/test_domain.cc | 1 - src/tests/grid/test_field.cc | 1 - src/tests/grid/test_grid_ptr.cc | 1 - src/tests/grid/test_grids.cc | 1 - src/tests/grid/test_rotation.cc | 1 - src/tests/grid/test_state.cc | 2 -- src/tests/interpolation/test_Quad3D.cc | 3 -- .../test_interpolation_finite_element.cc | 12 +++---- src/tests/io/test_gmsh.cc | 3 -- src/tests/io/test_pointcloud_io.cc | 3 -- src/tests/mesh/test_accumulate_facets.cc | 2 -- src/tests/mesh/test_connectivity.cc | 15 -------- src/tests/mesh/test_connectivity_kernel.cu | 11 +++--- src/tests/mesh/test_distmesh.cc | 2 -- src/tests/mesh/test_elements.cc | 2 -- src/tests/mesh/test_halo.cc | 2 -- src/tests/mesh/test_ll.cc | 4 --- src/tests/mesh/test_meshgen3d.cc | 2 -- src/tests/mesh/test_parfields.cc | 3 -- src/tests/mesh/test_rgg.cc | 3 -- src/tests/mesh/test_shapefunctions.cc | 4 +-- src/tests/numerics/test_fvm_nabla.cc | 2 -- src/tests/parallel/test_gather.cc | 5 +-- src/tests/parallel/test_haloexchange.cc | 3 -- src/tests/trans/test_trans.cc | 2 -- src/tests/trans/test_trans_invtrans_grad.cc | 3 -- src/tests/trans/test_transgeneral.cc | 2 -- src/tests/util/test_earth.cc | 3 -- src/tests/util/test_flags.cc | 4 --- src/tests/util/test_footprint.cc | 3 -- src/tests/util/test_indexview.cc | 3 -- src/tests/util/test_metadata.cc | 18 ++++------ src/tests/util/test_polygon.cc | 3 -- src/tests/util/test_vector.cc | 4 +-- 46 files changed, 56 insertions(+), 138 deletions(-) diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 4e86c76aa..e09ab6f0a 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -14,12 +14,38 @@ #include "eckit/runtime/Main.h" #include "eckit/mpi/Comm.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Trace.h" #include "eckit/config/Resource.h" #include "eckit/testing/Test.h" +using namespace eckit::testing; + namespace atlas { namespace test { +#ifdef CASE +#undef CASE +#endif + +#define CASE(description) \ +void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection); \ +static eckit::testing::TestRegister UNIQUE_NAME2(test_registration_, __LINE__)(description, &UNIQUE_NAME2(test_, __LINE__)); \ +void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection); \ +void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection) { \ + ATLAS_TRACE(description); \ + UNIQUE_NAME2(traced_test_, __LINE__)(_test_subsection); \ +} \ +void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection) + +#ifdef SECTION +#undef SECTION +#endif +#define SECTION(name) \ + _test_num += 1; \ + _test_count = _test_num; \ + _test_subsection = name; \ + if ((_test_num - 1) == _test) ATLAS_TRACE_SCOPE(name) + //---------------------------------------------------------------------------------------------------------------------- struct AtlasTestEnvironment { @@ -35,6 +61,14 @@ struct AtlasTestEnvironment { } ~AtlasTestEnvironment() { + bool report = eckit::Resource("--report;$ATLAS_TEST_REPORT", false); + if( report ) { +#if ATLAS_HAVE_TRACE + Log::info() << atlas::Trace::report() << std::endl; +#else + Log::warning() << "Atlas cannot generate report as ATLAS_HAVE_TRACE is not defined." << std::endl; +#endif + } atlas::Library::instance().finalise(); } }; diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 392592746..f122f6410 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -12,7 +12,6 @@ #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" #include "eckit/memory/SharedPtr.h" #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE @@ -28,7 +27,6 @@ using namespace atlas::array; -using namespace eckit::testing; namespace atlas { namespace test { diff --git a/src/tests/array/test_array_kernel.cu b/src/tests/array/test_array_kernel.cu index 0cce4f38f..0f732ef91 100644 --- a/src/tests/array/test_array_kernel.cu +++ b/src/tests/array/test_array_kernel.cu @@ -10,13 +10,11 @@ #include #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "atlas/runtime/Log.h" using namespace atlas::array; -using namespace eckit::testing; namespace atlas { namespace test { diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index f27d1592b..6f7c7a0f2 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -8,7 +8,6 @@ * does it submit to any jurisdiction. */ -#include "eckit/testing/Test.h" #include "eckit/memory/SharedPtr.h" #include "atlas/library/config.h" #include "atlas/array.h" @@ -19,7 +18,6 @@ using namespace atlas::array; using namespace atlas::array::helpers; -using namespace eckit::testing; template< typename Value, int Rank > struct Slice { diff --git a/src/tests/array/test_array_view_util.cc b/src/tests/array/test_array_view_util.cc index 42825894a..5d5b94dd6 100644 --- a/src/tests/array/test_array_view_util.cc +++ b/src/tests/array/test_array_view_util.cc @@ -12,10 +12,8 @@ #include "atlas/array/Array.h" #include "atlas/array/ArrayViewUtil.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" using namespace atlas::array; -using namespace eckit::testing; namespace atlas { namespace test { diff --git a/src/tests/array/test_svector.cc b/src/tests/array/test_svector.cc index dd99bc4d9..2c9ea1389 100644 --- a/src/tests/array/test_svector.cc +++ b/src/tests/array/test_svector.cc @@ -10,11 +10,9 @@ #include "atlas/library/config.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" #include "atlas/array/SVector.h" using namespace atlas::array; -using namespace eckit::testing; namespace atlas { namespace test { diff --git a/src/tests/array/test_svector_kernel.cu b/src/tests/array/test_svector_kernel.cu index 9d84786d5..d43ee26da 100644 --- a/src/tests/array/test_svector_kernel.cu +++ b/src/tests/array/test_svector_kernel.cu @@ -10,12 +10,9 @@ #include "atlas/library/config.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" #include "atlas/array/SVector.h" using namespace atlas::array; -using namespace eckit::testing; - namespace atlas { namespace test { @@ -24,7 +21,7 @@ __global__ void kernel_exe(int* list_ints_ptr, size_t size, int offset, bool* result ) { SVector list_ints(list_ints_ptr, size); - + *result = *result && (list_ints[offset] == 3); *result = *result && (list_ints[offset+1] == 4); @@ -54,7 +51,7 @@ CASE( "test_svector" ) *result=true; kernel_exe<<<1,1>>>(list_ints.data(), list_ints.size(), 0, result); cudaDeviceSynchronize(); - + err = cudaGetLastError(); if(err != cudaSuccess) throw eckit::AssertionFailed("failed to execute kernel"); diff --git a/src/tests/array/test_table.cc b/src/tests/array/test_table.cc index e0d17eca3..d30fce419 100644 --- a/src/tests/array/test_table.cc +++ b/src/tests/array/test_table.cc @@ -11,9 +11,7 @@ #include "atlas/array/Table.h" #include "atlas/runtime/Log.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" -using namespace eckit::testing; using namespace atlas::array; namespace atlas { diff --git a/src/tests/array/test_vector_kernel.cu b/src/tests/array/test_vector_kernel.cu index c495d61e2..9cbdcdd27 100644 --- a/src/tests/array/test_vector_kernel.cu +++ b/src/tests/array/test_vector_kernel.cu @@ -11,7 +11,6 @@ #include #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" #include "atlas/array/Vector.h" #include "atlas/array/gridtools/GPUClonable.h" @@ -20,7 +19,6 @@ #include "atlas/runtime/Log.h" using namespace atlas::array; -using namespace eckit::testing; namespace atlas { namespace test { diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index 72e9b9fd3..9b613310a 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -9,7 +9,6 @@ */ #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" #include "eckit/types/Types.h" #include "eckit/memory/ScopedPtr.h" #include "atlas/library/Library.h" @@ -29,7 +28,6 @@ using namespace eckit; using namespace atlas::functionspace; using namespace atlas::util; -using namespace eckit::testing; namespace atlas { namespace test { diff --git a/src/tests/functionspace/test_pointcloud.cc b/src/tests/functionspace/test_pointcloud.cc index 8e39c35be..d6dc53e70 100644 --- a/src/tests/functionspace/test_pointcloud.cc +++ b/src/tests/functionspace/test_pointcloud.cc @@ -13,11 +13,9 @@ #include "atlas/array.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" using namespace eckit; -using namespace eckit::testing; using namespace atlas::functionspace; using namespace atlas::util; diff --git a/src/tests/functionspace/test_structuredcolumns.cc b/src/tests/functionspace/test_structuredcolumns.cc index 1221a1b9a..9a3cd3d6d 100644 --- a/src/tests/functionspace/test_structuredcolumns.cc +++ b/src/tests/functionspace/test_structuredcolumns.cc @@ -26,11 +26,9 @@ #include "atlas/util/MicroDeg.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" using namespace eckit; -using namespace eckit::testing; using namespace atlas::functionspace; using namespace atlas::util; diff --git a/src/tests/grid/test_domain.cc b/src/tests/grid/test_domain.cc index b3b345a64..f27e7d063 100644 --- a/src/tests/grid/test_domain.cc +++ b/src/tests/grid/test_domain.cc @@ -17,7 +17,6 @@ #include "atlas/runtime/Log.h" #include "atlas/util/Config.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" using namespace eckit::testing; diff --git a/src/tests/grid/test_field.cc b/src/tests/grid/test_field.cc index a9018afe1..dc35f493c 100644 --- a/src/tests/grid/test_field.cc +++ b/src/tests/grid/test_field.cc @@ -26,7 +26,6 @@ #include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" -#include "eckit/testing/Test.h" #include "tests/AtlasTestEnvironment.h" using namespace std; diff --git a/src/tests/grid/test_grid_ptr.cc b/src/tests/grid/test_grid_ptr.cc index ecc7728f6..a8b376f15 100644 --- a/src/tests/grid/test_grid_ptr.cc +++ b/src/tests/grid/test_grid_ptr.cc @@ -23,7 +23,6 @@ #include "atlas/output/Gmsh.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" using Grid = atlas::Grid; using StructuredGrid = atlas::grid::StructuredGrid; diff --git a/src/tests/grid/test_grids.cc b/src/tests/grid/test_grids.cc index a78075988..48856e174 100644 --- a/src/tests/grid/test_grids.cc +++ b/src/tests/grid/test_grids.cc @@ -22,7 +22,6 @@ #include "eckit/types/FloatCompare.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" using StructuredGrid = atlas::grid::StructuredGrid; using Grid = atlas::Grid; diff --git a/src/tests/grid/test_rotation.cc b/src/tests/grid/test_rotation.cc index 6b10547cc..853147574 100644 --- a/src/tests/grid/test_rotation.cc +++ b/src/tests/grid/test_rotation.cc @@ -17,7 +17,6 @@ #include "eckit/types/FloatCompare.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" using atlas::util::Rotation; using atlas::util::Config; diff --git a/src/tests/grid/test_state.cc b/src/tests/grid/test_state.cc index 569bfd1ce..9608bd179 100644 --- a/src/tests/grid/test_state.cc +++ b/src/tests/grid/test_state.cc @@ -29,11 +29,9 @@ #include "atlas/runtime/Log.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" using namespace atlas::field; using namespace atlas::field; -using namespace eckit::testing; namespace atlas { namespace test { diff --git a/src/tests/interpolation/test_Quad3D.cc b/src/tests/interpolation/test_Quad3D.cc index 90183e638..63abf01e2 100644 --- a/src/tests/interpolation/test_Quad3D.cc +++ b/src/tests/interpolation/test_Quad3D.cc @@ -14,7 +14,6 @@ #include "atlas/util/Point.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" #include "eckit/types/FloatCompare.h" using atlas::interpolation::element::Quad3D; @@ -22,8 +21,6 @@ using atlas::interpolation::method::Intersect; using atlas::interpolation::method::Ray; using atlas::PointXYZ; -using namespace eckit::testing; - namespace atlas { namespace test { diff --git a/src/tests/interpolation/test_interpolation_finite_element.cc b/src/tests/interpolation/test_interpolation_finite_element.cc index 983ecd54c..d52f9f622 100644 --- a/src/tests/interpolation/test_interpolation_finite_element.cc +++ b/src/tests/interpolation/test_interpolation_finite_element.cc @@ -22,10 +22,8 @@ #include "atlas/util/CoordinateEnums.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" using namespace eckit; -using namespace eckit::testing; using namespace atlas::functionspace; using namespace atlas::util; @@ -41,7 +39,7 @@ CASE( "test_interpolation_finite_element" ) MeshGenerator meshgen("structured"); Mesh mesh = meshgen.generate(grid); NodeColumns fs(mesh); - + // Some points at the equator PointCloud pointcloud( { {00., 0.}, @@ -54,14 +52,14 @@ CASE( "test_interpolation_finite_element" ) {70., 0.}, {80., 0.}, {90., 0.}}); - + auto func = [](double x) -> double { return std::sin(x*M_PI/180.); }; - + Interpolation interpolation(Config("type","finite-element"),fs,pointcloud); - + Field field_source = fs.createField(option::name("source")); Field field_target("target",array::make_datatype(),array::make_shape(pointcloud.size())); - + auto lonlat = array::make_view(fs.nodes().lonlat()); auto source = array::make_view(field_source); for( size_t j=0; j #include using namespace eckit; -using namespace eckit::testing; using atlas::array::Array; using atlas::array::ArrayView; diff --git a/src/tests/util/test_earth.cc b/src/tests/util/test_earth.cc index ac2a48ce6..e48910611 100644 --- a/src/tests/util/test_earth.cc +++ b/src/tests/util/test_earth.cc @@ -14,10 +14,7 @@ #include "atlas/util/Point.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" - -using namespace eckit::testing; using atlas::util::Earth; namespace atlas { diff --git a/src/tests/util/test_flags.cc b/src/tests/util/test_flags.cc index 1956bac0e..bfe564ea8 100644 --- a/src/tests/util/test_flags.cc +++ b/src/tests/util/test_flags.cc @@ -12,10 +12,6 @@ #include "atlas/util/Bitflags.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" - -using namespace eckit::testing; - using atlas::util::Bitflags; diff --git a/src/tests/util/test_footprint.cc b/src/tests/util/test_footprint.cc index dbfd7d42f..15df1ee7b 100644 --- a/src/tests/util/test_footprint.cc +++ b/src/tests/util/test_footprint.cc @@ -22,11 +22,8 @@ #include "eckit/log/Bytes.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" - using namespace eckit; -using namespace eckit::testing; using namespace atlas::util; namespace atlas { diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index 335538f71..e78635325 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -14,8 +14,6 @@ #include "atlas/array/IndexView.h" #include "atlas/array/MakeView.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" - #ifdef ATLAS_HAVE_FORTRAN #define IN_FORTRAN @@ -24,7 +22,6 @@ #endif using namespace atlas::array; -using namespace eckit::testing; namespace atlas { namespace test { diff --git a/src/tests/util/test_metadata.cc b/src/tests/util/test_metadata.cc index 64f6b5788..8a5ad7911 100644 --- a/src/tests/util/test_metadata.cc +++ b/src/tests/util/test_metadata.cc @@ -14,12 +14,8 @@ #include "atlas/parallel/mpi/mpi.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" - - using namespace eckit; -using namespace eckit::testing; using namespace atlas::util; namespace atlas { @@ -34,14 +30,14 @@ CASE( "test_broadcast_to_self" ) { metadata.set("paramID",128); } - + // broadcast metadata.broadcast(); - + EXPECT( metadata.has("paramID") ); if( metadata.has("paramID") ) EXPECT( metadata.get("paramID") == 128 ); - + } // ----------------------------------------------------------------------------- @@ -54,16 +50,16 @@ CASE( "test_broadcast_to_other" ) { global.set("paramID",128); } - + Metadata local; - + // broadcast global.broadcast(local); - + EXPECT( local.has("paramID") ); if( local.has("paramID") ) EXPECT( local.get("paramID") == 128 ); - + if( parallel::mpi::comm().rank() != root ) EXPECT( ! global.has("paramID") ); } diff --git a/src/tests/util/test_polygon.cc b/src/tests/util/test_polygon.cc index 693243aeb..1a187aaa6 100644 --- a/src/tests/util/test_polygon.cc +++ b/src/tests/util/test_polygon.cc @@ -11,14 +11,11 @@ #include #include #include -#include "eckit/testing/Test.h" #include "atlas/util/SphericalPolygon.h" #include "atlas/util/Point.h" #include "tests/AtlasTestEnvironment.h" -using namespace eckit::testing; - namespace atlas { namespace test { diff --git a/src/tests/util/test_vector.cc b/src/tests/util/test_vector.cc index fa488e928..aa51467ac 100644 --- a/src/tests/util/test_vector.cc +++ b/src/tests/util/test_vector.cc @@ -10,9 +10,7 @@ #include "atlas/array/Vector.h" #include "tests/AtlasTestEnvironment.h" -#include "eckit/testing/Test.h" -using namespace eckit::testing; using namespace atlas::array; namespace atlas { @@ -58,4 +56,4 @@ CASE("test_vector") { int main(int argc, char **argv) { atlas::test::AtlasTestEnvironment env( argc, argv ); return run_tests ( argc, argv, false ); -} \ No newline at end of file +} From f40dbd7a78ac8cdc2ad47f46c0619d3367ee8e9d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 22 Jan 2018 09:51:57 +0000 Subject: [PATCH 259/355] ATLAS-143 Cleanup of testing --- src/tests/AtlasFixture.h | 44 ------------------- src/tests/AtlasTestEnvironment.h | 18 +++++++- src/tests/array/test_array.cc | 3 +- src/tests/array/test_array_slicer.cc | 3 +- src/tests/array/test_array_view_util.cc | 3 +- src/tests/array/test_svector.cc | 3 +- src/tests/array/test_table.cc | 3 +- src/tests/functionspace/test_functionspace.cc | 3 +- src/tests/functionspace/test_pointcloud.cc | 3 +- .../functionspace/test_structuredcolumns.cc | 3 +- src/tests/grid/test_domain.cc | 5 +-- src/tests/grid/test_field.cc | 4 +- src/tests/grid/test_grid_ptr.cc | 4 +- src/tests/grid/test_grids.cc | 5 +-- src/tests/grid/test_rotation.cc | 5 +-- src/tests/grid/test_state.cc | 3 +- src/tests/interpolation/test_Quad3D.cc | 3 +- .../test_interpolation_finite_element.cc | 3 +- src/tests/io/test_gmsh.cc | 3 +- src/tests/io/test_pointcloud_io.cc | 3 +- src/tests/mesh/test_accumulate_facets.cc | 7 ++- src/tests/mesh/test_connectivity.cc | 3 +- src/tests/mesh/test_distmesh.cc | 3 +- src/tests/mesh/test_elements.cc | 3 +- src/tests/mesh/test_halo.cc | 3 +- src/tests/mesh/test_ll.cc | 3 +- src/tests/mesh/test_meshgen3d.cc | 3 +- src/tests/mesh/test_parfields.cc | 3 +- src/tests/mesh/test_rgg.cc | 3 +- src/tests/mesh/test_shapefunctions.cc | 3 +- src/tests/numerics/test_fvm_nabla.cc | 3 +- src/tests/parallel/test_gather.cc | 5 +-- src/tests/parallel/test_haloexchange.cc | 3 +- src/tests/trans/CMakeLists.txt | 1 + src/tests/trans/test_trans.cc | 3 +- src/tests/trans/test_trans_invtrans_grad.cc | 3 +- src/tests/trans/test_transgeneral.cc | 5 +-- src/tests/util/test_earth.cc | 3 +- src/tests/util/test_flags.cc | 3 +- src/tests/util/test_footprint.cc | 3 +- src/tests/util/test_indexview.cc | 3 +- src/tests/util/test_metadata.cc | 3 +- src/tests/util/test_polygon.cc | 3 +- src/tests/util/test_vector.cc | 3 +- 44 files changed, 61 insertions(+), 141 deletions(-) delete mode 100644 src/tests/AtlasFixture.h diff --git a/src/tests/AtlasFixture.h b/src/tests/AtlasFixture.h deleted file mode 100644 index b11798c56..000000000 --- a/src/tests/AtlasFixture.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * (C) Copyright 1996-2017 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 "eckit/testing/Setup.h" - -#include "atlas/library/Library.h" -#include "eckit/runtime/Main.h" -#include "eckit/mpi/Comm.h" -#include "atlas/runtime/Log.h" -#include "eckit/config/Resource.h" - -namespace atlas { -namespace test { - - -struct AtlasFixture : public eckit::testing::Setup { - - AtlasFixture() { - eckit::Main::instance().taskID( eckit::mpi::comm("world").rank() ); - if( eckit::mpi::comm("world").size() != 1 ) { - long logtask = eckit::Resource("--logtask;$ATLAS_TEST_LOGTASK",0); - if( eckit::Main::instance().taskID() != logtask ) Log::reset(); - } - atlas::Library::instance().initialise(); - } - - ~AtlasFixture() { - atlas::Library::instance().finalise(); - } -}; - -//---------------------------------------------------------------------------------------------------------------------- - -} // end namespace test -} // end namespace atlas diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index e09ab6f0a..006896e9a 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -18,11 +18,13 @@ #include "eckit/config/Resource.h" #include "eckit/testing/Test.h" -using namespace eckit::testing; - namespace atlas { namespace test { +//---------------------------------------------------------------------------------------------------------------------- + +// Redefine macro's defined in "eckit/testing/Test.h" to include trace information + #ifdef CASE #undef CASE #endif @@ -75,5 +77,17 @@ struct AtlasTestEnvironment { //---------------------------------------------------------------------------------------------------------------------- +template< typename Environment > +int run(int argc, char* argv[]) { + Environment env( argc, argv ); + return eckit::testing::run_tests(argc,argv,false); +} + +int run(int argc, char* argv[]) { + return run( argc, argv ); +} + +//---------------------------------------------------------------------------------------------------------------------- + } // end namespace test } // end namespace atlas diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index f122f6410..441bfe9e2 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -591,7 +591,6 @@ CASE("test_acc_map") { int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return eckit::testing::run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index 6f7c7a0f2..b1e2b5343 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -375,7 +375,6 @@ CASE( "test_arrayview_slice_type" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return eckit::testing::run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/array/test_array_view_util.cc b/src/tests/array/test_array_view_util.cc index 5d5b94dd6..23254dd4a 100644 --- a/src/tests/array/test_array_view_util.cc +++ b/src/tests/array/test_array_view_util.cc @@ -58,7 +58,6 @@ CASE("test_get_parallel_dim") { int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/array/test_svector.cc b/src/tests/array/test_svector.cc index 2c9ea1389..e5de54113 100644 --- a/src/tests/array/test_svector.cc +++ b/src/tests/array/test_svector.cc @@ -70,7 +70,6 @@ CASE( "test_svector_resize" ) } // namespace atlas int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/array/test_table.cc b/src/tests/array/test_table.cc index d30fce419..eb48fce5f 100644 --- a/src/tests/array/test_table.cc +++ b/src/tests/array/test_table.cc @@ -226,7 +226,6 @@ CASE( "test_table_row" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index 9b613310a..de9265f1e 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -658,7 +658,6 @@ CASE( "test_SpectralFunctionSpace_norm" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/functionspace/test_pointcloud.cc b/src/tests/functionspace/test_pointcloud.cc index d6dc53e70..5dccac646 100644 --- a/src/tests/functionspace/test_pointcloud.cc +++ b/src/tests/functionspace/test_pointcloud.cc @@ -57,6 +57,5 @@ CASE( "test_functionspace_PointCloud" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/functionspace/test_structuredcolumns.cc b/src/tests/functionspace/test_structuredcolumns.cc index 9a3cd3d6d..fc200fb73 100644 --- a/src/tests/functionspace/test_structuredcolumns.cc +++ b/src/tests/functionspace/test_structuredcolumns.cc @@ -208,6 +208,5 @@ CASE( "test_functionspace_StructuredColumns_halo" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_domain.cc b/src/tests/grid/test_domain.cc index f27e7d063..67d4d70de 100644 --- a/src/tests/grid/test_domain.cc +++ b/src/tests/grid/test_domain.cc @@ -18,8 +18,6 @@ #include "atlas/util/Config.h" #include "tests/AtlasTestEnvironment.h" -using namespace eckit::testing; - namespace atlas { namespace test { @@ -123,6 +121,5 @@ CASE( "test_domain_global_from_zonalband" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_field.cc b/src/tests/grid/test_field.cc index dc35f493c..68923371f 100644 --- a/src/tests/grid/test_field.cc +++ b/src/tests/grid/test_field.cc @@ -30,7 +30,6 @@ using namespace std; using namespace eckit; -using namespace eckit::testing; using namespace atlas; using namespace atlas::grid; using namespace atlas::meshgenerator; @@ -156,6 +155,5 @@ CASE( "test_wrap_rawdata_direct" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_grid_ptr.cc b/src/tests/grid/test_grid_ptr.cc index a8b376f15..de91d7ce8 100644 --- a/src/tests/grid/test_grid_ptr.cc +++ b/src/tests/grid/test_grid_ptr.cc @@ -29,7 +29,6 @@ using StructuredGrid = atlas::grid::StructuredGrid; using RegularGrid = atlas::grid::RegularGrid; using Config = atlas::util::Config; -using namespace eckit::testing; namespace atlas { namespace test { @@ -208,6 +207,5 @@ CASE( "test_iterator" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_grids.cc b/src/tests/grid/test_grids.cc index 48856e174..950566280 100644 --- a/src/tests/grid/test_grids.cc +++ b/src/tests/grid/test_grids.cc @@ -28,8 +28,6 @@ using Grid = atlas::Grid; using Regular = atlas::grid::RegularGrid; using ReducedGaussianGrid = atlas::grid::ReducedGaussianGrid; -using namespace eckit::testing; - namespace atlas { namespace test { @@ -156,6 +154,5 @@ CASE( "test_reducedgaussian" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_rotation.cc b/src/tests/grid/test_rotation.cc index 853147574..0dbc255e3 100644 --- a/src/tests/grid/test_rotation.cc +++ b/src/tests/grid/test_rotation.cc @@ -21,8 +21,6 @@ using atlas::util::Rotation; using atlas::util::Config; -using namespace eckit::testing; - namespace atlas { namespace test { @@ -239,6 +237,5 @@ CASE( "test_rotation_angle_only" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_state.cc b/src/tests/grid/test_state.cc index 9608bd179..0490e403e 100644 --- a/src/tests/grid/test_state.cc +++ b/src/tests/grid/test_state.cc @@ -214,6 +214,5 @@ CASE( "state_create" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/interpolation/test_Quad3D.cc b/src/tests/interpolation/test_Quad3D.cc index 63abf01e2..d2c3bef42 100644 --- a/src/tests/interpolation/test_Quad3D.cc +++ b/src/tests/interpolation/test_Quad3D.cc @@ -234,6 +234,5 @@ CASE( "test_quadrilateral_intersection_corners" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/interpolation/test_interpolation_finite_element.cc b/src/tests/interpolation/test_interpolation_finite_element.cc index d52f9f622..0bb1901c8 100644 --- a/src/tests/interpolation/test_interpolation_finite_element.cc +++ b/src/tests/interpolation/test_interpolation_finite_element.cc @@ -97,6 +97,5 @@ CASE( "test_interpolation_finite_element" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/io/test_gmsh.cc b/src/tests/io/test_gmsh.cc index dc4126e6a..ba83fa932 100644 --- a/src/tests/io/test_gmsh.cc +++ b/src/tests/io/test_gmsh.cc @@ -38,6 +38,5 @@ CASE( "test_gmsh_output" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/io/test_pointcloud_io.cc b/src/tests/io/test_pointcloud_io.cc index ece7faa7e..565ce8aa3 100644 --- a/src/tests/io/test_pointcloud_io.cc +++ b/src/tests/io/test_pointcloud_io.cc @@ -453,6 +453,5 @@ CASE( "write_read_write_field" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_accumulate_facets.cc b/src/tests/mesh/test_accumulate_facets.cc index d38a07be7..eb9ddec3d 100644 --- a/src/tests/mesh/test_accumulate_facets.cc +++ b/src/tests/mesh/test_accumulate_facets.cc @@ -227,7 +227,7 @@ CASE( "test_accumulate_facets" ) 88, 89, 89, 67 }; - EXPECT( edge_nodes_data == make_view(edge_nodes_check, edge_nodes_check+2*nb_edges) ); + EXPECT( edge_nodes_data == eckit::testing::make_view(edge_nodes_check, edge_nodes_check+2*nb_edges) ); idx_t edge_to_cell_check[] = { 0, missing_value, @@ -402,7 +402,7 @@ CASE( "test_accumulate_facets" ) 78, missing_value, 78, 79 }; - EXPECT( edge_to_cell_data == make_view(edge_to_cell_check, edge_to_cell_check+2*nb_edges) ); + EXPECT( edge_to_cell_data == eckit::testing::make_view(edge_to_cell_check, edge_to_cell_check+2*nb_edges) ); } CASE( "test_build_edges" ) @@ -859,6 +859,5 @@ CASE( "test_build_edges_triangles_only" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_connectivity.cc b/src/tests/mesh/test_connectivity.cc index 897ae9f5f..a27345caa 100644 --- a/src/tests/mesh/test_connectivity.cc +++ b/src/tests/mesh/test_connectivity.cc @@ -561,6 +561,5 @@ CASE("test_multi_block_connectivity_insert") { int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_distmesh.cc b/src/tests/mesh/test_distmesh.cc index 7fd9bcd37..b250ee620 100644 --- a/src/tests/mesh/test_distmesh.cc +++ b/src/tests/mesh/test_distmesh.cc @@ -149,6 +149,5 @@ CASE( "test_distribute_t63" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_elements.cc b/src/tests/mesh/test_elements.cc index c9a7112e1..4b9519f62 100644 --- a/src/tests/mesh/test_elements.cc +++ b/src/tests/mesh/test_elements.cc @@ -472,6 +472,5 @@ CASE( "cells_add_add" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index 4f31ca040..7271c9046 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -506,6 +506,5 @@ CASE( "test_t63" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_ll.cc b/src/tests/mesh/test_ll.cc index e425f9263..59ea569c8 100644 --- a/src/tests/mesh/test_ll.cc +++ b/src/tests/mesh/test_ll.cc @@ -36,7 +36,6 @@ CASE( "test_ll_meshgen_one_part" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_meshgen3d.cc b/src/tests/mesh/test_meshgen3d.cc index 1be82a8b6..adf2d4a7b 100644 --- a/src/tests/mesh/test_meshgen3d.cc +++ b/src/tests/mesh/test_meshgen3d.cc @@ -53,6 +53,5 @@ CASE( "test_create_mesh" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_parfields.cc b/src/tests/mesh/test_parfields.cc index 308953e87..9f4c19330 100644 --- a/src/tests/mesh/test_parfields.cc +++ b/src/tests/mesh/test_parfields.cc @@ -209,7 +209,6 @@ CASE( "test2" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_rgg.cc b/src/tests/mesh/test_rgg.cc index f79e8071d..d97d220d6 100644 --- a/src/tests/mesh/test_rgg.cc +++ b/src/tests/mesh/test_rgg.cc @@ -511,6 +511,5 @@ CASE( "test_meshgen_ghost_at_end" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_shapefunctions.cc b/src/tests/mesh/test_shapefunctions.cc index cd28001c4..3243b1428 100644 --- a/src/tests/mesh/test_shapefunctions.cc +++ b/src/tests/mesh/test_shapefunctions.cc @@ -954,6 +954,5 @@ CASE( "test_polynomial" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/numerics/test_fvm_nabla.cc b/src/tests/numerics/test_fvm_nabla.cc index d31e0fbe0..fb9782523 100644 --- a/src/tests/numerics/test_fvm_nabla.cc +++ b/src/tests/numerics/test_fvm_nabla.cc @@ -354,6 +354,5 @@ CASE( "test_lapl" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/parallel/test_gather.cc b/src/tests/parallel/test_gather.cc index b309429e0..0008d7c25 100644 --- a/src/tests/parallel/test_gather.cc +++ b/src/tests/parallel/test_gather.cc @@ -104,7 +104,7 @@ CASE("test_gather") { if( parallel::mpi::comm().rank() == f.root ) { POD glb_c[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90 }; - EXPECT(glb == make_view( glb_c,glb_c+f.Ng() ) ); + EXPECT(glb == eckit::testing::make_view( glb_c,glb_c+f.Ng() ) ); } } } @@ -765,6 +765,5 @@ CASE("test_gather") { int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 0950da941..1018b8d18 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -737,7 +737,6 @@ CASE("test_haloexchange") { int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/trans/CMakeLists.txt b/src/tests/trans/CMakeLists.txt index b6780d358..2fc12e75f 100644 --- a/src/tests/trans/CMakeLists.txt +++ b/src/tests/trans/CMakeLists.txt @@ -49,5 +49,6 @@ ecbuild_add_test( TARGET atlas_test_transgeneral SOURCES test_transgeneral.cc CONDITION ATLAS_HAVE_TRANS LIBS atlas + ENVIRONMENT ATLAS_TEST_REPORT=1 ) diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 129d40fd2..7a66393d7 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -512,6 +512,5 @@ CASE( "test_trans_MIR_lonlat" ) int main(int argc, char **argv) { - atlas::test::AtlasTransEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run< atlas::test::AtlasTransEnvironment >( argc, argv ); } diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index 0656d21c2..1ba0c7757 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -192,7 +192,6 @@ CASE( "test_invtrans_grad" ) int main(int argc, char **argv) { - atlas::test::AtlasTransEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run< atlas::test::AtlasTransEnvironment >( argc, argv ); } diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 545b75694..f61525974 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -588,8 +588,5 @@ CASE( "test_trans_invtrans" ) { int main(int argc, char **argv) { - atlas::test::AtlasTransEnvironment env( argc, argv ); - int i = run_tests ( argc, argv, false ); - std::cout << atlas::Trace::report() << std::endl; - return i; + return atlas::test::run< atlas::test::AtlasTransEnvironment >( argc, argv ); } diff --git a/src/tests/util/test_earth.cc b/src/tests/util/test_earth.cc index e48910611..8697547a7 100644 --- a/src/tests/util/test_earth.cc +++ b/src/tests/util/test_earth.cc @@ -191,6 +191,5 @@ CASE( "test_earth_great_circle_latitude_given_longitude" ) } // namespace atlas int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_flags.cc b/src/tests/util/test_flags.cc index bfe564ea8..ed203aeb7 100644 --- a/src/tests/util/test_flags.cc +++ b/src/tests/util/test_flags.cc @@ -47,6 +47,5 @@ CASE( "test_Flags" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_footprint.cc b/src/tests/util/test_footprint.cc index 15df1ee7b..2f12ab02b 100644 --- a/src/tests/util/test_footprint.cc +++ b/src/tests/util/test_footprint.cc @@ -70,6 +70,5 @@ CASE( "test_broadcast_to_self" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index e78635325..9da0c5c4c 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -287,6 +287,5 @@ CASE( "test_indexview_3d" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_metadata.cc b/src/tests/util/test_metadata.cc index 8a5ad7911..9ad26339c 100644 --- a/src/tests/util/test_metadata.cc +++ b/src/tests/util/test_metadata.cc @@ -71,6 +71,5 @@ CASE( "test_broadcast_to_other" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_polygon.cc b/src/tests/util/test_polygon.cc index 1a187aaa6..e75aee4be 100644 --- a/src/tests/util/test_polygon.cc +++ b/src/tests/util/test_polygon.cc @@ -130,6 +130,5 @@ CASE( "test_polygon_something" ) int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_vector.cc b/src/tests/util/test_vector.cc index aa51467ac..aa1fa306d 100644 --- a/src/tests/util/test_vector.cc +++ b/src/tests/util/test_vector.cc @@ -54,6 +54,5 @@ CASE("test_vector") { int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } From 7dead3910f68fe76f92215c088c05fab1f7976ce Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Mon, 22 Jan 2018 12:11:55 +0000 Subject: [PATCH 260/355] ATLAS-135 first step towards creating vorticity divergence test in test_transgeneral --- src/atlas/trans/local/TransLocal.cc | 30 +++++++-- src/atlas/trans/local/TransLocal.h | 4 ++ src/tests/trans/test_transgeneral.cc | 94 +++++++++++++++++++++------- 3 files changed, 99 insertions(+), 29 deletions(-) diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index ce9a153a6..2b59306db 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -146,16 +146,25 @@ void TransLocal::invtrans_vordiv2wind( NOTIMP; } +void TransLocal::invtrans( + const int nb_scalar_fields, const double scalar_spectra[], + double gp_fields[], + const eckit::Configuration& config ) const +{ + invtrans_uv(nb_scalar_fields, 0, scalar_spectra, gp_fields, config); +} + //----------------------------------------------------------------------------- // Routine to compute the spectral transform by using a local Fourier transformation // for a grid (same latitude for all longitudes, allows to compute Legendre functions -// once for all longitudes) +// once for all longitudes). U and v components are divided by cos(latitude) for +// nb_vordiv_fields > 0. // // Author: // Andreas Mueller *ECMWF* // -void TransLocal::invtrans( - const int nb_scalar_fields, const double scalar_spectra[], +void TransLocal::invtrans_uv( + const int nb_scalar_fields, const int nb_vordiv_fields, const double scalar_spectra[], double gp_fields[], const eckit::Configuration& config ) const { @@ -196,6 +205,11 @@ void TransLocal::invtrans( invtrans_fourier( trcFT, lon, nb_fields, legReal.data(), legImag.data(), gp_fields+(nb_fields*idx)); ++idx; } + + // Divide U, V by cos(latitude): + for( int jfld=2*nb_vordiv_fields; jfld<4*nb_vordiv_fields; ++jfld ) { + gp_fields[nb_fields*idx+jfld] /= std::cos(lat); + } } } else { ATLAS_TRACE( "invtrans unstructured"); @@ -211,6 +225,11 @@ void TransLocal::invtrans( // Fourier transform: invtrans_fourier( trcFT, lon, nb_fields, legReal.data(), legImag.data(), gp_fields+(nb_fields*idx)); ++idx; + + // Divide U, V by cos(latitude): + for( int jfld=2*nb_vordiv_fields; jfld<4*nb_vordiv_fields; ++jfld ) { + gp_fields[nb_fields*idx+jfld] /= std::cos(lat); + } } } } @@ -329,7 +348,7 @@ void vd2uv( double za_r = 1./util::Earth::radiusInMeters(); for( int j=0; j(option::name("spf") | option::global()); Field spf = spectral. createField(option::name("spf")); Field gpf = gridpoints.createField(option::name("gpf")); - Field gpfg = gridpoints.createField(option::name("gpf") | option::global()); int N = (trc+2)*(trc+1)/2; std::vector rspecg (2*N); std::vector rgp (g.size()); std::vector rgp_analytic (g.size()); - ASSERT( 2*N == spectral.nb_spectral_coefficients_global() ); - int k = 0; for( int m=0; m<=trc; m++ ) { // zonal wavenumber for( int n=m; n<=trc; n++ ) { // total wavenumber @@ -524,36 +520,86 @@ CASE( "test_transgeneral_with_translib" ) if( sphericalharmonics_analytic_point(n, m, true, 0., 0.) == 0. ) { - ATLAS_DEBUG_VAR( k ); - array::ArrayView spg = array::make_view(spfg); - if( parallel::mpi::comm().rank() == 0 ) { - spg.assign(0.); - spg(k) = 1.; - } + array::ArrayView sp = array::make_view(spf); + sp.assign(0.); + sp(k) = 1.; + + EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); - EXPECT_NO_THROW( spectral.scatter(spfg,spf) ); + spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data()); + + // compute spectral transform with the general transform: + spectral_transform_grid(trc, trc, g, sp.data(), rgp.data(), false); - if( parallel::mpi::comm().rank() == 0 ) { - array::ArrayView sp = array::make_view(spf); - EXPECT( eckit::types::is_approximately_equal( sp(k), 1., 0.001 )); - for( size_t jp=0; jp gp = array::make_view(gpf); + double rms_trans = compute_rms(g.size(), gp.data(), rgp.data()); + double rms_gen = compute_rms(g.size(), rgp.data(), rgp_analytic.data()); + + if( rms_gen >= tolerance ) { + ATLAS_DEBUG_VAR(rms_gen); + ATLAS_DEBUG_VAR(tolerance); } + EXPECT( rms_gen < tolerance ); + EXPECT( rms_trans < tolerance ); + } + k++; + } + } + } +} - EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); +//----------------------------------------------------------------------------- - EXPECT_NO_THROW( gridpoints.gather(gpf,gpfg) ); +CASE( "test_trans_vordiv_with_translib" ) +{ + Log::info() << "test_trans_vordiv_with_translib" << std::endl; + // test transgeneral by comparing its result with the trans library + // this test is based on the test_nomesh case in test_trans.cc - array::ArrayView gpg = array::make_view(gpfg); + std::ostream& out = Log::info(); + double tolerance = 1.e-13; + Grid g( "F24" ); + grid::StructuredGrid gs(g); + int trc = 47; + trans::Trans trans(g,trc) ; - spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data()); + functionspace::Spectral spectral (trans); + functionspace::StructuredColumns gridpoints (g); + + int N = (trc+2)*(trc+1)/2; + double sp [2*N ]; + double vor [2*N ]; + double div [2*N ]; + double rspecg [2*N ]; + double gp [g.size()]; + double rgp [g.size()]; + double rgp_analytic [g.size()]; + + int nb_scalar = 1, nb_vordiv = 0; + + int k = 0; + for( int m=0; m<=trc; m++ ) { // zonal wavenumber + for( int n=m; n<=trc; n++ ) { // total wavenumber + for( int imag=0; imag<=1; imag++ ) { // real and imaginary part + + if( sphericalharmonics_analytic_point(n, m, true, 0., 0.) == 0. ) { + + for( int j=0; j<2*N; j++ ) { + sp [j] = 0.; + vor[j] = 0.; + div[j] = 0.; + } + sp[k] = 1.; + + EXPECT_NO_THROW( trans.invtrans( nb_scalar, sp, nb_vordiv, vor, div, gp ) ); + + spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg, rgp_analytic); // compute spectral transform with the general transform: - spectral_transform_grid(trc, trc, g, spg.data(), rgp.data(), false); + spectral_transform_grid(trc, trc, g, sp, rgp, false); - double rms_trans = compute_rms(g.size(), gpg.data(), rgp.data()); - double rms_gen = compute_rms(g.size(), rgp.data(), rgp_analytic.data()); + double rms_trans = compute_rms(g.size(), gp, rgp); + double rms_gen = compute_rms(g.size(), rgp, rgp_analytic); if( rms_gen >= tolerance ) { ATLAS_DEBUG_VAR(rms_gen); From dd7ab110f4c308b6fa32e2862f3c1c0a4aa8cdc7 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 23 Jan 2018 17:42:58 +0000 Subject: [PATCH 261/355] Update copyright headers --- CMakeLists.txt | 2 +- VERSION.cmake | 2 +- cmake/FindLatex.cmake | 20 +++++++++---------- cmake/atlas_host_device.cmake | 8 ++++++++ doc/CMakeLists.txt | 8 ++++++++ doc/user-guide/CMakeLists.txt | 8 ++++++++ .../core-functionalities/CMakeLists.txt | 8 ++++++++ .../fields/CMakeLists.txt | 8 ++++++++ .../functionspace/CMakeLists.txt | 8 ++++++++ .../global-grids/CMakeLists.txt | 8 ++++++++ .../meshes/CMakeLists.txt | 8 ++++++++ doc/user-guide/getting-started/CMakeLists.txt | 8 ++++++++ project_summary.cmake | 8 ++++---- src/CMakeLists.txt | 2 +- src/apps/CMakeLists.txt | 12 +++++++++-- src/apps/atlas-benchmark.cc | 2 +- src/apps/atlas-gaussian-latitudes.cc | 2 +- src/apps/atlas-gmsh-extract.cc | 2 +- src/apps/atlas-grids.cc | 2 +- src/apps/atlas-loadbalance.cc | 2 +- src/apps/atlas-meshgen.cc | 2 +- src/apps/atlas-numerics-nabla.F90 | 2 +- src/apps/atlas.cc | 2 +- src/atlas/CMakeLists.txt | 2 +- src/atlas/array.h | 2 +- src/atlas/array/Array.h | 2 +- src/atlas/array/ArrayIdx.h | 2 +- src/atlas/array/ArrayLayout.h | 2 +- src/atlas/array/ArrayShape.h | 2 +- src/atlas/array/ArraySpec.cc | 2 +- src/atlas/array/ArraySpec.h | 2 +- src/atlas/array/ArrayStrides.h | 2 +- src/atlas/array/ArrayUtil.cc | 2 +- src/atlas/array/ArrayUtil.h | 2 +- src/atlas/array/ArrayView.h | 2 +- src/atlas/array/ArrayViewDefs.h | 2 +- src/atlas/array/ArrayViewUtil.h | 2 +- src/atlas/array/DataType.h | 2 +- src/atlas/array/IndexView.h | 2 +- src/atlas/array/LocalView.cc | 2 +- src/atlas/array/LocalView.h | 2 +- src/atlas/array/Range.h | 2 +- src/atlas/array/SVector.h | 2 +- src/atlas/array/Table.cc | 2 +- src/atlas/array/Table.h | 2 +- src/atlas/array/TableView.cc | 2 +- src/atlas/array/TableView.h | 2 +- src/atlas/array/Vector.h | 2 +- src/atlas/array/gridtools/GPUClonable.h | 2 +- src/atlas/array/gridtools/GridToolsArray.cc | 2 +- .../array/gridtools/GridToolsArrayHelpers.h | 2 +- .../array/gridtools/GridToolsArrayView.cc | 2 +- .../array/gridtools/GridToolsArrayView.h | 2 +- .../array/gridtools/GridToolsDataStore.h | 2 +- .../array/gridtools/GridToolsIndexView.cc | 2 +- .../array/gridtools/GridToolsIndexView.h | 2 +- src/atlas/array/gridtools/GridToolsMakeView.h | 2 +- src/atlas/array/helpers/ArrayAssigner.h | 2 +- src/atlas/array/helpers/ArrayInitializer.h | 2 +- src/atlas/array/helpers/ArraySlicer.h | 2 +- src/atlas/array/helpers/ArrayWriter.h | 2 +- src/atlas/array/native/NativeArrayView.cc | 2 +- src/atlas/array/native/NativeArrayView.h | 2 +- src/atlas/array/native/NativeDataStore.h | 2 +- src/atlas/array/native/NativeIndexView.cc | 2 +- src/atlas/array/native/NativeIndexView.h | 2 +- src/atlas/array_fwd.h | 2 +- src/atlas/domain.h | 2 +- src/atlas/domain/Domain.cc | 2 +- src/atlas/domain/Domain.h | 2 +- src/atlas/field.h | 2 +- src/atlas/field/Field.cc | 2 +- src/atlas/field/Field.h | 2 +- src/atlas/field/FieldCreator.cc | 2 +- src/atlas/field/FieldCreator.h | 2 +- src/atlas/field/FieldCreatorArraySpec.cc | 2 +- src/atlas/field/FieldCreatorArraySpec.h | 2 +- src/atlas/field/FieldCreatorIFS.cc | 2 +- src/atlas/field/FieldCreatorIFS.h | 2 +- src/atlas/field/FieldSet.cc | 2 +- src/atlas/field/FieldSet.h | 2 +- src/atlas/field/State.cc | 2 +- src/atlas/field/State.h | 2 +- src/atlas/field/detail/FieldImpl.cc | 2 +- src/atlas/field/detail/FieldImpl.h | 2 +- src/atlas/functionspace.h | 2 +- src/atlas/functionspace/EdgeColumns.cc | 2 +- src/atlas/functionspace/EdgeColumns.h | 2 +- src/atlas/functionspace/FunctionSpace.cc | 2 +- src/atlas/functionspace/FunctionSpace.h | 2 +- src/atlas/functionspace/NodeColumns.cc | 2 +- src/atlas/functionspace/NodeColumns.h | 2 +- .../functionspace/NodeColumnsInterface.cc | 2 +- .../functionspace/NodeColumnsInterface.h | 2 +- src/atlas/functionspace/PointCloud.cc | 2 +- src/atlas/functionspace/PointCloud.h | 2 +- src/atlas/functionspace/Spectral.cc | 2 +- src/atlas/functionspace/Spectral.h | 2 +- src/atlas/functionspace/StructuredColumns.cc | 2 +- src/atlas/functionspace/StructuredColumns.h | 2 +- src/atlas/grid.h | 2 +- src/atlas/grid/Distribution.cc | 2 +- src/atlas/grid/Distribution.h | 2 +- src/atlas/grid/Grid.cc | 2 +- src/atlas/grid/Grid.h | 2 +- src/atlas/grid/Iterator.h | 2 +- src/atlas/grid/Partitioner.cc | 2 +- src/atlas/grid/Partitioner.h | 2 +- src/atlas/grid/detail/grid/Grid.cc | 2 +- src/atlas/grid/detail/grid/Grid.h | 2 +- src/atlas/grid/detail/grid/GridBuilder.cc | 2 +- src/atlas/grid/detail/grid/GridBuilder.h | 2 +- src/atlas/grid/detail/grid/Structured.cc | 2 +- src/atlas/grid/detail/grid/Structured.h | 2 +- src/atlas/grid/detail/grid/Unstructured.cc | 2 +- src/atlas/grid/detail/grid/Unstructured.h | 2 +- .../partitioner/EqualRegionsPartitioner.cc | 2 +- .../partitioner/EqualRegionsPartitioner.h | 2 +- .../partitioner/MatchingMeshPartitioner.h | 2 +- .../MatchingMeshPartitionerBruteForce.cc | 2 +- .../MatchingMeshPartitionerBruteForce.h | 2 +- .../MatchingMeshPartitionerLonLatPolygon.cc | 2 +- .../MatchingMeshPartitionerLonLatPolygon.h | 2 +- ...MatchingMeshPartitionerSphericalPolygon.cc | 2 +- .../MatchingMeshPartitionerSphericalPolygon.h | 2 +- .../grid/detail/partitioner/Partitioner.cc | 2 +- .../grid/detail/partitioner/Partitioner.h | 2 +- .../detail/partitioner/TransPartitioner.cc | 2 +- .../detail/partitioner/TransPartitioner.h | 2 +- .../grid/detail/pl/classic_gaussian/N.cc | 2 +- src/atlas/grid/detail/pl/classic_gaussian/N.h | 2 +- .../pl/classic_gaussian/PointsPerLatitude.cc | 2 +- .../pl/classic_gaussian/PointsPerLatitude.h | 2 +- .../grid/detail/spacing/gaussian/Latitudes.cc | 2 +- .../grid/detail/spacing/gaussian/Latitudes.h | 2 +- src/atlas/grid/detail/spacing/gaussian/N.cc | 2 +- src/atlas/grid/detail/spacing/gaussian/N.h | 2 +- src/atlas/interpolation.h | 2 +- src/atlas/interpolation/Interpolation.cc | 2 +- src/atlas/interpolation/Interpolation.h | 2 +- src/atlas/interpolation/Vector2D.h | 2 +- src/atlas/interpolation/Vector3D.h | 2 +- src/atlas/interpolation/element/Quad3D.cc | 2 +- src/atlas/interpolation/element/Quad3D.h | 2 +- src/atlas/interpolation/element/Triag3D.cc | 2 +- src/atlas/interpolation/element/Triag3D.h | 2 +- .../interpolation/method/FiniteElement.cc | 2 +- .../interpolation/method/FiniteElement.h | 2 +- src/atlas/interpolation/method/Intersect.cc | 2 +- src/atlas/interpolation/method/Intersect.h | 2 +- .../method/KNearestNeighbours.cc | 2 +- .../interpolation/method/KNearestNeighbours.h | 2 +- .../method/KNearestNeighboursBase.cc | 2 +- .../method/KNearestNeighboursBase.h | 2 +- src/atlas/interpolation/method/Method.cc | 2 +- src/atlas/interpolation/method/Method.h | 2 +- .../interpolation/method/NearestNeighbour.cc | 2 +- .../interpolation/method/NearestNeighbour.h | 2 +- src/atlas/interpolation/method/PointIndex3.cc | 2 +- src/atlas/interpolation/method/PointIndex3.h | 2 +- src/atlas/interpolation/method/PointSet.cc | 2 +- src/atlas/interpolation/method/PointSet.h | 2 +- src/atlas/interpolation/method/Ray.cc | 2 +- src/atlas/interpolation/method/Ray.h | 2 +- src/atlas/library/Library.cc | 2 +- src/atlas/library/Library.h | 2 +- src/atlas/mesh.h | 2 +- src/atlas/mesh/Connectivity.cc | 2 +- src/atlas/mesh/Connectivity.h | 2 +- src/atlas/mesh/ElementType.cc | 2 +- src/atlas/mesh/ElementType.h | 2 +- src/atlas/mesh/Elements.cc | 2 +- src/atlas/mesh/Elements.h | 2 +- src/atlas/mesh/Halo.cc | 2 +- src/atlas/mesh/Halo.h | 2 +- src/atlas/mesh/HybridElements.cc | 2 +- src/atlas/mesh/HybridElements.h | 2 +- src/atlas/mesh/IsGhostNode.h | 2 +- src/atlas/mesh/Mesh.cc | 2 +- src/atlas/mesh/Mesh.h | 2 +- src/atlas/mesh/Nodes.cc | 2 +- src/atlas/mesh/Nodes.h | 2 +- src/atlas/mesh/PartitionPolygon.cc | 2 +- src/atlas/mesh/PartitionPolygon.h | 2 +- src/atlas/mesh/actions/BuildCellCentres.cc | 2 +- src/atlas/mesh/actions/BuildCellCentres.h | 2 +- src/atlas/mesh/actions/BuildConvexHull3D.cc | 2 +- src/atlas/mesh/actions/BuildConvexHull3D.h | 2 +- src/atlas/mesh/actions/BuildDualMesh.cc | 2 +- src/atlas/mesh/actions/BuildDualMesh.h | 2 +- src/atlas/mesh/actions/BuildEdges.cc | 2 +- src/atlas/mesh/actions/BuildEdges.h | 2 +- src/atlas/mesh/actions/BuildHalo.cc | 2 +- src/atlas/mesh/actions/BuildHalo.h | 2 +- src/atlas/mesh/actions/BuildParallelFields.cc | 2 +- src/atlas/mesh/actions/BuildParallelFields.h | 2 +- .../mesh/actions/BuildPeriodicBoundaries.cc | 2 +- .../mesh/actions/BuildPeriodicBoundaries.h | 2 +- src/atlas/mesh/actions/BuildStatistics.cc | 2 +- src/atlas/mesh/actions/BuildStatistics.h | 2 +- src/atlas/mesh/actions/BuildTorusXYZField.cc | 2 +- src/atlas/mesh/actions/BuildTorusXYZField.h | 2 +- src/atlas/mesh/actions/BuildXYZField.cc | 2 +- src/atlas/mesh/actions/BuildXYZField.h | 2 +- src/atlas/mesh/actions/ExtendNodesGlobal.cc | 2 +- src/atlas/mesh/actions/ExtendNodesGlobal.h | 2 +- .../mesh/actions/WriteLoadBalanceReport.cc | 2 +- .../mesh/actions/WriteLoadBalanceReport.h | 2 +- src/atlas/mesh/detail/AccumulateFacets.cc | 2 +- src/atlas/mesh/detail/AccumulateFacets.h | 2 +- src/atlas/mesh/detail/MeshImpl.cc | 2 +- src/atlas/mesh/detail/MeshImpl.h | 2 +- src/atlas/mesh/detail/MeshIntf.cc | 2 +- src/atlas/mesh/detail/MeshIntf.h | 2 +- src/atlas/mesh/detail/PartitionGraph.cc | 2 +- src/atlas/mesh/detail/PartitionGraph.h | 2 +- src/atlas/mesh/detail/PeriodicTransform.h | 2 +- src/atlas/meshgenerator.h | 2 +- .../meshgenerator/DelaunayMeshGenerator.cc | 2 +- .../meshgenerator/DelaunayMeshGenerator.h | 2 +- src/atlas/meshgenerator/MeshGenerator.cc | 2 +- src/atlas/meshgenerator/MeshGenerator.h | 2 +- .../meshgenerator/StructuredMeshGenerator.cc | 2 +- .../meshgenerator/StructuredMeshGenerator.h | 2 +- src/atlas/numerics/Method.cc | 2 +- src/atlas/numerics/Method.h | 2 +- src/atlas/numerics/Nabla.cc | 2 +- src/atlas/numerics/Nabla.h | 12 +++++------ src/atlas/numerics/fvm/Method.cc | 2 +- src/atlas/numerics/fvm/Method.h | 2 +- src/atlas/numerics/fvm/Nabla.cc | 2 +- src/atlas/numerics/fvm/Nabla.h | 2 +- src/atlas/option.h | 2 +- src/atlas/option/Options.cc | 2 +- src/atlas/option/Options.h | 2 +- src/atlas/option/TransOptions.cc | 2 +- src/atlas/option/TransOptions.h | 2 +- src/atlas/output/Gmsh.cc | 2 +- src/atlas/output/Gmsh.h | 2 +- src/atlas/output/Output.cc | 2 +- src/atlas/output/Output.h | 2 +- src/atlas/output/detail/GmshIO.cc | 2 +- src/atlas/output/detail/GmshIO.h | 2 +- src/atlas/output/detail/PointCloudIO.cc | 2 +- src/atlas/output/detail/PointCloudIO.h | 2 +- src/atlas/parallel/Checksum.cc | 2 +- src/atlas/parallel/Checksum.h | 2 +- src/atlas/parallel/GatherScatter.cc | 2 +- src/atlas/parallel/GatherScatter.h | 2 +- src/atlas/parallel/HaloExchange.cc | 2 +- src/atlas/parallel/HaloExchange.h | 2 +- src/atlas/parallel/HaloExchangeCUDA.h | 2 +- src/atlas/parallel/HaloExchangeImpl.h | 2 +- src/atlas/parallel/mpi/Buffer.h | 2 +- src/atlas/parallel/mpi/Statistics.h | 2 +- src/atlas/parallel/mpi/mpi.cc | 2 +- src/atlas/parallel/mpi/mpi.h | 2 +- src/atlas/parallel/omp/omp.cc | 2 +- src/atlas/parallel/omp/omp.h | 2 +- src/atlas/projection.h | 2 +- src/atlas/runtime/AtlasTool.h | 2 +- src/atlas/runtime/Trace.h | 2 +- src/atlas/runtime/trace/Barriers.cc | 2 +- src/atlas/runtime/trace/Barriers.h | 2 +- src/atlas/runtime/trace/Logging.cc | 2 +- src/atlas/runtime/trace/Logging.h | 2 +- src/atlas/runtime/trace/Nesting.cc | 2 +- src/atlas/runtime/trace/Nesting.h | 2 +- src/atlas/runtime/trace/StopWatch.h | 2 +- src/atlas/runtime/trace/Timings.cc | 2 +- src/atlas/runtime/trace/Timings.h | 2 +- src/atlas/runtime/trace/TraceT.h | 2 +- src/atlas/trans/Trans.cc | 2 +- src/atlas/trans/Trans.h | 2 +- src/atlas/trans/ifs/TransIFS.cc | 2 +- src/atlas/trans/ifs/TransIFS.h | 2 +- src/atlas/trans/ifs/TransIFSNodeColumns.cc | 2 +- src/atlas/trans/ifs/TransIFSNodeColumns.h | 2 +- .../trans/ifs/TransIFSStructuredColumns.cc | 2 +- .../trans/ifs/TransIFSStructuredColumns.h | 2 +- src/atlas/trans/local/FourierTransforms.cc | 2 +- src/atlas/trans/local/FourierTransforms.h | 2 +- src/atlas/trans/local/LegendrePolynomials.cc | 2 +- src/atlas/trans/local/LegendrePolynomials.h | 2 +- src/atlas/trans/local/LegendreTransforms.cc | 2 +- src/atlas/trans/local/LegendreTransforms.h | 2 +- src/atlas/trans/local/TransLocal.cc | 2 +- src/atlas/trans/local/TransLocal.h | 2 +- src/atlas/util/Bitflags.h | 2 +- src/atlas/util/Config.cc | 2 +- src/atlas/util/Config.h | 2 +- src/atlas/util/Constants.h | 2 +- src/atlas/util/CoordinateEnums.h | 2 +- src/atlas/util/Earth.cc | 2 +- src/atlas/util/Earth.h | 2 +- src/atlas/util/GaussianLatitudes.cc | 2 +- src/atlas/util/GaussianLatitudes.h | 2 +- src/atlas/util/LonLatMicroDeg.h | 2 +- src/atlas/util/LonLatPolygon.cc | 2 +- src/atlas/util/LonLatPolygon.h | 2 +- src/atlas/util/Metadata.cc | 2 +- src/atlas/util/Metadata.h | 2 +- src/atlas/util/MicroDeg.h | 2 +- src/atlas/util/Polygon.cc | 2 +- src/atlas/util/Polygon.h | 2 +- src/atlas/util/Rotation.cc | 2 +- src/atlas/util/Rotation.h | 2 +- src/atlas/util/SphericalPolygon.cc | 2 +- src/atlas/util/SphericalPolygon.h | 2 +- src/atlas/util/Unique.h | 2 +- src/atlas_acc_support/CMakeLists.txt | 7 +++++++ src/atlas_f/CMakeLists.txt | 7 +++++++ src/sandbox/CMakeLists.txt | 2 +- .../benchmark_build_halo/CMakeLists.txt | 2 +- .../atlas-benchmark-build-halo.cc | 2 +- src/sandbox/benchmark_sorting/CMakeLists.txt | 2 +- .../atlas-benchmark-sorting.cc | 2 +- src/sandbox/fortran_acc_fields/CMakeLists.txt | 2 +- src/sandbox/grid_distribution/CMakeLists.txt | 2 +- .../atlas-grid-distribution.cc | 2 +- .../interpolation-fortran/CMakeLists.txt | 2 +- src/sandbox/interpolation/CMakeLists.txt | 2 +- src/sandbox/interpolation/PartitionedMesh.cc | 2 +- src/sandbox/interpolation/PartitionedMesh.h | 2 +- .../atlas-parallel-interpolation.cc | 2 +- src/tests/AtlasTestEnvironment.h | 2 +- src/tests/CMakeLists.txt | 2 +- src/tests/TestMeshes.h | 2 +- src/tests/array/CMakeLists.txt | 2 +- src/tests/array/test_array.cc | 2 +- src/tests/array/test_array_slicer.cc | 2 +- src/tests/array/test_array_view_util.cc | 2 +- src/tests/array/test_svector.cc | 2 +- src/tests/array/test_table.cc | 2 +- src/tests/field/CMakeLists.txt | 2 +- src/tests/field/fctest_field.F90 | 2 +- src/tests/field/fctest_field_gpu.F90 | 2 +- src/tests/functionspace/CMakeLists.txt | 2 +- .../functionspace/fctest_functionspace.F90 | 2 +- src/tests/functionspace/test_functionspace.cc | 2 +- src/tests/functionspace/test_pointcloud.cc | 2 +- .../functionspace/test_structuredcolumns.cc | 2 +- src/tests/grid/CMakeLists.txt | 7 +++++++ src/tests/grid/fctest_griddistribution.F90 | 2 +- src/tests/grid/fctest_state.F90 | 2 +- src/tests/grid/test_domain.cc | 2 +- src/tests/grid/test_field.cc | 2 +- src/tests/grid/test_grid_ptr.cc | 2 +- src/tests/grid/test_grids.cc | 2 +- src/tests/grid/test_rotation.cc | 2 +- src/tests/grid/test_state.cc | 2 +- src/tests/interpolation/CMakeLists.txt | 2 +- src/tests/interpolation/test_Quad3D.cc | 2 +- .../test_interpolation_finite_element.cc | 2 +- src/tests/io/CMakeLists.txt | 2 +- src/tests/io/fctest_gmsh.F90 | 2 +- src/tests/io/test_gmsh.cc | 2 +- src/tests/io/test_pointcloud_io.cc | 2 +- src/tests/mesh/CMakeLists.txt | 2 +- src/tests/mesh/fctest_connectivity.F90 | 2 +- src/tests/mesh/fctest_elements.F90 | 2 +- src/tests/mesh/fctest_mesh.F90 | 2 +- src/tests/mesh/fctest_meshgen.F90 | 2 +- src/tests/mesh/test_accumulate_facets.cc | 2 +- .../mesh/test_cgal_mesh_gen_from_points.cc | 2 +- src/tests/mesh/test_connectivity.cc | 2 +- src/tests/mesh/test_distmesh.cc | 2 +- src/tests/mesh/test_elements.cc | 2 +- src/tests/mesh/test_halo.cc | 2 +- src/tests/mesh/test_ll.cc | 2 +- src/tests/mesh/test_meshgen3d.cc | 2 +- src/tests/mesh/test_parfields.cc | 2 +- src/tests/mesh/test_rgg.cc | 2 +- src/tests/mesh/test_shapefunctions.cc | 2 +- src/tests/numerics/CMakeLists.txt | 2 +- src/tests/numerics/fctest_fvm_nabla.F90 | 2 +- src/tests/numerics/test_fvm_nabla.cc | 2 +- src/tests/parallel/CMakeLists.txt | 2 +- src/tests/parallel/test_gather.cc | 2 +- src/tests/parallel/test_haloexchange.cc | 2 +- src/tests/parallel/test_sync.F90 | 2 +- src/tests/trans/CMakeLists.txt | 2 +- src/tests/trans/fctest_trans.F90 | 2 +- .../trans/fctest_trans_invtrans_grad.F90 | 2 +- src/tests/trans/test_trans.cc | 2 +- src/tests/trans/test_trans_invtrans_grad.cc | 2 +- src/tests/trans/test_transgeneral.cc | 2 +- src/tests/util/CMakeLists.txt | 2 +- src/tests/util/fctest_error.F90 | 2 +- src/tests/util/fctest_logging.F90 | 2 +- src/tests/util/fctest_metadata.F90 | 2 +- src/tests/util/fctest_parametrisation.F90 | 2 +- src/tests/util/test_earth.cc | 2 +- src/tests/util/test_flags.cc | 2 +- src/tests/util/test_footprint.cc | 2 +- src/tests/util/test_indexview.cc | 2 +- src/tests/util/test_metadata.cc | 2 +- src/tests/util/test_polygon.cc | 2 +- src/tests/util/test_vector.cc | 2 +- 399 files changed, 506 insertions(+), 405 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 754f750e4..da341837f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/VERSION.cmake b/VERSION.cmake index 1b1e3cf37..d42b1cd16 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/cmake/FindLatex.cmake b/cmake/FindLatex.cmake index 3ba487cd4..fae30966b 100644 --- a/cmake/FindLatex.cmake +++ b/cmake/FindLatex.cmake @@ -1,4 +1,4 @@ -# © Copyright 1996-2017 ECMWF. +# (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. @@ -9,20 +9,20 @@ ############################################################################### # find latex libraries -FIND_PROGRAM (PDFLATEX - NAMES pdflatex +FIND_PROGRAM (PDFLATEX + NAMES pdflatex PATHS /usr/local/share/apps/TeXLive/2014/bin/x86_64-linux/) -FIND_PROGRAM (BIBTEX - NAMES bibtex +FIND_PROGRAM (BIBTEX + NAMES bibtex PATHS /usr/local/share/apps/TeXLive/2014/bin/x86_64-linux/) -FIND_PROGRAM (MAKEINDEX - NAMES makeindex +FIND_PROGRAM (MAKEINDEX + NAMES makeindex PATHS /usr/local/share/apps/TeXLive/2014/bin/x86_64-linux/) -FIND_PROGRAM (HTLATEX - NAMES htlatex +FIND_PROGRAM (HTLATEX + NAMES htlatex PATHS /usr/local/share/apps/TeXLive/2014/bin/x86_64-linux/) -if ( PDFLATEX AND BIBTEX AND MAKEINDEX AND HTLATEX ) +if ( PDFLATEX AND BIBTEX AND MAKEINDEX AND HTLATEX ) set( LATEX_FOUND TRUE ) endif() diff --git a/cmake/atlas_host_device.cmake b/cmake/atlas_host_device.cmake index 29d99774c..77060a956 100644 --- a/cmake/atlas_host_device.cmake +++ b/cmake/atlas_host_device.cmake @@ -1,3 +1,11 @@ +# (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. + function( create_cuda_wrapper variable ) set( options "" ) set( single_value_args SOURCE ) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 4e1d236b5..4d5c81ca6 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,3 +1,11 @@ +# (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. + add_subdirectory(user-guide) list( APPEND DOC_CODE_TARGETS diff --git a/doc/user-guide/CMakeLists.txt b/doc/user-guide/CMakeLists.txt index 1c7bb1de2..31e8f2b67 100644 --- a/doc/user-guide/CMakeLists.txt +++ b/doc/user-guide/CMakeLists.txt @@ -1,3 +1,11 @@ +# (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. + configure_file( version.tex.in version.tex ) add_subdirectory(getting-started) diff --git a/doc/user-guide/core-functionalities/CMakeLists.txt b/doc/user-guide/core-functionalities/CMakeLists.txt index 783d17a3c..044202515 100644 --- a/doc/user-guide/core-functionalities/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/CMakeLists.txt @@ -1,3 +1,11 @@ +# (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. + add_subdirectory(global-grids) add_subdirectory(meshes) add_subdirectory(fields) diff --git a/doc/user-guide/core-functionalities/fields/CMakeLists.txt b/doc/user-guide/core-functionalities/fields/CMakeLists.txt index 32a362cb2..5b8493a85 100644 --- a/doc/user-guide/core-functionalities/fields/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/fields/CMakeLists.txt @@ -1,3 +1,11 @@ +# (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. + ecbuild_add_executable( TARGET atlas_c-fields SOURCES fields.cc diff --git a/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt b/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt index c210a89a1..b699bc6de 100644 --- a/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/functionspace/CMakeLists.txt @@ -1,3 +1,11 @@ +# (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. + ecbuild_add_executable( TARGET atlas_c-NodeColumns SOURCES NodeColumns.cc diff --git a/doc/user-guide/core-functionalities/global-grids/CMakeLists.txt b/doc/user-guide/core-functionalities/global-grids/CMakeLists.txt index 302441297..0b0ee286d 100644 --- a/doc/user-guide/core-functionalities/global-grids/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/global-grids/CMakeLists.txt @@ -1,2 +1,10 @@ +# (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. + add_subdirectory(Structured) add_subdirectory(Unstructured) diff --git a/doc/user-guide/core-functionalities/meshes/CMakeLists.txt b/doc/user-guide/core-functionalities/meshes/CMakeLists.txt index 2208b2f35..2889511ac 100644 --- a/doc/user-guide/core-functionalities/meshes/CMakeLists.txt +++ b/doc/user-guide/core-functionalities/meshes/CMakeLists.txt @@ -1,3 +1,11 @@ +# (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. + ecbuild_add_executable( TARGET atlas_c-meshes-Structured SOURCES meshes-Structured.cc diff --git a/doc/user-guide/getting-started/CMakeLists.txt b/doc/user-guide/getting-started/CMakeLists.txt index 02c79101d..25651fa7c 100644 --- a/doc/user-guide/getting-started/CMakeLists.txt +++ b/doc/user-guide/getting-started/CMakeLists.txt @@ -1 +1,9 @@ +# (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. + add_subdirectory(installation) diff --git a/project_summary.cmake b/project_summary.cmake index 142b40434..5ee36ba27 100644 --- a/project_summary.cmake +++ b/project_summary.cmake @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. @@ -35,10 +35,10 @@ if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) ecbuild_info( "GRIDTOOLS_STORAGE" ) if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST ) ecbuild_info( " BACKEND : [HOST]" ) - endif() + endif() if( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA ) ecbuild_info( " BACKEND : [CUDA]" ) - endif() + endif() endif() @@ -58,4 +58,4 @@ if( ATLAS_HAVE_ACC ) ecbuild_info( " ACC_C_FLAGS : [${ACC_C_FLAGS}]" ) ecbuild_info( " ACC_Fortran_FLAGS : [${ACC_Fortran_FLAGS}]" ) -endif() \ No newline at end of file +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2e8373e43..d95b713da 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/apps/CMakeLists.txt b/src/apps/CMakeLists.txt index f238e195a..cfd4968fb 100644 --- a/src/apps/CMakeLists.txt +++ b/src/apps/CMakeLists.txt @@ -1,6 +1,14 @@ +# (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. + ecbuild_add_executable( TARGET atlas-main - OUTPUT_NAME atlas + OUTPUT_NAME atlas SOURCES atlas.cc LIBS atlas ) @@ -32,7 +40,7 @@ ecbuild_add_executable( ecbuild_add_executable( TARGET atlas-benchmark SOURCES atlas-benchmark.cc - LIBS atlas + LIBS atlas ) ecbuild_add_executable( diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index a52916317..49dac03e7 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/apps/atlas-gaussian-latitudes.cc b/src/apps/atlas-gaussian-latitudes.cc index c69965b65..1fcaebe3b 100644 --- a/src/apps/atlas-gaussian-latitudes.cc +++ b/src/apps/atlas-gaussian-latitudes.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/apps/atlas-gmsh-extract.cc b/src/apps/atlas-gmsh-extract.cc index 44b9e3d7f..425f2766c 100644 --- a/src/apps/atlas-gmsh-extract.cc +++ b/src/apps/atlas-gmsh-extract.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 29eb4254f..155c861f3 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/apps/atlas-loadbalance.cc b/src/apps/atlas-loadbalance.cc index 31287edc8..6a942f052 100644 --- a/src/apps/atlas-loadbalance.cc +++ b/src/apps/atlas-loadbalance.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/apps/atlas-meshgen.cc b/src/apps/atlas-meshgen.cc index 219192088..2c155aac6 100644 --- a/src/apps/atlas-meshgen.cc +++ b/src/apps/atlas-meshgen.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/apps/atlas-numerics-nabla.F90 b/src/apps/atlas-numerics-nabla.F90 index 10ec63ac7..ed96d0223 100644 --- a/src/apps/atlas-numerics-nabla.F90 +++ b/src/apps/atlas-numerics-nabla.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/apps/atlas.cc b/src/apps/atlas.cc index 41d09efc1..ba28ee409 100644 --- a/src/apps/atlas.cc +++ b/src/apps/atlas.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2012 ECMWF. + * (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. diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 4fdd6f6b0..6a1552bef 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/atlas/array.h b/src/atlas/array.h index ad428372e..1daa3b2ad 100644 --- a/src/atlas/array.h +++ b/src/atlas/array.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index e7883ae9e..e6b5235b9 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/ArrayIdx.h b/src/atlas/array/ArrayIdx.h index e3d018f70..e97ba05c7 100644 --- a/src/atlas/array/ArrayIdx.h +++ b/src/atlas/array/ArrayIdx.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/ArrayLayout.h b/src/atlas/array/ArrayLayout.h index 69662a11d..5e9dbfb9f 100644 --- a/src/atlas/array/ArrayLayout.h +++ b/src/atlas/array/ArrayLayout.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/ArrayShape.h b/src/atlas/array/ArrayShape.h index f81d7dd64..1876dc62c 100644 --- a/src/atlas/array/ArrayShape.h +++ b/src/atlas/array/ArrayShape.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/ArraySpec.cc b/src/atlas/array/ArraySpec.cc index 2af2489b6..7f88c5065 100644 --- a/src/atlas/array/ArraySpec.cc +++ b/src/atlas/array/ArraySpec.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/ArraySpec.h b/src/atlas/array/ArraySpec.h index fb6a8f81a..db6274cf7 100644 --- a/src/atlas/array/ArraySpec.h +++ b/src/atlas/array/ArraySpec.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/ArrayStrides.h b/src/atlas/array/ArrayStrides.h index f4dee3f5b..91ce60754 100644 --- a/src/atlas/array/ArrayStrides.h +++ b/src/atlas/array/ArrayStrides.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/ArrayUtil.cc b/src/atlas/array/ArrayUtil.cc index 769c33024..ce7487034 100644 --- a/src/atlas/array/ArrayUtil.cc +++ b/src/atlas/array/ArrayUtil.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/ArrayUtil.h b/src/atlas/array/ArrayUtil.h index bf8f32b43..49ff013ee 100644 --- a/src/atlas/array/ArrayUtil.h +++ b/src/atlas/array/ArrayUtil.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/ArrayView.h b/src/atlas/array/ArrayView.h index eb12f2393..41843fc8a 100644 --- a/src/atlas/array/ArrayView.h +++ b/src/atlas/array/ArrayView.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/ArrayViewDefs.h b/src/atlas/array/ArrayViewDefs.h index f8c16d69a..67f9865ca 100644 --- a/src/atlas/array/ArrayViewDefs.h +++ b/src/atlas/array/ArrayViewDefs.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/ArrayViewUtil.h b/src/atlas/array/ArrayViewUtil.h index 6724464ad..28a6dd1dc 100644 --- a/src/atlas/array/ArrayViewUtil.h +++ b/src/atlas/array/ArrayViewUtil.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/DataType.h b/src/atlas/array/DataType.h index c420e2bb8..d1d579150 100644 --- a/src/atlas/array/DataType.h +++ b/src/atlas/array/DataType.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/IndexView.h b/src/atlas/array/IndexView.h index 3473b19d5..88ab45258 100644 --- a/src/atlas/array/IndexView.h +++ b/src/atlas/array/IndexView.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/LocalView.cc b/src/atlas/array/LocalView.cc index f751624d5..885daf17e 100644 --- a/src/atlas/array/LocalView.cc +++ b/src/atlas/array/LocalView.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/LocalView.h b/src/atlas/array/LocalView.h index 49577dc69..b66c2e78c 100644 --- a/src/atlas/array/LocalView.h +++ b/src/atlas/array/LocalView.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/Range.h b/src/atlas/array/Range.h index 734235fb1..46f5d05a0 100644 --- a/src/atlas/array/Range.h +++ b/src/atlas/array/Range.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/SVector.h b/src/atlas/array/SVector.h index 01ac313a1..a6113ced8 100644 --- a/src/atlas/array/SVector.h +++ b/src/atlas/array/SVector.h @@ -1,5 +1,5 @@ /* -* (C) Copyright 1996-2016 ECMWF. +* (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. diff --git a/src/atlas/array/Table.cc b/src/atlas/array/Table.cc index 6dec8f1dd..ee4cf8525 100644 --- a/src/atlas/array/Table.cc +++ b/src/atlas/array/Table.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/Table.h b/src/atlas/array/Table.h index f633e5643..ee46a420d 100644 --- a/src/atlas/array/Table.h +++ b/src/atlas/array/Table.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/TableView.cc b/src/atlas/array/TableView.cc index 21bf93d18..e5e22f0d8 100644 --- a/src/atlas/array/TableView.cc +++ b/src/atlas/array/TableView.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/TableView.h b/src/atlas/array/TableView.h index 6d4381463..f125b1dfd 100644 --- a/src/atlas/array/TableView.h +++ b/src/atlas/array/TableView.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/array/Vector.h b/src/atlas/array/Vector.h index 75addc6e1..df42f5190 100644 --- a/src/atlas/array/Vector.h +++ b/src/atlas/array/Vector.h @@ -1,5 +1,5 @@ /* -* (C) Copyright 1996-2016 ECMWF. +* (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. diff --git a/src/atlas/array/gridtools/GPUClonable.h b/src/atlas/array/gridtools/GPUClonable.h index 0acc265ac..e2fba61c6 100644 --- a/src/atlas/array/gridtools/GPUClonable.h +++ b/src/atlas/array/gridtools/GPUClonable.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index c31ca542e..6488321e6 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index de04c8141..62d592075 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index 276f92c90..3669ecf55 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 11959644f..90a466ac7 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/gridtools/GridToolsDataStore.h b/src/atlas/array/gridtools/GridToolsDataStore.h index 61924dcda..1f9408627 100644 --- a/src/atlas/array/gridtools/GridToolsDataStore.h +++ b/src/atlas/array/gridtools/GridToolsDataStore.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/gridtools/GridToolsIndexView.cc b/src/atlas/array/gridtools/GridToolsIndexView.cc index a1478f0cf..92825f1e7 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.cc +++ b/src/atlas/array/gridtools/GridToolsIndexView.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/gridtools/GridToolsIndexView.h b/src/atlas/array/gridtools/GridToolsIndexView.h index 93dfaf713..a57cf876f 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.h +++ b/src/atlas/array/gridtools/GridToolsIndexView.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/gridtools/GridToolsMakeView.h b/src/atlas/array/gridtools/GridToolsMakeView.h index 0cb1c5da6..2537497af 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.h +++ b/src/atlas/array/gridtools/GridToolsMakeView.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/helpers/ArrayAssigner.h b/src/atlas/array/helpers/ArrayAssigner.h index 5441cf891..cc0aae196 100644 --- a/src/atlas/array/helpers/ArrayAssigner.h +++ b/src/atlas/array/helpers/ArrayAssigner.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/helpers/ArrayInitializer.h b/src/atlas/array/helpers/ArrayInitializer.h index 4f200fae9..f3133edf6 100644 --- a/src/atlas/array/helpers/ArrayInitializer.h +++ b/src/atlas/array/helpers/ArrayInitializer.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/helpers/ArraySlicer.h b/src/atlas/array/helpers/ArraySlicer.h index 861fb927a..537389016 100644 --- a/src/atlas/array/helpers/ArraySlicer.h +++ b/src/atlas/array/helpers/ArraySlicer.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/helpers/ArrayWriter.h b/src/atlas/array/helpers/ArrayWriter.h index 8e1601b20..fc2d9736c 100644 --- a/src/atlas/array/helpers/ArrayWriter.h +++ b/src/atlas/array/helpers/ArrayWriter.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/native/NativeArrayView.cc b/src/atlas/array/native/NativeArrayView.cc index 0c72e9229..3df23c548 100644 --- a/src/atlas/array/native/NativeArrayView.cc +++ b/src/atlas/array/native/NativeArrayView.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index c01622879..0b821247d 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/native/NativeDataStore.h b/src/atlas/array/native/NativeDataStore.h index 57c0bc3a1..b430dadd6 100644 --- a/src/atlas/array/native/NativeDataStore.h +++ b/src/atlas/array/native/NativeDataStore.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/native/NativeIndexView.cc b/src/atlas/array/native/NativeIndexView.cc index 8a295ecb2..3a0b090e4 100644 --- a/src/atlas/array/native/NativeIndexView.cc +++ b/src/atlas/array/native/NativeIndexView.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array/native/NativeIndexView.h b/src/atlas/array/native/NativeIndexView.h index 8bf3a00e7..bf97cf3a6 100644 --- a/src/atlas/array/native/NativeIndexView.h +++ b/src/atlas/array/native/NativeIndexView.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/array_fwd.h b/src/atlas/array_fwd.h index c1b4e65c6..afb5827f3 100644 --- a/src/atlas/array_fwd.h +++ b/src/atlas/array_fwd.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/domain.h b/src/atlas/domain.h index 963b14f15..580b0c0d1 100644 --- a/src/atlas/domain.h +++ b/src/atlas/domain.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/domain/Domain.cc b/src/atlas/domain/Domain.cc index f9906e5cc..63d42ceb7 100644 --- a/src/atlas/domain/Domain.cc +++ b/src/atlas/domain/Domain.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/domain/Domain.h b/src/atlas/domain/Domain.h index 632244fa0..4e9edb3e5 100644 --- a/src/atlas/domain/Domain.h +++ b/src/atlas/domain/Domain.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field.h b/src/atlas/field.h index c1ef5b762..bce9ecf23 100644 --- a/src/atlas/field.h +++ b/src/atlas/field.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/field/Field.cc b/src/atlas/field/Field.cc index 0ebc7eda6..c0fab1cc5 100644 --- a/src/atlas/field/Field.cc +++ b/src/atlas/field/Field.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/Field.h b/src/atlas/field/Field.h index 07e0ba305..e5294bbab 100644 --- a/src/atlas/field/Field.h +++ b/src/atlas/field/Field.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/FieldCreator.cc b/src/atlas/field/FieldCreator.cc index 40a508d11..a0ed11bcb 100644 --- a/src/atlas/field/FieldCreator.cc +++ b/src/atlas/field/FieldCreator.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/FieldCreator.h b/src/atlas/field/FieldCreator.h index d9222e543..dcda32dce 100644 --- a/src/atlas/field/FieldCreator.h +++ b/src/atlas/field/FieldCreator.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/FieldCreatorArraySpec.cc b/src/atlas/field/FieldCreatorArraySpec.cc index ac920959f..9d4f9caae 100644 --- a/src/atlas/field/FieldCreatorArraySpec.cc +++ b/src/atlas/field/FieldCreatorArraySpec.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/FieldCreatorArraySpec.h b/src/atlas/field/FieldCreatorArraySpec.h index 4511e51ea..9a963a326 100644 --- a/src/atlas/field/FieldCreatorArraySpec.h +++ b/src/atlas/field/FieldCreatorArraySpec.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/FieldCreatorIFS.cc b/src/atlas/field/FieldCreatorIFS.cc index 87e2dc7fe..1e6b2d711 100644 --- a/src/atlas/field/FieldCreatorIFS.cc +++ b/src/atlas/field/FieldCreatorIFS.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/FieldCreatorIFS.h b/src/atlas/field/FieldCreatorIFS.h index 2462fea4b..ae86dee14 100644 --- a/src/atlas/field/FieldCreatorIFS.h +++ b/src/atlas/field/FieldCreatorIFS.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/FieldSet.cc b/src/atlas/field/FieldSet.cc index d4a51301c..9f53f3975 100644 --- a/src/atlas/field/FieldSet.cc +++ b/src/atlas/field/FieldSet.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/FieldSet.h b/src/atlas/field/FieldSet.h index ac1028abc..395a8f7f8 100644 --- a/src/atlas/field/FieldSet.h +++ b/src/atlas/field/FieldSet.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/State.cc b/src/atlas/field/State.cc index 5a5c149cd..0911b4560 100644 --- a/src/atlas/field/State.cc +++ b/src/atlas/field/State.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/State.h b/src/atlas/field/State.h index 1e0b66749..9de6c95d1 100644 --- a/src/atlas/field/State.h +++ b/src/atlas/field/State.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index 92c72b914..825d4b62e 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/field/detail/FieldImpl.h b/src/atlas/field/detail/FieldImpl.h index 9097f9eb1..9a57144ff 100644 --- a/src/atlas/field/detail/FieldImpl.h +++ b/src/atlas/field/detail/FieldImpl.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace.h b/src/atlas/functionspace.h index 135ec8006..99a07ac9a 100644 --- a/src/atlas/functionspace.h +++ b/src/atlas/functionspace.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 74336700e..042173726 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/EdgeColumns.h b/src/atlas/functionspace/EdgeColumns.h index 8cd4a7d80..6a59c4ad5 100644 --- a/src/atlas/functionspace/EdgeColumns.h +++ b/src/atlas/functionspace/EdgeColumns.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/FunctionSpace.cc b/src/atlas/functionspace/FunctionSpace.cc index ddaf079c5..ac241bbe8 100644 --- a/src/atlas/functionspace/FunctionSpace.cc +++ b/src/atlas/functionspace/FunctionSpace.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/FunctionSpace.h b/src/atlas/functionspace/FunctionSpace.h index 8f893c8dd..43a9eee64 100644 --- a/src/atlas/functionspace/FunctionSpace.h +++ b/src/atlas/functionspace/FunctionSpace.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 039b1c9a0..95c2311c1 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/NodeColumns.h b/src/atlas/functionspace/NodeColumns.h index 60018febc..dac8581a3 100644 --- a/src/atlas/functionspace/NodeColumns.h +++ b/src/atlas/functionspace/NodeColumns.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/NodeColumnsInterface.cc b/src/atlas/functionspace/NodeColumnsInterface.cc index b4063f9ef..b8cc0742f 100644 --- a/src/atlas/functionspace/NodeColumnsInterface.cc +++ b/src/atlas/functionspace/NodeColumnsInterface.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/NodeColumnsInterface.h b/src/atlas/functionspace/NodeColumnsInterface.h index e3205f50c..0715a4a55 100644 --- a/src/atlas/functionspace/NodeColumnsInterface.h +++ b/src/atlas/functionspace/NodeColumnsInterface.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/PointCloud.cc b/src/atlas/functionspace/PointCloud.cc index f4fe450a1..2e34badc3 100644 --- a/src/atlas/functionspace/PointCloud.cc +++ b/src/atlas/functionspace/PointCloud.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/PointCloud.h b/src/atlas/functionspace/PointCloud.h index e7a75941f..993061133 100644 --- a/src/atlas/functionspace/PointCloud.h +++ b/src/atlas/functionspace/PointCloud.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index ec1932676..9456f81f5 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/Spectral.h b/src/atlas/functionspace/Spectral.h index 7015813d8..baaec4265 100644 --- a/src/atlas/functionspace/Spectral.h +++ b/src/atlas/functionspace/Spectral.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 845aba7c1..dfe6f5c17 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/functionspace/StructuredColumns.h b/src/atlas/functionspace/StructuredColumns.h index 09226bb52..9cda8f4b4 100644 --- a/src/atlas/functionspace/StructuredColumns.h +++ b/src/atlas/functionspace/StructuredColumns.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid.h b/src/atlas/grid.h index 9a3bc6976..35ff84067 100644 --- a/src/atlas/grid.h +++ b/src/atlas/grid.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/Distribution.cc b/src/atlas/grid/Distribution.cc index 774d5dd4a..8a6a6b1b1 100644 --- a/src/atlas/grid/Distribution.cc +++ b/src/atlas/grid/Distribution.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/Distribution.h b/src/atlas/grid/Distribution.h index 37487f321..37a4ce4d5 100644 --- a/src/atlas/grid/Distribution.h +++ b/src/atlas/grid/Distribution.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/Grid.cc b/src/atlas/grid/Grid.cc index a160724f4..99bf61f9a 100644 --- a/src/atlas/grid/Grid.cc +++ b/src/atlas/grid/Grid.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/Grid.h b/src/atlas/grid/Grid.h index 9b1aa0808..a7cb27042 100644 --- a/src/atlas/grid/Grid.h +++ b/src/atlas/grid/Grid.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/Iterator.h b/src/atlas/grid/Iterator.h index 04a0d25ed..1f6b4d6cb 100644 --- a/src/atlas/grid/Iterator.h +++ b/src/atlas/grid/Iterator.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/Partitioner.cc b/src/atlas/grid/Partitioner.cc index b8efad014..c999e911e 100644 --- a/src/atlas/grid/Partitioner.cc +++ b/src/atlas/grid/Partitioner.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/Partitioner.h b/src/atlas/grid/Partitioner.h index 239d7203c..0b2171246 100644 --- a/src/atlas/grid/Partitioner.h +++ b/src/atlas/grid/Partitioner.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/grid/Grid.cc b/src/atlas/grid/detail/grid/Grid.cc index d05db3675..c3c312e4f 100644 --- a/src/atlas/grid/detail/grid/Grid.cc +++ b/src/atlas/grid/detail/grid/Grid.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/grid/Grid.h b/src/atlas/grid/detail/grid/Grid.h index f2933ffc6..defc4c3eb 100644 --- a/src/atlas/grid/detail/grid/Grid.h +++ b/src/atlas/grid/detail/grid/Grid.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/grid/GridBuilder.cc b/src/atlas/grid/detail/grid/GridBuilder.cc index 4730af652..1a49b89cf 100644 --- a/src/atlas/grid/detail/grid/GridBuilder.cc +++ b/src/atlas/grid/detail/grid/GridBuilder.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/grid/GridBuilder.h b/src/atlas/grid/detail/grid/GridBuilder.h index ef1da2cd3..8b309a2ed 100644 --- a/src/atlas/grid/detail/grid/GridBuilder.h +++ b/src/atlas/grid/detail/grid/GridBuilder.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index 6dba38c31..b35d560f7 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index 6fa59b6b9..a56ad2fe2 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index 59f19abca..b9c7e7073 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index ee5fc06c7..6182c0b16 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index 920417565..9545e214e 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h index 006d15c7c..e7040c301 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h index b3db800ae..4239c9c5b 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc index 2ea0e07d2..4db2aa981 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h index e0f0a3ad9..15a3aedd7 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc index 97aa2a52b..605fc417d 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h index e54cefb3f..8d668282d 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc index f656481e6..395ed552b 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h index 49f4452f3..a997ea0cd 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/Partitioner.cc b/src/atlas/grid/detail/partitioner/Partitioner.cc index e5a4071c2..389de5a48 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.cc +++ b/src/atlas/grid/detail/partitioner/Partitioner.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/Partitioner.h b/src/atlas/grid/detail/partitioner/Partitioner.h index 62476ac96..9837d07a2 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.h +++ b/src/atlas/grid/detail/partitioner/Partitioner.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index 3009e4bc6..1960dd9c4 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.h b/src/atlas/grid/detail/partitioner/TransPartitioner.h index 667b1dec1..f91c65c89 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.h +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N.cc b/src/atlas/grid/detail/pl/classic_gaussian/N.cc index 2927e1b70..05525c01c 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N.h b/src/atlas/grid/detail/pl/classic_gaussian/N.h index 019ab2943..0cfbd4996 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N.h +++ b/src/atlas/grid/detail/pl/classic_gaussian/N.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc index e62c82e65..02726e550 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h index b085086a0..62df53c69 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h +++ b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc index 5d796bb32..1205b3f43 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.h b/src/atlas/grid/detail/spacing/gaussian/Latitudes.h index 35d87af78..59119391e 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.h +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/spacing/gaussian/N.cc b/src/atlas/grid/detail/spacing/gaussian/N.cc index 0be658ead..362de91d4 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/grid/detail/spacing/gaussian/N.h b/src/atlas/grid/detail/spacing/gaussian/N.h index 7a7c7dc49..8070fcdd4 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N.h +++ b/src/atlas/grid/detail/spacing/gaussian/N.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation.h b/src/atlas/interpolation.h index 609aba004..10c11c929 100644 --- a/src/atlas/interpolation.h +++ b/src/atlas/interpolation.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/Interpolation.cc b/src/atlas/interpolation/Interpolation.cc index 39cc9f5d9..ac1d3ebb0 100644 --- a/src/atlas/interpolation/Interpolation.cc +++ b/src/atlas/interpolation/Interpolation.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/Interpolation.h b/src/atlas/interpolation/Interpolation.h index 79d7b3ccc..c60dea734 100644 --- a/src/atlas/interpolation/Interpolation.h +++ b/src/atlas/interpolation/Interpolation.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/Vector2D.h b/src/atlas/interpolation/Vector2D.h index 181d70bdf..dddca2e1e 100644 --- a/src/atlas/interpolation/Vector2D.h +++ b/src/atlas/interpolation/Vector2D.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/Vector3D.h b/src/atlas/interpolation/Vector3D.h index c98294c52..c4b412d16 100644 --- a/src/atlas/interpolation/Vector3D.h +++ b/src/atlas/interpolation/Vector3D.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/element/Quad3D.cc b/src/atlas/interpolation/element/Quad3D.cc index 6ff7bce98..5c7e9e862 100644 --- a/src/atlas/interpolation/element/Quad3D.cc +++ b/src/atlas/interpolation/element/Quad3D.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/element/Quad3D.h b/src/atlas/interpolation/element/Quad3D.h index 18f269358..095c8d25e 100644 --- a/src/atlas/interpolation/element/Quad3D.h +++ b/src/atlas/interpolation/element/Quad3D.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/element/Triag3D.cc b/src/atlas/interpolation/element/Triag3D.cc index 3b5397e4b..7d4ed6e04 100644 --- a/src/atlas/interpolation/element/Triag3D.cc +++ b/src/atlas/interpolation/element/Triag3D.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/element/Triag3D.h b/src/atlas/interpolation/element/Triag3D.h index 64e89ef79..beee30dd0 100644 --- a/src/atlas/interpolation/element/Triag3D.h +++ b/src/atlas/interpolation/element/Triag3D.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/FiniteElement.cc b/src/atlas/interpolation/method/FiniteElement.cc index 68f949119..46f7c38f0 100644 --- a/src/atlas/interpolation/method/FiniteElement.cc +++ b/src/atlas/interpolation/method/FiniteElement.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/FiniteElement.h b/src/atlas/interpolation/method/FiniteElement.h index 02b9fc414..00fa3f77e 100644 --- a/src/atlas/interpolation/method/FiniteElement.h +++ b/src/atlas/interpolation/method/FiniteElement.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/Intersect.cc b/src/atlas/interpolation/method/Intersect.cc index 4b7326113..71b2b6e88 100644 --- a/src/atlas/interpolation/method/Intersect.cc +++ b/src/atlas/interpolation/method/Intersect.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/Intersect.h b/src/atlas/interpolation/method/Intersect.h index df742aa18..5af1293f6 100644 --- a/src/atlas/interpolation/method/Intersect.h +++ b/src/atlas/interpolation/method/Intersect.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/KNearestNeighbours.cc b/src/atlas/interpolation/method/KNearestNeighbours.cc index 694dab2e6..8624d903b 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.cc +++ b/src/atlas/interpolation/method/KNearestNeighbours.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/KNearestNeighbours.h b/src/atlas/interpolation/method/KNearestNeighbours.h index fb514c856..06311f31c 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.h +++ b/src/atlas/interpolation/method/KNearestNeighbours.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.cc b/src/atlas/interpolation/method/KNearestNeighboursBase.cc index f5b906db0..25e8d4f72 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.cc +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.h b/src/atlas/interpolation/method/KNearestNeighboursBase.h index c99e2f5dc..336eeb0c5 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.h +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index 099b97475..cb65434cf 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/Method.h b/src/atlas/interpolation/method/Method.h index 31f086ed4..77ba62a52 100644 --- a/src/atlas/interpolation/method/Method.h +++ b/src/atlas/interpolation/method/Method.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/NearestNeighbour.cc b/src/atlas/interpolation/method/NearestNeighbour.cc index 5c5c78350..06fc676d6 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.cc +++ b/src/atlas/interpolation/method/NearestNeighbour.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/NearestNeighbour.h b/src/atlas/interpolation/method/NearestNeighbour.h index b50e23ea0..9bcfb8bc4 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.h +++ b/src/atlas/interpolation/method/NearestNeighbour.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/PointIndex3.cc b/src/atlas/interpolation/method/PointIndex3.cc index 8eda68ac4..f9c9146fc 100644 --- a/src/atlas/interpolation/method/PointIndex3.cc +++ b/src/atlas/interpolation/method/PointIndex3.cc @@ -1,6 +1,6 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/PointIndex3.h b/src/atlas/interpolation/method/PointIndex3.h index e79175fc9..3d8698121 100644 --- a/src/atlas/interpolation/method/PointIndex3.h +++ b/src/atlas/interpolation/method/PointIndex3.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/PointSet.cc b/src/atlas/interpolation/method/PointSet.cc index c0ec1032b..d9f0936a1 100644 --- a/src/atlas/interpolation/method/PointSet.cc +++ b/src/atlas/interpolation/method/PointSet.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/PointSet.h b/src/atlas/interpolation/method/PointSet.h index 3122caa9a..cbf468e3d 100644 --- a/src/atlas/interpolation/method/PointSet.h +++ b/src/atlas/interpolation/method/PointSet.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/Ray.cc b/src/atlas/interpolation/method/Ray.cc index 2bf697d92..e1be87dd1 100644 --- a/src/atlas/interpolation/method/Ray.cc +++ b/src/atlas/interpolation/method/Ray.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/interpolation/method/Ray.h b/src/atlas/interpolation/method/Ray.h index 7b8ce1a9d..4e0771986 100644 --- a/src/atlas/interpolation/method/Ray.h +++ b/src/atlas/interpolation/method/Ray.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 65b316b68..2d277a8ab 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/library/Library.h b/src/atlas/library/Library.h index fd048bc46..f6944643a 100644 --- a/src/atlas/library/Library.h +++ b/src/atlas/library/Library.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh.h b/src/atlas/mesh.h index 162112f6f..2c38711b2 100644 --- a/src/atlas/mesh.h +++ b/src/atlas/mesh.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index ffd45b098..da2ebd837 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 14f86d71d..133a7afda 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/ElementType.cc b/src/atlas/mesh/ElementType.cc index b1412c22f..8d86f8ea2 100644 --- a/src/atlas/mesh/ElementType.cc +++ b/src/atlas/mesh/ElementType.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/ElementType.h b/src/atlas/mesh/ElementType.h index d1dda7240..aaa19d082 100644 --- a/src/atlas/mesh/ElementType.h +++ b/src/atlas/mesh/ElementType.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/Elements.cc b/src/atlas/mesh/Elements.cc index bc5f47329..4b2f847f4 100644 --- a/src/atlas/mesh/Elements.cc +++ b/src/atlas/mesh/Elements.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/Elements.h b/src/atlas/mesh/Elements.h index 8b0d48301..ae4d1a645 100644 --- a/src/atlas/mesh/Elements.h +++ b/src/atlas/mesh/Elements.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/Halo.cc b/src/atlas/mesh/Halo.cc index 2c5c7fc79..047cdfb84 100644 --- a/src/atlas/mesh/Halo.cc +++ b/src/atlas/mesh/Halo.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/Halo.h b/src/atlas/mesh/Halo.h index 7718993d3..f406f0482 100644 --- a/src/atlas/mesh/Halo.h +++ b/src/atlas/mesh/Halo.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/HybridElements.cc b/src/atlas/mesh/HybridElements.cc index 5a29d191e..376964c9b 100644 --- a/src/atlas/mesh/HybridElements.cc +++ b/src/atlas/mesh/HybridElements.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/HybridElements.h b/src/atlas/mesh/HybridElements.h index c7d2b5072..75c1d8f24 100644 --- a/src/atlas/mesh/HybridElements.h +++ b/src/atlas/mesh/HybridElements.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/IsGhostNode.h b/src/atlas/mesh/IsGhostNode.h index 6b0dab991..34482eae3 100644 --- a/src/atlas/mesh/IsGhostNode.h +++ b/src/atlas/mesh/IsGhostNode.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/Mesh.cc b/src/atlas/mesh/Mesh.cc index 4ba40cbe9..4f4d33ab5 100644 --- a/src/atlas/mesh/Mesh.cc +++ b/src/atlas/mesh/Mesh.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/Mesh.h b/src/atlas/mesh/Mesh.h index ccdd71087..99dd18ad6 100644 --- a/src/atlas/mesh/Mesh.h +++ b/src/atlas/mesh/Mesh.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/Nodes.cc b/src/atlas/mesh/Nodes.cc index 7cb8a18e8..d48bfb743 100644 --- a/src/atlas/mesh/Nodes.cc +++ b/src/atlas/mesh/Nodes.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/Nodes.h b/src/atlas/mesh/Nodes.h index f5bf042b1..26ecb6655 100644 --- a/src/atlas/mesh/Nodes.h +++ b/src/atlas/mesh/Nodes.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/PartitionPolygon.cc b/src/atlas/mesh/PartitionPolygon.cc index 469ddcf3e..b96e14f46 100644 --- a/src/atlas/mesh/PartitionPolygon.cc +++ b/src/atlas/mesh/PartitionPolygon.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/PartitionPolygon.h b/src/atlas/mesh/PartitionPolygon.h index 1fc38bc55..52bd485e5 100644 --- a/src/atlas/mesh/PartitionPolygon.h +++ b/src/atlas/mesh/PartitionPolygon.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildCellCentres.cc b/src/atlas/mesh/actions/BuildCellCentres.cc index dca9d3b87..2f6509db0 100644 --- a/src/atlas/mesh/actions/BuildCellCentres.cc +++ b/src/atlas/mesh/actions/BuildCellCentres.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildCellCentres.h b/src/atlas/mesh/actions/BuildCellCentres.h index 26afc62fd..5f5546202 100644 --- a/src/atlas/mesh/actions/BuildCellCentres.h +++ b/src/atlas/mesh/actions/BuildCellCentres.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.cc b/src/atlas/mesh/actions/BuildConvexHull3D.cc index 7fb76c237..490d81a80 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.cc +++ b/src/atlas/mesh/actions/BuildConvexHull3D.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.h b/src/atlas/mesh/actions/BuildConvexHull3D.h index 4c98d8cbd..39fcda85a 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.h +++ b/src/atlas/mesh/actions/BuildConvexHull3D.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index 4f0dba49e..f9b82634c 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildDualMesh.h b/src/atlas/mesh/actions/BuildDualMesh.h index a1556b937..7d5c37c80 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.h +++ b/src/atlas/mesh/actions/BuildDualMesh.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildEdges.cc b/src/atlas/mesh/actions/BuildEdges.cc index 8d862c810..8ef752807 100644 --- a/src/atlas/mesh/actions/BuildEdges.cc +++ b/src/atlas/mesh/actions/BuildEdges.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildEdges.h b/src/atlas/mesh/actions/BuildEdges.h index f78755e62..862e09220 100644 --- a/src/atlas/mesh/actions/BuildEdges.h +++ b/src/atlas/mesh/actions/BuildEdges.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index fbd84f04b..2972dc003 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildHalo.h b/src/atlas/mesh/actions/BuildHalo.h index 20183dcbe..2949e2171 100644 --- a/src/atlas/mesh/actions/BuildHalo.h +++ b/src/atlas/mesh/actions/BuildHalo.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 7968da35e..0c519b486 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildParallelFields.h b/src/atlas/mesh/actions/BuildParallelFields.h index e9230cb34..a4866c99d 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.h +++ b/src/atlas/mesh/actions/BuildParallelFields.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc b/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc index 126ce4518..8b1c4abe5 100644 --- a/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc +++ b/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildPeriodicBoundaries.h b/src/atlas/mesh/actions/BuildPeriodicBoundaries.h index 8a60c49b0..f31ff1a80 100644 --- a/src/atlas/mesh/actions/BuildPeriodicBoundaries.h +++ b/src/atlas/mesh/actions/BuildPeriodicBoundaries.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildStatistics.cc b/src/atlas/mesh/actions/BuildStatistics.cc index 585e46996..7eb21719c 100644 --- a/src/atlas/mesh/actions/BuildStatistics.cc +++ b/src/atlas/mesh/actions/BuildStatistics.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildStatistics.h b/src/atlas/mesh/actions/BuildStatistics.h index e8785141b..5d3724f47 100644 --- a/src/atlas/mesh/actions/BuildStatistics.h +++ b/src/atlas/mesh/actions/BuildStatistics.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildTorusXYZField.cc b/src/atlas/mesh/actions/BuildTorusXYZField.cc index a0e9d6575..ce718b404 100644 --- a/src/atlas/mesh/actions/BuildTorusXYZField.cc +++ b/src/atlas/mesh/actions/BuildTorusXYZField.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildTorusXYZField.h b/src/atlas/mesh/actions/BuildTorusXYZField.h index baae0c79f..8d128a026 100644 --- a/src/atlas/mesh/actions/BuildTorusXYZField.h +++ b/src/atlas/mesh/actions/BuildTorusXYZField.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildXYZField.cc b/src/atlas/mesh/actions/BuildXYZField.cc index aa5c5efb6..689856f35 100644 --- a/src/atlas/mesh/actions/BuildXYZField.cc +++ b/src/atlas/mesh/actions/BuildXYZField.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/BuildXYZField.h b/src/atlas/mesh/actions/BuildXYZField.h index 6c6fe2f2f..341bd65ec 100644 --- a/src/atlas/mesh/actions/BuildXYZField.h +++ b/src/atlas/mesh/actions/BuildXYZField.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.cc b/src/atlas/mesh/actions/ExtendNodesGlobal.cc index 264998a4d..a5cc6056d 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.cc +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.h b/src/atlas/mesh/actions/ExtendNodesGlobal.h index d5ea19b0e..ea37b878b 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.h +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc index 1ba9a6d53..89d0e3236 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.h b/src/atlas/mesh/actions/WriteLoadBalanceReport.h index 36dfc3e72..c522d84b0 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.h +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/detail/AccumulateFacets.cc b/src/atlas/mesh/detail/AccumulateFacets.cc index 4df5770e6..834b0299d 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.cc +++ b/src/atlas/mesh/detail/AccumulateFacets.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/detail/AccumulateFacets.h b/src/atlas/mesh/detail/AccumulateFacets.h index ccc48b257..131964f74 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.h +++ b/src/atlas/mesh/detail/AccumulateFacets.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/detail/MeshImpl.cc b/src/atlas/mesh/detail/MeshImpl.cc index 001978dfa..deae8f925 100644 --- a/src/atlas/mesh/detail/MeshImpl.cc +++ b/src/atlas/mesh/detail/MeshImpl.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/detail/MeshImpl.h b/src/atlas/mesh/detail/MeshImpl.h index 063412520..f8b0fd153 100644 --- a/src/atlas/mesh/detail/MeshImpl.h +++ b/src/atlas/mesh/detail/MeshImpl.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/detail/MeshIntf.cc b/src/atlas/mesh/detail/MeshIntf.cc index 03bfa3cef..902571826 100644 --- a/src/atlas/mesh/detail/MeshIntf.cc +++ b/src/atlas/mesh/detail/MeshIntf.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/detail/MeshIntf.h b/src/atlas/mesh/detail/MeshIntf.h index 48cbeedd7..c3a026e04 100644 --- a/src/atlas/mesh/detail/MeshIntf.h +++ b/src/atlas/mesh/detail/MeshIntf.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/detail/PartitionGraph.cc b/src/atlas/mesh/detail/PartitionGraph.cc index ae0cd877a..d23f0ef61 100644 --- a/src/atlas/mesh/detail/PartitionGraph.cc +++ b/src/atlas/mesh/detail/PartitionGraph.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/detail/PartitionGraph.h b/src/atlas/mesh/detail/PartitionGraph.h index f537eccd6..a7232446f 100644 --- a/src/atlas/mesh/detail/PartitionGraph.h +++ b/src/atlas/mesh/detail/PartitionGraph.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/mesh/detail/PeriodicTransform.h b/src/atlas/mesh/detail/PeriodicTransform.h index 60ef4bb87..4df7ed283 100644 --- a/src/atlas/mesh/detail/PeriodicTransform.h +++ b/src/atlas/mesh/detail/PeriodicTransform.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/meshgenerator.h b/src/atlas/meshgenerator.h index 42ebb49bf..d0eb44c73 100644 --- a/src/atlas/meshgenerator.h +++ b/src/atlas/meshgenerator.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/meshgenerator/DelaunayMeshGenerator.cc b/src/atlas/meshgenerator/DelaunayMeshGenerator.cc index 9599ed54c..09e02dbf7 100644 --- a/src/atlas/meshgenerator/DelaunayMeshGenerator.cc +++ b/src/atlas/meshgenerator/DelaunayMeshGenerator.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/meshgenerator/DelaunayMeshGenerator.h b/src/atlas/meshgenerator/DelaunayMeshGenerator.h index a46d49000..7b75aaaa8 100644 --- a/src/atlas/meshgenerator/DelaunayMeshGenerator.h +++ b/src/atlas/meshgenerator/DelaunayMeshGenerator.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/meshgenerator/MeshGenerator.cc b/src/atlas/meshgenerator/MeshGenerator.cc index c0986f534..11b98de4c 100644 --- a/src/atlas/meshgenerator/MeshGenerator.cc +++ b/src/atlas/meshgenerator/MeshGenerator.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/meshgenerator/MeshGenerator.h b/src/atlas/meshgenerator/MeshGenerator.h index 0c06df696..a7d3ba6e3 100644 --- a/src/atlas/meshgenerator/MeshGenerator.h +++ b/src/atlas/meshgenerator/MeshGenerator.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index c44ce333a..238bf1931 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.h b/src/atlas/meshgenerator/StructuredMeshGenerator.h index ecd943a51..fa3d63639 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.h +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/numerics/Method.cc b/src/atlas/numerics/Method.cc index 5089273d3..b14ae9c0d 100644 --- a/src/atlas/numerics/Method.cc +++ b/src/atlas/numerics/Method.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/numerics/Method.h b/src/atlas/numerics/Method.h index 10ab45bef..646e74641 100644 --- a/src/atlas/numerics/Method.h +++ b/src/atlas/numerics/Method.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/numerics/Nabla.cc b/src/atlas/numerics/Nabla.cc index 813dde023..f957cf730 100644 --- a/src/atlas/numerics/Nabla.cc +++ b/src/atlas/numerics/Nabla.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/numerics/Nabla.h b/src/atlas/numerics/Nabla.h index 15def7e8c..88eff110f 100644 --- a/src/atlas/numerics/Nabla.h +++ b/src/atlas/numerics/Nabla.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2015 ECMWF. + * (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. @@ -39,13 +39,13 @@ class NablaImpl : public eckit::Owned { class Nabla { public: - + using nabla_t = NablaImpl; - + private: - + eckit::SharedPtr nabla_; - + public: Nabla(); @@ -58,7 +58,7 @@ class Nabla { void divergence(const Field &vector, Field &div) const; void curl(const Field &vector, Field &curl) const; void laplacian(const Field &scalar, Field &laplacian) const; - + const nabla_t* get() const { return nabla_.get(); } }; diff --git a/src/atlas/numerics/fvm/Method.cc b/src/atlas/numerics/fvm/Method.cc index 669c7cd1a..3b7e945ff 100644 --- a/src/atlas/numerics/fvm/Method.cc +++ b/src/atlas/numerics/fvm/Method.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/numerics/fvm/Method.h b/src/atlas/numerics/fvm/Method.h index 71dda48fa..fb139d5fa 100644 --- a/src/atlas/numerics/fvm/Method.h +++ b/src/atlas/numerics/fvm/Method.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/numerics/fvm/Nabla.cc b/src/atlas/numerics/fvm/Nabla.cc index e708a804c..7bc7c36a0 100644 --- a/src/atlas/numerics/fvm/Nabla.cc +++ b/src/atlas/numerics/fvm/Nabla.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/numerics/fvm/Nabla.h b/src/atlas/numerics/fvm/Nabla.h index bb0281550..8388a48ce 100644 --- a/src/atlas/numerics/fvm/Nabla.h +++ b/src/atlas/numerics/fvm/Nabla.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/option.h b/src/atlas/option.h index 9c72bbbd8..3c94f25e6 100644 --- a/src/atlas/option.h +++ b/src/atlas/option.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/option/Options.cc b/src/atlas/option/Options.cc index 6f109ad19..abf6070ad 100644 --- a/src/atlas/option/Options.cc +++ b/src/atlas/option/Options.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/option/Options.h b/src/atlas/option/Options.h index ddb210b6d..6728b455f 100644 --- a/src/atlas/option/Options.h +++ b/src/atlas/option/Options.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/option/TransOptions.cc b/src/atlas/option/TransOptions.cc index 4bba28675..e69d5daf5 100644 --- a/src/atlas/option/TransOptions.cc +++ b/src/atlas/option/TransOptions.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/option/TransOptions.h b/src/atlas/option/TransOptions.h index a87789d28..bc54dd206 100644 --- a/src/atlas/option/TransOptions.h +++ b/src/atlas/option/TransOptions.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/output/Gmsh.cc b/src/atlas/output/Gmsh.cc index 75b4f2b4f..406273a76 100644 --- a/src/atlas/output/Gmsh.cc +++ b/src/atlas/output/Gmsh.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/output/Gmsh.h b/src/atlas/output/Gmsh.h index 256480fb0..0d325b54d 100644 --- a/src/atlas/output/Gmsh.h +++ b/src/atlas/output/Gmsh.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/output/Output.cc b/src/atlas/output/Output.cc index 0c1d37dbf..2f465a55f 100644 --- a/src/atlas/output/Output.cc +++ b/src/atlas/output/Output.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/output/Output.h b/src/atlas/output/Output.h index f06f4b9e8..9bc4779ed 100644 --- a/src/atlas/output/Output.h +++ b/src/atlas/output/Output.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index d1ba5222c..b2dc6d9cb 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/output/detail/GmshIO.h b/src/atlas/output/detail/GmshIO.h index 139f00ecf..859b25649 100644 --- a/src/atlas/output/detail/GmshIO.h +++ b/src/atlas/output/detail/GmshIO.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/output/detail/PointCloudIO.cc b/src/atlas/output/detail/PointCloudIO.cc index a18db22de..99c9ec93d 100644 --- a/src/atlas/output/detail/PointCloudIO.cc +++ b/src/atlas/output/detail/PointCloudIO.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/output/detail/PointCloudIO.h b/src/atlas/output/detail/PointCloudIO.h index 49164e645..88a72bed1 100644 --- a/src/atlas/output/detail/PointCloudIO.h +++ b/src/atlas/output/detail/PointCloudIO.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/Checksum.cc b/src/atlas/parallel/Checksum.cc index 44061b99e..901edd763 100644 --- a/src/atlas/parallel/Checksum.cc +++ b/src/atlas/parallel/Checksum.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/Checksum.h b/src/atlas/parallel/Checksum.h index 1f692adef..07042c171 100644 --- a/src/atlas/parallel/Checksum.h +++ b/src/atlas/parallel/Checksum.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index 9f7cad986..d924bdf51 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index 34bb5931a..f28dcd0c4 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 7e36efc90..ddd7c2e3b 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index ca9267c5c..42044d797 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index 4cc81f1cc..d5d6c4877 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -1,7 +1,7 @@ #pragma once /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/HaloExchangeImpl.h b/src/atlas/parallel/HaloExchangeImpl.h index b71757e41..b84508f63 100644 --- a/src/atlas/parallel/HaloExchangeImpl.h +++ b/src/atlas/parallel/HaloExchangeImpl.h @@ -1,7 +1,7 @@ #pragma once /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/mpi/Buffer.h b/src/atlas/parallel/mpi/Buffer.h index 0fe4148a5..b7e22bdb5 100644 --- a/src/atlas/parallel/mpi/Buffer.h +++ b/src/atlas/parallel/mpi/Buffer.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index b328e38c7..5724bf189 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/mpi/mpi.cc b/src/atlas/parallel/mpi/mpi.cc index 26485f7cf..8285c28bf 100644 --- a/src/atlas/parallel/mpi/mpi.cc +++ b/src/atlas/parallel/mpi/mpi.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/mpi/mpi.h b/src/atlas/parallel/mpi/mpi.h index daf65b8aa..8525507bc 100644 --- a/src/atlas/parallel/mpi/mpi.h +++ b/src/atlas/parallel/mpi/mpi.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/omp/omp.cc b/src/atlas/parallel/omp/omp.cc index d5429741e..154261ddd 100644 --- a/src/atlas/parallel/omp/omp.cc +++ b/src/atlas/parallel/omp/omp.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/parallel/omp/omp.h b/src/atlas/parallel/omp/omp.h index 0297a6210..6bbd10eaf 100644 --- a/src/atlas/parallel/omp/omp.h +++ b/src/atlas/parallel/omp/omp.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/projection.h b/src/atlas/projection.h index 711228620..a68b5a891 100644 --- a/src/atlas/projection.h +++ b/src/atlas/projection.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/atlas/runtime/AtlasTool.h b/src/atlas/runtime/AtlasTool.h index c0f406e37..e073749d8 100644 --- a/src/atlas/runtime/AtlasTool.h +++ b/src/atlas/runtime/AtlasTool.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/Trace.h b/src/atlas/runtime/Trace.h index 447de8aa9..3907be741 100644 --- a/src/atlas/runtime/Trace.h +++ b/src/atlas/runtime/Trace.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/Barriers.cc b/src/atlas/runtime/trace/Barriers.cc index 5977bc44a..58d56829b 100644 --- a/src/atlas/runtime/trace/Barriers.cc +++ b/src/atlas/runtime/trace/Barriers.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/Barriers.h b/src/atlas/runtime/trace/Barriers.h index 009383885..2936ad24c 100644 --- a/src/atlas/runtime/trace/Barriers.h +++ b/src/atlas/runtime/trace/Barriers.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/Logging.cc b/src/atlas/runtime/trace/Logging.cc index 0944a727a..ddb05c9e9 100644 --- a/src/atlas/runtime/trace/Logging.cc +++ b/src/atlas/runtime/trace/Logging.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/Logging.h b/src/atlas/runtime/trace/Logging.h index 1d99fdd3c..fd1a3ab2a 100644 --- a/src/atlas/runtime/trace/Logging.h +++ b/src/atlas/runtime/trace/Logging.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/Nesting.cc b/src/atlas/runtime/trace/Nesting.cc index a0e121b23..8fb2943f0 100644 --- a/src/atlas/runtime/trace/Nesting.cc +++ b/src/atlas/runtime/trace/Nesting.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/Nesting.h b/src/atlas/runtime/trace/Nesting.h index e00d72b13..cb12cdcb2 100644 --- a/src/atlas/runtime/trace/Nesting.h +++ b/src/atlas/runtime/trace/Nesting.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/StopWatch.h b/src/atlas/runtime/trace/StopWatch.h index 2522f973e..923055d4d 100644 --- a/src/atlas/runtime/trace/StopWatch.h +++ b/src/atlas/runtime/trace/StopWatch.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/Timings.cc b/src/atlas/runtime/trace/Timings.cc index d9330c166..51519e47b 100644 --- a/src/atlas/runtime/trace/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/Timings.h b/src/atlas/runtime/trace/Timings.h index 651010ecf..6d70fcbd4 100644 --- a/src/atlas/runtime/trace/Timings.h +++ b/src/atlas/runtime/trace/Timings.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/runtime/trace/TraceT.h b/src/atlas/runtime/trace/TraceT.h index d96c511c6..439a0befe 100644 --- a/src/atlas/runtime/trace/TraceT.h +++ b/src/atlas/runtime/trace/TraceT.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index f29582bf2..f7e6e0d04 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/Trans.h b/src/atlas/trans/Trans.h index 80ca0ea1a..cb8aaddd5 100644 --- a/src/atlas/trans/Trans.h +++ b/src/atlas/trans/Trans.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index abb04bc39..49fa0f2c2 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/ifs/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h index 4c721c013..fb7f7efc2 100644 --- a/src/atlas/trans/ifs/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/ifs/TransIFSNodeColumns.cc b/src/atlas/trans/ifs/TransIFSNodeColumns.cc index df76e6a29..a7721ac37 100644 --- a/src/atlas/trans/ifs/TransIFSNodeColumns.cc +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/ifs/TransIFSNodeColumns.h b/src/atlas/trans/ifs/TransIFSNodeColumns.h index 098c269e0..bfff78fce 100644 --- a/src/atlas/trans/ifs/TransIFSNodeColumns.h +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc index 10ca8b546..7f11697be 100644 --- a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/ifs/TransIFSStructuredColumns.h b/src/atlas/trans/ifs/TransIFSStructuredColumns.h index 045c16096..5824ee2d8 100644 --- a/src/atlas/trans/ifs/TransIFSStructuredColumns.h +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc index 53280d0e5..7f7e0aaa3 100644 --- a/src/atlas/trans/local/FourierTransforms.cc +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/local/FourierTransforms.h b/src/atlas/trans/local/FourierTransforms.h index d4c503f3b..5d49adc0a 100644 --- a/src/atlas/trans/local/FourierTransforms.h +++ b/src/atlas/trans/local/FourierTransforms.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index 299422e6e..1693582f4 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/local/LegendrePolynomials.h b/src/atlas/trans/local/LegendrePolynomials.h index f746435a1..200a7320b 100644 --- a/src/atlas/trans/local/LegendrePolynomials.h +++ b/src/atlas/trans/local/LegendrePolynomials.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/local/LegendreTransforms.cc b/src/atlas/trans/local/LegendreTransforms.cc index 67a491751..b594a5ed6 100644 --- a/src/atlas/trans/local/LegendreTransforms.cc +++ b/src/atlas/trans/local/LegendreTransforms.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/local/LegendreTransforms.h b/src/atlas/trans/local/LegendreTransforms.h index 892084b5c..a5716b50b 100644 --- a/src/atlas/trans/local/LegendreTransforms.h +++ b/src/atlas/trans/local/LegendreTransforms.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 571284ef4..32052a83b 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/trans/local/TransLocal.h b/src/atlas/trans/local/TransLocal.h index cf971dcbd..95e86cdc2 100644 --- a/src/atlas/trans/local/TransLocal.h +++ b/src/atlas/trans/local/TransLocal.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/Bitflags.h b/src/atlas/util/Bitflags.h index 864e20af2..1068b7742 100644 --- a/src/atlas/util/Bitflags.h +++ b/src/atlas/util/Bitflags.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/Config.cc b/src/atlas/util/Config.cc index 83a5d8f6e..fa415fad5 100644 --- a/src/atlas/util/Config.cc +++ b/src/atlas/util/Config.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/Config.h b/src/atlas/util/Config.h index 64006580d..c391583e0 100644 --- a/src/atlas/util/Config.h +++ b/src/atlas/util/Config.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/Constants.h b/src/atlas/util/Constants.h index 107ced6e6..890c48087 100644 --- a/src/atlas/util/Constants.h +++ b/src/atlas/util/Constants.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/CoordinateEnums.h b/src/atlas/util/CoordinateEnums.h index 2bbe50856..f710ac130 100644 --- a/src/atlas/util/CoordinateEnums.h +++ b/src/atlas/util/CoordinateEnums.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index 9161e5e64..bcbd18925 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/Earth.h b/src/atlas/util/Earth.h index 54bf4909e..647fc866b 100644 --- a/src/atlas/util/Earth.h +++ b/src/atlas/util/Earth.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/GaussianLatitudes.cc b/src/atlas/util/GaussianLatitudes.cc index c9ba49a97..e61db6d16 100644 --- a/src/atlas/util/GaussianLatitudes.cc +++ b/src/atlas/util/GaussianLatitudes.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/GaussianLatitudes.h b/src/atlas/util/GaussianLatitudes.h index 68b429714..65da7e804 100644 --- a/src/atlas/util/GaussianLatitudes.h +++ b/src/atlas/util/GaussianLatitudes.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/LonLatMicroDeg.h b/src/atlas/util/LonLatMicroDeg.h index aa84302d1..a55fdc33a 100644 --- a/src/atlas/util/LonLatMicroDeg.h +++ b/src/atlas/util/LonLatMicroDeg.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/LonLatPolygon.cc b/src/atlas/util/LonLatPolygon.cc index d8f5c88d9..36ba22f94 100644 --- a/src/atlas/util/LonLatPolygon.cc +++ b/src/atlas/util/LonLatPolygon.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2018 ECMWF. + * (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. diff --git a/src/atlas/util/LonLatPolygon.h b/src/atlas/util/LonLatPolygon.h index c0455f962..0e82cf63e 100644 --- a/src/atlas/util/LonLatPolygon.h +++ b/src/atlas/util/LonLatPolygon.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2018 ECMWF. + * (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. diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index 3443f7ef2..3f3cbf354 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/Metadata.h b/src/atlas/util/Metadata.h index 61003fb8b..e4962758d 100644 --- a/src/atlas/util/Metadata.h +++ b/src/atlas/util/Metadata.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/MicroDeg.h b/src/atlas/util/MicroDeg.h index 481e7e523..bc07f324e 100644 --- a/src/atlas/util/MicroDeg.h +++ b/src/atlas/util/MicroDeg.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/Polygon.cc b/src/atlas/util/Polygon.cc index 3997853ed..d4650c989 100644 --- a/src/atlas/util/Polygon.cc +++ b/src/atlas/util/Polygon.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2018 ECMWF. + * (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. diff --git a/src/atlas/util/Polygon.h b/src/atlas/util/Polygon.h index 4498909e9..c60266900 100644 --- a/src/atlas/util/Polygon.h +++ b/src/atlas/util/Polygon.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2018 ECMWF. + * (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. diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index abd94fc04..9974e031c 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/Rotation.h b/src/atlas/util/Rotation.h index 9c4a8d2ac..82d3bbc4c 100644 --- a/src/atlas/util/Rotation.h +++ b/src/atlas/util/Rotation.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas/util/SphericalPolygon.cc b/src/atlas/util/SphericalPolygon.cc index a90d50689..276616b76 100644 --- a/src/atlas/util/SphericalPolygon.cc +++ b/src/atlas/util/SphericalPolygon.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2018 ECMWF. + * (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. diff --git a/src/atlas/util/SphericalPolygon.h b/src/atlas/util/SphericalPolygon.h index fee3c9e91..ca730d96d 100644 --- a/src/atlas/util/SphericalPolygon.h +++ b/src/atlas/util/SphericalPolygon.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2018 ECMWF. + * (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. diff --git a/src/atlas/util/Unique.h b/src/atlas/util/Unique.h index 94b504425..bb0749ac4 100644 --- a/src/atlas/util/Unique.h +++ b/src/atlas/util/Unique.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/atlas_acc_support/CMakeLists.txt b/src/atlas_acc_support/CMakeLists.txt index 678f23fa7..beb10aac4 100644 --- a/src/atlas_acc_support/CMakeLists.txt +++ b/src/atlas_acc_support/CMakeLists.txt @@ -1,3 +1,10 @@ +# (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. if( ATLAS_HAVE_ACC ) diff --git a/src/atlas_f/CMakeLists.txt b/src/atlas_f/CMakeLists.txt index adb1b1f43..e07d5a8fe 100644 --- a/src/atlas_f/CMakeLists.txt +++ b/src/atlas_f/CMakeLists.txt @@ -1,3 +1,10 @@ +# (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. configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/atlas_f.h.in ${CMAKE_CURRENT_BINARY_DIR}/../atlas/atlas_f.h ) diff --git a/src/sandbox/CMakeLists.txt b/src/sandbox/CMakeLists.txt index 88761b2f2..f4714d0e4 100644 --- a/src/sandbox/CMakeLists.txt +++ b/src/sandbox/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/sandbox/benchmark_build_halo/CMakeLists.txt b/src/sandbox/benchmark_build_halo/CMakeLists.txt index 2ba1441b9..1e0be371b 100644 --- a/src/sandbox/benchmark_build_halo/CMakeLists.txt +++ b/src/sandbox/benchmark_build_halo/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc index 12cb45cba..1a0d4932d 100644 --- a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/sandbox/benchmark_sorting/CMakeLists.txt b/src/sandbox/benchmark_sorting/CMakeLists.txt index 8754839c3..e4188fb5d 100644 --- a/src/sandbox/benchmark_sorting/CMakeLists.txt +++ b/src/sandbox/benchmark_sorting/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index c6df07997..10ff97144 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/sandbox/fortran_acc_fields/CMakeLists.txt b/src/sandbox/fortran_acc_fields/CMakeLists.txt index 83e2f1888..ee9f0eb7f 100644 --- a/src/sandbox/fortran_acc_fields/CMakeLists.txt +++ b/src/sandbox/fortran_acc_fields/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/sandbox/grid_distribution/CMakeLists.txt b/src/sandbox/grid_distribution/CMakeLists.txt index 22cbb760d..5e4309b29 100644 --- a/src/sandbox/grid_distribution/CMakeLists.txt +++ b/src/sandbox/grid_distribution/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/sandbox/grid_distribution/atlas-grid-distribution.cc b/src/sandbox/grid_distribution/atlas-grid-distribution.cc index eded3ccdd..242c76c10 100644 --- a/src/sandbox/grid_distribution/atlas-grid-distribution.cc +++ b/src/sandbox/grid_distribution/atlas-grid-distribution.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/sandbox/interpolation-fortran/CMakeLists.txt b/src/sandbox/interpolation-fortran/CMakeLists.txt index 9ec3a4dfd..195f8eada 100644 --- a/src/sandbox/interpolation-fortran/CMakeLists.txt +++ b/src/sandbox/interpolation-fortran/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/sandbox/interpolation/CMakeLists.txt b/src/sandbox/interpolation/CMakeLists.txt index b7adf9bad..2d382df8f 100644 --- a/src/sandbox/interpolation/CMakeLists.txt +++ b/src/sandbox/interpolation/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/sandbox/interpolation/PartitionedMesh.cc b/src/sandbox/interpolation/PartitionedMesh.cc index 9f79b7e8f..d80a4e6cf 100644 --- a/src/sandbox/interpolation/PartitionedMesh.cc +++ b/src/sandbox/interpolation/PartitionedMesh.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/sandbox/interpolation/PartitionedMesh.h b/src/sandbox/interpolation/PartitionedMesh.h index 71dc87c9c..c9f7d747c 100644 --- a/src/sandbox/interpolation/PartitionedMesh.h +++ b/src/sandbox/interpolation/PartitionedMesh.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/sandbox/interpolation/atlas-parallel-interpolation.cc b/src/sandbox/interpolation/atlas-parallel-interpolation.cc index a41445e14..c0dad4954 100644 --- a/src/sandbox/interpolation/atlas-parallel-interpolation.cc +++ b/src/sandbox/interpolation/atlas-parallel-interpolation.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 006896e9a..2e39c0f43 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 63fc52bfb..57528d02b 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/TestMeshes.h b/src/tests/TestMeshes.h index 00991249d..405470e46 100644 --- a/src/tests/TestMeshes.h +++ b/src/tests/TestMeshes.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/array/CMakeLists.txt b/src/tests/array/CMakeLists.txt index 547e3af19..c9ed65871 100644 --- a/src/tests/array/CMakeLists.txt +++ b/src/tests/array/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 441bfe9e2..c809a2ed5 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index b1e2b5343..916973ff1 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/tests/array/test_array_view_util.cc b/src/tests/array/test_array_view_util.cc index 23254dd4a..9e1fa0144 100644 --- a/src/tests/array/test_array_view_util.cc +++ b/src/tests/array/test_array_view_util.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/tests/array/test_svector.cc b/src/tests/array/test_svector.cc index e5de54113..b649b4a0d 100644 --- a/src/tests/array/test_svector.cc +++ b/src/tests/array/test_svector.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/tests/array/test_table.cc b/src/tests/array/test_table.cc index eb48fce5f..c59767ac6 100644 --- a/src/tests/array/test_table.cc +++ b/src/tests/array/test_table.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/tests/field/CMakeLists.txt b/src/tests/field/CMakeLists.txt index 69e88b4d1..21b91f288 100644 --- a/src/tests/field/CMakeLists.txt +++ b/src/tests/field/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2016 ECMWF. +# (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. diff --git a/src/tests/field/fctest_field.F90 b/src/tests/field/fctest_field.F90 index 47de73a67..4a79cfffe 100644 --- a/src/tests/field/fctest_field.F90 +++ b/src/tests/field/fctest_field.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2016 ECMWF. +! (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 diff --git a/src/tests/field/fctest_field_gpu.F90 b/src/tests/field/fctest_field_gpu.F90 index 2ba719cad..52d6c5751 100644 --- a/src/tests/field/fctest_field_gpu.F90 +++ b/src/tests/field/fctest_field_gpu.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2016 ECMWF. +! (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 diff --git a/src/tests/functionspace/CMakeLists.txt b/src/tests/functionspace/CMakeLists.txt index c135aa5a9..7c23ae5dd 100644 --- a/src/tests/functionspace/CMakeLists.txt +++ b/src/tests/functionspace/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/functionspace/fctest_functionspace.F90 b/src/tests/functionspace/fctest_functionspace.F90 index 23b6d55d2..ec1a40854 100644 --- a/src/tests/functionspace/fctest_functionspace.F90 +++ b/src/tests/functionspace/fctest_functionspace.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index de9265f1e..cc13b515e 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/functionspace/test_pointcloud.cc b/src/tests/functionspace/test_pointcloud.cc index 5dccac646..28692e67e 100644 --- a/src/tests/functionspace/test_pointcloud.cc +++ b/src/tests/functionspace/test_pointcloud.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/functionspace/test_structuredcolumns.cc b/src/tests/functionspace/test_structuredcolumns.cc index fc200fb73..07bbe661b 100644 --- a/src/tests/functionspace/test_structuredcolumns.cc +++ b/src/tests/functionspace/test_structuredcolumns.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/grid/CMakeLists.txt b/src/tests/grid/CMakeLists.txt index a88466698..1acbc2063 100644 --- a/src/tests/grid/CMakeLists.txt +++ b/src/tests/grid/CMakeLists.txt @@ -1,3 +1,10 @@ +# (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. if( HAVE_FCTEST ) foreach(test diff --git a/src/tests/grid/fctest_griddistribution.F90 b/src/tests/grid/fctest_griddistribution.F90 index 852f2cdd8..526b8951a 100644 --- a/src/tests/grid/fctest_griddistribution.F90 +++ b/src/tests/grid/fctest_griddistribution.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/grid/fctest_state.F90 b/src/tests/grid/fctest_state.F90 index 0d0d8e9ad..7f3a40b69 100644 --- a/src/tests/grid/fctest_state.F90 +++ b/src/tests/grid/fctest_state.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/grid/test_domain.cc b/src/tests/grid/test_domain.cc index 67d4d70de..9c9dd65c0 100644 --- a/src/tests/grid/test_domain.cc +++ b/src/tests/grid/test_domain.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/tests/grid/test_field.cc b/src/tests/grid/test_field.cc index 68923371f..367e04a7d 100644 --- a/src/tests/grid/test_field.cc +++ b/src/tests/grid/test_field.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/grid/test_grid_ptr.cc b/src/tests/grid/test_grid_ptr.cc index de91d7ce8..949f952aa 100644 --- a/src/tests/grid/test_grid_ptr.cc +++ b/src/tests/grid/test_grid_ptr.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/tests/grid/test_grids.cc b/src/tests/grid/test_grids.cc index 950566280..179828070 100644 --- a/src/tests/grid/test_grids.cc +++ b/src/tests/grid/test_grids.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/grid/test_rotation.cc b/src/tests/grid/test_rotation.cc index 0dbc255e3..8831b0b26 100644 --- a/src/tests/grid/test_rotation.cc +++ b/src/tests/grid/test_rotation.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/tests/grid/test_state.cc b/src/tests/grid/test_state.cc index 0490e403e..06c9359df 100644 --- a/src/tests/grid/test_state.cc +++ b/src/tests/grid/test_state.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/interpolation/CMakeLists.txt b/src/tests/interpolation/CMakeLists.txt index d31d3b784..73cd96d13 100644 --- a/src/tests/interpolation/CMakeLists.txt +++ b/src/tests/interpolation/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/interpolation/test_Quad3D.cc b/src/tests/interpolation/test_Quad3D.cc index d2c3bef42..b575c7d7e 100644 --- a/src/tests/interpolation/test_Quad3D.cc +++ b/src/tests/interpolation/test_Quad3D.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/interpolation/test_interpolation_finite_element.cc b/src/tests/interpolation/test_interpolation_finite_element.cc index 0bb1901c8..0e4e9f8bc 100644 --- a/src/tests/interpolation/test_interpolation_finite_element.cc +++ b/src/tests/interpolation/test_interpolation_finite_element.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/io/CMakeLists.txt b/src/tests/io/CMakeLists.txt index e6f5148fd..05bc36850 100644 --- a/src/tests/io/CMakeLists.txt +++ b/src/tests/io/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/io/fctest_gmsh.F90 b/src/tests/io/fctest_gmsh.F90 index 6b608bc0c..04c0e8078 100644 --- a/src/tests/io/fctest_gmsh.F90 +++ b/src/tests/io/fctest_gmsh.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/io/test_gmsh.cc b/src/tests/io/test_gmsh.cc index ba83fa932..a29f4d38c 100644 --- a/src/tests/io/test_gmsh.cc +++ b/src/tests/io/test_gmsh.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/io/test_pointcloud_io.cc b/src/tests/io/test_pointcloud_io.cc index 565ce8aa3..d330f9dd0 100644 --- a/src/tests/io/test_pointcloud_io.cc +++ b/src/tests/io/test_pointcloud_io.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/CMakeLists.txt b/src/tests/mesh/CMakeLists.txt index fd2e50bc8..1cc52172c 100644 --- a/src/tests/mesh/CMakeLists.txt +++ b/src/tests/mesh/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/mesh/fctest_connectivity.F90 b/src/tests/mesh/fctest_connectivity.F90 index 473d780eb..8c5577814 100644 --- a/src/tests/mesh/fctest_connectivity.F90 +++ b/src/tests/mesh/fctest_connectivity.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/mesh/fctest_elements.F90 b/src/tests/mesh/fctest_elements.F90 index 9ed425e0a..0c50d95ae 100644 --- a/src/tests/mesh/fctest_elements.F90 +++ b/src/tests/mesh/fctest_elements.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/mesh/fctest_mesh.F90 b/src/tests/mesh/fctest_mesh.F90 index 1e9fee7d8..501523e8e 100644 --- a/src/tests/mesh/fctest_mesh.F90 +++ b/src/tests/mesh/fctest_mesh.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/mesh/fctest_meshgen.F90 b/src/tests/mesh/fctest_meshgen.F90 index 70d11adb9..50446c5f2 100644 --- a/src/tests/mesh/fctest_meshgen.F90 +++ b/src/tests/mesh/fctest_meshgen.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/mesh/test_accumulate_facets.cc b/src/tests/mesh/test_accumulate_facets.cc index eb9ddec3d..585ca327a 100644 --- a/src/tests/mesh/test_accumulate_facets.cc +++ b/src/tests/mesh/test_accumulate_facets.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/test_cgal_mesh_gen_from_points.cc b/src/tests/mesh/test_cgal_mesh_gen_from_points.cc index 08d83ad51..ab7e7789f 100644 --- a/src/tests/mesh/test_cgal_mesh_gen_from_points.cc +++ b/src/tests/mesh/test_cgal_mesh_gen_from_points.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/test_connectivity.cc b/src/tests/mesh/test_connectivity.cc index a27345caa..80d3c84b8 100644 --- a/src/tests/mesh/test_connectivity.cc +++ b/src/tests/mesh/test_connectivity.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. diff --git a/src/tests/mesh/test_distmesh.cc b/src/tests/mesh/test_distmesh.cc index b250ee620..c510a21d7 100644 --- a/src/tests/mesh/test_distmesh.cc +++ b/src/tests/mesh/test_distmesh.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/test_elements.cc b/src/tests/mesh/test_elements.cc index 4b9519f62..245a6f220 100644 --- a/src/tests/mesh/test_elements.cc +++ b/src/tests/mesh/test_elements.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index 7271c9046..9b79e1d95 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/test_ll.cc b/src/tests/mesh/test_ll.cc index 59ea569c8..bfb4078e8 100644 --- a/src/tests/mesh/test_ll.cc +++ b/src/tests/mesh/test_ll.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/test_meshgen3d.cc b/src/tests/mesh/test_meshgen3d.cc index adf2d4a7b..063b28587 100644 --- a/src/tests/mesh/test_meshgen3d.cc +++ b/src/tests/mesh/test_meshgen3d.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/test_parfields.cc b/src/tests/mesh/test_parfields.cc index 9f4c19330..a8955593e 100644 --- a/src/tests/mesh/test_parfields.cc +++ b/src/tests/mesh/test_parfields.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/test_rgg.cc b/src/tests/mesh/test_rgg.cc index d97d220d6..260f96bd2 100644 --- a/src/tests/mesh/test_rgg.cc +++ b/src/tests/mesh/test_rgg.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/mesh/test_shapefunctions.cc b/src/tests/mesh/test_shapefunctions.cc index 3243b1428..97481419b 100644 --- a/src/tests/mesh/test_shapefunctions.cc +++ b/src/tests/mesh/test_shapefunctions.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/numerics/CMakeLists.txt b/src/tests/numerics/CMakeLists.txt index b1fbd2911..7f8d3c2f9 100644 --- a/src/tests/numerics/CMakeLists.txt +++ b/src/tests/numerics/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/numerics/fctest_fvm_nabla.F90 b/src/tests/numerics/fctest_fvm_nabla.F90 index 4d38cc029..a2b4d9e06 100644 --- a/src/tests/numerics/fctest_fvm_nabla.F90 +++ b/src/tests/numerics/fctest_fvm_nabla.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2015 ECMWF. +! (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 diff --git a/src/tests/numerics/test_fvm_nabla.cc b/src/tests/numerics/test_fvm_nabla.cc index fb9782523..398df843e 100644 --- a/src/tests/numerics/test_fvm_nabla.cc +++ b/src/tests/numerics/test_fvm_nabla.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/parallel/CMakeLists.txt b/src/tests/parallel/CMakeLists.txt index 854523bde..5841f725b 100644 --- a/src/tests/parallel/CMakeLists.txt +++ b/src/tests/parallel/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/parallel/test_gather.cc b/src/tests/parallel/test_gather.cc index 0008d7c25..9f7d2a65b 100644 --- a/src/tests/parallel/test_gather.cc +++ b/src/tests/parallel/test_gather.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 1018b8d18..8051633d7 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/parallel/test_sync.F90 b/src/tests/parallel/test_sync.F90 index a2b06cd7d..47962480d 100644 --- a/src/tests/parallel/test_sync.F90 +++ b/src/tests/parallel/test_sync.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (C) Copyright 2013 ECMWF. ! =================================================================== ! test_sync program diff --git a/src/tests/trans/CMakeLists.txt b/src/tests/trans/CMakeLists.txt index 2fc12e75f..db1bfb849 100644 --- a/src/tests/trans/CMakeLists.txt +++ b/src/tests/trans/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/trans/fctest_trans.F90 b/src/tests/trans/fctest_trans.F90 index f8d6355d5..77d47049e 100644 --- a/src/tests/trans/fctest_trans.F90 +++ b/src/tests/trans/fctest_trans.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/trans/fctest_trans_invtrans_grad.F90 b/src/tests/trans/fctest_trans_invtrans_grad.F90 index a77affe01..5c99a2080 100644 --- a/src/tests/trans/fctest_trans_invtrans_grad.F90 +++ b/src/tests/trans/fctest_trans_invtrans_grad.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 7a66393d7..e8679c885 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index 1ba0c7757..d4b0cf973 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index f61525974..d9a2254e4 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/util/CMakeLists.txt b/src/tests/util/CMakeLists.txt index 382fbeff2..e90c0ca3f 100644 --- a/src/tests/util/CMakeLists.txt +++ b/src/tests/util/CMakeLists.txt @@ -1,4 +1,4 @@ -# (C) Copyright 1996-2017 ECMWF. +# (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. diff --git a/src/tests/util/fctest_error.F90 b/src/tests/util/fctest_error.F90 index 1273750e7..f8ef0888b 100644 --- a/src/tests/util/fctest_error.F90 +++ b/src/tests/util/fctest_error.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/util/fctest_logging.F90 b/src/tests/util/fctest_logging.F90 index 820a39f52..a69a8c320 100644 --- a/src/tests/util/fctest_logging.F90 +++ b/src/tests/util/fctest_logging.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/util/fctest_metadata.F90 b/src/tests/util/fctest_metadata.F90 index df31ac073..2ade5e262 100644 --- a/src/tests/util/fctest_metadata.F90 +++ b/src/tests/util/fctest_metadata.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/util/fctest_parametrisation.F90 b/src/tests/util/fctest_parametrisation.F90 index d65118ad5..1bcc21bb1 100644 --- a/src/tests/util/fctest_parametrisation.F90 +++ b/src/tests/util/fctest_parametrisation.F90 @@ -1,4 +1,4 @@ -! (C) Copyright 1996-2017 ECMWF. +! (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 diff --git a/src/tests/util/test_earth.cc b/src/tests/util/test_earth.cc index 8697547a7..48099fb7e 100644 --- a/src/tests/util/test_earth.cc +++ b/src/tests/util/test_earth.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/util/test_flags.cc b/src/tests/util/test_flags.cc index ed203aeb7..5b3b7763a 100644 --- a/src/tests/util/test_flags.cc +++ b/src/tests/util/test_flags.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/util/test_footprint.cc b/src/tests/util/test_footprint.cc index 2f12ab02b..b1beb1e57 100644 --- a/src/tests/util/test_footprint.cc +++ b/src/tests/util/test_footprint.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index 9da0c5c4c..34193414d 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/util/test_metadata.cc b/src/tests/util/test_metadata.cc index 9ad26339c..2efa11456 100644 --- a/src/tests/util/test_metadata.cc +++ b/src/tests/util/test_metadata.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. diff --git a/src/tests/util/test_polygon.cc b/src/tests/util/test_polygon.cc index e75aee4be..826aece40 100644 --- a/src/tests/util/test_polygon.cc +++ b/src/tests/util/test_polygon.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2018 ECMWF. + * (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. diff --git a/src/tests/util/test_vector.cc b/src/tests/util/test_vector.cc index aa1fa306d..b8045506f 100644 --- a/src/tests/util/test_vector.cc +++ b/src/tests/util/test_vector.cc @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2016 ECMWF. + * (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. From 74afcfb90878d8908a876cb8cbe01772c11818f8 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 23 Jan 2018 17:53:35 +0000 Subject: [PATCH 262/355] Compatibility with eckit/0.19.1 --- src/tests/AtlasTestEnvironment.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 2e39c0f43..36a1c96e0 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -17,6 +17,7 @@ #include "atlas/runtime/Trace.h" #include "eckit/config/Resource.h" #include "eckit/testing/Test.h" +#include "eckit/eckit_version.h" namespace atlas { namespace test { @@ -25,10 +26,14 @@ namespace test { // Redefine macro's defined in "eckit/testing/Test.h" to include trace information -#ifdef CASE -#undef CASE -#endif +#define _ECKIT_VERSION (ECKIT_MAJOR_VERSION * 10000 \ + + ECKIT_MINOR_VERSION * 100 \ + + ECKIT_PATCH_VERSION) +// Test ECKIT_VERSION < 0.19.1 +#if _ECKIT_VERSION < 1901 + +#undef CASE #define CASE(description) \ void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection); \ static eckit::testing::TestRegister UNIQUE_NAME2(test_registration_, __LINE__)(description, &UNIQUE_NAME2(test_, __LINE__)); \ @@ -39,15 +44,15 @@ void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection) { \ } \ void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection) -#ifdef SECTION #undef SECTION -#endif #define SECTION(name) \ _test_num += 1; \ _test_count = _test_num; \ _test_subsection = name; \ if ((_test_num - 1) == _test) ATLAS_TRACE_SCOPE(name) +#endif + //---------------------------------------------------------------------------------------------------------------------- struct AtlasTestEnvironment { From d320d1b94c0be7d3c21e79979d360c5c3df25fbe Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 23 Jan 2018 18:09:15 +0000 Subject: [PATCH 263/355] ATLAS-143 Automatic tracing of tests --- src/tests/AtlasTestEnvironment.h | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 36a1c96e0..4ad380d4e 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -48,8 +48,34 @@ void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection) #define SECTION(name) \ _test_num += 1; \ _test_count = _test_num; \ - _test_subsection = name; \ - if ((_test_num - 1) == _test) ATLAS_TRACE_SCOPE(name) + _test_subsection = (name); \ + if ((_test_num - 1) == _test) ATLAS_TRACE_SCOPE(_test_subsection) + +#else + +#undef CASE +#define CASE(description) \ +void UNIQUE_NAME2(test_, __LINE__) (std::string& , int&, int); \ +static eckit::testing::TestRegister UNIQUE_NAME2(test_registration_, __LINE__)(description, &UNIQUE_NAME2(test_, __LINE__)); \ +void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection, int& _num_subsections, int _subsection); \ +void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection, int& _num_subsections, int _subsection) { \ + ATLAS_TRACE(description); \ + UNIQUE_NAME2(traced_test_, __LINE__)(_test_subsection,_num_subsections,_subsection); \ +} \ +void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection, int& _num_subsections, int _subsection) + +#undef SECTION +#define SECTION(name) \ + _num_subsections += 1; \ + _test_subsection = (name); \ + if ((_num_subsections - 1) == _subsection) { \ + eckit::Log::info() << "Running section \"" << _test_subsection << "\" ..." << std::endl; \ + } \ + if ((_num_subsections - 1) == _subsection) ATLAS_TRACE_SCOPE(_test_subsection) + +#ifndef SETUP +#define SETUP(name) +#endif #endif From a9af8204e127af9a527f7f3cabe15fd95c12683d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 24 Jan 2018 12:48:35 +0000 Subject: [PATCH 264/355] ATLAS-144 Fix possible FPE in StructuredMeshgenerator --- src/atlas/meshgenerator/StructuredMeshGenerator.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 238bf1931..5c79b80da 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -424,8 +424,8 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co const double dxN = std::abs(xN2-xN1); const double dxS = std::abs(xS2-xS1); const double dx = std::min(dxN,dxS); - const double alpha1 = ( dx==0. ? 0. : std::atan2((xN1-xS1)/dx,1.) * to_deg ); - const double alpha2 = ( dx==0. ? 0. : std::atan2((xN2-xS2)/dx,1.) * to_deg ); + const double alpha1 = ( dx==0. ? 0. : std::atan2((xN1-xS1),dx) * to_deg ); + const double alpha2 = ( dx==0. ? 0. : std::atan2((xN2-xS2),dx) * to_deg ); if( std::abs(alpha1) <= max_angle && std::abs(alpha2) <= max_angle ) { if( triangulate_quads ) From df375504d01ce9fd8922edf7d2a9c4ee1e94d50b Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 24 Jan 2018 15:15:23 +0000 Subject: [PATCH 265/355] Trans: configure nproma --- src/atlas/option/TransOptions.cc | 5 +++ src/atlas/option/TransOptions.h | 6 +++ src/atlas/trans/ifs/TransIFS.cc | 75 +++++++++++++++++++++++++------- src/atlas/trans/ifs/TransIFS.h | 9 ++-- 4 files changed, 76 insertions(+), 19 deletions(-) diff --git a/src/atlas/option/TransOptions.cc b/src/atlas/option/TransOptions.cc index e69d5daf5..5265051ad 100644 --- a/src/atlas/option/TransOptions.cc +++ b/src/atlas/option/TransOptions.cc @@ -65,6 +65,11 @@ read_legendre::read_legendre( const eckit::PathName& filepath ) set("read_legendre",filepath); } +nproma::nproma( int nproma ) +{ + set("nproma",nproma); +} + // ---------------------------------------------------------------------------- } // namespace option diff --git a/src/atlas/option/TransOptions.h b/src/atlas/option/TransOptions.h index bc54dd206..899b76903 100644 --- a/src/atlas/option/TransOptions.h +++ b/src/atlas/option/TransOptions.h @@ -80,5 +80,11 @@ class read_legendre : public util::Config { // ---------------------------------------------------------------------------- +class nproma : public util::Config { + nproma( int ); +}; + +// ---------------------------------------------------------------------------- + } // namespace option } // namespace atlas diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index 49fa0f2c2..f7bfe3b00 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -40,7 +40,7 @@ static TransBuilderGrid builder("ifs"); class TransParameters { public: - TransParameters( const eckit::Configuration& config ) : config_(config) {} + TransParameters( const TransIFS& trans, const eckit::Configuration& config ) : trans_(trans), config_(config) {} ~TransParameters() {} bool scalar_derivatives() const { @@ -80,7 +80,19 @@ class TransParameters { return config_.getBool("global",false); } + int nproma() const { + return config_.getInt("nproma",trans_->ngptot); + } + + int ngpblks() const { + int _ngptot = trans_->ngptot; + int _nproma = nproma(); + ASSERT(_ngptot%_nproma == 0); // assert _ngptot is divisable by nproma + return _ngptot/_nproma; + } + private: + const Trans_t* trans_; const eckit::Configuration& config_; }; @@ -229,7 +241,12 @@ void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra double gp_fields[], const eckit::Configuration& config ) const { - TransParameters params(config); + TransParameters params(*this,config); + + ATLAS_DEBUG_VAR( params.global() ); + ATLAS_DEBUG_VAR( params.nproma() ); + ATLAS_DEBUG_VAR( params.ngpblks() ); + struct ::InvTrans_t args = new_invtrans(trans_.get()); args.nscalar = nb_scalar_fields; args.rspscalar = scalar_spectra; @@ -241,6 +258,8 @@ void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra args.lscalarders = params.scalar_derivatives(); args.luvder_EW = params.wind_EW_derivatives(); args.lvordivgp = params.vorticity_divergence_fields(); + args.nproma = params.nproma(); + args.ngpblks = params.ngpblks(); TRANS_CHECK( ::trans_invtrans(&args) ); } @@ -250,14 +269,7 @@ void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra double gp_fields[], const eckit::Configuration& config ) const { - TransParameters params(config); - struct ::InvTrans_t args = new_invtrans(trans_.get()); - args.nscalar = nb_scalar_fields; - args.rspscalar = scalar_spectra; - args.rgp = gp_fields; - args.lglobal = params.global(); - args.lscalarders = params.scalar_derivatives(); - TRANS_CHECK( ::trans_invtrans(&args) ); + return invtrans( nb_scalar_fields, scalar_spectra, 0, nullptr, nullptr, gp_fields, config ); } /////////////////////////////////////////////////////////////////////////////// @@ -266,7 +278,16 @@ void TransIFS::invtrans( const int nb_vordiv_fields, const double vorticity_spec double gp_fields[], const eckit::Configuration& config ) const { - TransParameters params(config); + TransParameters params(*this,config); + bool global = params.global(); + int nproma = params.nproma(); + int ngpblks; + if( nproma == 0 ) { // default + nproma = global ? trans_->ngptotg : trans_->ngptot; + ngpblks = 1; + } else { + ngpblks = global ? (trans_->ngptotg/nproma) : (trans_->ngptot/nproma); + } struct ::InvTrans_t args = new_invtrans(trans_.get()); args.nvordiv = nb_vordiv_fields; args.rspvor = vorticity_spectra; @@ -275,6 +296,8 @@ void TransIFS::invtrans( const int nb_vordiv_fields, const double vorticity_spec args.lglobal = params.global(); args.luvder_EW = params.wind_EW_derivatives(); args.lvordivgp = params.vorticity_divergence_fields(); + args.nproma = params.nproma(); + args.ngpblks = params.ngpblks(); TRANS_CHECK( ::trans_invtrans(&args) ); } @@ -283,12 +306,23 @@ void TransIFS::invtrans( const int nb_vordiv_fields, const double vorticity_spec void TransIFS::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], const eckit::Configuration& config ) const { - TransParameters params(config); + TransParameters params(*this,config); + bool global = params.global(); + int nproma = params.nproma(); + int ngpblks; + if( nproma == 0 ) { // default + nproma = global ? trans_->ngptotg : trans_->ngptot; + ngpblks = 1; + } else { + ngpblks = global ? (trans_->ngptotg/nproma) : (trans_->ngptot/nproma); + } struct ::DirTrans_t args = new_dirtrans(trans_.get()); args.nscalar = nb_fields; args.rgp = scalar_fields; args.rspscalar = scalar_spectra; args.lglobal = params.global(); + args.nproma = params.nproma(); + args.ngpblks = params.ngpblks(); TRANS_CHECK( ::trans_dirtrans(&args) ); } @@ -297,13 +331,24 @@ void TransIFS::dirtrans( const int nb_fields, const double scalar_fields[], doub void TransIFS::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], const eckit::Configuration& config ) const { - TransParameters params(config); + TransParameters params(*this,config); + bool global = params.global(); + int nproma = params.nproma(); + int ngpblks; + if( nproma == 0 ) { // default + nproma = global ? trans_->ngptotg : trans_->ngptot; + ngpblks = 1; + } else { + ngpblks = global ? (trans_->ngptotg/nproma) : (trans_->ngptot/nproma); + } struct ::DirTrans_t args = new_dirtrans(trans_.get()); args.nvordiv = nb_fields; args.rspvor = vorticity_spectra; args.rspdiv = divergence_spectra; args.rgp = wind_fields; args.lglobal = params.global(); + args.nproma = params.nproma(); + args.ngpblks = params.ngpblks(); TRANS_CHECK( ::trans_dirtrans(&args) ); } @@ -760,7 +805,7 @@ void TransIFS::ctor_spectral_only(long truncation, const eckit::Configuration& ) void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const eckit::Configuration& config ) { - TransParameters p(config); + TransParameters p(*this,config); std::vector nloen(nlat); for( long jlat=0; jlat= 0 ) diff --git a/src/atlas/trans/ifs/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h index fb7f7efc2..233f856e9 100644 --- a/src/atlas/trans/ifs/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -131,11 +131,12 @@ class TransIFS : public trans::TransImpl { /*! * @brief invtrans * @param nb_scalar_fields - * @param scalar_spectra + * @param scalar_spectra [NSPEC2][nb_scalar_fields] * @param nb_vordiv_fields - * @param vorticity_spectra - * @param divergence_spectra - * @param gp_fields + * @param vorticity_spectra [NSPEC2][nb_vordiv_fields] + * @param divergence_spectra [NSPEC2][nb_vordiv_fields] + * @param gp_fields Ordering: [NGPBLKS][NFLD][NPROMA] if distributed, + * [NFLD][NGPTOTG] if global ( add option::global() ) */ virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], From d2732e5400d5634ae10e7c780698c5dbb8f3fd4d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 24 Jan 2018 17:09:38 +0000 Subject: [PATCH 266/355] ATLAS-145 VorDivToUV API --- src/atlas/CMakeLists.txt | 7 + src/atlas/functionspace/Spectral.h | 8 +- src/atlas/trans/Trans.cc | 1 + src/atlas/trans/VorDivToUV.cc | 199 +++++++++++++++++++++++ src/atlas/trans/VorDivToUV.h | 159 ++++++++++++++++++ src/atlas/trans/ifs/TransIFS.cc | 5 - src/atlas/trans/ifs/VorDivToUVIFS.cc | 71 ++++++++ src/atlas/trans/ifs/VorDivToUVIFS.h | 71 ++++++++ src/atlas/trans/local/VorDivToUVLocal.cc | 49 ++++++ src/atlas/trans/local/VorDivToUVLocal.h | 70 ++++++++ src/tests/trans/test_trans.cc | 49 ++++++ 11 files changed, 683 insertions(+), 6 deletions(-) create mode 100644 src/atlas/trans/VorDivToUV.cc create mode 100644 src/atlas/trans/VorDivToUV.h create mode 100644 src/atlas/trans/ifs/VorDivToUVIFS.cc create mode 100644 src/atlas/trans/ifs/VorDivToUVIFS.h create mode 100644 src/atlas/trans/local/VorDivToUVLocal.cc create mode 100644 src/atlas/trans/local/VorDivToUVLocal.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 6a1552bef..8c25f43da 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -318,6 +318,8 @@ numerics/fvm/Nabla.cc trans/Trans.h trans/Trans.cc +trans/VorDivToUV.h +trans/VorDivToUV.cc trans/local/TransLocal.h trans/local/TransLocal.cc trans/local/LegendrePolynomials.h @@ -326,6 +328,9 @@ trans/local/LegendreTransforms.h trans/local/LegendreTransforms.cc trans/local/FourierTransforms.h trans/local/FourierTransforms.cc +trans/local/VorDivToUVLocal.h +trans/local/VorDivToUVLocal.cc + ) if( ATLAS_HAVE_TRANS ) list( APPEND atlas_numerics_srcs @@ -335,6 +340,8 @@ list( APPEND atlas_numerics_srcs trans/ifs/TransIFSNodeColumns.cc trans/ifs/TransIFSStructuredColumns.h trans/ifs/TransIFSStructuredColumns.cc + trans/ifs/VorDivToUVIFS.h + trans/ifs/VorDivToUVIFS.cc ) endif() diff --git a/src/atlas/functionspace/Spectral.h b/src/atlas/functionspace/Spectral.h index baaec4265..b6353493a 100644 --- a/src/atlas/functionspace/Spectral.h +++ b/src/atlas/functionspace/Spectral.h @@ -23,7 +23,6 @@ namespace atlas { namespace atlas { namespace trans { class Trans; - class TransImpl; } } @@ -130,9 +129,16 @@ class Spectral : public FunctionSpace { const detail::Spectral* functionspace_; }; +} // namespace functionspace +} // namespace atlas // ------------------------------------------------------------------- // C wrapper interfaces to C++ routines +namespace atlas { +namespace field { class FieldSetImpl; class FieldImpl; } +namespace trans { class TransImpl; } +namespace functionspace { + extern "C" { const detail::Spectral* atlas__SpectralFunctionSpace__new__config ( const eckit::Configuration* config ); diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index f7e6e0d04..554fc640d 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -57,6 +57,7 @@ namespace { load_builder_functionspace(); load_builder_grid(); #endif + load_builder_grid(); } }; diff --git a/src/atlas/trans/VorDivToUV.cc b/src/atlas/trans/VorDivToUV.cc new file mode 100644 index 000000000..0a5838ab7 --- /dev/null +++ b/src/atlas/trans/VorDivToUV.cc @@ -0,0 +1,199 @@ +/* + * (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/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/utils/Hash.h" + +#include "atlas/trans/VorDivToUV.h" +#include "atlas/runtime/Log.h" +#include "atlas/functionspace.h" +#include "atlas/grid/Grid.h" + +#ifdef ATLAS_HAVE_TRANS +#include "atlas/trans/ifs/VorDivToUVIFS.h" +#define TRANS_DEFAULT "ifs" +#else +#define TRANS_DEFAULT "local" +#endif +#include "atlas/trans/local/VorDivToUVLocal.h" + +namespace atlas { +namespace trans { + +VorDivToUVImpl::~VorDivToUVImpl() { +} + +namespace { + + static eckit::Mutex *local_mutex = 0; + static std::map *m = 0; + static pthread_once_t once = PTHREAD_ONCE_INIT; + + static void init() { + local_mutex = new eckit::Mutex(); + m = new std::map(); + } + + template void load_builder() { VorDivToUVBuilder("tmp"); } + + struct force_link { + force_link() + { +#ifdef ATLAS_HAVE_TRANS + load_builder(); +#endif + load_builder(); + } + }; + + VorDivToUVFactory& factory( const std::string& name ) { + std::map::const_iterator j = m->find(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) + Log::error() << " " << (*j).first << std::endl; + throw eckit::SeriousBug(std::string("No VorDivToUVFactory called ") + name); + } + return *j->second; + } + + +} + + + +VorDivToUVFactory::VorDivToUVFactory(const std::string &name): + name_(name) { + + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + ASSERT(m->find(name) == m->end()); + (*m)[name] = this; +} + + +VorDivToUVFactory::~VorDivToUVFactory() { + eckit::AutoLock lock(local_mutex); + m->erase(name_); +} + + +bool VorDivToUVFactory::has(const std::string& name) { + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + return ( m->find(name) != m->end() ); +} + + +void VorDivToUVFactory::list(std::ostream& out) { + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + const char* sep = ""; + for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { + out << sep << (*j).first; + sep = ", "; + } +} + + +VorDivToUV::Implementation *VorDivToUVFactory::build( const FunctionSpace& sp, const eckit::Configuration& config ) { + + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + std::string suffix ( "("+sp.type()+")" ); + std::string name = config.getString("type",TRANS_DEFAULT)+suffix; + + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + + if( not config.has("type") and not has(name) ) { + name = std::string("local")+suffix; + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + } + + return factory(name).make(sp,config); +} + + +VorDivToUV::Implementation *VorDivToUVFactory::build( int truncation, const eckit::Configuration& config ) { + + pthread_once(&once, init); + + eckit::AutoLock lock(local_mutex); + + static force_link static_linking; + + std::string name = config.getString("type",TRANS_DEFAULT); + + Log::debug() << "Looking for VorDivToUVFactory [" << name << "]" << std::endl; + + if( not config.has("type") and not has(name) ) { + name = std::string("local"); + Log::debug() << "Looking for VorDivToUVFactory [" << name << "]" << std::endl; + } + + return factory(name).make(truncation,config); +} + + +VorDivToUV::VorDivToUV() { +} + +VorDivToUV::VorDivToUV( Implementation* impl ) : + impl_(impl) { +} + +VorDivToUV::VorDivToUV( const FunctionSpace& sp, const eckit::Configuration& config ) : + impl_( VorDivToUVFactory::build(sp,config) ) +{ +} + +VorDivToUV::VorDivToUV( int truncation, const eckit::Configuration& config ) : + impl_( VorDivToUVFactory::build(truncation,config) ) +{ +} + +VorDivToUV::VorDivToUV( const VorDivToUV& other ) : + impl_(other.impl_) { +} + +int VorDivToUV::truncation() const { + return impl_->truncation(); +} + +// -- IFS type fields -- +// These fields have special interpretation required. You need to know what you're doing. +// See IFS trans library. + +void VorDivToUV::execute( const int nb_coeff, const int nb_fields, const double vorticity[], const double divergence[], + double U[], double V[], + const eckit::Configuration& config ) const { + impl_->execute( nb_coeff, nb_fields, vorticity, divergence, U, V, config ); +} + + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/VorDivToUV.h b/src/atlas/trans/VorDivToUV.h new file mode 100644 index 000000000..c7a5165ea --- /dev/null +++ b/src/atlas/trans/VorDivToUV.h @@ -0,0 +1,159 @@ +/* + * (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 + +#include "eckit/config/Configuration.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" +#include "eckit/io/Buffer.h" +#include "eckit/io/DataHandle.h" + +#include "atlas/util/Config.h" + +//----------------------------------------------------------------------------- +// Forward declarations + +namespace atlas { + class Field; + class FieldSet; + class FunctionSpace; + class Grid; +} + +//----------------------------------------------------------------------------- + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +class VorDivToUVImpl : public eckit::Owned { + +public: + + virtual ~VorDivToUVImpl() = 0; + + virtual int truncation() const = 0; + + // -- IFS type fields -- + // These fields have special interpretation required. You need to know what you're doing. + // See IFS trans library. + + /*! + * @brief Compute spectral wind (U/V) from spectral vorticity/divergence + * + * U = u*cos(lat) + * V = v*cos(lat) + * + * @param nb_fields [in] Number of fields + * @param vorticity [in] Spectral vorticity + * @param divergence [in] Spectral divergence + * @param U [out] Spectral wind U = u*cos(lat) + * @param V [out] Spectral wind V = v*cos(lat) + */ + virtual void execute( const int nb_coeff, const int nb_fields, + const double vorticity[], const double divergence[], + double U[], double V[], + const eckit::Configuration& = util::NoConfig() ) const = 0; +}; + +// ------------------------------------------------------------------ + + +class VorDivToUVFactory { +public: + + /*! + * \brief build VorDivToUV + * \return VorDivToUVImpl + */ + static VorDivToUVImpl* build( const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); + static VorDivToUVImpl* build( int truncation, const eckit::Configuration& = util::Config() ); + + /*! + * \brief list all registered trans implementations + */ + static void list(std::ostream &); + + static bool has(const std::string& name); + +private: + + std::string name_; + virtual VorDivToUVImpl* make( const FunctionSpace& sp, const eckit::Configuration& ) { return nullptr; } + virtual VorDivToUVImpl* make( int truncation, const eckit::Configuration& ) { return nullptr; } + +protected: + + VorDivToUVFactory(const std::string&); + virtual ~VorDivToUVFactory(); + +}; + +//---------------------------------------------------------------------------------------------------------------------- + +template +class VorDivToUVBuilder : public VorDivToUVFactory { + virtual VorDivToUVImpl* make( const FunctionSpace& sp, const eckit::Configuration& config ) { + return new T(sp,config); + } + virtual VorDivToUVImpl* make( int truncation, const eckit::Configuration& config ) { + return new T(truncation, config); + } +public: + VorDivToUVBuilder(const std::string& name) : VorDivToUVFactory(name) {} +}; + +//---------------------------------------------------------------------------------------------------------------------- + +class VorDivToUV { + +public: + + using Implementation = VorDivToUVImpl; + +private: + + eckit::SharedPtr< Implementation > impl_; + +public: + + VorDivToUV(); + VorDivToUV( Implementation* ); + VorDivToUV( const VorDivToUV& ); + + VorDivToUV( const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); + VorDivToUV( int truncation, const eckit::Configuration& = util::NoConfig() ); + + void hash(eckit::Hash&) const; + const Implementation* get() const { return impl_.get(); } + operator bool() const { return impl_.owners(); } + + int truncation() const; + + // -- IFS type fields -- + // These fields have special interpretation required. You need to know what you're doing. + // See IFS trans library. + + virtual void execute( const int nb_coeff, const int nb_fields, + const double vorticity[], const double divergence[], + double U[], double V[], + const eckit::Configuration& = util::NoConfig() ) const; + +}; + +//---------------------------------------------------------------------------------------------------------------------- + +} // namespace trans +} // namespace atlas + diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index f7bfe3b00..4fd0e94c7 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -242,11 +242,6 @@ void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra const eckit::Configuration& config ) const { TransParameters params(*this,config); - - ATLAS_DEBUG_VAR( params.global() ); - ATLAS_DEBUG_VAR( params.nproma() ); - ATLAS_DEBUG_VAR( params.ngpblks() ); - struct ::InvTrans_t args = new_invtrans(trans_.get()); args.nscalar = nb_scalar_fields; args.rspscalar = scalar_spectra; diff --git a/src/atlas/trans/ifs/VorDivToUVIFS.cc b/src/atlas/trans/ifs/VorDivToUVIFS.cc new file mode 100644 index 000000000..ac43fa55e --- /dev/null +++ b/src/atlas/trans/ifs/VorDivToUVIFS.cc @@ -0,0 +1,71 @@ +/* + * (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 "atlas/trans/ifs/VorDivToUVIFS.h" + +#include "atlas/functionspace/Spectral.h" +#include "atlas/runtime/Log.h" +#include "atlas/parallel/mpi/mpi.h" + +using atlas::functionspace::Spectral; +using atlas::FunctionSpace; + +namespace atlas { +namespace trans { + +namespace { +static VorDivToUVBuilder builder("ifs"); +} + +namespace { +void trans_check(const int code, const char* msg, const eckit::CodeLocation& location) { + if(code != TRANS_SUCCESS) { + std::stringstream errmsg; + errmsg << "atlas::trans ERROR: " << msg << " failed: \n"; + errmsg << ::trans_error_msg(code); + throw eckit::Exception(errmsg.str(),location); + } +} +#define TRANS_CHECK( CALL ) trans_check(CALL, #CALL, Here() ) + +} + +void VorDivToUVIFS::execute( const int nb_coeff, const int nb_fields, + const double vorticity[], const double divergence[], + double U[], double V[], + const eckit::Configuration& config ) const +{ + struct ::VorDivToUV_t vordiv_to_UV = new_vordiv_to_UV(); + vordiv_to_UV.rspvor = vorticity; + vordiv_to_UV.rspdiv = divergence; + vordiv_to_UV.rspu = U; + vordiv_to_UV.rspv = V; + 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) ); +} + + +VorDivToUVIFS::VorDivToUVIFS( const int truncation, const eckit::Configuration& config ) : + truncation_(truncation) { +} + +VorDivToUVIFS::VorDivToUVIFS( const FunctionSpace& fs, const eckit::Configuration& config ) : + truncation_( Spectral(fs).truncation() ) { +} + + +VorDivToUVIFS::~VorDivToUVIFS() +{ +} + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/VorDivToUVIFS.h b/src/atlas/trans/ifs/VorDivToUVIFS.h new file mode 100644 index 000000000..03a98273a --- /dev/null +++ b/src/atlas/trans/ifs/VorDivToUVIFS.h @@ -0,0 +1,71 @@ +/* + * (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 "transi/trans.h" +#include "atlas/trans/VorDivToUV.h" + +//----------------------------------------------------------------------------- +// Forward declarations + +namespace atlas { +class FunctionSpace; +} + +//----------------------------------------------------------------------------- + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +class VorDivToUVIFS : public trans::VorDivToUVImpl { +public: + + VorDivToUVIFS( const FunctionSpace&, const eckit::Configuration& = util::NoConfig() ); + VorDivToUVIFS( int truncation, const eckit::Configuration& = util::NoConfig() ); + + virtual ~VorDivToUVIFS(); + + virtual int truncation() const override { return truncation_; } + +// pure virtual interface + +// -- IFS style API -- +// These fields have special interpretation required. You need to know what you're doing. +// See IFS trans library. + + /*! + * @brief Compute spectral wind (U/V) from spectral vorticity/divergence + * + * U = u*cos(lat) + * V = v*cos(lat) + * + * @param nb_fields [in] Number of fields + * @param vorticity [in] Spectral vorticity + * @param divergence [in] Spectral divergence + * @param U [out] Spectral wind U = u*cos(lat) + * @param V [out] Spectral wind V = v*cos(lat) + */ + virtual void execute( const int nb_coeff, const int nb_fields, + const double vorticity[], const double divergence[], + double U[], double V[], + const eckit::Configuration& = util::NoConfig() ) const override ; + +private: + int truncation_; +}; + + +// ------------------------------------------------------------------ + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc new file mode 100644 index 000000000..041964366 --- /dev/null +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -0,0 +1,49 @@ +/* + * (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 "atlas/trans/local/VorDivToUVLocal.h" + +#include "atlas/functionspace/Spectral.h" +#include "atlas/runtime/Log.h" + +using atlas::functionspace::Spectral; +using atlas::FunctionSpace; + +namespace atlas { +namespace trans { + +namespace { +static VorDivToUVBuilder builder("local"); +} + +void VorDivToUVLocal::execute( const int nb_coeff, const int nb_fields, + const double vorticity[], const double divergence[], + double U[], double V[], + const eckit::Configuration& config ) const +{ + NOTIMP; +} + + +VorDivToUVLocal::VorDivToUVLocal( const int truncation, const eckit::Configuration& config ) : + truncation_(truncation) { +} + +VorDivToUVLocal::VorDivToUVLocal( const FunctionSpace& fs, const eckit::Configuration& config ) : + truncation_( Spectral(fs).truncation() ) { +} + + +VorDivToUVLocal::~VorDivToUVLocal() +{ +} + +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/VorDivToUVLocal.h b/src/atlas/trans/local/VorDivToUVLocal.h new file mode 100644 index 000000000..064bd4295 --- /dev/null +++ b/src/atlas/trans/local/VorDivToUVLocal.h @@ -0,0 +1,70 @@ +/* + * (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/trans/VorDivToUV.h" + +//----------------------------------------------------------------------------- +// Forward declarations + +namespace atlas { +class FunctionSpace; +} + +//----------------------------------------------------------------------------- + +namespace atlas { +namespace trans { + +//----------------------------------------------------------------------------- + +class VorDivToUVLocal : public trans::VorDivToUVImpl { +public: + + VorDivToUVLocal( const FunctionSpace&, const eckit::Configuration& = util::NoConfig() ); + VorDivToUVLocal( int truncation, const eckit::Configuration& = util::NoConfig() ); + + virtual ~VorDivToUVLocal(); + + virtual int truncation() const override { return truncation_; } + +// pure virtual interface + +// -- IFS style API -- +// These fields have special interpretation required. You need to know what you're doing. +// See IFS trans library. + + /*! + * @brief Compute spectral wind (U/V) from spectral vorticity/divergence + * + * U = u*cos(lat) + * V = v*cos(lat) + * + * @param nb_fields [in] Number of fields + * @param vorticity [in] Spectral vorticity + * @param divergence [in] Spectral divergence + * @param U [out] Spectral wind U = u*cos(lat) + * @param V [out] Spectral wind V = v*cos(lat) + */ + virtual void execute( const int nb_coeff, const int nb_fields, + const double vorticity[], const double divergence[], + double U[], double V[], + const eckit::Configuration& = util::NoConfig() ) const override ; + +private: + int truncation_; +}; + + +// ------------------------------------------------------------------ + +} // namespace trans +} // namespace atlas diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index e8679c885..3b3a7f945 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -27,6 +27,7 @@ #include "atlas/output/Gmsh.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/trans/Trans.h" +#include "atlas/trans/VorDivToUV.h" #include "atlas/array/MakeView.h" #include "tests/AtlasTestEnvironment.h" @@ -504,6 +505,54 @@ CASE( "test_trans_MIR_lonlat" ) } } +CASE( "test_trans_VorDivToUV") +{ + int nfld = 10; + std::vector truncation_array{159,160,1279,1280}; + for( int i=0; i field_U ( nfld*nspec2 ); + std::vector field_V ( nfld*nspec2 ); + + vordiv_to_UV.execute( nspec2, nfld, field_vor.data(), field_div.data(), field_U.data(), field_V.data() ); + + // TODO: do some meaningful checks + + } + + // With Local + { + trans::VorDivToUV vordiv_to_UV(truncation,util::Config("type","local")); + EXPECT( vordiv_to_UV.truncation() == truncation ); + + std::vector field_U ( nfld*nspec2 ); + std::vector field_V ( nfld*nspec2 ); + + // TODO: + // vordiv_to_UV.execute( nspec2, nfld, field_vor.data(), field_div.data(), field_U.data(), field_V.data() ); + + // TODO: do some meaningful checks + } + + + } +} + //----------------------------------------------------------------------------- From b6ed979d08cf9d361aa5d9a8ee9dafe0765d587e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 24 Jan 2018 17:24:38 +0000 Subject: [PATCH 267/355] ATLAS-145 VorDivToUV API cosmetic --- src/tests/trans/test_trans.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 3b3a7f945..d959a9f8a 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -523,7 +523,7 @@ CASE( "test_trans_VorDivToUV") // With IFS if( trans::VorDivToUVFactory::has("ifs") ) { - trans::VorDivToUV vordiv_to_UV(truncation,util::Config("type","ifs")); + trans::VorDivToUV vordiv_to_UV(truncation, option::type("ifs")); EXPECT( vordiv_to_UV.truncation() == truncation ); std::vector field_U ( nfld*nspec2 ); @@ -537,7 +537,7 @@ CASE( "test_trans_VorDivToUV") // With Local { - trans::VorDivToUV vordiv_to_UV(truncation,util::Config("type","local")); + trans::VorDivToUV vordiv_to_UV(truncation, option::type("local")); EXPECT( vordiv_to_UV.truncation() == truncation ); std::vector field_U ( nfld*nspec2 ); From 1c84c34f9d1f8833b39fa01f8b868e0b0300c1bc Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Wed, 24 Jan 2018 18:05:42 +0000 Subject: [PATCH 268/355] ATLAS-135 some bug-fixes. Still working on the vordiv test in transgeneral --- src/atlas/trans/local/TransLocal.cc | 20 +++++--- src/tests/trans/test_transgeneral.cc | 74 ++++++++++++++++++---------- 2 files changed, 60 insertions(+), 34 deletions(-) diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 2b59306db..ae785f2c7 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -254,7 +254,7 @@ void prfi1b( const double rspec[], // spectral data double pia[]) // spectral components in data layout of trans library { - int ilcm = truncation-km, ioff = (2*truncation-km+1)*km, nlei1 = truncation+4+(truncation+4+1)%2; + int ilcm = truncation-km, ioff = (2*truncation-km+3)*km, nlei1 = truncation+4+(truncation+4+1)%2; for( int j=0; j<=ilcm; ++j ) { int inm = ioff+(ilcm-j)*2; for( int jfld=0; jfld0 ) rft *= 2.; // the famous factor 2 that noone really understands if( imag==0 ) { rft *= std::cos(m*lon); @@ -265,6 +265,8 @@ double sphericalharmonics_analytic_point( void spectral_transform_grid_analytic( const size_t trc, // truncation (in) const size_t trcFT, // truncation for Fourier transformation (in) + const int nb_scalar, + const int nb_vordiv, const double n, // total wave number (implemented so far for n<4 const double m, // zonal wave number (implemented so far for m<4, m= tolerance ) { + //EXPECT_NO_THROW( spectral_transform_grid(trc, trc, g, sp, rgp, false) ); + //EXPECT_NO_THROW( transLocal.invtrans( nb_scalar, sp, rgp) ); + EXPECT_NO_THROW( transLocal.invtrans( nb_scalar, sp, nb_vordiv, vor, div, rgp) ); + Log::info() << "Trans library: m=" << m << " n=" << n << " imag=" << imag << std::endl; + for( int j=0; j= tolerance ) { ATLAS_DEBUG_VAR(rms_gen); ATLAS_DEBUG_VAR(tolerance); - } - EXPECT( rms_gen < tolerance ); - EXPECT( rms_trans < tolerance ); + //} + //if( rms_trans >= tolerance ) { + ATLAS_DEBUG_VAR(rms_trans); + ATLAS_DEBUG_VAR(tolerance); + //} + //EXPECT( rms_gen < tolerance ); + //EXPECT( rms_trans < tolerance ); } k++; } From 183aec6912dc30dc43c14eb3fe559df7d427710a Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 25 Jan 2018 07:43:33 +0000 Subject: [PATCH 269/355] Remove strange test --- src/tests/trans/test_trans.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index d959a9f8a..fca6d99be 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -508,7 +508,7 @@ CASE( "test_trans_MIR_lonlat" ) CASE( "test_trans_VorDivToUV") { int nfld = 10; - std::vector truncation_array{159,160,1279,1280}; + std::vector truncation_array{159,160,1279}; for( int i=0; i Date: Thu, 25 Jan 2018 08:37:48 +0000 Subject: [PATCH 270/355] Update readme --- README.md | 88 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index a5026690f..3fca3d2d7 100644 --- a/README.md +++ b/README.md @@ -3,23 +3,26 @@ Atlas Project home: https://software.ecmwf.int/wiki/display/ATLAS/Atlas Contact: Willem Deconinck (willem.deconinck@ecmwf.int) +Publication (open-access): https://doi.org/10.1016/j.cpc.2017.07.006 Atlas is a ECMWF framework for parallel data-structures supporting unstructured grids and function spaces, with the aim to investigate alternative more scalable -dynamical core options for IFS, and to create modern interpolation and product -generation softrware +dynamical core options for Earth System models, and to support modern interpolation +and product generation softrware Atlas is predominantly C++ code, with main features available to Fortran codes through a F2003 interface. It requires some flavour of Unix (such as Linux). It is known to run on a number of systems, some of which are directly supported by ECMWF. -Tested compilers include +If Atlas has been useful in your research, please cite the above-mentioned publication. -- GCC 4.8.1 -- Intel 13.0.1, 14.0.1 -- CCE 8.2.7, 8.3.1 +Tested compilers include +- GCC 4.9.1, 5.3.0, 6.3.0, 7.2.0 +- Intel 15.0.2, 16.0.3, 17. +- CCE 8.4.5, 8.5.8, 8.6.2 +- PGI-Fortran 17.7 combined with GNU-C/C++ 6.3 Third Party Requirements ------------------------ @@ -27,68 +30,93 @@ Third Party Requirements Requirements to compile atlas: - CMake --- For use and installation see http://www.cmake.org/ -- ecbuild +- ecbuild --- ECMWF library of CMake macros - eckit (with mpi support) -- python (only when Fortran bindings are required) Recommended: -- OpenMP --- Shared memory parallelisation -- fkit --- Unit testing for Fortran +- fckit --- For enabling Fortran interfaces +- python (only when Fortran bindings are required) + +Optional for certain features: +- gridtools-storage --- For GPU interoperability +- transi --- For enabling IFS spherical harmonics transforms ( not open-source ) +- CGAL --- For enabling Delaunay triangulation of unstructured grids Installation ------------ Atlas employs an out-of-source build/install based on CMake. +Make sure ecbuild, eckit and fckit are installed and the ecbuild +executable script is found ( `which ecbuild` ): + +```bash +# For finding eckit +ECKIT_PATH # Path to eckit prefix + +# For finding fckit +FCKIT_PATH # Path to fckit prefix +``` + +Other environment variables that could be required for optional features: + +```bash +# For finding gridtools-storage +GRIDTOOLS_STORAGE_PATH # Path to gridtools-storage prefix + +# For finding transi +TRANSI_PATH # Path to transi prefix + +# For finding CGAL +BOOST_ROOT # Path to Boost prefix +CGAL_DIR # Path to directory containing CGALConfig.cmake +``` + +Now proceed with installation as follows + ```bash # Environment --- Edit as needed ATLAS_SRC=$(pwd) ATLAS_BUILD=build ATLAS_INSTALL=$HOME/local -export CC=mpicc -export CXX=mpicxx # 1. Create the build directory: mkdir $ATLAS_BUILD cd $ATLAS_BUILD # 2. Run CMake -cmake $ATLAS_SRC -DCMAKE_INSTALL_PREFIX=$ATLAS_INSTALL +ecbuild --prefix=$ATLAS_INSTALL -- $ATLAS_SRC # 3. Compile / Install make -j10 make install + +# 4. Check installation +$ATLAS_INSTALL/bin/atlas --info ``` Extra flags maybe added to step 2 to fine-tune configuration. -- `-DCMAKE_BUILD_TYPE=DEBUG|RELEASE|BIT` --- Optimisation level - * DEBUG: No optimisation - * BIT: Maximum optimisation while remaning bit-reproducible - * RELEASE: Maximum optimisation +- `--build=DEBUG|RELEASE|BIT` --- Optimisation level + * DEBUG: No optimisation (-O0 -g) + * BIT: Maximum optimisation while remaning bit-reproducible (-O2 -g) + * RELEASE: Maximum optimisation (-O3) - `-DENABLE_OMP=OFF` --- Disable OpenMP -- `-DENABLE_MPI=OFF` --- Disable MPI - `-DENABLE_FORTRAN=OFF` --- Disable Compilation of Fortran bindings > **Note:** > By default compilation is done using shared libraries. Some systems have linking > problems with static libraries that have not been compiled with `-fPIC`. > In this case, also compile atlas using static linking, by adding to step 2: - `-DBUILD_SHARED_LIBS=OFF` + `--static` Runtime Configuration --------------------- -Atlas behaviour can be configured through variables defined at the command-line, in the -environment, or in configuration files. -In following table, the column "variable" can be edited in configuration files. - -| variable | command line | environment | default | -|-----------------------------|------------------|--------------------------|--------------------| -| `debug` | `--debug` | `$DEBUG` | `0` | -| | `--name` | | `` | -| `atlas.logfile` | `--logfile` | `$ATLAS_LOGFILE` | | -| `atlas.logfile_task` | `--logfile_task` | `$ATLAS_LOGFILE_TASK` | `-1` | -| `atlas.console_task` | `--console_task` | `$ATLAS_CONSOLE_TASK` | `0` | +Atlas behaviour can be configured through some environment variables with defaults marked in square brackets + +- `ATLAS_INFO=<0|[1]>` --- Control printing of Atlas standard information +- `ATLAS_DEBUG=<[0]|1>` --- Control printing of Atlas debug information +- `ATLAS_TRACE=<[0]|1>` --- Control printing of Atlas traces (includes timings) From 0c793064786a0bfe8c71fca7f280eeca9ef1d3ee Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 25 Jan 2018 11:45:06 +0000 Subject: [PATCH 271/355] ATLAS-146 Fix OpenMP stubs --- src/apps/atlas-benchmark.cc | 4 +- src/atlas/parallel/omp/omp.cc | 300 ++++++---------------------------- src/atlas/parallel/omp/omp.h | 86 +++------- 3 files changed, 80 insertions(+), 310 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 49dac03e7..eb2575c2c 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -215,7 +215,7 @@ void AtlasBenchmark::execute(const Args& args) haloexchange_timer = TimerStats("halo-exchange"); if( omp_threads > 0 ) - omp_set_num_threads(omp_threads); + atlas_omp_set_num_threads(omp_threads); Log::info() << "atlas-benchmark\n" << endl; Log::info() << Library::instance().information() << endl; @@ -225,7 +225,7 @@ void AtlasBenchmark::execute(const Args& args) Log::info() << " niter: " << niter << endl; Log::info() << endl; Log::info() << " MPI tasks: "< +#else +extern void omp_set_num_threads(int num_threads); +extern int omp_get_num_threads(void); +extern int omp_get_max_threads(void); +extern int omp_get_thread_num(void); +extern int omp_get_num_procs(void); +extern int omp_in_parallel(void); +extern int omp_set_dynamic(int dynamic_threads); +extern int omp_get_dynamic(void); +extern void omp_set_nested(int nested); +extern int omp_get_nested(void); +#endif -#ifndef _OPENMP // We need openmp stubs - -#include -#include -#include "eckit/exception/Exceptions.h" - -extern "C" { +#pragma weak omp_set_num_threads +#pragma weak omp_get_num_threads +#pragma weak omp_get_max_threads +#pragma weak omp_get_thread_num +#pragma weak omp_get_num_procs +#pragma weak omp_in_parallel +#pragma weak omp_set_dynamic +#pragma weak omp_get_dynamic +#pragma weak omp_set_nested +#pragma weak omp_get_nested -void omp_set_num_threads(int num_threads) -{ -} -int omp_get_num_threads(void) -{ - return 1; -} -int omp_get_max_threads(void) -{ - return 1; -} -int omp_get_thread_num(void) -{ - return 0; -} -int omp_get_num_procs(void) -{ - return 1; -} -int omp_in_parallel(void) -{ - return 0; -} -void omp_set_dynamic(int dynamic_threads) +void atlas_omp_set_num_threads(int num_threads) { + if( omp_set_num_threads ) omp_set_num_threads(num_threads); } -int omp_get_dynamic(void) -{ - return 0; -} -void omp_set_nested(int nested) -{ -} -int omp_get_nested(void) -{ - return 0; -} -void omp_set_schedule(omp_sched_t kind, int modifier) -{ -} -void omp_get_schedule(omp_sched_t *kind, int *modifier) -{ - *kind = omp_sched_static; - *modifier = 0; -} -int omp_get_thread_limit(void) -{ - return 1; -} -void omp_set_max_active_levels(int max_active_levels) -{ -} -int omp_get_max_active_levels(void) -{ - return 0; -} -int omp_get_level(void) -{ - return 0; -} -int omp_get_ancestor_thread_num(int level) -{ - if (level == 0) - { - return 0; - } - else - { - return -1; - } -} -int omp_get_team_size(int level) -{ - if (level == 0) - { - return 1; - } - else - { - return -1; - } -} -int omp_get_active_level(void) -{ - return 0; -} -int omp_in_final(void) -{ - return 1; -} -struct __omp_lock -{ - int lock; -}; -enum { UNLOCKED = -1, INIT, LOCKED }; -void omp_init_lock(omp_lock_t *arg) -{ -struct __omp_lock *lock = (struct __omp_lock *)arg; - lock->lock = UNLOCKED; -} -void omp_destroy_lock(omp_lock_t *arg) -{ -struct __omp_lock *lock = (struct __omp_lock *)arg; - lock->lock = INIT; -} -void omp_set_lock(omp_lock_t *arg) -{ -struct __omp_lock *lock = (struct __omp_lock *)arg; - if (lock->lock == UNLOCKED) - { - lock->lock = LOCKED; - } - else if (lock->lock == LOCKED) - { - fprintf(stderr, -"error: deadlock in using lock variable\n"); - exit(1); - } - else - { - fprintf(stderr, "error: lock not initialized\n"); - exit(1); - } -} -void omp_unset_lock(omp_lock_t *arg) -{ -struct __omp_lock *lock = (struct __omp_lock *)arg; - if (lock->lock == LOCKED) - { - lock->lock = UNLOCKED; - } - else if (lock->lock == UNLOCKED) - { - fprintf(stderr, "error: lock not set\n"); - exit(1); - } - else - { - fprintf(stderr, "error: lock not initialized\n"); - exit(1); - } -} -int omp_test_lock(omp_lock_t *arg) + +int atlas_omp_get_num_threads(void) { -struct __omp_lock *lock = (struct __omp_lock *)arg; - if (lock->lock == UNLOCKED) - { - lock->lock = LOCKED; - return 1; - } - else if (lock->lock == LOCKED) - { - return 0; - } - else - { - fprintf(stderr, "error: lock not initialized\n"); - exit(1); - } - return -1; + return omp_get_num_threads ? omp_get_num_threads() : 1; } -struct __omp_nest_lock -{ - short owner; -short count; -}; -enum { NOOWNER = -1, MASTER = 0 }; -void omp_init_nest_lock(omp_nest_lock_t *arg) + +int atlas_omp_get_max_threads(void) { -struct __omp_nest_lock *nlock=(struct __omp_nest_lock *)arg; -nlock->owner = NOOWNER; - nlock->count = 0; + return omp_get_max_threads ? omp_get_max_threads() : 1; } -void omp_destroy_nest_lock(omp_nest_lock_t *arg) + +int atlas_omp_get_thread_num(void) { -struct __omp_nest_lock *nlock=(struct __omp_nest_lock *)arg; - nlock->owner = NOOWNER; - nlock->count = UNLOCKED; + return omp_get_thread_num ? omp_get_thread_num() : 0; } -void omp_set_nest_lock(omp_nest_lock_t *arg) + +int atlas_omp_get_num_procs(void) { -struct __omp_nest_lock *nlock=(struct __omp_nest_lock *)arg; - if (nlock->owner == MASTER && nlock->count >= 1) - { - nlock->count++; - } - else if (nlock->owner == NOOWNER && nlock->count == 0) - { - nlock->owner = MASTER; - nlock->count = 1; - } - else - { - fprintf(stderr, -"error: lock corrupted or not initialized\n"); - exit(1); - } + return omp_get_num_procs ? omp_get_num_procs() : 1; } -void omp_unset_nest_lock(omp_nest_lock_t *arg) + +int atlas_omp_in_parallel(void) { -struct __omp_nest_lock *nlock=(struct __omp_nest_lock *)arg; - if (nlock->owner == MASTER && nlock->count >= 1) - { - nlock->count--; - if (nlock->count == 0) - { - nlock->owner = NOOWNER; - } - } - else if (nlock->owner == NOOWNER && nlock->count == 0) - { - fprintf(stderr, "error: lock not set\n"); - exit(1); - } - else - { - fprintf(stderr, -"error: lock corrupted or not initialized\n"); - exit(1); - } + return omp_in_parallel ? omp_in_parallel() : 0; } -int omp_test_nest_lock(omp_nest_lock_t *arg) + +void atlas_omp_set_dynamic(int dynamic_threads) { -struct __omp_nest_lock *nlock=(struct __omp_nest_lock *)arg; - omp_set_nest_lock(arg); - return nlock->count; + if( omp_set_dynamic ) omp_set_dynamic(dynamic_threads); } -double omp_get_wtime(void) + +int atlas_omp_get_dynamic(void) { - throw eckit::NotImplemented("omp_get_wtime()\n" - "This function does not provide a working" - "wallclock ATLAS_TRACE();. Replace it with a version" - "customized for the target machine", Here() ); - return 0.0; + return omp_get_dynamic ? omp_get_dynamic() : 0; } -double omp_get_wtick(void) -{ - throw eckit::NotImplemented("omp_get_wtick()\n" - "This function does not provide a working" - "clock tick function. Replace it with" - "a version customized for the target machine.", Here() ); - return 365. * 86400.; +void atlas_omp_set_nested(int nested) +{ + if( omp_set_nested ) omp_set_nested(nested); } +int atlas_omp_get_nested(void) +{ + return omp_get_nested ? omp_get_nested() : 0; } -#endif - -#endif - -#endif diff --git a/src/atlas/parallel/omp/omp.h b/src/atlas/parallel/omp/omp.h index 6bbd10eaf..228c9f50c 100644 --- a/src/atlas/parallel/omp/omp.h +++ b/src/atlas/parallel/omp/omp.h @@ -8,62 +8,25 @@ * does it submit to any jurisdiction. */ -#ifndef atlas_omp_h -#define atlas_omp_h - -#include "atlas/library/config.h" - -#ifdef ATLAS_HAVE_OMP -#include -#else -/// Minimal set of stubs (see atlas_omp.cc) -inline void omp_set_num_threads(int num_threads) -{ -} -inline int omp_get_num_threads(void) -{ - return 1; -} -inline int omp_get_max_threads(void) -{ - return 1; -} -inline int omp_get_thread_num(void) -{ - return 0; -} -inline int omp_get_num_procs(void) -{ - return 1; -} -inline int omp_in_parallel(void) -{ - return 0; -} -inline void omp_set_dynamic(int dynamic_threads) -{ -} -inline int omp_get_dynamic(void) -{ - return 0; -} -inline void omp_set_nested(int nested) -{ -} -inline int omp_get_nested(void) -{ - return 0; -} - -#endif - -#define ATLAS_STR(x) #x -#define ATLAS_STRINGIFY(x) ATLAS_STR(x) -#define ATLAS_CONCATENATE(X,Y) X Y - -#ifdef ATLAS_HAVE_OMP +#pragma once + +void atlas_omp_set_num_threads(int num_threads); +int atlas_omp_get_num_threads(void); +int atlas_omp_get_max_threads(void); +int atlas_omp_get_thread_num(void); +int atlas_omp_get_num_procs(void); +int atlas_omp_in_parallel(void); +void atlas_omp_set_dynamic(int dynamic_threads); +int atlas_omp_get_dynamic(void); +void atlas_omp_set_nested(int nested); +int atlas_omp_get_nested(void); + + +#ifdef _OPENMP +#define __ATLAS_OMP_STR(x) #x +#define __ATLAS_OMP_STRINGIFY(x) __ATLAS_OMP_STR(x) #define atlas_omp_pragma(x) \ - _Pragma( ATLAS_STRINGIFY( x ) ) + _Pragma( __ATLAS_OMP_STRINGIFY( x ) ) #else #define atlas_omp_pragma(x) #endif @@ -74,23 +37,24 @@ inline int omp_get_nested(void) #define atlas_omp_critical atlas_omp_pragma(omp critical) template -class atlas_scoped_helper +class atlas_omp_scoped_helper { public: - atlas_scoped_helper(T p): value(p), once_(true) {} + atlas_omp_scoped_helper(T p): value(p), once_(true) {} bool once() const { return once_; } void done() { once_=false; } T value; private: bool once_; }; -#define atlas_scoped(T,VAR,VAL) \ - for( atlas_scoped_helper VAR(VAL); VAR.once(); VAR.done() ) + +#define __atlas_omp_scoped(T,VAR,VAL) \ + for( atlas_omp_scoped_helper VAR(VAL); VAR.once(); VAR.done() ) #define atlas_omp_critical_ordered \ - atlas_scoped(const size_t, _nthreads, omp_get_num_threads()) \ + __atlas_omp_scoped(const size_t, _nthreads, atlas_omp_get_num_threads()) \ atlas_omp_pragma( omp for ordered schedule(static,1) )\ for( size_t _thread=0; _thread<_nthreads.value; ++_thread )\ atlas_omp_pragma( omp ordered ) -#endif +#undef __atlas_omp_scoped From 57a17619ebf1cb0a5b242dbf3ce067586ed66d14 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 25 Jan 2018 12:24:30 +0000 Subject: [PATCH 272/355] ATLAS-146 Fix OpenMP stubs with clang --- src/atlas/parallel/omp/omp.cc | 65 ++++++++++++++++++++++++++--------- src/atlas/parallel/omp/omp.h | 4 ++- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/atlas/parallel/omp/omp.cc b/src/atlas/parallel/omp/omp.cc index 1d7d21152..0272164ec 100644 --- a/src/atlas/parallel/omp/omp.cc +++ b/src/atlas/parallel/omp/omp.cc @@ -13,18 +13,20 @@ #ifdef _OPENMP #include #else -extern void omp_set_num_threads(int num_threads); -extern int omp_get_num_threads(void); -extern int omp_get_max_threads(void); -extern int omp_get_thread_num(void); -extern int omp_get_num_procs(void); -extern int omp_in_parallel(void); -extern int omp_set_dynamic(int dynamic_threads); -extern int omp_get_dynamic(void); -extern void omp_set_nested(int nested); -extern int omp_get_nested(void); +extern "C" void omp_set_num_threads(int num_threads); +extern "C" int omp_get_num_threads(void); +extern "C" int omp_get_max_threads(void); +extern "C" int omp_get_thread_num(void); +extern "C" int omp_get_num_procs(void); +extern "C" int omp_in_parallel(void); +extern "C" int omp_set_dynamic(int dynamic_threads); +extern "C" int omp_get_dynamic(void); +extern "C" void omp_set_nested(int nested); +extern "C" int omp_get_nested(void); #endif +#ifdef ATLAS_HAVE_OMP +extern "C" { #pragma weak omp_set_num_threads #pragma weak omp_get_num_threads #pragma weak omp_get_max_threads @@ -35,54 +37,83 @@ extern int omp_get_nested(void); #pragma weak omp_get_dynamic #pragma weak omp_set_nested #pragma weak omp_get_nested +} +#endif void atlas_omp_set_num_threads(int num_threads) { +#ifdef ATLAS_HAVE_OMP if( omp_set_num_threads ) omp_set_num_threads(num_threads); +#endif } int atlas_omp_get_num_threads(void) { - return omp_get_num_threads ? omp_get_num_threads() : 1; +#ifdef ATLAS_HAVE_OMP + if( omp_get_num_threads ) return omp_get_num_threads(); +#endif + return 1; } int atlas_omp_get_max_threads(void) { - return omp_get_max_threads ? omp_get_max_threads() : 1; +#ifdef ATLAS_HAVE_OMP + if( omp_get_max_threads ) return omp_get_max_threads(); +#endif + return 1; } int atlas_omp_get_thread_num(void) { - return omp_get_thread_num ? omp_get_thread_num() : 0; +#ifdef ATLAS_HAVE_OMP + if( omp_get_thread_num ) return omp_get_thread_num(); +#endif + return 0; } int atlas_omp_get_num_procs(void) { - return omp_get_num_procs ? omp_get_num_procs() : 1; +#ifdef ATLAS_HAVE_OMP + if( omp_get_num_procs ) return omp_get_num_procs(); +#endif + return 1; } int atlas_omp_in_parallel(void) { - return omp_in_parallel ? omp_in_parallel() : 0; +#ifdef ATLAS_HAVE_OMP + if( omp_in_parallel ) return omp_in_parallel(); +#endif + return 0; } void atlas_omp_set_dynamic(int dynamic_threads) { +#ifdef ATLAS_HAVE_OMP if( omp_set_dynamic ) omp_set_dynamic(dynamic_threads); +#endif } int atlas_omp_get_dynamic(void) { - return omp_get_dynamic ? omp_get_dynamic() : 0; +#ifdef ATLAS_HAVE_OMP + if( omp_get_dynamic ) return omp_get_dynamic(); +#endif + return 0; } void atlas_omp_set_nested(int nested) { +#ifdef ATLAS_HAVE_OMP if( omp_set_nested ) omp_set_nested(nested); +#endif } int atlas_omp_get_nested(void) { - return omp_get_nested ? omp_get_nested() : 0; +#ifdef ATLAS_HAVE_OMP + if( omp_get_nested ) return omp_get_nested(); +#endif + return 0; } diff --git a/src/atlas/parallel/omp/omp.h b/src/atlas/parallel/omp/omp.h index 228c9f50c..de7f7a069 100644 --- a/src/atlas/parallel/omp/omp.h +++ b/src/atlas/parallel/omp/omp.h @@ -10,6 +10,8 @@ #pragma once +#include "atlas/library/config.h" + void atlas_omp_set_num_threads(int num_threads); int atlas_omp_get_num_threads(void); int atlas_omp_get_max_threads(void); @@ -22,7 +24,7 @@ void atlas_omp_set_nested(int nested); int atlas_omp_get_nested(void); -#ifdef _OPENMP +#ifdef ATLAS_HAVE_OMP #define __ATLAS_OMP_STR(x) #x #define __ATLAS_OMP_STRINGIFY(x) __ATLAS_OMP_STR(x) #define atlas_omp_pragma(x) \ From da98b6f91595eb59fbde3b66755925ee905552f6 Mon Sep 17 00:00:00 2001 From: Tiago Quintino Date: Thu, 25 Jan 2018 13:11:42 +0000 Subject: [PATCH 273/355] Fix bamboo leap42 --- bamboo/CLANG-env.sh | 6 +++++- bamboo/INTEL-env.sh | 1 + bamboo/{opensuse131-env.sh => leap42-env.sh} | 0 bamboo/{opensuse131-flags.cmake => leap42-flags.cmake} | 0 4 files changed, 6 insertions(+), 1 deletion(-) rename bamboo/{opensuse131-env.sh => leap42-env.sh} (100%) rename bamboo/{opensuse131-flags.cmake => leap42-flags.cmake} (100%) diff --git a/bamboo/CLANG-env.sh b/bamboo/CLANG-env.sh index 231bea37e..94f039c9e 100644 --- a/bamboo/CLANG-env.sh +++ b/bamboo/CLANG-env.sh @@ -6,4 +6,8 @@ if [[ ! $(command -v module > /dev/null 2>&1) ]]; then fi module unload grib_api module unload eccodes -module switch gnu clang/3.6.2 +module unload emos +module unload fftw +module unload libemos + +module switch gnu clang diff --git a/bamboo/INTEL-env.sh b/bamboo/INTEL-env.sh index 797aadb3d..84571e0fb 100644 --- a/bamboo/INTEL-env.sh +++ b/bamboo/INTEL-env.sh @@ -8,4 +8,5 @@ module unload eccodes module unload emos module unload fftw module unload libemos + module switch gnu intel/16.0.3 diff --git a/bamboo/opensuse131-env.sh b/bamboo/leap42-env.sh similarity index 100% rename from bamboo/opensuse131-env.sh rename to bamboo/leap42-env.sh diff --git a/bamboo/opensuse131-flags.cmake b/bamboo/leap42-flags.cmake similarity index 100% rename from bamboo/opensuse131-flags.cmake rename to bamboo/leap42-flags.cmake From affccad03bb36a10856b5854cd1dac91a5ec0b2f Mon Sep 17 00:00:00 2001 From: Tiago Quintino Date: Thu, 25 Jan 2018 13:55:15 +0000 Subject: [PATCH 274/355] Fix bamboo leap42 link fail to boost/cgal --- bamboo/leap42-flags.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/bamboo/leap42-flags.cmake b/bamboo/leap42-flags.cmake index 3c609675f..c3167eda8 100644 --- a/bamboo/leap42-flags.cmake +++ b/bamboo/leap42-flags.cmake @@ -3,3 +3,4 @@ set( ENABLE_MPI OFF CACHE BOOL "Disable MPI" ) set( ENABLE_TRANS ON CACHE BOOL "Enable TRANS" ) set( ENABLE_ATLAS_TEST_GRIDSPEC ON CACHE BOOL "Enable atlas_test_gridspec") set( ENABLE_BOUNDSCHECKING ON CACHE BOOL "Enable bounds checking") +set( ENABLE_TESSELATION OFF CACHE BOOL "Disable CGAL" ) # cgal is old in leap42 From cf566d3bdd9770703bb799b0b74e5c0475ef7fe2 Mon Sep 17 00:00:00 2001 From: Tiago Quintino Date: Thu, 25 Jan 2018 15:17:32 +0000 Subject: [PATCH 275/355] Fix bamboo leap42 again --- bamboo/CLANG-env.sh | 1 + bamboo/CLANG-flags.cmake | 1 + bamboo/INTEL-flags.cmake | 1 + 3 files changed, 3 insertions(+) diff --git a/bamboo/CLANG-env.sh b/bamboo/CLANG-env.sh index 94f039c9e..600367f14 100644 --- a/bamboo/CLANG-env.sh +++ b/bamboo/CLANG-env.sh @@ -4,6 +4,7 @@ if [[ ! $(command -v module > /dev/null 2>&1) ]]; then . /usr/local/apps/module/init/bash fi + module unload grib_api module unload eccodes module unload emos diff --git a/bamboo/CLANG-flags.cmake b/bamboo/CLANG-flags.cmake index f9725b61f..260e632c3 100644 --- a/bamboo/CLANG-flags.cmake +++ b/bamboo/CLANG-flags.cmake @@ -3,3 +3,4 @@ set( ENABLE_MPI OFF CACHE BOOL "Disable MPI under Clang compilat set( ENABLE_TRANS ON CACHE BOOL "Enable TRANS" ) set( ENABLE_ATLAS_TEST_GRIDSPEC ON CACHE BOOL "Enable atlas_test_gridspec") set( ENABLE_BOUNDSCHECKING ON CACHE BOOL "Enable bounds checking") +set( ENABLE_TESSELATION OFF CACHE BOOL "Disable CGAL" ) # cgal is old in leap42 diff --git a/bamboo/INTEL-flags.cmake b/bamboo/INTEL-flags.cmake index 5e5ba3d69..f869c68d8 100644 --- a/bamboo/INTEL-flags.cmake +++ b/bamboo/INTEL-flags.cmake @@ -3,3 +3,4 @@ set( ENABLE_MPI OFF CACHE BOOL "Disable MPI under Intel compilat set( ENABLE_TRANS ON CACHE BOOL "Enable TRANS" ) set( ENABLE_ATLAS_TEST_GRIDSPEC ON CACHE BOOL "Enable atlas_test_gridspec") set( ENABLE_BOUNDSCHECKING ON CACHE BOOL "Enable bounds checking") +set( ENABLE_TESSELATION OFF CACHE BOOL "Disable CGAL" ) # cgal is old in leap42 From 3ee4344a95ec57183e85db9a010cb21dad227dbd Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 25 Jan 2018 16:56:15 +0000 Subject: [PATCH 276/355] Don't try to link with fckit if ENABLE_FORTRAN=OFF --- CMakeLists.txt | 4 +++- bamboo/CLANG-env.sh | 1 - bamboo/CLANG-flags.cmake | 2 -- bamboo/INTEL-env.sh | 1 - bamboo/INTEL-flags.cmake | 1 - bamboo/flags.cmake | 1 - bamboo/leap42-flags.cmake | 2 -- src/atlas/functionspace/EdgeColumns.cc | 2 +- src/tests/functionspace/fctest_functionspace.F90 | 8 ++++++++ 9 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index da341837f..6bb9f97a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,9 +66,11 @@ if( ATLAS_HAVE_FORTRAN ) ecbuild_warn( "In order to compile atlas_f, fckit is required to be compiled with eckit. Turning off fortran." ) set( HAVE_FORTRAN 0 ) set( ATLAS_HAVE_FORTRAN 0 ) + unset( FCKIT_LIBRARIES ) endif() - +else() + unset( FCKIT_LIBRARIES ) endif() ### MPI ... diff --git a/bamboo/CLANG-env.sh b/bamboo/CLANG-env.sh index 600367f14..33c46d1dc 100644 --- a/bamboo/CLANG-env.sh +++ b/bamboo/CLANG-env.sh @@ -5,7 +5,6 @@ if [[ ! $(command -v module > /dev/null 2>&1) ]]; then . /usr/local/apps/module/init/bash fi -module unload grib_api module unload eccodes module unload emos module unload fftw diff --git a/bamboo/CLANG-flags.cmake b/bamboo/CLANG-flags.cmake index 260e632c3..2fbdcb741 100644 --- a/bamboo/CLANG-flags.cmake +++ b/bamboo/CLANG-flags.cmake @@ -1,6 +1,4 @@ # don't use trans library until it supports build without MPI -set( ENABLE_MPI OFF CACHE BOOL "Disable MPI under Clang compilation" ) set( ENABLE_TRANS ON CACHE BOOL "Enable TRANS" ) -set( ENABLE_ATLAS_TEST_GRIDSPEC ON CACHE BOOL "Enable atlas_test_gridspec") set( ENABLE_BOUNDSCHECKING ON CACHE BOOL "Enable bounds checking") set( ENABLE_TESSELATION OFF CACHE BOOL "Disable CGAL" ) # cgal is old in leap42 diff --git a/bamboo/INTEL-env.sh b/bamboo/INTEL-env.sh index 84571e0fb..b9fb01587 100644 --- a/bamboo/INTEL-env.sh +++ b/bamboo/INTEL-env.sh @@ -3,7 +3,6 @@ if [[ ! $(command -v module > /dev/null 2>&1) ]]; then . /usr/local/apps/module/init/bash fi # unload modules not available for intel -module unload grib_api module unload eccodes module unload emos module unload fftw diff --git a/bamboo/INTEL-flags.cmake b/bamboo/INTEL-flags.cmake index f869c68d8..b3a645475 100644 --- a/bamboo/INTEL-flags.cmake +++ b/bamboo/INTEL-flags.cmake @@ -1,6 +1,5 @@ # don't use trans library until it supports build without MPI set( ENABLE_MPI OFF CACHE BOOL "Disable MPI under Intel compilation" ) set( ENABLE_TRANS ON CACHE BOOL "Enable TRANS" ) -set( ENABLE_ATLAS_TEST_GRIDSPEC ON CACHE BOOL "Enable atlas_test_gridspec") set( ENABLE_BOUNDSCHECKING ON CACHE BOOL "Enable bounds checking") set( ENABLE_TESSELATION OFF CACHE BOOL "Disable CGAL" ) # cgal is old in leap42 diff --git a/bamboo/flags.cmake b/bamboo/flags.cmake index 1bb3fc51b..7cbfaf36a 100644 --- a/bamboo/flags.cmake +++ b/bamboo/flags.cmake @@ -12,5 +12,4 @@ #set(CMAKE_Fortran_LINK_FLAGS "-L/usr/local/apps/gcc/4.8.1/LP64/lib/gcc/x86_64-suse-linux/4.8.1/") #link_directories("/usr/local/apps/gcc/4.8.1/LP64/lib/gcc/x86_64-suse-linux/4.8.1/") -SET(ENABLE_MPI OFF CACHE BOOL "Disable MPI") SET(ENABLE_SANDBOX OFF CACHE BOOL "Disable sandbox") diff --git a/bamboo/leap42-flags.cmake b/bamboo/leap42-flags.cmake index c3167eda8..2fbdcb741 100644 --- a/bamboo/leap42-flags.cmake +++ b/bamboo/leap42-flags.cmake @@ -1,6 +1,4 @@ # don't use trans library until it supports build without MPI -set( ENABLE_MPI OFF CACHE BOOL "Disable MPI" ) set( ENABLE_TRANS ON CACHE BOOL "Enable TRANS" ) -set( ENABLE_ATLAS_TEST_GRIDSPEC ON CACHE BOOL "Enable atlas_test_gridspec") set( ENABLE_BOUNDSCHECKING ON CACHE BOOL "Enable bounds checking") set( ENABLE_TESSELATION OFF CACHE BOOL "Disable CGAL" ) # cgal is old in leap42 diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 042173726..3ce1e32bf 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -151,7 +151,7 @@ EdgeColumns::EdgeColumns( const Mesh& mesh, const eckit::Configuration ¶ms ) { nb_levels_ = config_levels(params); - size_t mesh_halo; + size_t mesh_halo(0); mesh.metadata().get("halo",mesh_halo); size_t halo = mesh_halo; diff --git a/src/tests/functionspace/fctest_functionspace.F90 b/src/tests/functionspace/fctest_functionspace.F90 index ec1a40854..67796c11a 100644 --- a/src/tests/functionspace/fctest_functionspace.F90 +++ b/src/tests/functionspace/fctest_functionspace.F90 @@ -130,6 +130,8 @@ module fcta_FunctionSpace_fxt call fs%final() call mesh%final() call grid%final() +#else +#warning test test_nodes disabled #endif END_TEST @@ -238,6 +240,8 @@ module fcta_FunctionSpace_fxt FCTEST_CHECK_EQUAL( grid%owners(), 1 ) call grid%final() +#else +#warning test test_nodescolumns disabled #endif END_TEST @@ -481,6 +485,8 @@ module fcta_FunctionSpace_fxt call edges%final() call mesh%final() call grid%final() +#else +#warning test test_edges disabled #endif END_TEST @@ -544,6 +550,8 @@ module fcta_FunctionSpace_fxt call fs%final() call fs_base%final() call grid%final() +#else +#warning test test_structuredcolumns disabled #endif END_TEST From a427cdb6411b2b83318285dfff36c4cf35e81296 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Mon, 29 Jan 2018 17:07:13 +0000 Subject: [PATCH 277/355] ATLAS-135 vd2uv implemented. Seems to work. Still sometimes an issue with mutex when running ctest transgeneral --- src/atlas/trans/local/TransLocal.cc | 173 ++----------- src/atlas/trans/local/VorDivToUVLocal.cc | 140 +++++++++- src/tests/trans/test_trans.cc | 19 +- src/tests/trans/test_transgeneral.cc | 311 +++++++++++++++-------- 4 files changed, 381 insertions(+), 262 deletions(-) diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 83af7763a..9e34a404c 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -17,7 +17,8 @@ #include "atlas/trans/local/FourierTransforms.h" #include "atlas/trans/local/LegendreTransforms.h" #include "atlas/trans/local/LegendrePolynomials.h" -#include "atlas/util/Earth.h" +#include "atlas/trans/VorDivToUV.h" +#include "atlas/option.h" namespace atlas { namespace trans { @@ -203,13 +204,11 @@ void TransLocal::invtrans_uv( for( size_t i=0; i U(nb_vordiv_spec,0.); + std::vector V(nb_vordiv_spec,0.); + trans::VorDivToUV vordiv_to_UV(truncation_, option::type("local")); + vordiv_to_UV.execute( nb_vordiv_spec, nb_vordiv_fields, vorticity_spectra, divergence_spectra, U.data(), V.data() ); // perform spectral transform to compute all fields in grid point space - invtrans_uv(nb_all_fields, nb_vordiv_fields, all_spectra, gp_fields, config); + invtrans_uv(nb_vordiv_fields, nb_vordiv_fields, U.data(), gp_fields, config); + invtrans_uv(nb_vordiv_fields, nb_vordiv_fields, V.data(), gp_fields+nb_gp, config); + invtrans_uv(nb_scalar_fields, 0, scalar_spectra, gp_fields+2*nb_gp, config); } diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index 041964366..83630968c 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -12,6 +12,7 @@ #include "atlas/functionspace/Spectral.h" #include "atlas/runtime/Log.h" +#include "atlas/util/Earth.h" using atlas::functionspace::Spectral; using atlas::FunctionSpace; @@ -23,12 +24,149 @@ namespace { static VorDivToUVBuilder builder("local"); } +// -------------------------------------------------------------------------------------------------------------------- +void prfi1b( + const int truncation, + const int km, // zonal wavenumber + const int nb_fields, // number of fields + const double rspec[], // spectral data + double pia[]) // spectral components in data layout of trans library +{ + int ilcm = truncation+1-km, ioff = (2*truncation-km+3)*km, nlei1 = truncation+4+(truncation+4+1)%2; + for( int j=1; j<=ilcm; j++ ) { + int inm = ioff+(ilcm-j)*2; + for( int jfld=0; jfld repsnm((truncation+1)*(truncation+6)/2); + std::vector rlapin(truncation+3); + int idx = 0; + for( int jm=0; jm<=truncation; ++jm ) { + for( int jn=jm; jn<=truncation+2; ++jn, ++idx ) { + repsnm[idx] = std::sqrt((jn*jn-jm*jm)/(4.*jn*jn-1.)); + } + } + repsnm[0] = 0.; + for( int jn=1; jn<=truncation+2; ++jn ) { + rlapin[jn] = -util::Earth::radiusInMeters()*util::Earth::radiusInMeters()/(jn*(jn+1.)); + } + rlapin[0] = 0.; + std::vector zepsnm(truncation+6); + std::vector zlapin(truncation+6); + std::vector zn (truncation+6); + for( int jn=km-1; jn<=truncation+2; ++jn ) { + int ij = truncation+3-jn; + if( jn>=0 ) { + zlapin[ij] = rlapin[jn]; + if ( jn truncation_array{159,160,1279}; + int nfld = 1; // TODO: test for nfld>1 + std::vector truncation_array{1};// truncation_array{159,160,1279}; for( int i=0; i field_div( nfld*nspec2, 0. ); // TODO: initialise field_vor and field_div with something meaningful + field_vor[4*nfld] = 1.; + Log::info() << "vor: " << std::endl; + for( int j=0; j field_U ( nfld*nspec2 ); std::vector field_V ( nfld*nspec2 ); - // TODO: - // vordiv_to_UV.execute( nspec2, nfld, field_vor.data(), field_div.data(), field_U.data(), field_V.data() ); + vordiv_to_UV.execute( nspec2, nfld, field_vor.data(), field_div.data(), field_U.data(), field_V.data() ); // TODO: do some meaningful checks + Log::info() << "Local transform" << std::endl; + Log::info() << "U: " << std::endl; + for( int j=0; j0 ) rft *= 2.; // the famous factor 2 that noone really understands if( imag==0 ) { - rft *= std::cos(m*lon); + rft *= loncos; } else { - rft *= -std::sin(m*lon); + rft *= -lonsin; } // Legendre part of the spherical harmonics (following http://mathworld.wolfram.com/SphericalHarmonic.html // multiplied with -2*sqrt(pi) due to different normalization and different coordinates): @@ -227,28 +231,110 @@ double sphericalharmonics_analytic_point( // LegendreP[n, m, x]/Sqrt[1/2*Integrate[LegendreP[n, m, y]^2, {y, -1, 1}]]) // n, m need to be replaced by hand with the correct values // (otherwise the command will be too long for the free version of wolframalpha) - 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==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==45 && n==45 ) - return std::pow(latcos,45)*rft*21.*std::sqrt(1339044123748208678378695.)/8796093022208.; // sign? + + // 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==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==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==45 && n==45 ) + return std::pow(latcos,45)*rft*21.*std::sqrt(1339044123748208678378695.)/8796093022208.; // sign? + } else { + return 0.; + } + } + + // for the remainder the factor 2 from rft is already included in the formulas: + + // vorticity: + if ( ivar_in==0 ) { + if ( ivar_out==0 ) { // u: + if ( m==0 && n==0 ) + return 0.; + if ( m==0 && n==1 ) { + 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; + } 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==1 && n==1 ) { + if ( imag==0 ) { + return a*std::sqrt(3./2.)*lonsin; + } else { + return a*std::sqrt(3./2.)*loncos; + } + } + } else { + return 0.; + } + } + + // 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==1 && n==1 ) { + 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==1 ) { + 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; + } else { + return -a*std::sqrt(3./2.)*lonsin*latsin; // sign? + } + } + } else { + return 0.; + } + } return -1.; } @@ -263,14 +349,14 @@ double sphericalharmonics_analytic_point( void spectral_transform_grid_analytic( const size_t trc, // truncation (in) const size_t trcFT, // truncation for Fourier transformation (in) - const int nb_scalar, - const int nb_vordiv, const double n, // total wave number (implemented so far for n<4 const double m, // zonal wave number (implemented so far for m<4, m 1.e-15 ) { + if( rms > 2.e-15 ) { out << " !!!!" << std::endl; for( int jp=0; jp sp = array::make_view(spf); sp.assign(0.); @@ -527,7 +616,7 @@ CASE( "test_transgeneral_with_translib" ) EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); - spectral_transform_grid_analytic(trc, trc, 1, 0, n, m, imag, g, rspecg.data(), rgp_analytic.data()); + spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data(), 2, 2); // compute spectral transform with the general transform: spectral_transform_grid(trc, trc, g, sp.data(), rgp.data(), false); @@ -569,66 +658,86 @@ CASE( "test_trans_vordiv_with_translib" ) functionspace::StructuredColumns gridpoints (g); int nb_scalar = 1, nb_vordiv = 1; - int N = (trc+2)*(trc+1)/2, nb_all = nb_scalar+4*nb_vordiv; - double sp [2*N ]; - double vor [2*N ]; - double div [2*N ]; - double rspecg [2*N ]; + int N = (trc+2)*(trc+1)/2, nb_all = nb_scalar+2*nb_vordiv; + double sp [2*N]; + double vor [2*N]; + double div [2*N]; + double rspecg [2*N]; double gp [nb_all*g.size()]; double rgp [nb_all*g.size()]; - double rgp_analytic [nb_all*g.size()]; - - int k = 0; - for( int m=0; m<=trc; m++ ) { // zonal wavenumber - for( int n=m; n<=trc; n++ ) { // total wavenumber - for( int imag=0; imag<=1; imag++ ) { // real and imaginary part - - if( sphericalharmonics_analytic_point(n, m, true, 0., 0.) == 0. ) { - - for( int j=0; j<2*N; j++ ) { - sp [j] = 0.; - vor[j] = 0.; - div[j] = 0.; - } - sp[k] = 1.; - - for( int j=0; j= tolerance ) { + ATLAS_DEBUG_VAR(rms_gen); + ATLAS_DEBUG_VAR(tolerance); + //} + //if( rms_trans >= tolerance ) { + ATLAS_DEBUG_VAR(rms_trans); + ATLAS_DEBUG_VAR(tolerance); + //} + EXPECT( rms_trans < tolerance ); + // local transformation truncates the spectral U,V to trc! This is different from + // the analytic solution and trans library's invtrans! + bool invalid = ( ivar_in<2 && ivar_out<2 && n==trc ); + if( !invalid ) EXPECT( rms_gen < tolerance ); + icase++; + } + k++; } - - EXPECT_NO_THROW( trans.invtrans( nb_scalar, sp, nb_vordiv, vor, div, gp ) ); - - spectral_transform_grid_analytic(trc, trc, nb_scalar, nb_vordiv, n, m, imag, g, rspecg, rgp_analytic); - - // compute spectral transform with the general transform: - //EXPECT_NO_THROW( spectral_transform_grid(trc, trc, g, sp, rgp, false) ); - //EXPECT_NO_THROW( transLocal.invtrans( nb_scalar, sp, rgp) ); - EXPECT_NO_THROW( transLocal.invtrans( nb_scalar, sp, nb_vordiv, vor, div, rgp) ); - Log::info() << "Trans library: m=" << m << " n=" << n << " imag=" << imag << std::endl; - for( int j=0; j= tolerance ) { - ATLAS_DEBUG_VAR(rms_gen); - ATLAS_DEBUG_VAR(tolerance); - //} - //if( rms_trans >= tolerance ) { - ATLAS_DEBUG_VAR(rms_trans); - ATLAS_DEBUG_VAR(tolerance); - //} - //EXPECT( rms_gen < tolerance ); - //EXPECT( rms_trans < tolerance ); } - k++; } } } From 8ec559dd7a0945ea347fe5065217f93bc96aa5f1 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Mon, 29 Jan 2018 18:52:26 +0000 Subject: [PATCH 278/355] ATLAS-135 fixed segfault in VorDivToUVLocal.cc --- src/atlas/trans/VorDivToUV.h | 4 ++-- src/atlas/trans/local/VorDivToUVLocal.cc | 2 +- src/tests/trans/test_trans.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/atlas/trans/VorDivToUV.h b/src/atlas/trans/VorDivToUV.h index c7a5165ea..ee2febbfb 100644 --- a/src/atlas/trans/VorDivToUV.h +++ b/src/atlas/trans/VorDivToUV.h @@ -77,8 +77,8 @@ class VorDivToUVFactory { * \brief build VorDivToUV * \return VorDivToUVImpl */ - static VorDivToUVImpl* build( const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); - static VorDivToUVImpl* build( int truncation, const eckit::Configuration& = util::Config() ); + static VorDivToUVImpl* build( const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); + static VorDivToUVImpl* build( int truncation, const eckit::Configuration& = util::NoConfig() ); /*! * \brief list all registered trans implementations diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index 83630968c..b1f097b02 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -145,7 +145,7 @@ void vd2uv( int inm = ioff+(ilcm-j)*2; for( int jfld=0; jfld field_div( nfld*nspec2, 0. ); // TODO: initialise field_vor and field_div with something meaningful - field_vor[4*nfld] = 1.; + field_vor[2*nfld] = 1.; Log::info() << "vor: " << std::endl; for( int j=0; j Date: Tue, 30 Jan 2018 15:06:36 +0000 Subject: [PATCH 279/355] ATLAS-135 minor bug fixes and clean-up --- src/atlas/trans/local/VorDivToUVLocal.cc | 8 ++--- src/tests/trans/test_transgeneral.cc | 43 ++++++++++++------------ 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index b1f097b02..87eff01de 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -103,7 +103,7 @@ void vd2uv( std::vector rv (2*nb_vordiv_fields*nlei1); prfi1b(truncation, km, nb_vordiv_fields, vorticity_spectra, rvor.data()); prfi1b(truncation, km, nb_vordiv_fields, divergence_spectra, rdiv.data()); -//Log::info() << "nlei1=" << nlei1 << std::endl; + if( km==0 ) { for( int jfld=0; jfld 2.e-15 ) { out << " !!!!" << std::endl; for( int jp=0; jp sp (2*N); + std::vector vor (2*N); + std::vector div (2*N); + std::vector rspecg (2*N); double gp [nb_all*g.size()]; double rgp [nb_all*g.size()]; double rgp_analytic [g.size()]; @@ -697,37 +697,37 @@ CASE( "test_trans_vordiv_with_translib" ) rgp_analytic[j] = 0.; } - spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg, rgp_analytic, ivar_in, ivar_out); - Log::info() << "Case " << icase << " Analytic solution: ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; + spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic, ivar_in, ivar_out); + /*Log::info() << "Case " << icase << " Analytic solution: ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; for( int j=0; j= tolerance ) { + if( rms_gen >= tolerance ) { ATLAS_DEBUG_VAR(rms_gen); ATLAS_DEBUG_VAR(tolerance); - //} - //if( rms_trans >= tolerance ) { + } + if( rms_trans >= tolerance ) { ATLAS_DEBUG_VAR(rms_trans); ATLAS_DEBUG_VAR(tolerance); - //} + } EXPECT( rms_trans < tolerance ); // local transformation truncates the spectral U,V to trc! This is different from // the analytic solution and trans library's invtrans! @@ -741,6 +741,7 @@ CASE( "test_trans_vordiv_with_translib" ) } } } + Log::info() << "Vordiv+scalar comparison with trans: all " << icase << " cases successfully passed!" << std::endl; } //----------------------------------------------------------------------------- From bc6560c6e2754c939318b427ada1dff0bcf81070 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Tue, 30 Jan 2018 19:28:40 +0000 Subject: [PATCH 280/355] ATLAS-135 transposition of grid point fields implemented. test_trans_vordiv_with_translib currently commented out due to some memory issue --- src/atlas/trans/local/TransLocal.cc | 26 +++++- src/tests/trans/test_transgeneral.cc | 130 ++++++++++++++------------- 2 files changed, 91 insertions(+), 65 deletions(-) diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 9e34a404c..1228f2705 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -40,6 +40,19 @@ int fourier_truncation( double truncation, double lat ) { return truncation; } +void gp_transpose( + const int nb_size, + const int nb_fields, + const double gp_tmp[], + double gp_fields[] ) +{ + for( int jgp=0; jgp legReal(nb_fields*(truncation_+1)); std::vector legImag(nb_fields*(truncation_+1)); + std::vector gp_tmp(nb_fields*grid_.size(), 0.); // Transform if( grid::StructuredGrid g = grid_ ) { @@ -203,9 +217,9 @@ void TransLocal::invtrans_uv( // Fourier transform: for( size_t i=0; i sp (2*N); - std::vector vor (2*N); - std::vector div (2*N); + std::vector sp (2*N*nb_scalar); + std::vector vor (2*N*nb_vordiv); + std::vector div (2*N*nb_vordiv); std::vector rspecg (2*N); - double gp [nb_all*g.size()]; - double rgp [nb_all*g.size()]; - double rgp_analytic [g.size()]; + std::vector gp (nb_all*g.size()); + std::vector rgp (nb_all*g.size()); + std::vector rgp_analytic (g.size()); int icase = 0; - for( int ivar_in=0; ivar_in<3; ivar_in++ ) { // vorticity, divergence, scalar + /*for( int ivar_in=0; ivar_in<3; ivar_in++ ) { // vorticity, divergence, scalar for( int ivar_out=0; ivar_out<3; ivar_out++ ) { // u, v, scalar if( ivar_out==2) { tolerance = 1.e-13; + nb_fld = nb_scalar; } else { tolerance = 1.e-4; + nb_fld = nb_vordiv; } int k = 0; for( int m=0; m<=trc; m++ ) { // zonal wavenumber @@ -682,57 +684,63 @@ CASE( "test_trans_vordiv_with_translib" ) if( sphericalharmonics_analytic_point(n, m, true, 0., 0., ivar_in, ivar_in) == 0. ) { - for( int j=0; j<2*N; j++ ) { - sp [j] = 0.; - vor[j] = 0.; - div[j] = 0.; - } - if( ivar_in==0 ) vor[k] = 1.; - if( ivar_in==1 ) div[k] = 1.; - if( ivar_in==2 ) sp [k] = 1.; - - for( int j=0; j= tolerance ) { + ATLAS_DEBUG_VAR(rms_gen); + ATLAS_DEBUG_VAR(tolerance); + } + if( rms_trans >= tolerance ) { + ATLAS_DEBUG_VAR(rms_trans); + ATLAS_DEBUG_VAR(tolerance); + } + EXPECT( rms_trans < tolerance ); + // local transformation truncates the spectral U,V to trc! This is different from + // the analytic solution and trans library's invtrans! + bool invalid = ( ivar_in<2 && ivar_out<2 && n==trc ); + //if( !invalid ) EXPECT( rms_gen < tolerance ); } - - spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic, ivar_in, ivar_out); - /*Log::info() << "Case " << icase << " Analytic solution: ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; - for( int j=0; j= tolerance ) { - ATLAS_DEBUG_VAR(rms_gen); - ATLAS_DEBUG_VAR(tolerance); - } - if( rms_trans >= tolerance ) { - ATLAS_DEBUG_VAR(rms_trans); - ATLAS_DEBUG_VAR(tolerance); - } - EXPECT( rms_trans < tolerance ); - // local transformation truncates the spectral U,V to trc! This is different from - // the analytic solution and trans library's invtrans! - bool invalid = ( ivar_in<2 && ivar_out<2 && n==trc ); - if( !invalid ) EXPECT( rms_gen < tolerance ); icase++; } k++; @@ -740,7 +748,7 @@ CASE( "test_trans_vordiv_with_translib" ) } } } - } + }*/ Log::info() << "Vordiv+scalar comparison with trans: all " << icase << " cases successfully passed!" << std::endl; } From 0a526d7ea83c61c89557a490b2f3a582f90fafa8 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Wed, 31 Jan 2018 16:55:32 +0000 Subject: [PATCH 281/355] ATLAS-135 transformation with multiple vorticity, divergence and/or scalar fields works now. test_trans_vordiv_with_translib works again correctly. Currently no known issues. --- src/atlas/trans/local/TransLocal.cc | 40 ++++++++------ src/atlas/trans/local/VorDivToUVLocal.cc | 11 ++-- src/tests/trans/test_transgeneral.cc | 67 +++++++++++++----------- 3 files changed, 66 insertions(+), 52 deletions(-) diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 1228f2705..afbfa4d4a 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -40,19 +40,6 @@ int fourier_truncation( double truncation, double lat ) { return truncation; } -void gp_transpose( - const int nb_size, - const int nb_fields, - const double gp_tmp[], - double gp_fields[] ) -{ - for( int jgp=0; jgp sp (2*N*nb_scalar); std::vector vor (2*N*nb_vordiv); @@ -668,7 +668,7 @@ CASE( "test_trans_vordiv_with_translib" ) std::vector rgp_analytic (g.size()); int icase = 0; - /*for( int ivar_in=0; ivar_in<3; ivar_in++ ) { // vorticity, divergence, scalar + for( int ivar_in=0; ivar_in<3; ivar_in++ ) { // vorticity, divergence, scalar for( int ivar_out=0; ivar_out<3; ivar_out++ ) { // u, v, scalar if( ivar_out==2) { tolerance = 1.e-13; @@ -677,14 +677,14 @@ CASE( "test_trans_vordiv_with_translib" ) tolerance = 1.e-4; nb_fld = nb_vordiv; } - int k = 0; - for( int m=0; m<=trc; m++ ) { // zonal wavenumber - for( int n=m; n<=trc; n++ ) { // total wavenumber - for( int imag=0; imag<=1; imag++ ) { // real and imaginary part + for( int jfld=0; jfld= tolerance ) { - ATLAS_DEBUG_VAR(rms_gen); - ATLAS_DEBUG_VAR(tolerance); - } - if( rms_trans >= tolerance ) { - ATLAS_DEBUG_VAR(rms_trans); - ATLAS_DEBUG_VAR(tolerance); - } - EXPECT( rms_trans < tolerance ); // local transformation truncates the spectral U,V to trc! This is different from // the analytic solution and trans library's invtrans! bool invalid = ( ivar_in<2 && ivar_out<2 && n==trc ); - //if( !invalid ) EXPECT( rms_gen < tolerance ); + + if( !invalid ) { + if( rms_gen >= tolerance ) { + ATLAS_DEBUG_VAR(rms_gen); + ATLAS_DEBUG_VAR(tolerance); + } + if( rms_trans >= tolerance ) { + ATLAS_DEBUG_VAR(rms_trans); + ATLAS_DEBUG_VAR(tolerance); + } + EXPECT( rms_trans < tolerance ); + EXPECT( rms_gen < tolerance ); + } + icase++; } - icase++; + k++; } - k++; } } } } - }*/ + } Log::info() << "Vordiv+scalar comparison with trans: all " << icase << " cases successfully passed!" << std::endl; } From 028206d67e0b79529565bbbce8cac094c459a718 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 1 Feb 2018 18:23:22 +0000 Subject: [PATCH 282/355] Fix dual setup of trans for TransPartitioner --- src/atlas/trans/ifs/TransIFS.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index 4fd0e94c7..d9d01ca10 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -755,7 +755,6 @@ TransIFS::TransIFS( const Grid& grid, const long truncation, const eckit::Config TransIFS( Cache(), grid, truncation, config ) { ASSERT( grid.domain().global() ); ASSERT( not grid.projection() ); - ctor( grid, truncation, config ); } TransIFS::TransIFS(const Grid& grid, const eckit::Configuration& config ) : @@ -805,6 +804,7 @@ void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const for( long jlat=0; jlat1)); TRANS_CHECK(::trans_set_resol(trans_.get(),nlat,nloen.data())); if( truncation >= 0 ) TRANS_CHECK(::trans_set_trunc(trans_.get(),truncation)); @@ -830,7 +830,6 @@ void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const trans_->lsplit = p.split_latitudes(); trans_->flt = p.flt(); - TRANS_CHECK(::trans_use_mpi(parallel::mpi::comm().size()>1)); TRANS_CHECK(::trans_setup(trans_.get())); } @@ -838,6 +837,7 @@ void TransIFS::ctor_lonlat(const long nlon, const long nlat, long truncation, co { TransParameters p(*this,config); TRANS_CHECK(::trans_new(trans_.get())); + TRANS_CHECK(::trans_use_mpi(parallel::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)); @@ -861,7 +861,6 @@ void TransIFS::ctor_lonlat(const long nlon, const long nlat, long truncation, co trans_->lsplit = p.split_latitudes(); trans_->flt = p.flt(); - TRANS_CHECK(::trans_use_mpi(parallel::mpi::comm().size()>1)); TRANS_CHECK(::trans_setup(trans_.get())); } From 61a3066ddbd06f6b632744e43dda2e7fb99e437e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 2 Feb 2018 10:34:54 +0000 Subject: [PATCH 283/355] More macros for debugging --- src/atlas/CMakeLists.txt | 1 + src/atlas/runtime/Log.cc | 49 ++++++++++++++++++++++++++++++++++++++++ src/atlas/runtime/Log.h | 14 +++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/atlas/runtime/Log.cc diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 8c25f43da..04f0f39c7 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -33,6 +33,7 @@ runtime/ErrorHandling.cc runtime/AtlasTool.h runtime/AtlasTool.cc runtime/Log.h +runtime/Log.cc runtime/Trace.h runtime/trace/CallStack.h runtime/trace/CallStack.cc diff --git a/src/atlas/runtime/Log.cc b/src/atlas/runtime/Log.cc new file mode 100644 index 000000000..126b040b1 --- /dev/null +++ b/src/atlas/runtime/Log.cc @@ -0,0 +1,49 @@ +/* + * (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 +#include +#include +#include "atlas/runtime/Log.h" +#include "atlas/parallel/mpi/mpi.h" +#include "eckit/os/BackTrace.h" + +namespace atlas { + +std::string backtrace() { + return eckit::BackTrace::dump(); +} + +std::ostream& Log::debug_parallel() { + const auto& comm = parallel::mpi::comm(); + auto rank = comm.rank(); + comm.barrier(); + for( int i=0; i Date: Fri, 2 Feb 2018 15:25:45 +0000 Subject: [PATCH 284/355] Improve atlas configuration --- src/atlas/library/Library.cc | 78 +++++++++++++++++++---------- src/atlas/library/Library.h | 14 ++++-- src/atlas/runtime/trace/Barriers.cc | 2 +- src/tests/AtlasTestEnvironment.h | 28 +++++------ 4 files changed, 75 insertions(+), 47 deletions(-) diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 2d277a8ab..c1ef1dc2e 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -56,6 +56,13 @@ namespace { } return ss.str(); } + + bool getEnv( const std::string& env, bool default_value ) { + if (::getenv( env.c_str() ) ) { + return eckit::Translator()(::getenv( env.c_str() )); + } + return default_value; + } } //---------------------------------------------------------------------------------------------------------------------- @@ -63,7 +70,14 @@ namespace { static Library libatlas; -Library::Library() : eckit::system::Library( std::string("atlas") ) {} +Library::Library() : + eckit::system::Library( std::string("atlas") ), + debug_( eckit::system::Library::debug() ), + info_( getEnv("ATLAS_INFO", true) ), + trace_( getEnv("ATLAS_TRACE", false) ), + trace_report_( getEnv("ATLAS_TRACE_REPORT", false) ), + trace_barriers_( getEnv("ATLAS_TRACE_BARRIERS", false) ) { +} Library& Library::instance() { return libatlas; @@ -95,24 +109,16 @@ void Library::initialise(int argc, char **argv) { initialise(); } -namespace{ - bool getEnv( const std::string& env, bool default_value ) { - if (::getenv( env.c_str() ) ) { - return eckit::Translator()(::getenv( env.c_str() )); - } - return default_value; - } -} void Library::initialise(const eckit::Parametrisation& config) { - if( not config.get("trace",info_) ) { - info_ = getEnv("ATLAS_INFO",info_); - } - if( not config.get("trace",trace_) ) { - trace_ = getEnv("ATLAS_TRACE",trace_); + if( config.has("log") ) { + config.get("log.info",info_); + config.get("log.trace",trace_); + config.get("log.debug",debug_); } - if( not config.get("barriers",barriers_) ) { - barriers_ = getEnv("ATLAS_BARRIERS",barriers_); + if( config.has("trace") ) { + config.get("trace.barriers",trace_barriers_); + config.get("trace.report", trace_report_); } // Summary @@ -125,10 +131,12 @@ void Library::initialise(const eckit::Parametrisation& config) { out << " communicator [" << parallel::mpi::comm() << "] \n"; out << " size [" << parallel::mpi::comm().size() << "] \n"; out << " rank [" << parallel::mpi::comm().rank() << "] \n"; - out << " barriers [" << barriers() << "] \n"; out << " \n"; - out << " trace [" << str(trace()) << "] \n"; - out << " debug [" << str(debug()) << "] \n"; + out << " log.info [" << str(info_) << "] \n"; + out << " log.trace [" << str(trace()) << "] \n"; + out << " log.debug [" << str(debug()) << "] \n"; + out << " trace.barriers [" << str(traceBarriers()) << "] \n"; + out << " trace.report [" << str(trace_report_) << "] \n"; out << " \n"; out << atlas::Library::instance().information(); out << std::flush; @@ -139,6 +147,11 @@ void Library::initialise() { } void Library::finalise() { + + if( ATLAS_HAVE_TRACE && trace_report_ ) { + Log::info() << atlas::Trace::report() << std::endl; + } + // Make sure that these specialised channels that wrap Log::info() are // destroyed before eckit::Log::info gets destroyed. // Just in case someone still tries to log, we reset to empty channels. @@ -149,28 +162,39 @@ void Library::finalise() { Log::flush(); } +std::ostream& Library::infoChannel() const { + if( info_channel_ ) return *info_channel_; + if( info_ ) { + return eckit::Log::info(); + } else { + info_channel_.reset( new eckit::Channel() ); + } + return *info_channel_; +} + std::ostream& Library::traceChannel() const { 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())))); + new eckit::PrefixTarget("ATLAS_TRACE",new eckit::OStreamTarget(eckit::Log::info())))); } else { trace_channel_.reset( new eckit::Channel() ); } return *trace_channel_; } -std::ostream& Library::infoChannel() const { - if( info_channel_ ) return *info_channel_; - if( info_ ) { - return eckit::Log::info(); + +eckit::Channel& Library::debugChannel() const { + if (debug_channel_) { return *debug_channel_; } + if (debug_) { + debug_channel_.reset( new eckit::Channel( + new eckit::PrefixTarget("ATLAS_DEBUG"))); } else { - info_channel_.reset( new eckit::Channel() ); + debug_channel_.reset( new eckit::Channel() ); } - return *trace_channel_; + return *debug_channel_; } - //---------------------------------------------------------------------------------------------------------------------- void Library::Information::print( std::ostream& out ) const { diff --git a/src/atlas/library/Library.h b/src/atlas/library/Library.h index f6944643a..cbda82b4a 100644 --- a/src/atlas/library/Library.h +++ b/src/atlas/library/Library.h @@ -39,7 +39,7 @@ class Library : public eckit::system::Library { void initialise(const eckit::Parametrisation&); void initialise(); void finalise(); - + struct Information { friend std::ostream& operator<<(std::ostream& s, const Information& i) { i.print(s); return s; } void print(std::ostream&) const; @@ -48,8 +48,11 @@ class Library : public eckit::system::Library { std::ostream& infoChannel() const; std::ostream& traceChannel() const; + virtual eckit::Channel& debugChannel() const override; bool trace() const { return trace_; } - bool barriers() const { return barriers_; } + virtual bool debug() const override { return debug_; } + + bool traceBarriers() const { return trace_barriers_; } protected: @@ -57,9 +60,12 @@ class Library : public eckit::system::Library { bool info_{true}; bool trace_{false}; - bool barriers_{false}; - mutable std::unique_ptr trace_channel_; + bool debug_{false}; + bool trace_barriers_{false}; + bool trace_report_{false}; mutable std::unique_ptr info_channel_; + mutable std::unique_ptr trace_channel_; + mutable std::unique_ptr debug_channel_; }; typedef Library Atlas; diff --git a/src/atlas/runtime/trace/Barriers.cc b/src/atlas/runtime/trace/Barriers.cc index 58d56829b..0e8ce2bb8 100644 --- a/src/atlas/runtime/trace/Barriers.cc +++ b/src/atlas/runtime/trace/Barriers.cc @@ -24,7 +24,7 @@ namespace trace { class BarriersState { private: BarriersState() { - barriers_ = atlas::Library::instance().barriers(); + barriers_ = atlas::Library::instance().traceBarriers(); } bool barriers_; StopWatch stopwatch_; diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 4ad380d4e..4dc756060 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -10,14 +10,17 @@ #pragma once -#include "atlas/library/Library.h" -#include "eckit/runtime/Main.h" +#include "eckit/config/Resource.h" +#include "eckit/eckit_version.h" #include "eckit/mpi/Comm.h" +#include "eckit/runtime/Main.h" +#include "eckit/testing/Test.h" + +#include "atlas/library/Library.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "eckit/config/Resource.h" -#include "eckit/testing/Test.h" -#include "eckit/eckit_version.h" +#include "atlas/util/Config.h" + namespace atlas { namespace test { @@ -83,6 +86,8 @@ void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection, int& _n struct AtlasTestEnvironment { + using Config = util::Config; + AtlasTestEnvironment(int argc, char * argv[]) { eckit::Main::initialise(argc, argv); eckit::Main::instance().taskID( eckit::mpi::comm("world").rank() ); @@ -90,19 +95,12 @@ struct AtlasTestEnvironment { long logtask = eckit::Resource("--logtask;$ATLAS_TEST_LOGTASK", 0); if( eckit::Main::instance().taskID() != logtask ) Log::reset(); } - atlas::Library::instance().initialise(); + bool report = eckit::Resource("--report;$ATLAS_TRACE_REPORT", false); + Library::instance().initialise( Config("trace", Config("report",report) ) ); } ~AtlasTestEnvironment() { - bool report = eckit::Resource("--report;$ATLAS_TEST_REPORT", false); - if( report ) { -#if ATLAS_HAVE_TRACE - Log::info() << atlas::Trace::report() << std::endl; -#else - Log::warning() << "Atlas cannot generate report as ATLAS_HAVE_TRACE is not defined." << std::endl; -#endif - } - atlas::Library::instance().finalise(); + Library::instance().finalise(); } }; From 1ce7e34454bc2fcbd90744c436d56c534e82d0f9 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 2 Feb 2018 16:05:49 +0000 Subject: [PATCH 285/355] Add timers to TransIFS::invtrans --- src/atlas/trans/ifs/TransIFS.cc | 43 +++-------------------------- src/atlas/trans/local/TransLocal.cc | 5 ++-- src/tests/trans/CMakeLists.txt | 2 +- 3 files changed, 8 insertions(+), 42 deletions(-) diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index d9d01ca10..4148f1ee4 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -241,6 +241,7 @@ void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra double gp_fields[], const eckit::Configuration& config ) const { + ATLAS_TRACE("TransIFS::invtrans"); TransParameters params(*this,config); struct ::InvTrans_t args = new_invtrans(trans_.get()); args.nscalar = nb_scalar_fields; @@ -273,27 +274,7 @@ void TransIFS::invtrans( const int nb_vordiv_fields, const double vorticity_spec double gp_fields[], const eckit::Configuration& config ) const { - TransParameters params(*this,config); - bool global = params.global(); - int nproma = params.nproma(); - int ngpblks; - if( nproma == 0 ) { // default - nproma = global ? trans_->ngptotg : trans_->ngptot; - ngpblks = 1; - } else { - ngpblks = global ? (trans_->ngptotg/nproma) : (trans_->ngptot/nproma); - } - struct ::InvTrans_t args = new_invtrans(trans_.get()); - args.nvordiv = nb_vordiv_fields; - args.rspvor = vorticity_spectra; - args.rspdiv = divergence_spectra; - args.rgp = gp_fields; - args.lglobal = params.global(); - args.luvder_EW = params.wind_EW_derivatives(); - args.lvordivgp = params.vorticity_divergence_fields(); - args.nproma = params.nproma(); - args.ngpblks = params.ngpblks(); - TRANS_CHECK( ::trans_invtrans(&args) ); + return invtrans( 0, nullptr, nb_vordiv_fields, vorticity_spectra, divergence_spectra, gp_fields, config ); } /////////////////////////////////////////////////////////////////////////////// @@ -301,16 +282,8 @@ void TransIFS::invtrans( const int nb_vordiv_fields, const double vorticity_spec void TransIFS::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], const eckit::Configuration& config ) const { + ATLAS_TRACE(); TransParameters params(*this,config); - bool global = params.global(); - int nproma = params.nproma(); - int ngpblks; - if( nproma == 0 ) { // default - nproma = global ? trans_->ngptotg : trans_->ngptot; - ngpblks = 1; - } else { - ngpblks = global ? (trans_->ngptotg/nproma) : (trans_->ngptot/nproma); - } struct ::DirTrans_t args = new_dirtrans(trans_.get()); args.nscalar = nb_fields; args.rgp = scalar_fields; @@ -326,16 +299,8 @@ void TransIFS::dirtrans( const int nb_fields, const double scalar_fields[], doub void TransIFS::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], const eckit::Configuration& config ) const { + ATLAS_TRACE(); TransParameters params(*this,config); - bool global = params.global(); - int nproma = params.nproma(); - int ngpblks; - if( nproma == 0 ) { // default - nproma = global ? trans_->ngptotg : trans_->ngptot; - ngpblks = 1; - } else { - ngpblks = global ? (trans_->ngptotg/nproma) : (trans_->ngptot/nproma); - } struct ::DirTrans_t args = new_dirtrans(trans_.get()); args.nvordiv = nb_fields; args.rspvor = vorticity_spectra; diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index afbfa4d4a..2ac00c293 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -211,7 +211,7 @@ void TransLocal::invtrans_uv( // Transform if( grid::StructuredGrid g = grid_ ) { - ATLAS_TRACE( "invtrans structured"); + ATLAS_TRACE( "invtrans_uv structured"); int idx = 0; for( size_t j=0; j Date: Mon, 5 Feb 2018 17:24:22 +0000 Subject: [PATCH 286/355] Reduce time of atlas_test_transgeneral --- src/tests/trans/test_transgeneral.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 58a9753ff..22651bc87 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -648,9 +648,9 @@ CASE( "test_trans_vordiv_with_translib" ) std::ostream& out = Log::info(); double tolerance = 1.e-13; - Grid g( "F24" ); + Grid g( "F12" ); // This was F24 (but test takes too long) grid::StructuredGrid gs(g); - int trc = 47; + int trc = 23; // This was 47 (corresponding to F24) trans::Trans trans (g, trc) ; trans::Trans transLocal(g, trc, util::Config("type","local")); From 13f9ccd724bf161bce0cf46dab84f45538d35d6f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 5 Feb 2018 17:25:12 +0000 Subject: [PATCH 287/355] Improved configuration of AtlasTool --- src/atlas/library/Library.cc | 64 ++++++---- src/atlas/library/Library.h | 8 +- src/atlas/runtime/AtlasTool.cc | 205 +++++++++++++++++++++++++++++++++ src/atlas/runtime/AtlasTool.h | 95 ++++----------- src/atlas/runtime/Log.h | 8 +- 5 files changed, 274 insertions(+), 106 deletions(-) diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index c1ef1dc2e..3b18ecaf3 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -63,6 +63,14 @@ namespace { } return default_value; } + + int getEnv( const std::string& env, int default_value ) { + if (::getenv( env.c_str() ) ) { + return eckit::Translator()(::getenv( env.c_str() )); + } + return default_value; + } + } //---------------------------------------------------------------------------------------------------------------------- @@ -99,7 +107,12 @@ void Library::initialise(int argc, char **argv) { if( not Main::ready() ) { Main::initialise(argc, argv); Main::instance().taskID( eckit::mpi::comm("world").rank() ); - if( Main::instance().taskID() != 0 ) Log::reset(); + if( Main::instance().taskID() != 0 ) { + eckit::Log::warning().reset(); + eckit::Log::info().reset(); + eckit::Log::debug().reset(); + atlas::Log::debug().reset(); + } Log::debug() << "Atlas initialised eckit::Main.\n"; if( eckit::mpi::comm("world").size() > 1 ) Log::debug() << @@ -121,25 +134,31 @@ 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(); + // Summary - std::ostream& out = Log::debug(); - out << "Executable [" << Main::instance().name() << "]\n"; - out << " \n"; - out << " current dir [" << PathName(LocalPathName::cwd()).fullName() << "]\n"; - out << " \n"; - out << " MPI\n"; - out << " communicator [" << parallel::mpi::comm() << "] \n"; - out << " size [" << parallel::mpi::comm().size() << "] \n"; - out << " rank [" << parallel::mpi::comm().rank() << "] \n"; - out << " \n"; - out << " log.info [" << str(info_) << "] \n"; - out << " log.trace [" << str(trace()) << "] \n"; - out << " log.debug [" << str(debug()) << "] \n"; - out << " trace.barriers [" << str(traceBarriers()) << "] \n"; - out << " trace.report [" << str(trace_report_) << "] \n"; - out << " \n"; - out << atlas::Library::instance().information(); - out << std::flush; + if( getEnv( "ATLAS_LOG_RANK", 0 ) == parallel::mpi::comm().rank() ) { + std::ostream& out = Log::debug(); + out << "Executable [" << Main::instance().name() << "]\n"; + out << " \n"; + out << " current dir [" << PathName(LocalPathName::cwd()).fullName() << "]\n"; + out << " \n"; + out << " MPI\n"; + out << " communicator [" << parallel::mpi::comm() << "] \n"; + out << " size [" << parallel::mpi::comm().size() << "] \n"; + out << " rank [" << parallel::mpi::comm().rank() << "] \n"; + out << " \n"; + out << " log.info [" << str(info_) << "] \n"; + out << " log.trace [" << str(trace()) << "] \n"; + out << " log.debug [" << str(debug()) << "] \n"; + out << " trace.barriers [" << str(traceBarriers()) << "] \n"; + out << " trace.report [" << str(trace_report_) << "] \n"; + out << " \n"; + out << atlas::Library::instance().information(); + out << std::flush; + } } void Library::initialise() { @@ -162,17 +181,16 @@ void Library::finalise() { Log::flush(); } -std::ostream& Library::infoChannel() const { - if( info_channel_ ) return *info_channel_; +eckit::Channel& Library::infoChannel() const { if( info_ ) { return eckit::Log::info(); - } else { + } else if( ! info_channel_ ) { info_channel_.reset( new eckit::Channel() ); } return *info_channel_; } -std::ostream& Library::traceChannel() const { +eckit::Channel& Library::traceChannel() const { if( trace_channel_ ) return *trace_channel_; if( trace_ ) { trace_channel_.reset( new eckit::Channel( diff --git a/src/atlas/library/Library.h b/src/atlas/library/Library.h index cbda82b4a..4f6eca2e9 100644 --- a/src/atlas/library/Library.h +++ b/src/atlas/library/Library.h @@ -46,8 +46,8 @@ class Library : public eckit::system::Library { }; Information information() const { return Information(); } - std::ostream& infoChannel() const; - std::ostream& traceChannel() const; + virtual eckit::Channel& infoChannel() const; + virtual eckit::Channel& traceChannel() const; virtual eckit::Channel& debugChannel() const override; bool trace() const { return trace_; } virtual bool debug() const override { return debug_; } @@ -63,8 +63,8 @@ class Library : public eckit::system::Library { bool debug_{false}; bool trace_barriers_{false}; bool trace_report_{false}; - mutable std::unique_ptr info_channel_; - mutable std::unique_ptr trace_channel_; + mutable std::unique_ptr info_channel_; + mutable std::unique_ptr trace_channel_; mutable std::unique_ptr debug_channel_; }; diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index 9c7271db0..4540fa9d4 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -1 +1,206 @@ +#include + +#include "eckit/config/LibEcKit.h" + +#include "eckit/log/FileTarget.h" +#include "eckit/log/PrefixTarget.h" #include "atlas/runtime/AtlasTool.h" +#include "atlas/library/config.h" + + +namespace { +static std::string debug_prefix(const std::string& libname) { + std::string s = libname; + std::transform(s.begin(), s.end(), s.begin(), ::toupper); + s += "_DEBUG"; + return s; +} + +void debug_addTarget(eckit::LogTarget* target) { + for( std::string libname : eckit::system::Library::list() ) { + const eckit::system::Library& lib = eckit::system::Library::lookup(libname); + if( lib.debug() ) { + lib.debugChannel().addTarget( new eckit::PrefixTarget(debug_prefix(libname), target ) ); + } + } + if( eckit::Log::debug() ) eckit::Log::debug().addTarget(target); +} + +void debug_setTarget(eckit::LogTarget* target) { + for( std::string libname : eckit::system::Library::list() ) { + const eckit::system::Library& lib = eckit::system::Library::lookup(libname); + if( lib.debug() ) { + lib.debugChannel().setTarget( new eckit::PrefixTarget(debug_prefix(libname), 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( 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() )); + } + return default_value; +} + +int getEnv( const std::string& env, int default_value ) { + if (::getenv( env.c_str() ) ) { + return eckit::Translator()(::getenv( env.c_str() )); + } + return default_value; +} + +} + +void atlas::AtlasTool::add_option(eckit::option::Option *option) +{ + options_.push_back( option ); +} + +void atlas::AtlasTool::help(std::ostream &out) +{ + out << "NAME\n" << indent() << name(); + std::string brief = briefDescription(); + if ( brief.size() ) out << " - " << brief << '\n'; + + std::string usg = usage(); + if ( usg.size() ) { + out << '\n'; + out << "SYNOPSIS\n" << indent() << usg << '\n'; + } + std::string desc = longDescription(); + if ( desc.size() ) { + out << '\n'; + out << "DESCRIPTION\n" << indent() << desc << '\n'; + } + out << '\n'; + out << "OPTIONS\n"; + for( Options::const_iterator it = options_.begin(); it!= options_.end(); ++it ) { + out << indent() << (**it) << "\n\n"; + } + out << std::flush; +} + +bool atlas::AtlasTool::handle_help() +{ + for( int i=1; i("help","Print this help") ); + add_option( new SimpleOption("debug","Debug level") ); + taskID( eckit::mpi::comm("world").rank()); +} + +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; + } + 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(); + } + + return status; +} + +void atlas::AtlasTool::run() +{ + if( handle_help() ) + return; + + if( argc()-1 < minimumPositionalArguments() ) + { + if( taskID() == 0 ) + std::cout << "Usage: " << usage() << std::endl; + return; + } + Options opts = options_; + Args args(&atlas::usage, + opts, + numberOfPositionalArguments(), + minimumPositionalArguments()); + + atlas::Library::instance().initialise(); + setupLogging(); + execute(args); + atlas::Library::instance().finalise(); +} + +void atlas::AtlasTool::setupLogging() +{ + int log_rank = getEnv( "ATLAS_LOG_RANK", 0 ); + bool use_logfile = getEnv( "ATLAS_LOG_FILE", false ); + + if( use_logfile ) { + + eckit::LogTarget* logfile = + new eckit::FileTarget(displayName() + ".log.p" + std::to_string(taskID())); + + if( parallel::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); + 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); + debug_setTarget(logfile); + } + + } else { + + if( parallel::mpi::comm().rank() != log_rank ) { + 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/AtlasTool.h b/src/atlas/runtime/AtlasTool.h index e073749d8..4c72b70c1 100644 --- a/src/atlas/runtime/AtlasTool.h +++ b/src/atlas/runtime/AtlasTool.h @@ -13,14 +13,16 @@ #include #include -#include "eckit/runtime/Tool.h" #include "eckit/option/CmdArgs.h" +#include "eckit/option/Separator.h" #include "eckit/option/SimpleOption.h" #include "eckit/option/VectorOption.h" -#include "eckit/option/Separator.h" +#include "eckit/runtime/Tool.h" + #include "atlas/library/Library.h" -#include "atlas/runtime/Log.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Log.h" +#include "atlas/util/Config.h" //-------------------------------------------------------------------------------- @@ -29,6 +31,7 @@ using eckit::option::VectorOption; using eckit::option::Separator; using eckit::option::CmdArgs; using eckit::option::Option; +using atlas::util::Config; namespace atlas { @@ -52,86 +55,28 @@ class AtlasTool : public eckit::Tool { virtual std::string usage() { return name() + " [OPTION]... [--help,-h] [--debug]"; } - void add_option( eckit::option::Option* option ) - { - options_.push_back( option ); - } - - virtual void help( std::ostream &out = Log::info() ) - { - out << "NAME\n" << indent() << name(); - std::string brief = briefDescription(); - if ( brief.size() ) out << " - " << brief << '\n'; - - std::string usg = usage(); - if ( usg.size() ) { - out << '\n'; - out << "SYNOPSIS\n" << indent() << usg << '\n'; - } - std::string desc = longDescription(); - if ( desc.size() ) { - out << '\n'; - out << "DESCRIPTION\n" << indent() << desc << '\n'; - } - out << '\n'; - out << "OPTIONS\n"; - for( Options::const_iterator it = options_.begin(); it!= options_.end(); ++it ) { - out << indent() << (**it) << "\n\n"; - } - out << std::flush; - } + void add_option( eckit::option::Option* option ); + + virtual void help( std::ostream &out = Log::info() ); virtual int numberOfPositionalArguments() { return -1; } virtual int minimumPositionalArguments() { return 0; } - bool handle_help() - { - for( int i=1; i("help","Print this help") ); - add_option( new SimpleOption("debug","Debug level") ); - taskID( eckit::mpi::comm("world").rank()); - if( taskID() != 0 ) - Log::reset(); - } + void setupLogging(); private: Options options_; diff --git a/src/atlas/runtime/Log.h b/src/atlas/runtime/Log.h index 89f73c3fd..148677b41 100644 --- a/src/atlas/runtime/Log.h +++ b/src/atlas/runtime/Log.h @@ -18,11 +18,11 @@ class Log : public detail::LogBase { public: - typedef eckit::Channel Channel; + using Channel = eckit::Channel; // derives from std::ostream - static std::ostream& info() { return atlas::Library::instance().infoChannel(); } - static std::ostream& trace() { return atlas::Library::instance().traceChannel(); } - static std::ostream& debug() { return atlas::Library::instance().debugChannel(); } + static Channel& info() { return atlas::Library::instance().infoChannel(); } + static Channel& trace() { return atlas::Library::instance().traceChannel(); } + static Channel& debug() { return atlas::Library::instance().debugChannel(); } static std::ostream& debug_parallel(); From 69cd964625b56831a6b1d04af8733109113ac4e1 Mon Sep 17 00:00:00 2001 From: Pedro Maciel Date: Tue, 6 Feb 2018 14:55:58 +0000 Subject: [PATCH 288/355] Remove undefined method prototype --- src/atlas/util/Polygon.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/atlas/util/Polygon.h b/src/atlas/util/Polygon.h index c60266900..52181d212 100644 --- a/src/atlas/util/Polygon.h +++ b/src/atlas/util/Polygon.h @@ -79,10 +79,6 @@ class Polygon : public std::vector { return s; } -protected: - - void construct( const edge_set_t& ); - }; //------------------------------------------------------------------------------------------------------ From e64be95757af5a6c33ece531ff137492afcb9331 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Tue, 6 Feb 2018 17:00:00 +0000 Subject: [PATCH 289/355] ATLAS-135 local transformation now uses always truncation+1 for the transformation of U and V. This is the same behavior like in the trans library --- src/atlas/trans/local/LegendreTransforms.cc | 20 ++- src/atlas/trans/local/LegendreTransforms.h | 15 +- src/atlas/trans/local/TransLocal.cc | 180 +++++++++++--------- src/atlas/trans/local/TransLocal.h | 2 +- src/atlas/trans/local/VorDivToUVLocal.cc | 31 ++-- src/tests/trans/test_transgeneral.cc | 30 ++-- 6 files changed, 155 insertions(+), 123 deletions(-) diff --git a/src/atlas/trans/local/LegendreTransforms.cc b/src/atlas/trans/local/LegendreTransforms.cc index b594a5ed6..189651bf5 100644 --- a/src/atlas/trans/local/LegendreTransforms.cc +++ b/src/atlas/trans/local/LegendreTransforms.cc @@ -19,6 +19,7 @@ namespace trans { void invtrans_legendre( const size_t trc, // truncation (in) const size_t trcFT, // truncation for Fourier transformation (in) + const size_t trcLP, // truncation of Legendre polynomials data legpol. Needs to be >= trc (in) const double legpol[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) const int nb_fields, // number of fields const double spec[], // spectral data, size (trc+1)*trc (in) @@ -26,19 +27,22 @@ void invtrans_legendre( double leg_imag[] ) // values of associated Legendre functions, size (trc+1)*trc/2 (out) { // Legendre transformation: - int k = 0; + int k = 0, klp = 0; for( int jm=0; jm<=trcFT; ++jm ) { for( int jfld=0; jfld0 - leg_real[jm*nb_fields+jfld] += 2. * spec[(2*k )*nb_fields+jfld] * legpol[k]; - leg_imag[jm*nb_fields+jfld] += 2. * spec[(2*k+1)*nb_fields+jfld] * legpol[k]; + for( int jn=jm; jn<=trcLP; ++jn, ++klp ) { + if( jn<=trc ) { + for( int jfld=0; jfld0 + leg_real[jm*nb_fields+jfld] += 2. * spec[(2*k )*nb_fields+jfld] * legpol[klp]; + leg_imag[jm*nb_fields+jfld] += 2. * spec[(2*k+1)*nb_fields+jfld] * legpol[klp]; + } + ++k; } } } diff --git a/src/atlas/trans/local/LegendreTransforms.h b/src/atlas/trans/local/LegendreTransforms.h index a5716b50b..e75b0c3a4 100644 --- a/src/atlas/trans/local/LegendreTransforms.h +++ b/src/atlas/trans/local/LegendreTransforms.h @@ -22,13 +22,14 @@ namespace trans { // Andreas Mueller *ECMWF* // void invtrans_legendre( - const size_t trc, // truncation (in) - const size_t trcFT, // truncation for Fourier transformation (in) - const double legpol[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) - const int nb_fields, // Number of fields - const double spec[], // spectral data, size (trc+1)*trc (in) - double leg_real[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) - double leg_imag[] ); // values of associated Legendre functions, size (trc+1)*trc/2 (out) + const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + const size_t trcLP, // truncation of Legendre polynomials data legpol. Needs to be >= trc (in) + const double legpol[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) + const int nb_fields, // number of fields + const double spec[], // spectral data, size (trc+1)*trc (in) + double leg_real[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + double leg_imag[] ); // values of associated Legendre functions, size (trc+1)*trc/2 (out) // -------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index afbfa4d4a..3a566b5b3 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -58,13 +58,13 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const long truncat legendre_begin_.resize( g.ny() ); for( size_t j=0; j recomputed_legendre_; - - auto legPol = [&](double lat, int j) -> const double * { - if( precompute_ ) { - return legendre_data(j); - } else { - recomputed_legendre_.resize( legendre_size( truncation_ ) ); - compute_legendre_polynomials( truncation_, lat, recomputed_legendre_.data() ); - return recomputed_legendre_.data(); - } - }; - - // Temporary storage for legendre space - std::vector legReal(nb_fields*(truncation_+1)); - std::vector legImag(nb_fields*(truncation_+1)); - std::vector gp_tmp(nb_fields*grid_.size(), 0.); - - // Transform - if( grid::StructuredGrid g = grid_ ) { - ATLAS_TRACE( "invtrans structured"); - int idx = 0; - for( size_t j=0; j0 ) { + int nb_fields = nb_scalar_fields; + + // Depending on "precompute_legendre_", we have to compute the + // legendre polynomials for every latitute + std::vector recomputed_legendre_; + + auto legPol = [&](double lat, int j) -> const double * { + if( precompute_ ) { + return legendre_data(j); + } else { + recomputed_legendre_.resize( legendre_size( truncation ) ); + compute_legendre_polynomials( truncation, lat, recomputed_legendre_.data() ); + return recomputed_legendre_.data(); + } + }; + + // Temporary storage for legendre space + std::vector legReal(nb_fields*(truncation+1)); + std::vector legImag(nb_fields*(truncation+1)); + std::vector gp_tmp(nb_fields*grid_.size(), 0.); + + // Transform + if( grid::StructuredGrid g = grid_ ) { + ATLAS_TRACE( "invtrans structured"); + int idx = 0; + for( size_t j=0; j U(nb_vordiv_spec,0.); - std::vector V(nb_vordiv_spec,0.); - trans::VorDivToUV vordiv_to_UV(truncation_, option::type("local")); - vordiv_to_UV.execute( nb_vordiv_spec, nb_vordiv_fields, vorticity_spectra, divergence_spectra, U.data(), V.data() ); + // increase truncation in vorticity_spectra and divergence_spectra: + int nb_vordiv_spec_ext = 2*legendre_size(truncation_+1)*nb_vordiv_fields; + std::vector vorticity_spectra_extended(nb_vordiv_spec_ext,0.); + std::vector divergence_spectra_extended(nb_vordiv_spec_ext,0.); + extend_truncation(truncation_, nb_vordiv_fields, vorticity_spectra, vorticity_spectra_extended.data()); + extend_truncation(truncation_, nb_vordiv_fields, divergence_spectra, divergence_spectra_extended.data()); + + // call vd2uv to compute u and v in spectral space + std::vector U_ext(nb_vordiv_spec_ext,0.); + std::vector V_ext(nb_vordiv_spec_ext,0.); + trans::VorDivToUV vordiv_to_UV_ext(truncation_+1, option::type("local")); + vordiv_to_UV_ext.execute( nb_vordiv_spec_ext, nb_vordiv_fields, vorticity_spectra_extended.data(), divergence_spectra_extended.data(), U_ext.data(), V_ext.data() ); // perform spectral transform to compute all fields in grid point space - invtrans_uv(nb_vordiv_fields, nb_vordiv_fields, U.data(), gp_fields, config); - invtrans_uv(nb_vordiv_fields, nb_vordiv_fields, V.data(), gp_fields+nb_gp*nb_vordiv_fields, config); - invtrans_uv(nb_scalar_fields, 0, scalar_spectra, gp_fields+2*nb_gp*nb_vordiv_fields, config); + invtrans_uv(truncation_+1, nb_vordiv_fields, nb_vordiv_fields, U_ext.data(), gp_fields, config); + invtrans_uv(truncation_+1, nb_vordiv_fields, nb_vordiv_fields, V_ext.data(), gp_fields+nb_gp*nb_vordiv_fields, config); + invtrans_uv(truncation_ , nb_scalar_fields, 0, scalar_spectra, gp_fields+2*nb_gp*nb_vordiv_fields, config); } diff --git a/src/atlas/trans/local/TransLocal.h b/src/atlas/trans/local/TransLocal.h index 39277b21f..d88dd45d7 100644 --- a/src/atlas/trans/local/TransLocal.h +++ b/src/atlas/trans/local/TransLocal.h @@ -117,7 +117,7 @@ class TransLocal : public trans::TransImpl { const double* legendre_data( int j ) const { return legendre_.data() + legendre_begin_[j]; } double* legendre_data( int j ) { return legendre_.data() + legendre_begin_[j]; } - void invtrans_uv( const int nb_scalar_fields, const int nb_vordiv_fields, const double scalar_spectra[], + void invtrans_uv(const int truncation, const int nb_scalar_fields, const int nb_vordiv_fields, const double scalar_spectra[], double gp_fields[], const eckit::Configuration& = util::NoConfig() ) const; diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index 8692068df..adc866595 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -25,6 +25,8 @@ static VorDivToUVBuilder builder("local"); } // -------------------------------------------------------------------------------------------------------------------- +// Routine to copy spectral data into internal storage form of IFS trans +// Ported to C++ by: Andreas Mueller *ECMWF* void prfi1b( const int truncation, const int km, // zonal wavenumber @@ -50,6 +52,11 @@ void prfi1b( } // -------------------------------------------------------------------------------------------------------------------- +// Routine to compute spectral velocities (*cos(latitude)) out of spectral vorticity and divergence +// Reference: +// ECMWF Research Department documentation of the IFS +// Temperton, 1991, MWR 119 p1303 +// Ported to C++ by: Andreas Mueller *ECMWF* void vd2uv( const int truncation, const int km, // zonal wavenumber @@ -63,8 +70,8 @@ void vd2uv( int nlei1 = truncation+4+(truncation+4+1)%2; + // repsnm: epsilon from eq.(2.12) and (2.13) in [Temperton 1991] std::vector repsnm((truncation+1)*(truncation+6)/2); - std::vector rlapin(truncation+3); int idx = 0; for( int jm=0; jm<=truncation; ++jm ) { for( int jn=jm; jn<=truncation+2; ++jn, ++idx ) { @@ -72,10 +79,15 @@ void vd2uv( } } repsnm[0] = 0.; + + // rlapin: constant factor from eq.(2.2) and (2.3) in [Temperton 1991] + std::vector rlapin(truncation+3); for( int jn=1; jn<=truncation+2; ++jn ) { rlapin[jn] = -util::Earth::radiusInMeters()*util::Earth::radiusInMeters()/(jn*(jn+1.)); } rlapin[0] = 0.; + + // inverse the order of repsnm and rlapin for improved accuracy std::vector zepsnm(truncation+6); std::vector zlapin(truncation+6); std::vector zn (truncation+6); @@ -93,10 +105,10 @@ void vd2uv( zepsnm[ij] = 0.; } zn[ij] = jn; - //Log::info() << "ij=" << ij << " jn=" << zn[ij] << " rlapin=" << zlapin[ij] << " repsnm=" << zepsnm[ij] << std::endl; } zn[0] = truncation+3; + // copy spectral data into internal trans storage: std::vector rvor(2*nb_vordiv_fields*nlei1); std::vector rdiv(2*nb_vordiv_fields*nlei1); std::vector ru (2*nb_vordiv_fields*nlei1); @@ -104,14 +116,11 @@ void vd2uv( prfi1b(truncation, km, nb_vordiv_fields, vorticity_spectra, rvor.data()); prfi1b(truncation, km, nb_vordiv_fields, divergence_spectra, rdiv.data()); - //Log::info() << "km=" << km << " rvor: " << std::endl; - //for( int j=0; j<2*nb_vordiv_fields*nlei1; j++ ) Log::info() << rvor[j] << " "; - //Log::info() << std::endl; + // compute eq.(2.12) and (2.13) in [Temperton 1991]: if( km==0 ) { for( int jfld=0; jfld& zlfpol, // values of associated Legendre functions, size (trc+1)*trc/2 (in) const double rspecg[]) // spectral data, size (trc+1)*trc (in) { - trans::invtrans_legendre( trc, trcFT, zlfpol.data(), 1, rspecg, rlegReal.data(), rlegImag.data() ); + trans::invtrans_legendre( trc, trcFT, trc, zlfpol.data(), 1, rspecg, rlegReal.data(), rlegImag.data() ); } //----------------------------------------------------------------------------- @@ -648,9 +648,9 @@ CASE( "test_trans_vordiv_with_translib" ) std::ostream& out = Log::info(); double tolerance = 1.e-13; - Grid g( "F24" ); + Grid g( "F12" ); grid::StructuredGrid gs(g); - int trc = 47; + int trc = 23; trans::Trans trans (g, trc) ; trans::Trans transLocal(g, trc, util::Config("type","local")); @@ -729,22 +729,16 @@ CASE( "test_trans_vordiv_with_translib" ) double rms_trans = compute_rms(g.size(), gp.data()+pos*g.size(), rgp_analytic.data()); double rms_gen = compute_rms(g.size(), rgp.data()+pos*g.size(), rgp_analytic.data()); - // local transformation truncates the spectral U,V to trc! This is different from - // the analytic solution and trans library's invtrans! - bool invalid = ( ivar_in<2 && ivar_out<2 && n==trc ); - - if( !invalid ) { - if( rms_gen >= tolerance ) { - ATLAS_DEBUG_VAR(rms_gen); - ATLAS_DEBUG_VAR(tolerance); - } - if( rms_trans >= tolerance ) { - ATLAS_DEBUG_VAR(rms_trans); - ATLAS_DEBUG_VAR(tolerance); - } - EXPECT( rms_trans < tolerance ); - EXPECT( rms_gen < tolerance ); + if( rms_gen >= tolerance ) { + ATLAS_DEBUG_VAR(rms_gen); + ATLAS_DEBUG_VAR(tolerance); + } + if( rms_trans >= tolerance ) { + ATLAS_DEBUG_VAR(rms_trans); + ATLAS_DEBUG_VAR(tolerance); } + EXPECT( rms_trans < tolerance ); + EXPECT( rms_gen < tolerance ); icase++; } k++; From a89630fc32f829b2aec0a64f17769136fa94b79f Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Wed, 7 Feb 2018 19:14:28 +0000 Subject: [PATCH 290/355] ATLAS-135 first version of reduced truncation towards the poles implemented. Also more analytic test cases added --- .vscode/c_cpp_properties.json | 83 +++++++++++++++++++++ src/.vscode/c_cpp_properties.json | 83 +++++++++++++++++++++ src/.vscode/settings.json | 21 ++++++ src/atlas/trans/local/TransLocal.cc | 23 ++++-- src/tests/trans/test_transgeneral.cc | 104 ++++++++++++++++++++++++--- 5 files changed, 300 insertions(+), 14 deletions(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 src/.vscode/c_cpp_properties.json create mode 100644 src/.vscode/settings.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 000000000..30b77762a --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,83 @@ +{ + "configurations": [ + { + "name": "Mac", + "includePath": [ + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", + "/usr/local/include", + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include", + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", + "/usr/include", + "/Users/andreas/Development/atlas-bundle/source/eckit/src", + "/Users/andreas/Development/atlas-bundle/source/fckit/src", + "/Users/andreas/Development/atlas-bundle/source/transi/src", + "/Users/andreas/Development/atlas-bundle/source/ecbuild/src", + "/Users/andreas/Development/atlas-bundle/source/atlas/src", + "/Users/andreas/Development/atlas-bundle/build/eckit/src", + "/Users/andreas/Development/atlas-bundle/build/fckit/src", + "/Users/andreas/Development/atlas-bundle/build/transi/src", + "/Users/andreas/Development/atlas-bundle/build/ecbuild/src", + "/Users/andreas/Development/atlas-bundle/build/atlas/src", + "${workspaceRoot}" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", + "/usr/local/include", + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include", + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", + "/usr/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "macFrameworkPath": [ + "/System/Library/Frameworks", + "/Library/Frameworks" + ] + }, + { + "name": "Linux", + "includePath": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + }, + { + "name": "Win32", + "includePath": [ + "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", + "${workspaceRoot}" + ], + "defines": [ + "_DEBUG", + "UNICODE" + ], + "intelliSenseMode": "msvc-x64", + "browse": { + "path": [ + "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + } + ], + "version": 3 +} \ No newline at end of file diff --git a/src/.vscode/c_cpp_properties.json b/src/.vscode/c_cpp_properties.json new file mode 100644 index 000000000..30b77762a --- /dev/null +++ b/src/.vscode/c_cpp_properties.json @@ -0,0 +1,83 @@ +{ + "configurations": [ + { + "name": "Mac", + "includePath": [ + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", + "/usr/local/include", + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include", + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", + "/usr/include", + "/Users/andreas/Development/atlas-bundle/source/eckit/src", + "/Users/andreas/Development/atlas-bundle/source/fckit/src", + "/Users/andreas/Development/atlas-bundle/source/transi/src", + "/Users/andreas/Development/atlas-bundle/source/ecbuild/src", + "/Users/andreas/Development/atlas-bundle/source/atlas/src", + "/Users/andreas/Development/atlas-bundle/build/eckit/src", + "/Users/andreas/Development/atlas-bundle/build/fckit/src", + "/Users/andreas/Development/atlas-bundle/build/transi/src", + "/Users/andreas/Development/atlas-bundle/build/ecbuild/src", + "/Users/andreas/Development/atlas-bundle/build/atlas/src", + "${workspaceRoot}" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", + "/usr/local/include", + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include", + "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", + "/usr/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "macFrameworkPath": [ + "/System/Library/Frameworks", + "/Library/Frameworks" + ] + }, + { + "name": "Linux", + "includePath": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + }, + { + "name": "Win32", + "includePath": [ + "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", + "${workspaceRoot}" + ], + "defines": [ + "_DEBUG", + "UNICODE" + ], + "intelliSenseMode": "msvc-x64", + "browse": { + "path": [ + "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + } + ], + "version": 3 +} \ No newline at end of file diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json new file mode 100644 index 000000000..e889d5567 --- /dev/null +++ b/src/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "C_Cpp.intelliSenseEngineFallback": "Enabled", + "files.associations": { + "__split_buffer": "cpp", + "__tree": "cpp", + "array": "cpp", + "bitset": "cpp", + "deque": "cpp", + "initializer_list": "cpp", + "iterator": "cpp", + "list": "cpp", + "map": "cpp", + "regex": "cpp", + "set": "cpp", + "stack": "cpp", + "string": "cpp", + "string_view": "cpp", + "utility": "cpp", + "vector": "cpp" + } +} \ No newline at end of file diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 059bd6189..dec947dd2 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -36,8 +36,21 @@ size_t legendre_size( const size_t truncation ) { return (truncation+2)*(truncation+1)/2; } -int fourier_truncation( double truncation, double lat ) { - return truncation; +int fourier_truncation( const int truncation, const int nx, const int nxmax, const double lat ) { + int linear_truncation = (nxmax-1)/2, trc = truncation; + if( truncation>=linear_truncation ) { + // linear + trc = (nx-1)/2; + } else if( truncation>=2./3.*linear_truncation ) { + // quadratic + trc = (nx-1)/(2+3*(linear_truncation-truncation)/linear_truncation*std::pow(std::sin(lat),2)); + } else { + // cubic + trc = (nx-1)/(2+std::pow(std::sin(lat),2))-1; + } + trc = std::min(truncation, trc); + //Log::info() << "truncation=" << truncation << " trc=" << trc << " nx=" << nx << " nxmax=" << nxmax << " lat=" << lat << std::endl; + return trc; } } // namespace anonymous @@ -211,7 +224,7 @@ void TransLocal::invtrans_uv( int idx = 0; for( size_t j=0; j sp (2*N*nb_scalar); std::vector vor (2*N*nb_vordiv); @@ -670,11 +757,12 @@ CASE( "test_trans_vordiv_with_translib" ) int icase = 0; for( int ivar_in=0; ivar_in<3; ivar_in++ ) { // vorticity, divergence, scalar for( int ivar_out=0; ivar_out<3; ivar_out++ ) { // u, v, scalar + int nb_fld = 1; if( ivar_out==2) { tolerance = 1.e-13; nb_fld = nb_scalar; } else { - tolerance = 1.e-4; + tolerance = 2.e-6; nb_fld = nb_vordiv; } for( int jfld=0; jfld= tolerance ) { + if( rms_gen >= tolerance || rms_trans >= tolerance ) { + Log::info() << "Case " << icase << " ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; ATLAS_DEBUG_VAR(rms_gen); - ATLAS_DEBUG_VAR(tolerance); - } - if( rms_trans >= tolerance ) { ATLAS_DEBUG_VAR(rms_trans); ATLAS_DEBUG_VAR(tolerance); } From def3facd26ec2b681a69365528582b748112781c Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Thu, 8 Feb 2018 10:39:28 +0000 Subject: [PATCH 291/355] removed vscode files that were accidentally included in the previous commit --- .vscode/c_cpp_properties.json | 83 ----------------------------------- 1 file changed, 83 deletions(-) delete mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 30b77762a..000000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "configurations": [ - { - "name": "Mac", - "includePath": [ - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", - "/usr/local/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", - "/usr/include", - "/Users/andreas/Development/atlas-bundle/source/eckit/src", - "/Users/andreas/Development/atlas-bundle/source/fckit/src", - "/Users/andreas/Development/atlas-bundle/source/transi/src", - "/Users/andreas/Development/atlas-bundle/source/ecbuild/src", - "/Users/andreas/Development/atlas-bundle/source/atlas/src", - "/Users/andreas/Development/atlas-bundle/build/eckit/src", - "/Users/andreas/Development/atlas-bundle/build/fckit/src", - "/Users/andreas/Development/atlas-bundle/build/transi/src", - "/Users/andreas/Development/atlas-bundle/build/ecbuild/src", - "/Users/andreas/Development/atlas-bundle/build/atlas/src", - "${workspaceRoot}" - ], - "defines": [], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", - "/usr/local/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", - "/usr/include", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - }, - "macFrameworkPath": [ - "/System/Library/Frameworks", - "/Library/Frameworks" - ] - }, - { - "name": "Linux", - "includePath": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "defines": [], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - }, - { - "name": "Win32", - "includePath": [ - "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", - "${workspaceRoot}" - ], - "defines": [ - "_DEBUG", - "UNICODE" - ], - "intelliSenseMode": "msvc-x64", - "browse": { - "path": [ - "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - } - ], - "version": 3 -} \ No newline at end of file From 8949acd5ddf7081ec49c8f74a46308fb6af49490 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Thu, 8 Feb 2018 10:41:08 +0000 Subject: [PATCH 292/355] some more --- src/.vscode/c_cpp_properties.json | 83 ------------------------------- src/.vscode/settings.json | 21 -------- 2 files changed, 104 deletions(-) delete mode 100644 src/.vscode/c_cpp_properties.json delete mode 100644 src/.vscode/settings.json diff --git a/src/.vscode/c_cpp_properties.json b/src/.vscode/c_cpp_properties.json deleted file mode 100644 index 30b77762a..000000000 --- a/src/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "configurations": [ - { - "name": "Mac", - "includePath": [ - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", - "/usr/local/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", - "/usr/include", - "/Users/andreas/Development/atlas-bundle/source/eckit/src", - "/Users/andreas/Development/atlas-bundle/source/fckit/src", - "/Users/andreas/Development/atlas-bundle/source/transi/src", - "/Users/andreas/Development/atlas-bundle/source/ecbuild/src", - "/Users/andreas/Development/atlas-bundle/source/atlas/src", - "/Users/andreas/Development/atlas-bundle/build/eckit/src", - "/Users/andreas/Development/atlas-bundle/build/fckit/src", - "/Users/andreas/Development/atlas-bundle/build/transi/src", - "/Users/andreas/Development/atlas-bundle/build/ecbuild/src", - "/Users/andreas/Development/atlas-bundle/build/atlas/src", - "${workspaceRoot}" - ], - "defines": [], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1", - "/usr/local/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/9.0.0/include", - "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include", - "/usr/include", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - }, - "macFrameworkPath": [ - "/System/Library/Frameworks", - "/Library/Frameworks" - ] - }, - { - "name": "Linux", - "includePath": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "defines": [], - "intelliSenseMode": "clang-x64", - "browse": { - "path": [ - "/usr/include", - "/usr/local/include", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - }, - { - "name": "Win32", - "includePath": [ - "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include", - "${workspaceRoot}" - ], - "defines": [ - "_DEBUG", - "UNICODE" - ], - "intelliSenseMode": "msvc-x64", - "browse": { - "path": [ - "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/include/*", - "${workspaceRoot}" - ], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - } - ], - "version": 3 -} \ No newline at end of file diff --git a/src/.vscode/settings.json b/src/.vscode/settings.json deleted file mode 100644 index e889d5567..000000000 --- a/src/.vscode/settings.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "C_Cpp.intelliSenseEngineFallback": "Enabled", - "files.associations": { - "__split_buffer": "cpp", - "__tree": "cpp", - "array": "cpp", - "bitset": "cpp", - "deque": "cpp", - "initializer_list": "cpp", - "iterator": "cpp", - "list": "cpp", - "map": "cpp", - "regex": "cpp", - "set": "cpp", - "stack": "cpp", - "string": "cpp", - "string_view": "cpp", - "utility": "cpp", - "vector": "cpp" - } -} \ No newline at end of file From 6e536acc33f98ee8f8f4dd71cee870d5f0c2298b Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Thu, 8 Feb 2018 18:58:14 +0000 Subject: [PATCH 293/355] ATLAS-135 some fixes. Added reduced truncation to analytic solution. Test passes now successfully with octahedral mesh --- src/atlas/trans/local/FourierTransforms.cc | 20 ++++++++++++++++++++ src/atlas/trans/local/FourierTransforms.h | 6 ++++++ src/atlas/trans/local/TransLocal.cc | 17 ----------------- src/tests/trans/test_transgeneral.cc | 14 ++++++++++---- 4 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc index 7f7e0aaa3..159213c36 100644 --- a/src/atlas/trans/local/FourierTransforms.cc +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -9,6 +9,7 @@ */ #include +#include #include "atlas/trans/local/FourierTransforms.h" namespace atlas { @@ -38,6 +39,25 @@ void invtrans_fourier( } } +int fourier_truncation( const int truncation, const int nx, const int nxmax, const double lat ) { + int linear_truncation = (nxmax-1)/2; + int trc = truncation; + if( truncation>=linear_truncation ) { + // linear + trc = (nx-1)/2; + } else if( truncation>=2./3.*linear_truncation ) { + // quadratic + //trc = (nx-1)/(2+std::pow(std::cos(lat),2)); + trc = (nx-1)/(2+3*(linear_truncation-truncation)/linear_truncation*std::pow(std::cos(lat),2)); + } else { + // cubic + trc = (nx-1)/(2+std::pow(std::cos(lat),2))-1; + } + trc = std::min(truncation, trc); + //Log::info() << "truncation=" << truncation << " trc=" << trc << " nx=" << nx << " nxmax=" << nxmax << " latsin2=" << std::pow(std::cos(lat),2) << std::endl; + return trc; +} + // -------------------------------------------------------------------------------------------------------------------- } // namespace trans diff --git a/src/atlas/trans/local/FourierTransforms.h b/src/atlas/trans/local/FourierTransforms.h index 5d49adc0a..812bcf141 100644 --- a/src/atlas/trans/local/FourierTransforms.h +++ b/src/atlas/trans/local/FourierTransforms.h @@ -30,6 +30,12 @@ void invtrans_fourier( const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) double rgp[] ); // gridpoint +int fourier_truncation( + const int truncation, + const int nx, + const int nxmax, + const double lat ); + // -------------------------------------------------------------------------------------------------------------------- } // namespace trans diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index dec947dd2..c6837afaa 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -36,23 +36,6 @@ size_t legendre_size( const size_t truncation ) { return (truncation+2)*(truncation+1)/2; } -int fourier_truncation( const int truncation, const int nx, const int nxmax, const double lat ) { - int linear_truncation = (nxmax-1)/2, trc = truncation; - if( truncation>=linear_truncation ) { - // linear - trc = (nx-1)/2; - } else if( truncation>=2./3.*linear_truncation ) { - // quadratic - trc = (nx-1)/(2+3*(linear_truncation-truncation)/linear_truncation*std::pow(std::sin(lat),2)); - } else { - // cubic - trc = (nx-1)/(2+std::pow(std::sin(lat),2))-1; - } - trc = std::min(truncation, trc); - //Log::info() << "truncation=" << truncation << " trc=" << trc << " nx=" << nx << " nxmax=" << nxmax << " lat=" << lat << std::endl; - return trc; -} - } // namespace anonymous // -------------------------------------------------------------------------------------------------------------------- diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 512a191bb..091f03f9b 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -466,7 +466,11 @@ void spectral_transform_grid_analytic( double lon = g.x(i,j) * util::Constants::degreesToRadians(); // compute spherical harmonics: - rgp[idx++] = sphericalharmonics_analytic_point(n, m, imag, lon, lat, ivar_in, ivar_out); + if( trans::fourier_truncation(trc, g.nx(j), g.nxmax(), lat)>=m ) { + rgp[idx++] = sphericalharmonics_analytic_point(n, m, imag, lon, lat, ivar_in, ivar_out); + } else { + rgp[idx++] = 0.; + } } } } else { @@ -735,9 +739,9 @@ CASE( "test_trans_vordiv_with_translib" ) // resolution: (Reduce this number if the test takes too long!) int res = 12; - Grid g( "F" + std::to_string(res) ); + Grid g( "O" + std::to_string(res) ); grid::StructuredGrid gs(g); - int trc = res*2-2; + int trc = res*2-1; trans::Trans trans (g, trc) ; trans::Trans transLocal(g, trc, util::Config("type","local")); @@ -816,11 +820,13 @@ CASE( "test_trans_vordiv_with_translib" ) double rms_trans = compute_rms(g.size(), gp.data()+pos*g.size(), rgp_analytic.data()); double rms_gen = compute_rms(g.size(), rgp.data()+pos*g.size(), rgp_analytic.data()); + double rms_diff = compute_rms(g.size(), rgp.data()+pos*g.size(), gp.data()+pos*g.size()); - if( rms_gen >= tolerance || rms_trans >= tolerance ) { + if( rms_gen >= tolerance || rms_trans >= tolerance || rms_diff >= tolerance ) { Log::info() << "Case " << icase << " ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; ATLAS_DEBUG_VAR(rms_gen); ATLAS_DEBUG_VAR(rms_trans); + ATLAS_DEBUG_VAR(rms_diff); ATLAS_DEBUG_VAR(tolerance); } EXPECT( rms_trans < tolerance ); From 1660572d7b3c6c744804c5b01e298104400001b7 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 9 Feb 2018 13:52:10 +0000 Subject: [PATCH 294/355] Version 0.13.0 --- VERSION.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION.cmake b/VERSION.cmake index d42b1cd16..3856c1d38 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.12.1-develop" ) +set ( ${PROJECT_NAME}_VERSION_STR "0.13.0" ) From 7cc44b307d75b9a0a09939aa574b75ccbc4fca70 Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Fri, 9 Feb 2018 18:57:44 +0000 Subject: [PATCH 295/355] ATLAS-135 fourier_truncation is now identical with trans for O-meshes still differences for other meshes --- src/atlas/trans/ifs/TransIFS.cc | 5 +++-- src/atlas/trans/local/FourierTransforms.cc | 17 +++++++++----- src/atlas/trans/local/FourierTransforms.h | 1 + src/atlas/trans/local/TransLocal.cc | 2 +- src/tests/trans/test_transgeneral.cc | 26 ++++++++++++++++++++-- 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index 4148f1ee4..b0b49ebc1 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -794,8 +794,9 @@ void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const trans_->fft = p.fft(); trans_->lsplit = p.split_latitudes(); trans_->flt = p.flt(); - - 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 ) diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc index 159213c36..741fd7709 100644 --- a/src/atlas/trans/local/FourierTransforms.cc +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -10,6 +10,7 @@ #include #include +#include #include "atlas/trans/local/FourierTransforms.h" namespace atlas { @@ -39,22 +40,28 @@ void invtrans_fourier( } } -int fourier_truncation( const int truncation, const int nx, const int nxmax, const double lat ) { - int linear_truncation = (nxmax-1)/2; +int fourier_truncation( + const int truncation, + const int nx, + const int nxmax, + const int ndgl, + const double lat ) +{ + int linear_truncation = ndgl-1; int trc = truncation; if( truncation>=linear_truncation ) { // linear trc = (nx-1)/2; - } else if( truncation>=2./3.*linear_truncation ) { + } else if( truncation>=ndgl*2/3-1 ) { // quadratic //trc = (nx-1)/(2+std::pow(std::cos(lat),2)); - trc = (nx-1)/(2+3*(linear_truncation-truncation)/linear_truncation*std::pow(std::cos(lat),2)); + trc = (nx-1)/(2+3*(linear_truncation-truncation)/ndgl*std::pow(std::cos(lat),2)); } else { // cubic trc = (nx-1)/(2+std::pow(std::cos(lat),2))-1; } trc = std::min(truncation, trc); - //Log::info() << "truncation=" << truncation << " trc=" << trc << " nx=" << nx << " nxmax=" << nxmax << " latsin2=" << std::pow(std::cos(lat),2) << std::endl; + //std::cout << "truncation=" << truncation << " 2./3.*ndgl-1=" << 2./3.*ndgl-1 << " nx=" << nx << " nxmax=" << nxmax << " latsin2=" << std::pow(std::cos(lat),2) << std::endl; return trc; } diff --git a/src/atlas/trans/local/FourierTransforms.h b/src/atlas/trans/local/FourierTransforms.h index 812bcf141..019fe9e36 100644 --- a/src/atlas/trans/local/FourierTransforms.h +++ b/src/atlas/trans/local/FourierTransforms.h @@ -34,6 +34,7 @@ int fourier_truncation( const int truncation, const int nx, const int nxmax, + const int ndgl, const double lat ); // -------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index c6837afaa..4b6c4e1fa 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -207,7 +207,7 @@ void TransLocal::invtrans_uv( int idx = 0; for( size_t j=0; j=m ) { + if( trans::fourier_truncation(trc, g.nx(j), g.nxmax(), g.ny(), lat)>=m ) { rgp[idx++] = sphericalharmonics_analytic_point(n, m, imag, lon, lat, ivar_in, ivar_out); } else { rgp[idx++] = 0.; @@ -822,7 +822,7 @@ CASE( "test_trans_vordiv_with_translib" ) double rms_gen = compute_rms(g.size(), rgp.data()+pos*g.size(), rgp_analytic.data()); double rms_diff = compute_rms(g.size(), rgp.data()+pos*g.size(), gp.data()+pos*g.size()); - if( rms_gen >= tolerance || rms_trans >= tolerance || rms_diff >= tolerance ) { + if( rms_gen>=tolerance || rms_trans>=tolerance || rms_diff>=tolerance ) { Log::info() << "Case " << icase << " ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; ATLAS_DEBUG_VAR(rms_gen); ATLAS_DEBUG_VAR(rms_trans); @@ -857,6 +857,28 @@ CASE( "test_trans_invtrans" ) { trans.invtrans(1,rspec.data(),rgp.data()); } + +//----------------------------------------------------------------------------- + +CASE( "test_trans_fourier_truncation" ) +{ + Log::info() << "test_trans_fourier_truncation" << std::endl; + // test transgeneral by comparing its result with the trans library + // this test is based on the test_nomesh case in test_trans.cc + + Grid g( "N640" ); + grid::StructuredGrid gs(g); + int ndgl = gs.ny(); + //int trc = ndgl-1; // linear + //int trc = 2./3.*ndgl-1; // quadratic + int trc = ndgl/2. -1; // cubic + trans::Trans trans(g, trc) ; + for( int j=0; j Date: Mon, 12 Feb 2018 14:50:50 +0000 Subject: [PATCH 296/355] ATLAS-135 fourier_truncation produces identical truncation for O and F N is slightly different for quadratic and cubic because local transform doesn't require the number of modes to be monotone --- src/atlas/trans/local/FourierTransforms.cc | 7 ++++--- src/atlas/trans/local/FourierTransforms.h | 3 ++- src/atlas/trans/local/TransLocal.cc | 3 ++- src/tests/trans/test_transgeneral.cc | 18 ++++++++++++------ 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc index 741fd7709..75d3fc816 100644 --- a/src/atlas/trans/local/FourierTransforms.cc +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -45,11 +45,12 @@ int fourier_truncation( const int nx, const int nxmax, const int ndgl, - const double lat ) + const double lat, + const bool fullgrid ) { int linear_truncation = ndgl-1; int trc = truncation; - if( truncation>=linear_truncation ) { + if( truncation>=linear_truncation || fullgrid ) { // linear trc = (nx-1)/2; } else if( truncation>=ndgl*2/3-1 ) { @@ -61,7 +62,7 @@ int fourier_truncation( trc = (nx-1)/(2+std::pow(std::cos(lat),2))-1; } trc = std::min(truncation, trc); - //std::cout << "truncation=" << truncation << " 2./3.*ndgl-1=" << 2./3.*ndgl-1 << " nx=" << nx << " nxmax=" << nxmax << " latsin2=" << std::pow(std::cos(lat),2) << std::endl; + //std::cout << "truncation=" << truncation << " trc=" << trc << " ndgl*2/3-1=" << ndgl*2/3-1 << " nx=" << nx << " nxmax=" << nxmax << " latsin2=" << std::pow(std::cos(lat),2) << std::endl; return trc; } diff --git a/src/atlas/trans/local/FourierTransforms.h b/src/atlas/trans/local/FourierTransforms.h index 019fe9e36..dfbf1dccf 100644 --- a/src/atlas/trans/local/FourierTransforms.h +++ b/src/atlas/trans/local/FourierTransforms.h @@ -35,7 +35,8 @@ int fourier_truncation( const int nx, const int nxmax, const int ndgl, - const double lat ); + const double lat, + const bool fullgrid ); // -------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 4b6c4e1fa..3d0114761 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -205,9 +205,10 @@ void TransLocal::invtrans_uv( if( grid::StructuredGrid g = grid_ ) { ATLAS_TRACE( "invtrans_uv structured"); int idx = 0; + bool fullgrid = (g.nx(0)==g.nxmax()); for( size_t j=0; j=m ) { + if( trans::fourier_truncation(trc, g.nx(j), g.nxmax(), g.ny(), lat, fullgrid)>=m ) { rgp[idx++] = sphericalharmonics_analytic_point(n, m, imag, lon, lat, ivar_in, ivar_out); } else { rgp[idx++] = 0.; @@ -857,27 +858,32 @@ CASE( "test_trans_invtrans" ) { trans.invtrans(1,rspec.data(),rgp.data()); } +#endif //----------------------------------------------------------------------------- +#if 0 CASE( "test_trans_fourier_truncation" ) { Log::info() << "test_trans_fourier_truncation" << std::endl; // test transgeneral by comparing its result with the trans library // this test is based on the test_nomesh case in test_trans.cc - Grid g( "N640" ); + Grid g( "F640" ); grid::StructuredGrid gs(g); int ndgl = gs.ny(); - //int trc = ndgl-1; // linear + //int trc = 2*ndgl; // extreme high truncation (below linear) + int trc = ndgl-1; // linear //int trc = 2./3.*ndgl-1; // quadratic - int trc = ndgl/2. -1; // cubic + //int trc = ndgl/2. -1; // cubic trans::Trans trans(g, trc) ; + bool fullgrid = (gs.nx(0)==gs.nxmax()); for( int j=0; j Date: Mon, 12 Feb 2018 17:30:46 +0000 Subject: [PATCH 297/355] ATLAS-135 also tested case between linear and quadtratic with the new version of transi --- src/tests/trans/test_transgeneral.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 6b5768f88..8c731e1b8 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -869,11 +869,12 @@ CASE( "test_trans_fourier_truncation" ) // test transgeneral by comparing its result with the trans library // this test is based on the test_nomesh case in test_trans.cc - Grid g( "F640" ); + Grid g( "O640" ); grid::StructuredGrid gs(g); int ndgl = gs.ny(); //int trc = 2*ndgl; // extreme high truncation (below linear) int trc = ndgl-1; // linear + //int trc = 5./6.*ndgl-1; // between linear and quadratic //int trc = 2./3.*ndgl-1; // quadratic //int trc = ndgl/2. -1; // cubic trans::Trans trans(g, trc) ; @@ -881,7 +882,7 @@ CASE( "test_trans_fourier_truncation" ) for( int j=0; j Date: Tue, 13 Feb 2018 16:43:46 +0000 Subject: [PATCH 298/355] ATLAS-135 generalised test if grid is regular --- src/atlas/trans/local/TransLocal.cc | 3 +-- src/tests/trans/test_transgeneral.cc | 8 +++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 3d0114761..bffe9fa86 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -205,10 +205,9 @@ void TransLocal::invtrans_uv( if( grid::StructuredGrid g = grid_ ) { ATLAS_TRACE( "invtrans_uv structured"); int idx = 0; - bool fullgrid = (g.nx(0)==g.nxmax()); for( size_t j=0; j=m ) { + if( trans::fourier_truncation(trc, g.nx(j), g.nxmax(), g.ny(), lat, grid::RegularGrid(g))>=m ) { rgp[idx++] = sphericalharmonics_analytic_point(n, m, imag, lon, lat, ivar_in, ivar_out); } else { rgp[idx++] = 0.; @@ -869,7 +868,7 @@ CASE( "test_trans_fourier_truncation" ) // test transgeneral by comparing its result with the trans library // this test is based on the test_nomesh case in test_trans.cc - Grid g( "O640" ); + Grid g( "F640" ); grid::StructuredGrid gs(g); int ndgl = gs.ny(); //int trc = 2*ndgl; // extreme high truncation (below linear) @@ -878,10 +877,9 @@ CASE( "test_trans_fourier_truncation" ) //int trc = 2./3.*ndgl-1; // quadratic //int trc = ndgl/2. -1; // cubic trans::Trans trans(g, trc) ; - bool fullgrid = (gs.nx(0)==gs.nxmax()); for( int j=0; j Date: Tue, 13 Feb 2018 17:17:09 +0000 Subject: [PATCH 299/355] ATLAS-135 Treat grids with projection as unstructured --- src/atlas/trans/local/TransLocal.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index bffe9fa86..900911c2e 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -48,8 +48,9 @@ TransLocal::TransLocal( const Cache& cache, const Grid& grid, const long truncat precompute_ ( config.getBool("precompute", true) ) { if ( precompute_ ) { - if( grid::StructuredGrid g = grid_ ) { + if( grid::StructuredGrid(grid_) && not grid_.projection() ) { ATLAS_TRACE("Precompute legendre structured"); + grid::StructuredGrid g(grid_); size_t size(0); legendre_begin_.resize( g.ny() ); for( size_t j=0; j Date: Sun, 15 Oct 2017 23:34:02 +0100 Subject: [PATCH 300/355] ATLAS-147 Caching of NodeColumns and EdgeColumns communication patterns --- src/atlas/CMakeLists.txt | 1 + src/atlas/functionspace/EdgeColumns.cc | 146 ++++++++--- src/atlas/functionspace/EdgeColumns.h | 11 +- src/atlas/functionspace/NodeColumns.cc | 229 +++++++++++------- src/atlas/functionspace/NodeColumns.h | 43 +--- src/atlas/mesh/Halo.cc | 7 + src/atlas/mesh/Halo.h | 12 +- src/atlas/mesh/actions/BuildDualMesh.cc | 5 +- src/atlas/parallel/Checksum.cc | 15 +- src/atlas/parallel/Checksum.h | 9 +- src/atlas/parallel/GatherScatter.cc | 2 + src/atlas/parallel/GatherScatter.h | 2 +- src/atlas/util/detail/Cache.h | 46 ++++ .../atlas-parallel-interpolation.cc | 4 +- 14 files changed, 335 insertions(+), 197 deletions(-) create mode 100644 src/atlas/util/detail/Cache.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index 04f0f39c7..d738d7811 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -467,6 +467,7 @@ util/Rotation.h util/SphericalPolygon.cc util/SphericalPolygon.h util/detail/BlackMagic.h +util/detail/Cache.h ) list( APPEND atlas_internals_srcs diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 3ce1e32bf..5bb6a3ef2 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -10,25 +10,28 @@ #include #include +#include #include "eckit/utils/MD5.h" +#include "atlas/array/MakeView.h" +#include "atlas/functionspace/EdgeColumns.h" #include "atlas/library/config.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildHalo.h" +#include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildPeriodicBoundaries.h" -#include "atlas/functionspace/EdgeColumns.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/IsGhostNode.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/parallel/Checksum.h" +#include "atlas/parallel/GatherScatter.h" +#include "atlas/parallel/HaloExchange.h" #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/ErrorHandling.h" -#include "atlas/parallel/HaloExchange.h" -#include "atlas/parallel/GatherScatter.h" -#include "atlas/parallel/Checksum.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "atlas/array/MakeView.h" +#include "atlas/util/detail/Cache.h" + #ifdef ATLAS_HAVE_FORTRAN #define REMOTE_IDX_BASE 1 @@ -63,6 +66,82 @@ array::LocalView make_leveled_view(const Field &field) } } +class EdgeColumnsHaloExchangeCache : public util::Cache { +private: + using Base = util::Cache; + EdgeColumnsHaloExchangeCache() {} +public: + static EdgeColumnsHaloExchangeCache& instance() { + static EdgeColumnsHaloExchangeCache inst; + return inst; + } + value_type* get( const Mesh& mesh ) { + creator_type creator = std::bind( &EdgeColumnsHaloExchangeCache::create, mesh ); + std::ostringstream key ; + key << "mesh[address="<setup( array::make_view(mesh.edges().partition()).data(), + array::make_view(mesh.edges().remote_index()).data(), + REMOTE_IDX_BASE, + mesh.edges().size()); + return value; + } +}; + +class EdgeColumnsGatherScatterCache : public util::Cache { +private: + using Base = util::Cache; + EdgeColumnsGatherScatterCache() {} +public: + static EdgeColumnsGatherScatterCache& instance() { + static EdgeColumnsGatherScatterCache inst; + return inst; + } + value_type* get( const Mesh& mesh ) { + creator_type creator = std::bind( &EdgeColumnsGatherScatterCache::create, mesh ); + std::ostringstream key ; + key << "mesh[address="<setup(array::make_view(mesh.edges().partition()).data(), + array::make_view(mesh.edges().remote_index()).data(), + REMOTE_IDX_BASE, + array::make_view(mesh.edges().global_index()).data(), + mesh.edges().size()); + return value; + } +}; + +class EdgeColumnsChecksumCache : public util::Cache { +private: + using Base = util::Cache; + EdgeColumnsChecksumCache() {} +public: + static EdgeColumnsChecksumCache& instance() { + static EdgeColumnsChecksumCache inst; + return inst; + } + value_type* get( const Mesh& mesh ) { + creator_type creator = std::bind( &EdgeColumnsChecksumCache::create, mesh ); + std::ostringstream key ; + key << "mesh[address="< gather( EdgeColumnsGatherScatterCache::instance().get(mesh) ); + value->setup( gather ); + return value; + } +}; void EdgeColumns::set_field_metadata(const eckit::Configuration& config, Field& field) const { @@ -159,7 +238,6 @@ EdgeColumns::EdgeColumns( const Mesh& mesh, const eckit::Configuration ¶ms ) ASSERT( mesh_halo == halo ); - constructor(); } @@ -197,43 +275,19 @@ void EdgeColumns::constructor() { ATLAS_TRACE("EdgeColumns()"); - nb_edges_ = mesh().edges().size(); - - gather_scatter_.reset(new parallel::GatherScatter()); - halo_exchange_.reset(new parallel::HaloExchange()); - checksum_.reset(new parallel::Checksum()); - - const Field& partition = edges().partition(); - const Field& remote_index = edges().remote_index(); - const Field& global_index = edges().global_index(); - - ATLAS_TRACE_SCOPE("Setup halo_exchange") - { - halo_exchange_->setup( - array::make_view(partition).data(), - array::make_view(remote_index).data(),REMOTE_IDX_BASE, - nb_edges_); + ATLAS_TRACE_SCOPE("HaloExchange") { + halo_exchange_.reset( EdgeColumnsHaloExchangeCache::instance().get( mesh_ ) ); } - ATLAS_TRACE_SCOPE("Setup gather_scatter") - { - gather_scatter_->setup( - array::make_view(partition).data(), - array::make_view(remote_index).data(),REMOTE_IDX_BASE, - array::make_view(global_index).data(), - nb_edges_); + ATLAS_TRACE_SCOPE("Setup gather_scatter") { + gather_scatter_.reset( EdgeColumnsGatherScatterCache::instance().get( mesh_ ) ); } - ATLAS_TRACE_SCOPE("Setup checksum") - { - checksum_->setup( - array::make_view(partition).data(), - array::make_view(remote_index).data(),REMOTE_IDX_BASE, - array::make_view(global_index).data(), - nb_edges_); + ATLAS_TRACE_SCOPE("Setup checksum") { + checksum_.reset( EdgeColumnsChecksumCache::instance().get( mesh_ ) ); } - nb_edges_global_ = gather_scatter_->glb_dof(); + nb_edges_ = mesh().edges().size(); } EdgeColumns::~EdgeColumns() {} @@ -255,6 +309,8 @@ size_t EdgeColumns::nb_edges() const size_t EdgeColumns::nb_edges_global() const { + if( nb_edges_global_ >= 0 ) return nb_edges_global_; + nb_edges_global_ = gather().glb_dof(); return nb_edges_global_; } @@ -305,6 +361,8 @@ void EdgeColumns::haloExchange( Field& field ) const } const parallel::HaloExchange& EdgeColumns::halo_exchange() const { + if (halo_exchange_) return *halo_exchange_; + halo_exchange_.reset( EdgeColumnsHaloExchangeCache::instance().get( mesh_ ) ); return *halo_exchange_; } @@ -354,10 +412,16 @@ void EdgeColumns::gather( const Field& local, Field& global ) const } const parallel::GatherScatter& EdgeColumns::gather() const { + if( gather_scatter_ ) + return *gather_scatter_; + gather_scatter_.reset( EdgeColumnsGatherScatterCache::instance().get( mesh_ ) ); return *gather_scatter_; } const parallel::GatherScatter& EdgeColumns::scatter() const { + if( gather_scatter_ ) + return *gather_scatter_; + gather_scatter_.reset( EdgeColumnsGatherScatterCache::instance().get( mesh_ ) ); return *gather_scatter_; } @@ -475,6 +539,8 @@ std::string EdgeColumns::checksum( const Field& field ) const { const parallel::Checksum& EdgeColumns::checksum() const { + if (checksum_) return *checksum_; + checksum_.reset( EdgeColumnsChecksumCache::instance().get( mesh_ ) ); return *checksum_; } diff --git a/src/atlas/functionspace/EdgeColumns.h b/src/atlas/functionspace/EdgeColumns.h index 6a59c4ad5..d1dec3252 100644 --- a/src/atlas/functionspace/EdgeColumns.h +++ b/src/atlas/functionspace/EdgeColumns.h @@ -89,8 +89,6 @@ class EdgeColumns : public FunctionSpaceImpl private: // methods - std::string gather_scatter_name() const; - std::string checksum_name() const; void constructor(); size_t config_size(const eckit::Configuration& config) const; array::DataType config_datatype(const eckit::Configuration&) const; @@ -106,11 +104,10 @@ class EdgeColumns : public FunctionSpaceImpl size_t nb_levels_; mesh::HybridElements& edges_; // non-const because functionspace may modify mesh size_t nb_edges_; - size_t nb_edges_global_; - - eckit::SharedPtr gather_scatter_; // without ghost - eckit::SharedPtr halo_exchange_; - eckit::SharedPtr checksum_; + mutable long nb_edges_global_{-1}; + mutable eckit::SharedPtr gather_scatter_; // without ghost + mutable eckit::SharedPtr halo_exchange_; + mutable eckit::SharedPtr checksum_; }; // ------------------------------------------------------------------- diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 95c2311c1..6d4805123 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -12,27 +12,31 @@ #include #include #include +#include #include "eckit/os/BackTrace.h" #include "eckit/utils/MD5.h" +#include "atlas/array/ArrayView.h" +#include "atlas/functionspace/NodeColumns.h" #include "atlas/library/config.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/mesh/Nodes.h" -#include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildHalo.h" +#include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildPeriodicBoundaries.h" -#include "atlas/functionspace/NodeColumns.h" #include "atlas/mesh/IsGhostNode.h" -#include "atlas/parallel/HaloExchange.h" -#include "atlas/parallel/GatherScatter.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" #include "atlas/parallel/Checksum.h" +#include "atlas/parallel/GatherScatter.h" +#include "atlas/parallel/HaloExchange.h" #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Trace.h" +#include "atlas/util/detail/Cache.h" + + #undef atlas_omp_critical_ordered #define atlas_omp_critical_ordered atlas_omp_critical -#include "atlas/array/ArrayView.h" #ifdef ATLAS_HAVE_FORTRAN #define REMOTE_IDX_BASE 1 @@ -40,6 +44,7 @@ #define REMOTE_IDX_BASE 0 #endif + namespace atlas { namespace functionspace { namespace detail { @@ -98,22 +103,121 @@ array::LocalView make_per_level_view(const Field &field) } + +class NodeColumnsHaloExchangeCache : public util::Cache { +private: + using Base = util::Cache; + NodeColumnsHaloExchangeCache() {} +public: + static NodeColumnsHaloExchangeCache& instance() { + static NodeColumnsHaloExchangeCache inst; + return inst; + } + value_type* get( const Mesh& mesh, long halo ) { + creator_type creator = std::bind( &NodeColumnsHaloExchangeCache::create, mesh, halo ); + std::ostringstream key ; + key << "mesh[address="<setup( array::make_view(mesh.nodes().partition()).data(), + array::make_view(mesh.nodes().remote_index()).data(), + REMOTE_IDX_BASE,nb_nodes); + + return value; + } +}; + +class NodeColumnsGatherScatterCache : public util::Cache { +private: + using Base = util::Cache; + NodeColumnsGatherScatterCache() {} +public: + static NodeColumnsGatherScatterCache& instance() { + static NodeColumnsGatherScatterCache inst; + return inst; + } + value_type* get( const Mesh& mesh ) { + creator_type creator = std::bind( &NodeColumnsGatherScatterCache::create, mesh ); + std::ostringstream key ; + key << "mesh.nodes[address="< mask(mesh.nodes().size()); + const size_t npts = mask.size(); + atlas_omp_parallel_for( size_t n=0; n This would add periodic west-bc to the gather, but means that global-sums, means, etc are computed wrong + //if( mask[j] == 1 && internals::Topology::check(flags(j),internals::Topology::BC) ) { + // mask[j] = 0; + //} + } + + value->setup(array::make_view(mesh.nodes().partition()).data(), + array::make_view(mesh.nodes().remote_index()).data(), + REMOTE_IDX_BASE, + array::make_view(mesh.nodes().global_index()).data(), + mask.data(),mesh.nodes().size()); + return value; + } +}; + +class NodeColumnsChecksumCache : public util::Cache { +private: + using Base = util::Cache; + NodeColumnsChecksumCache() {} +public: + static NodeColumnsChecksumCache& instance() { + static NodeColumnsChecksumCache inst; + return inst; + } + value_type* get( const Mesh& mesh ) { + creator_type creator = std::bind( &NodeColumnsChecksumCache::create, mesh ); + std::ostringstream key ; + key << "mesh[address="< gather( NodeColumnsGatherScatterCache::instance().get(mesh) ); + value->setup( gather ); + return value; + } +}; + NodeColumns::NodeColumns( Mesh mesh ) : NodeColumns( mesh, util::NoConfig() ) { } -NodeColumns::NodeColumns(Mesh mesh, const mesh::Halo &halo) : - NodeColumns( mesh, util::Config("halo",halo.size()) ) { -} - NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration & config ) : mesh_(mesh), nodes_(mesh_.nodes()), - halo_( mesh::Halo(config.getInt("halo",0) ) ), nb_levels_( config.getInt("levels",0) ), nb_nodes_(nodes_.size()), nb_nodes_global_(0) { ATLAS_TRACE(); + if( config.has("halo") ) { + halo_ = mesh::Halo(config.getInt("halo") ); + } else { + halo_ = mesh::Halo(mesh); + } constructor(); } @@ -123,7 +227,6 @@ void NodeColumns::constructor() mesh::actions::build_nodes_parallel_fields( mesh_.nodes() ); mesh::actions::build_periodic_boundaries(mesh_); - gather_scatter_.reset(new parallel::GatherScatter()); halo_exchange_.reset(new parallel::HaloExchange()); checksum_.reset(new parallel::Checksum()); @@ -144,65 +247,19 @@ void NodeColumns::constructor() } } - ATLAS_TRACE_SCOPE("HaloExchange") - { - Field& part = mesh_.nodes().partition(); - Field& ridx = mesh_.nodes().remote_index(); - halo_exchange_->setup( array::make_view(part).data(), - array::make_view(ridx).data(), - REMOTE_IDX_BASE,nb_nodes_); + ATLAS_TRACE_SCOPE("HaloExchange") { + halo_exchange_.reset( NodeColumnsHaloExchangeCache::instance().get(mesh_,halo_.size()) ); } - ATLAS_TRACE_SCOPE("GatherScatter") - { - // Create new gather_scatter - gather_scatter_.reset( new parallel::GatherScatter() ); - - Field& ridx = mesh_.nodes().remote_index(); - Field& part = mesh_.nodes().partition(); - Field& gidx = mesh_.nodes().global_index(); - - mesh::IsGhostNode is_ghost(mesh_.nodes()); - std::vector mask(mesh_.nodes().size()); - const size_t npts = mask.size(); - atlas_omp_parallel_for( size_t n=0; n This would add periodic west-bc to the gather, but means that global-sums, means, etc are computed wrong - //if( mask[j] == 1 && internals::Topology::check(flags(j),internals::Topology::BC) ) { - // mask[j] = 0; - //} - } - gather_scatter_->setup(array::make_view(part).data(), - array::make_view(ridx).data(), - REMOTE_IDX_BASE, - array::make_view(gidx).data(), - mask.data(),nb_nodes_); + ATLAS_TRACE_SCOPE("GatherScatter") { + gather_scatter_.reset( NodeColumnsGatherScatterCache::instance().get(mesh_) ); } - ATLAS_TRACE_SCOPE("Checksum") - { - - // Create new checksum - checksum_.reset( new parallel::Checksum() ); - - Field& ridx = mesh_.nodes().remote_index(); - Field& part = mesh_.nodes().partition(); - Field& gidx = mesh_.nodes().global_index(); - mesh::IsGhostNode is_ghost(mesh_.nodes()); - std::vector mask(mesh_.nodes().size()); - const size_t npts = mask.size(); - atlas_omp_parallel_for( size_t n=0; nsetup(array::make_view(part).data(), - array::make_view(ridx).data(), - REMOTE_IDX_BASE, - array::make_view(gidx).data(), - mask.data(),nb_nodes_); + ATLAS_TRACE_SCOPE("Checksum") { + checksum_.reset( NodeColumnsChecksumCache::instance().get(mesh_) ); } - nb_nodes_global_ = gather_scatter_->glb_dof(); + nb_nodes_global_ = gather().glb_dof(); } NodeColumns::~NodeColumns() {} @@ -224,26 +281,11 @@ size_t NodeColumns::nb_nodes() const size_t NodeColumns::nb_nodes_global() const { + if( nb_nodes_global_>=0 ) return nb_nodes_global_; + nb_nodes_global_ = gather().glb_dof(); return nb_nodes_global_; } -std::string NodeColumns::halo_name() const -{ - std::stringstream ss; ss << "nodes_" << halo_.size(); - return ss.str(); -} - -std::string NodeColumns::gather_scatter_name() const -{ - return "nodes_gather_scatter"; -} - -std::string NodeColumns::checksum_name() const -{ - return "nodes_checksum"; -} - - size_t NodeColumns::config_nb_nodes(const eckit::Configuration& config) const { size_t size = nb_nodes(); @@ -453,10 +495,14 @@ void NodeColumns::gather( const Field& local, Field& global ) const } const parallel::GatherScatter& NodeColumns::gather() const { + if (gather_scatter_) return *gather_scatter_; + gather_scatter_.reset( NodeColumnsGatherScatterCache::instance().get( mesh_ ) ); return *gather_scatter_; } const parallel::GatherScatter& NodeColumns::scatter() const { + if (gather_scatter_) return *gather_scatter_; + gather_scatter_.reset( NodeColumnsGatherScatterCache::instance().get( mesh_ ) ); return *gather_scatter_; } @@ -2139,18 +2185,22 @@ NodeColumns::NodeColumns( const FunctionSpace& functionspace ) : functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { } -NodeColumns::NodeColumns( Mesh mesh, const mesh::Halo& halo ) : - FunctionSpace( new detail::NodeColumns(mesh,halo) ), - functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { + +namespace { +detail::NodeColumns* make_functionspace( Mesh mesh, const eckit::Configuration& config ) { + ATLAS_DEBUG_VAR( mesh.get() ); + ATLAS_DEBUG_VAR( config ); + return new detail::NodeColumns(mesh, config); +} } NodeColumns::NodeColumns( Mesh mesh ) : - FunctionSpace( new detail::NodeColumns(mesh) ), + FunctionSpace( make_functionspace(mesh,util::NoConfig()) ), functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { } NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration& config ) : - FunctionSpace( new detail::NodeColumns(mesh, config) ), + FunctionSpace( make_functionspace(mesh, config) ), functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { } @@ -2226,9 +2276,6 @@ const parallel::Checksum& NodeColumns::checksum() const { - - - } // namespace functionspace } // namespace atlas diff --git a/src/atlas/functionspace/NodeColumns.h b/src/atlas/functionspace/NodeColumns.h index dac8581a3..d9ae00289 100644 --- a/src/atlas/functionspace/NodeColumns.h +++ b/src/atlas/functionspace/NodeColumns.h @@ -49,7 +49,6 @@ class NodeColumns : public FunctionSpaceImpl { public: - NodeColumns( Mesh mesh, const mesh::Halo & ); NodeColumns( Mesh mesh, const eckit::Configuration & ); NodeColumns( Mesh mesh ); @@ -234,9 +233,6 @@ class NodeColumns : public FunctionSpaceImpl private: // methods - std::string halo_name() const; - std::string gather_scatter_name() const; - std::string checksum_name() const; void constructor(); size_t config_nb_nodes(const eckit::Configuration&) const; @@ -254,12 +250,12 @@ class NodeColumns : public FunctionSpaceImpl mesh::Nodes& nodes_; // non-const because functionspace may modify mesh mesh::Halo halo_; size_t nb_nodes_; - size_t nb_nodes_global_; + mutable long nb_nodes_global_{-1}; size_t nb_levels_; - eckit::SharedPtr gather_scatter_; // without ghost - eckit::SharedPtr halo_exchange_; - eckit::SharedPtr checksum_; + mutable eckit::SharedPtr gather_scatter_; // without ghost + mutable eckit::SharedPtr halo_exchange_; + mutable eckit::SharedPtr checksum_; private: @@ -433,7 +429,6 @@ class NodeColumns : public FunctionSpace NodeColumns(); NodeColumns( const FunctionSpace& ); - NodeColumns( Mesh mesh, const mesh::Halo & ); NodeColumns( Mesh mesh ); NodeColumns( Mesh mesh, const eckit::Configuration & ); @@ -621,11 +616,6 @@ void NodeColumns::sum( const Field& field, Value& sum, size_t& N ) const { functionspace_->sum(field,sum,N); } -//template< typename Value > -//void NodeColumns::sum( const Field& field, std::vector& sum, size_t& N ) const { -// functionspace_->sum(field,sum,N); -//} - inline void NodeColumns::sumPerLevel( const Field& field, Field& sum, size_t& N ) const { functionspace_->sumPerLevel(field,sum,N); } @@ -635,11 +625,6 @@ void NodeColumns::orderIndependentSum( const Field& field, Value& sum, size_t& N functionspace_->orderIndependentSum(field,sum,N); } -//template< typename Value > -//void NodeColumns::orderIndependentSum( const Field& field, std::vector& sum, size_t& N ) const { -// functionspace_->orderIndependentSum(field,sum,N); -//} - inline void NodeColumns::orderIndependentSumPerLevel( const Field& field, Field& sum, size_t& N ) const { functionspace_->orderIndependentSumPerLevel(field,sum,N); } @@ -654,16 +639,6 @@ void NodeColumns::maximum( const Field& field, Value& maximum ) const { functionspace_->maximum(field,maximum); } -//template< typename Value > -//void NodeColumns::minimum( const Field& field, std::vector& minimum ) const { -// functionspace_->minimum(field,minimum); -//} - -//template< typename Value > -//void NodeColumns::maximum( const Field& field, std::vector& maximum) const { -// functionspace_->maximum(field,maximum); -//} - inline void NodeColumns::minimumPerLevel( const Field& field, Field& minimum ) const { return functionspace_->minimumPerLevel(field,minimum); } @@ -725,11 +700,6 @@ void NodeColumns::mean( const Field& field, Value& mean, size_t& N ) const { functionspace_->mean(field,mean,N); } -//template< typename Value > -//void NodeColumns::mean( const Field& field, std::vector& mean, size_t& N ) const { -// functionspace_->mean(field,mean,N); -//} - inline void NodeColumns::meanPerLevel( const Field& field, Field& mean, size_t& N ) const { functionspace_->meanPerLevel(field,mean,N); } @@ -739,11 +709,6 @@ void NodeColumns::meanAndStandardDeviation( const Field& field, Value& mean, Val functionspace_->meanAndStandardDeviation(field,mean,stddev,N); } -//template< typename Value > -//void NodeColumns::meanAndStandardDeviation( const Field& field, std::vector& mean, std::vector& stddev, size_t& N ) const { -// functionspace_->meanAndStandardDeviation(field,mean,stddev,N); -//} - inline void NodeColumns::meanAndStandardDeviationPerLevel( const Field& field, Field& mean, Field& stddev, size_t& N ) const { functionspace_->meanAndStandardDeviationPerLevel(field,mean,stddev,N); } diff --git a/src/atlas/mesh/Halo.cc b/src/atlas/mesh/Halo.cc index 047cdfb84..853a55032 100644 --- a/src/atlas/mesh/Halo.cc +++ b/src/atlas/mesh/Halo.cc @@ -8,6 +8,7 @@ * does it submit to any jurisdiction. */ +#include "eckit/exception/Exceptions.h" #include "atlas/mesh/Halo.h" #include "atlas/mesh/Mesh.h" #include "atlas/util/Metadata.h" @@ -21,6 +22,12 @@ Halo::Halo(const Mesh& mesh) mesh.metadata().get("halo",size_); } +long Halo::size() const { + ASSERT( size_>=0 ); + return size_; +} + + } // namespace mesh } // namespace atlas diff --git a/src/atlas/mesh/Halo.h b/src/atlas/mesh/Halo.h index f406f0482..e731e8a55 100644 --- a/src/atlas/mesh/Halo.h +++ b/src/atlas/mesh/Halo.h @@ -8,8 +8,7 @@ * does it submit to any jurisdiction. */ -#ifndef atlas_mesh_Halo_h -#define atlas_mesh_Halo_h +#pragma once #include @@ -25,14 +24,13 @@ namespace mesh { class Halo { public: + Halo() {} Halo(const Mesh& mesh); - Halo(const size_t size) : size_(size) {} - size_t size() const { return size_; } + Halo(const long size) : size_(size) {} + long size() const; private: - size_t size_; + long size_{-1}; }; } // namespace mesh } // namespace atlas - -#endif // atlas_mesh_Halo_h diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index f9b82634c..d3d1b62c1 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -135,7 +135,7 @@ void build_median_dual_mesh( Mesh& mesh ) array::make_view(skewness).assign(0.); array::make_view(alpha).assign(0.5); - functionspace::NodeColumns nodes_fs(mesh, Halo(mesh)); + functionspace::NodeColumns nodes_fs(mesh ); { ATLAS_TRACE("halo-exchange dual_volumes"); nodes_fs.haloExchange(nodes.field( "dual_volumes" )); @@ -146,7 +146,6 @@ void build_median_dual_mesh( Mesh& mesh ) ATLAS_TRACE( "halo-exchange dual_normals" ); edges_fs.haloExchange(edges.field( "dual_normals" )); } - make_dual_normals_outward(mesh); } @@ -454,7 +453,7 @@ void build_brick_dual_mesh(const Grid& grid, Mesh& mesh) } - functionspace::NodeColumns nodes_fs( mesh,Halo(mesh) ); + functionspace::NodeColumns nodes_fs( mesh ); nodes_fs.haloExchange(nodes.field("dual_volumes")); } else diff --git a/src/atlas/parallel/Checksum.cc b/src/atlas/parallel/Checksum.cc index 901edd763..ebe9ebf46 100644 --- a/src/atlas/parallel/Checksum.cc +++ b/src/atlas/parallel/Checksum.cc @@ -32,8 +32,8 @@ void Checksum::setup( const int part[], const int parsize ) { parsize_ = parsize; - gather_.setup(part,remote_idx,base, - glb_idx,parsize); + gather_.reset( new GatherScatter() ); + gather_->setup(part,remote_idx,base,glb_idx,parsize); is_setup_ = true; } @@ -43,11 +43,18 @@ void Checksum::setup( const int part[], const gidx_t glb_idx[], const int mask[], const int parsize ) { parsize_ = parsize; - gather_.setup(part,remote_idx,base, - glb_idx,mask,parsize); + gather_.reset( new GatherScatter() ); + gather_->setup(part,remote_idx,base,glb_idx,mask,parsize); is_setup_ = true; } +void Checksum::setup( const eckit::SharedPtr& gather ) { + gather_ = gather; + parsize_ = gather->parsize_; + is_setup_ = true; +} + + ///////////////////// diff --git a/src/atlas/parallel/Checksum.h b/src/atlas/parallel/Checksum.h index 07042c171..2e65e3088 100644 --- a/src/atlas/parallel/Checksum.h +++ b/src/atlas/parallel/Checksum.h @@ -62,6 +62,9 @@ class Checksum: public eckit::Owned { void setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], const int mask[], const int parsize ); + + /// @brief Setup + void setup( const eckit::SharedPtr& ); template std::string execute( const DATA_TYPE lfield[], @@ -82,7 +85,7 @@ class Checksum: public eckit::Owned { private: // data std::string name_; - GatherScatter gather_; + eckit::SharedPtr gather_; bool is_setup_; size_t parsize_; }; @@ -107,10 +110,10 @@ std::string Checksum::execute( const DATA_TYPE data[], local_checksums[pp] = util::checksum(data+pp*var_size,var_size); } - std::vector global_checksums( parallel::mpi::comm().rank() == root ? gather_.glb_dof() : 0 ); + std::vector global_checksums( parallel::mpi::comm().rank() == root ? gather_->glb_dof() : 0 ); parallel::Field loc(local_checksums.data(),1); parallel::Field glb(global_checksums.data(),1); - gather_.gather(&loc,&glb,1); + gather_->gather(&loc,&glb,1); util::checksum_t glb_checksum = util::checksum( global_checksums.data(), diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index d924bdf51..0ca1073b8 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -98,6 +98,8 @@ void GatherScatter::setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], const int mask[], const size_t parsize ) { + ATLAS_TRACE("GatherScatter::setup"); + parsize_ = parsize; glbcounts_.resize(nproc); glbcounts_.assign(nproc,0); diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index f28dcd0c4..ecca1cb19 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -258,7 +258,7 @@ class GatherScatter: public eckit::Owned { bool is_setup_; - size_t parsize_; + size_t parsize_; friend class Checksum; int glb_cnt(size_t root) const { return myproc==root ? glbcnt_ : 0 ; } diff --git a/src/atlas/util/detail/Cache.h b/src/atlas/util/detail/Cache.h new file mode 100644 index 000000000..fb69fc367 --- /dev/null +++ b/src/atlas/util/detail/Cache.h @@ -0,0 +1,46 @@ +/* + * (C) Copyright 1996-2017 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 + +namespace atlas { +namespace util { + +template +class Cache { +public: + using key_type = Key; + using value_type = Value; + using creator_type = std::function; + + value_type* get(const key_type& key, const creator_type& creator) { + std::lock_guard guard(lock_); + auto it = map_.find(key); + if (it != map_.end()) { + auto& value = it->second; + if( value ) { + Log::debug() << key << " was found in cache" << std::endl; + return value; + } + } + Log::debug() << key << " not found in cache, creating new" << std::endl; + value_type* value = creator(); + map_[key] = value; + return value; + } +private: + std::mutex lock_; + std::map map_; +}; + +} // namespace util +} // namespace atlas diff --git a/src/sandbox/interpolation/atlas-parallel-interpolation.cc b/src/sandbox/interpolation/atlas-parallel-interpolation.cc index c0dad4954..2b3be3548 100644 --- a/src/sandbox/interpolation/atlas-parallel-interpolation.cc +++ b/src/sandbox/interpolation/atlas-parallel-interpolation.cc @@ -120,12 +120,12 @@ void AtlasParallelInterpolation::execute(const AtlasTool::Args& args) { Log::info() << "Partitioning source grid, halo of " << eckit::Plural(source_mesh_halo, "element") << std::endl; src.partition(src_grid); - functionspace::NodeColumns src_functionspace(src.mesh(), source_mesh_halo); + functionspace::NodeColumns src_functionspace(src.mesh(), option::halo(source_mesh_halo)); src.writeGmsh("src-mesh.msh"); Log::info() << "Partitioning target grid, halo of " << eckit::Plural(target_mesh_halo, "element") << std::endl; tgt.partition(tgt_grid, src); - functionspace::NodeColumns tgt_functionspace(tgt.mesh(), target_mesh_halo); + functionspace::NodeColumns tgt_functionspace(tgt.mesh(), option::halo(target_mesh_halo)); tgt.writeGmsh("tgt-mesh.msh"); From 0a729099eb4686a431e8d7cbd01e95db8cf4b15c Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 16 Oct 2017 09:12:01 +0100 Subject: [PATCH 301/355] ATLAS-147 On demand computation of NodeColumns and EdgeColumns communication patterns --- src/atlas/functionspace/EdgeColumns.cc | 44 ++++++++++++------------- src/atlas/functionspace/NodeColumns.cc | 42 +++++++++++------------ src/atlas/mesh/actions/BuildDualMesh.cc | 2 +- src/atlas/util/detail/Cache.h | 11 ++++--- 4 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 5bb6a3ef2..d82c64ac5 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -75,7 +75,7 @@ class EdgeColumnsHaloExchangeCache : public util::Cache get( const Mesh& mesh ) { creator_type creator = std::bind( &EdgeColumnsHaloExchangeCache::create, mesh ); std::ostringstream key ; key << "mesh[address="< get( const Mesh& mesh ) { creator_type creator = std::bind( &EdgeColumnsGatherScatterCache::create, mesh ); std::ostringstream key ; key << "mesh[address="< get( const Mesh& mesh ) { creator_type creator = std::bind( &EdgeColumnsChecksumCache::create, mesh ); std::ostringstream key ; key << "mesh[address="< get( const Mesh& mesh, long halo ) { creator_type creator = std::bind( &NodeColumnsHaloExchangeCache::create, mesh, halo ); std::ostringstream key ; key << "mesh[address="< get( const Mesh& mesh ) { creator_type creator = std::bind( &NodeColumnsGatherScatterCache::create, mesh ); std::ostringstream key ; key << "mesh.nodes[address="< get( const Mesh& mesh ) { creator_type creator = std::bind( &NodeColumnsChecksumCache::create, mesh ); std::ostringstream key ; key << "mesh[address="< 0) { mesh::actions::build_halo(mesh_,halo_.size()); @@ -247,19 +243,19 @@ void NodeColumns::constructor() } } - ATLAS_TRACE_SCOPE("HaloExchange") { - halo_exchange_.reset( NodeColumnsHaloExchangeCache::instance().get(mesh_,halo_.size()) ); - } +// ATLAS_TRACE_SCOPE("HaloExchange") { +// halo_exchange_.reset( NodeColumnsHaloExchangeCache::instance().get(mesh_,halo_.size()) ); +// } - ATLAS_TRACE_SCOPE("GatherScatter") { - gather_scatter_.reset( NodeColumnsGatherScatterCache::instance().get(mesh_) ); - } +// ATLAS_TRACE_SCOPE("GatherScatter") { +// gather_scatter_.reset( NodeColumnsGatherScatterCache::instance().get(mesh_) ); +// } - ATLAS_TRACE_SCOPE("Checksum") { - checksum_.reset( NodeColumnsChecksumCache::instance().get(mesh_) ); - } +// ATLAS_TRACE_SCOPE("Checksum") { +// checksum_.reset( NodeColumnsChecksumCache::instance().get(mesh_) ); +// } - nb_nodes_global_ = gather().glb_dof(); +// nb_nodes_global_ = gather().glb_dof(); } NodeColumns::~NodeColumns() {} @@ -445,7 +441,9 @@ void NodeColumns::haloExchange( Field& field, bool on_device ) const } const parallel::HaloExchange& NodeColumns::halo_exchange() const { - return *halo_exchange_;; + if ( halo_exchange_ ) return *halo_exchange_; + halo_exchange_ = NodeColumnsHaloExchangeCache::instance().get( mesh_, halo_.size() ); + return *halo_exchange_; } @@ -496,13 +494,13 @@ void NodeColumns::gather( const Field& local, Field& global ) const const parallel::GatherScatter& NodeColumns::gather() const { if (gather_scatter_) return *gather_scatter_; - gather_scatter_.reset( NodeColumnsGatherScatterCache::instance().get( mesh_ ) ); + gather_scatter_ = NodeColumnsGatherScatterCache::instance().get( mesh_ ); return *gather_scatter_; } const parallel::GatherScatter& NodeColumns::scatter() const { if (gather_scatter_) return *gather_scatter_; - gather_scatter_.reset( NodeColumnsGatherScatterCache::instance().get( mesh_ ) ); + gather_scatter_ = NodeColumnsGatherScatterCache::instance().get( mesh_ ); return *gather_scatter_; } @@ -599,6 +597,8 @@ std::string NodeColumns::checksum( const Field& field ) const { const parallel::Checksum& NodeColumns::checksum() const { + if (checksum_) return *checksum_; + checksum_ = NodeColumnsChecksumCache::instance().get( mesh_ ); return *checksum_; } diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index d3d1b62c1..f8b53862a 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -135,7 +135,7 @@ void build_median_dual_mesh( Mesh& mesh ) array::make_view(skewness).assign(0.); array::make_view(alpha).assign(0.5); - functionspace::NodeColumns nodes_fs(mesh ); + functionspace::NodeColumns nodes_fs(mesh); { ATLAS_TRACE("halo-exchange dual_volumes"); nodes_fs.haloExchange(nodes.field( "dual_volumes" )); diff --git a/src/atlas/util/detail/Cache.h b/src/atlas/util/detail/Cache.h index fb69fc367..421c1d243 100644 --- a/src/atlas/util/detail/Cache.h +++ b/src/atlas/util/detail/Cache.h @@ -11,6 +11,7 @@ #include #include #include +#include "eckit/memory/SharedPtr.h" namespace atlas { namespace util { @@ -22,24 +23,26 @@ class Cache { using value_type = Value; using creator_type = std::function; - value_type* get(const key_type& key, const creator_type& creator) { + eckit::SharedPtr get(const key_type& key, const creator_type& creator) { std::lock_guard guard(lock_); auto it = map_.find(key); if (it != map_.end()) { - auto& value = it->second; + eckit::SharedPtr value = it->second; if( value ) { Log::debug() << key << " was found in cache" << std::endl; return value; + } else { + Log::debug() << key << " was found in cache but is not valid. Revert to not found." << std::endl; } } Log::debug() << key << " not found in cache, creating new" << std::endl; - value_type* value = creator(); + eckit::SharedPtr value( creator() ); map_[key] = value; return value; } private: std::mutex lock_; - std::map map_; + std::map< key_type, eckit::SharedPtr > map_; }; } // namespace util From ecb8ba8b910ab0526ae887255c20c1db6e262991 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 1 Feb 2018 18:25:08 +0000 Subject: [PATCH 302/355] ATLAS-147 bugfix in NodeColumns::nb_nodes_global(), all tests pass --- src/atlas/functionspace/NodeColumns.cc | 3 ++- src/atlas/util/detail/Cache.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 24a692021..ddbf1a4cd 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -292,7 +292,8 @@ size_t NodeColumns::config_nb_nodes(const eckit::Configuration& config) const { size_t owner(0); config.get("owner",owner); - size = (parallel::mpi::comm().rank() == owner ? nb_nodes_global() : 0); + size_t _nb_nodes_global = nb_nodes_global(); + size = (parallel::mpi::comm().rank() == owner ? _nb_nodes_global : 0); } } return size; diff --git a/src/atlas/util/detail/Cache.h b/src/atlas/util/detail/Cache.h index 421c1d243..1f57ed96b 100644 --- a/src/atlas/util/detail/Cache.h +++ b/src/atlas/util/detail/Cache.h @@ -12,6 +12,7 @@ #include #include #include "eckit/memory/SharedPtr.h" +#include "atlas/runtime/Log.h" namespace atlas { namespace util { @@ -22,7 +23,7 @@ class Cache { using key_type = Key; using value_type = Value; using creator_type = std::function; - + eckit::SharedPtr get(const key_type& key, const creator_type& creator) { std::lock_guard guard(lock_); auto it = map_.find(key); From 7ad03715729c3b943f24df077b9020f91e8c0551 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 16 Oct 2017 16:20:43 +0100 Subject: [PATCH 303/355] ATLAS-147 Play with EqualRegionsPartitioner --- .../partitioner/EqualRegionsPartitioner.cc | 218 +++++++++++++++--- src/atlas/mesh/Nodes.cc | 3 +- src/atlas/mesh/actions/BuildEdges.cc | 5 +- src/atlas/mesh/actions/BuildHalo.cc | 5 +- src/atlas/mesh/actions/BuildParallelFields.cc | 2 +- src/atlas/mesh/detail/AccumulateFacets.cc | 19 +- 6 files changed, 212 insertions(+), 40 deletions(-) diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index 9545e214e..5e489a1ae 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -18,6 +18,9 @@ #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" #include "atlas/util/MicroDeg.h" #include "atlas/runtime/Trace.h" +#include "atlas/runtime/Log.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/parallel/mpi/Buffer.h" using atlas::util::microdeg; @@ -449,7 +452,7 @@ void EqualRegionsPartitioner::partition( int nb_nodes, NodeInt nodes[], int part already by construction in this order, but then sorting is really fast */ - std::sort( nodes, nodes+nb_nodes, compare_NS_WE); +// std::sort( nodes, nodes+nb_nodes, compare_NS_WE); /* For every band, now sort from west to east, and north to south. Inside every band @@ -503,40 +506,197 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { for(size_t j = 0; j < grid.size(); ++j) part[j] = 0; } else { - std::vector nodes(grid.size()); - int n(0); + + ATLAS_TRACE("EqualRegionsPartitioner::partition"); ASSERT( grid.projection().units() == "degrees" ); - if( auto reduced_grid = StructuredGrid(grid) ) { - for(size_t jlat = 0; jlat < reduced_grid.ny(); ++jlat) { - for(size_t jlon = 0; jlon < reduced_grid.nx(jlat); ++jlon) { - nodes[n].x = microdeg(reduced_grid.x(jlon,jlat)); - nodes[n].y = microdeg(reduced_grid.y(jlat)); - nodes[n].n = n; - ++n; + + const auto& comm = parallel::mpi::comm(); + int mpi_rank = comm.rank(); + + std::vector nodes(grid.size()); + std::vector recv_buffer(3*grid.size()); + long nb_workers = comm.size(); + + /* + Sort nodes from north to south, and west to east. Now we can easily split + the points in bands. Note, for StructuredGrid, this should not be necessary, as it is + already by construction in this order, but then sorting is really fast + */ + + ATLAS_TRACE_SCOPE("sort all") { + std::vector requests; + + for( long w=0; w " << w_end << std::endl; + + + if( mpi_rank==0 ) { + requests.push_back( comm.iReceive( + recv_buffer.data()+3*w_begin, + 3*(w_end-w_begin), + /* source= */ w, /* tag= */ 0 ) ); + } + + if( w == mpi_rank ) { + std::vector w_nodes(w_end-w_begin); + + ATLAS_TRACE_SCOPE("create one bit") { + int i(0); + int j(0); + for( PointXY point : grid.xy() ) { + if( i >= w_begin && i < w_end ) { + w_nodes[j].x = microdeg(point.x()); + w_nodes[j].y = microdeg(point.y()); + w_nodes[j].n = i; + ++j; + } + ++i; + } + } + ATLAS_TRACE_SCOPE("sort one bit") { + std::sort(w_nodes.begin(),w_nodes.end(), compare_NS_WE ); + } + ATLAS_TRACE_SCOPE("send to rank0") { + std::vector send_buffer(3*(w_end-w_begin)); + for( int j=0; j points; -// grid().lonlat(points); -// for(size_t j = 0; j < grid().npts(); ++j) { -// nodes[n].x = microdeg(points[j].lon()); -// nodes[n].y = microdeg(points[j].lat()); -// nodes[n].n = n; -// ++n; -// } + } + ATLAS_TRACE_SCOPE("merge sorted") { + for( long w=0; w requests; + + int nb_parts = N_; + int nb_nodes = grid.size(); + int chunk_size = nb_nodes/nb_parts; + int chunk_remainder = nb_nodes - chunk_size*nb_parts; + int remainder = chunk_remainder; + std::vector count; + count.reserve(nb_parts); + int end=0; + for( int band=0; band0?1:0) ); + end += count.back(); + } + + int w; + if( nb_workers >= nb_bands() ) { + w = band; + } else { + NOTIMP; + } + + if( mpi_rank==0 ) { + requests.push_back( comm.iReceive( + recv_buffer.data()+3*begin, + 3*(end-begin), + /* source= */ w, /* tag= */ 0 ) ); + } + + if( w == mpi_rank ) { + std::sort( nodes.data()+begin, nodes.data()+end, compare_WE_NS ); + std::vector send_buffer(3*(end-begin)); + for( int j=0; j part = array::make_view( partition() ); array::ArrayView flags = array::make_view( field("flags") ); + const int mpi_rank = parallel::mpi::comm().rank(); for(size_t n=previous_size; n edge_sort(nb_edges); + std::vector edge_sort; edge_sort.reserve(nb_edges); { UniqueLonLat compute_uid( mesh ); for( size_t jedge=0; jedge 0 ) + bool inserted = uid2node.insert( std::make_pair(uid,jnode) ).second; + if( not inserted ) { int other = uid2node[uid]; std::stringstream msg; @@ -247,7 +247,6 @@ void build_lookup_uid2node( Mesh& mesh, Uid2Node& uid2node ) << glb_idx(other) << " (" << xy(other,XX) <<","<< xy(other,YY)<<")"; notes.add_error(msg.str()); } - uid2node[uid] = jnode; } if( notes.error() ) throw eckit::SeriousBug(notes.str(),Here()); diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 0c519b486..ae2b31f0c 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -867,7 +867,7 @@ Field& build_edges_global_idx( Mesh& mesh ) std::vector edge_sort; edge_sort.reserve(glb_nb_edges); for( size_t jedge=0; jedge > node_to_facet(nodes.size()); + for( size_t j=0; j Date: Fri, 2 Feb 2018 11:36:23 +0000 Subject: [PATCH 304/355] ATLAS-147 MeshObserver to erase caches --- src/atlas/functionspace/EdgeColumns.cc | 88 ++++++++++++++++++------- src/atlas/functionspace/NodeColumns.cc | 90 +++++++++++++++++++------- src/atlas/mesh/Halo.cc | 6 ++ src/atlas/mesh/Halo.h | 6 ++ src/atlas/mesh/detail/MeshImpl.cc | 15 +++++ src/atlas/mesh/detail/MeshImpl.h | 14 ++++ src/atlas/util/detail/Cache.h | 24 +++++-- 7 files changed, 189 insertions(+), 54 deletions(-) diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index d82c64ac5..83e958852 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -66,23 +66,36 @@ array::LocalView make_leveled_view(const Field &field) } } -class EdgeColumnsHaloExchangeCache : public util::Cache { +class EdgeColumnsHaloExchangeCache : + public util::Cache, + public mesh::detail::MeshObserver +{ private: using Base = util::Cache; - EdgeColumnsHaloExchangeCache() {} + EdgeColumnsHaloExchangeCache() : Base("EdgeColumnsHaloExchangeCache") {} public: static EdgeColumnsHaloExchangeCache& instance() { static EdgeColumnsHaloExchangeCache inst; return inst; } - eckit::SharedPtr get( const Mesh& mesh ) { + eckit::SharedPtr get_or_create( const Mesh& mesh ) { creator_type creator = std::bind( &EdgeColumnsHaloExchangeCache::create, mesh ); - std::ostringstream key ; - key << "mesh[address="<attachObserver(instance()); value_type* value = new value_type(); value->setup( array::make_view(mesh.edges().partition()).data(), array::make_view(mesh.edges().remote_index()).data(), @@ -92,23 +105,36 @@ class EdgeColumnsHaloExchangeCache : public util::Cache { +class EdgeColumnsGatherScatterCache : + public util::Cache, + public mesh::detail::MeshObserver +{ private: using Base = util::Cache; - EdgeColumnsGatherScatterCache() {} + EdgeColumnsGatherScatterCache() : Base("EdgeColumnsGatherScatterCache"){} public: static EdgeColumnsGatherScatterCache& instance() { static EdgeColumnsGatherScatterCache inst; return inst; } - eckit::SharedPtr get( const Mesh& mesh ) { + eckit::SharedPtr get_or_create( const Mesh& mesh ) { creator_type creator = std::bind( &EdgeColumnsGatherScatterCache::create, mesh ); - std::ostringstream key ; - key << "mesh[address="<attachObserver(instance()); value_type* value = new value_type(); value->setup(array::make_view(mesh.edges().partition()).data(), array::make_view(mesh.edges().remote_index()).data(), @@ -119,25 +145,38 @@ class EdgeColumnsGatherScatterCache : public util::Cache { +class EdgeColumnsChecksumCache : + public util::Cache, + public mesh::detail::MeshObserver +{ private: using Base = util::Cache; - EdgeColumnsChecksumCache() {} + EdgeColumnsChecksumCache() : Base("EdgeColumnsChecksumCache") {} public: static EdgeColumnsChecksumCache& instance() { static EdgeColumnsChecksumCache inst; return inst; } - eckit::SharedPtr get( const Mesh& mesh ) { + eckit::SharedPtr get_or_create( const Mesh& mesh ) { creator_type creator = std::bind( &EdgeColumnsChecksumCache::create, mesh ); - std::ostringstream key ; - key << "mesh[address="<attachObserver(instance()); value_type* value = new value_type(); - eckit::SharedPtr gather( EdgeColumnsGatherScatterCache::instance().get(mesh) ); + eckit::SharedPtr gather( EdgeColumnsGatherScatterCache::instance().get_or_create(mesh) ); value->setup( gather ); return value; } @@ -178,7 +217,8 @@ size_t EdgeColumns::config_size(const eckit::Configuration& config) const { size_t owner(0); config.get("owner",owner); - size = (parallel::mpi::comm().rank() == owner ? nb_edges_global() : 0); + size_t _nb_edges_global( nb_edges_global() ); + size = (parallel::mpi::comm().rank() == owner ? _nb_edges_global : 0); } } return size; @@ -360,7 +400,7 @@ void EdgeColumns::haloExchange( Field& field ) const const parallel::HaloExchange& EdgeColumns::halo_exchange() const { if (halo_exchange_) return *halo_exchange_; - halo_exchange_ = EdgeColumnsHaloExchangeCache::instance().get( mesh_ ); + halo_exchange_ = EdgeColumnsHaloExchangeCache::instance().get_or_create( mesh_ ); return *halo_exchange_; } @@ -412,14 +452,14 @@ const parallel::GatherScatter& EdgeColumns::gather() const { if( gather_scatter_ ) return *gather_scatter_; - gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get( mesh_ ); + gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } const parallel::GatherScatter& EdgeColumns::scatter() const { if( gather_scatter_ ) return *gather_scatter_; - gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get( mesh_ ); + gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } @@ -538,7 +578,7 @@ std::string EdgeColumns::checksum( const Field& field ) const { const parallel::Checksum& EdgeColumns::checksum() const { if (checksum_) return *checksum_; - checksum_ = EdgeColumnsChecksumCache::instance().get( mesh_ ) ; + checksum_ = EdgeColumnsChecksumCache::instance().get_or_create( mesh_ ) ; return *checksum_; } diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index ddbf1a4cd..d6aad6748 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -104,24 +104,38 @@ array::LocalView make_per_level_view(const Field &field) } -class NodeColumnsHaloExchangeCache : public util::Cache { +class NodeColumnsHaloExchangeCache : + public util::Cache, + public mesh::detail::MeshObserver +{ private: using Base = util::Cache; - NodeColumnsHaloExchangeCache() {} + NodeColumnsHaloExchangeCache() : Base("NodeColumnsHaloExchangeCache") {} public: static NodeColumnsHaloExchangeCache& instance() { static NodeColumnsHaloExchangeCache inst; return inst; } - eckit::SharedPtr get( const Mesh& mesh, long halo ) { + eckit::SharedPtr get_or_create( const Mesh& mesh, long halo ) { creator_type creator = std::bind( &NodeColumnsHaloExchangeCache::create, mesh, halo ); - std::ostringstream key ; - key << "mesh[address="< get( const Mesh& mesh ) { + eckit::SharedPtr get_or_create( const Mesh& mesh ) { creator_type creator = std::bind( &NodeColumnsGatherScatterCache::create, mesh ); - std::ostringstream key ; - key << "mesh.nodes[address="<attachObserver(instance()); + value_type* value = new value_type(); mesh::IsGhostNode is_ghost(mesh.nodes()); @@ -178,25 +206,37 @@ class NodeColumnsGatherScatterCache : public util::Cache { +class NodeColumnsChecksumCache : + public util::Cache, + public mesh::detail::MeshObserver +{ private: using Base = util::Cache; - NodeColumnsChecksumCache() {} + NodeColumnsChecksumCache(): Base("NodeColumnsChecksumCache"){} public: static NodeColumnsChecksumCache& instance() { static NodeColumnsChecksumCache inst; return inst; } - eckit::SharedPtr get( const Mesh& mesh ) { + eckit::SharedPtr get_or_create( const Mesh& mesh ) { creator_type creator = std::bind( &NodeColumnsChecksumCache::create, mesh ); - std::ostringstream key ; - key << "mesh[address="<attachObserver(instance()); value_type* value = new value_type(); - eckit::SharedPtr gather( NodeColumnsGatherScatterCache::instance().get(mesh) ); + eckit::SharedPtr gather( NodeColumnsGatherScatterCache::instance().get_or_create(mesh) ); value->setup( gather ); return value; } @@ -443,7 +483,7 @@ void NodeColumns::haloExchange( Field& field, bool on_device ) const const parallel::HaloExchange& NodeColumns::halo_exchange() const { if ( halo_exchange_ ) return *halo_exchange_; - halo_exchange_ = NodeColumnsHaloExchangeCache::instance().get( mesh_, halo_.size() ); + halo_exchange_ = NodeColumnsHaloExchangeCache::instance().get_or_create( mesh_, halo_.size() ); return *halo_exchange_; } @@ -495,13 +535,13 @@ void NodeColumns::gather( const Field& local, Field& global ) const const parallel::GatherScatter& NodeColumns::gather() const { if (gather_scatter_) return *gather_scatter_; - gather_scatter_ = NodeColumnsGatherScatterCache::instance().get( mesh_ ); + gather_scatter_ = NodeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } const parallel::GatherScatter& NodeColumns::scatter() const { if (gather_scatter_) return *gather_scatter_; - gather_scatter_ = NodeColumnsGatherScatterCache::instance().get( mesh_ ); + gather_scatter_ = NodeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; } @@ -599,7 +639,7 @@ std::string NodeColumns::checksum( const Field& field ) const { const parallel::Checksum& NodeColumns::checksum() const { if (checksum_) return *checksum_; - checksum_ = NodeColumnsChecksumCache::instance().get( mesh_ ); + checksum_ = NodeColumnsChecksumCache::instance().get_or_create( mesh_ ); return *checksum_; } diff --git a/src/atlas/mesh/Halo.cc b/src/atlas/mesh/Halo.cc index 853a55032..5eb39b204 100644 --- a/src/atlas/mesh/Halo.cc +++ b/src/atlas/mesh/Halo.cc @@ -22,6 +22,12 @@ Halo::Halo(const Mesh& mesh) mesh.metadata().get("halo",size_); } +Halo::Halo(const detail::MeshImpl& mesh) +{ + size_=0; + mesh.metadata().get("halo",size_); +} + long Halo::size() const { ASSERT( size_>=0 ); return size_; diff --git a/src/atlas/mesh/Halo.h b/src/atlas/mesh/Halo.h index e731e8a55..d9f982bb4 100644 --- a/src/atlas/mesh/Halo.h +++ b/src/atlas/mesh/Halo.h @@ -14,6 +14,11 @@ namespace atlas { class Mesh; +namespace mesh { +namespace detail { + class MeshImpl; +} +} } namespace atlas { @@ -26,6 +31,7 @@ class Halo public: Halo() {} Halo(const Mesh& mesh); + Halo(const detail::MeshImpl& mesh); Halo(const long size) : size_(size) {} long size() const; private: diff --git a/src/atlas/mesh/detail/MeshImpl.cc b/src/atlas/mesh/detail/MeshImpl.cc index deae8f925..0238970be 100644 --- a/src/atlas/mesh/detail/MeshImpl.cc +++ b/src/atlas/mesh/detail/MeshImpl.cc @@ -8,6 +8,7 @@ * does it submit to any jurisdiction. */ +#include #include "atlas/mesh/detail/MeshImpl.h" #include "eckit/exception/Exceptions.h" @@ -48,6 +49,9 @@ MeshImpl::MeshImpl(): MeshImpl::~MeshImpl() { + for( MeshObserver* o : mesh_observers_ ) { + o->onMeshDestruction(*this); + } } void MeshImpl::print(std::ostream& os) const @@ -162,6 +166,17 @@ const PartitionPolygon& MeshImpl::polygon(size_t halo) const { return *polygons_[halo]; } +void MeshImpl::attachObserver( MeshObserver& observer ) const { + if( std::find( mesh_observers_.begin(), mesh_observers_.end(), &observer ) == mesh_observers_.end() ) { + mesh_observers_.push_back( &observer ); + } +} + +void MeshImpl::detachObserver( MeshObserver& observer ) const { + mesh_observers_.erase( + std::remove( mesh_observers_.begin(), mesh_observers_.end(), &observer ), + mesh_observers_.end() ); +} //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/mesh/detail/MeshImpl.h b/src/atlas/mesh/detail/MeshImpl.h index f8b0fd153..2547ca021 100644 --- a/src/atlas/mesh/detail/MeshImpl.h +++ b/src/atlas/mesh/detail/MeshImpl.h @@ -42,6 +42,8 @@ namespace detail { //---------------------------------------------------------------------------------------------------------------------- +class MeshObserver; + class MeshImpl : public eckit::Owned { public: // methods @@ -106,6 +108,9 @@ class MeshImpl : public eckit::Owned { const Grid& grid() const { return grid_; } + void attachObserver(MeshObserver&) const; + void detachObserver(MeshObserver&) const; + private: // methods friend class ::atlas::Mesh; @@ -143,6 +148,15 @@ class MeshImpl : public eckit::Owned { mutable eckit::SharedPtr partition_graph_; mutable std::vector> polygons_; + + mutable std::vector mesh_observers_; +}; + +//---------------------------------------------------------------------------------------------------------------------- + +class MeshObserver { +public: + virtual void onMeshDestruction(MeshImpl&) = 0; }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/util/detail/Cache.h b/src/atlas/util/detail/Cache.h index 1f57ed96b..8657d2779 100644 --- a/src/atlas/util/detail/Cache.h +++ b/src/atlas/util/detail/Cache.h @@ -1,5 +1,5 @@ /* - * (C) Copyright 1996-2017 ECMWF. + * (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. @@ -11,6 +11,7 @@ #include #include #include +#include #include "eckit/memory/SharedPtr.h" #include "atlas/runtime/Log.h" @@ -24,24 +25,37 @@ class Cache { using value_type = Value; using creator_type = std::function; - eckit::SharedPtr get(const key_type& key, const creator_type& creator) { + Cache(const std::string& name) : name_(name) {} + + eckit::SharedPtr get_or_create(const key_type& key, const creator_type& creator) { std::lock_guard guard(lock_); auto it = map_.find(key); if (it != map_.end()) { eckit::SharedPtr value = it->second; if( value ) { - Log::debug() << key << " was found in cache" << std::endl; + Log::debug() << "Key \"" << key << "\" was found in cache \""< value( creator() ); map_[key] = value; return value; } + + void remove(const key_type& key) { + std::lock_guard guard(lock_); + if( map_.erase(key) ) { + Log::debug() << "Erased key \"" << key << "\" from cache \""< > map_; }; From 0e752d50a3dbc64ac613f770c7fe11ea8969839e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 2 Feb 2018 12:54:44 +0000 Subject: [PATCH 305/355] ATLAS-147 Avoid GatherScatter setup when creating of global fields --- src/atlas/functionspace/NodeColumns.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index d6aad6748..3ed647ae7 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -128,7 +128,7 @@ class NodeColumnsHaloExchangeCache : private: static Base::key_type key( const mesh::detail::MeshImpl& mesh, long halo ) { std::ostringstream key ; - key << "mesh.nodes[address="<<&mesh<<"],halo="<=0 ) return nb_nodes_global_; - nb_nodes_global_ = gather().glb_dof(); + if( Grid grid = mesh().grid() ) { + nb_nodes_global_ = grid.size(); + } else { + nb_nodes_global_ = gather().glb_dof(); + } return nb_nodes_global_; } From f7f11d310648b5f69adbca947cf0ac8e62061acf Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 16 Oct 2017 18:52:41 +0100 Subject: [PATCH 306/355] ATLAS-147 Experiment with predicate for iterator --- src/atlas/grid/Grid.h | 10 ++- src/atlas/grid/Iterator.h | 12 ++-- src/atlas/grid/detail/grid/Grid.h | 4 ++ src/atlas/grid/detail/grid/Structured.h | 70 +++++++++++++++++++ src/atlas/grid/detail/grid/Unstructured.h | 2 + .../partitioner/EqualRegionsPartitioner.cc | 19 ++++- 6 files changed, 106 insertions(+), 11 deletions(-) diff --git a/src/atlas/grid/Grid.h b/src/atlas/grid/Grid.h index a7cb27042..e639a5376 100644 --- a/src/atlas/grid/Grid.h +++ b/src/atlas/grid/Grid.h @@ -10,6 +10,7 @@ #pragma once +#include #include "eckit/memory/SharedPtr.h" #include "atlas/grid/detail/grid/Grid.h" #include "atlas/grid/detail/grid/Unstructured.h" @@ -43,12 +44,16 @@ class Grid { public: using iterator = grid::IteratorXY; using const_iterator = iterator; + using Predicate = std::function< bool(long) >; public: + IterateXY(const Implementation& grid, Predicate p) : grid_(grid), p_(p), use_p_(true) {} IterateXY(const Implementation& grid) : grid_(grid) {} - iterator begin() const { return grid_.xy_begin(); } - iterator end() const { return grid_.xy_end(); } + iterator begin() const { return use_p_ ? grid_.xy_begin(p_) : grid_.xy_begin(); } + iterator end() const { return use_p_ ? grid_.xy_end(p_) : grid_.xy_end(); } private: const Implementation& grid_; + Predicate p_; + bool use_p_{false}; }; class IterateLonLat { @@ -65,6 +70,7 @@ class Grid { public: + IterateXY xy( IterateXY::Predicate p ) const { return IterateXY(*grid_,p); } IterateXY xy() const { return IterateXY(*grid_); } IterateLonLat lonlat() const { return IterateLonLat(*grid_); } diff --git a/src/atlas/grid/Iterator.h b/src/atlas/grid/Iterator.h index 1f6b4d6cb..10138a44c 100644 --- a/src/atlas/grid/Iterator.h +++ b/src/atlas/grid/Iterator.h @@ -30,11 +30,11 @@ class IteratorXY { bool next( PointXY& xy ) { return iterator_->next(xy); } - + PointXY operator *() const { return iterator_->operator *(); } - + const IteratorXY& operator ++() { iterator_->operator ++(); return *this; @@ -43,7 +43,7 @@ class IteratorXY { bool operator ==(const IteratorXY &other) const { return iterator_->operator ==(*other.iterator_); } - + bool operator !=(const IteratorXY &other) const { return iterator_->operator !=(*other.iterator_); } @@ -66,11 +66,11 @@ class IteratorLonLat { bool next( PointLonLat& lonlat ) { return iterator_->next(lonlat); } - + PointLonLat operator *() const { return iterator_->operator *(); } - + const IteratorLonLat& operator ++() { iterator_->operator ++(); return *this; @@ -79,7 +79,7 @@ class IteratorLonLat { bool operator ==(const IteratorLonLat &other) const { return iterator_->operator ==(*other.iterator_); } - + bool operator !=(const IteratorLonLat &other) const { return iterator_->operator !=(*other.iterator_); } diff --git a/src/atlas/grid/detail/grid/Grid.h b/src/atlas/grid/detail/grid/Grid.h index defc4c3eb..565b0b05b 100644 --- a/src/atlas/grid/detail/grid/Grid.h +++ b/src/atlas/grid/detail/grid/Grid.h @@ -11,6 +11,7 @@ #pragma once #include +#include #include "eckit/memory/Builder.h" #include "eckit/memory/Owned.h" #include "atlas/domain/Domain.h" @@ -41,6 +42,7 @@ class Grid : public eckit::Owned { class IteratorXY { public: + using Predicate = std::function; virtual bool next(PointXY&) =0; virtual const PointXY operator *() const =0; virtual const IteratorXY& operator ++() =0; @@ -101,6 +103,8 @@ class Grid : public eckit::Owned { virtual IteratorXY* xy_begin() const=0; virtual IteratorXY* xy_end() const=0; + virtual IteratorXY* xy_begin(IteratorXY::Predicate p) const=0; + virtual IteratorXY* xy_end(IteratorXY::Predicate p) const=0; virtual IteratorLonLat* lonlat_begin() const=0; virtual IteratorLonLat* lonlat_end() const=0; diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index a56ad2fe2..8c864a6d9 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -92,6 +92,73 @@ class Structured : public Grid { size_t j_; }; + + class IteratorXYPredicated: public Grid::IteratorXY { + public: + IteratorXYPredicated(const Structured& grid, Grid::IteratorXY::Predicate p, bool begin = true): + grid_(grid), + p_(p), + i_(0), + j_( begin ? 0 : grid.ny() ), + n_(0), + size_(grid.size()) { + } + + virtual bool next(PointXY& xy) { + NOTIMP; + + if( j_(other).j_ && i_ == static_cast(other).i_; + } + + virtual bool operator !=(const Grid::IteratorXY &other) const { + return i_ != static_cast(other).i_ || j_ != static_cast(other).j_; + } + + + private: + Grid::IteratorXY::Predicate p_; + const Structured& grid_; + size_t i_; + size_t j_; + size_t n_; + size_t size_; + }; + + + + class IteratorLonLat: public Grid::IteratorLonLat { public: IteratorLonLat(const Structured& grid, bool begin = true): @@ -329,6 +396,9 @@ class Structured : public Grid { 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 { return new IteratorXYPredicated(*this,p); } + virtual IteratorXYPredicated* xy_end(IteratorXY::Predicate p) const { return new IteratorXYPredicated(*this,p,false); } + protected: // methods diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index 6182c0b16..bd58094ca 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -148,6 +148,8 @@ class Unstructured : public Grid { 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 IteratorXY* xy_begin(IteratorXY::Predicate p) const { return xy_begin(); } + virtual IteratorXY* xy_end(IteratorXY::Predicate p) const { return xy_end(); } private: // methods diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index 5e489a1ae..7fa62466b 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -546,17 +546,30 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { std::vector w_nodes(w_end-w_begin); ATLAS_TRACE_SCOPE("create one bit") { - int i(0); int j(0); - for( PointXY point : grid.xy() ) { - if( i >= w_begin && i < w_end ) { + auto filter = [](long n, long begin, long end) { + return (n>=begin && n i , j : " << i << " , " << j << std::endl; + } ATLAS_TRACE_SCOPE("sort one bit") { std::sort(w_nodes.begin(),w_nodes.end(), compare_NS_WE ); From a9ee2149d30cb652119ca22a589c9b0781619870 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Mon, 16 Oct 2017 23:29:14 +0100 Subject: [PATCH 307/355] ATLAS-147 parallel sorting strategy for EqualRegionsPartitioner --- src/atlas/grid/detail/grid/Structured.h | 11 + .../partitioner/EqualRegionsPartitioner.cc | 264 +++++++++--------- .../atlas-benchmark-build-halo.cc | 2 +- src/tests/grid/test_grid_ptr.cc | 21 ++ 4 files changed, 165 insertions(+), 133 deletions(-) diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index 8c864a6d9..4c6fb67fd 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -102,8 +102,19 @@ class Structured : public Grid { j_( begin ? 0 : grid.ny() ), n_(0), size_(grid.size()) { + if( begin ) { + while( not p_(n_) && n_ nodes(grid.size()); - std::vector recv_buffer(3*grid.size()); + int* nodes_buffer = reinterpret_cast(nodes.data()); long nb_workers = comm.size(); /* @@ -532,57 +532,54 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { long w_begin = w * grid.size()/N_; long w_end = (w+1) * grid.size()/N_; if( w==nb_workers-1 ) w_end = grid.size(); - //Log::info() << Here() << " " << w << " : " << w_begin << " -> " << w_end << std::endl; - + size_t w_size = w_end - w_begin; if( mpi_rank==0 ) { requests.push_back( comm.iReceive( - recv_buffer.data()+3*w_begin, - 3*(w_end-w_begin), + nodes_buffer+3*w_begin, 3*w_size, /* source= */ w, /* tag= */ 0 ) ); } if( w == mpi_rank ) { - std::vector w_nodes(w_end-w_begin); + std::vector w_nodes(w_size); + int* w_nodes_buffer = reinterpret_cast(w_nodes.data()); ATLAS_TRACE_SCOPE("create one bit") { - int j(0); - auto filter = [](long n, long begin, long end) { - return (n>=begin && n=w_begin && n i , j : " << i << " , " << j << std::endl; - + else + { + int i(0); + int j(0); + for( PointXY point : grid.xy() ) { + if( i >= w_begin && i < w_end ) { + w_nodes[j].x = microdeg(point.x()); + w_nodes[j].y = microdeg(point.y()); + w_nodes[j].n = i; + ++j; + } + ++i; + } + + } } ATLAS_TRACE_SCOPE("sort one bit") { std::sort(w_nodes.begin(),w_nodes.end(), compare_NS_WE ); } ATLAS_TRACE_SCOPE("send to rank0") { - std::vector send_buffer(3*(w_end-w_begin)); - for( int j=0; j requests; - - int nb_parts = N_; - int nb_nodes = grid.size(); - int chunk_size = nb_nodes/nb_parts; - int chunk_remainder = nb_nodes - chunk_size*nb_parts; - int remainder = chunk_remainder; - std::vector count; - count.reserve(nb_parts); - int end=0; - for( int band=0; band0?1:0) ); - end += count.back(); - } - - int w; - if( nb_workers >= nb_bands() ) { - w = band; - } else { - NOTIMP; - } - - if( mpi_rank==0 ) { - requests.push_back( comm.iReceive( - recv_buffer.data()+3*begin, - 3*(end-begin), - /* source= */ w, /* tag= */ 0 ) ); - } - - if( w == mpi_rank ) { - std::sort( nodes.data()+begin, nodes.data()+end, compare_WE_NS ); - std::vector send_buffer(3*(end-begin)); - for( int j=0; j requests; + + int nb_parts = N_; + int nb_nodes = grid.size(); + int chunk_size = nb_nodes/nb_parts; + int chunk_remainder = nb_nodes - chunk_size*nb_parts; + int remainder = chunk_remainder; + std::vector count; count.reserve(nb_parts); + std::vector displs; displs.reserve(nb_parts); + std::vector b_count; b_count.reserve(nb_bands()); + std::vector b_displs; b_displs.reserve(nb_bands()); + + { + int end = 0; + for( int band=0; band0?1:0); + displs.push_back(end); + count.push_back(w_size); + end += w_size; + b_size += w_size; + } + b_count.push_back(b_size); + } + } + + int w(0); + for( int band=0; band=5 && n<10); + if( b ) Log::debug() << "n = " << n << std::endl; + return b; + }; + + // auto pred = std::bind( filter, std::placeholders::_1, w_begin, w_end ); + + int i(0); + for( atlas::PointXY xy : grid.xy(filter) ) { + Log::debug() << i++ << " " << xy << std::endl; + } + EXPECT( i == 5 ); + + Log::debug() << std::flush; +} + //----------------------------------------------------------------------------- } // namespace test From bd353bf3924db1dc7389c7e0c53b513d01cc0b2f Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 17 Oct 2017 10:15:32 +0000 Subject: [PATCH 308/355] ATLAS-147 Equalregions partitioner take shortcut for StructuredGrid --- .../partitioner/EqualRegionsPartitioner.cc | 165 ++++++++++-------- 1 file changed, 91 insertions(+), 74 deletions(-) diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index aaab565d3..71a9b443e 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -524,84 +524,101 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { already by construction in this order, but then sorting is really fast */ - ATLAS_TRACE_SCOPE("sort all") { - std::vector requests; - - for( long w=0; w structured_grid.x(0,0) ); + + ATLAS_TRACE("Take shortcut"); + int n(0); + for( size_t j=0; j requests; - if( w == mpi_rank ) { - std::vector w_nodes(w_size); - int* w_nodes_buffer = reinterpret_cast(w_nodes.data()); - - ATLAS_TRACE_SCOPE("create one bit") { - if( true ) // optimized experimental when true (still need to benchmark) - { - auto filter = [w_begin,w_end](long n) { - return (n>=w_begin && n= w_begin && i < w_end ) { - w_nodes[j].x = microdeg(point.x()); - w_nodes[j].y = microdeg(point.y()); - w_nodes[j].n = i; - ++j; - } - ++i; - } - + + if( w == mpi_rank ) { + std::vector w_nodes(w_size); + int* w_nodes_buffer = reinterpret_cast(w_nodes.data()); + + ATLAS_TRACE_SCOPE("create one bit") { + if( true ) // optimized experimental when true (still need to benchmark) + { + auto filter = [w_begin,w_end](long n) { + return (n>=w_begin && n= w_begin && i < w_end ) { + w_nodes[j].x = microdeg(point.x()); + w_nodes[j].y = microdeg(point.y()); + w_nodes[j].n = i; + ++j; + } + ++i; + } + } + } + ATLAS_TRACE_SCOPE("sort one bit") { + std::sort(w_nodes.begin(),w_nodes.end(), compare_NS_WE ); + } + ATLAS_TRACE_SCOPE("send to rank0") { + comm.send( w_nodes_buffer, 3*w_size, /* dest= */ 0, /* tag= */ 0 ); + } } - } - ATLAS_TRACE_SCOPE("sort one bit") { - std::sort(w_nodes.begin(),w_nodes.end(), compare_NS_WE ); - } - ATLAS_TRACE_SCOPE("send to rank0") { - comm.send( w_nodes_buffer, 3*w_size, /* dest= */ 0, /* tag= */ 0 ); - } } - } - ATLAS_TRACE_MPI( WAIT ) { - for( auto request : requests ) { - comm.wait( request ); + ATLAS_TRACE_MPI( WAIT ) { + for( auto request : requests ) { + comm.wait( request ); + } } - } - ATLAS_TRACE_SCOPE("merge sorted") { - for( long w=0; w Date: Tue, 17 Oct 2017 14:54:30 +0100 Subject: [PATCH 309/355] ATLAS-147 Fix serial implementation --- CMakeLists.txt | 2 +- .../partitioner/EqualRegionsPartitioner.cc | 51 +++++++++++-------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bb9f97a6..bde464f58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ ecbuild_declare_project() ### eckit -ecbuild_use_package( PROJECT eckit VERSION 0.18 REQUIRED ) +ecbuild_use_package( PROJECT eckit VERSION 0.18.1 REQUIRED ) ecbuild_debug( " ECKIT_FEATURES : [${ECKIT_FEATURES}]" ) # options & dependencies diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index 71a9b443e..e0622bcb0 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -513,6 +513,7 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { const auto& comm = parallel::mpi::comm(); int mpi_rank = comm.rank(); + int mpi_size = comm.size(); std::vector nodes(grid.size()); int* nodes_buffer = reinterpret_cast(nodes.data()); @@ -545,23 +546,25 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { ATLAS_TRACE("sort all"); std::vector requests; - for( long w=0; w w_nodes(w_size); int* w_nodes_buffer = reinterpret_cast(w_nodes.data()); - + ATLAS_TRACE_SCOPE("create one bit") { if( true ) // optimized experimental when true (still need to benchmark) { @@ -606,9 +609,9 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { } } ATLAS_TRACE_SCOPE("merge sorted") { - for( long w=0; w displs; displs.reserve(nb_parts); std::vector b_count; b_count.reserve(nb_bands()); std::vector b_displs; b_displs.reserve(nb_bands()); - + { int end = 0; for( int band=0; band Date: Tue, 17 Oct 2017 15:06:28 +0100 Subject: [PATCH 310/355] ATLAS-147 Predicate for unstructured grid iterator --- src/atlas/grid/detail/grid/Unstructured.h | 57 ++++++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index bd58094ca..80b701dab 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -74,6 +74,59 @@ class Unstructured : public Grid { size_t n_; }; + class IteratorXYPredicated: public Grid::IteratorXY { + public: + IteratorXYPredicated(const Unstructured& grid, Grid::IteratorXY::Predicate p, bool begin=true): + grid_(grid), + p_(p), + size_(grid_.points_->size()), + n_( begin ? 0 : grid_.points_->size() ) { + + if( begin) { + + } + } + + virtual bool next(PointXY& xy) { + NOTIMP; + if( n_ != grid_.points_->size() ) { + xy = grid_.xy(n_++); + return true; + } else { + return false; + } + } + + virtual const PointXY operator *() const { + return grid_.xy(n_); + } + + virtual const Grid::IteratorXY& operator ++() { + do { + ++n_; + if( n_ == size_ ) return *this; + } while( not p_(n_) ); + return *this; + } + + virtual bool operator ==(const Grid::IteratorXY &other) const { + return n_ == static_cast(other).n_; + } + + virtual bool operator !=(const Grid::IteratorXY &other) const { + return n_ != static_cast(other).n_; + } + + private: + const Unstructured& grid_; + Grid::IteratorXY::Predicate p_; + size_t n_; + size_t size_; + }; + + + + class IteratorLonLat: public Grid::IteratorLonLat { public: IteratorLonLat(const Unstructured& grid, bool begin=true): @@ -148,8 +201,8 @@ class Unstructured : public Grid { 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 IteratorXY* xy_begin(IteratorXY::Predicate p) const { return xy_begin(); } - virtual IteratorXY* xy_end(IteratorXY::Predicate p) const { return xy_end(); } + virtual IteratorXYPredicated* xy_begin(IteratorXY::Predicate p) const { return new IteratorXYPredicated(*this,p); } + virtual IteratorXYPredicated* xy_end(IteratorXY::Predicate p) const { return new IteratorXYPredicated(*this,p,false); } private: // methods From a7780f4caac3c3ec0c79c33e7e64d4019b6bcde4 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 17 Oct 2017 18:11:57 +0100 Subject: [PATCH 311/355] ATLAS-147 Avoid global renumbering --- src/apps/atlas-benchmark.cc | 6 +- src/atlas/functionspace/NodeColumns.cc | 1 - src/atlas/mesh/actions/BuildHalo.cc | 176 ++++++++++++++++-- src/atlas/mesh/actions/BuildParallelFields.cc | 19 +- .../meshgenerator/StructuredMeshGenerator.cc | 2 +- .../atlas-benchmark-sorting.cc | 7 +- src/tests/mesh/test_halo.cc | 1 - 7 files changed, 181 insertions(+), 31 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index eb2575c2c..4b16ee27d 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -538,10 +538,10 @@ double AtlasBenchmark::result() if( output ) { std::vector levels( 1, 0 ); - atlas::output::Output gmsh = atlas::output::Gmsh( "benchmark.msh", util::Config("levels",levels) ); + atlas::output::Output gmsh = atlas::output::Gmsh( "benchmark.msh", util::Config("levels",levels)("ghost",true) ); gmsh.write( mesh ); - gmsh.write( mesh.nodes().field("field") ); - gmsh.write( mesh.nodes().field("grad") ); + gmsh.write( scalar_field ); + gmsh.write( grad_field ); } return norm; } diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 3ed647ae7..a581783ff 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -269,7 +269,6 @@ void NodeColumns::constructor() if( halo_.size() > 0) { mesh::actions::build_halo(mesh_,halo_.size()); - mesh::actions::renumber_nodes_glb_idx(mesh_.nodes()); std::stringstream ss; ss << "nb_nodes_including_halo["< #include +#include "atlas/array.h" +#include "atlas/array/IndexView.h" +#include "atlas/field/Field.h" #include "atlas/library/config.h" -#include "atlas/runtime/Log.h" +#include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/Elements.h" #include "atlas/mesh/actions/BuildHalo.h" -#include "atlas/field/Field.h" +#include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/detail/AccumulateFacets.h" -#include "atlas/util/CoordinateEnums.h" #include "atlas/mesh/detail/PeriodicTransform.h" -#include "atlas/util/Unique.h" -#include "atlas/util/LonLatMicroDeg.h" -#include "atlas/util/MicroDeg.h" #include "atlas/parallel/mpi/Buffer.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/IndexView.h" -#include "atlas/array.h" +#include "atlas/parallel/mpi/Buffer.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" +#include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/parallel/mpi/Buffer.h" +#include "atlas/util/CoordinateEnums.h" +#include "atlas/util/LonLatMicroDeg.h" +#include "atlas/util/MicroDeg.h" +#include "atlas/util/Unique.h" + //#define DEBUG_OUTPUT #ifdef DEBUG_OUTPUT @@ -62,6 +63,144 @@ namespace atlas { namespace mesh { namespace actions { +struct Node +{ + Node(gidx_t gid, int idx) + { + g = gid; + i = idx; + } + gidx_t g; + gidx_t i; + bool operator < (const Node& other) const + { + return ( g Those specific periodic points at the EAST boundary are not checked for uid, +// and could receive different gidx for different tasks + + + // unused // int mypart = parallel::mpi::comm().rank(); + int nparts = parallel::mpi::comm().size(); + size_t root = 0; + + array::ArrayView nodes_glb_idx = array::make_view ( nodes.global_index() ); + //nodes_glb_idx.dump( Log::info() ); + Log::info() << "min = " << nodes.global_index().metadata().getLong("min") << std::endl; + Log::info() << "max = " << nodes.global_index().metadata().getLong("max") << std::endl; + Log::info() << "human_readable = " << nodes.global_index().metadata().getBool("human_readable") << std::endl; + gidx_t glb_idx_max = 0; + + std::vector points_to_edit; + + if( do_all ) { + points_to_edit.resize(nodes_glb_idx.size()); + for( size_t i=0; i glb_idx(points_to_edit.size()); + int nb_nodes = glb_idx.size(); + for( size_t i=0; i recvcounts(parallel::mpi::comm().size()); + std::vector recvdispls(parallel::mpi::comm().size()); + + ATLAS_TRACE_MPI( GATHER ) { + parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + } + int glb_nb_nodes = std::accumulate(recvcounts.begin(),recvcounts.end(),0); + + recvdispls[0]=0; + for (int jpart=1; jpart glb_idx_gathered( glb_nb_nodes ); + ATLAS_TRACE_MPI( GATHER ) { + parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), + glb_idx_gathered.data(), + recvcounts.data(), recvdispls.data(), root); + } + + + // 2) Sort all global indices, and renumber from 1 to glb_nb_edges + std::vector node_sort; node_sort.reserve(glb_nb_nodes); + for( size_t jnode=0; jnode 0 && node_sort[jnode].g != node_sort[jnode-1].g ) { + ++gid; + } + int inode = node_sort[jnode].i; + glb_idx_gathered[inode] = gid; + } + + // 3) Scatter renumbered back + ATLAS_TRACE_MPI( SCATTER ) { + parallel::mpi::comm().scatterv(glb_idx_gathered.data(), + recvcounts.data(), recvdispls.data(), + glb_idx.data(), glb_idx.size(), root); + } + + for( int jnode=0; jnode bool - { + auto node_already_exists = [&node_uid,&new_node_uid]( uid_t uid ) { std::vector::iterator it = std::lower_bound( node_uid.begin(), node_uid.end(), uid ); bool not_found = ( it == node_uid.end() || uid < *it ); if( not_found ) { @@ -1094,6 +1232,7 @@ void BuildHalo::operator () ( int nb_elems ) if( halo == nb_elems ) return; + ATLAS_TRACE( "Increasing mesh halo" ); for(int jhalo=halo ; jhalo loc_edge_id_arr(nb_edges); @@ -872,7 +883,7 @@ Field& build_edges_global_idx( Mesh& mesh ) std::sort(edge_sort.begin(), edge_sort.end()); // Assume edge gid start - uid_t gid=200000; + uid_t gid(0); for( size_t jedge=0; jedge points_to_edit; @@ -157,7 +157,6 @@ void refactored_renumber_nodes_glb_idx( const mesh::actions::BuildHalo& build_ha std::sort(node_sort.begin(), node_sort.end()); } - // Assume edge gid start gidx_t gid=glb_idx_max; for( size_t jnode=0; jnode Date: Tue, 6 Feb 2018 12:08:37 +0000 Subject: [PATCH 312/355] Fix ATLAS_DEBUG() macro --- src/atlas/runtime/Log.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atlas/runtime/Log.h b/src/atlas/runtime/Log.h index 148677b41..5e0c43a30 100644 --- a/src/atlas/runtime/Log.h +++ b/src/atlas/runtime/Log.h @@ -54,10 +54,10 @@ namespace detail { #define ATLAS_DEBUG_WHAT(WHAT) do{ ::atlas::Log::info() << "DEBUG(" << WHAT << ") @ " << Here() << std::endl; } while(0) #define ATLAS_DEBUG_VAR(VAR) do{ ::atlas::Log::info() << "DEBUG( " << #VAR << " : " << VAR << " ) @ " << Here() << std::endl; } while(0) -#define ATLAS_DEBUG(...) __ATLAS_SPLICE( __ATLAS_DEBUG_, __ATLAS_NARGS(__VA_ARGS__) ) (__VA_ARGS__) +#define ATLAS_DEBUG(...) __ATLAS_SPLICE( __ATLAS_DEBUG_, __ATLAS_NARG(__VA_ARGS__) ) (__VA_ARGS__) #define __ATLAS_DEBUG_0 ATLAS_DEBUG_HERE #define __ATLAS_DEBUG_1 ATLAS_DEBUG_WHAT -#define ATLAS_DEBUG_BACKTRACE() do{ ::atlas::Log::info() << "DEBUG() @ " << Here() << "Backtrace:\n" << backtrace() << std::endl; } while (0) +#define ATLAS_DEBUG_BACKTRACE() do{ ::atlas::Log::info() << "DEBUG() @ " << Here() << "Backtrace:\n" << ::atlas::backtrace() << std::endl; } while (0) #define ATLAS_DEBUG_PARALLEL_HERE() do{ ::atlas::print_parallel_here(std::cout,Here()); } while (0) From 037aca50522f598e2e544bfccba1e3ea837d7cad Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 6 Feb 2018 12:09:07 +0000 Subject: [PATCH 313/355] Silence cray compiler warning --- CMakeLists.txt | 1 + cmake/CompileFlags.cmake | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 cmake/CompileFlags.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index bde464f58..d7126c4fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,6 +233,7 @@ if( CMAKE_Fortran_COMPILER_ID MATCHES "PGI" AND endif() include_directories( ${ATLAS_INCLUDE_DIRS} ${ATLAS_EXTRA_INCLUDE_DIRS} ) +include(CompileFlags) add_subdirectory( src ) ################################################################################ diff --git a/cmake/CompileFlags.cmake b/cmake/CompileFlags.cmake new file mode 100644 index 000000000..522e4a6cb --- /dev/null +++ b/cmake/CompileFlags.cmake @@ -0,0 +1,10 @@ +if( CMAKE_CXX_COMPILER_ID MATCHES Cray ) + + ecbuild_add_cxx_flags("-hnomessage=3140") # colon separated numbers + ecbuild_add_fortran_flags("-hnomessage=3140") # colon separated numbers + +# CC-3140 crayc++: WARNING File = atlas/functionspace/NodeColumns.cc, Line = 1, Column = 1 +# The IPA optimization level was changed to "1" due to the presence of OMP +# directives, ACC directives, or ASM intrinsics. + +endif() From 257c532891cfb8fe2ed7d767648ea3b31ecf8fa3 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 6 Feb 2018 12:09:58 +0000 Subject: [PATCH 314/355] ATLAS-147 Remove scatter points from internal mesh in python plot --- src/atlas/mesh/PartitionPolygon.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/atlas/mesh/PartitionPolygon.cc b/src/atlas/mesh/PartitionPolygon.cc index b96e14f46..7308d0165 100644 --- a/src/atlas/mesh/PartitionPolygon.cc +++ b/src/atlas/mesh/PartitionPolygon.cc @@ -125,13 +125,13 @@ void PartitionPolygon::outputPythonScript(const eckit::PathName& filepath, const "\n" "count_" << r << " = " << count << "\n" "count_all_" << r << " = " << count_all << "\n" "" - "\n" "x_" << r << " = ["; for (size_t i=0; i Date: Tue, 6 Feb 2018 12:10:33 +0000 Subject: [PATCH 315/355] ATLAS-147 Remove debug print --- src/atlas/functionspace/NodeColumns.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index a581783ff..7fa16d785 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -2232,8 +2232,6 @@ NodeColumns::NodeColumns( const FunctionSpace& functionspace ) : namespace { detail::NodeColumns* make_functionspace( Mesh mesh, const eckit::Configuration& config ) { - ATLAS_DEBUG_VAR( mesh.get() ); - ATLAS_DEBUG_VAR( config ); return new detail::NodeColumns(mesh, config); } } From 08f1290ec66c6b6090287ddf64984a754d8db639 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 6 Feb 2018 14:35:14 +0000 Subject: [PATCH 316/355] ATLAS-148 Improve debug macros --- src/atlas/CMakeLists.txt | 1 + src/atlas/runtime/Log.cc | 26 +++++------------- src/atlas/runtime/Log.h | 17 +++++++++--- src/atlas/util/detail/Debug.h | 50 +++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 src/atlas/util/detail/Debug.h diff --git a/src/atlas/CMakeLists.txt b/src/atlas/CMakeLists.txt index d738d7811..5ae55e36b 100644 --- a/src/atlas/CMakeLists.txt +++ b/src/atlas/CMakeLists.txt @@ -468,6 +468,7 @@ util/SphericalPolygon.cc util/SphericalPolygon.h util/detail/BlackMagic.h util/detail/Cache.h +util/detail/Debug.h ) list( APPEND atlas_internals_srcs diff --git a/src/atlas/runtime/Log.cc b/src/atlas/runtime/Log.cc index 126b040b1..79f2fdb6d 100644 --- a/src/atlas/runtime/Log.cc +++ b/src/atlas/runtime/Log.cc @@ -8,9 +8,6 @@ * does it submit to any jurisdiction. */ -#include -#include -#include #include "atlas/runtime/Log.h" #include "atlas/parallel/mpi/mpi.h" #include "eckit/os/BackTrace.h" @@ -21,29 +18,20 @@ std::string backtrace() { return eckit::BackTrace::dump(); } -std::ostream& Log::debug_parallel() { +namespace detail { + +void debug_parallel_here( const eckit::CodeLocation& here ) { const auto& comm = parallel::mpi::comm(); - auto rank = comm.rank(); comm.barrier(); - for( int i=0; i #include "atlas/util/detail/BlackMagic.h" #define ATLAS_DEBUG_HERE() do{ ::atlas::Log::info() << "DEBUG() @ " << Here() << std::endl; } while(0) @@ -60,4 +60,13 @@ namespace detail { #define ATLAS_DEBUG_BACKTRACE() do{ ::atlas::Log::info() << "DEBUG() @ " << Here() << "Backtrace:\n" << ::atlas::backtrace() << std::endl; } while (0) -#define ATLAS_DEBUG_PARALLEL_HERE() do{ ::atlas::print_parallel_here(std::cout,Here()); } while (0) +#define ATLAS_DEBUG_PARALLEL_HERE() do{ ::atlas::detail::debug_parallel_here( Here() ); } while (0) +#define ATLAS_DEBUG_PARALLEL_WHAT(WHAT) do{ \ + std::stringstream w;\ + w << WHAT;\ + ::atlas::detail::debug_parallel_what( Here(), w.str() ); } while (0) + +#define ATLAS_DEBUG_PARALLEL(...) __ATLAS_SPLICE( __ATLAS_DEBUG_PARALLEL_, __ATLAS_NARG(__VA_ARGS__) ) (__VA_ARGS__) +#define __ATLAS_DEBUG_PARALLEL_0 ATLAS_DEBUG_PARALLEL_HERE +#define __ATLAS_DEBUG_PARALLEL_1 ATLAS_DEBUG_PARALLEL_WHAT + diff --git a/src/atlas/util/detail/Debug.h b/src/atlas/util/detail/Debug.h new file mode 100644 index 000000000..086fd4957 --- /dev/null +++ b/src/atlas/util/detail/Debug.h @@ -0,0 +1,50 @@ +#include "eckit/config/Resource.h" +#include "atlas/mesh.h" +#include "atlas/field.h" +#include "atlas/functionspace.h" +#include "atlas/parallel/mpi/mpi.h" + +namespace atlas { +namespace debug { + +inline gidx_t node_global_index(int i=0) { + static std::vector g = eckit::Resource>("$ATLAS_DEBUG_NODE_GLOBAL_INDEX", std::vector{-1} ); + return g[i]; +} + +inline gidx_t edge_global_index(int i=0) { + static std::vector g = eckit::Resource>("$ATLAS_DEBUG_EDGE_GLOBAL_INDEX", std::vector{-1} ); + return g[i]; +} + +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; + } + return false; +} + +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; + } + return false; +} + + +inline int mpi_rank() { + static int r = eckit::Resource("$ATLAS_DEBUG_MPI_RANK",-1); + return r; +} + +inline std::string rank_str() { + static std::string s = "["+std::to_string(parallel::mpi::comm().rank())+"] "; + return s; +} + +} +} From d1b5b4c3230a65d97270e6835c7ceae7c8c0642d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 6 Feb 2018 14:47:34 +0000 Subject: [PATCH 317/355] ATLAS-148 Prepare atlas-benchmark for debugging --- src/apps/atlas-benchmark.cc | 214 ++++++++++++++++++---------- src/atlas/mesh/actions/BuildHalo.cc | 10 +- 2 files changed, 142 insertions(+), 82 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 4b16ee27d..20fd769a9 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -53,11 +53,13 @@ #include "atlas/runtime/AtlasTool.h" #include "atlas/runtime/Trace.h" #include "atlas/util/CoordinateEnums.h" +#include "atlas/util/Earth.h" #include "atlas/output/Gmsh.h" #include "atlas/parallel/Checksum.h" #include "atlas/parallel/HaloExchange.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/omp/omp.h" +#include "atlas/util/detail/Debug.h" //---------------------------------------------------------------------------------------------------------------------- @@ -157,6 +159,8 @@ class AtlasBenchmark: public AtlasTool { int verify(const double&); + void initial_condition(const Field& field, const double& beta); + private: Mesh mesh; @@ -280,8 +284,10 @@ void AtlasBenchmark::execute(const Args& args) "atlas-benchmark-setup/*" }); Log::info() << timer.report( report_config ) << std::endl; - Log::info() << endl; + + parallel::mpi::comm().barrier(); + Log::info() << "Results:" << endl; double res = result(); @@ -292,6 +298,30 @@ void AtlasBenchmark::execute(const Args& args) //---------------------------------------------------------------------------------------------------------------------- +void AtlasBenchmark::initial_condition(const Field& field, const double& beta) +{ + const double radius = util::Earth::radiusInMeters(); + const double USCAL = 20.; + const double pvel = USCAL/radius; + const double deg2rad = M_PI/180.; + + auto lonlat_deg = array::make_view (mesh.nodes().lonlat()); + auto var = array::make_view (field); + + size_t nnodes = mesh.nodes().size(); + for( size_t jnode=0; jnode ( mesh.edges().field("dual_normals") ); auto field = array::make_view ( scalar_field ); + initial_condition(scalar_field,0.); + double radius = 6371.22e+03; // Earth's radius double height = 80.e+03; // Height of atmosphere double deg2rad = M_PI/180.; @@ -330,9 +367,6 @@ void AtlasBenchmark::setup() double hy = radius; double G = hx*hy; V(jnode) *= std::pow(deg2rad,2) * G; - - for(size_t jlev = 0; jlev < nlev; ++jlev) - field(jnode,jlev) = 100.+50.*std::cos(2*y); } atlas_omp_parallel_for( size_t jedge=0; jedge( grad_field ); auto avgS = array::make_view( *avgS_arr ); + auto node_glb_idx = array::make_view(mesh.nodes().global_index()); + auto node_part = array::make_view(mesh.nodes().partition()); + auto edge_part = array::make_view(mesh.edges().partition()); + auto edge_glb_idx = array::make_view(mesh.edges().global_index()); atlas_omp_parallel_for( size_t jedge=0; jedge( grad_field ); - double maxval = numeric_limits::min(); - double minval = numeric_limits::max();; + auto grad = array::make_view( grad_field ); + double maxval = -std::numeric_limits::max(); + double minval = std::numeric_limits::max();; double norm = 0.; + + nodes_fs.haloExchange(grad_field); + auto glb_idx = array::make_view(mesh.nodes().global_index()); + auto part = array::make_view(mesh.nodes().partition()); for(size_t jnode = 0; jnode < nnodes; ++jnode) { + if( !is_ghost[jnode] ) { - for(size_t jlev = 0; jlev < nlev; ++jlev) + for(size_t jlev = 0; jlev < 1; ++jlev) { - maxval = max(maxval,grad(jnode,jlev,LON)); - maxval = max(maxval,grad(jnode,jlev,LAT)); - maxval = max(maxval,grad(jnode,jlev,ZZ)); - minval = min(minval,grad(jnode,jlev,LON)); - minval = min(minval,grad(jnode,jlev,LAT)); - minval = min(minval,grad(jnode,jlev,ZZ)); -// norm += std::pow(vecnorm(grad[jnode][jlev].data(),3),2); - norm += std::pow(vecnorm( grad.slice(jnode,jlev,Range::all()).data(),3),2); + const double scaling = 1.e12; + grad(jnode,jlev,LON) *= scaling; + grad(jnode,jlev,LAT) *= scaling; + grad(jnode,jlev,ZZ) *= scaling; + + std::array v; + v[0] = grad(jnode,jlev,LON); + v[1] = grad(jnode,jlev,LAT); + v[2] = grad(jnode,jlev,ZZ); + + maxval = std::max(maxval,v[0]); + maxval = std::max(maxval,v[1]); + maxval = std::max(maxval,v[2]); + minval = std::min(minval,v[0]); + minval = std::min(minval,v[1]); + minval = std::min(minval,v[2]); + + //if( parallel::mpi::comm().rank() == 478 ) { + // std::cout << " " << jnode << " part " << part(jnode) << " glb_idx " << glb_idx(jnode) << " x,y,z " << v[0] << "," << v[1] << ","<< v[2] << std::endl; + //} + + + norm += v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; } } } - ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduceInPlace(maxval, eckit::mpi::max()); - parallel::mpi::comm().allReduceInPlace(minval, eckit::mpi::min()); - parallel::mpi::comm().allReduceInPlace(norm, eckit::mpi::sum()); - } - - norm = std::sqrt(norm); - - Log::info() << " checksum: " << nodes_fs.checksum().execute( grad ) << endl; - Log::info() << " maxval: " << setw(13) << setprecision(6) << scientific << maxval << endl; - Log::info() << " minval: " << setw(13) << setprecision(6) << scientific << minval << endl; - Log::info() << " norm: " << setw(13) << setprecision(6) << scientific << norm << endl; if( output ) { @@ -543,61 +615,49 @@ double AtlasBenchmark::result() gmsh.write( scalar_field ); gmsh.write( grad_field ); } - return norm; -} -int AtlasBenchmark::verify(const double& norm) -{ - if( nlev != 137 ) - { - Log::warning() << "Results cannot be verified with nlev != 137" << endl; - return 1; + + bool found; + for ( size_t jnode=0; jnode norms; - norms[ "N16"] = 1.473937e-09; - norms[ "N24"] = 2.090045e-09; - norms[ "N32"] = 2.736576e-09; - norms[ "N48"] = 3.980306e-09; - norms[ "N64"] = 5.219642e-09; - norms[ "N80"] = 6.451913e-09; - norms[ "N96"] = 7.647690e-09; - norms[ "N128"] = 1.009042e-08; - norms[ "N160"] = 1.254571e-08; - norms[ "N200"] = 1.557589e-08; - norms[ "N256"] = 1.983944e-08; - norms[ "N320"] = 2.469347e-08; - norms[ "N400"] = 3.076775e-08; - norms[ "N512"] = 3.924470e-08; - norms[ "N576"] = 4.409003e-08; - norms[ "N640"] = 4.894316e-08; - norms[ "N800"] = 6.104009e-08; - norms["N1024"] = 7.796900e-08; - norms["N1280"] = 9.733947e-08; - norms["N1600"] = 1.215222e-07; - norms["N2000"] = 1.517164e-07; - norms["N4000"] = 2.939562e-07; - - if( norms.count(gridname) == 0 ) + if( parallel::mpi::comm().rank() == debug::mpi_rank() ) ASSERT(found); + + + for(size_t jnode = 0; jnode < nnodes; ++jnode) { - Log::warning() << "Results cannot be verified with grid "<< gridname << '\n'; - Log::warning() << "Valid grids: \n"; - for( std::map::const_iterator it=norms.begin(); it!=norms.end(); ++it) - { - Log::warning() << " - " << it->first << "\n"; + size_t jlev=0; + if ( glb_idx(jnode) == debug::node_global_index() ) { + std::cout << "["< nodes_glb_idx = array::make_view ( nodes.global_index() ); //nodes_glb_idx.dump( Log::info() ); - Log::info() << "min = " << nodes.global_index().metadata().getLong("min") << std::endl; - Log::info() << "max = " << nodes.global_index().metadata().getLong("max") << std::endl; - Log::info() << "human_readable = " << nodes.global_index().metadata().getBool("human_readable") << std::endl; +// ATLAS_DEBUG( "min = " << nodes.global_index().metadata().getLong("min") ); +// ATLAS_DEBUG( "max = " << nodes.global_index().metadata().getLong("max") ); +// ATLAS_DEBUG( "human_readable = " << nodes.global_index().metadata().getBool("human_readable") ); gidx_t glb_idx_max = 0; std::vector points_to_edit; @@ -116,8 +116,8 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui glb_idx[i] = nodes_glb_idx(points_to_edit[i]); - ATLAS_DEBUG_VAR( points_to_edit ); - ATLAS_DEBUG_VAR( points_to_edit.size() ); +// ATLAS_DEBUG_VAR( points_to_edit ); +// ATLAS_DEBUG_VAR( points_to_edit.size() ); /* * Sorting following gidx will define global order of From 79be511647408af216fc603f4f7d68180f93d1f3 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 6 Feb 2018 15:01:26 +0000 Subject: [PATCH 318/355] ATLAS-148 Remove superfluous ATLAS_TRACE from BuildHalo --- src/atlas/mesh/actions/BuildHalo.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 553a7118a..b773cae93 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -26,7 +26,6 @@ #include "atlas/mesh/detail/AccumulateFacets.h" #include "atlas/mesh/detail/PeriodicTransform.h" #include "atlas/parallel/mpi/Buffer.h" -#include "atlas/parallel/mpi/Buffer.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" @@ -398,7 +397,7 @@ void accumulate_elements( const Mesh& mesh, std::vector& found_elements, std::set< uid_t >& new_nodes_uid ) { - ATLAS_TRACE(); + //ATLAS_TRACE(); const mesh::HybridElements::Connectivity &elem_nodes = mesh.cells().node_connectivity(); const array::ArrayView elem_part = array::make_view( mesh.cells().partition() ); @@ -614,7 +613,7 @@ class BuildHaloHelper template< typename NodeContainer, typename ElementContainer > void fill_sendbuffer(Buffers& buf,const NodeContainer& nodes_uid, const ElementContainer& elems, const int p) { - ATLAS_TRACE(); + //ATLAS_TRACE(); int nb_nodes = nodes_uid.size(); buf.node_glb_idx[p].resize(nb_nodes); @@ -677,7 +676,7 @@ class BuildHaloHelper template< typename NodeContainer, typename ElementContainer > void fill_sendbuffer(Buffers& buf,const NodeContainer& nodes_uid, const ElementContainer& elems, const PeriodicTransform& transform, int newflags, const int p) { - ATLAS_TRACE(); + //ATLAS_TRACE(); int nb_nodes = nodes_uid.size(); buf.node_glb_idx[p].resize(nb_nodes); From 21f918f096c150893c21374f6496c41debef4752 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 6 Feb 2018 15:45:32 +0000 Subject: [PATCH 319/355] ATLAS-148 Work on new algorithm to compute edge partitions --- src/atlas/mesh/actions/BuildParallelFields.cc | 352 +++++++----------- 1 file changed, 135 insertions(+), 217 deletions(-) diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 3254d3071..aa341fc7a 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -26,12 +26,14 @@ #include "atlas/runtime/Log.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Trace.h" +#include "atlas/parallel/mpi/Buffer.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/GatherScatter.h" +#include "atlas/util/detail/Debug.h" + +#define EDGE(jedge) "Edge("< edge_part = array::make_view( edges.partition() ); + array::ArrayView edge_part = array::make_view( edges.partition() ); + array::ArrayView edge_glb_idx = array::make_view( edges.global_index() ); + const mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); const mesh::HybridElements::Connectivity& edge_to_elem = edges.cell_connectivity(); @@ -383,249 +387,163 @@ Field& build_edges_partition( Mesh& mesh ) array::ArrayView node_part = array::make_view( nodes.partition() ); array::ArrayView xy = array::make_view( nodes.xy() ); array::ArrayView flags = array::make_view( nodes.field("flags") ); -#ifdef DEBUGGING_PARFIELDS - array::ArrayView gidx = array::make_view( nodes.global_index() ); -#endif + array::ArrayView node_gidx = array::make_view( nodes.global_index() ); array::ArrayView elem_part = array::make_view(mesh.cells().partition() ); + auto check_flags = [&](idx_t jedge, int flag) { + idx_t ip1 = edge_nodes(jedge,0); + idx_t ip2 = edge_nodes(jedge,1); + 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; + } + return false; + }; + PeriodicTransform transform; size_t nb_edges = edges.size(); std::vector periodic(nb_edges); + std::vector bdry_edges; bdry_edges.reserve(nb_edges); + std::map global_to_local; + for( size_t jedge=0; jedge pc[1] ) edge_part(jedge) = pn1; - else if( pc[0] < pc[1] ) edge_part(jedge) = pn2; - else edge_part(jedge) = std::min(pn1,pn2); - -#ifdef DEBUGGING_PARFIELDS - if( OWNED_EDGE(jedge) ) - DEBUG( EDGE(jedge) << " --> pn1,pn2,pe1,pe2 " << pn1 << "," << pn2<< "," << pe1 << "," << pe2); -#endif - - } + int y1 = util::microdeg(xy(ip1,YY)); + int y2 = util::microdeg(xy(ip2,YY)); + int p; + if( y1 == y2 ) { + int x1 = util::microdeg(xy(ip1,XX)); + int x2 = util::microdeg(xy(ip2,XX)); + p = (x1 < x2) ? pn1 : pn2; + } else { + p = (y1 > y2) ? pn1 : pn2; } -#ifdef DEBUGGING_PARFIELDS - if( OWNED_EDGE(jedge) ) - DEBUG( EDGE(jedge) << " --> pn1,pn2 " << pn1 << "," << pn2); -#endif - -#ifdef DEBUGGING_PARFIELDS_disable - if( periodic[jedge] ) - DEBUG(EDGE(jedge)<<" is periodic " << periodic[jedge]); -#endif - -#ifdef DEBUGGING_PARFIELDS_disable - if( PERIODIC_EDGE(jedge) ) - DEBUG( EDGE(jedge) <<": edge_part="< " << uid << " part " << edge_part(jedge)); -#endif - -#ifdef DEBUGGING_PARFIELDS - if( OWNED_UID(uid) ) - { - double x1,y1, x2,y2, xe,ye; - x1 = xy(ip1,XX); - y1 = xy(ip1,YY); - x2 = xy(ip2,XX); - y2 = xy(ip2,YY); - xe = centroid[XX]; - ye = centroid[YY]; - DEBUG( uid << " --> " << EDGE(jedge) << " x1,y1 - x2,y2 - xe,ye " << x1<<","< > send_found( parallel::mpi::comm().size() ); - std::vector< std::vector > recv_found( parallel::mpi::comm().size() ); - - for( size_t jpart=0; jpart& recv_edge = recv_unknown[jpart]; - const size_t nb_recv_edges = recv_edge.size()/varsize; - // array::ArrayView recv_edge( recv_unknown[ jpart ].data(), - // array::make_shape(recv_unknown[ jpart ].size()/varsize,varsize) ); - for( size_t jedge=0; jedge::iterator it = std::lower_bound( bdry_edges.begin(), bdry_edges.end(), gid ); + bool found = !( it == bdry_edges.end() || gid < *it ); + return found; + }; + + int mpi_size = eckit::mpi::comm().size(); + parallel::mpi::Buffer recv_bdry_edges_from_parts(mpi_size); + std::vector< std::vector > send_gidx(mpi_size); + std::vector< std::vector > send_part(mpi_size); + std::vector< std::vector > recv_gidx(mpi_size); + std::vector< std::vector > recv_part(mpi_size); + parallel::mpi::comm().allGatherv(bdry_edges.begin(),bdry_edges.end(),recv_bdry_edges_from_parts); + for( int p=0; p " << edge_part(iedge) << std::endl; } } - // Sanity check + +// // Sanity check for( size_t jedge=0; jedge part " << edge_part(jedge)); -#endif +//#ifdef DEBUGGING_PARFIELDS +// if( OWNED_EDGE(jedge) ) +// DEBUG( EDGE(jedge) << " --> part " << edge_part(jedge)); +//#endif -#ifdef DEBUGGING_PARFIELDS_disable - if( PERIODIC_EDGE(jedge) ) - DEBUG_VAR( " the part is " << edge_part(jedge) ); -#endif - } - /// TODO: Make sure that the edge-partition is at least one of the partition numbers of the - /// neighbouring elements. - /// Because of this problem, the size of the halo should be set to 2 instead of 1!!! - /// This will be addressed with JIRA issue ATLAS-12 +//#ifdef DEBUGGING_PARFIELDS_disable +// if( PERIODIC_EDGE(jedge) ) +// DEBUG_VAR( " the part is " << edge_part(jedge) ); +//#endif +// } +// /// TODO: Make sure that the edge-partition is at least one of the partition numbers of the +// /// neighbouring elements. +// /// Because of this problem, the size of the halo should be set to 2 instead of 1!!! +// /// This will be addressed with JIRA issue ATLAS-12 return edges.partition(); } @@ -650,7 +568,7 @@ Field& build_edges_remote_idx( Mesh& mesh ) array::ArrayView xy = array::make_view( nodes.xy() ); array::ArrayView flags = array::make_view( nodes.field("flags") ); #ifdef DEBUGGING_PARFIELDS - array::ArrayView gidx = array::make_view( nodes.global_index() ); + array::ArrayView node_gidx = array::make_view( nodes.global_index() ); array::ArrayView node_part = array::make_view( nodes.partition() ); #endif @@ -720,8 +638,8 @@ Field& build_edges_remote_idx( Mesh& mesh ) send_needed[ edge_part(jedge) ].push_back( uid ); send_needed[ edge_part(jedge) ].push_back( jedge ); #ifdef DEBUGGING_PARFIELDS - send_needed[ edge_part(jedge) ].push_back( gidx(ip1) ); - send_needed[ edge_part(jedge) ].push_back( gidx(ip2) ); + send_needed[ edge_part(jedge) ].push_back( node_gidx(ip1) ); + send_needed[ edge_part(jedge) ].push_back( node_gidx(ip2) ); send_needed[ edge_part(jedge) ].push_back( node_part(ip1) ); send_needed[ edge_part(jedge) ].push_back( node_part(ip2) ); #endif From fc1ed2511f50afd0424bc1dc5d0cfc8a66dea002 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 7 Feb 2018 11:44:09 +0000 Subject: [PATCH 320/355] ATLAS-148 destroyed structuredmeshgenerator, failures in build_node_remote_idx --- src/apps/atlas-benchmark.cc | 5 +- src/atlas/mesh/actions/BuildParallelFields.cc | 8 +- .../meshgenerator/StructuredMeshGenerator.cc | 115 ++++-------------- src/atlas/runtime/AtlasTool.cc | 18 ++- 4 files changed, 50 insertions(+), 96 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 20fd769a9..2ca7aa010 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -335,8 +335,8 @@ void AtlasBenchmark::setup() ATLAS_TRACE_SCOPE( "build_pole_edges" ) { build_pole_edges(mesh); } //mesh.polygon(0).outputPythonScript("plot_polygon.py"); - //atlas::output::Output gmsh = atlas::output::Gmsh( "edges.msh", util::Config("ghost",true)("edges",true)("elements",false) ); - //gmsh.write( mesh ); + atlas::output::Output gmsh = atlas::output::Gmsh( "edges.msh", util::Config("ghost",true)("edges",true)("elements",false) ); + gmsh.write( mesh ); ATLAS_TRACE_SCOPE( "build_edges_parallel_fiels" ) { build_edges_parallel_fields(mesh); } ATLAS_TRACE_SCOPE( "build_median_dual_mesh" ) { build_median_dual_mesh(mesh); } @@ -472,6 +472,7 @@ void AtlasBenchmark::iteration() if( debug_here ) std::cout << std::endl; } + ::exit(1); atlas_omp_parallel_for( size_t jnode=0; jnode 1 ) - { - add_triag=true; - } - else if( cnt_mypart == 1) - { - int pcnts[3]; - for( int j=0; j<3; ++j ) - pcnts[j] = std::count(np, np+3, np[j]); - int cnt_max = *std::max_element(pcnts,pcnts+3); - if( cnt_max == 1) - { - if( 0.5*(yN+yS) > 1e-6 ) - { - if( pS1 == mypart ) - add_triag = true; - } - else - { - if( pN1 == mypart ) - add_triag = true; - } + if( pN2 == pS1 ) { + add_triag = ( mypart == pN1 ); + } else if( pN1 == pS1 ) { + add_triag = ( mypart == pN2 ); + } else { + if( 0.5*(yN+yS) > 1e-6 ) { + add_triag = ( mypart == pN1 ); + } else { + add_triag = ( mypart == pS1 ); } } -#else - if( 0.5*(yN+yS) > 1e-6 ) - { - if( pN1 == mypart ) - add_triag = true; - } - else - { - if( pS1 == mypart ) - add_triag = true; - } -#endif + if (add_triag) { ++region.ntriags; @@ -659,54 +629,17 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co add_triag = false; -#ifdef PARTITIONING_BEFORE_ATLAS_0_12 - int cnt_mypart = 0; - int np[3] = {pN1, pS1, pS2}; - for( int j=0; j<3; ++j ) { - if (np[j]==mypart) ++cnt_mypart; - } - - if( cnt_mypart > 1 ) - { - add_triag=true; - } - else if( cnt_mypart == 1) - { - int pcnts[3]; - for( int j=0; j<3; ++j ) - pcnts[j] = std::count(np, np+3, np[j]); - int cnt_max = *std::max_element(pcnts,pcnts+3); - if( cnt_max == 1) - { - // if( latN == 0 && mypart = pN1 ) || latS == rg.nlat()-1 ) - // { - // add_triag = true; - // } - // else - if( 0.5*(yN+yS) > 1e-6 ) - { - if( pS2 == mypart ) - add_triag = true; - } - else - { - if( pN1 == mypart ) - add_triag = true; - } + if( pN1 == pS2 ) { + add_triag = ( mypart == pS1 ); + } else if( pN1 == pS1 ) { + add_triag = ( mypart == pS2 ); + } else { + if( 0.5*(yN+yS) > 1.e-6 ) { + add_triag = ( mypart == pN1 ); + } else { + add_triag = ( mypart == pS2 ); } } -#else - if( 0.5*(yN+yS) > 1e-6 ) - { - if( pN1 == mypart ) - add_triag = true; - } - else - { - if( pS2 == mypart ) - add_triag = true; - } -#endif if (add_triag) { @@ -1066,7 +999,7 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons glb_idx(inode) = periodic_glb.at(jlat)+1; - part(inode) = part(inode_left); + part(inode) = part( offset_glb.at(jlat) ); // part(inode_left); ghost(inode) = 1; Topology::reset(flags(inode)); Topology::set(flags(inode),Topology::BC|Topology::EAST); diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index 4540fa9d4..b988deb71 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -9,6 +9,16 @@ namespace { + +int digits(int number) { + int d = 0; + while( number ) { + number /= 10; + d++; + } + return d; +} + static std::string debug_prefix(const std::string& libname) { std::string s = libname; std::transform(s.begin(), s.end(), s.begin(), ::toupper); @@ -109,6 +119,7 @@ bool atlas::AtlasTool::handle_help() atlas::AtlasTool::AtlasTool(int argc, char **argv): eckit::Tool(argc,argv) { eckit::LibEcKit::instance().setAbortHandler( []{ + Log::error() << "["< Date: Wed, 7 Feb 2018 13:09:45 +0000 Subject: [PATCH 321/355] ATLAS-148 Fix meshgenerator, plus polluted prints --- src/apps/atlas-meshgen.cc | 2 +- src/atlas/mesh/actions/BuildParallelFields.cc | 10 ++++++++-- .../meshgenerator/StructuredMeshGenerator.cc | 6 ++++-- src/atlas/util/detail/Debug.h | 17 +++++++++++++++-- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/apps/atlas-meshgen.cc b/src/apps/atlas-meshgen.cc index 2c155aac6..174bf7137 100644 --- a/src/apps/atlas-meshgen.cc +++ b/src/apps/atlas-meshgen.cc @@ -211,7 +211,7 @@ void Meshgen2Gmsh::execute(const Args& args) } if( grid.projection().units() == "degrees" ) { - functionspace::NodeColumns nodes_fs(mesh,option::halo(halo)); + // functionspace::NodeColumns nodes_fs(mesh,option::halo(halo)); } else { Log::warning() << "Not yet implemented: building halo's with projections not defined in degrees" << std::endl; Log::warning() << "units: " << grid.projection().units() << std::endl; diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 1eebf7be3..bb87ad603 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -261,8 +261,9 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) proc[jpart] = jpart; // <--------- - array::IndexView ridx = array::make_indexview( nodes.remote_index() ); - array::ArrayView part = array::make_view( nodes.partition() ); + auto ridx = array::make_indexview( nodes.remote_index() ); + auto part = array::make_view( nodes.partition() ); + auto gidx = array::make_view( nodes.global_index() ); size_t nb_nodes = nodes.size(); int varsize=2; @@ -274,6 +275,11 @@ Field& build_nodes_remote_idx( mesh::Nodes& nodes ) for( size_t jnode=0; jnode(rg.nx(jlat)); @@ -999,8 +1000,9 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons glb_idx(inode) = periodic_glb.at(jlat)+1; - part(inode) = part( offset_glb.at(jlat) ); // part(inode_left); + part(inode) = parts.at( offset_glb.at(jlat) ); // part(inode_left); ghost(inode) = 1; + std::cout << debug::rank_str() << "periodic point gidx: " << glb_idx(inode) << " part: " << part(inode) << " master = " << 1+ offset_glb.at(jlat) << std::endl; Topology::reset(flags(inode)); Topology::set(flags(inode),Topology::BC|Topology::EAST); Topology::set(flags(inode),Topology::GHOST); diff --git a/src/atlas/util/detail/Debug.h b/src/atlas/util/detail/Debug.h index 086fd4957..7a8300821 100644 --- a/src/atlas/util/detail/Debug.h +++ b/src/atlas/util/detail/Debug.h @@ -17,7 +17,12 @@ inline gidx_t edge_global_index(int i=0) { return g[i]; } -bool is_node_global_index( gidx_t x ) { +inline gidx_t node_uid(int i=0) { + static std::vector g = eckit::Resource>("$ATLAS_DEBUG_NODE_UID", std::vector{-1} ); + return g[i]; +} + +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 ) @@ -26,7 +31,7 @@ bool is_node_global_index( gidx_t x ) { return false; } -bool is_edge_global_index( gidx_t x ) { +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 ) @@ -35,6 +40,14 @@ bool is_edge_global_index( gidx_t x ) { return false; } +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; + } + return false; +} inline int mpi_rank() { static int r = eckit::Resource("$ATLAS_DEBUG_MPI_RANK",-1); From 056216d45e1801e519a12b7f22eeb636343903a5 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 7 Feb 2018 18:23:27 +0000 Subject: [PATCH 322/355] ATLAS-148 Meshgenerator fixed? still polluted --- .../meshgenerator/StructuredMeshGenerator.cc | 201 +++++++++--------- 1 file changed, 101 insertions(+), 100 deletions(-) diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index af8915fd5..7b8fa059d 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -350,6 +350,8 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co ipS2 = std::min(ipS1+1,endS); int jelem=0; + int pE = parts.at(offset.at(latN)); + #if DEBUG_OUTPUT Log::info() << "=================\n"; @@ -535,6 +537,8 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co } else if( cnt_max < 3 ) // 3 or 4 points don't belong to mypart { + if( pN1 == mypart ) add_quad = true; +/* if( 0.5*(yN+yS) > 1e-6) { if ( pS1 == mypart ) add_quad = true; @@ -543,6 +547,7 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co { if ( pN2 == mypart ) add_quad = true; } +*/ } } if (add_quad) @@ -579,19 +584,8 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co elem(2) = -1; elem(3) = ipN2; - add_triag = false; - - if( pN2 == pS1 ) { - add_triag = ( mypart == pN1 ); - } else if( pN1 == pS1 ) { - add_triag = ( mypart == pN2 ); - } else { - if( 0.5*(yN+yS) > 1e-6 ) { - add_triag = ( mypart == pN1 ); - } else { - add_triag = ( mypart == pS1 ); - } - } + pE = pN1; + add_triag = (mypart == pE); if (add_triag) { @@ -628,19 +622,15 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co elem(2) = ipS2; elem(3) = -1; - add_triag = false; - - if( pN1 == pS2 ) { - add_triag = ( mypart == pS1 ); - } else if( pN1 == pS1 ) { - add_triag = ( mypart == pS2 ); + if( pS1 == pE && pN1 != pE ) { + if( xN1 < 0.5*(xS1+xS2) ) { + pE = pN1; + } // else pE of previous element } else { - if( 0.5*(yN+yS) > 1.e-6 ) { - add_triag = ( mypart == pN1 ); - } else { - add_triag = ( mypart == pS2 ); - } + pE = pN1; } + if( ipN1 == rg.nx(latN) ) pE = pS1; + add_triag = (mypart == pE); if (add_triag) { @@ -682,8 +672,8 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co if( region.nb_lat_elems.at(jlat) == 0 && latS == size_t(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)); +// 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 ) @@ -714,7 +704,7 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co nb_region_nodes += region.lat_end.at(jlat)-region.lat_begin.at(jlat)+1; // Count extra periodic node - if( periodic_east_west && size_t(region.lat_end.at(jlat)) == rg.nx(jlat) - 1) ++nb_region_nodes; + //if( periodic_east_west && size_t(region.lat_end.at(jlat)) == rg.nx(jlat) - 1) ++nb_region_nodes; } region.nnodes = nb_region_nodes; @@ -893,23 +883,26 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons } for( int jlon=region.lat_begin.at(jlat); jlon<=region.lat_end.at(jlat); ++jlon ) { - n = offset_glb.at(jlat) + jlon; - if( parts.at(n) == mypart ) { - node_numbering.at(jnode) = node_number; - ++node_number; + if( jlon < rg.nx(jlat) ) { + n = offset_glb.at(jlat) + jlon; + if( parts.at(n) == mypart ) { + node_numbering.at(jnode) = node_number; + ++node_number; + } + else { + ghost_nodes.push_back( GhostNode(jlat,jlon,jnode)); + } + ++jnode; } - else { - ghost_nodes.push_back( GhostNode(jlat,jlon,jnode)); + else if ( include_periodic_ghost_points ) // add periodic point + { + part(jnode) = part(jnode-1); + ghost(jnode) = 1; + ghost_nodes.push_back( GhostNode(jlat,rg.nx(jlat),jnode) ); + ++jnode; + } else { + --l; } - ++jnode; - } - if(include_periodic_ghost_points && size_t(region.lat_end.at(jlat)) == rg.nx(jlat) - 1) // add periodic point - { - ++l; - part(jnode) = part(jnode-1); - ghost(jnode) = 1; - ghost_nodes.push_back( GhostNode(jlat,rg.nx(jlat),jnode) ); - ++jnode; } } for( size_t jghost=0; jghost( mesh.cells().global_index() ); + auto node_gidx = array::make_view( mesh.nodes().global_index() ); + const mesh::Nodes& nodes = mesh.nodes(); node2elem.resize(nodes.size()); @@ -292,6 +295,17 @@ void accumulate_partition_bdry_nodes_old( Mesh& mesh, std::vector& bdry_nod } } bdry_nodes = std::vector( bdry_nodes_set.begin(), bdry_nodes_set.end()); + + //debugging + { + auto node_gidx = array::make_view(mesh.nodes().global_index()); + for( int j=0; j& node_uid, + const parallel::mpi::BufferView& request_node_uid, const Uid2Node& uid2node, const Node2Elem& node2elem, - std::vector& found_elements, + std::vector& found_elements, std::set< uid_t >& new_nodes_uid ) { //ATLAS_TRACE(); const mesh::HybridElements::Connectivity &elem_nodes = mesh.cells().node_connectivity(); - const array::ArrayView elem_part = array::make_view( mesh.cells().partition() ); + const auto elem_part = array::make_view( mesh.cells().partition() ); + const auto cell_gidx = array::make_view( mesh.cells().global_index() ); + const auto node_gidx = array::make_view( mesh.nodes().global_index() ); - size_t nb_nodes = node_uid.size(); + size_t nb_nodes = request_node_uid.size(); const size_t mpi_rank = parallel::mpi::comm().rank(); - std::set< int > found_elements_set; + std::set< idx_t > found_elements_set; for( size_t jnode=0; jnodesecond; +// if( debug::is_node_global_index( node_gidx(inode) ) ) { +// std::cout << debug::rank_str() << " node " << node_gidx(inode) << " found" << std::endl; +// } } if( inode != -1 && size_t(inode) < node2elem.size() ) { for(size_t jelem = 0; jelem < node2elem[inode].size(); ++jelem) { - int e = node2elem[inode][jelem]; + idx_t e = node2elem[inode][jelem]; if( size_t(elem_part(e)) == mpi_rank ) { found_elements_set.insert( e ); @@ -431,7 +454,7 @@ void accumulate_elements( const Mesh& mesh, } // found_bdry_elements_set now contains elements for the nodes - found_elements = std::vector( found_elements_set.begin(), found_elements_set.end()); + found_elements = std::vector( found_elements_set.begin(), found_elements_set.end()); UniqueLonLat compute_uid( mesh ); @@ -439,7 +462,8 @@ void accumulate_elements( const Mesh& mesh, new_nodes_uid.clear(); for(size_t jelem = 0; jelem < found_elements.size(); ++jelem) { - size_t e = found_elements[jelem]; + idx_t e = found_elements[jelem]; + size_t nb_elem_nodes = elem_nodes.cols(e); for( size_t n=0; nrow(ielem) ); buf.elem_part [p][jelem] = elem_part(ielem); buf.elem_type [p][jelem] = mesh.cells().type_idx(ielem); for( size_t jnode=0; jnodecols(ielem); ++jnode ) buf.elem_nodes_id[p][jelemnode++] = compute_uid( (*elem_nodes)(ielem,jnode) ); + + if( debug::is_cell_global_index( elem_glb_idx(ielem) ) ) { + std::cout << debug::rank_str() << "uid of elem " << elem_glb_idx(ielem) << " : " << buf.elem_glb_idx[p][jelem] << std::endl; + } + } } @@ -964,7 +998,7 @@ class BuildHaloHelper namespace { -void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, bool periodic = false ) { +void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, bool periodic = false ) { auto& comm = parallel::mpi::comm(); #ifndef ATLAS_103 /* deprecated */ @@ -1055,6 +1089,8 @@ void increase_halo_interior( BuildHaloHelper& helper ) build_lookup_uid2node(helper.mesh,helper.uid2node); + auto cell_gidx = array::make_view( helper.mesh.cells().global_index() ); + // All buffers needed to move elements and nodes BuildHaloHelper::Buffers sendmesh(helper.mesh); BuildHaloHelper::Buffers recvmesh(helper.mesh); @@ -1070,6 +1106,12 @@ void increase_halo_interior( BuildHaloHelper& helper ) for(size_t jnode = 0; jnode < bdry_nodes.size(); ++jnode) send_bdry_nodes_uid[jnode] = helper.compute_uid(bdry_nodes[jnode]); + for( auto uid : send_bdry_nodes_uid ) { + if( debug::is_node_uid(uid) ) { + std::cout << debug::rank_str() << "requesting elements for uid " << uid << std::endl; + } + } + size_t mpi_size = parallel::mpi::comm().size(); atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); @@ -1090,7 +1132,11 @@ void increase_halo_interior( BuildHaloHelper& helper ) parallel::mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; - std::vector found_bdry_elems; + if( debug::is_mpi_rank() && debug::is_mpi_rank(jpart) ) { + std::cout << debug::rank_str() << "handling requests from " << jpart << std::endl; + } + + std::vector found_bdry_elems; std::set< uid_t > found_bdry_nodes_uid; accumulate_elements(helper.mesh,recv_bdry_nodes_uid, @@ -1099,6 +1145,12 @@ void increase_halo_interior( BuildHaloHelper& helper ) found_bdry_elems, found_bdry_nodes_uid); + for( idx_t elem : found_bdry_elems ) { + if( debug::is_cell_global_index( cell_gidx(elem) ) ) { + std::cout << debug::rank_str() << "found requested elem " << cell_gidx(elem) << std::endl; + } + } + // 4) Fill node and element buffers to send back helper.fill_sendbuffer(sendmesh, found_bdry_nodes_uid, found_bdry_elems, jpart); } diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 7b8fa059d..b5c554dfd 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -937,9 +937,6 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons l+=region.lat_end.at(jlat)-region.lat_begin.at(jlat)+1; double y = rg.y(jlat); - if( region.lat_end[jlat] == rg.nx(jlat) ) { - std::cout << debug::rank_str() << jlat << " includes periodic point " << std::endl; - } for( int jlon=region.lat_begin.at(jlat); jlon<=region.lat_end.at(jlat); ++jlon ) { if( jlon < rg.nx(jlat) ) { @@ -1000,7 +997,6 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons // part(inode) = part(inode_left); part(inode) = mypart; ghost(inode) = 1; - std::cout << debug::rank_str() << "periodic point gidx: " << glb_idx(inode) << " part: " << part(inode) << " master = " << 1+ offset_glb.at(jlat) << std::endl; Topology::reset(flags(inode)); Topology::set(flags(inode),Topology::BC|Topology::EAST); Topology::set(flags(inode),Topology::GHOST); diff --git a/src/atlas/util/Unique.h b/src/atlas/util/Unique.h index bb0749ac4..1bafb2337 100644 --- a/src/atlas/util/Unique.h +++ b/src/atlas/util/Unique.h @@ -173,7 +173,8 @@ inline uidx_t unique_lonlat( const double elem_lonlat[], size_t npts ) // FIXME: this should be `unique_lonlat( centroid )` // but this causes some weird behavior in parallelisation - return detail::unique32( microdeg(centroid[LON]), microdeg(centroid[LAT]) ); + return unique_lonlat( centroid[LON], centroid[LAT] ); +// return detail::unique32( microdeg(centroid[LON]), microdeg(centroid[LAT]) ); } @@ -213,7 +214,8 @@ inline uidx_t UniqueLonLat::operator()( const mesh::Connectivity::Row& elem_node // FIXME: this should be `unique_lonlat( centroid )` // but this causes some weird behavior in parallelisation - return detail::unique32( microdeg(centroid[XX]), microdeg(centroid[YY]) ); + return unique_lonlat( centroid[XX], centroid[YY] ); +// return detail::unique32( microdeg(centroid[XX]), microdeg(centroid[YY]) ); } @@ -234,7 +236,8 @@ inline uidx_t UniqueLonLat::operator()( const int elem_nodes[], size_t npts ) co // FIXME: this should be `unique_lonlat( centroid )` // but this causes some weird behavior in parallelisation - return detail::unique32( microdeg(centroid[XX]), microdeg(centroid[YY]) ); + return unique_lonlat( centroid[XX], centroid[YY] ); +// return detail::unique32( microdeg(centroid[XX]), microdeg(centroid[YY]) ); } diff --git a/src/atlas/util/detail/Debug.h b/src/atlas/util/detail/Debug.h index 7a8300821..cd0286746 100644 --- a/src/atlas/util/detail/Debug.h +++ b/src/atlas/util/detail/Debug.h @@ -17,6 +17,11 @@ inline gidx_t edge_global_index(int i=0) { return g[i]; } +inline gidx_t cell_global_index(int i=0) { + static std::vector g = eckit::Resource>("$ATLAS_DEBUG_CELL_GLOBAL_INDEX", std::vector{-1} ); + return g[i]; +} + inline gidx_t node_uid(int i=0) { static std::vector g = eckit::Resource>("$ATLAS_DEBUG_NODE_UID", std::vector{-1} ); return g[i]; @@ -40,6 +45,15 @@ inline bool is_edge_global_index( gidx_t x ) { return false; } +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; + } + return false; +} + 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 ) { @@ -49,11 +63,38 @@ inline bool is_node_uid( gidx_t x ) { return false; } -inline int mpi_rank() { - static int r = eckit::Resource("$ATLAS_DEBUG_MPI_RANK",-1); - return r; +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; + } + return false; +} + +inline int mpi_rank(int i=0) { + static std::vector g = eckit::Resource>("$ATLAS_DEBUG_MPI_RANK", std::vector{-1} ); + return g[i]; +} + +inline int is_mpi_rank() { + static std::vector v = eckit::Resource>("$ATLAS_DEBUG_MPI_RANK", std::vector() ); + static int r = parallel::mpi::comm().rank(); + for( long g : v ) { + if ( r == g ) + return true; + } + return false; } +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; + } + return false; +} inline std::string rank_str() { static std::string s = "["+std::to_string(parallel::mpi::comm().rank())+"] "; return s; From 262b4466e4a965043af11cf2d7be215951191160 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 7 Feb 2018 23:03:24 +0000 Subject: [PATCH 324/355] ATLAS-148 atlas-benchmark seems to run OK. More testing needed with checksums, and big cleanup of print statements --- src/apps/atlas-benchmark.cc | 1 - src/atlas/mesh/actions/BuildHalo.cc | 16 +++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 9fe6e0c53..2d7a89945 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -475,7 +475,6 @@ void AtlasBenchmark::iteration() if( debug_here ) std::cout << std::endl; } - ::exit(1); atlas_omp_parallel_for( size_t jnode=0; jnoderow(ielem) ); + buf.elem_glb_idx[p][jelem] = elem_glb_idx(ielem); buf.elem_part [p][jelem] = elem_part(ielem); buf.elem_type [p][jelem] = mesh.cells().type_idx(ielem); for( size_t jnode=0; jnodecols(ielem); ++jnode ) buf.elem_nodes_id[p][jelemnode++] = compute_uid( (*elem_nodes)(ielem,jnode) ); if( debug::is_cell_global_index( elem_glb_idx(ielem) ) ) { - std::cout << debug::rank_str() << "uid of elem " << elem_glb_idx(ielem) << " : " << buf.elem_glb_idx[p][jelem] << std::endl; + auto elem_uid = compute_uid( elem_nodes->row(ielem) ); + std::cout << debug::rank_str() << "uid of elem " << elem_glb_idx(ielem) << " : " << elem_uid << std::endl; } } @@ -777,7 +778,7 @@ class BuildHaloHelper } // Global index of element is based on UID of destination - buf.elem_glb_idx[p][jelem] = util::unique_lonlat( crds.data(), elem_nodes->cols(ielem) ); + buf.elem_glb_idx[p][jelem] = - util::unique_lonlat( crds.data(), elem_nodes->cols(ielem) ); } } @@ -895,16 +896,17 @@ class BuildHaloHelper ATLAS_TRACE(); const size_t mpi_size = parallel::mpi::comm().size(); - + auto cell_gidx = array::make_view(mesh.cells().global_index()); // Elements might be duplicated from different Tasks. We need to identify unique entries int nb_elems = mesh.cells().size(); // std::set elem_uid; - std::vector elem_uid(nb_elems); + std::vector elem_uid(2*nb_elems); std::set new_elem_uid; { ATLAS_TRACE( "compute elem_uid" ); for( int jelem=0; jelemrow(jelem)); + elem_uid[jelem*2+0] = - compute_uid(elem_nodes->row(jelem)); + elem_uid[jelem*2+1] = cell_gidx(jelem); } std::sort( elem_uid.begin(), elem_uid.end() ); } @@ -974,7 +976,7 @@ class BuildHaloHelper for(size_t e = 0; e < elems[jpart].size(); ++e) { size_t jelem = elems[jpart][e]; - elem_type_glb_idx(new_elems_pos+new_elem) = buf.elem_glb_idx[jpart][jelem]; + elem_type_glb_idx(new_elems_pos+new_elem) = std::abs(buf.elem_glb_idx[jpart][jelem]); elem_type_part (new_elems_pos+new_elem) = buf.elem_part[jpart][jelem]; elem_type_halo (new_elems_pos+new_elem) = halo+1; elem_type_patch (new_elems_pos+new_elem) = 0; From c704b421fe8707d4866aa0519eff303faa8e811b Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 8 Feb 2018 10:20:41 +0000 Subject: [PATCH 325/355] ATLAS-148 Checksums seem to be OK in atlas-benchmark. Still needs cleanup and unit-tests need fixing --- src/apps/atlas-benchmark.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 2d7a89945..2c38ce257 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -335,11 +335,11 @@ void AtlasBenchmark::setup() ATLAS_TRACE_SCOPE( "build_pole_edges" ) { build_pole_edges(mesh); } //mesh.polygon(0).outputPythonScript("plot_polygon.py"); - atlas::output::Output gmsh = atlas::output::Gmsh( "edges.msh", util::Config("ghost",true)("edges",true)("elements",false) ); - gmsh.write( mesh ); +// atlas::output::Output gmsh = atlas::output::Gmsh( "edges.msh", util::Config("ghost",true)("edges",true)("elements",false) ); +// gmsh.write( mesh ); - gmsh = atlas::output::Gmsh( "elements.msh", util::Config("ghost",true)("edges",false)("elements",true) ); - gmsh.write( mesh ); +// gmsh = atlas::output::Gmsh( "elements.msh", util::Config("ghost",true)("edges",false)("elements",true) ); +// gmsh.write( mesh ); ATLAS_TRACE_SCOPE( "build_edges_parallel_fiels" ) { build_edges_parallel_fields(mesh); } ATLAS_TRACE_SCOPE( "build_median_dual_mesh" ) { build_median_dual_mesh(mesh); } From 08ab48ad44a8f895ffc2fc4049d69c3553ebc49d Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 9 Feb 2018 13:48:51 +0000 Subject: [PATCH 326/355] ATLAS-148 cleanup --- src/CMakeLists.txt | 7 --- src/apps/atlas-benchmark.cc | 49 ------------------- src/atlas/mesh/actions/BuildHalo.cc | 49 ------------------- src/atlas/mesh/actions/BuildParallelFields.cc | 18 +++---- .../meshgenerator/StructuredMeshGenerator.cc | 42 ++++------------ 5 files changed, 16 insertions(+), 149 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d95b713da..2a48b5b55 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,13 +48,6 @@ else() set( ATLAS_HAVE_GRIDTOOLS_STORAGE 0 ) endif() -if( ATLAS_HAVE_MPI ) - - set( ATLAS_MPI_C_LIBRARIES ${MPI_CXX_LIBRARIES} ) - ecbuild_include_mpi() - -endif() - add_subdirectory( atlas_acc_support ) add_subdirectory( atlas ) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 2c38ce257..349f42c3a 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -59,7 +59,6 @@ #include "atlas/parallel/HaloExchange.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/omp/omp.h" -#include "atlas/util/detail/Debug.h" //---------------------------------------------------------------------------------------------------------------------- @@ -442,38 +441,12 @@ void AtlasBenchmark::iteration() int ip1 = edge2node(jedge,0); int ip2 = edge2node(jedge,1); - bool debug_here = false; - if( debug::is_node_global_index( node_glb_idx(ip1) ) || debug::is_node_global_index( node_glb_idx(ip2) ) ) { - debug_here = true; - } - if( debug_here ) { - if( debug::is_edge_global_index( edge_glb_idx(jedge) ) ) { - std::cout << "* "; - } - else { - std::cout << " "; - } - - std::cout << debug::rank_str() << "Edge["<& bdry_nod } } bdry_nodes = std::vector( bdry_nodes_set.begin(), bdry_nodes_set.end()); - - //debugging - { - auto node_gidx = array::make_view(mesh.nodes().global_index()); - for( int j=0; j( mesh.cells().partition() ); - const auto cell_gidx = array::make_view( mesh.cells().global_index() ); - const auto node_gidx = array::make_view( mesh.nodes().global_index() ); size_t nb_nodes = request_node_uid.size(); const size_t mpi_rank = parallel::mpi::comm().rank(); @@ -426,19 +412,12 @@ void accumulate_elements( const Mesh& mesh, { uid_t uid = request_node_uid(jnode); -// if( debug::is_mpi_rank() && debug::is_node_uid(uid) ) { -// std::cout << debug::rank_str() << "accumulate_elements for uid " << uid << std::endl; -// } - int inode = -1; // search and get node index for uid Uid2Node::const_iterator found = uid2node.find(uid); if( found != uid2node.end() ) { inode = found->second; -// if( debug::is_node_global_index( node_gidx(inode) ) ) { -// std::cout << debug::rank_str() << " node " << node_gidx(inode) << " found" << std::endl; -// } } if( inode != -1 && size_t(inode) < node2elem.size() ) { @@ -690,21 +669,11 @@ class BuildHaloHelper buf.elem_nodes_displs[p][jelem] = jelemnode; size_t ielem = elems[jelem]; - if( debug::is_cell_global_index( elem_glb_idx(ielem) ) ) { - std::cout << debug::rank_str() << "preparing send of elem " << elem_glb_idx(ielem) << std::endl; - } - buf.elem_glb_idx[p][jelem] = elem_glb_idx(ielem); buf.elem_part [p][jelem] = elem_part(ielem); buf.elem_type [p][jelem] = mesh.cells().type_idx(ielem); for( size_t jnode=0; jnodecols(ielem); ++jnode ) buf.elem_nodes_id[p][jelemnode++] = compute_uid( (*elem_nodes)(ielem,jnode) ); - - if( debug::is_cell_global_index( elem_glb_idx(ielem) ) ) { - auto elem_uid = compute_uid( elem_nodes->row(ielem) ); - std::cout << debug::rank_str() << "uid of elem " << elem_glb_idx(ielem) << " : " << elem_uid << std::endl; - } - } } @@ -1091,8 +1060,6 @@ void increase_halo_interior( BuildHaloHelper& helper ) build_lookup_uid2node(helper.mesh,helper.uid2node); - auto cell_gidx = array::make_view( helper.mesh.cells().global_index() ); - // All buffers needed to move elements and nodes BuildHaloHelper::Buffers sendmesh(helper.mesh); BuildHaloHelper::Buffers recvmesh(helper.mesh); @@ -1108,12 +1075,6 @@ void increase_halo_interior( BuildHaloHelper& helper ) for(size_t jnode = 0; jnode < bdry_nodes.size(); ++jnode) send_bdry_nodes_uid[jnode] = helper.compute_uid(bdry_nodes[jnode]); - for( auto uid : send_bdry_nodes_uid ) { - if( debug::is_node_uid(uid) ) { - std::cout << debug::rank_str() << "requesting elements for uid " << uid << std::endl; - } - } - size_t mpi_size = parallel::mpi::comm().size(); atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); @@ -1134,10 +1095,6 @@ void increase_halo_interior( BuildHaloHelper& helper ) parallel::mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; - if( debug::is_mpi_rank() && debug::is_mpi_rank(jpart) ) { - std::cout << debug::rank_str() << "handling requests from " << jpart << std::endl; - } - std::vector found_bdry_elems; std::set< uid_t > found_bdry_nodes_uid; @@ -1147,12 +1104,6 @@ void increase_halo_interior( BuildHaloHelper& helper ) found_bdry_elems, found_bdry_nodes_uid); - for( idx_t elem : found_bdry_elems ) { - if( debug::is_cell_global_index( cell_gidx(elem) ) ) { - std::cout << debug::rank_str() << "found requested elem " << cell_gidx(elem) << std::endl; - } - } - // 4) Fill node and element buffers to send back helper.fill_sendbuffer(sendmesh, found_bdry_nodes_uid, found_bdry_elems, jpart); } diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index bb87ad603..de6cffa52 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -29,7 +29,6 @@ #include "atlas/parallel/mpi/Buffer.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/GatherScatter.h" -#include "atlas/util/detail/Debug.h" #define EDGE(jedge) "Edge("< " << edge_part(iedge) << std::endl; + // Log::error() << EDGE(iedge) << " part " << prev << " --> " << edge_part(iedge) << std::endl; } } @@ -523,14 +517,14 @@ Field& build_edges_partition( Mesh& mesh ) bool edge_partition_is_same_as_one_of_nodes = ( p == pn1 || p == pn2 ); if ( edge_is_partition_boundary ) { if( not edge_partition_is_same_as_one_of_nodes ) { - Log::error() << debug::rank_str() << EDGE(jedge) << " [p"< 2 ) // 3 or 4 points belong to mypart { - if( pN1 == mypart ) - { - add_quad = true; - } - } - else if ( latS == rg.ny()-1 ) - { - if( pS2 == mypart ) - { - add_quad = true; - } - } - else if( cnt_mypart > 2 ) // 3 or 4 points belong to mypart - { - add_quad = true; + pE = mypart; } - else if( cnt_max < 3 ) // 3 or 4 points don't belong to mypart + else // 3 or 4 points don't belong to mypart { - if( pN1 == mypart ) add_quad = true; -/* - if( 0.5*(yN+yS) > 1e-6) - { - if ( pS1 == mypart ) add_quad = true; - } - else - { - if ( pN2 == mypart ) add_quad = true; - } -*/ + pE = pN1; + if( latS == rg.ny()-1 ) pE = pS1; } } + add_quad = ( pE == mypart ); if (add_quad) { ++region.nquads; @@ -585,6 +562,7 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co elem(3) = ipN2; pE = pN1; + if( latS == rg.ny()-1 ) pE = pS1; add_triag = (mypart == pE); if (add_triag) @@ -630,6 +608,8 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co pE = pN1; } if( ipN1 == rg.nx(latN) ) pE = pS1; + if( latS == rg.ny()-1 ) pE = pS1; + add_triag = (mypart == pE); if (add_triag) @@ -993,9 +973,7 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons glb_idx(inode) = periodic_glb.at(jlat)+1; - // part(inode) = parts.at( offset_glb.at(jlat) ); // part(inode_left); - // part(inode) = part(inode_left); - part(inode) = mypart; + part(inode) = mypart; // The actual part will be fixed later ghost(inode) = 1; Topology::reset(flags(inode)); Topology::set(flags(inode),Topology::BC|Topology::EAST); From 341c045eef145d2972d4d6987d447e51175b5aca Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 9 Feb 2018 17:49:24 +0000 Subject: [PATCH 327/355] ATLAS-148 Fix StructuredMeshGenerator for quads --- .../meshgenerator/StructuredMeshGenerator.cc | 36 +++++++++++-------- src/tests/mesh/test_distmesh.cc | 1 - 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index de9bb5515..6d40493cd 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -507,21 +507,23 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co elem(2) = ipS2; elem(3) = ipN2; add_quad = false; - int np[] = {pN1, pN2, pS1, pS2}; - int cnt_mypart = std::count(np, np+4, mypart); - if( cnt_mypart > 0 ) - { - int pcnts[4]; - for( int j=0; j<4; ++j ) - pcnts[j] = std::count(np, np+4, np[j]); - int cnt_max = *std::max_element(pcnts,pcnts+4); - - if( cnt_mypart > 2 ) // 3 or 4 points belong to mypart - { - pE = mypart; + std::array np {pN1, pN2, pS1, pS2}; + std::array pcnts; + 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 ) pE = pS1; + } else if ( pcnts[2] > 2 ) { // 3 or more of pS1 + pE = pS1; + if( latN == 0 ) pE = pN1; + } + else { + std::array::iterator p_max = std::max_element(pcnts.begin(),pcnts.end()); + if( *p_max > 2 ) { // 3 or 4 points belong to same part + pE = np[ std::distance(np.begin(),p_max) ]; } - else // 3 or 4 points don't belong to mypart - { + else { // 3 or 4 points don't belong to mypart pE = pN1; if( latS == rg.ny()-1 ) pE = pS1; } @@ -876,7 +878,9 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons } else if ( include_periodic_ghost_points ) // add periodic point { - part(jnode) = part(jnode-1); +#warning TODO: use second approach + part(jnode) = mypart; + //part(jnode) = parts.at( offset_glb.at(jlat) ); ghost(jnode) = 1; ghost_nodes.push_back( GhostNode(jlat,rg.nx(jlat),jnode) ); ++jnode; @@ -973,6 +977,8 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons glb_idx(inode) = periodic_glb.at(jlat)+1; +#warning TODO: use second approach +// part(inode) = parts.at( offset_glb.at(jlat) ); part(inode) = mypart; // The actual part will be fixed later ghost(inode) = 1; Topology::reset(flags(inode)); diff --git a/src/tests/mesh/test_distmesh.cc b/src/tests/mesh/test_distmesh.cc index c510a21d7..ee156fe74 100644 --- a/src/tests/mesh/test_distmesh.cc +++ b/src/tests/mesh/test_distmesh.cc @@ -111,7 +111,6 @@ CASE( "test_distribute_t63" ) mesh::actions::write_load_balance_report(m,"load_balance.dat"); - // Mesh& mesh1 = Mesh::from_id(meshid); Mesh& mesh1 = m; EXPECT( mesh1.nodes().size() == m.nodes().size() ); From c30a964ff55ed0b58c60fc4d47390eaf773badbe Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 9 Feb 2018 15:59:29 +0000 Subject: [PATCH 328/355] AtlasTestEnvironment using nonblocking MPI barrier for each CASE --- src/tests/AtlasTestEnvironment.h | 75 +++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 4dc756060..b35064d0a 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -10,17 +10,29 @@ #pragma once +#include +#include +#include + #include "eckit/config/Resource.h" #include "eckit/eckit_version.h" +#include "eckit/eckit_config.h" #include "eckit/mpi/Comm.h" #include "eckit/runtime/Main.h" +#include "eckit/config/Resource.h" +#include "eckit/config/LibEcKit.h" #include "eckit/testing/Test.h" +#include "eckit/log/PrefixTarget.h" #include "atlas/library/Library.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" #include "atlas/util/Config.h" +#include "atlas/runtime/trace/StopWatch.h" +#ifdef ECKIT_HAVE_MPI +#include +#endif namespace atlas { namespace test { @@ -64,6 +76,10 @@ void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection, int& _n void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection, int& _num_subsections, int _subsection) { \ ATLAS_TRACE(description); \ UNIQUE_NAME2(traced_test_, __LINE__)(_test_subsection,_num_subsections,_subsection); \ + if( atlas::test::barrier_timeout( atlas::test::ATLAS_MPI_BARRIER_TIMEOUT() ) ) { \ + atlas::Log::warning() << "\nWARNING: Test \""<< description << "\" failed with MPI deadlock. (${ATLAS_MPI_BARRIER_TIMEOUT}="<("${ATLAS_MPI_BARRIER_TIMEOUT",3.); + return v; +} + + +static int barrier_timeout( double seconds ) { +#ifdef ECKIT_HAVE_MPI + if( eckit::mpi::comm().size() > 1 ) { + MPI_Request req; + MPI_Ibarrier( MPI_COMM_WORLD, &req ); + + int barrier_succesful = 0; + runtime::trace::StopWatch watch; watch.start(); + while( not barrier_succesful ) { + watch.stop(); + if( watch.elapsed() > seconds ) { + return 1; + } + watch.start(); + std::this_thread::sleep_for( std::chrono::milliseconds(100) ); + MPI_Test( &req, &barrier_succesful, MPI_STATUS_IGNORE ); + } + } +#endif + return 0; +} + + struct AtlasTestEnvironment { using Config = util::Config; @@ -92,11 +137,21 @@ struct AtlasTestEnvironment { eckit::Main::initialise(argc, argv); eckit::Main::instance().taskID( eckit::mpi::comm("world").rank() ); if( eckit::mpi::comm("world").size() != 1 ) { - long logtask = eckit::Resource("--logtask;$ATLAS_TEST_LOGTASK", 0); - if( eckit::Main::instance().taskID() != logtask ) Log::reset(); + long logtask = eckit::Resource("$ATLAS_LOG_TASK", 0); + if( eckit::Main::instance().taskID() != logtask ) { + eckit::Log::info().reset(); + eckit::Log::warning().reset(); + eckit::Log::debug().reset(); + } + eckit::Log::error().setTarget( + new eckit::PrefixTarget( "["+std::to_string(eckit::mpi::comm().rank())+"]" ) ); } - bool report = eckit::Resource("--report;$ATLAS_TRACE_REPORT", false); - Library::instance().initialise( Config("trace", Config("report",report) ) ); + eckit::LibEcKit::instance().setAbortHandler( []{ + Log::error() << "Calling MPI_Abort" << std::endl; + eckit::mpi::comm().abort(); + }); + Library::instance().initialise(); + eckit::mpi::comm().barrier(); } ~AtlasTestEnvironment() { @@ -109,7 +164,15 @@ struct AtlasTestEnvironment { template< typename Environment > int run(int argc, char* argv[]) { Environment env( argc, argv ); - return eckit::testing::run_tests(argc,argv,false); + int errors = eckit::testing::run_tests(argc,argv,false); + if( eckit::mpi::comm().size() > 1 ) { + if( barrier_timeout(ATLAS_MPI_BARRIER_TIMEOUT()) ) { + eckit::Log::warning() << "\nWARNING: Tests failed with MPI deadlock (${ATLAS_MPI_BARRIER_TIMEOUT}="< Date: Fri, 9 Feb 2018 17:49:39 +0000 Subject: [PATCH 329/355] ATLAS-148 Fix atlas_test_rgg --- src/tests/mesh/test_rgg.cc | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/tests/mesh/test_rgg.cc b/src/tests/mesh/test_rgg.cc index 260f96bd2..c3fdde1d9 100644 --- a/src/tests/mesh/test_rgg.cc +++ b/src/tests/mesh/test_rgg.cc @@ -376,7 +376,7 @@ CASE( "test_rgg_meshgen_many_parts" ) int triags[] = { 42, 13, 12, 13, 12, 14, 0, 1, 0, 1, 1, 0, 1, 0, 14, 12, 13, 11, 14, 42}; int nb_owned = 0; - std::vector all_owned ( grid.size()+grid.ny()+1, -1 ); + std::vector all_owned ( grid.size(), -1 ); for(size_t p = 0; p < nb_parts; ++p) { @@ -396,6 +396,7 @@ CASE( "test_rgg_meshgen_many_parts" ) Log::info() << "generated grid " << p << std::endl; array::ArrayView part = array::make_view( m.nodes().partition() ); array::ArrayView gidx = array::make_view( m.nodes().global_index() ); + array::ArrayView lonlat = array::make_view( m.nodes().lonlat() ); area += test::compute_lonlat_area(m); ATLAS_DEBUG_HERE(); @@ -441,25 +442,27 @@ DISABLE{ // Test if all nodes are owned for( size_t n=0; n Date: Tue, 13 Feb 2018 14:23:30 +0000 Subject: [PATCH 330/355] ATLAS-148 Element global indices are now human-readable in periodic halo --- src/apps/atlas-meshgen.cc | 2 +- src/atlas/functionspace/NodeColumns.cc | 1 + src/atlas/mesh/Mesh.h | 2 + src/atlas/mesh/actions/BuildHalo.cc | 151 ++++++++++++++++++++--- src/atlas/mesh/actions/BuildHalo.h | 5 +- src/atlas/meshgenerator/MeshGenerator.cc | 7 ++ src/tests/mesh/test_halo.cc | 6 +- 7 files changed, 149 insertions(+), 25 deletions(-) diff --git a/src/apps/atlas-meshgen.cc b/src/apps/atlas-meshgen.cc index 174bf7137..2c155aac6 100644 --- a/src/apps/atlas-meshgen.cc +++ b/src/apps/atlas-meshgen.cc @@ -211,7 +211,7 @@ void Meshgen2Gmsh::execute(const Args& args) } if( grid.projection().units() == "degrees" ) { - // functionspace::NodeColumns nodes_fs(mesh,option::halo(halo)); + functionspace::NodeColumns nodes_fs(mesh,option::halo(halo)); } else { Log::warning() << "Not yet implemented: building halo's with projections not defined in degrees" << std::endl; Log::warning() << "units: " << grid.projection().units() << std::endl; diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 7fa16d785..9ba36b4cd 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -263,6 +263,7 @@ NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration & config ) : void NodeColumns::constructor() { + ASSERT( mesh_ ); mesh::actions::build_nodes_parallel_fields( mesh_.nodes() ); mesh::actions::build_periodic_boundaries(mesh_); diff --git a/src/atlas/mesh/Mesh.h b/src/atlas/mesh/Mesh.h index 99dd18ad6..f9cf12563 100644 --- a/src/atlas/mesh/Mesh.h +++ b/src/atlas/mesh/Mesh.h @@ -121,6 +121,8 @@ class Mesh { const Grid& grid() const { return impl_->grid(); } + operator bool() const { return impl_; } + private: // methods friend std::ostream& operator<<(std::ostream& s, const Mesh& p) { diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index b8e395e66..ead42ed70 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -61,16 +61,16 @@ namespace atlas { namespace mesh { namespace actions { -struct Node +struct Entity { - Node(gidx_t gid, int idx) + Entity(gidx_t gid, int idx) { g = gid; i = idx; } gidx_t g; gidx_t i; - bool operator < (const Node& other) const + bool operator < (const Entity& other) const { return ( g glb_idx(points_to_edit.size()); @@ -158,9 +158,9 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui // 2) Sort all global indices, and renumber from 1 to glb_nb_edges - std::vector node_sort; node_sort.reserve(glb_nb_nodes); + std::vector node_sort; node_sort.reserve(glb_nb_nodes); for( size_t jnode=0; jnode cells_glb_idx = array::make_view ( cells.global_index() ); +// ATLAS_DEBUG( "min = " << cells.global_index().metadata().getLong("min") ); +// ATLAS_DEBUG( "max = " << cells.global_index().metadata().getLong("max") ); +// ATLAS_DEBUG( "human_readable = " << cells.global_index().metadata().getBool("human_readable") ); + gidx_t glb_idx_max = 0; + + std::vector cells_to_edit; + + if( do_all ) { + cells_to_edit.resize(cells_glb_idx.size()); + for( size_t i=0; i glb_idx(cells_to_edit.size()); + int nb_cells = glb_idx.size(); + for( size_t i=0; i recvcounts(parallel::mpi::comm().size()); + std::vector recvdispls(parallel::mpi::comm().size()); + ATLAS_TRACE_MPI( GATHER ) { + parallel::mpi::comm().gather(nb_cells, recvcounts, root); + } + int glb_nb_cells = std::accumulate(recvcounts.begin(),recvcounts.end(),0); + recvdispls[0]=0; + for (int jpart=1; jpart glb_idx_gathered( glb_nb_cells ); + ATLAS_TRACE_MPI( GATHER ) { + parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), + glb_idx_gathered.data(), + recvcounts.data(), recvdispls.data(), root); + } + + + // 2) Sort all global indices, and renumber from 1 to glb_nb_edges + std::vector cell_sort; cell_sort.reserve(glb_nb_cells); + for( size_t jnode=0; jnode 0 && cell_sort[jcell].g != cell_sort[jcell-1].g ) { + ++gid; + } + int icell = cell_sort[jcell].i; + glb_idx_gathered[icell] = gid; + } + + // 3) Scatter renumbered back + ATLAS_TRACE_MPI( SCATTER ) { + parallel::mpi::comm().scatterv(glb_idx_gathered.data(), + recvcounts.data(), recvdispls.data(), + glb_idx.data(), glb_idx.size(), root); + } + + for( int jcell=0; jcell new_periodic_ghost_points; + std::vector new_periodic_ghost_points; + std::vector< std::vector > new_periodic_ghost_cells; } status; public: @@ -753,7 +843,7 @@ class BuildHaloHelper } - void add_nodes(Buffers& buf, bool periodic ) + void add_nodes( Buffers& buf, bool periodic ) { ATLAS_TRACE(); @@ -860,7 +950,7 @@ class BuildHaloHelper } } - void add_elements(Buffers& buf) + void add_elements( Buffers& buf, bool periodic ) { ATLAS_TRACE(); @@ -890,6 +980,10 @@ class BuildHaloHelper } }; + if( not status.new_periodic_ghost_cells.size() ) + status.new_periodic_ghost_cells.resize(mesh.cells().nb_types()); + + std::vector< std::vector > received_new_elems( mpi_size ); for(size_t jpart = 0; jpart < mpi_size; ++jpart) { @@ -931,6 +1025,8 @@ class BuildHaloHelper // Add new elements BlockConnectivity &node_connectivity = elements.node_connectivity(); if( nb_elements_of_type[t] == 0 ) continue; + + size_t old_size = elements.size(); size_t new_elems_pos = elements.add(nb_elements_of_type[t]); auto elem_type_glb_idx = elements.view( mesh.cells().global_index() ); @@ -945,22 +1041,28 @@ class BuildHaloHelper for(size_t e = 0; e < elems[jpart].size(); ++e) { size_t jelem = elems[jpart][e]; - elem_type_glb_idx(new_elems_pos+new_elem) = std::abs(buf.elem_glb_idx[jpart][jelem]); - elem_type_part (new_elems_pos+new_elem) = buf.elem_part[jpart][jelem]; - elem_type_halo (new_elems_pos+new_elem) = halo+1; - elem_type_patch (new_elems_pos+new_elem) = 0; + int loc_idx = new_elems_pos+new_elem; + elem_type_glb_idx(loc_idx) = std::abs(buf.elem_glb_idx[jpart][jelem]); + elem_type_part (loc_idx) = buf.elem_part[jpart][jelem]; + elem_type_halo (loc_idx) = halo+1; + elem_type_patch (loc_idx) = 0; for( size_t n=0; n +#include +#include "atlas/library/config.h" namespace atlas { class Mesh; @@ -26,7 +28,8 @@ class BuildHalo { BuildHalo( Mesh& mesh ) : mesh_(mesh) {} void operator()(int nb_elems); public: - std::vector periodic_local_index_; + std::vector periodic_points_local_index_; + std::vector periodic_cells_local_index_; private: Mesh& mesh_; diff --git a/src/atlas/meshgenerator/MeshGenerator.cc b/src/atlas/meshgenerator/MeshGenerator.cc index 11b98de4c..7da6ad410 100644 --- a/src/atlas/meshgenerator/MeshGenerator.cc +++ b/src/atlas/meshgenerator/MeshGenerator.cc @@ -10,6 +10,7 @@ #include #include +#include #include "eckit/thread/AutoLock.h" #include "eckit/thread/Mutex.h" @@ -121,6 +122,12 @@ void MeshGeneratorImpl::generateGlobalElementNumbering( Mesh& mesh ) const { glb_idx(jelem) = gid++; } + + size_t max_glb_idx = std::accumulate(elem_counts.begin(),elem_counts.end(),size_t(0)); + + mesh.cells().global_index().metadata().set("human_readable",true); + mesh.cells().global_index().metadata().set("min",1); + mesh.cells().global_index().metadata().set("max",max_glb_idx); } diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index f9bcf856a..fb1ddfb59 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -108,7 +108,7 @@ CASE( "test_small" ) #endif #if 1 -CASE( "test_t63" ) +CASE( "test_custom" ) { // Mesh m = test::generate_mesh( T63() ); @@ -119,10 +119,10 @@ CASE( "test_t63" ) mesh::actions::build_halo(m,1); //mesh::actions::build_edges(m); //mesh::actions::build_pole_edges(m); - //mesh::actions::build_edges_parallel_fields(m.function_space("edges"),m-.nodes()); + //mesh::actions::build_edges_parallel_fields(m.function_space("edges"),m.nodes()); //mesh::actions::build_centroid_dual_mesh(m); - std::stringstream filename; filename << "T63_halo.msh"; + std::stringstream filename; filename << "custom.msh"; Gmsh(filename.str(),util::Config("ghost",true)).write(m); // EXPECT( eckit::types::is_approximately_equal( test::dual_volume(m), 2.*M_PI*M_PI, 1e-6 )); From b409d2e7793762e5f96abb152cc33316d1038d56 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 13 Feb 2018 14:30:30 +0000 Subject: [PATCH 331/355] ATLAS-148 Update atlas_test_halo --- src/tests/mesh/test_halo.cc | 126 +++++++++++++++++------------------- 1 file changed, 60 insertions(+), 66 deletions(-) diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index fb1ddfb59..0656d9201 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -170,7 +170,6 @@ CASE( "test_custom" ) 681187136332936887, 681187136358651173, 681187136384365458, - 681187136410079744, 717939789677242368, 717939789699742368, 717939789722242368, @@ -190,12 +189,12 @@ CASE( "test_custom" ) 717939789879742368, 717939789902242368, 754708008423385696, + 681187136410079744, 717939789924742368, 717939789947242368, 717939789969742368, 717939789992242368, 717939790014742368, - 717939790037242368, 607990293310953217, 644481443565331585, 681187136024365459, @@ -203,8 +202,7 @@ CASE( "test_custom" ) 754708008243385697, 607990293742953216, 644481443985331584, - 681187136435794030, - 717939790059742368 + 681187136435794030 }; break; case 1: @@ -240,6 +238,12 @@ CASE( "test_custom" ) 754708008400885696, 791480219139130656, 828248437727773984, + 865001091371008037, + 901706783697184768, + 901706783727184768, + 901706783757184768, + 901706783787184768, + 901706783817184768, 681187136050079744, 681187136075794030, 681187136101508315, @@ -252,17 +256,19 @@ CASE( "test_custom" ) 791480219161630656, 791480219184130656, 828248437750273984, - 865001091371008037, - 901706783697184768, - 901706783727184768, - 901706783757184768, - 901706783787184768, - 901706783817184768, + 865001091396722322, + 901706783847184768, + 938197933945563136, + 938197933981563136, + 938197934017563136, + 938197934053563136, + 938197934089563136, 717939789654742369, 754708008243385697, 791480219004130657, 828248437592773985, - 865001091216722323 + 865001091216722323, + 901706783667184769 }; break; case 2: @@ -298,11 +304,14 @@ CASE( "test_custom" ) 717939789924742368, 754708008378385696, 754708008513385696, - 791480219116630656, 791480219251630656, - 828248437705273984, 828248437840273984, 865001091345293751, + 865001091473865179, + 901706783817184768, + 901706783847184768, + 901706783877184768, + 901706783907184768, 644481443745331584, 644481443775331584, 644481443805331584, @@ -311,22 +320,22 @@ CASE( "test_custom" ) 681187136307222601, 717939789789742368, 717939789767242368, - 754708008333385696, 754708008355885696, - 791480219094130656, - 828248437682773984, + 791480219116630656, + 828248437705273984, 865001091319579465, + 901706783787184768, 717939789947242368, 754708008535885696, 791480219274130656, 791480219296630656, 828248437862773984, - 865001091473865179, - 901706783787184768, - 901706783817184768, - 901706783847184768, - 901706783877184768, - 901706783907184768 + 865001091499579465, + 901706783937184768, + 938197934053563136, + 938197934089563136, + 938197934125563136, + 938197934161563136 }; break; case 3: @@ -358,40 +367,45 @@ CASE( "test_custom" ) 828248437907773984, 828248437930273984, 828248437952773984, + 644481443955331584, 681187136410079744, 717939789902242368, 717939790037242368, 754708008490885696, 754708008625885696, - 791480219229130656, 791480219386630656, - 828248437817773984, 828248437975273984, + 865001091473865179, + 865001091499579465, + 865001091525293751, + 865001091551008037, + 865001091576722322, + 865001091602436608, + 607990293706953216, 644481443805331584, 644481443835331584, 644481443865331584, 644481443895331584, 644481443925331584, - 644481443955331584, 681187136255794030, 717939789879742368, - 754708008445885696, 754708008468385696, - 791480219206630656, - 828248437795273984, - 865001091422436608, + 791480219229130656, + 828248437817773984, 865001091448150894, - 865001091473865179, - 865001091499579465, - 865001091525293751, - 865001091551008037, - 865001091576722322, - 865001091602436608, + 901706783907184768, + 901706783937184768, + 901706783967184768, + 901706783997184768, + 901706784027184768, + 901706784057184768, + 644481443985331584, 681187136435794030, 717939790059742368, 754708008648385696, 791480219409130656, - 828248437997773984 + 828248437997773984, + 865001091628150894 }; break; case 4: @@ -423,48 +437,28 @@ CASE( "test_custom" ) 938197934197563136, 938197934233563136, 938197934269563136, - 828248437840273984, - 828248437862773984, - 828248437885273984, - 828248437907773984, - 828248437930273984, - 828248437952773984, - 828248437975273984, + 865001091602436608, + 901706784057184768, + 938197934305563136, 865001091242436608, 865001091268150894, 865001091293865179, 865001091319579465, 865001091345293751, 865001091371008037, + 828248437840273984, 865001091396722322, 865001091422436608, 865001091448150894, - 865001091602436608, - 901706784057184768, - 938197934305563136, - 828248437615273984, - 828248437637773984, - 828248437660273984, - 828248437682773984, - 828248437705273984, - 828248437727773984, - 828248437750273984, - 828248437772773984, - 828248437795273984, - 828248437817773984, - 791480219229130656, - 791480219251630656, - 791480219274130656, - 791480219296630656, - 791480219319130656, - 791480219341630656, - 791480219364130656, - 791480219386630656, - 828248437592773985, + 828248437862773984, + 828248437885273984, + 828248437907773984, + 828248437930273984, + 828248437952773984, + 828248437975273984, 865001091216722323, 901706783667184769, 938197933909563137, - 791480219409130656, 828248437997773984, 865001091628150894, 901706784087184768, From a0413ecbab6e8fe965c2950db4cf34826c11b8a1 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 13 Feb 2018 14:39:44 +0000 Subject: [PATCH 332/355] ATLAS-148 Update atlas_test_parfields --- src/tests/mesh/test_parfields.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tests/mesh/test_parfields.cc b/src/tests/mesh/test_parfields.cc index a8955593e..cc1c50fc0 100644 --- a/src/tests/mesh/test_parfields.cc +++ b/src/tests/mesh/test_parfields.cc @@ -185,8 +185,9 @@ CASE( "test2" ) if( is_ghost(jnode) ) ++nb_ghost; } - if( parallel::mpi::comm().rank() == 0 ) EXPECT( nb_ghost == 129 ); - if( parallel::mpi::comm().rank() == 1 ) EXPECT( nb_ghost == 0 ); + ATLAS_DEBUG_VAR( nb_ghost ); + if( parallel::mpi::comm().rank() == 0 ) EXPECT( nb_ghost == 128 ); // South boundary of Northern hemisphere + if( parallel::mpi::comm().rank() == 1 ) EXPECT( nb_ghost == 0 ); // Southern hemisphere has no ghosts mesh::actions::build_periodic_boundaries(m); @@ -196,10 +197,12 @@ CASE( "test2" ) if( is_ghost(jnode) ) ++nb_periodic; } - if( parallel::mpi::comm().rank() == 0 ) EXPECT( nb_periodic == 32 ); - if( parallel::mpi::comm().rank() == 1 ) EXPECT( nb_periodic == 32 ); + ATLAS_DEBUG_VAR( nb_periodic ); - Gmsh("periodic.msh").write(m); + if( parallel::mpi::comm().rank() == 0 ) EXPECT( nb_periodic == 33 ); // Periodic East boundary of Northern hemisphere (plus one point south) + if( parallel::mpi::comm().rank() == 1 ) EXPECT( nb_periodic == 32 ); // Periodic East boundary of Southern hemisphere + + Gmsh("periodic.msh",util::Config("info",true)).write(m); } //----------------------------------------------------------------------------- From 7282b2cccb95364619697b7c2d94c3090292e336 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 13 Feb 2018 16:00:29 +0000 Subject: [PATCH 333/355] Simplify namespace atlas::parallel::mpi to atlas::mpi --- src/apps/atlas-benchmark.cc | 12 +-- src/apps/atlas-loadbalance.cc | 2 +- src/apps/atlas-meshgen.cc | 2 +- src/atlas/functionspace/EdgeColumns.cc | 2 +- src/atlas/functionspace/NodeColumns.cc | 42 +++++----- src/atlas/functionspace/Spectral.cc | 8 +- src/atlas/functionspace/StructuredColumns.cc | 10 +-- src/atlas/grid/Partitioner.cc | 2 +- .../partitioner/EqualRegionsPartitioner.cc | 2 +- .../MatchingMeshPartitionerLonLatPolygon.cc | 2 +- ...MatchingMeshPartitionerSphericalPolygon.cc | 2 +- .../grid/detail/partitioner/Partitioner.cc | 2 +- src/atlas/library/Library.cc | 8 +- src/atlas/mesh/Nodes.cc | 4 +- src/atlas/mesh/PartitionPolygon.cc | 2 +- src/atlas/mesh/actions/BuildDualMesh.cc | 6 +- src/atlas/mesh/actions/BuildEdges.cc | 4 +- src/atlas/mesh/actions/BuildHalo.cc | 62 +++++++------- src/atlas/mesh/actions/BuildParallelFields.cc | 74 ++++++++--------- src/atlas/mesh/actions/BuildParallelFields.h | 2 +- .../mesh/actions/BuildPeriodicBoundaries.cc | 50 +++++------ src/atlas/mesh/actions/BuildStatistics.cc | 16 ++-- .../mesh/actions/WriteLoadBalanceReport.cc | 20 ++--- src/atlas/mesh/detail/MeshImpl.cc | 4 +- src/atlas/mesh/detail/PartitionGraph.cc | 2 +- src/atlas/meshgenerator/MeshGenerator.cc | 10 +-- .../meshgenerator/RegularMeshGenerator.cc | 6 +- .../meshgenerator/StructuredMeshGenerator.cc | 6 +- src/atlas/output/Gmsh.cc | 6 +- src/atlas/output/Gmsh.h | 4 +- src/atlas/output/detail/GmshIO.cc | 26 +++--- src/atlas/parallel/Checksum.h | 4 +- src/atlas/parallel/GatherScatter.cc | 14 ++-- src/atlas/parallel/GatherScatter.h | 4 +- src/atlas/parallel/HaloExchange.cc | 14 ++-- src/atlas/parallel/HaloExchange.h | 8 +- src/atlas/parallel/mpi/Buffer.h | 8 +- src/atlas/parallel/mpi/Statistics.h | 12 ++- src/atlas/parallel/mpi/mpi.cc | 2 - src/atlas/parallel/mpi/mpi.h | 2 - src/atlas/runtime/AtlasTool.cc | 10 +-- src/atlas/runtime/ErrorHandling.cc | 4 +- src/atlas/runtime/Log.cc | 4 +- src/atlas/runtime/trace/Barriers.cc | 10 +-- src/atlas/runtime/trace/Timings.cc | 6 +- src/atlas/trans/ifs/TransIFS.cc | 14 ++-- src/atlas/util/Metadata.cc | 18 ++-- src/atlas/util/detail/Debug.h | 4 +- .../atlas-benchmark-build-halo.cc | 2 +- .../atlas-benchmark-sorting.cc | 16 ++-- .../atlas-grid-distribution.cc | 4 +- src/tests/functionspace/test_functionspace.cc | 32 ++++---- .../functionspace/test_structuredcolumns.cc | 8 +- src/tests/mesh/test_distmesh.cc | 2 +- src/tests/mesh/test_halo.cc | 14 ++-- src/tests/mesh/test_parfields.cc | 24 +++--- src/tests/numerics/test_fvm_nabla.cc | 2 +- src/tests/parallel/test_gather.cc | 82 +++++++++---------- src/tests/parallel/test_haloexchange.cc | 70 ++++++++-------- src/tests/trans/test_trans.cc | 34 ++++---- src/tests/trans/test_trans_invtrans_grad.cc | 4 +- src/tests/trans/test_transgeneral.cc | 2 +- src/tests/util/test_metadata.cc | 6 +- 63 files changed, 414 insertions(+), 426 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 349f42c3a..e39104d28 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -227,7 +227,7 @@ void AtlasBenchmark::execute(const Args& args) Log::info() << " nlev: " << nlev << endl; Log::info() << " niter: " << niter << endl; Log::info() << endl; - Log::info() << " MPI tasks: "< 1 || edges ) + if( mpi::comm().size() > 1 || edges ) meshgenerator_config.set("3d",false); MeshGenerator meshgenerator(Implementationype,meshgenerator_config); diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 83e958852..81558c9af 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -218,7 +218,7 @@ size_t EdgeColumns::config_size(const eckit::Configuration& config) const size_t owner(0); config.get("owner",owner); size_t _nb_edges_global( nb_edges_global() ); - size = (parallel::mpi::comm().rank() == owner ? _nb_edges_global : 0); + size = (mpi::comm().rank() == owner ? _nb_edges_global : 0); } } return size; diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 9ba36b4cd..1b25d330a 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -337,7 +337,7 @@ size_t NodeColumns::config_nb_nodes(const eckit::Configuration& config) const size_t owner(0); config.get("owner",owner); size_t _nb_nodes_global = nb_nodes_global(); - size = (parallel::mpi::comm().rank() == owner ? _nb_nodes_global : 0); + size = (mpi::comm().rank() == owner ? _nb_nodes_global : 0); } } return size; @@ -694,7 +694,7 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, size_t& } } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); + mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); } N = fs.nb_nodes_global() * arr.shape(1); @@ -773,7 +773,7 @@ void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& re } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); + mpi::comm().allReduce(local_sum, result, eckit::mpi::sum()); } N = fs.nb_nodes_global() * arr.shape(1); @@ -873,7 +873,7 @@ void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& s } } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduceInPlace(sum_per_level.data(), sum.size(), eckit::mpi::sum()); + mpi::comm().allReduceInPlace(sum_per_level.data(), sum.size(), eckit::mpi::sum()); } N = fs.nb_nodes_global(); } @@ -910,7 +910,7 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs , const Field& fie result += glb(jnode); } ATLAS_TRACE_MPI( BROADCAST ) { - parallel::mpi::comm().broadcast(&result, 1, root); + mpi::comm().broadcast(&result, 1, root); } N = fs.nb_nodes_global(); } @@ -987,7 +987,7 @@ void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& fiel for( size_t j=0; j( global ); for( size_t n=0; n("owner"); ATLAS_TRACE_MPI( BROADCAST ) { - parallel::mpi::comm().broadcast(result,root); + mpi::comm().broadcast(result,root); } N = fs.nb_nodes_global(); } @@ -1096,7 +1096,7 @@ void dispatch_order_independent_sum_per_level( const NodeColumns& fs, const Fiel Field global = fs.createField( field , option::name("global")|option::global()); fs.gather(field,global); - if( parallel::mpi::comm().rank() == 0 ) { + if( mpi::comm().rank() == 0 ) { const array::LocalView glb = make_leveled_view(global); for( size_t n=0; n sum_array(sumfield.size()); - if( parallel::mpi::comm().rank() == root ) { + if( mpi::comm().rank() == root ) { size_t c(0); for( size_t l=0; l } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduce(local_minimum, min, eckit::mpi::min()); + mpi::comm().allReduce(local_minimum, min, eckit::mpi::min()); } } @@ -1245,7 +1245,7 @@ void dispatch_maximum( const NodeColumns& fs, const Field& field, std::vector } } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduce(local_maximum, max, eckit::mpi::max()); + mpi::comm().allReduce(local_maximum, max, eckit::mpi::max()); } } @@ -1349,7 +1349,7 @@ void dispatch_minimum_per_level( const NodeColumns& fs, const Field& field, Fiel } } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduceInPlace(min.data(),min_field.size(),eckit::mpi::min()); + mpi::comm().allReduceInPlace(min.data(),min_field.size(),eckit::mpi::min()); } } @@ -1418,7 +1418,7 @@ void dispatch_maximum_per_level( const NodeColumns& fs, const Field& field, Fiel } } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduceInPlace(max.data(),max_field.size(),eckit::mpi::max()); + mpi::comm().allReduceInPlace(max.data(),max_field.size(),eckit::mpi::max()); } } @@ -1496,8 +1496,8 @@ void dispatch_minimum_and_location( const NodeColumns& fs, const Field& field, s } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduce(min_and_gidx_loc, min_and_gidx_glb, eckit::mpi::minloc()); - parallel::mpi::comm().allReduce(min_and_level_loc,min_and_level_glb,eckit::mpi::minloc()); + mpi::comm().allReduce(min_and_gidx_loc, min_and_gidx_glb, eckit::mpi::minloc()); + mpi::comm().allReduce(min_and_level_loc,min_and_level_glb,eckit::mpi::minloc()); } for( size_t j=0; j1)); + TRANS_CHECK(::trans_use_mpi(mpi::comm().size()>1)); TRANS_CHECK(::trans_setup(trans_.get())); } @@ -109,7 +109,7 @@ size_t Spectral::config_size(const eckit::Configuration& config) const { size_t owner(0); config.get("owner",owner); - size = (parallel::mpi::comm().rank() == owner ? nb_spectral_coefficients_global() : 0); + size = (mpi::comm().rank() == owner ? nb_spectral_coefficients_global() : 0); } } return size; @@ -234,7 +234,7 @@ void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset size_t root=0; glb.metadata().get("owner",root); ASSERT( loc.shape(0) == nb_spectral_coefficients() ); - if( parallel::mpi::comm().rank() == root ) + if( mpi::comm().rank() == root ) ASSERT( glb.shape(0) == nb_spectral_coefficients_global() ); std::vector nto(1,root+1); if( loc.rank() > 1 ) { @@ -283,7 +283,7 @@ void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldse size_t root=0; glb.metadata().get("owner",root); ASSERT( loc.shape(0) == nb_spectral_coefficients() ); - if( parallel::mpi::comm().rank() == root ) + if( mpi::comm().rank() == root ) ASSERT( glb.shape(0) == nb_spectral_coefficients_global() ); std::vector nfrom(1,root+1); if( loc.rank() > 1 ) { diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index dfe6f5c17..f5c3422ff 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -224,7 +224,7 @@ size_t StructuredColumns::config_size(const eckit::Configuration& config) const { size_t owner(0); config.get("owner",owner); - size = (parallel::mpi::comm().rank() == owner ? grid_.size() : 0); + size = (mpi::comm().rank() == owner ? grid_.size() : 0); } } return size; @@ -251,7 +251,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& { throw eckit::BadCast("Grid is not a grid::Structured type", Here()); } - const eckit::mpi::Comm& comm = parallel::mpi::comm(); + const eckit::mpi::Comm& comm = mpi::comm(); grid::Partitioner partitioner( p ); @@ -272,7 +272,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& } distribution_ = distribution.type(); - int mpi_rank = parallel::mpi::comm().rank(); + int mpi_rank = mpi::comm().rank(); j_begin_ = std::numeric_limits::max(); j_end_ = std::numeric_limits::min(); @@ -480,7 +480,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& auto build_partition_graph = [this]() -> std::unique_ptr { - const eckit::mpi::Comm& comm = parallel::mpi::comm(); + const eckit::mpi::Comm& comm = mpi::comm(); const int mpi_size = int(comm.size()); const int mpi_rank = int(comm.rank()); @@ -514,7 +514,7 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& auto p = array::make_view< int, 1 >( partition() ); auto g = array::make_view< gidx_t, 1 >( global_index() ); - const eckit::mpi::Comm& comm = parallel::mpi::comm(); + const eckit::mpi::Comm& comm = mpi::comm(); const int mpi_size = int(comm.size()); const int mpi_rank = int(comm.rank()); diff --git a/src/atlas/grid/Partitioner.cc b/src/atlas/grid/Partitioner.cc index c999e911e..7ebfaf2e0 100644 --- a/src/atlas/grid/Partitioner.cc +++ b/src/atlas/grid/Partitioner.cc @@ -37,7 +37,7 @@ Partitioner::Partitioner( const std::string& type, const size_t nb_partitions): namespace { detail::partitioner::Partitioner* partitioner_from_config( const Partitioner::Config& config ) { std::string type; - long partitions = parallel::mpi::comm().size(); + long partitions = mpi::comm().size(); if( not config.get("type",type) ) throw eckit::BadParameter("'type' missing in configuration for Partitioner",Here()); config.get("partitions",partitions); diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index e0622bcb0..b91ff4397 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -511,7 +511,7 @@ void EqualRegionsPartitioner::partition( const Grid& grid, int part[] ) const { ASSERT( grid.projection().units() == "degrees" ); - const auto& comm = parallel::mpi::comm(); + const auto& comm = mpi::comm(); int mpi_rank = comm.rank(); int mpi_size = comm.size(); diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc index 605fc417d..e4759383f 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc @@ -32,7 +32,7 @@ PartitionerBuilder __builder("lonlat-polyg void MatchingMeshPartitionerLonLatPolygon::partition( const Grid& grid, int partitioning[] ) const { - const eckit::mpi::Comm& comm = atlas::parallel::mpi::comm(); + const eckit::mpi::Comm& comm = atlas::mpi::comm(); const int mpi_rank = int(comm.rank()); const int mpi_size = int(comm.size()); diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc index 395ed552b..6a26e3123 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc @@ -31,7 +31,7 @@ PartitionerBuilder __builder("spherical void MatchingMeshPartitionerSphericalPolygon::partition( const Grid& grid, int partitioning[] ) const { - const eckit::mpi::Comm& comm = atlas::parallel::mpi::comm(); + const eckit::mpi::Comm& comm = atlas::mpi::comm(); const int mpi_rank = int(comm.rank()); const int mpi_size = int(comm.size()); diff --git a/src/atlas/grid/detail/partitioner/Partitioner.cc b/src/atlas/grid/detail/partitioner/Partitioner.cc index 389de5a48..5b0f9bfb8 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.cc +++ b/src/atlas/grid/detail/partitioner/Partitioner.cc @@ -49,7 +49,7 @@ namespace grid { namespace detail { namespace partitioner { -Partitioner::Partitioner(): nb_partitions_(parallel::mpi::comm().size()) { +Partitioner::Partitioner(): nb_partitions_(mpi::comm().size()) { } Partitioner::Partitioner(const size_t nb_partitions): nb_partitions_(nb_partitions) { diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 3b18ecaf3..b7991d25b 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -139,16 +139,16 @@ void Library::initialise(const eckit::Parametrisation& config) { if( not info_ ) info_channel_ .reset(); // Summary - if( getEnv( "ATLAS_LOG_RANK", 0 ) == parallel::mpi::comm().rank() ) { + if( getEnv( "ATLAS_LOG_RANK", 0 ) == mpi::comm().rank() ) { std::ostream& out = Log::debug(); out << "Executable [" << Main::instance().name() << "]\n"; out << " \n"; out << " current dir [" << PathName(LocalPathName::cwd()).fullName() << "]\n"; out << " \n"; out << " MPI\n"; - out << " communicator [" << parallel::mpi::comm() << "] \n"; - out << " size [" << parallel::mpi::comm().size() << "] \n"; - out << " rank [" << parallel::mpi::comm().rank() << "] \n"; + out << " communicator [" << mpi::comm() << "] \n"; + out << " size [" << mpi::comm().size() << "] \n"; + out << " rank [" << mpi::comm().rank() << "] \n"; out << " \n"; out << " log.info [" << str(info_) << "] \n"; out << " log.trace [" << str(trace()) << "] \n"; diff --git a/src/atlas/mesh/Nodes.cc b/src/atlas/mesh/Nodes.cc index a961af91d..eb0792e1a 100644 --- a/src/atlas/mesh/Nodes.cc +++ b/src/atlas/mesh/Nodes.cc @@ -48,7 +48,7 @@ Nodes::Nodes(): size_(0) for(size_t n=0; n part = array::make_view( partition() ); array::ArrayView flags = array::make_view( field("flags") ); - const int mpi_rank = parallel::mpi::comm().rank(); + const int mpi_rank = mpi::comm().rank(); for(size_t n=previous_size; n& pole_edge_no } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); - parallel::mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); + mpi::comm().allReduceInPlace(min, 2, eckit::mpi::min()); + mpi::comm().allReduceInPlace(max, 2, eckit::mpi::max()); } double tol = 1e-6; diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index ead42ed70..b2c405688 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -84,8 +84,8 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui // and could receive different gidx for different tasks - // unused // int mypart = parallel::mpi::comm().rank(); - int nparts = parallel::mpi::comm().size(); + // unused // int mypart = mpi::comm().rank(); + int nparts = mpi::comm().size(); size_t root = 0; array::ArrayView nodes_glb_idx = array::make_view ( nodes.global_index() ); @@ -136,11 +136,11 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui // 1) Gather all global indices, together with location - std::vector recvcounts(parallel::mpi::comm().size()); - std::vector recvdispls(parallel::mpi::comm().size()); + std::vector recvcounts(mpi::comm().size()); + std::vector recvdispls(mpi::comm().size()); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + mpi::comm().gather(nb_nodes, recvcounts, root); } int glb_nb_nodes = std::accumulate(recvcounts.begin(),recvcounts.end(),0); @@ -151,7 +151,7 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui std::vector glb_idx_gathered( glb_nb_nodes ); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), + mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); } @@ -179,7 +179,7 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui // 3) Scatter renumbered back ATLAS_TRACE_MPI( SCATTER ) { - parallel::mpi::comm().scatterv(glb_idx_gathered.data(), + mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); } @@ -200,7 +200,7 @@ void make_cells_global_index_human_readable( const mesh::actions::BuildHalo& bui { ATLAS_TRACE(); - int nparts = parallel::mpi::comm().size(); + int nparts = mpi::comm().size(); size_t root = 0; array::ArrayView cells_glb_idx = array::make_view ( cells.global_index() ); @@ -229,11 +229,11 @@ void make_cells_global_index_human_readable( const mesh::actions::BuildHalo& bui // 1) Gather all global indices, together with location - std::vector recvcounts(parallel::mpi::comm().size()); - std::vector recvdispls(parallel::mpi::comm().size()); + std::vector recvcounts(mpi::comm().size()); + std::vector recvdispls(mpi::comm().size()); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gather(nb_cells, recvcounts, root); + mpi::comm().gather(nb_cells, recvcounts, root); } int glb_nb_cells = std::accumulate(recvcounts.begin(),recvcounts.end(),0); @@ -244,7 +244,7 @@ void make_cells_global_index_human_readable( const mesh::actions::BuildHalo& bui std::vector glb_idx_gathered( glb_nb_cells ); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), + mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); } @@ -272,7 +272,7 @@ void make_cells_global_index_human_readable( const mesh::actions::BuildHalo& bui // 3) Scatter renumbered back ATLAS_TRACE_MPI( SCATTER ) { - parallel::mpi::comm().scatterv(glb_idx_gathered.data(), + mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); } @@ -482,7 +482,7 @@ void build_lookup_uid2node( Mesh& mesh, Uid2Node& uid2node ) } void accumulate_elements( const Mesh& mesh, - const parallel::mpi::BufferView& request_node_uid, + const mpi::BufferView& request_node_uid, const Uid2Node& uid2node, const Node2Elem& node2elem, std::vector& found_elements, @@ -493,7 +493,7 @@ void accumulate_elements( const Mesh& mesh, const auto elem_part = array::make_view( mesh.cells().partition() ); size_t nb_nodes = request_node_uid.size(); - const size_t mpi_rank = parallel::mpi::comm().rank(); + const size_t mpi_rank = mpi::comm().rank(); std::set< idx_t > found_elements_set; @@ -573,7 +573,7 @@ class BuildHaloHelper Buffers(Mesh& mesh) { - const size_t mpi_size = parallel::mpi::comm().size(); + const size_t mpi_size = mpi::comm().size(); node_part.resize(mpi_size); node_ridx.resize(mpi_size); @@ -589,7 +589,7 @@ class BuildHaloHelper void print( std::ostream& os ) const { - const size_t mpi_size = parallel::mpi::comm().size(); + const size_t mpi_size = mpi::comm().size(); os << "Nodes\n" << "-----\n"; size_t n(0); @@ -622,7 +622,7 @@ class BuildHaloHelper static void all_to_all(Buffers& send, Buffers& recv) { ATLAS_TRACE(); - const eckit::mpi::Comm& comm = parallel::mpi::comm(); + const eckit::mpi::Comm& comm = mpi::comm(); ATLAS_TRACE_MPI( ALLTOALL ) { comm.allToAll(send.node_glb_idx, recv.node_glb_idx); @@ -734,7 +734,7 @@ class BuildHaloHelper } else { - Log::warning() << "Node with uid " << uid << " needed by ["<(mesh.cells().global_index()); // Elements might be duplicated from different Tasks. We need to identify unique entries int nb_elems = mesh.cells().size(); @@ -1071,8 +1071,8 @@ class BuildHaloHelper namespace { -void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::parallel::mpi::Buffer& recv, bool periodic = false ) { - auto& comm = parallel::mpi::comm(); +void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::mpi::Buffer& recv, bool periodic = false ) { + auto& comm = mpi::comm(); #ifndef ATLAS_103 /* deprecated */ ATLAS_TRACE( "gather_bdry_nodes old way" ); @@ -1177,8 +1177,8 @@ void increase_halo_interior( BuildHaloHelper& helper ) for(size_t jnode = 0; jnode < bdry_nodes.size(); ++jnode) send_bdry_nodes_uid[jnode] = helper.compute_uid(bdry_nodes[jnode]); - size_t mpi_size = parallel::mpi::comm().size(); - atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); + size_t mpi_size = mpi::comm().size(); + atlas::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts ); @@ -1195,7 +1195,7 @@ void increase_halo_interior( BuildHaloHelper& helper ) // 3) Find elements and nodes completing these elements in // other tasks that have my nodes through its UID - parallel::mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; + mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; std::vector found_bdry_elems; std::set< uid_t > found_bdry_nodes_uid; @@ -1283,8 +1283,8 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri send_bdry_nodes_uid[jnode] = util::unique_lonlat(crd); } - size_t mpi_size = parallel::mpi::comm().size(); - atlas::parallel::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); + size_t mpi_size = mpi::comm().size(); + atlas::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts, /* periodic = */ true ); @@ -1294,7 +1294,7 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri #else Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); // add own rank to neighbours to allow periodicity with self (pole caps) - size_t rank = parallel::mpi::comm().rank(); + size_t rank = mpi::comm().rank(); neighbours.insert( std::upper_bound( neighbours.begin(), neighbours.end(), rank ), rank ); for (size_t jpart : neighbours) #endif @@ -1302,7 +1302,7 @@ void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& peri // 3) Find elements and nodes completing these elements in // other tasks that have my nodes through its UID - atlas::parallel::mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; + atlas::mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; std::vector found_bdry_elems; std::set< uid_t > found_bdry_nodes_uid; diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index de6cffa52..b0e6479cc 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -160,8 +160,8 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) UniqueLonLat compute_uid(nodes); - // unused // int mypart = parallel::mpi::comm().rank(); - int nparts = parallel::mpi::comm().size(); + // unused // int mypart = mpi::comm().rank(); + int nparts = mpi::comm().size(); size_t root = 0; array::ArrayView glb_idx = array::make_view ( nodes.global_index() ); @@ -188,11 +188,11 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) loc_id(jnode) = glb_idx(jnode); } - std::vector recvcounts(parallel::mpi::comm().size()); - std::vector recvdispls(parallel::mpi::comm().size()); + std::vector recvcounts(mpi::comm().size()); + std::vector recvdispls(mpi::comm().size()); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + mpi::comm().gather(nb_nodes, recvcounts, root); } recvdispls[0]=0; @@ -205,7 +205,7 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) array::ArrayView glb_id = array::make_view(glb_id_arr); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gatherv(loc_id.data(), loc_id.size(), glb_id.data(), recvcounts.data(), recvdispls.data(), root); + mpi::comm().gatherv(loc_id.data(), loc_id.size(), glb_id.data(), recvcounts.data(), recvdispls.data(), root); } // 2) Sort all global indices, and renumber from 1 to glb_nb_edges @@ -233,7 +233,7 @@ void renumber_nodes_glb_idx( mesh::Nodes& nodes ) // 3) Scatter renumbered back ATLAS_TRACE_MPI( SCATTER ) { - parallel::mpi::comm().scatterv(glb_id.data(), recvcounts.data(), recvdispls.data(), loc_id.data(), loc_id.size(), root); + mpi::comm().scatterv(glb_id.data(), recvcounts.data(), recvdispls.data(), loc_id.data(), loc_id.size(), root); } for( int jnode=0; jnode > send_needed( parallel::mpi::comm().size() ); - std::vector< std::vector > recv_needed( parallel::mpi::comm().size() ); + std::vector< std::vector > send_needed( mpi::comm().size() ); + std::vector< std::vector > recv_needed( mpi::comm().size() ); int sendcnt=0; std::map lookup; for( size_t jnode=0; jnode > send_found( parallel::mpi::comm().size() ); - std::vector< std::vector > recv_found( parallel::mpi::comm().size() ); + std::vector< std::vector > send_found( mpi::comm().size() ); + std::vector< std::vector > recv_found( mpi::comm().size() ); for( size_t jpart=0; jpart edge_part = array::make_view( edges.partition() ); @@ -467,12 +467,12 @@ Field& build_edges_partition( Mesh& mesh ) }; int mpi_size = eckit::mpi::comm().size(); - parallel::mpi::Buffer recv_bdry_edges_from_parts(mpi_size); + mpi::Buffer recv_bdry_edges_from_parts(mpi_size); std::vector< std::vector > send_gidx(mpi_size); std::vector< std::vector > send_part(mpi_size); std::vector< std::vector > recv_gidx(mpi_size); std::vector< std::vector > recv_part(mpi_size); - parallel::mpi::comm().allGatherv(bdry_edges.begin(),bdry_edges.end(),recv_bdry_edges_from_parts); + mpi::comm().allGatherv(bdry_edges.begin(),bdry_edges.end(),recv_bdry_edges_from_parts); for( int p=0; p > send_needed( parallel::mpi::comm().size() ); - std::vector< std::vector > recv_needed( parallel::mpi::comm().size() ); + std::vector< std::vector > send_needed( mpi::comm().size() ); + std::vector< std::vector > recv_needed( mpi::comm().size() ); int sendcnt=0; std::map lookup; @@ -657,11 +657,11 @@ Field& build_edges_remote_idx( Mesh& mesh ) #endif ATLAS_TRACE_MPI( ALLTOALL ) { - parallel::mpi::comm().allToAll(send_needed, recv_needed); + mpi::comm().allToAll(send_needed, recv_needed); } - std::vector< std::vector > send_found( parallel::mpi::comm().size() ); - std::vector< std::vector > recv_found( parallel::mpi::comm().size() ); + std::vector< std::vector > send_found( mpi::comm().size() ); + std::vector< std::vector > recv_found( mpi::comm().size() ); std::map::iterator found; for( size_t jpart=0; jpart recvcounts(parallel::mpi::comm().size()); - std::vector recvdispls(parallel::mpi::comm().size()); + std::vector recvcounts(mpi::comm().size()); + std::vector recvdispls(mpi::comm().size()); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gather(nb_edges, recvcounts, root); + mpi::comm().gather(nb_edges, recvcounts, root); } recvdispls[0]=0; @@ -792,7 +792,7 @@ Field& build_edges_global_idx( Mesh& mesh ) array::ArrayView glb_edge_id = array::make_view(glb_edge_id_arr); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gatherv(loc_edge_id.data(), loc_edge_id.size(), + mpi::comm().gatherv(loc_edge_id.data(), loc_edge_id.size(), glb_edge_id.data(), recvcounts.data(), recvdispls.data(), root); } @@ -822,7 +822,7 @@ Field& build_edges_global_idx( Mesh& mesh ) // 3) Scatter renumbered back ATLAS_TRACE_MPI( SCATTER ) { - parallel::mpi::comm().scatterv(glb_edge_id.data(), recvcounts.data(), recvdispls.data(), + mpi::comm().scatterv(glb_edge_id.data(), recvcounts.data(), recvdispls.data(), loc_edge_id.data(), loc_edge_id.size(), root); } diff --git a/src/atlas/mesh/actions/BuildParallelFields.h b/src/atlas/mesh/actions/BuildParallelFields.h index a4866c99d..9ae757924 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.h +++ b/src/atlas/mesh/actions/BuildParallelFields.h @@ -35,7 +35,7 @@ void build_parallel_fields( Mesh& mesh ); /* * Build parallel fields for the "nodes" function space if they don't exist. * - glb_idx: create unique indices for non-positive values - * - partition: set to parallel::mpi::comm().rank() for negative values + * - partition: set to mpi::comm().rank() for negative values * - remote_idx: rebuild from scratch */ void build_nodes_parallel_fields( mesh::Nodes& nodes ); diff --git a/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc b/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc index 8b1c4abe5..17a461f0b 100644 --- a/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc +++ b/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc @@ -47,7 +47,7 @@ void build_periodic_boundaries( Mesh& mesh ) - int mypart = parallel::mpi::comm().rank(); + int mypart = mpi::comm().rank(); mesh::Nodes& nodes = mesh.nodes(); @@ -95,22 +95,22 @@ void build_periodic_boundaries( Mesh& mesh ) } } - std::vector< std::vector > found_master(parallel::mpi::comm().size()); - std::vector< std::vector > send_slave_idx(parallel::mpi::comm().size()); + std::vector< std::vector > found_master(mpi::comm().size()); + std::vector< std::vector > send_slave_idx(mpi::comm().size()); // Find masters on other tasks to send to me { int sendcnt = slave_nodes.size(); - std::vector< int > recvcounts( parallel::mpi::comm().size() ); + std::vector< int > recvcounts( mpi::comm().size() ); ATLAS_TRACE_MPI( ALLGATHER ) { - parallel::mpi::comm().allGather(sendcnt, recvcounts.begin(), recvcounts.end()); + mpi::comm().allGather(sendcnt, recvcounts.begin(), recvcounts.end()); } - std::vector recvdispls( parallel::mpi::comm().size() ); + std::vector recvdispls( mpi::comm().size() ); recvdispls[0] = 0; int recvcnt = recvcounts[0]; - for( size_t jproc=1; jproc recvbuf(recvcnt); ATLAS_TRACE_MPI( ALLGATHER ) { - parallel::mpi::comm().allGatherv(slave_nodes.begin(), slave_nodes.end(), recvbuf.begin(), recvcounts.data(), recvdispls.data()); + mpi::comm().allGatherv(slave_nodes.begin(), slave_nodes.end(), recvbuf.begin(), recvcounts.data(), recvdispls.data()); } PeriodicTransform transform; - for( size_t jproc=0; jproc > recv_slave_idx( parallel::mpi::comm().size() ); - std::vector< std::vector > send_master_part( parallel::mpi::comm().size() ); - std::vector< std::vector > recv_master_part( parallel::mpi::comm().size() ); - std::vector< std::vector > send_master_ridx( parallel::mpi::comm().size() ); - std::vector< std::vector > recv_master_ridx( parallel::mpi::comm().size() ); + std::vector< std::vector > recv_slave_idx( mpi::comm().size() ); + std::vector< std::vector > send_master_part( mpi::comm().size() ); + std::vector< std::vector > recv_master_part( mpi::comm().size() ); + std::vector< std::vector > send_master_ridx( mpi::comm().size() ); + std::vector< std::vector > recv_master_ridx( mpi::comm().size() ); - // std::vector< std::vector > send_slave_part( parallel::mpi::comm().size() ); - // std::vector< std::vector > recv_slave_part( parallel::mpi::comm().size() ); - // std::vector< std::vector > send_slave_ridx( parallel::mpi::comm().size() ); - // std::vector< std::vector > recv_slave_ridx( parallel::mpi::comm().size() ); + // std::vector< std::vector > send_slave_part( mpi::comm().size() ); + // std::vector< std::vector > recv_slave_part( mpi::comm().size() ); + // std::vector< std::vector > send_slave_ridx( mpi::comm().size() ); + // std::vector< std::vector > recv_slave_ridx( mpi::comm().size() ); { - for( size_t jproc=0; jproc rho = array::make_view( mesh.cells().add( @@ -173,7 +173,7 @@ void build_statistics( Mesh& mesh ) tri_quality(eta(ielem), rho(ielem), p1, p2, p3); - if( parallel::mpi::comm().size() == 1 ) + if( mpi::comm().size() == 1 ) { ofs << std::setw(idt) << rho(ielem) << std::setw(idt) << eta(ielem) @@ -198,7 +198,7 @@ void build_statistics( Mesh& mesh ) quad_quality(eta(ielem), rho(ielem), p1, p2, p3, p4); - if( parallel::mpi::comm().size() == 1 ) + if( mpi::comm().size() == 1 ) { ofs << std::setw(idt) << rho(ielem) << std::setw(idt) << eta(ielem) @@ -208,12 +208,12 @@ void build_statistics( Mesh& mesh ) } } - if( parallel::mpi::comm().size() == 1 ) + if( mpi::comm().size() == 1 ) ofs.close(); } eckit::PathName dual_stats_path("dual_stats.txt"); - if( parallel::mpi::comm().size() == 1 ) + if( mpi::comm().size() == 1 ) { ofs.open( dual_stats_path.localPath(), std::ofstream::out ); ofs << "# STATISTICS dual_area \n"; @@ -235,7 +235,7 @@ void build_statistics( Mesh& mesh ) dual_delta_sph(jnode) = std::sqrt(dual_volumes(jnode)*hx*hy); } - if( parallel::mpi::comm().size() == 1 ) + if( mpi::comm().size() == 1 ) { for( size_t jnode=0; jnode nb_total_nodes(npart,0); @@ -77,9 +77,9 @@ void write_load_balance_report( const Mesh& mesh, std::ostream& ofs ) /// @note this could be improved by packing the 3 integers in a vector, and doing only comm() call ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gather(nb_nodes, nb_total_nodes, root); - parallel::mpi::comm().gather(nowned, nb_owned_nodes, root); - parallel::mpi::comm().gather(nghost, nb_ghost_nodes, root); + mpi::comm().gather(nb_nodes, nb_total_nodes, root); + mpi::comm().gather(nowned, nb_owned_nodes, root); + mpi::comm().gather(nghost, nb_ghost_nodes, root); } for( size_t p=0; p elem_counts( parallel::mpi::comm().size() ); - std::vector elem_displs( parallel::mpi::comm().size() ); + std::vector elem_counts( mpi::comm().size() ); + std::vector elem_displs( mpi::comm().size() ); ATLAS_TRACE_MPI( ALLGATHER ) { - parallel::mpi::comm().allGather(loc_nb_elems, elem_counts.begin(), elem_counts.end()); + mpi::comm().allGather(loc_nb_elems, elem_counts.begin(), elem_counts.end()); } elem_displs.at(0) = 0; - for(size_t jpart = 1; jpart < parallel::mpi::comm().size(); ++jpart) + for(size_t jpart = 1; jpart < mpi::comm().size(); ++jpart) { elem_displs.at(jpart) = elem_displs.at(jpart-1) + elem_counts.at(jpart-1); } - gidx_t gid = 1+elem_displs.at( parallel::mpi::comm().rank() ); + gidx_t gid = 1+elem_displs.at( mpi::comm().rank() ); array::ArrayView glb_idx = array::make_view( mesh.cells().global_index() ); diff --git a/src/atlas/meshgenerator/RegularMeshGenerator.cc b/src/atlas/meshgenerator/RegularMeshGenerator.cc index aa3403b2f..6c1eb983c 100644 --- a/src/atlas/meshgenerator/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/RegularMeshGenerator.cc @@ -77,14 +77,14 @@ void RegularMeshGenerator::configure_defaults() { // This option sets number of parts the mesh will be split in - options.set( "nb_parts", parallel::mpi::comm().size() ); + options.set( "nb_parts", mpi::comm().size() ); // This option sets the part that will be generated - options.set( "part", parallel::mpi::comm().rank() ); + options.set( "part", mpi::comm().rank() ); // This options sets the default partitioner std::string partitioner; - if( grid::Partitioner::exists("trans") && parallel::mpi::comm().size() > 1 ) + if( grid::Partitioner::exists("trans") && mpi::comm().size() > 1 ) partitioner = "trans"; else partitioner = "checkerboard"; diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 6d40493cd..5392bfd2d 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -143,10 +143,10 @@ void StructuredMeshGenerator::configure_defaults() options.set( "3d", false ); // This option sets number of parts the mesh will be split in - options.set( "nb_parts", parallel::mpi::comm().size() ); + options.set( "nb_parts", mpi::comm().size() ); // This option sets the part that will be generated - options.set( "part", parallel::mpi::comm().rank() ); + options.set( "part", mpi::comm().rank() ); // Experimental option. The result is a non-standard Reduced Gaussian Grid, with a ragged Greenwich line options.set("stagger", false ); @@ -176,7 +176,7 @@ void StructuredMeshGenerator::generate(const Grid& grid, Mesh& mesh ) const options.get("partitioner",partitioner_type); if ( rg.ny()%2 == 1 ) partitioner_type = "equal_regions"; // Odd number of latitudes - if ( nb_parts == 1 || parallel::mpi::comm().size() == 1 ) partitioner_type = "equal_regions"; // Only one part --> Trans is slower + 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) ); diff --git a/src/atlas/output/Gmsh.cc b/src/atlas/output/Gmsh.cc index 406273a76..854580344 100644 --- a/src/atlas/output/Gmsh.cc +++ b/src/atlas/output/Gmsh.cc @@ -51,17 +51,17 @@ GmshFileStream::GmshFileStream(const PathName& file_path, const char* mode, int if ( std::string(mode)=="w" ) omode = std::ios_base::out; else if( std::string(mode)=="a" ) omode = std::ios_base::app; - if( part<0 || parallel::mpi::comm().size() == 1 ) + if( part<0 || mpi::comm().size() == 1 ) { std::ofstream::open(file_path.localPath(), omode); } else { - if (parallel::mpi::comm().rank() == 0) + if (mpi::comm().rank() == 0) { PathName par_path(file_path); std::ofstream par_file(par_path.localPath(), std::ios_base::out); - for(size_t p = 0; p < parallel::mpi::comm().size(); ++p) + for(size_t p = 0; p < mpi::comm().size(); ++p) { par_file << "Merge \"" << parallelPathName(file_path,p) << "\";" << std::endl; } diff --git a/src/atlas/output/Gmsh.h b/src/atlas/output/Gmsh.h index 0d325b54d..34f04d048 100644 --- a/src/atlas/output/Gmsh.h +++ b/src/atlas/output/Gmsh.h @@ -29,8 +29,8 @@ namespace output { class GmshFileStream : public std::ofstream { public: - static std::string parallelPathName(const PathName& path,int part = parallel::mpi::comm().rank()); - GmshFileStream(const PathName& file_path, const char* mode, int part = parallel::mpi::comm().rank()); + static std::string parallelPathName(const PathName& path,int part = mpi::comm().rank()); + GmshFileStream(const PathName& file_path, const char* mode, int part = mpi::comm().rank()); }; diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index b2dc6d9cb..01e133a01 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -49,17 +49,17 @@ static double rad2deg = util::Constants::radiansToDegrees(); class GmshFile : public std::ofstream { public: - GmshFile(const PathName& file_path, std::ios_base::openmode mode, int part = atlas::parallel::mpi::comm().rank()) + GmshFile(const PathName& file_path, std::ios_base::openmode mode, int part = atlas::mpi::comm().rank()) { PathName par_path(file_path); - if (atlas::parallel::mpi::comm().size() == 1 || part == -1) { + if (atlas::mpi::comm().size() == 1 || part == -1) { std::ofstream::open(par_path.localPath(), mode); } else { Translator to_str; - if (atlas::parallel::mpi::comm().rank() == 0) { + if (atlas::mpi::comm().rank() == 0) { PathName par_path(file_path); std::ofstream par_file(par_path.localPath(), std::ios_base::out); - for(size_t p = 0; p < atlas::parallel::mpi::comm().size(); ++p) { + for(size_t p = 0; p < atlas::mpi::comm().size(); ++p) { PathName loc_path(file_path); // loc_path = loc_path.baseName(false) + "_p" + to_str(p) + ".msh"; loc_path = loc_path.baseName(false) + ".msh.p" + to_str(p); @@ -243,7 +243,7 @@ void write_field_nodes( { Log::debug() << "writing NodeColumns field " << field.name() << " defined in NodeColumns..." << std::endl; - bool gather( gmsh_options.get("gather") && atlas::parallel::mpi::comm().size() > 1 ); + bool gather( gmsh_options.get("gather") && atlas::mpi::comm().size() > 1 ); bool binary( !gmsh_options.get("ascii") ); size_t nlev = std::max(1,field.levels()); size_t ndata = std::min(function_space.nb_nodes(),field.shape(0)); @@ -266,7 +266,7 @@ void write_field_nodes( for (size_t ilev=0; ilev < lev.size(); ++ilev) { size_t jlev = lev[ilev]; - if( ( gather && atlas::parallel::mpi::comm().rank() == 0 ) || !gather ) + if( ( gather && atlas::mpi::comm().rank() == 0 ) || !gather ) { out << "$NodeData\n"; out << "1\n"; @@ -277,7 +277,7 @@ void write_field_nodes( out << field_step(field) << "\n"; out << field_vars(nvars) << "\n"; out << ndata << "\n"; - out << atlas::parallel::mpi::comm().rank() << "\n"; + out << atlas::mpi::comm().rank() << "\n"; auto data = gather ? make_level_view( field_glb, ndata, jlev ) : make_level_view( field, ndata, jlev ); write_level( out, gidx, data ); out << "$EndNodeData\n"; @@ -298,7 +298,7 @@ void write_field_nodes( { Log::debug() << "writing StructuredColumns field " << field.name() << "..." << std::endl; - bool gather( gmsh_options.get("gather") && atlas::parallel::mpi::comm().size() > 1 ); + bool gather( gmsh_options.get("gather") && atlas::mpi::comm().size() > 1 ); bool binary( !gmsh_options.get("ascii") ); size_t nlev = std::max(1,field.levels()); size_t ndata = std::min(function_space.sizeOwned(),field.shape(0)); @@ -344,7 +344,7 @@ void write_field_nodes( out << field_step(field) << "\n"; out << field_vars(nvars) << "\n"; out << ndata << "\n"; - out << atlas::parallel::mpi::comm().rank() << "\n"; + out << atlas::mpi::comm().rank() << "\n"; auto data = gather ? make_level_view( field_glb, ndata, jlev ) : make_level_view( field, ndata, jlev ); write_level( out, gidx, data ); out << "$EndNodeData\n"; @@ -404,7 +404,7 @@ void write_field_elems(const Metadata& gmsh_options, const FunctionSpace& functi if ( nvars == 1 ) out << nvars << "\n"; else if( nvars <= 3 ) out << 3 << "\n"; out << ndata << "\n"; - out << parallel::mpi::comm().rank() << "\n"; + out << mpi::comm().rank() << "\n"; if( binary ) { @@ -767,7 +767,7 @@ void GmshIO::read(const PathName& file_path, Mesh& mesh ) const void GmshIO::write(const Mesh& mesh, const PathName& file_path) const { - int part = mesh.metadata().has("part") ? mesh.metadata().get("part") : atlas::parallel::mpi::comm().rank(); + int part = mesh.metadata().has("part") ? mesh.metadata().get("part") : atlas::mpi::comm().rank(); bool include_ghost = options.get("ghost") && options.get("elements"); std::string nodes_field = options.get("nodes"); @@ -1053,7 +1053,7 @@ void GmshIO::write_delegate( bool binary( !options.get("ascii") ); if ( binary ) mode |= std::ios_base::binary; bool gather = options.has("gather") ? options.get("gather") : false; - GmshFile file(file_path,mode,gather?-1:atlas::parallel::mpi::comm().rank()); + GmshFile file(file_path,mode,gather?-1:atlas::mpi::comm().rank()); // Header if (is_new_file) @@ -1106,7 +1106,7 @@ void GmshIO::write_delegate( bool gather = options.has("gather") ? options.get("gather") : false; - GmshFile file(file_path,mode,gather?-1:atlas::parallel::mpi::comm().rank()); + GmshFile file(file_path,mode,gather?-1:atlas::mpi::comm().rank()); // Header if (is_new_file) diff --git a/src/atlas/parallel/Checksum.h b/src/atlas/parallel/Checksum.h index 2e65e3088..04f85f40d 100644 --- a/src/atlas/parallel/Checksum.h +++ b/src/atlas/parallel/Checksum.h @@ -110,7 +110,7 @@ std::string Checksum::execute( const DATA_TYPE data[], local_checksums[pp] = util::checksum(data+pp*var_size,var_size); } - std::vector global_checksums( parallel::mpi::comm().rank() == root ? gather_->glb_dof() : 0 ); + std::vector global_checksums( mpi::comm().rank() == root ? gather_->glb_dof() : 0 ); parallel::Field loc(local_checksums.data(),1); parallel::Field glb(global_checksums.data(),1); gather_->gather(&loc,&glb,1); @@ -119,7 +119,7 @@ std::string Checksum::execute( const DATA_TYPE data[], global_checksums.data(), global_checksums.size()); - parallel::mpi::comm().broadcast(glb_checksum, root); + mpi::comm().broadcast(glb_checksum, root); return eckit::Translator()(glb_checksum); } diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index 0ca1073b8..d8c690cb0 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -30,7 +30,7 @@ struct IsGhostPoint part_ = part; ridx_ = ridx; base_ = base; - mypart_ = parallel::mpi::comm().rank(); + mypart_ = mpi::comm().rank(); } bool operator()(int idx) @@ -81,16 +81,16 @@ GatherScatter::GatherScatter() : name_(), is_setup_(false) { - myproc = parallel::mpi::comm().rank(); - nproc = parallel::mpi::comm().size(); + myproc = mpi::comm().rank(); + nproc = mpi::comm().size(); } GatherScatter::GatherScatter(const std::string& name) : name_(name), is_setup_(false) { - myproc = parallel::mpi::comm().rank(); - nproc = parallel::mpi::comm().size(); + myproc = mpi::comm().rank(); + nproc = mpi::comm().size(); } @@ -120,7 +120,7 @@ void GatherScatter::setup( const int part[], } ATLAS_TRACE_MPI( ALLGATHER ) { - parallel::mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); + mpi::comm().allGather(loccnt_, glbcounts_.begin(), glbcounts_.end()); } glbcnt_ = std::accumulate(glbcounts_.begin(),glbcounts_.end(),0); @@ -133,7 +133,7 @@ void GatherScatter::setup( const int part[], std::vector recvnodes(glbcnt_); ATLAS_TRACE_MPI( ALLGATHER ) { - parallel::mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, + mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, recvnodes.data(), glbcounts_.data(), glbdispls_.data()); } diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index ecca1cb19..808fa1aad 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -302,7 +302,7 @@ void GatherScatter::gather( parallel::Field lfields[], /// Gather ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gatherv(loc_buffer, glb_buffer, glb_counts, glb_displs, root); + mpi::comm().gatherv(loc_buffer, glb_buffer, glb_counts, glb_displs, root); } /// Unpack @@ -363,7 +363,7 @@ void GatherScatter::scatter( parallel::Field gfields[], /// Scatter ATLAS_TRACE_MPI( SCATTER ) { - parallel::mpi::comm().scatterv(glb_buffer.begin(), glb_buffer.end(), glb_counts, glb_displs, loc_buffer.begin(), loc_buffer.end(), root); + mpi::comm().scatterv(glb_buffer.begin(), glb_buffer.end(), glb_counts, glb_displs, loc_buffer.begin(), loc_buffer.end(), root); } /// Unpack diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index ddd7c2e3b..d76ae9e52 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -30,7 +30,7 @@ struct IsGhostPoint part_ = part; ridx_ = ridx; base_ = base; - mypart_ = parallel::mpi::comm().rank(); + mypart_ = mpi::comm().rank(); } bool operator()(size_t idx) @@ -50,16 +50,16 @@ HaloExchange::HaloExchange() : name_(), is_setup_(false) { - myproc = parallel::mpi::comm().rank(); - nproc = parallel::mpi::comm().size(); + myproc = mpi::comm().rank(); + nproc = mpi::comm().size(); } HaloExchange::HaloExchange(const std::string& name) : name_(name), is_setup_(false) { - myproc = parallel::mpi::comm().rank(); - nproc = parallel::mpi::comm().size(); + myproc = mpi::comm().rank(); + nproc = mpi::comm().size(); } void HaloExchange::setup( const int part[], @@ -92,7 +92,7 @@ void HaloExchange::setup( const int part[], Find the amount of nodes this proc has to send to each other proc */ ATLAS_TRACE_MPI( ALLTOALL ) { - parallel::mpi::comm().allToAll(recvcounts_, sendcounts_); + mpi::comm().allToAll(recvcounts_, sendcounts_); } sendcnt_ = std::accumulate(sendcounts_.begin(),sendcounts_.end(),0); @@ -130,7 +130,7 @@ void HaloExchange::setup( const int part[], std::vector recv_requests(sendcnt_); ATLAS_TRACE_MPI( ALLTOALL ) { - parallel::mpi::comm().allToAllv(send_requests.data(), recvcounts_.data(), recvdispls_.data(), + mpi::comm().allToAllv(send_requests.data(), recvcounts_.data(), recvdispls_.data(), recv_requests.data(), sendcounts_.data(), senddispls_.data()); } diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 42044d797..ae4f3fdf3 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -159,7 +159,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const { if(recv_counts[jproc] > 0) { - recv_req[jproc] = parallel::mpi::comm().iReceive(&recv_buffer[recv_displs[jproc]], recv_counts[jproc], jproc, tag); + recv_req[jproc] = mpi::comm().iReceive(&recv_buffer[recv_displs[jproc]], recv_counts[jproc], jproc, tag); } } } @@ -173,7 +173,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const { if(send_counts[jproc] > 0) { - send_req[jproc] = parallel::mpi::comm().iSend( + send_req[jproc] = mpi::comm().iSend( &send_buffer[send_displs[jproc]], send_counts[jproc], jproc, tag); } @@ -186,7 +186,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const { if( recvcounts_[jproc] > 0) { - parallel::mpi::comm().wait(recv_req[jproc]); + mpi::comm().wait(recv_req[jproc]); } } } @@ -200,7 +200,7 @@ void HaloExchange::execute(array::Array& field, bool on_device) const { if( sendcounts_[jproc] > 0) { - parallel::mpi::comm().wait(send_req[jproc]); + mpi::comm().wait(send_req[jproc]); } } } diff --git a/src/atlas/parallel/mpi/Buffer.h b/src/atlas/parallel/mpi/Buffer.h index b7e22bdb5..75249e2ce 100644 --- a/src/atlas/parallel/mpi/Buffer.h +++ b/src/atlas/parallel/mpi/Buffer.h @@ -8,15 +8,12 @@ * does it submit to any jurisdiction. */ -#ifndef ATLAS_MPI_BUFFER_h -#define ATLAS_MPI_BUFFER_h +#pragma once #include "atlas/parallel/mpi/mpi.h" - #include "atlas/array/LocalView.h" namespace atlas { -namespace parallel { namespace mpi { /// @brief Buffer @@ -67,7 +64,4 @@ struct Buffer : public eckit::mpi::Buffer // ---------------------------------------------------------------------------------- } // namespace mpi -} // namespace parallel } // namespace atlas - -#endif diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 5724bf189..471b754ad 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -21,17 +21,16 @@ #include "atlas/util/detail/BlackMagic.h" #undef ATLAS_TRACE_MPI -#define ATLAS_TRACE_MPI(...) ATLAS_TRACE_MPI_( ::atlas::parallel::mpi::Statistics, 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__) ) -#define __ATLAS_TRACE_MPI_ENUM(operation) ::atlas::parallel::mpi::Operation::__ATLAS_STRINGIFY(operation) +#define __ATLAS_TRACE_MPI_ENUM(operation) ::atlas::mpi::Operation::__ATLAS_STRINGIFY(operation) #endif namespace atlas { -namespace parallel { namespace mpi { struct StatisticsTimerTraits { @@ -74,13 +73,13 @@ static const std::string& name(Operation c) { return names[ static_cast(c) ]; } -class Statistics : public runtime::trace::TraceT< StatisticsTimerTraits > { +class Trace : public runtime::trace::TraceT< StatisticsTimerTraits > { using Base = runtime::trace::TraceT< StatisticsTimerTraits >; public: - Statistics( const eckit::CodeLocation& loc, Operation c ) : + Trace( const eckit::CodeLocation& loc, Operation c ) : Base( loc, name(c), make_labels(c) ) { } - Statistics( const eckit::CodeLocation& loc, Operation c, const std::string& title ) : + Trace( const eckit::CodeLocation& loc, Operation c, const std::string& title ) : Base( loc, title, make_labels(c) ) { } private: @@ -90,5 +89,4 @@ class Statistics : public runtime::trace::TraceT< StatisticsTimerTraits > { }; } // namespace mpi -} // namespace parallel } // namespace atlas diff --git a/src/atlas/parallel/mpi/mpi.cc b/src/atlas/parallel/mpi/mpi.cc index 8285c28bf..106383db5 100644 --- a/src/atlas/parallel/mpi/mpi.cc +++ b/src/atlas/parallel/mpi/mpi.cc @@ -11,7 +11,6 @@ #include "atlas/parallel/mpi/mpi.h" namespace atlas { -namespace parallel { namespace mpi { const eckit::mpi::Comm& comm() @@ -20,5 +19,4 @@ const eckit::mpi::Comm& comm() } } // namespace mpi -} // namespace parallel } // namespace atlas diff --git a/src/atlas/parallel/mpi/mpi.h b/src/atlas/parallel/mpi/mpi.h index 8525507bc..a73062f27 100644 --- a/src/atlas/parallel/mpi/mpi.h +++ b/src/atlas/parallel/mpi/mpi.h @@ -14,11 +14,9 @@ #include "atlas/parallel/mpi/Statistics.h" namespace atlas { -namespace parallel { namespace mpi { const eckit::mpi::Comm& comm(); } // namespace mpi -} // namespace parallel } // namespace atlas diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index b988deb71..848fb5b11 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -119,8 +119,8 @@ bool atlas::AtlasTool::handle_help() atlas::AtlasTool::AtlasTool(int argc, char **argv): eckit::Tool(argc,argv) { eckit::LibEcKit::instance().setAbortHandler( []{ - Log::error() << "["<("help","Print this help") ); @@ -188,7 +188,7 @@ void atlas::AtlasTool::setupLogging() if( use_logfile ) { - int d = digits(parallel::mpi::comm().size()); + int d = digits(mpi::comm().size()); std::string rankstr = std::to_string(taskID()); for( int i = rankstr.size(); i1)); + TRANS_CHECK(::trans_use_mpi(mpi::comm().size()>1)); TRANS_CHECK(::trans_setup(trans_.get())); } @@ -769,14 +769,14 @@ void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const for( long jlat=0; jlat1)); + 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_)); - if( p.read_legendre().size() && parallel::mpi::comm().size() == 1 ) + if( p.read_legendre().size() && mpi::comm().size() == 1 ) { eckit::PathName file( p.read_legendre() ); if( not file.exists() ) @@ -786,7 +786,7 @@ void TransIFS::ctor_rgg(const long nlat, const long pl[], long truncation, const } TRANS_CHECK(::trans_set_read(trans_.get(),file.asString().c_str())); } - if( p.write_legendre().size() && parallel::mpi::comm().size() == 1 ) { + 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())); } @@ -803,13 +803,13 @@ void TransIFS::ctor_lonlat(const long nlon, const long nlat, long truncation, co { TransParameters p(*this,config); TRANS_CHECK(::trans_new(trans_.get())); - TRANS_CHECK(::trans_use_mpi(parallel::mpi::comm().size()>1)); + 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() && parallel::mpi::comm().size() == 1 ) { + if( p.read_legendre().size() && mpi::comm().size() == 1 ) { eckit::PathName file( p.read_legendre() ); if( not file.exists() ) { @@ -818,7 +818,7 @@ void TransIFS::ctor_lonlat(const long nlon, const long nlat, long truncation, co } TRANS_CHECK(::trans_set_read(trans_.get(),file.asString().c_str())); } - if( p.write_legendre().size() && parallel::mpi::comm().size() == 1 ) { + 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())); } diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index 3f3cbf354..b627c42be 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -63,7 +63,7 @@ void Metadata::broadcast(Metadata& dest, const size_t root) { std::string buffer; int buffer_size; - if( atlas::parallel::mpi::comm().rank() == root ) + if( atlas::mpi::comm().rank() == root ) { std::stringstream s; eckit::JSON json(s); @@ -74,18 +74,18 @@ void Metadata::broadcast(Metadata& dest, const size_t root) } ATLAS_TRACE_MPI( BROADCAST ) { - atlas::parallel::mpi::comm().broadcast(buffer_size,root); + atlas::mpi::comm().broadcast(buffer_size,root); } - if( atlas::parallel::mpi::comm().rank() != root ) { + if( atlas::mpi::comm().rank() != root ) { buffer.resize(buffer_size); } ATLAS_TRACE_MPI( BROADCAST ) { - atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); + atlas::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); } - if( not (&dest==this && atlas::parallel::mpi::comm().rank() == root ) ) + if( not (&dest==this && atlas::mpi::comm().rank() == root ) ) { std::stringstream s; s << buffer; @@ -105,7 +105,7 @@ void Metadata::broadcast(Metadata& dest, const size_t root) const { std::string buffer; int buffer_size; - if( atlas::parallel::mpi::comm().rank() == root ) + if( atlas::mpi::comm().rank() == root ) { std::stringstream s; eckit::JSON json(s); @@ -116,15 +116,15 @@ void Metadata::broadcast(Metadata& dest, const size_t root) const } ATLAS_TRACE_MPI( BROADCAST ) { - atlas::parallel::mpi::comm().broadcast(buffer_size,root); + atlas::mpi::comm().broadcast(buffer_size,root); } - if( atlas::parallel::mpi::comm().rank() != root ) { + if( atlas::mpi::comm().rank() != root ) { buffer.resize(buffer_size); } ATLAS_TRACE_MPI( BROADCAST ) { - atlas::parallel::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); + atlas::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); } // Fill in dest diff --git a/src/atlas/util/detail/Debug.h b/src/atlas/util/detail/Debug.h index cd0286746..72a31c423 100644 --- a/src/atlas/util/detail/Debug.h +++ b/src/atlas/util/detail/Debug.h @@ -79,7 +79,7 @@ inline int mpi_rank(int i=0) { inline int is_mpi_rank() { static std::vector v = eckit::Resource>("$ATLAS_DEBUG_MPI_RANK", std::vector() ); - static int r = parallel::mpi::comm().rank(); + static int r = mpi::comm().rank(); for( long g : v ) { if ( r == g ) return true; @@ -96,7 +96,7 @@ inline int is_mpi_rank(int x) { return false; } inline std::string rank_str() { - static std::string s = "["+std::to_string(parallel::mpi::comm().rank())+"] "; + static std::string s = "["+std::to_string(mpi::comm().rank())+"] "; return s; } diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc index 5fa77cf13..ff0cf6624 100644 --- a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -110,7 +110,7 @@ void Tool::execute(const Args& args) ATLAS_TRACE("iteration"); Mesh mesh = meshgenerator.generate(grid); mesh::actions::build_halo( mesh, halo ); - parallel::mpi::comm().barrier(); + mpi::comm().barrier(); } timer.stop(); Log::info() << Trace::report() << std::endl; diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index efd050629..4220a6b70 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -80,8 +80,8 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui UniqueLonLat compute_uid(nodes); - // unused // int mypart = parallel::mpi::comm().rank(); - int nparts = parallel::mpi::comm().size(); + // unused // int mypart = mpi::comm().rank(); + int nparts = mpi::comm().size(); size_t root = 0; array::ArrayView nodes_glb_idx = array::make_view ( nodes.global_index() ); @@ -126,11 +126,11 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui // 1) Gather all global indices, together with location - std::vector recvcounts(parallel::mpi::comm().size()); - std::vector recvdispls(parallel::mpi::comm().size()); + std::vector recvcounts(mpi::comm().size()); + std::vector recvdispls(mpi::comm().size()); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gather(nb_nodes, recvcounts, root); + mpi::comm().gather(nb_nodes, recvcounts, root); } recvdispls[0]=0; @@ -142,7 +142,7 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui std::vector glb_idx_gathered( glb_nb_nodes ); ATLAS_TRACE_MPI( GATHER ) { - parallel::mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); + mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); } @@ -174,7 +174,7 @@ void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& bui // 3) Scatter renumbered back ATLAS_TRACE_MPI( SCATTER ) { - parallel::mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); + mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); } for( int jnode=0; jnode(option::name("partition")); array::ArrayView arr = array::make_view(field); - arr.assign(parallel::mpi::comm().rank()); + arr.assign(mpi::comm().rank()); //field->dump( Log::info() ); nodes_fs.haloExchange(field); //field->dump( Log::info() ); @@ -155,7 +155,7 @@ CASE( "test_functionspace_NodeColumns" ) Field field2 = nodes_fs.createField(option::name("partition2")|option::variables(2)); Log::info() << "field2.rank() = " << field2.rank() << std::endl; array::ArrayView arr2 = array::make_view(field2); - arr2.assign(parallel::mpi::comm().rank()); + arr2.assign(mpi::comm().rank()); //field2->dump( Log::info() ); nodes_fs.haloExchange(field2); @@ -163,7 +163,7 @@ CASE( "test_functionspace_NodeColumns" ) Log::info() << nodes_fs.checksum(field) << std::endl; - size_t root = parallel::mpi::comm().size()-1; + size_t root = mpi::comm().size()-1; Field glb_field = nodes_fs.createField( option::name("partition") | option::datatype(field.datatype()) | @@ -188,7 +188,7 @@ CASE( "test_functionspace_NodeColumns" ) //glb_field->dump( Log::info() ); - if( parallel::mpi::comm().rank() == root ) + if( mpi::comm().rank() == root ) glb_field.metadata().set("test_broadcast",123); arr.assign(-1); @@ -221,15 +221,15 @@ CASE( "test_functionspace_NodeColumns" ) gidx_t gidx_min; array::ArrayView sfc_arr = array::make_view( field ); - sfc_arr.assign( parallel::mpi::comm().rank()+1 ); + sfc_arr.assign( mpi::comm().rank()+1 ); fs.maximum(surface_scalar_field,max); - EXPECT( max == double(parallel::mpi::comm().size()) ); + EXPECT( max == double(mpi::comm().size()) ); fs.minimum(surface_scalar_field,min); EXPECT( min == 1 ); fs.maximumAndLocation(field,max,gidx_max); - EXPECT( max == double(parallel::mpi::comm().size()) ); + EXPECT( max == double(mpi::comm().size()) ); Log::info() << "global index for maximum: " << gidx_max << std::endl; fs.minimumAndLocation(field,min,gidx_min); @@ -278,9 +278,9 @@ CASE( "test_functionspace_NodeColumns" ) std::vector gidx_min; auto vec_arr = array::make_view( field ); - vec_arr.assign( parallel::mpi::comm().rank()+1 ); + vec_arr.assign( mpi::comm().rank()+1 ); fs.maximum(field, max); - std::vector check_max(field.variables(), parallel::mpi::comm().size()); + std::vector check_max(field.variables(), mpi::comm().size()); EXPECT( max == check_max ); fs.minimum(field,min); @@ -334,15 +334,15 @@ CASE( "test_functionspace_NodeColumns" ) EXPECT(field.levels() == nb_levels); array::ArrayView arr = array::make_view( field ); - arr.assign( parallel::mpi::comm().rank()+1 ); + arr.assign( mpi::comm().rank()+1 ); fs.maximum(field,max); - EXPECT( max == double(parallel::mpi::comm().size()) ); + EXPECT( max == double(mpi::comm().size()) ); fs.minimum(field,min); EXPECT( min == 1 ); fs.maximumAndLocation(field,max,gidx_max,level); - EXPECT( max == double(parallel::mpi::comm().size()) ); + EXPECT( max == double(mpi::comm().size()) ); Log::info() << "global index for maximum: " << gidx_max << std::endl; Log::info() << "level for maximum: " << level << std::endl; @@ -414,9 +414,9 @@ CASE( "test_functionspace_NodeColumns" ) std::vector levels; array::ArrayView vec_arr = array::make_view( field ); - vec_arr.assign( parallel::mpi::comm().rank()+1 ); + vec_arr.assign( mpi::comm().rank()+1 ); fs.maximum(field,max); - std::vector check_max(nvar,parallel::mpi::comm().size()); + std::vector check_max(nvar,mpi::comm().size()); EXPECT( max == check_max ); fs.minimum(field,min); @@ -626,12 +626,12 @@ CASE( "test_SpectralFunctionSpace_norm" ) { auto twoD = array::make_view( twoD_field ); twoD.assign(0.); - if( parallel::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( field ); auto value_glb = array::make_view( field_glb ); - value.assign(parallel::mpi::comm().rank()); + value.assign(mpi::comm().rank()); fs.gather(field,field_glb); @@ -61,7 +61,7 @@ CASE( "test_functionspace_StructuredColumns_no_halo" ) // Log::info() << value_glb(j) << " "; // Log::info() << std::endl; - if( parallel::mpi::comm().rank() == root && parallel::mpi::comm().size() == 5 ) { + if( mpi::comm().rank() == root && mpi::comm().size() == 5 ) { std::vector check{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; EXPECT( value_glb.size() == check.size() ); @@ -78,7 +78,7 @@ CASE( "test_functionspace_StructuredColumns_no_halo" ) CASE( "test_functionspace_StructuredColumns_halo" ) { - ATLAS_DEBUG_VAR( parallel::mpi::comm().size() ); + ATLAS_DEBUG_VAR( mpi::comm().size() ); int root=0; // grid::StructuredGrid grid( // grid::StructuredGrid::XSpace( {0.,360.} , {2,4,6,6,4,2} , false ), @@ -116,7 +116,7 @@ CASE( "test_functionspace_StructuredColumns_halo" ) //EXPECT( fs.checksum(field) == "cef2694016492d408fa157b7c59ce741" ); - eckit::PathName filepath("test_functionspace_StructuredColumns_halo_p"+std::to_string(parallel::mpi::comm().rank())+".py"); + eckit::PathName filepath("test_functionspace_StructuredColumns_halo_p"+std::to_string(mpi::comm().rank())+".py"); std::ofstream f(filepath.asString().c_str(), std::ios::trunc ); diff --git a/src/tests/mesh/test_distmesh.cc b/src/tests/mesh/test_distmesh.cc index ee156fe74..90a632478 100644 --- a/src/tests/mesh/test_distmesh.cc +++ b/src/tests/mesh/test_distmesh.cc @@ -62,7 +62,7 @@ double dual_volume(Mesh& mesh) ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduceInPlace(area, eckit::mpi::sum()); + mpi::comm().allReduceInPlace(area, eckit::mpi::sum()); } return area; diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index 0656d9201..71efa3a2a 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -57,7 +57,7 @@ double dual_volume(Mesh& mesh) } ATLAS_TRACE_MPI( ALLREDUCE ) { - parallel::mpi::comm().allReduceInPlace(area, eckit::mpi::sum()); + mpi::comm().allReduceInPlace(area, eckit::mpi::sum()); } return area; @@ -76,12 +76,12 @@ CASE( "test_small" ) mesh::actions::build_halo(*m,2); - if( parallel::mpi::comm().size() == 5 ) + if( mpi::comm().size() == 5 ) { IndexView ridx ( m->nodes().remote_index() ); array::array::ArrayView gidx ( m->nodes().global_index() ); - switch( parallel::mpi::comm().rank() ) // with 5 tasks + switch( mpi::comm().rank() ) // with 5 tasks { case 0: EXPECT( ridx(9) == 9 ); @@ -93,7 +93,7 @@ CASE( "test_small" ) } else { - if( parallel::mpi::comm().rank() == 0 ) + if( mpi::comm().rank() == 0 ) std::cout << "skipping tests with 5 mpi tasks!" << std::endl; } @@ -102,7 +102,7 @@ CASE( "test_small" ) EXPECT( eckit::types::is_approximately_equal( test::dual_volume(*m), 2.*M_PI*M_PI, 1e-6 )); - std::stringstream filename; filename << "small_halo_p" << parallel::mpi::comm().rank() << ".msh"; + std::stringstream filename; filename << "small_halo_p" << mpi::comm().rank() << ".msh"; Gmsh(filename.str()).write(*m); } #endif @@ -130,7 +130,7 @@ CASE( "test_custom" ) auto lonlat = array::make_view( m.nodes().lonlat() ); std::vector check; - switch( parallel::mpi::comm().rank() ) { + switch( mpi::comm().rank() ) { case 0: check = { 607990293346953216, 607990293382953216, @@ -472,7 +472,7 @@ CASE( "test_custom" ) for( size_t j=0; j(nodes.partition()) ), ridx_( make_indexview(nodes.remote_index()) ), - mypart_(parallel::mpi::comm().rank()) + mypart_(mpi::comm().rank()) { } @@ -88,11 +88,11 @@ CASE( "test1" ) glb_idx(2) = 3; part(2) = 0; glb_idx(3) = 4; part(3) = 0; glb_idx(4) = 5; part(4) = 0; - glb_idx(5) = 6; part(5) = std::min(1,(int)parallel::mpi::comm().size()-1); - glb_idx(6) = 7; part(6) = std::min(1,(int)parallel::mpi::comm().size()-1); - glb_idx(7) = 8; part(7) = std::min(1,(int)parallel::mpi::comm().size()-1); - glb_idx(8) = 9; part(8) = std::min(1,(int)parallel::mpi::comm().size()-1); - glb_idx(9) = 10; part(9) = std::min(1,(int)parallel::mpi::comm().size()-1); + glb_idx(5) = 6; part(5) = std::min(1,(int)mpi::comm().size()-1); + glb_idx(6) = 7; part(6) = std::min(1,(int)mpi::comm().size()-1); + glb_idx(7) = 8; part(7) = std::min(1,(int)mpi::comm().size()-1); + glb_idx(8) = 9; part(8) = std::min(1,(int)mpi::comm().size()-1); + glb_idx(9) = 10; part(9) = std::min(1,(int)mpi::comm().size()-1); xy(0,XX) = 0.; xy(0,YY) = 80.; Topology::set( flags(0), Topology::BC|Topology::WEST ); xy(1,XX) = 0.; xy(1,YY) =-80.; Topology::set( flags(1), Topology::BC|Topology::WEST ); @@ -123,7 +123,7 @@ CASE( "test1" ) test::IsGhost is_ghost( m.nodes() ); - switch ( parallel::mpi::comm().rank() ) + switch ( mpi::comm().rank() ) { case 0: EXPECT( is_ghost(0) == false ); @@ -158,7 +158,7 @@ CASE( "test1" ) EXPECT( part(9) == 0 ); EXPECT( loc(8) == 0 ); EXPECT( loc(9) == 1 ); - if( parallel::mpi::comm().rank() == 1 ) + if( mpi::comm().rank() == 1 ) { EXPECT( is_ghost(8) == true ); EXPECT( is_ghost(9) == true ); @@ -186,8 +186,8 @@ CASE( "test2" ) } ATLAS_DEBUG_VAR( nb_ghost ); - if( parallel::mpi::comm().rank() == 0 ) EXPECT( nb_ghost == 128 ); // South boundary of Northern hemisphere - if( parallel::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); @@ -199,8 +199,8 @@ CASE( "test2" ) ATLAS_DEBUG_VAR( nb_periodic ); - if( parallel::mpi::comm().rank() == 0 ) EXPECT( nb_periodic == 33 ); // Periodic East boundary of Northern hemisphere (plus one point south) - if( parallel::mpi::comm().rank() == 1 ) EXPECT( nb_periodic == 32 ); // Periodic East boundary of Southern hemisphere + 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 Gmsh("periodic.msh",util::Config("info",true)).write(m); } diff --git a/src/tests/numerics/test_fvm_nabla.cc b/src/tests/numerics/test_fvm_nabla.cc index 398df843e..d4feabf30 100644 --- a/src/tests/numerics/test_fvm_nabla.cc +++ b/src/tests/numerics/test_fvm_nabla.cc @@ -57,7 +57,7 @@ double dual_volume(const Mesh& mesh) } } - parallel::mpi::comm().allReduceInPlace(area, eckit::mpi::sum()); + mpi::comm().allReduceInPlace(area, eckit::mpi::sum()); return area; } diff --git a/src/tests/parallel/test_gather.cc b/src/tests/parallel/test_gather.cc index 9f7d2a65b..35377d6f9 100644 --- a/src/tests/parallel/test_gather.cc +++ b/src/tests/parallel/test_gather.cc @@ -40,8 +40,8 @@ struct Fixture { Fixture() { int nnodes_c[] = {6, 6, 7}; nb_nodes = vec(nnodes_c); - Nl = nb_nodes[parallel::mpi::comm().rank()]; - switch( parallel::mpi::comm().rank() ) + Nl = nb_nodes[mpi::comm().rank()]; + switch( mpi::comm().rank() ) { case 0: { //./----> extra ghost point with nonstandard gidx @@ -76,7 +76,7 @@ struct Fixture { int Nl; size_t root; - int Ng() { return parallel::mpi::comm().rank() == root ? gather_scatter.glb_dof() : 0; } + int Ng() { return mpi::comm().rank() == root ? gather_scatter.glb_dof() : 0; } }; //----------------------------------------------------------------------------- @@ -88,20 +88,20 @@ CASE("test_gather") { SECTION( "test_gather_rank0" ) { - for( f.root=0; f.root loc(f.Nl); std::vector glb(f.Ng()); for( int j=0; j loc(f.Nl,2); array::ArrayT glb(f.Ng(),2); @@ -120,8 +120,8 @@ CASE("test_gather") { array::ArrayT glb2(f.Ng(),1); array::ArrayView locv = array::make_view(loc); for( int j=0; j(), loc_strides, loc_extents, 2, glb.data(), glb_strides, glb_extents, 2, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { auto glbv = array::make_view(glb); POD glb_c[] = { 10,100, 20,200, 30,300, 40,400, 50,500, 60,600, 70,700, 80,800, 90,900 }; @@ -156,7 +156,7 @@ CASE("test_gather") { f.gather_scatter.gather( loc.data(), loc_strides, loc_extents, 2, glb1.data(), glb_strides, glb_extents, 2, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { auto glbv = array::make_view(glb1); POD glb1_c[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90 }; @@ -177,7 +177,7 @@ CASE("test_gather") { f.gather_scatter.gather( loc.data()+1, loc_strides, loc_extents, 1, glb2.data(), glb_strides, glb_extents, 1, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { auto glbv = array::make_view(glb2); POD glb2_c[] = { 100, 200, 300, 400, 500, 600, 700, 800, 900 }; @@ -194,7 +194,7 @@ CASE("test_gather") { SECTION( "test_gather_rank1" ) { - for( f.root=0; f.root loc(f.Nl,2); array::ArrayT glb(f.Ng(),2); @@ -202,8 +202,8 @@ CASE("test_gather") { array::ArrayT glb2(f.Ng(),1); array::ArrayView locv = array::make_view(loc); for( int j=0; j(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { 10,100, 20,200, 30,300, 40,400, 50,500, 60,600, 70,700, 80,800, 90,900 }; EXPECT(make_view(glb.data(),glb.data()+2*f.Ng()) == make_view(glb_c,glb_c+2*f.Ng())); @@ -280,7 +280,7 @@ CASE("test_gather") { f.gather_scatter.gather( loc.data(), loc_strides, loc_extents, loc_rank, loc_mpl_idxpos, loc_mpl_rank, glb1.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb1_c[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90 }; EXPECT(make_view(glb1.data(),glb1.data()+f.Ng()) == make_view( glb1_c,glb1_c+f.Ng())); @@ -305,7 +305,7 @@ CASE("test_gather") { glb2.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb2_c[] = { 100, 200, 300, 400, 500, 600, 700, 800, 900 }; EXPECT(make_view(glb2.data(),glb2.data()+f.Ng()) == make_view(glb2_c,glb2_c+f.Ng())); @@ -318,7 +318,7 @@ CASE("test_gather") { SECTION( "test_gather_rank2" ) { - for( f.root=0; f.root loc(f.Nl,3,2); array::ArrayT glb(f.Ng(),3,2); @@ -333,8 +333,8 @@ CASE("test_gather") { { for(int i = 0; i < 3; ++i) { - locv(p,i,0) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); - locv(p,i,1) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); + locv(p,i,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); + locv(p,i,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); } } @@ -355,7 +355,7 @@ CASE("test_gather") { glb.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { -1,1, -10,10, -100,100, -2,2, -20,20, -200,200, @@ -387,7 +387,7 @@ CASE("test_gather") { glbx1.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { -1, -10, -100, -2, -20, -200, @@ -419,7 +419,7 @@ CASE("test_gather") { glbx2.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { 1, 10, 100, 2, 20, 200, @@ -452,7 +452,7 @@ CASE("test_gather") { glb1x.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { -1,1, -2,2, @@ -484,7 +484,7 @@ CASE("test_gather") { glb2x.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { -10,10, -20,20, @@ -517,7 +517,7 @@ CASE("test_gather") { glb32.data(), glb_strides, glb_extents, glb_rank, glb_mpl_idxpos, glb_mpl_rank, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { 100, 200, @@ -537,7 +537,7 @@ CASE("test_gather") { SECTION( "test_gather_rank0_ArrayView" ) { - for( f.root=0; f.root loc(f.Nl); @@ -547,14 +547,14 @@ CASE("test_gather") { array::ArrayView glbv = array::make_view(glb); for(int p = 0; p < f.Nl; ++p) { - locv(p) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : f.gidx[p]*10 ); + locv(p) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*10 ); } // Gather complete field { f.gather_scatter.gather( locv, glbv, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { 10, 20, @@ -574,7 +574,7 @@ CASE("test_gather") { SECTION( "test_gather_rank1_ArrayView" ) { - for( f.root=0; f.root loc(f.Nl,2); @@ -584,15 +584,15 @@ CASE("test_gather") { array::ArrayView glbv = array::make_view(glb); for(int p = 0; p < f.Nl; ++p) { - locv(p,0) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : -f.gidx[p]*10 ); - locv(p,1) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : f.gidx[p]*10 ); + locv(p,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*10 ); + locv(p,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*10 ); } // Gather complete field { f.gather_scatter.gather( locv, glbv, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { -10,10, -20,20, @@ -618,7 +618,7 @@ CASE("test_gather") { SECTION( "test_gather_rank2_ArrayView" ) { - for( f.root=0; f.root loc(f.Nl,3,2); @@ -630,8 +630,8 @@ CASE("test_gather") { { for(int i = 0; i < 3; ++i) { - locv(p,i,0) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); - locv(p,i,1) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); + locv(p,i,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); + locv(p,i,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); } } @@ -639,7 +639,7 @@ CASE("test_gather") { { f.gather_scatter.gather( locv, glbv, f.root ); } - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { -1,1, -10,10, -100,100, -2,2, -20,20, -200,200, @@ -665,7 +665,7 @@ CASE("test_gather") { SECTION( "test_scatter_rank2_ArrayView" ) { - for( f.root=0; f.root loc(f.Nl,3,2); @@ -673,7 +673,7 @@ CASE("test_gather") { array::ArrayView locv = array::make_view(loc); array::ArrayView glbv = array::make_view(glb); - if( parallel::mpi::comm().rank() == f.root ) + if( mpi::comm().rank() == f.root ) { POD glb_c[] = { -1,1, -10,10, -100,100, -2,2, -20,20, -200,200, @@ -699,7 +699,7 @@ CASE("test_gather") { f.gather_scatter.scatter( glbv, locv, f.root ); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { POD loc_c[] = { nan,nan, nan,nan, nan,nan, diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 8051633d7..aade0d3b2 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -110,8 +110,8 @@ struct Fixture { Fixture(bool on_device) : on_device_(on_device) { int nnodes_c[] = {5, 6, 7}; nb_nodes = vec(nnodes_c); - N = nb_nodes[parallel::mpi::comm().rank()]; - switch( parallel::mpi::comm().rank() ) + N = nb_nodes[mpi::comm().rank()]; + switch( mpi::comm().rank() ) { case 0: { @@ -153,7 +153,7 @@ void test_rank0_arrview(Fixture& f) { array::ArrayT arr(f.N); array::ArrayView arrv = array::make_host_view(arr); for( int j=0; j::apply(arrv, arr_c); break; } @@ -177,8 +177,8 @@ void test_rank1(Fixture& f) { array::ArrayT arr(f.N,2); array::ArrayView arrv = array::make_host_view(arr); for( int j=0; j::apply(arrv, arr_c); break; } @@ -203,8 +203,8 @@ void test_rank1_strided_v1(Fixture& f) { array::ArrayT arr_t(f.N,2); array::ArrayView arrv_t = array::make_host_view(arr_t); for( int j=0; jsyncHostDevice(); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { POD arr_c[] = { 90,0, 10,100, 20,200, 30,300, 40,0 }; validate::apply(arrv_t, arr_c); break; } @@ -246,8 +246,8 @@ void test_rank1_strided_v2(Fixture& f) { array::ArrayT arr_t(f.N,2); array::ArrayView arrv_t = array::make_host_view(arr_t); for( int j=0; j(*arr, false); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { POD arr_c[] = { 0,900, 10,100, 20,200, 30,300, 0,400 }; validate::apply(arrv_t, arr_c); break; } @@ -285,8 +285,8 @@ void test_rank2(Fixture& f) { { for( size_t i=0; i<3; ++i ) { - arrv(p,i,0) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); - arrv(p,i,1) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); + arrv(p,i,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); + arrv(p,i,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); } } @@ -296,7 +296,7 @@ void test_rank2(Fixture& f) { arr.syncHostDevice(); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { @@ -335,8 +335,8 @@ void test_rank2_l1(Fixture& f) { { for( size_t i=0; i<3; ++i ) { - arrv_t(p,i,0) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); - arrv_t(p,i,1) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); + arrv_t(p,i,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); + arrv_t(p,i,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); } } arr_t.syncHostDevice(); @@ -358,7 +358,7 @@ void test_rank2_l1(Fixture& f) { arr_t.syncHostDevice(); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { @@ -405,8 +405,8 @@ void test_rank2_l2_v2(Fixture& f) { { for( size_t i=0; i<3; ++i ) { - arrv_t(p,i,0) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); - arrv_t(p,i,1) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); + arrv_t(p,i,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); + arrv_t(p,i,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); } } @@ -421,7 +421,7 @@ void test_rank2_l2_v2(Fixture& f) { f.halo_exchange.execute(*arr, f.on_device_); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { @@ -468,8 +468,8 @@ void test_rank2_v2(Fixture& f) { { for( size_t i=0; i<3; ++i ) { - arrv_t(p,i,0) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); - arrv_t(p,i,1) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); + arrv_t(p,i,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); + arrv_t(p,i,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); } } @@ -484,7 +484,7 @@ void test_rank2_v2(Fixture& f) { f.halo_exchange.execute(*arr, f.on_device_); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { @@ -533,7 +533,7 @@ void test_rank0_wrap(Fixture& f) { arr->syncHostDevice(); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { POD arr_c[] = { 9, 1, 2, 3, 4}; validate::apply(arrv, arr_c); break; } @@ -548,13 +548,13 @@ void test_rank1_paralleldim1(Fixture& f) { array::ArrayT arr(2,f.N); array::ArrayView arrv = array::make_view(arr); for( int j=0; j(arr, false); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { POD arr_c[] = { 90, 10, 20 , 30 , 40, 900, 100, 200, 300, 400 }; //90,900, 10,100, 20,200, 30,300, 40,400 }; validate::apply(arrv, arr_c); break; } @@ -572,14 +572,14 @@ void test_rank2_paralleldim2(Fixture& f) { { for( size_t i=0; i<3; ++i ) { - arrv(i,p,0) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); - arrv(i,p,1) = (size_t(f.part[p]) != parallel::mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); + arrv(i,p,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); + arrv(i,p,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); } } f.halo_exchange.execute >(arr, false); - switch( parallel::mpi::comm().rank() ) + switch( mpi::comm().rank() ) { case 0: { @@ -615,8 +615,8 @@ void test_rank1_cinterface(Fixture& f) { array::ArrayT arr(f.N,2); array::ArrayView arrv = array::make_host_view(arr); for( int j=0; j::apply(arrv, arr_c); break; } diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 100746b0c..73e15759d 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -51,7 +51,7 @@ namespace test { struct AtlasTransEnvironment : public AtlasTestEnvironment { AtlasTransEnvironment(int argc, char * argv[]) : AtlasTestEnvironment(argc, argv) { - if( parallel::mpi::comm().size() == 1 ) + if( mpi::comm().size() == 1 ) trans_use_mpi(false); trans_init(); } @@ -67,7 +67,7 @@ void read_rspecg(trans::TransImpl& trans, std::vector& rspecg, std::vect { Log::info() << "read_rspecg ...\n"; nfld = 2; - if( parallel::mpi::comm().rank() == 0 ) + if( mpi::comm().rank() == 0 ) { rspecg.resize(nfld*trans.spectralCoefficients()); for( int i=0; i& rspecg, std::vect void read_rspecg( Field spec ) { Log::info() << "read_rspecg ...\n"; - if( parallel::mpi::comm().rank() == 0 ) + if( mpi::comm().rank() == 0 ) { functionspace::Spectral funcspace = spec.functionspace(); int nb_spectral_coefficients_global = functionspace::Spectral( spec.functionspace() ).nb_spectral_coefficients_global(); @@ -126,11 +126,11 @@ CASE( "test_trans_distribution_matches_atlas" ) EXPECT( trans.truncation() == 159 ); // -------------- do checks -------------- // - EXPECT( t->nproc == parallel::mpi::comm().size() ); - EXPECT( t->myproc == parallel::mpi::comm().rank()+1 ); + EXPECT( t->nproc == mpi::comm().size() ); + EXPECT( t->myproc == mpi::comm().rank()+1 ); - if( parallel::mpi::comm().rank() == 0 ) // all tasks do the same, so only one needs to check + if( mpi::comm().rank() == 0 ) // all tasks do the same, so only one needs to check { int max_nb_regions_EW(0); for( int j=0; jnb_bands(); ++j ) @@ -139,7 +139,7 @@ CASE( "test_trans_distribution_matches_atlas" ) EXPECT( t->n_regions_NS == trans_partitioner->nb_bands() ); EXPECT( t->n_regions_EW == max_nb_regions_EW ); - EXPECT( distribution.nb_partitions() == parallel::mpi::comm().size() ); + EXPECT( distribution.nb_partitions() == mpi::comm().size() ); EXPECT( distribution.partition().size() == g.size() ); std::vector npts(distribution.nb_partitions(),0); @@ -148,7 +148,7 @@ CASE( "test_trans_distribution_matches_atlas" ) ++npts[distribution.partition(j)]; EXPECT( t->ngptotg == g.size() ); - EXPECT( t->ngptot == npts[parallel::mpi::comm().rank()] ); + EXPECT( t->ngptot == npts[mpi::comm().rank()] ); EXPECT( t->ngptotmx == *std::max_element(npts.begin(),npts.end()) ); // array::LocalView n_regions ( trans.n_regions() ) ; @@ -171,7 +171,7 @@ CASE( "test_write_read_cache" ) { Log::info() << "test_write_read_cache" << std::endl; using namespace trans; - if( parallel::mpi::comm().size() == 1 ) { + if( mpi::comm().size() == 1 ) { // Create trans that will write file Trans trans_write_F24( Grid("F24"), 23, option::write_legendre("cached_legendre_coeffs-F24") | option::flt(false) ); Trans trans_write_N24( Grid("N24"), 23, option::write_legendre("cached_legendre_coeffs-N24") | option::flt(false) ); @@ -215,7 +215,7 @@ CASE( "test_distspec" ) trans.invtrans( nfld, rspec.data(), rgp.data() ); trans.gathgrid( nfld, nto.data(), rgp.data(), rgpg.data() ); - if( parallel::mpi::comm().rank() == 0 ) { + if( mpi::comm().rank() == 0 ) { EXPECT( eckit::types::is_approximately_equal( specnorms[0], 1., 1.e-10 )); EXPECT( eckit::types::is_approximately_equal( specnorms[1], 2., 1.e-10 )); } @@ -237,7 +237,7 @@ CASE( "test_distspec_speconly" ) fs.scatter(glb,dist); fs.norm(dist,specnorms); - if( parallel::mpi::comm().rank() == 0 ) { + if( mpi::comm().rank() == 0 ) { EXPECT( eckit::types::is_approximately_equal( specnorms[0], 1., 1.e-10 )); EXPECT( eckit::types::is_approximately_equal( specnorms[1], 2., 1.e-10 )); } @@ -257,7 +257,7 @@ CASE( "test_distribution" ) grid::Distribution d_eqreg = grid::Partitioner( new EqualRegionsPartitioner() ).partition(g); Log::info() << "eqregions distribution created" << std::endl; - if( parallel::mpi::comm().rank() == 0 ) + if( mpi::comm().rank() == 0 ) { EXPECT( d_trans.nb_partitions() == d_eqreg.nb_partitions() ); EXPECT( d_trans.max_pts() == d_eqreg.max_pts() ); @@ -352,14 +352,14 @@ CASE( "test_nomesh" ) Field gpfg = gridpoints.createField(option::name("gpf") | option::global()); array::ArrayView spg = array::make_view(spfg); - if( parallel::mpi::comm().rank() == 0 ) { + if( mpi::comm().rank() == 0 ) { spg.assign(0.); spg(0) = 4.; } EXPECT_NO_THROW( spectral.scatter(spfg,spf) ); - if( parallel::mpi::comm().rank() == 0 ) { + if( mpi::comm().rank() == 0 ) { array::ArrayView sp = array::make_view(spf); EXPECT( eckit::types::is_approximately_equal( sp(0), 4., 0.001 )); for( size_t jp=0; jp gpg = array::make_view(gpfg); for( size_t jp=0; jp spf( trans.spectralCoefficients() ); std::vector gpf( grid.size() ); - if( parallel::mpi::comm().size() == 1 ) { + if( mpi::comm().size() == 1 ) { EXPECT_NO_THROW( trans.invtrans( 1, spf.data(), gpf.data(), option::global() ) ); EXPECT_NO_THROW( trans.dirtrans( 1, gpf.data(), spf.data(), option::global() ) ); diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index d4b0cf973..034ab7d02 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -42,7 +42,7 @@ namespace test { struct AtlasTransEnvironment : public AtlasTestEnvironment { AtlasTransEnvironment(int argc, char * argv[]) : AtlasTestEnvironment(argc, argv) { - if( parallel::mpi::comm().size() == 1 ) + if( mpi::comm().size() == 1 ) trans_use_mpi(false); trans_init(); } @@ -114,7 +114,7 @@ CASE( "test_invtrans_ifsStyle" ) std::vector init_gp (trans.trans()->ngptot); std::vector init_sp (trans.trans()->nspec2); std::vector nfrom(nfld,1); - if( parallel::mpi::comm().rank()==0) { + if( mpi::comm().rank()==0) { double beta = M_PI*0.5; rotated_flow_magnitude(g,init_gpg.data(),beta); } diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index d528b8a68..98142c043 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -52,7 +52,7 @@ namespace test { struct AtlasTransEnvironment : public AtlasTestEnvironment { AtlasTransEnvironment(int argc, char * argv[]) : AtlasTestEnvironment(argc, argv) { - if( parallel::mpi::comm().size() == 1 ) + if( mpi::comm().size() == 1 ) trans_use_mpi(false); trans_init(); } diff --git a/src/tests/util/test_metadata.cc b/src/tests/util/test_metadata.cc index 2efa11456..c206dc318 100644 --- a/src/tests/util/test_metadata.cc +++ b/src/tests/util/test_metadata.cc @@ -26,7 +26,7 @@ namespace test { CASE( "test_broadcast_to_self" ) { Metadata metadata; - if( parallel::mpi::comm().rank() == 0 ) + if( mpi::comm().rank() == 0 ) { metadata.set("paramID",128); } @@ -46,7 +46,7 @@ CASE( "test_broadcast_to_other" ) { size_t root = 0; Metadata global; - if( parallel::mpi::comm().rank() == root ) + if( mpi::comm().rank() == root ) { global.set("paramID",128); } @@ -60,7 +60,7 @@ CASE( "test_broadcast_to_other" ) if( local.has("paramID") ) EXPECT( local.get("paramID") == 128 ); - if( parallel::mpi::comm().rank() != root ) + if( mpi::comm().rank() != root ) EXPECT( ! global.has("paramID") ); } From cb09fa46a43f257990a8076fec3fbc20f86f76c0 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 13 Feb 2018 17:10:28 +0000 Subject: [PATCH 334/355] ATLAS-103 Disable this work for now. It seems slower. Revisit in future. --- src/atlas/mesh/actions/BuildHalo.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index b2c405688..4374bd113 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -46,10 +46,6 @@ // #define ATLAS_103 // #define ATLAS_103_SORT -#ifndef ATLAS_103 -#warning ATLAS-103 proposed solution deactivated -#endif - using atlas::mesh::detail::accumulate_facets; using atlas::mesh::detail::PeriodicTransform; using atlas::util::UniqueLonLat; @@ -1083,6 +1079,7 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& } #else ATLAS_TRACE(); + Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); if( periodic ) { // add own rank to neighbours to allow periodicity with self (pole caps) @@ -1100,7 +1097,7 @@ void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& int sendcnt = send.size(); ATLAS_TRACE_MPI(ISEND) { for( size_t to : neighbours ) { - count_requests.push_back( comm.iSend( sendcnt, to, counts_tag ) ); + counts_requests.push_back( comm.iSend( sendcnt, to, counts_tag ) ); } } From 38144d8cb63772d57f1e7a6e2a056cc6aa397bbe Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Tue, 13 Feb 2018 18:32:31 +0000 Subject: [PATCH 335/355] Update clangformat --- .clang-format | 106 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/.clang-format b/.clang-format index 2e78ae782..795d4f81a 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,106 @@ +--- Language: Cpp -BasedOnStyle: Google +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: true + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: AfterColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true ColumnLimit: 120 -AccessModifierOffset: -2 \ No newline at end of file +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeCategories: + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: false +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 4 +UseTab: Never +... From 3b36ddca8168317909d6dba347c26687a7d31b10 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 14 Feb 2018 14:50:31 +0000 Subject: [PATCH 336/355] Fix insane sanity checks --- src/atlas/mesh/actions/BuildParallelFields.cc | 43 ++++++++++++------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index b0e6479cc..382967023 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -376,15 +376,6 @@ Field& build_edges_partition( Mesh& mesh ) const mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); const mesh::HybridElements::Connectivity& edge_to_elem = edges.cell_connectivity(); - std::shared_ptr< array::ArrayView > is_pole_edge; - bool has_pole_edges = false; - if( edges.has_field("is_pole_edge") ) - { - has_pole_edges = true; - is_pole_edge = std::shared_ptr< array::ArrayView > ( - new array::ArrayView( array::make_view( edges.field("is_pole_edge") ) ) ); - } - array::ArrayView node_part = array::make_view( nodes.partition() ); array::ArrayView xy = array::make_view( nodes.xy() ); array::ArrayView flags = array::make_view( nodes.field("flags") ); @@ -501,7 +492,14 @@ Field& build_edges_partition( Mesh& mesh ) } -// // Sanity check + // Sanity check + std::shared_ptr< array::ArrayView > is_pole_edge; + bool has_pole_edges = false; + if( edges.has_field("is_pole_edge") ) + { + has_pole_edges = true; + is_pole_edge = std::shared_ptr>( new array::ArrayView(array::make_view( edges.field("is_pole_edge") ) ) ); + } int insane = 0; for( size_t jedge=0; jedge Date: Wed, 14 Feb 2018 16:54:12 +0000 Subject: [PATCH 337/355] Fix atlas with GridTools-CUDA backend --- src/atlas/array/gridtools/GridToolsArray.cc | 6 +++--- src/atlas/mesh/Connectivity.cc | 19 ++++++++++++++++++- src/atlas/mesh/Connectivity.h | 1 + .../atlas-benchmark-sorting.cc | 4 ++-- src/sandbox/fortran_acc_fields/CMakeLists.txt | 1 + .../interpolation-fortran/CMakeLists.txt | 1 + src/tests/AtlasTestEnvironment.h | 4 +++- src/tests/array/test_array_kernel.cu | 3 +-- src/tests/array/test_svector_kernel.cu | 3 +-- src/tests/array/test_vector_kernel.cu | 3 +-- src/tests/mesh/test_connectivity.cc | 13 ++++++++----- src/tests/mesh/test_connectivity_kernel.cu | 3 +-- 12 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 6488321e6..7fe7dcc01 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -297,9 +297,9 @@ bool ArrayT::accMap() const { template void ArrayT::insert(size_t idx1, size_t size1) { - if( hostNeedsUpdate() ) { - cloneFromDevice(); - } + //if( hostNeedsUpdate() ) { + // cloneFromDevice(); + //} if( not hasDefaultLayout() ) NOTIMP; diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index da2ebd837..fd0b45d23 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -214,7 +214,24 @@ void IrregularConnectivityImpl::add(const BlockConnectivityImpl &block ) { if( !owns_ ) throw eckit::AssertionFailed("HybridConnectivity must be owned to be resized directly"); bool fortran_array = FORTRAN_BASE; - add(block.rows(),block.cols(),block.data(),fortran_array); + const size_t rows = block.rows(); + const size_t cols = block.cols(); + const idx_t* values = block.data(); + + std::vector values_vector; + if( ! block.values_view_.contiguous() ) { + values_vector.resize(rows*cols); + values = values_vector.data(); + for( int i=0, c=0; i glb_idx(points_to_edit.size()); diff --git a/src/sandbox/fortran_acc_fields/CMakeLists.txt b/src/sandbox/fortran_acc_fields/CMakeLists.txt index ee9f0eb7f..d6970a647 100644 --- a/src/sandbox/fortran_acc_fields/CMakeLists.txt +++ b/src/sandbox/fortran_acc_fields/CMakeLists.txt @@ -11,6 +11,7 @@ if( ATLAS_HAVE_ACC ) TARGET atlas-acc-fields SOURCES atlas-acc-fields.F90 LIBS atlas_f + LINKER_LANGUAGE Fortran NOINSTALL ) target_compile_options( atlas-acc-fields PUBLIC ${ACC_Fortran_FLAGS} ) diff --git a/src/sandbox/interpolation-fortran/CMakeLists.txt b/src/sandbox/interpolation-fortran/CMakeLists.txt index 195f8eada..2846fd963 100644 --- a/src/sandbox/interpolation-fortran/CMakeLists.txt +++ b/src/sandbox/interpolation-fortran/CMakeLists.txt @@ -10,6 +10,7 @@ ecbuild_add_executable( TARGET atlas-interpolation-fortran SOURCES atlas-interpolation-fortran.F90 LIBS atlas_f + LINKER_LANGUAGE Fortran NOINSTALL ) diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index b35064d0a..e9e75c036 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -30,9 +30,11 @@ #include "atlas/util/Config.h" #include "atlas/runtime/trace/StopWatch.h" +#ifdef ATLAS_TEST_MPI #ifdef ECKIT_HAVE_MPI #include #endif +#endif namespace atlas { namespace test { @@ -107,7 +109,7 @@ static double ATLAS_MPI_BARRIER_TIMEOUT() { static int barrier_timeout( double seconds ) { -#ifdef ECKIT_HAVE_MPI +#ifdef ATLAS_TEST_MPI if( eckit::mpi::comm().size() > 1 ) { MPI_Request req; MPI_Ibarrier( MPI_COMM_WORLD, &req ); diff --git a/src/tests/array/test_array_kernel.cu b/src/tests/array/test_array_kernel.cu index 0f732ef91..a553837e0 100644 --- a/src/tests/array/test_array_kernel.cu +++ b/src/tests/array/test_array_kernel.cu @@ -106,6 +106,5 @@ CASE( "test_array_loop" ) } int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/array/test_svector_kernel.cu b/src/tests/array/test_svector_kernel.cu index d43ee26da..200d1a46e 100644 --- a/src/tests/array/test_svector_kernel.cu +++ b/src/tests/array/test_svector_kernel.cu @@ -106,6 +106,5 @@ CASE( "test_svector_resize" ) } int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/array/test_vector_kernel.cu b/src/tests/array/test_vector_kernel.cu index 9cbdcdd27..ef00c4b0b 100644 --- a/src/tests/array/test_vector_kernel.cu +++ b/src/tests/array/test_vector_kernel.cu @@ -104,6 +104,5 @@ CASE( "test_vector_kernel" ) } int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_connectivity.cc b/src/tests/mesh/test_connectivity.cc index 80d3c84b8..901211c91 100644 --- a/src/tests/mesh/test_connectivity.cc +++ b/src/tests/mesh/test_connectivity.cc @@ -316,12 +316,14 @@ Log::info() << "\n\n\ntest_multi_block_connectivity_add_block\n" << std::endl; 1,3,76,4,3 } ); EXPECT( conn1.owns() ); - ATLAS_DEBUG_HERE(); + EXPECT(conn1(0,2) == 1 ); + EXPECT(conn1(1,1) == 4 ); + EXPECT(conn1(2,2) == 76 ); + mbc.add(conn1); } EXPECT( mbc.blocks() == 1 ); - EXPECT(mbc(0,2) == 1 ); EXPECT(mbc(1,1) == 4 ); EXPECT(mbc(2,2) == 76 ); @@ -336,8 +338,10 @@ Log::info() << "\n\n\ntest_multi_block_connectivity_add_block\n" << std::endl; 61,41, 11,31 }); EXPECT( conn2.owns() ); + EXPECT(conn2(0,0) == 31); + EXPECT(conn2(1,1) == 41); + EXPECT(conn2(2,0) == 11); - ATLAS_DEBUG_HERE(); mbc.add(conn2); } EXPECT( mbc.blocks() == 2 ); @@ -356,13 +360,12 @@ Log::info() << "\n\n\ntest_multi_block_connectivity_add_block\n" << std::endl; EXPECT(mbc(1, 1,1) == 41 ); EXPECT(mbc(1, 2,0) == 11 ); - ATLAS_DEBUG_HERE(); const BlockConnectivity& b0 = mbc.block(0); EXPECT( b0.owns() == false ); EXPECT(b0(0,2) == 1 ); EXPECT(b0(1,1) == 4 ); EXPECT(b0(2,2) == 76 ); - ATLAS_DEBUG_HERE(); + const BlockConnectivity& b1 = mbc.block(1); EXPECT( b1.owns() == false ); EXPECT(b1(0,0) == 31 ); diff --git a/src/tests/mesh/test_connectivity_kernel.cu b/src/tests/mesh/test_connectivity_kernel.cu index 1915e3cfa..bc37b4ed2 100644 --- a/src/tests/mesh/test_connectivity_kernel.cu +++ b/src/tests/mesh/test_connectivity_kernel.cu @@ -193,6 +193,5 @@ CASE( "test_multiblock_connectivity" ) } int main(int argc, char **argv) { - atlas::test::AtlasTestEnvironment env( argc, argv ); - return run_tests ( argc, argv, false ); + return atlas::test::run( argc, argv ); } From 0c2b817cf3692b9bcfe13520d32d36d426c935b0 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Wed, 14 Feb 2018 17:54:43 +0000 Subject: [PATCH 338/355] ATLAS-148 Fix mesh-generator for 3D RegularLonLat grids --- .../meshgenerator/StructuredMeshGenerator.cc | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 5392bfd2d..7333e88d8 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -363,7 +363,7 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co if( ipN1 == endN && ipS1 == endS ) break; #if DEBUG_OUTPUT - Log::info(Here()) << "-------\n"; + Log::info() << "-------\n"; #endif //ASSERT(offset.at(latN)+ipN1 < parts.size()); @@ -490,7 +490,7 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co #if DEBUG_OUTPUT - DEBUG_VAR(jelem); + ATLAS_DEBUG_VAR(jelem); #endif auto elem = lat_elems_view.slice(jelem,Range::all()); @@ -646,7 +646,7 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co } region.nb_lat_elems.at(jlat) = jelem; #if DEBUG_OUTPUT - DEBUG_VAR(region.nb_lat_elems.at(jlat)); + ATLAS_DEBUG_VAR(region.nb_lat_elems.at(jlat)); #endif if( region.nb_lat_elems.at(jlat) == 0 && latN == size_t(region.north) ) { ++region.north; @@ -695,7 +695,7 @@ void StructuredMeshGenerator::generate_region(const grid::StructuredGrid& rg, co throw Exception("Trying to generate mesh with too many partitions. Reduce the number of partitions.",Here()); } #if DEBUG_OUTPUT - DEBUG("End of generate_region()"); + ATLAS_DEBUG("End of generate_region()"); #endif } @@ -773,23 +773,23 @@ void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, cons if ( remove_periodic_ghost_points ) { for(size_t jlat = 0; jlat < rg.ny(); ++jlat) { - if( rg.nx(jlat) > 0 ) + if( region.lat_end[jlat] >= rg.nx(jlat) ) --nnodes; } } #if DEBUG_OUTPUT - DEBUG_VAR(include_periodic_ghost_points); - DEBUG_VAR(include_north_pole); - DEBUG_VAR(include_south_pole); - DEBUG_VAR(three_dimensional); - DEBUG_VAR(patch_north_pole); - DEBUG_VAR(patch_south_pole); - DEBUG_VAR(rg.npts()); - DEBUG_VAR(nnodes); - DEBUG_VAR(ntriags); - DEBUG_VAR(nquads); - DEBUG_VAR(options.get("ghost_at_end")); + ATLAS_DEBUG_VAR(include_periodic_ghost_points); + ATLAS_DEBUG_VAR(include_north_pole); + ATLAS_DEBUG_VAR(include_south_pole); + ATLAS_DEBUG_VAR(three_dimensional); + ATLAS_DEBUG_VAR(patch_north_pole); + ATLAS_DEBUG_VAR(patch_south_pole); + ATLAS_DEBUG_VAR(rg.size()); + ATLAS_DEBUG_VAR(nnodes); + ATLAS_DEBUG_VAR(ntriags); + ATLAS_DEBUG_VAR(nquads); + ATLAS_DEBUG_VAR(options.get("ghost_at_end")); #endif From 7a6f7120caafac2d6637e17c4012178097047703 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 09:26:07 +0000 Subject: [PATCH 339/355] Edit clang-format configuration --- .clang-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index 795d4f81a..24bfb9984 100644 --- a/.clang-format +++ b/.clang-format @@ -98,7 +98,7 @@ SpacesBeforeTrailingComments: 2 SpacesInAngles: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false -SpacesInParentheses: false +SpacesInParentheses: true SpacesInSquareBrackets: false Standard: Auto TabWidth: 4 From 84fa8df208bb8ad6fcdd435dc391c56b61b95f9c Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 09:56:28 +0000 Subject: [PATCH 340/355] WARNING: Applied clangformat for first time. All files touched --- .../fields/fields-on-grid.cc | 60 +- .../core-functionalities/fields/fields.cc | 64 +- .../functionspace/NodeColumns.cc | 142 +- .../functionspace/StructuredColumns.cc | 68 +- .../Structured/global-grids-Structured.cc | 20 +- .../Unstructured/global-grids-Unstructured.cc | 368 +- .../meshes/meshes-Structured.cc | 17 +- .../installation/hello-world.cc | 5 +- src/apps/atlas-benchmark.cc | 938 ++-- src/apps/atlas-gaussian-latitudes.cc | 185 +- src/apps/atlas-gmsh-extract.cc | 379 +- src/apps/atlas-grids.cc | 308 +- src/apps/atlas-loadbalance.cc | 175 +- src/apps/atlas-meshgen.cc | 399 +- src/apps/atlas.cc | 111 +- src/atlas/array.h | 5 +- src/atlas/array/Array.h | 211 +- src/atlas/array/ArrayIdx.h | 35 +- src/atlas/array/ArrayLayout.h | 34 +- src/atlas/array/ArrayShape.h | 47 +- src/atlas/array/ArraySpec.cc | 190 +- src/atlas/array/ArraySpec.h | 70 +- src/atlas/array/ArrayStrides.h | 40 +- src/atlas/array/ArrayUtil.cc | 14 +- src/atlas/array/ArrayUtil.h | 80 +- src/atlas/array/ArrayView.h | 9 +- src/atlas/array/ArrayViewDefs.h | 37 +- src/atlas/array/ArrayViewUtil.h | 46 +- src/atlas/array/DataType.h | 373 +- src/atlas/array/IndexView.h | 12 +- src/atlas/array/LocalView.cc | 75 +- src/atlas/array/LocalView.h | 172 +- src/atlas/array/MakeView.h | 2 +- src/atlas/array/Range.h | 89 +- src/atlas/array/SVector.h | 160 +- src/atlas/array/Table.cc | 349 +- src/atlas/array/Table.h | 186 +- src/atlas/array/TableView.cc | 89 +- src/atlas/array/TableView.h | 277 +- src/atlas/array/Vector.h | 193 +- src/atlas/array/gridtools/GPUClonable.h | 29 +- src/atlas/array/gridtools/GridToolsArray.cc | 728 +-- .../array/gridtools/GridToolsArrayHelpers.h | 378 +- .../array/gridtools/GridToolsArrayView.cc | 148 +- .../array/gridtools/GridToolsArrayView.h | 108 +- .../array/gridtools/GridToolsDataStore.h | 58 +- .../array/gridtools/GridToolsIndexView.cc | 26 +- .../array/gridtools/GridToolsIndexView.h | 126 +- .../array/gridtools/GridToolsMakeView.cc | 277 +- src/atlas/array/gridtools/GridToolsMakeView.h | 17 +- src/atlas/array/gridtools/GridToolsTraits.h | 23 +- src/atlas/array/helpers/ArrayAssigner.h | 126 +- src/atlas/array/helpers/ArrayInitializer.h | 222 +- src/atlas/array/helpers/ArraySlicer.h | 402 +- src/atlas/array/helpers/ArrayWriter.h | 59 +- src/atlas/array/native/NativeArray.cc | 465 +- src/atlas/array/native/NativeArrayView.cc | 70 +- src/atlas/array/native/NativeArrayView.h | 184 +- src/atlas/array/native/NativeDataStore.h | 104 +- src/atlas/array/native/NativeIndexView.cc | 33 +- src/atlas/array/native/NativeIndexView.h | 162 +- src/atlas/array/native/NativeMakeView.cc | 183 +- src/atlas/array_fwd.h | 27 +- src/atlas/domain.h | 3 +- src/atlas/domain/Domain.cc | 48 +- src/atlas/domain/Domain.h | 131 +- src/atlas/domain/detail/Domain.cc | 23 +- src/atlas/domain/detail/Domain.h | 55 +- src/atlas/domain/detail/EmptyDomain.cc | 26 +- src/atlas/domain/detail/EmptyDomain.h | 17 +- src/atlas/domain/detail/GlobalDomain.cc | 36 +- src/atlas/domain/detail/GlobalDomain.h | 23 +- src/atlas/domain/detail/RectangularDomain.cc | 146 +- src/atlas/domain/detail/RectangularDomain.h | 32 +- src/atlas/domain/detail/ZonalBandDomain.cc | 85 +- src/atlas/domain/detail/ZonalBandDomain.h | 29 +- src/atlas/field.h | 3 +- src/atlas/field/Field.cc | 388 +- src/atlas/field/Field.h | 244 +- src/atlas/field/FieldCreator.cc | 137 +- src/atlas/field/FieldCreator.h | 70 +- src/atlas/field/FieldCreatorArraySpec.cc | 81 +- src/atlas/field/FieldCreatorArraySpec.h | 30 +- src/atlas/field/FieldCreatorIFS.cc | 96 +- src/atlas/field/FieldCreatorIFS.h | 26 +- src/atlas/field/FieldSet.cc | 161 +- src/atlas/field/FieldSet.h | 170 +- src/atlas/field/State.cc | 352 +- src/atlas/field/State.h | 145 +- src/atlas/field/detail/FieldImpl.cc | 663 +-- src/atlas/field/detail/FieldImpl.h | 427 +- src/atlas/functionspace.h | 9 +- src/atlas/functionspace/EdgeColumns.cc | 1192 ++--- src/atlas/functionspace/EdgeColumns.h | 142 +- src/atlas/functionspace/FunctionSpace.cc | 139 +- src/atlas/functionspace/FunctionSpace.h | 145 +- src/atlas/functionspace/NodeColumns.cc | 3447 +++++++------ src/atlas/functionspace/NodeColumns.h | 622 +-- .../functionspace/NodeColumnsInterface.cc | 2169 ++++----- .../functionspace/NodeColumnsInterface.h | 347 +- src/atlas/functionspace/PointCloud.cc | 76 +- src/atlas/functionspace/PointCloud.h | 45 +- src/atlas/functionspace/Spectral.cc | 645 ++- src/atlas/functionspace/Spectral.h | 182 +- src/atlas/functionspace/StructuredColumns.cc | 1494 +++--- src/atlas/functionspace/StructuredColumns.h | 428 +- src/atlas/grid.h | 5 +- src/atlas/grid/Distribution.cc | 116 +- src/atlas/grid/Distribution.h | 134 +- src/atlas/grid/Grid.cc | 127 +- src/atlas/grid/Grid.h | 355 +- src/atlas/grid/Iterator.h | 61 +- src/atlas/grid/Partitioner.cc | 102 +- src/atlas/grid/Partitioner.h | 48 +- src/atlas/grid/Spacing.cc | 33 +- src/atlas/grid/Spacing.h | 71 +- src/atlas/grid/detail/grid/Gaussian.cc | 291 +- src/atlas/grid/detail/grid/Gaussian.h | 8 +- src/atlas/grid/detail/grid/Grid.cc | 90 +- src/atlas/grid/detail/grid/Grid.h | 74 +- src/atlas/grid/detail/grid/GridBuilder.cc | 242 +- src/atlas/grid/detail/grid/GridBuilder.h | 39 +- src/atlas/grid/detail/grid/LonLat.cc | 364 +- src/atlas/grid/detail/grid/Regional.cc | 410 +- src/atlas/grid/detail/grid/Structured.cc | 975 ++-- src/atlas/grid/detail/grid/Structured.h | 456 +- src/atlas/grid/detail/grid/Unstructured.cc | 114 +- src/atlas/grid/detail/grid/Unstructured.h | 266 +- .../partitioner/CheckerboardPartitioner.cc | 371 +- .../partitioner/CheckerboardPartitioner.h | 40 +- .../partitioner/EqualRegionsPartitioner.cc | 711 +-- .../partitioner/EqualRegionsPartitioner.h | 108 +- .../partitioner/MatchingMeshPartitioner.h | 33 +- .../MatchingMeshPartitionerBruteForce.cc | 258 +- .../MatchingMeshPartitionerBruteForce.h | 27 +- .../MatchingMeshPartitionerLonLatPolygon.cc | 62 +- .../MatchingMeshPartitionerLonLatPolygon.h | 38 +- ...MatchingMeshPartitionerSphericalPolygon.cc | 60 +- .../MatchingMeshPartitionerSphericalPolygon.h | 38 +- .../grid/detail/partitioner/Partitioner.cc | 162 +- .../grid/detail/partitioner/Partitioner.h | 79 +- .../detail/partitioner/TransPartitioner.cc | 118 +- .../detail/partitioner/TransPartitioner.h | 30 +- .../grid/detail/pl/classic_gaussian/N.cc | 22 +- src/atlas/grid/detail/pl/classic_gaussian/N.h | 98 +- .../grid/detail/pl/classic_gaussian/N1024.cc | 1087 +---- .../grid/detail/pl/classic_gaussian/N128.cc | 139 +- .../grid/detail/pl/classic_gaussian/N1280.cc | 1358 +----- .../grid/detail/pl/classic_gaussian/N16.cc | 20 +- .../grid/detail/pl/classic_gaussian/N160.cc | 173 +- .../grid/detail/pl/classic_gaussian/N1600.cc | 1697 +------ .../grid/detail/pl/classic_gaussian/N200.cc | 214 +- .../grid/detail/pl/classic_gaussian/N2000.cc | 2120 +------- .../grid/detail/pl/classic_gaussian/N24.cc | 29 +- .../grid/detail/pl/classic_gaussian/N256.cc | 272 +- .../grid/detail/pl/classic_gaussian/N32.cc | 37 +- .../grid/detail/pl/classic_gaussian/N320.cc | 341 +- .../grid/detail/pl/classic_gaussian/N400.cc | 426 +- .../grid/detail/pl/classic_gaussian/N4000.cc | 4255 +---------------- .../grid/detail/pl/classic_gaussian/N48.cc | 54 +- .../grid/detail/pl/classic_gaussian/N512.cc | 544 +-- .../grid/detail/pl/classic_gaussian/N576.cc | 610 +-- .../grid/detail/pl/classic_gaussian/N64.cc | 71 +- .../grid/detail/pl/classic_gaussian/N640.cc | 677 +-- .../grid/detail/pl/classic_gaussian/N80.cc | 88 +- .../grid/detail/pl/classic_gaussian/N800.cc | 846 +--- .../grid/detail/pl/classic_gaussian/N8000.cc | 1322 ++--- .../grid/detail/pl/classic_gaussian/N96.cc | 105 +- .../pl/classic_gaussian/PointsPerLatitude.cc | 28 +- .../pl/classic_gaussian/PointsPerLatitude.h | 18 +- .../grid/detail/spacing/CustomSpacing.cc | 63 +- src/atlas/grid/detail/spacing/CustomSpacing.h | 37 +- src/atlas/grid/detail/spacing/FocusSpacing.cc | 86 +- src/atlas/grid/detail/spacing/FocusSpacing.h | 15 +- .../grid/detail/spacing/GaussianSpacing.cc | 86 +- .../grid/detail/spacing/GaussianSpacing.h | 29 +- .../grid/detail/spacing/LinearSpacing.cc | 161 +- src/atlas/grid/detail/spacing/LinearSpacing.h | 63 +- src/atlas/grid/detail/spacing/Spacing.cc | 12 +- src/atlas/grid/detail/spacing/Spacing.h | 33 +- .../grid/detail/spacing/gaussian/Latitudes.cc | 193 +- .../grid/detail/spacing/gaussian/Latitudes.h | 38 +- src/atlas/grid/detail/spacing/gaussian/N.cc | 22 +- src/atlas/grid/detail/spacing/gaussian/N.h | 100 +- .../grid/detail/spacing/gaussian/N1024.cc | 380 +- .../grid/detail/spacing/gaussian/N128.cc | 52 +- .../grid/detail/spacing/gaussian/N1280.cc | 474 +- src/atlas/grid/detail/spacing/gaussian/N16.cc | 24 +- .../grid/detail/spacing/gaussian/N160.cc | 63 +- .../grid/detail/spacing/gaussian/N1600.cc | 589 ++- .../grid/detail/spacing/gaussian/N200.cc | 78 +- .../grid/detail/spacing/gaussian/N2000.cc | 735 ++- src/atlas/grid/detail/spacing/gaussian/N24.cc | 33 +- .../grid/detail/spacing/gaussian/N256.cc | 99 +- src/atlas/grid/detail/spacing/gaussian/N32.cc | 43 +- .../grid/detail/spacing/gaussian/N320.cc | 122 +- .../grid/detail/spacing/gaussian/N400.cc | 151 +- .../grid/detail/spacing/gaussian/N4000.cc | 1463 +++--- src/atlas/grid/detail/spacing/gaussian/N48.cc | 60 +- .../grid/detail/spacing/gaussian/N512.cc | 193 +- .../grid/detail/spacing/gaussian/N576.cc | 216 +- src/atlas/grid/detail/spacing/gaussian/N64.cc | 28 +- .../grid/detail/spacing/gaussian/N640.cc | 239 +- src/atlas/grid/detail/spacing/gaussian/N80.cc | 34 +- .../grid/detail/spacing/gaussian/N800.cc | 298 +- .../grid/detail/spacing/gaussian/N8000.cc | 2919 +++++------ src/atlas/grid/detail/spacing/gaussian/N96.cc | 40 +- src/atlas/interpolation.h | 3 +- src/atlas/interpolation/Interpolation.cc | 67 +- src/atlas/interpolation/Interpolation.h | 59 +- src/atlas/interpolation/Vector2D.h | 65 +- src/atlas/interpolation/Vector3D.h | 75 +- src/atlas/interpolation/element/Quad3D.cc | 55 +- src/atlas/interpolation/element/Quad3D.h | 44 +- src/atlas/interpolation/element/Triag3D.cc | 69 +- src/atlas/interpolation/element/Triag3D.h | 47 +- .../interpolation/method/FiniteElement.cc | 245 +- .../interpolation/method/FiniteElement.h | 62 +- src/atlas/interpolation/method/Intersect.cc | 10 +- src/atlas/interpolation/method/Intersect.h | 38 +- .../method/KNearestNeighbours.cc | 91 +- .../interpolation/method/KNearestNeighbours.h | 30 +- .../method/KNearestNeighboursBase.cc | 50 +- .../method/KNearestNeighboursBase.h | 21 +- src/atlas/interpolation/method/Method.cc | 112 +- src/atlas/interpolation/method/Method.h | 66 +- .../interpolation/method/NearestNeighbour.cc | 64 +- .../interpolation/method/NearestNeighbour.h | 30 +- src/atlas/interpolation/method/PointIndex3.cc | 47 +- src/atlas/interpolation/method/PointIndex3.h | 41 +- src/atlas/interpolation/method/PointSet.cc | 68 +- src/atlas/interpolation/method/PointSet.h | 117 +- src/atlas/interpolation/method/Ray.cc | 36 +- src/atlas/interpolation/method/Ray.h | 25 +- src/atlas/library/Library.cc | 295 +- src/atlas/library/Library.h | 27 +- src/atlas/library/config.h | 21 +- src/atlas/mesh.h | 13 +- src/atlas/mesh/Connectivity.cc | 1359 +++--- src/atlas/mesh/Connectivity.h | 755 +-- src/atlas/mesh/ElementType.cc | 72 +- src/atlas/mesh/ElementType.h | 267 +- src/atlas/mesh/Elements.cc | 369 +- src/atlas/mesh/Elements.h | 339 +- src/atlas/mesh/Halo.cc | 29 +- src/atlas/mesh/Halo.h | 31 +- src/atlas/mesh/HybridElements.cc | 630 ++- src/atlas/mesh/HybridElements.h | 366 +- src/atlas/mesh/IsGhostNode.h | 32 +- src/atlas/mesh/Mesh.cc | 21 +- src/atlas/mesh/Mesh.h | 79 +- src/atlas/mesh/Nodes.cc | 625 +-- src/atlas/mesh/Nodes.h | 260 +- src/atlas/mesh/PartitionPolygon.cc | 275 +- src/atlas/mesh/PartitionPolygon.h | 39 +- src/atlas/mesh/actions/BuildCellCentres.cc | 99 +- src/atlas/mesh/actions/BuildCellCentres.h | 14 +- src/atlas/mesh/actions/BuildConvexHull3D.cc | 130 +- src/atlas/mesh/actions/BuildConvexHull3D.h | 14 +- src/atlas/mesh/actions/BuildDualMesh.cc | 747 ++- src/atlas/mesh/actions/BuildDualMesh.h | 18 +- src/atlas/mesh/actions/BuildEdges.cc | 665 ++- src/atlas/mesh/actions/BuildEdges.h | 30 +- src/atlas/mesh/actions/BuildHalo.cc | 2142 ++++----- src/atlas/mesh/actions/BuildHalo.h | 36 +- src/atlas/mesh/actions/BuildParallelFields.cc | 1384 +++--- src/atlas/mesh/actions/BuildParallelFields.h | 36 +- .../mesh/actions/BuildPeriodicBoundaries.cc | 338 +- .../mesh/actions/BuildPeriodicBoundaries.h | 16 +- src/atlas/mesh/actions/BuildStatistics.cc | 375 +- src/atlas/mesh/actions/BuildStatistics.h | 20 +- src/atlas/mesh/actions/BuildTorusXYZField.cc | 80 +- src/atlas/mesh/actions/BuildTorusXYZField.h | 28 +- src/atlas/mesh/actions/BuildXYZField.cc | 60 +- src/atlas/mesh/actions/BuildXYZField.h | 29 +- src/atlas/mesh/actions/ExtendNodesGlobal.cc | 77 +- src/atlas/mesh/actions/ExtendNodesGlobal.h | 23 +- .../mesh/actions/WriteLoadBalanceReport.cc | 364 +- .../mesh/actions/WriteLoadBalanceReport.h | 14 +- src/atlas/mesh/detail/AccumulateFacets.cc | 213 +- src/atlas/mesh/detail/AccumulateFacets.h | 33 +- src/atlas/mesh/detail/MeshImpl.cc | 184 +- src/atlas/mesh/detail/MeshImpl.h | 93 +- src/atlas/mesh/detail/MeshIntf.cc | 70 +- src/atlas/mesh/detail/MeshIntf.h | 28 +- src/atlas/mesh/detail/PartitionGraph.cc | 237 +- src/atlas/mesh/detail/PartitionGraph.h | 42 +- src/atlas/mesh/detail/PeriodicTransform.h | 76 +- src/atlas/meshgenerator.h | 3 +- .../meshgenerator/DelaunayMeshGenerator.cc | 128 +- .../meshgenerator/DelaunayMeshGenerator.h | 28 +- src/atlas/meshgenerator/MeshGenerator.cc | 345 +- src/atlas/meshgenerator/MeshGenerator.h | 108 +- .../meshgenerator/RegularMeshGenerator.cc | 870 ++-- .../meshgenerator/RegularMeshGenerator.h | 37 +- .../meshgenerator/StructuredMeshGenerator.cc | 2133 ++++----- .../meshgenerator/StructuredMeshGenerator.h | 73 +- src/atlas/numerics/Method.cc | 30 +- src/atlas/numerics/Method.h | 19 +- src/atlas/numerics/Nabla.cc | 237 +- src/atlas/numerics/Nabla.h | 118 +- src/atlas/numerics/fvm/Method.cc | 254 +- src/atlas/numerics/fvm/Method.h | 88 +- src/atlas/numerics/fvm/Nabla.cc | 748 ++- src/atlas/numerics/fvm/Nabla.h | 45 +- src/atlas/option.h | 3 +- src/atlas/option/Options.cc | 72 +- src/atlas/option/Options.h | 41 +- src/atlas/option/TransOptions.cc | 63 +- src/atlas/option/TransOptions.h | 33 +- src/atlas/output/Gmsh.cc | 366 +- src/atlas/output/Gmsh.h | 111 +- src/atlas/output/Output.cc | 258 +- src/atlas/output/Output.h | 185 +- src/atlas/output/detail/GmshIO.cc | 1668 +++---- src/atlas/output/detail/GmshIO.h | 184 +- src/atlas/output/detail/PointCloudIO.cc | 553 +-- src/atlas/output/detail/PointCloudIO.h | 201 +- src/atlas/parallel/Checksum.cc | 142 +- src/atlas/parallel/Checksum.h | 291 +- src/atlas/parallel/GatherScatter.cc | 648 ++- src/atlas/parallel/GatherScatter.h | 955 ++-- src/atlas/parallel/HaloExchange.cc | 310 +- src/atlas/parallel/HaloExchange.h | 384 +- src/atlas/parallel/HaloExchangeCUDA.h | 25 +- src/atlas/parallel/HaloExchangeImpl.h | 127 +- src/atlas/parallel/mpi/Buffer.h | 56 +- src/atlas/parallel/mpi/Statistics.h | 86 +- src/atlas/parallel/mpi/mpi.cc | 12 +- src/atlas/parallel/mpi/mpi.h | 9 +- src/atlas/parallel/omp/omp.cc | 88 +- src/atlas/parallel/omp/omp.h | 56 +- src/atlas/projection.h | 3 +- src/atlas/projection/Projection.cc | 20 +- src/atlas/projection/Projection.h | 74 +- .../projection/detail/LambertProjection.cc | 136 +- .../projection/detail/LambertProjection.h | 31 +- .../projection/detail/LonLatProjection.cc | 22 +- .../projection/detail/LonLatProjection.h | 44 +- .../projection/detail/MercatorProjection.cc | 90 +- .../projection/detail/MercatorProjection.h | 36 +- src/atlas/projection/detail/ProjectionImpl.cc | 47 +- src/atlas/projection/detail/ProjectionImpl.h | 74 +- .../projection/detail/SchmidtProjection.cc | 68 +- .../projection/detail/SchmidtProjection.h | 18 +- src/atlas/runtime/AtlasTool.cc | 313 +- src/atlas/runtime/AtlasTool.h | 62 +- src/atlas/runtime/ErrorHandling.cc | 288 +- src/atlas/runtime/ErrorHandling.h | 155 +- src/atlas/runtime/Log.cc | 21 +- src/atlas/runtime/Log.h | 89 +- src/atlas/runtime/Trace.h | 21 +- src/atlas/runtime/trace/Barriers.cc | 69 +- src/atlas/runtime/trace/Barriers.h | 19 +- src/atlas/runtime/trace/CallStack.cc | 20 +- src/atlas/runtime/trace/CallStack.h | 40 +- src/atlas/runtime/trace/Logging.cc | 44 +- src/atlas/runtime/trace/Logging.h | 20 +- src/atlas/runtime/trace/Nesting.cc | 67 +- src/atlas/runtime/trace/Nesting.h | 15 +- src/atlas/runtime/trace/StopWatch.h | 59 +- src/atlas/runtime/trace/Timings.cc | 542 +-- src/atlas/runtime/trace/Timings.h | 31 +- src/atlas/runtime/trace/TraceT.h | 119 +- src/atlas/trans/Trans.cc | 286 +- src/atlas/trans/Trans.h | 393 +- src/atlas/trans/VorDivToUV.cc | 179 +- src/atlas/trans/VorDivToUV.h | 121 +- src/atlas/trans/ifs/TransIFS.cc | 2633 +++++----- src/atlas/trans/ifs/TransIFS.h | 734 ++- src/atlas/trans/ifs/TransIFSNodeColumns.cc | 37 +- src/atlas/trans/ifs/TransIFSNodeColumns.h | 31 +- .../trans/ifs/TransIFSStructuredColumns.cc | 39 +- .../trans/ifs/TransIFSStructuredColumns.h | 31 +- src/atlas/trans/ifs/VorDivToUVIFS.cc | 74 +- src/atlas/trans/ifs/VorDivToUVIFS.h | 60 +- src/atlas/trans/local/FourierTransforms.cc | 81 +- src/atlas/trans/local/FourierTransforms.h | 35 +- src/atlas/trans/local/LegendrePolynomials.cc | 130 +- src/atlas/trans/local/LegendrePolynomials.h | 22 +- src/atlas/trans/local/LegendreTransforms.cc | 58 +- src/atlas/trans/local/LegendreTransforms.h | 28 +- src/atlas/trans/local/TransLocal.cc | 373 +- src/atlas/trans/local/TransLocal.h | 120 +- src/atlas/trans/local/VorDivToUVLocal.cc | 216 +- src/atlas/trans/local/VorDivToUVLocal.h | 58 +- src/atlas/util/Bitflags.h | 64 +- src/atlas/util/Checksum.cc | 62 +- src/atlas/util/Checksum.h | 16 +- src/atlas/util/Config.cc | 433 +- src/atlas/util/Config.h | 201 +- src/atlas/util/Constants.h | 10 +- src/atlas/util/CoordinateEnums.h | 18 +- src/atlas/util/Earth.cc | 221 +- src/atlas/util/Earth.h | 62 +- src/atlas/util/GaussianLatitudes.cc | 22 +- src/atlas/util/GaussianLatitudes.h | 34 +- src/atlas/util/LonLatMicroDeg.h | 85 +- src/atlas/util/LonLatPolygon.cc | 69 +- src/atlas/util/LonLatPolygon.h | 28 +- src/atlas/util/Metadata.cc | 498 +- src/atlas/util/Metadata.h | 122 +- src/atlas/util/MicroDeg.h | 16 +- src/atlas/util/Point.h | 121 +- src/atlas/util/Polygon.cc | 161 +- src/atlas/util/Polygon.h | 56 +- src/atlas/util/Rotation.cc | 332 +- src/atlas/util/Rotation.h | 48 +- src/atlas/util/SphericalPolygon.cc | 57 +- src/atlas/util/SphericalPolygon.h | 28 +- src/atlas/util/Unique.h | 357 +- src/atlas/util/detail/BlackMagic.h | 108 +- src/atlas/util/detail/Cache.h | 71 +- src/atlas/util/detail/Debug.h | 132 +- src/atlas_acc_support/atlas_acc_map_data.h | 2 +- src/atlas_f/internals/Library.cc | 63 +- src/atlas_f/internals/Library.h | 19 +- src/atlas_f/internals/atlas_read_file.cc | 75 +- src/atlas_f/internals/atlas_read_file.h | 5 +- .../atlas-benchmark-build-halo.cc | 143 +- .../atlas-benchmark-sorting.cc | 384 +- src/sandbox/fortran_modinc/mod1.h | 6 +- src/sandbox/fortran_modinc/mod2.h | 6 +- .../atlas-grid-distribution.cc | 268 +- src/sandbox/interpolation/PartitionedMesh.cc | 64 +- src/sandbox/interpolation/PartitionedMesh.h | 27 +- .../atlas-parallel-interpolation.cc | 280 +- src/tests/AtlasTestEnvironment.h | 188 +- src/tests/TestMeshes.h | 24 +- src/tests/array/test_array.cc | 814 ++-- src/tests/array/test_array_slicer.cc | 580 ++- src/tests/array/test_array_view_util.cc | 44 +- src/tests/array/test_svector.cc | 36 +- src/tests/array/test_table.cc | 360 +- src/tests/functionspace/test_functionspace.cc | 1050 ++-- src/tests/functionspace/test_pointcloud.cc | 39 +- .../functionspace/test_structuredcolumns.cc | 370 +- src/tests/grid/test_domain.cc | 147 +- src/tests/grid/test_field.cc | 166 +- src/tests/grid/test_grid_ptr.cc | 299 +- src/tests/grid/test_grids.cc | 195 +- src/tests/grid/test_rotation.cc | 345 +- src/tests/grid/test_state.cc | 253 +- src/tests/interpolation/test_Quad3D.cc | 260 +- .../test_interpolation_finite_element.cc | 113 +- src/tests/io/test_gmsh.cc | 23 +- src/tests/io/test_pointcloud_io.cc | 658 ++- src/tests/mesh/test_accumulate_facets.cc | 1269 ++--- .../mesh/test_cgal_mesh_gen_from_points.cc | 24 +- src/tests/mesh/test_connectivity.cc | 836 ++-- src/tests/mesh/test_distmesh.cc | 161 +- src/tests/mesh/test_elements.cc | 697 ++- src/tests/mesh/test_halo.cc | 555 +-- src/tests/mesh/test_ll.cc | 22 +- src/tests/mesh/test_meshgen3d.cc | 36 +- src/tests/mesh/test_parfields.cc | 329 +- src/tests/mesh/test_rgg.cc | 809 ++-- src/tests/mesh/test_shapefunctions.cc | 1239 +++-- src/tests/numerics/test_fvm_nabla.cc | 532 +-- src/tests/parallel/test_gather.cc | 782 ++- src/tests/parallel/test_haloexchange.cc | 988 ++-- src/tests/trans/test_trans.cc | 757 ++- src/tests/trans/test_trans_invtrans_grad.cc | 265 +- src/tests/trans/test_transgeneral.cc | 1156 +++-- src/tests/util/test_earth.cc | 190 +- src/tests/util/test_flags.cc | 41 +- src/tests/util/test_footprint.cc | 80 +- src/tests/util/test_indexview.cc | 283 +- src/tests/util/test_metadata.cc | 56 +- src/tests/util/test_polygon.cc | 139 +- src/tests/util/test_vector.cc | 41 +- 471 files changed, 47208 insertions(+), 67816 deletions(-) diff --git a/doc/user-guide/core-functionalities/fields/fields-on-grid.cc b/doc/user-guide/core-functionalities/fields/fields-on-grid.cc index 64f65562d..18e0c84ee 100644 --- a/doc/user-guide/core-functionalities/fields/fields-on-grid.cc +++ b/doc/user-guide/core-functionalities/fields/fields-on-grid.cc @@ -4,56 +4,48 @@ #include "atlas/library/Library.h" #include "atlas/runtime/Log.h" - +using atlas::Field; using atlas::Log; -using atlas::array::make_shape; using atlas::array::make_datatype; +using atlas::array::make_shape; using atlas::array::make_view; -using atlas::Field; using atlas::grid::StructuredGrid; -int main(int argc, char *argv[]) -{ - atlas::Library::instance().initialise(argc, argv); +int main( int argc, char* argv[] ) { + atlas::Library::instance().initialise( argc, argv ); - int jnode = 0; - const double rpi = 2.0 * asin(1.0); + int jnode = 0; + const double rpi = 2.0 * asin( 1.0 ); const double deg2rad = rpi / 180.; - const double zlatc = 0.0 * rpi; - const double zlonc = 1.0 * rpi; - const double zrad = 2.0 * rpi / 9.0; - double zdist, zlon, zlat; + const double zlatc = 0.0 * rpi; + const double zlonc = 1.0 * rpi; + const double zrad = 2.0 * rpi / 9.0; + double zdist, zlon, zlat; - StructuredGrid grid("N32"); + StructuredGrid grid( "N32" ); const size_t nb_nodes = grid.size(); - Field field_pressure( "pressure", make_datatype(), make_shape(nb_nodes) ); + Field field_pressure( "pressure", make_datatype(), make_shape( nb_nodes ) ); - auto pressure = make_view(field_pressure); - for (size_t jlat =0; jlat < grid.ny(); ++jlat) - { - zlat = grid.y(jlat); + auto pressure = make_view( field_pressure ); + for ( size_t jlat = 0; jlat < grid.ny(); ++jlat ) { + zlat = grid.y( jlat ); zlat = zlat * deg2rad; - for (size_t jlon =0; jlon < grid.nx(jlat); ++jlon) - { - zlon = grid.x(jlon,jlat); - zlon = zlon * deg2rad; - zdist = 2.0 * sqrt((cos(zlat) * sin((zlon-zlonc)/2)) * - (cos(zlat) * sin((zlon-zlonc)/2)) + - sin((zlat-zlatc)/2) * sin((zlat-zlatc)/2)); - - pressure(jnode) = 0.0; - if (zdist < zrad) - { - pressure(jnode) = 0.5 * (1. + cos(rpi*zdist/zrad)); - } - jnode = jnode+1; + for ( size_t jlon = 0; jlon < grid.nx( jlat ); ++jlon ) { + zlon = grid.x( jlon, jlat ); + zlon = zlon * deg2rad; + zdist = 2.0 * sqrt( ( cos( zlat ) * sin( ( zlon - zlonc ) / 2 ) ) * + ( cos( zlat ) * sin( ( zlon - zlonc ) / 2 ) ) + + sin( ( zlat - zlatc ) / 2 ) * sin( ( zlat - zlatc ) / 2 ) ); + + pressure( jnode ) = 0.0; + if ( zdist < zrad ) { pressure( jnode ) = 0.5 * ( 1. + cos( rpi * zdist / zrad ) ); } + jnode = jnode + 1; } } Log::info() << "==========================================" << std::endl; - Log::info() << "memory field_pressure = " - << field_pressure.bytes() * 1.e-9 << " GB" << std::endl; + Log::info() << "memory field_pressure = " << field_pressure.bytes() * 1.e-9 << " GB" << std::endl; Log::info() << "==========================================" << std::endl; atlas::Library::instance().finalise(); diff --git a/doc/user-guide/core-functionalities/fields/fields.cc b/doc/user-guide/core-functionalities/fields/fields.cc index 601f4ce65..5f8cea3e3 100644 --- a/doc/user-guide/core-functionalities/fields/fields.cc +++ b/doc/user-guide/core-functionalities/fields/fields.cc @@ -5,66 +5,62 @@ #include "atlas/runtime/Log.h" #include "atlas/util/Metadata.h" -using atlas::Log; using atlas::Field; using atlas::FieldSet; +using atlas::Log; using atlas::array::ArrayView; -using atlas::array::make_shape; using atlas::array::make_datatype; +using atlas::array::make_shape; using atlas::array::make_view; -int main(int argc, char *argv[]) -{ - atlas::Library::instance().initialise(argc, argv); +int main( int argc, char* argv[] ) { + atlas::Library::instance().initialise( argc, argv ); // Define fields - Field field_pressure ( "pressure", make_datatype(), make_shape(100) ); - Field field_wind ( "wind", make_datatype(), make_shape(100,2) ); + Field field_pressure( "pressure", make_datatype(), make_shape( 100 ) ); + Field field_wind( "wind", make_datatype(), make_shape( 100, 2 ) ); // Access field data - auto pressure = make_view(field_pressure); - auto wind = make_view(field_wind); + auto pressure = make_view( field_pressure ); + auto wind = make_view( field_wind ); // Assign values to fields - for (size_t jnode = 0; jnode < 100; ++jnode) - { - pressure(jnode) = 101325.0; - wind(jnode,0) = 0.01 + double(jnode); - wind(jnode,1) = 0.02 + double(jnode); + for ( size_t jnode = 0; jnode < 100; ++jnode ) { + pressure( jnode ) = 101325.0; + wind( jnode, 0 ) = 0.01 + double( jnode ); + wind( jnode, 1 ) = 0.02 + double( jnode ); } // Add info to fields std::string unitsP, unitsW; - field_pressure.metadata().set("units", "[Pa]"); - field_pressure.metadata().get("units", unitsP); - field_wind .metadata().set("units", "[m/s]"); - field_wind .metadata().get("units", unitsW); + field_pressure.metadata().set( "units", "[Pa]" ); + field_pressure.metadata().get( "units", unitsP ); + field_wind.metadata().set( "units", "[m/s]" ); + field_wind.metadata().get( "units", unitsW ); // Define fieldSet FieldSet fields; - fields.add(field_pressure); // Add field_pressure to fieldSet - fields.add(field_wind); // Add field_wind to fieldSet + fields.add( field_pressure ); // Add field_pressure to fieldSet + fields.add( field_wind ); // Add field_wind to fieldSet // Retrieve field from fieldSet - Field field_pressure2 = fields.field("pressure"); - Field field_wind2 = fields.field("wind"); + Field field_pressure2 = fields.field( "pressure" ); + Field field_wind2 = fields.field( "wind" ); // Print some useful info - Log::info() << "name = " << field_wind.name() << std::endl; - Log::info() << "size = " << field_wind.size() << std::endl; - Log::info() << "units = " << unitsW << std::endl; - Log::info() << "rank = " << field_wind.rank() << std::endl; - Log::info() << "shape = " << field_wind.shape(0) << " " - << field_wind.shape(1) << std::endl; - Log::info() << "memory = " << field_wind.bytes() - << " bytes" << std::endl; - Log::info() << "type = " << field_wind.datatype().str() << std::endl; + Log::info() << "name = " << field_wind.name() << std::endl; + Log::info() << "size = " << field_wind.size() << std::endl; + Log::info() << "units = " << unitsW << std::endl; + Log::info() << "rank = " << field_wind.rank() << std::endl; + Log::info() << "shape = " << field_wind.shape( 0 ) << " " << field_wind.shape( 1 ) << std::endl; + Log::info() << "memory = " << field_wind.bytes() << " bytes" << std::endl; + Log::info() << "type = " << field_wind.datatype().str() << std::endl; Log::info() << "kind = " << field_wind.datatype().kind() << std::endl; // Print some values - Log::info() << "pressure(9) = " << pressure(9) << std::endl; - Log::info() << "wind(9, 0) = " << wind(9,0) << std::endl; - Log::info() << "wind(9, 1) = " << wind(9,1) << std::endl; + Log::info() << "pressure(9) = " << pressure( 9 ) << std::endl; + Log::info() << "wind(9, 0) = " << wind( 9, 0 ) << std::endl; + Log::info() << "wind(9, 1) = " << wind( 9, 1 ) << std::endl; atlas::Library::instance().finalise(); diff --git a/doc/user-guide/core-functionalities/functionspace/NodeColumns.cc b/doc/user-guide/core-functionalities/functionspace/NodeColumns.cc index 62885a9d5..df3bb57a8 100644 --- a/doc/user-guide/core-functionalities/functionspace/NodeColumns.cc +++ b/doc/user-guide/core-functionalities/functionspace/NodeColumns.cc @@ -1,33 +1,32 @@ -#include "atlas/library/Library.h" -#include "atlas/runtime/Log.h" -#include "atlas/grid/Grid.h" -#include "atlas/field/Field.h" +#include "atlas/functionspace/NodeColumns.h" #include "atlas/array/ArrayView.h" +#include "atlas/field/Field.h" +#include "atlas/grid/Grid.h" +#include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/output/Gmsh.h" -#include "atlas/functionspace/NodeColumns.h" +#include "atlas/runtime/Log.h" using namespace atlas; -using atlas::array::make_view; using atlas::array::make_shape; +using atlas::array::make_view; using atlas::functionspace::NodeColumns; using atlas::gidx_t; using atlas::grid::StructuredGrid; using atlas::meshgenerator::StructuredMeshGenerator; using atlas::output::Gmsh; -int main(int argc, char *argv[]) -{ - atlas::Library::instance().initialise(argc, argv); +int main( int argc, char* argv[] ) { + atlas::Library::instance().initialise( argc, argv ); // Generate global classic reduced Gaussian grid StructuredGrid grid( "N32" ); // Generate mesh associated to structured grid StructuredMeshGenerator meshgenerator; - Mesh mesh = meshgenerator.generate(grid); + Mesh mesh = meshgenerator.generate( grid ); // Number of nodes in the mesh // (different from number of points on a grid!) @@ -37,80 +36,74 @@ int main(int argc, char *argv[]) size_t nb_levels = 10; // Generate functionspace associated to mesh - NodeColumns fs_nodes( mesh, option::levels(nb_levels) | option::halo(1) ); + NodeColumns fs_nodes( mesh, option::levels( nb_levels ) | option::halo( 1 ) ); // Note on field generation - Field field_scalar1 = fs_nodes.createField(option::name("scalar1") | option::levels(false) ); - Field field_scalar2 = fs_nodes.createField(option::name("scalar2") ); - Field field_vector1 = fs_nodes.createField(option::name("vector1") | option::levels(false) | option::variables(2)); - Field field_vector2 = fs_nodes.createField(option::name("vector2") | option::variables(2) ); - Field field_tensor1 = fs_nodes.createField(option::name("tensor1") | option::levels(false) | option::variables(2*2)); - Field field_tensor2 = fs_nodes.createField(option::name("tensor2") | option::variables(2*2) ); + Field field_scalar1 = fs_nodes.createField( option::name( "scalar1" ) | option::levels( false ) ); + Field field_scalar2 = fs_nodes.createField( option::name( "scalar2" ) ); + Field field_vector1 = + fs_nodes.createField( option::name( "vector1" ) | option::levels( false ) | option::variables( 2 ) ); + Field field_vector2 = fs_nodes.createField( option::name( "vector2" ) | option::variables( 2 ) ); + Field field_tensor1 = fs_nodes.createField( option::name( "tensor1" ) | option::levels( false ) | + option::variables( 2 * 2 ) ); + Field field_tensor2 = fs_nodes.createField( option::name( "tensor2" ) | option::variables( 2 * 2 ) ); /* .... */ // Variables for scalar1 field definition - const double rpi = 2.0 * asin(1.0); + const double rpi = 2.0 * asin( 1.0 ); const double deg2rad = rpi / 180.; - const double zlatc = 0.0 * rpi; - const double zlonc = 1.0 * rpi; - const double zrad = 2.0 * rpi / 9.0; - double zdist, zlon, zlat; + const double zlatc = 0.0 * rpi; + const double zlonc = 1.0 * rpi; + const double zrad = 2.0 * rpi / 9.0; + double zdist, zlon, zlat; // Retrieve lonlat field to calculate scalar1 function - auto scalar1 = make_view( field_scalar1 ); - auto lonlat = make_view( mesh.nodes().lonlat() ); - for (size_t jnode = 0; jnode < nb_nodes; ++jnode) - { - zlon = lonlat(jnode,0) * deg2rad; - zlat = lonlat(jnode,1) * deg2rad; - - zdist = 2.0 * sqrt((cos(zlat) * sin((zlon-zlonc)/2)) * - (cos(zlat) * sin((zlon-zlonc)/2)) + - sin((zlat-zlatc)/2) * sin((zlat-zlatc)/2)); - - scalar1(jnode) = 0.0; - if (zdist < zrad) - { - scalar1(jnode) = 0.5 * (1. + cos(rpi*zdist/zrad)); - } + auto scalar1 = make_view( field_scalar1 ); + auto lonlat = make_view( mesh.nodes().lonlat() ); + for ( size_t jnode = 0; jnode < nb_nodes; ++jnode ) { + zlon = lonlat( jnode, 0 ) * deg2rad; + zlat = lonlat( jnode, 1 ) * deg2rad; + + zdist = + 2.0 * sqrt( ( cos( zlat ) * sin( ( zlon - zlonc ) / 2 ) ) * ( cos( zlat ) * sin( ( zlon - zlonc ) / 2 ) ) + + sin( ( zlat - zlatc ) / 2 ) * sin( ( zlat - zlatc ) / 2 ) ); + + scalar1( jnode ) = 0.0; + if ( zdist < zrad ) { scalar1( jnode ) = 0.5 * ( 1. + cos( rpi * zdist / zrad ) ); } } // Write mesh and field in gmsh format for visualization - Gmsh gmsh("scalar1.msh"); - gmsh.write(mesh); - gmsh.write(field_scalar1); + Gmsh gmsh( "scalar1.msh" ); + gmsh.write( mesh ); + gmsh.write( field_scalar1 ); /* .... */ // Halo exchange - fs_nodes.haloExchange(field_scalar1); - std::string checksum = fs_nodes.checksum(field_scalar1); + fs_nodes.haloExchange( field_scalar1 ); + std::string checksum = fs_nodes.checksum( field_scalar1 ); Log::info() << checksum << std::endl; // Create a global field - Field field_global = fs_nodes.createField( field_scalar1, option::name("global") | option::global() ); + Field field_global = fs_nodes.createField( field_scalar1, option::name( "global" ) | option::global() ); // Gather operation - fs_nodes.gather(field_scalar1, field_global); + fs_nodes.gather( field_scalar1, field_global ); - Log::info() << "local nodes = " - << fs_nodes.nb_nodes() << std::endl; - Log::info() << "grid points = " - << grid.size() << std::endl; - Log::info() << "field_global.shape(0) = " - << field_global.shape(0) << std::endl; + Log::info() << "local nodes = " << fs_nodes.nb_nodes() << std::endl; + Log::info() << "grid points = " << grid.size() << std::endl; + Log::info() << "field_global.shape(0) = " << field_global.shape( 0 ) << std::endl; // Scatter operation - fs_nodes.scatter(field_global, field_scalar1); + fs_nodes.scatter( field_global, field_scalar1 ); // Halo exchange and checksum - fs_nodes.haloExchange(field_scalar1); - checksum = fs_nodes.checksum(field_scalar1); - Log::info() << field_scalar1.name() << " checksum : " - << checksum << std::endl; + fs_nodes.haloExchange( field_scalar1 ); + checksum = fs_nodes.checksum( field_scalar1 ); + Log::info() << field_scalar1.name() << " checksum : " << checksum << std::endl; // FieldSet checksum FieldSet fields; - fields.add(field_scalar1); - fields.add(field_vector1); - checksum = fs_nodes.checksum(fields); + fields.add( field_scalar1 ); + fields.add( field_vector1 ); + checksum = fs_nodes.checksum( fields ); Log::info() << "FieldSet checksum : " << checksum << std::endl; /* .... */ @@ -121,39 +114,36 @@ int main(int argc, char *argv[]) double min, max, sum, mean, stddev; // Minimum and maximum - fs_nodes.minimum(field_scalar1, min); - fs_nodes.maximum(field_scalar1, max); + fs_nodes.minimum( field_scalar1, min ); + fs_nodes.maximum( field_scalar1, max ); Log::info() << "min: " << min << std::endl; Log::info() << "max: " << max << std::endl; // Minimum and maximum + location - fs_nodes.minimumAndLocation(field_scalar1, min, gidx_min); - fs_nodes.maximumAndLocation(field_scalar1, max, gidx_max); - Log::info() << "min: " << min << ", " + fs_nodes.minimumAndLocation( field_scalar1, min, gidx_min ); + fs_nodes.maximumAndLocation( field_scalar1, max, gidx_max ); + Log::info() << "min: " << min << ", " << "global_id = " << gidx_min << std::endl; - Log::info() << "max: " << max << ", " + Log::info() << "max: " << max << ", " << "global_id = " << gidx_max << std::endl; // Summation - fs_nodes.sum(field_scalar1, sum, N); - Log::info() << "sum: " << sum - << ", nb_nodes = " << N << std::endl; + fs_nodes.sum( field_scalar1, sum, N ); + Log::info() << "sum: " << sum << ", nb_nodes = " << N << std::endl; // Order independent (from partitioning) summation - fs_nodes.orderIndependentSum(field_scalar1, sum, N); - Log::info() << "oi_sum: " << sum - << ", nb_nodes = " << N << std::endl; + fs_nodes.orderIndependentSum( field_scalar1, sum, N ); + Log::info() << "oi_sum: " << sum << ", nb_nodes = " << N << std::endl; // Average over number of nodes - fs_nodes.mean(field_scalar1, mean, N); + fs_nodes.mean( field_scalar1, mean, N ); Log::info() << "mean: " << mean << ", nb_nodes = " << N << std::endl; // Average and standard deviation over number of nodes - fs_nodes.meanAndStandardDeviation( - field_scalar1, mean, stddev, N); - Log::info() << "mean = " << mean << ", " + fs_nodes.meanAndStandardDeviation( field_scalar1, mean, stddev, N ); + Log::info() << "mean = " << mean << ", " << "std_deviation: " << stddev << ", " - << "nb_nodes: " << N << std::endl; + << "nb_nodes: " << N << std::endl; atlas::Library::instance().finalise(); diff --git a/doc/user-guide/core-functionalities/functionspace/StructuredColumns.cc b/doc/user-guide/core-functionalities/functionspace/StructuredColumns.cc index 5fdd12adc..15a7086d8 100644 --- a/doc/user-guide/core-functionalities/functionspace/StructuredColumns.cc +++ b/doc/user-guide/core-functionalities/functionspace/StructuredColumns.cc @@ -1,71 +1,65 @@ #include -#include "atlas/library/Library.h" -#include "atlas/grid.h" -#include "atlas/field.h" #include "atlas/array.h" +#include "atlas/field.h" +#include "atlas/functionspace.h" +#include "atlas/grid.h" +#include "atlas/library/Library.h" #include "atlas/mesh.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/output/Gmsh.h" -#include "atlas/functionspace.h" #include "atlas/util/CoordinateEnums.h" using namespace atlas; -using atlas::meshgenerator::StructuredMeshGenerator; -using atlas::functionspace::StructuredColumns; using atlas::array::ArrayView; using atlas::array::make_view; +using atlas::functionspace::StructuredColumns; +using atlas::meshgenerator::StructuredMeshGenerator; using atlas::output::Gmsh; -int main(int argc, char *argv[]) -{ - atlas::Library::instance().initialise(argc, argv); +int main( int argc, char* argv[] ) { + atlas::Library::instance().initialise( argc, argv ); // Generate global reduced grid Grid grid( "N32" ); // Generate functionspace associated to grid - StructuredColumns fs(grid); + StructuredColumns fs( grid ); // Variables for scalar1 field definition const double deg2rad = M_PI / 180.; - const double zlatc = 0.0 * M_PI; - const double zlonc = 1.0 * M_PI; - const double zrad = 2.0 * M_PI / 9.0; - int jnode = 0; + const double zlatc = 0.0 * M_PI; + const double zlonc = 1.0 * M_PI; + const double zrad = 2.0 * M_PI / 9.0; + int jnode = 0; // Calculate scalar function - Field field_scalar1 = fs.createField(option::name("scalar1")); - auto xy = make_view(fs.xy()); - auto scalar1 = make_view(field_scalar1); + Field field_scalar1 = fs.createField( option::name( "scalar1" ) ); + auto xy = make_view( fs.xy() ); + auto scalar1 = make_view( field_scalar1 ); - for (idx_t j = fs.j_begin(); j < fs.j_end(); ++j) - { - for (idx_t i = fs.i_begin(j); i < fs.i_end(j); ++i) - { - double zlon = xy( fs.index(i,j), XX ) * deg2rad; - double zlat = xy( fs.index(i,j), YY ) * deg2rad; - double zdist = 2.0 * std::sqrt((cos(zlat) * std::sin((zlon-zlonc)/2.)) * - (std::cos(zlat) * std::sin((zlon-zlonc)/2.)) + - std::sin((zlat-zlatc)/2.) * std::sin((zlat-zlatc)/2.)); + for ( idx_t j = fs.j_begin(); j < fs.j_end(); ++j ) { + for ( idx_t i = fs.i_begin( j ); i < fs.i_end( j ); ++i ) { + double zlon = xy( fs.index( i, j ), XX ) * deg2rad; + double zlat = xy( fs.index( i, j ), YY ) * deg2rad; + double zdist = 2.0 * std::sqrt( ( cos( zlat ) * std::sin( ( zlon - zlonc ) / 2. ) ) * + ( std::cos( zlat ) * std::sin( ( zlon - zlonc ) / 2. ) ) + + std::sin( ( zlat - zlatc ) / 2. ) * std::sin( ( zlat - zlatc ) / 2. ) ); - scalar1(jnode) = 0.0; - if (zdist < zrad) - { - scalar1(jnode) = 0.5 * (1. + std::cos(M_PI*zdist/zrad)); - } + scalar1( jnode ) = 0.0; + if ( zdist < zrad ) { scalar1( jnode ) = 0.5 * ( 1. + std::cos( M_PI * zdist / zrad ) ); } ++jnode; } } // Write field { - // Generate visualisation mesh associated to grid - StructuredMeshGenerator meshgenerator; - Mesh mesh = meshgenerator.generate(grid); + // Generate visualisation mesh associated to grid + StructuredMeshGenerator meshgenerator; + Mesh mesh = meshgenerator.generate( grid ); - Gmsh gmsh("scalar1.msh"); - gmsh.write(mesh); - gmsh.write(field_scalar1); + Gmsh gmsh( "scalar1.msh" ); + gmsh.write( mesh ); + gmsh.write( field_scalar1 ); } Library::instance().finalise(); diff --git a/doc/user-guide/core-functionalities/global-grids/Structured/global-grids-Structured.cc b/doc/user-guide/core-functionalities/global-grids/Structured/global-grids-Structured.cc index c1f094200..e18b9f59b 100644 --- a/doc/user-guide/core-functionalities/global-grids/Structured/global-grids-Structured.cc +++ b/doc/user-guide/core-functionalities/global-grids/Structured/global-grids-Structured.cc @@ -1,25 +1,21 @@ -#include "atlas/library/Library.h" #include "atlas/grid/Grid.h" +#include "atlas/library/Library.h" #include "atlas/runtime/Log.h" using atlas::Log; using atlas::grid::StructuredGrid; -int main(int argc, char *argv[]) -{ - atlas::Library::instance().initialise(argc, argv); +int main( int argc, char* argv[] ) { + atlas::Library::instance().initialise( argc, argv ); StructuredGrid grid( "O32" ); - + Log::info() << "nx first = " << grid.nx().front() << std::endl; - Log::info() << "ny = " << grid.ny() << std::endl; - Log::info() << "npts = " << grid.size() << std::endl; - Log::info() << "xy = " << grid.xy(0,0) << std::endl; - Log::info() << "lonlat = " << grid.lonlat(0,0) << std::endl; + Log::info() << "ny = " << grid.ny() << std::endl; + Log::info() << "npts = " << grid.size() << std::endl; + Log::info() << "xy = " << grid.xy( 0, 0 ) << std::endl; + Log::info() << "lonlat = " << grid.lonlat( 0, 0 ) << std::endl; atlas::Library::instance().finalise(); return 0; } - - - diff --git a/doc/user-guide/core-functionalities/global-grids/Unstructured/global-grids-Unstructured.cc b/doc/user-guide/core-functionalities/global-grids/Unstructured/global-grids-Unstructured.cc index cc54397f9..57e2a55c2 100644 --- a/doc/user-guide/core-functionalities/global-grids/Unstructured/global-grids-Unstructured.cc +++ b/doc/user-guide/core-functionalities/global-grids/Unstructured/global-grids-Unstructured.cc @@ -1,204 +1,200 @@ -#include "atlas/library/Library.h" #include "atlas/grid.h" +#include "atlas/library/Library.h" #include "atlas/meshgenerator.h" +#include "atlas/output/Gmsh.h" #include "atlas/runtime/Log.h" #include "atlas/util/Point.h" -#include "atlas/output/Gmsh.h" using namespace atlas; using atlas::grid::UnstructuredGrid; -using atlas::util::Config; using atlas::output::Gmsh; +using atlas::util::Config; -int main(int argc, char *argv[]) -{ - atlas::Library::instance().initialise(argc, argv); +int main( int argc, char* argv[] ) { + atlas::Library::instance().initialise( argc, argv ); - Grid grid = UnstructuredGrid( { - {180,0}, - {90,0}, - {-90,0}, - {0,90}, - {0,-90}, - {0,0}, - {18,0}, - {36,0}, - {54,0}, - {72,0}, - {108,0}, - {126,0}, - {144,0}, - {162,0}, - {-162,0}, - {-144,0}, - {-126,0}, - {-108,0}, - {-72,0}, - {-54,0}, - {-36,0}, - {-18,0}, - {0,18}, - {0,36}, - {0,54}, - {0,72}, - {180,72}, - {180,54}, - {180,36}, - {180,18}, - {180,-18}, - {180,-36}, - {180,-54}, - {180,-72}, - {0,-72}, - {0,-54}, - {0,-36}, - {0,-18}, - {90,18}, - {90,36}, - {90,54}, - {90,72}, - {-90,72}, - {-90,54}, - {-90,36}, - {-90,18}, - {-90,-18}, - {-90,-36}, - {-90,-54}, - {-90,-72}, - {90,-72}, - {90,-54}, - {90,-36}, - {90,-18}, - {123.974,-58.6741}, - {154.087,-16.9547}, - {154.212,-58.8675}, - {114.377,-41.9617}, - {125.567,-23.5133}, - {137.627,-40.8524}, - {106.162,-24.5874}, - {158.508,-38.55}, - {137.826,-72.8109}, - {142.103,-26.799}, - {138.256,-13.8871}, - {168.39,-24.3266}, - {168.954,-12.0094}, - {117.333,-12.35}, - {102.254,-11.1537}, - {120.307,59.7167}, - {107.196,26.0167}, - {144.768,28.3721}, - {150.891,60.0343}, - {164.566,25.5053}, - {116.851,14.0295}, - {124.84,28.3978}, - {157.901,42.042}, - {111.41,43.1056}, - {134.333,44.6677}, - {103.277,11.707}, - {135.358,73.2119}, - {135.349,14.2311}, - {153.48,13.386}, - {168.071,11.5344}, - {-162.99,26.3775}, - {-147.519,56.1313}, - {-122.579,27.4824}, - {-117.909,59.2376}, - {-104.052,27.3616}, - {-153.107,14.9717}, - {-110.833,41.7436}, - {-144.847,32.8534}, - {-161.546,42.1031}, - {-129.866,44.5201}, - {-133.883,72.4163}, - {-166.729,11.8907}, - {-135.755,15.2529}, - {-106.063,14.4869}, - {-119.452,11.7037}, - {-146.026,-58.6741}, - {-115.913,-16.9547}, - {-115.788,-58.8675}, - {-155.623,-41.9617}, - {-144.433,-23.5133}, - {-132.373,-40.8524}, - {-163.838,-24.5874}, - {-111.492,-38.55}, - {-132.174,-72.8109}, - {-127.897,-26.799}, - {-131.744,-13.8871}, - {-101.61,-24.3266}, - {-101.046,-12.0094}, - {-152.667,-12.35}, - {-167.746,-11.1537}, - {-14.0127,-27.2963}, - {-59.193,-57.0815}, - {-56.465,-19.5751}, - {-27.056,-59.3077}, - {-57.124,-35.9752}, - {-33.4636,-28.3914}, - {-74.8037,-46.8602}, - {-40.089,-45.1376}, - {-74.8149,-28.3136}, - {-21.3072,-42.2177}, - {-44.0778,-72.6353}, - {-19.6969,-12.8527}, - {-40.1318,-12.1601}, - {-72.691,-11.4129}, - {-56.0261,58.6741}, - {-25.9127,16.9547}, - {-25.7876,58.8675}, - {-65.6229,41.9617}, - {-54.4335,23.5133}, - {-42.373,40.8524}, - {-73.838,24.5874}, - {-21.4917,38.55}, - {-42.1744,72.8109}, - {-37.8974,26.799}, - {-41.7437,13.8871}, - {-11.6095,24.3266}, - {-11.0459,12.0094}, - {-62.667,12.35}, - {-77.7456,11.1537}, - {30.3071,59.7167}, - {17.1956,26.0167}, - {54.7676,28.3721}, - {60.8915,60.0343}, - {74.5657,25.5053}, - {26.8506,14.0295}, - {34.8398,28.3978}, - {67.9014,42.042}, - {21.41,43.1056}, - {44.3335,44.6677}, - {13.2772,11.707}, - {45.3579,73.2119}, - {45.3492,14.2311}, - {63.4799,13.386}, - {78.0714,11.5344}, - {17.01,-26.3775}, - {32.4806,-56.1313}, - {57.4213,-27.4824}, - {62.0912,-59.2376}, - {75.9483,-27.3616}, - {26.893,-14.9717}, - {69.1672,-41.7436}, - {35.1527,-32.8534}, - {18.4543,-42.1031}, - {50.1344,-44.5201}, - {46.1172,-72.4163}, - {13.2711,-11.8907}, - {44.2448,-15.2529}, - {73.9368,-14.4869}, - {60.5478,-11.7037} - }); + Grid grid = UnstructuredGrid( {{180, 0}, + {90, 0}, + {-90, 0}, + {0, 90}, + {0, -90}, + {0, 0}, + {18, 0}, + {36, 0}, + {54, 0}, + {72, 0}, + {108, 0}, + {126, 0}, + {144, 0}, + {162, 0}, + {-162, 0}, + {-144, 0}, + {-126, 0}, + {-108, 0}, + {-72, 0}, + {-54, 0}, + {-36, 0}, + {-18, 0}, + {0, 18}, + {0, 36}, + {0, 54}, + {0, 72}, + {180, 72}, + {180, 54}, + {180, 36}, + {180, 18}, + {180, -18}, + {180, -36}, + {180, -54}, + {180, -72}, + {0, -72}, + {0, -54}, + {0, -36}, + {0, -18}, + {90, 18}, + {90, 36}, + {90, 54}, + {90, 72}, + {-90, 72}, + {-90, 54}, + {-90, 36}, + {-90, 18}, + {-90, -18}, + {-90, -36}, + {-90, -54}, + {-90, -72}, + {90, -72}, + {90, -54}, + {90, -36}, + {90, -18}, + {123.974, -58.6741}, + {154.087, -16.9547}, + {154.212, -58.8675}, + {114.377, -41.9617}, + {125.567, -23.5133}, + {137.627, -40.8524}, + {106.162, -24.5874}, + {158.508, -38.55}, + {137.826, -72.8109}, + {142.103, -26.799}, + {138.256, -13.8871}, + {168.39, -24.3266}, + {168.954, -12.0094}, + {117.333, -12.35}, + {102.254, -11.1537}, + {120.307, 59.7167}, + {107.196, 26.0167}, + {144.768, 28.3721}, + {150.891, 60.0343}, + {164.566, 25.5053}, + {116.851, 14.0295}, + {124.84, 28.3978}, + {157.901, 42.042}, + {111.41, 43.1056}, + {134.333, 44.6677}, + {103.277, 11.707}, + {135.358, 73.2119}, + {135.349, 14.2311}, + {153.48, 13.386}, + {168.071, 11.5344}, + {-162.99, 26.3775}, + {-147.519, 56.1313}, + {-122.579, 27.4824}, + {-117.909, 59.2376}, + {-104.052, 27.3616}, + {-153.107, 14.9717}, + {-110.833, 41.7436}, + {-144.847, 32.8534}, + {-161.546, 42.1031}, + {-129.866, 44.5201}, + {-133.883, 72.4163}, + {-166.729, 11.8907}, + {-135.755, 15.2529}, + {-106.063, 14.4869}, + {-119.452, 11.7037}, + {-146.026, -58.6741}, + {-115.913, -16.9547}, + {-115.788, -58.8675}, + {-155.623, -41.9617}, + {-144.433, -23.5133}, + {-132.373, -40.8524}, + {-163.838, -24.5874}, + {-111.492, -38.55}, + {-132.174, -72.8109}, + {-127.897, -26.799}, + {-131.744, -13.8871}, + {-101.61, -24.3266}, + {-101.046, -12.0094}, + {-152.667, -12.35}, + {-167.746, -11.1537}, + {-14.0127, -27.2963}, + {-59.193, -57.0815}, + {-56.465, -19.5751}, + {-27.056, -59.3077}, + {-57.124, -35.9752}, + {-33.4636, -28.3914}, + {-74.8037, -46.8602}, + {-40.089, -45.1376}, + {-74.8149, -28.3136}, + {-21.3072, -42.2177}, + {-44.0778, -72.6353}, + {-19.6969, -12.8527}, + {-40.1318, -12.1601}, + {-72.691, -11.4129}, + {-56.0261, 58.6741}, + {-25.9127, 16.9547}, + {-25.7876, 58.8675}, + {-65.6229, 41.9617}, + {-54.4335, 23.5133}, + {-42.373, 40.8524}, + {-73.838, 24.5874}, + {-21.4917, 38.55}, + {-42.1744, 72.8109}, + {-37.8974, 26.799}, + {-41.7437, 13.8871}, + {-11.6095, 24.3266}, + {-11.0459, 12.0094}, + {-62.667, 12.35}, + {-77.7456, 11.1537}, + {30.3071, 59.7167}, + {17.1956, 26.0167}, + {54.7676, 28.3721}, + {60.8915, 60.0343}, + {74.5657, 25.5053}, + {26.8506, 14.0295}, + {34.8398, 28.3978}, + {67.9014, 42.042}, + {21.41, 43.1056}, + {44.3335, 44.6677}, + {13.2772, 11.707}, + {45.3579, 73.2119}, + {45.3492, 14.2311}, + {63.4799, 13.386}, + {78.0714, 11.5344}, + {17.01, -26.3775}, + {32.4806, -56.1313}, + {57.4213, -27.4824}, + {62.0912, -59.2376}, + {75.9483, -27.3616}, + {26.893, -14.9717}, + {69.1672, -41.7436}, + {35.1527, -32.8534}, + {18.4543, -42.1031}, + {50.1344, -44.5201}, + {46.1172, -72.4163}, + {13.2711, -11.8907}, + {44.2448, -15.2529}, + {73.9368, -14.4869}, + {60.5478, -11.7037}} ); // Create mesh from grid - MeshGenerator meshgen("delaunay"); - Mesh mesh = meshgen.generate(grid); + MeshGenerator meshgen( "delaunay" ); + Mesh mesh = meshgen.generate( grid ); // Output - Gmsh gmsh("unstructured.msh",Config("coordinates","xyz")); - gmsh.write(mesh); + Gmsh gmsh( "unstructured.msh", Config( "coordinates", "xyz" ) ); + gmsh.write( mesh ); atlas::Library::instance().finalise(); return 0; } - diff --git a/doc/user-guide/core-functionalities/meshes/meshes-Structured.cc b/doc/user-guide/core-functionalities/meshes/meshes-Structured.cc index 215c723dc..bcf3dc901 100644 --- a/doc/user-guide/core-functionalities/meshes/meshes-Structured.cc +++ b/doc/user-guide/core-functionalities/meshes/meshes-Structured.cc @@ -1,5 +1,5 @@ -#include "atlas/library/Library.h" #include "atlas/grid/Grid.h" +#include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/output/Gmsh.h" @@ -11,20 +11,19 @@ using atlas::meshgenerator::StructuredMeshGenerator; using atlas::output::Gmsh; using atlas::util::Config; -int main(int argc, char *argv[]) -{ - atlas::Library::instance().initialise(argc, argv); +int main( int argc, char* argv[] ) { + atlas::Library::instance().initialise( argc, argv ); StructuredMeshGenerator meshgenerator; Grid grid( "O32" ); - Mesh mesh = meshgenerator.generate(grid); + Mesh mesh = meshgenerator.generate( grid ); - Gmsh gmsh_2d("mesh2d.msh"); - Gmsh gmsh_3d("mesh3d.msh", Config("coordinates", "xyz") ); + Gmsh gmsh_2d( "mesh2d.msh" ); + Gmsh gmsh_3d( "mesh3d.msh", Config( "coordinates", "xyz" ) ); - gmsh_2d.write(mesh); - gmsh_3d.write(mesh); + gmsh_2d.write( mesh ); + gmsh_3d.write( mesh ); atlas::Library::instance().finalise(); diff --git a/doc/user-guide/getting-started/installation/hello-world.cc b/doc/user-guide/getting-started/installation/hello-world.cc index 5b957047c..342859642 100644 --- a/doc/user-guide/getting-started/installation/hello-world.cc +++ b/doc/user-guide/getting-started/installation/hello-world.cc @@ -1,9 +1,8 @@ #include "atlas/library/Library.h" #include "atlas/runtime/Log.h" -int main(int argc, char** argv) -{ - atlas::Library::instance().initialise(argc, argv); +int main( int argc, char** argv ) { + atlas::Library::instance().initialise( argc, argv ); atlas::Log::info() << "Hello world!" << std::endl; atlas::Library::instance().finalise(); diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index e39104d28..26e2c5041 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -22,27 +23,27 @@ * - Number of iterations, so caches can warm up, and timings can be averaged * - Number of OpenMP threads per MPI task * - * Results should be bit-identical when changing number of OpenMP threads or MPI tasks. + * Results should be bit-identical when changing number of OpenMP threads or MPI + * tasks. * A checksum on all bits is used to verify between scaling runs. * * */ +#include +#include +#include #include +#include #include -#include -#include -#include #include -#include #include "eckit/exception/Exceptions.h" #include "eckit/log/Timer.h" -#include "atlas/library/Library.h" #include "atlas/functionspace.h" #include "atlas/grid.h" -#include "atlas/meshgenerator.h" +#include "atlas/library/Library.h" #include "atlas/mesh.h" #include "atlas/mesh/IsGhostNode.h" #include "atlas/mesh/actions/BuildDualMesh.h" @@ -50,31 +51,32 @@ #include "atlas/mesh/actions/BuildHalo.h" #include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildPeriodicBoundaries.h" -#include "atlas/runtime/AtlasTool.h" -#include "atlas/runtime/Trace.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/util/Earth.h" +#include "atlas/meshgenerator.h" #include "atlas/output/Gmsh.h" #include "atlas/parallel/Checksum.h" #include "atlas/parallel/HaloExchange.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/omp/omp.h" +#include "atlas/runtime/AtlasTool.h" +#include "atlas/runtime/Trace.h" +#include "atlas/util/CoordinateEnums.h" +#include "atlas/util/Earth.h" //---------------------------------------------------------------------------------------------------------------------- -using std::unique_ptr; -using std::string; -using std::stringstream; -using std::min; -using std::max; -using std::vector; -using std::setw; -using std::setprecision; -using std::scientific; -using std::fixed; using std::cout; using std::endl; +using std::fixed; +using std::max; +using std::min; using std::numeric_limits; +using std::scientific; +using std::setprecision; +using std::setw; +using std::string; +using std::stringstream; +using std::unique_ptr; +using std::vector; using Topology = atlas::mesh::Nodes::Topology; using atlas::mesh::IsGhostNode; @@ -89,536 +91,488 @@ using namespace atlas::meshgenerator; using atlas::AtlasTool; namespace { - void usage(const std::string& tool) { - Log::info() << "Usage: "<( "grid", "Grid unique identifier" ) ); + add_option( new SimpleOption( "nlev", "Vertical resolution: Number of levels" ) ); + add_option( new SimpleOption( "niter", "Number of iterations" ) ); + add_option( new SimpleOption( "omp", "Number of OpenMP threads per MPI task" ) ); + add_option( new SimpleOption( "progress", "Show progress bar instead of intermediate timings" ) ); + add_option( new SimpleOption( "output", "Write output in gmsh format" ) ); + add_option( new SimpleOption( "exclude", "Exclude number of iterations in statistics (default=1)" ) ); + add_option( new SimpleOption( "details", "Show detailed timers (default=false)" ) ); + } - AtlasBenchmark(int argc,char **argv): AtlasTool(argc,argv) - { - add_option( new SimpleOption("grid","Grid unique identifier") ); - add_option( new SimpleOption("nlev","Vertical resolution: Number of levels") ); - add_option( new SimpleOption("niter","Number of iterations") ); - add_option( new SimpleOption("omp","Number of OpenMP threads per MPI task") ); - add_option( new SimpleOption("progress","Show progress bar instead of intermediate timings") ); - add_option( new SimpleOption("output","Write output in gmsh format") ); - add_option( new SimpleOption("exclude","Exclude number of iterations in statistics (default=1)") ); - add_option( new SimpleOption("details","Show detailed timers (default=false)") ); - } - - void setup(); + void setup(); - void iteration(); + void iteration(); - double result(); + double result(); - int verify(const double&); + int verify( const double& ); - void initial_condition(const Field& field, const double& beta); + void initial_condition( const Field& field, const double& beta ); private: - - Mesh mesh; - functionspace::NodeColumns nodes_fs; - Field scalar_field; - Field grad_field; - - vector pole_edges; - vector is_ghost; - - size_t nnodes; - size_t nedges; - size_t nlev; - size_t niter; - size_t exclude; - bool output; - long omp_threads; - double dz; - std::string gridname; - - TimerStats iteration_timer; - TimerStats haloexchange_timer; - size_t iter; - bool progress; + Mesh mesh; + functionspace::NodeColumns nodes_fs; + Field scalar_field; + Field grad_field; + + vector pole_edges; + vector is_ghost; + + size_t nnodes; + size_t nedges; + size_t nlev; + size_t niter; + size_t exclude; + bool output; + long omp_threads; + double dz; + std::string gridname; + + TimerStats iteration_timer; + TimerStats haloexchange_timer; + size_t iter; + bool progress; public: - int exit_code; - + int exit_code; }; //---------------------------------------------------------------------------------------------------------------------- -void AtlasBenchmark::execute(const Args& args) -{ - Trace timer( Here(),"atlas-benchmark"); - // Timer::Logging set_channel( Log::info() ); - - nlev = 137; - args.get("nlev",nlev); - gridname = "N64"; - args.get("grid",gridname); - niter = 100; - args.get("niter",niter); - omp_threads = -1; - args.get("omp",omp_threads); - progress = false; - args.get("progress",progress); - exclude = niter==1?0:1; - args.get("exclude",exclude); - output = false; - args.get("output",output); - bool help(false); - args.get("help",help); - - iteration_timer = TimerStats("iteration"); - haloexchange_timer = TimerStats("halo-exchange"); - - if( omp_threads > 0 ) - atlas_omp_set_num_threads(omp_threads); - - Log::info() << "atlas-benchmark\n" << endl; - Log::info() << Library::instance().information() << endl; - Log::info() << "Configuration:" << endl; - Log::info() << " grid: " << gridname << endl; - Log::info() << " nlev: " << nlev << endl; - Log::info() << " niter: " << niter << endl; - Log::info() << endl; - Log::info() << " MPI tasks: "<(static_cast(iter)/static_cast(niter-1)*50.0); - while( tic <= tics_needed ) - { - Log::info() << '*' << std::flush; - ++tic; - } - if ( iter == niter-1 ) - { - if ( tic < 51 ) Log::info() << '*'; - Log::info() << endl; - } +void AtlasBenchmark::execute( const Args& args ) { + Trace timer( Here(), "atlas-benchmark" ); + // Timer::Logging set_channel( Log::info() ); + + nlev = 137; + args.get( "nlev", nlev ); + gridname = "N64"; + args.get( "grid", gridname ); + niter = 100; + args.get( "niter", niter ); + omp_threads = -1; + args.get( "omp", omp_threads ); + progress = false; + args.get( "progress", progress ); + exclude = niter == 1 ? 0 : 1; + args.get( "exclude", exclude ); + output = false; + args.get( "output", output ); + bool help( false ); + args.get( "help", help ); + + iteration_timer = TimerStats( "iteration" ); + haloexchange_timer = TimerStats( "halo-exchange" ); + + if ( omp_threads > 0 ) atlas_omp_set_num_threads( omp_threads ); + + Log::info() << "atlas-benchmark\n" << endl; + Log::info() << Library::instance().information() << endl; + Log::info() << "Configuration:" << endl; + Log::info() << " grid: " << gridname << endl; + Log::info() << " nlev: " << nlev << endl; + Log::info() << " niter: " << niter << endl; + Log::info() << endl; + Log::info() << " MPI tasks: " << mpi::comm().size() << endl; + Log::info() << " OpenMP threads per MPI task: " << atlas_omp_get_max_threads() << endl; + Log::info() << endl; + + Log::info() << "Timings:" << endl; + + ATLAS_TRACE_SCOPE( "setup", {"atlas-benchmark-setup"} ) { setup(); } + + Log::info() << " Executing " << niter << " iterations: \n"; + if ( progress ) { + Log::info() << " 0% 10 20 30 40 50 60 70 80 90 100%\n"; + Log::info() << " |----|----|----|----|----|----|----|----|----|----|\n"; + Log::info() << " " << std::flush; } - iteration(); - } - timer.stop(); - - - Log::info() << "Iteration timer Statistics:\n" - << " min: " << setprecision(5) << fixed << iteration_timer.min - << " max: " << setprecision(5) << fixed << iteration_timer.max - << " avg: " << setprecision(5) << fixed << iteration_timer.avg << endl; - Log::info() << "Communication timer Statistics:\n" - << " min: " << setprecision(5) << fixed << haloexchange_timer.min - << " max: " << setprecision(5) << fixed << haloexchange_timer.max - << " avg: " << setprecision(5) << fixed << haloexchange_timer.avg - << " ( "<< setprecision(2) << haloexchange_timer.avg/iteration_timer.avg*100. << "% )" << endl; - - util::Config report_config; - report_config.set("indent",4); - 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; - - mpi::comm().barrier(); - - Log::info() << "Results:" << endl; - - double res = result(); - - Log::info() << endl; - exit_code = verify( res ); + unsigned int tic = 0; + for ( iter = 0; iter < niter; ++iter ) { + if ( progress ) { + unsigned int tics_needed = + static_cast( static_cast( iter ) / static_cast( niter - 1 ) * 50.0 ); + while ( tic <= tics_needed ) { + Log::info() << '*' << std::flush; + ++tic; + } + if ( iter == niter - 1 ) { + if ( tic < 51 ) Log::info() << '*'; + Log::info() << endl; + } + } + iteration(); + } + timer.stop(); + + Log::info() << "Iteration timer Statistics:\n" + << " min: " << setprecision( 5 ) << fixed << iteration_timer.min << " max: " << setprecision( 5 ) + << fixed << iteration_timer.max << " avg: " << setprecision( 5 ) << fixed << iteration_timer.avg + << endl; + Log::info() << "Communication timer Statistics:\n" + << " min: " << setprecision( 5 ) << fixed << haloexchange_timer.min << " max: " << setprecision( 5 ) + << fixed << haloexchange_timer.max << " avg: " << setprecision( 5 ) << fixed << haloexchange_timer.avg + << " ( " << setprecision( 2 ) << haloexchange_timer.avg / iteration_timer.avg * 100. << "% )" << endl; + + util::Config report_config; + report_config.set( "indent", 4 ); + 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; + + mpi::comm().barrier(); + + Log::info() << "Results:" << endl; + + double res = result(); + + Log::info() << endl; + exit_code = verify( res ); } //---------------------------------------------------------------------------------------------------------------------- -void AtlasBenchmark::initial_condition(const Field& field, const double& beta) -{ - const double radius = util::Earth::radiusInMeters(); - const double USCAL = 20.; - const double pvel = USCAL/radius; - const double deg2rad = M_PI/180.; - - auto lonlat_deg = array::make_view (mesh.nodes().lonlat()); - auto var = array::make_view (field); - - size_t nnodes = mesh.nodes().size(); - for( size_t jnode=0; jnode( mesh.nodes().lonlat() ); + auto var = array::make_view( field ); + + size_t nnodes = mesh.nodes().size(); + for ( size_t jnode = 0; jnode < nnodes; ++jnode ) { + double x = lonlat_deg( jnode, LON ) * deg2rad; + double y = lonlat_deg( jnode, LAT ) * deg2rad; + 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 ( size_t jlev = 0; jlev < field.levels(); ++jlev ) + var( jnode, jlev ) = std::sqrt( Ux * Ux + Uy * Uy ); + } } //---------------------------------------------------------------------------------------------------------------------- -void AtlasBenchmark::setup() -{ - size_t halo = 1; - - StructuredGrid grid; - ATLAS_TRACE_SCOPE( "Create grid" ) { grid = Grid(gridname); } - ATLAS_TRACE_SCOPE( "Create mesh" ) { mesh = MeshGenerator( "structured", util::Config("partitioner","equal_regions") ).generate(grid); } - - ATLAS_TRACE_SCOPE( "Create node_fs") { nodes_fs = functionspace::NodeColumns(mesh,option::halo(halo)); } - ATLAS_TRACE_SCOPE( "build_edges" ) { build_edges(mesh); } - ATLAS_TRACE_SCOPE( "build_pole_edges" ) { build_pole_edges(mesh); } - - //mesh.polygon(0).outputPythonScript("plot_polygon.py"); -// atlas::output::Output gmsh = atlas::output::Gmsh( "edges.msh", util::Config("ghost",true)("edges",true)("elements",false) ); -// gmsh.write( mesh ); - -// gmsh = atlas::output::Gmsh( "elements.msh", util::Config("ghost",true)("edges",false)("elements",true) ); -// gmsh.write( mesh ); - - ATLAS_TRACE_SCOPE( "build_edges_parallel_fiels" ) { build_edges_parallel_fields(mesh); } - ATLAS_TRACE_SCOPE( "build_median_dual_mesh" ) { build_median_dual_mesh(mesh); } - ATLAS_TRACE_SCOPE( "build_node_to_edge_connectivity" ) { build_node_to_edge_connectivity(mesh); } - - scalar_field = nodes_fs.createField( option::name("field") | option::levels(nlev) ); - grad_field = nodes_fs.createField( option::name("grad") | option::levels(nlev) | option::variables(3) ); - - nnodes = mesh.nodes().size(); - nedges = mesh.edges().size(); - - auto lonlat = array::make_view ( mesh.nodes().xy() ); - auto V = array::make_view ( mesh.nodes().field("dual_volumes") ); - auto S = array::make_view ( mesh.edges().field("dual_normals") ); - auto field = array::make_view ( scalar_field ); - - initial_condition(scalar_field,0.); - - double radius = 6371.22e+03; // Earth's radius - double height = 80.e+03; // Height of atmosphere - double deg2rad = M_PI/180.; - atlas_omp_parallel_for( size_t jnode=0; jnode(nlev); - - auto edge_is_pole = array::make_view ( mesh.edges().field("is_pole_edge") ); - const mesh::Connectivity& node2edge = mesh.nodes().edge_connectivity(); - const mesh::MultiBlockConnectivity& edge2node = mesh.edges().node_connectivity(); - auto node2edge_sign = array::make_view ( mesh.nodes().add( - Field("to_edge_sign",array::make_datatype(),array::make_shape(nnodes,node2edge.maxcols()) ) ) ); - - atlas_omp_parallel_for( size_t jnode=0; jnode( option::name( "field" ) | option::levels( nlev ) ); + grad_field = + nodes_fs.createField( option::name( "grad" ) | option::levels( nlev ) | option::variables( 3 ) ); + + nnodes = mesh.nodes().size(); + nedges = mesh.edges().size(); + + auto lonlat = array::make_view( mesh.nodes().xy() ); + auto V = array::make_view( mesh.nodes().field( "dual_volumes" ) ); + auto S = array::make_view( mesh.edges().field( "dual_normals" ) ); + auto field = array::make_view( scalar_field ); + + initial_condition( scalar_field, 0. ); + + double radius = 6371.22e+03; // Earth's radius + double height = 80.e+03; // Height of atmosphere + double deg2rad = M_PI / 180.; + atlas_omp_parallel_for( size_t jnode = 0; jnode < nnodes; ++jnode ) { + lonlat( jnode, LON ) = lonlat( jnode, LON ) * deg2rad; + lonlat( jnode, LAT ) = lonlat( jnode, LAT ) * deg2rad; + double y = lonlat( jnode, LAT ); + double hx = radius * std::cos( y ); + double hy = radius; + double G = hx * hy; + V( jnode ) *= std::pow( deg2rad, 2 ) * G; + } + atlas_omp_parallel_for( size_t jedge = 0; jedge < nedges; ++jedge ) { + S( jedge, LON ) *= deg2rad; + S( jedge, LAT ) *= deg2rad; + } + dz = height / static_cast( nlev ); + + auto edge_is_pole = array::make_view( mesh.edges().field( "is_pole_edge" ) ); + const mesh::Connectivity& node2edge = mesh.nodes().edge_connectivity(); + const mesh::MultiBlockConnectivity& edge2node = mesh.edges().node_connectivity(); + auto node2edge_sign = array::make_view( mesh.nodes().add( + Field( "to_edge_sign", array::make_datatype(), array::make_shape( nnodes, node2edge.maxcols() ) ) ) ); + + atlas_omp_parallel_for( size_t jnode = 0; jnode < nnodes; ++jnode ) { + for ( size_t jedge = 0; jedge < node2edge.cols( jnode ); ++jedge ) { + size_t iedge = node2edge( jnode, jedge ); + size_t ip1 = edge2node( iedge, 0 ); + if ( jnode == ip1 ) + node2edge_sign( jnode, jedge ) = 1.; + else + node2edge_sign( jnode, jedge ) = -1.; + } + } + + vector tmp( nedges ); + int c( 0 ); + for ( size_t jedge = 0; jedge < nedges; ++jedge ) { + if ( edge_is_pole( jedge ) ) tmp[c++] = jedge; + } + pole_edges.reserve( c ); + for ( int jedge = 0; jedge < c; ++jedge ) + pole_edges.push_back( tmp[jedge] ); + + auto flags = array::make_view( mesh.nodes().field( "flags" ) ); + is_ghost.reserve( nnodes ); + for ( size_t jnode = 0; jnode < nnodes; ++jnode ) { + is_ghost.push_back( Topology::check( flags( jnode ), Topology::GHOST ) ); } - } - - vector tmp(nedges); - int c(0); - for(size_t jedge = 0; jedge < nedges; ++jedge) - { - if( edge_is_pole(jedge) ) - tmp[c++] = jedge; - } - pole_edges.reserve(c); - for( int jedge=0; jedge( mesh.nodes().field("flags") ); - is_ghost.reserve(nnodes); - for(size_t jnode = 0; jnode < nnodes; ++jnode) - { - is_ghost.push_back( Topology::check(flags(jnode),Topology::GHOST) ); - } } //---------------------------------------------------------------------------------------------------------------------- -void AtlasBenchmark::iteration() -{ - Trace t( Here() ); - Trace compute( Here(), "compute" ); - unique_ptr avgS_arr( array::Array::create(nedges,nlev,2ul) ); - const auto& node2edge = mesh.nodes().edge_connectivity(); - const auto& edge2node = mesh.edges().node_connectivity(); - const auto field = array::make_view( scalar_field ); - const auto S = array::make_view( mesh.edges().field("dual_normals")); - const auto V = array::make_view( mesh.nodes().field("dual_volumes")); - const auto node2edge_sign = array::make_view ( mesh.nodes().field("to_edge_sign") ); - - auto grad = array::make_view( grad_field ); - auto avgS = array::make_view( *avgS_arr ); - auto node_glb_idx = array::make_view(mesh.nodes().global_index()); - auto node_part = array::make_view(mesh.nodes().partition()); - auto edge_part = array::make_view(mesh.edges().partition()); - auto edge_glb_idx = array::make_view(mesh.edges().global_index()); - - atlas_omp_parallel_for( size_t jedge=0; jedge avgS_arr( array::Array::create( nedges, nlev, 2ul ) ); + const auto& node2edge = mesh.nodes().edge_connectivity(); + const auto& edge2node = mesh.edges().node_connectivity(); + const auto field = array::make_view( scalar_field ); + const auto S = array::make_view( mesh.edges().field( "dual_normals" ) ); + const auto V = array::make_view( mesh.nodes().field( "dual_volumes" ) ); + const auto node2edge_sign = array::make_view( mesh.nodes().field( "to_edge_sign" ) ); + + auto grad = array::make_view( grad_field ); + auto avgS = array::make_view( *avgS_arr ); + auto node_glb_idx = array::make_view( mesh.nodes().global_index() ); + auto node_part = array::make_view( mesh.nodes().partition() ); + auto edge_part = array::make_view( mesh.edges().partition() ); + auto edge_glb_idx = array::make_view( mesh.edges().global_index() ); + + atlas_omp_parallel_for( size_t jedge = 0; jedge < nedges; ++jedge ) { + int ip1 = edge2node( jedge, 0 ); + int ip2 = edge2node( jedge, 1 ); + + for ( size_t jlev = 0; jlev < nlev; ++jlev ) { + double avg = ( field( ip1, jlev ) + field( ip2, jlev ) ) * 0.5; + avgS( jedge, jlev, LON ) = S( jedge, LON ) * avg; + avgS( jedge, jlev, LAT ) = S( jedge, LAT ) * avg; + } } - } - - atlas_omp_parallel_for( size_t jnode=0; jnode 2 ) { + for ( size_t jlev = 1; jlev < nlev - 1; ++jlev ) { + grad( jnode, jlev, ZZ ) = ( field( jnode, jlev + 1 ) - field( jnode, jlev - 1 ) ) * dzi_2; + } + } + if ( nlev > 1 ) { + 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.; } - } - // special treatment for the north & south pole cell faces - // Sx == 0 at pole, and Sy has same sign at both sides of pole - for(size_t jedge = 0; jedge < pole_edges.size(); ++jedge) - { - int iedge = pole_edges[jedge]; - int ip2 = edge2node(iedge,1); - // correct for wrong Y-derivatives in previous loop - for(size_t jlev = 0; jlev < nlev; ++jlev) - grad(ip2,jlev,LAT) += 2.*avgS(iedge,jlev,LAT)/V(ip2); - } - - double dzi = 1./dz; - double dzi_2 = 0.5*dzi; - - atlas_omp_parallel_for( size_t jnode=0; jnode 2 ) - { - for(size_t jlev = 1; jlev < nlev - 1; ++jlev) - { - grad(jnode,jlev,ZZ) = (field(jnode,jlev+1) - field(jnode,jlev-1))*dzi_2; - } + compute.stop(); + + // halo-exchange + Trace halo( Here(), "halo-exchange" ); + nodes_fs.halo_exchange().execute( grad_field.array() ); + halo.stop(); + + t.stop(); + + if ( iter >= exclude ) { + haloexchange_timer.update( halo ); + iteration_timer.update( t ); } - if( nlev > 1 ) - { - 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 ( !progress ) { + Log::info() << setw( 6 ) << iter + 1 << " total: " << fixed << setprecision( 5 ) << t.elapsed() + << " communication: " << setprecision( 5 ) << halo.elapsed() << " ( " << setprecision( 2 ) + << fixed << setw( 3 ) << halo.elapsed() / t.elapsed() * 100 << "% )" << endl; } - if( nlev == 1 ) - grad(jnode,0,ZZ) = 0.; - } - compute.stop(); - - // halo-exchange - Trace halo( Here(), "halo-exchange"); - nodes_fs.halo_exchange().execute(grad_field.array()); - halo.stop(); - - t.stop(); - - if( iter >= exclude ) - { - haloexchange_timer.update(halo); - iteration_timer.update(t); - } - - if( !progress ) - { - Log::info() << setw(6) << iter+1 - << " total: " << fixed << setprecision(5) << t.elapsed() - << " communication: " << setprecision(5) << halo.elapsed() - << " ( "<< setprecision(2) << fixed << setw(3) - << halo.elapsed()/t.elapsed()*100 << "% )" << endl; - } } //---------------------------------------------------------------------------------------------------------------------- -template< typename DATA_TYPE > -DATA_TYPE vecnorm( const DATA_TYPE vec[], size_t size ) -{ - DATA_TYPE norm=0; - for(size_t j=0; j < size; ++j) - norm += vec[j]*vec[j]; - return norm; +template +DATA_TYPE vecnorm( const DATA_TYPE vec[], size_t size ) { + DATA_TYPE norm = 0; + for ( size_t j = 0; j < size; ++j ) + norm += vec[j] * vec[j]; + return norm; } -double AtlasBenchmark::result() -{ - auto grad = array::make_view( grad_field ); - double maxval = -std::numeric_limits::max(); - double minval = std::numeric_limits::max();; - double norm = 0.; - - nodes_fs.haloExchange(grad_field); - auto glb_idx = array::make_view(mesh.nodes().global_index()); - auto part = array::make_view(mesh.nodes().partition()); - for(size_t jnode = 0; jnode < nnodes; ++jnode) - { - - if( !is_ghost[jnode] ) - { - for(size_t jlev = 0; jlev < 1; ++jlev) - { - const double scaling = 1.e12; - grad(jnode,jlev,LON) *= scaling; - grad(jnode,jlev,LAT) *= scaling; - grad(jnode,jlev,ZZ) *= scaling; - - std::array v; - v[0] = grad(jnode,jlev,LON); - v[1] = grad(jnode,jlev,LAT); - v[2] = grad(jnode,jlev,ZZ); - - maxval = std::max(maxval,v[0]); - maxval = std::max(maxval,v[1]); - maxval = std::max(maxval,v[2]); - minval = std::min(minval,v[0]); - minval = std::min(minval,v[1]); - minval = std::min(minval,v[2]); - - //if( mpi::comm().rank() == 478 ) { - // std::cout << " " << jnode << " part " << part(jnode) << " glb_idx " << glb_idx(jnode) << " x,y,z " << v[0] << "," << v[1] << ","<< v[2] << std::endl; - //} - - - norm += v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - } +double AtlasBenchmark::result() { + auto grad = array::make_view( grad_field ); + double maxval = -std::numeric_limits::max(); + double minval = std::numeric_limits::max(); + ; + double norm = 0.; + + nodes_fs.haloExchange( grad_field ); + auto glb_idx = array::make_view( mesh.nodes().global_index() ); + auto part = array::make_view( mesh.nodes().partition() ); + for ( size_t jnode = 0; jnode < nnodes; ++jnode ) { + if ( !is_ghost[jnode] ) { + for ( size_t jlev = 0; jlev < 1; ++jlev ) { + const double scaling = 1.e12; + grad( jnode, jlev, LON ) *= scaling; + grad( jnode, jlev, LAT ) *= scaling; + grad( jnode, jlev, ZZ ) *= scaling; + + std::array v; + v[0] = grad( jnode, jlev, LON ); + v[1] = grad( jnode, jlev, LAT ); + v[2] = grad( jnode, jlev, ZZ ); + + maxval = std::max( maxval, v[0] ); + maxval = std::max( maxval, v[1] ); + maxval = std::max( maxval, v[2] ); + minval = std::min( minval, v[0] ); + minval = std::min( minval, v[1] ); + minval = std::min( minval, v[2] ); + + // if( mpi::comm().rank() == 478 ) { + // std::cout << " " << jnode << " part " << part(jnode) << " + // glb_idx " << glb_idx(jnode) << " x,y,z " << v[0] << "," << v[1] + // << ","<< v[2] << std::endl; + //} + + norm += v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; + } + } } - } - if( output ) - { - std::vector levels( 1, 0 ); - atlas::output::Output gmsh = atlas::output::Gmsh( "benchmark.msh", util::Config("levels",levels)("ghost",true) ); - gmsh.write( mesh ); - gmsh.write( scalar_field ); - gmsh.write( grad_field ); - } + if ( output ) { + std::vector levels( 1, 0 ); + atlas::output::Output gmsh = + atlas::output::Gmsh( "benchmark.msh", util::Config( "levels", levels )( "ghost", true ) ); + gmsh.write( mesh ); + gmsh.write( scalar_field ); + gmsh.write( grad_field ); + } - ATLAS_TRACE_MPI( ALLREDUCE ) { - mpi::comm().allReduceInPlace(maxval, eckit::mpi::max()); - mpi::comm().allReduceInPlace(minval, eckit::mpi::min()); - mpi::comm().allReduceInPlace(norm, eckit::mpi::sum()); - } + ATLAS_TRACE_MPI( ALLREDUCE ) { + mpi::comm().allReduceInPlace( maxval, eckit::mpi::max() ); + mpi::comm().allReduceInPlace( minval, eckit::mpi::min() ); + mpi::comm().allReduceInPlace( norm, eckit::mpi::sum() ); + } - norm = std::sqrt(norm); + norm = std::sqrt( norm ); - Log::info() << " maxval: " << setw(13) << setprecision(6) << scientific << maxval << endl; - Log::info() << " minval: " << setw(13) << setprecision(6) << scientific << minval << endl; - Log::info() << " norm: " << setw(13) << setprecision(6) << scientific << norm << endl; + Log::info() << " maxval: " << setw( 13 ) << setprecision( 6 ) << scientific << maxval << endl; + Log::info() << " minval: " << setw( 13 ) << setprecision( 6 ) << scientific << minval << endl; + Log::info() << " norm: " << setw( 13 ) << setprecision( 6 ) << scientific << norm << endl; - Log::info() << " checksum: " << nodes_fs.checksum().execute( grad ) << endl; + Log::info() << " checksum: " << nodes_fs.checksum().execute( grad ) << endl; - return norm; + return norm; } -int AtlasBenchmark::verify(const double& norm) -{ - Log::warning() << "Verification is not yet implemented" << endl; - return 1; +int AtlasBenchmark::verify( const double& norm ) { + Log::warning() << "Verification is not yet implemented" << endl; + return 1; } //---------------------------------------------------------------------------------------------------------------------- -int main( int argc, char **argv ) -{ - AtlasBenchmark tool(argc,argv); - return tool.start(); +int main( int argc, char** argv ) { + AtlasBenchmark tool( argc, argv ); + return tool.start(); } diff --git a/src/apps/atlas-gaussian-latitudes.cc b/src/apps/atlas-gaussian-latitudes.cc index 1fcaebe3b..99bedf130 100644 --- a/src/apps/atlas-gaussian-latitudes.cc +++ b/src/apps/atlas-gaussian-latitudes.cc @@ -4,26 +4,27 @@ * 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 + * 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 -#include +#include +#include +#include #include +#include +#include -#include "eckit/exception/Exceptions.h" #include "eckit/config/Resource.h" -#include "eckit/runtime/Tool.h" +#include "eckit/exception/Exceptions.h" #include "eckit/runtime/Main.h" +#include "eckit/runtime/Tool.h" -#include "atlas/library/Library.h" #include "atlas/grid/detail/spacing/GaussianSpacing.h" +#include "atlas/library/Library.h" //------------------------------------------------------------------------------------------------------ @@ -34,105 +35,97 @@ using atlas::grid::spacing::GaussianSpacing; //------------------------------------------------------------------------------------------------------ class AtlasGaussianLatitudes : public eckit::Tool { - - virtual void run(); + virtual void run(); public: - - AtlasGaussianLatitudes(int argc,char **argv): eckit::Tool(argc,argv) - { - do_run = false; - - bool help = Resource< bool >("--help",false); - - std::string help_str = - "NAME\n" - " atlas-gaussian-latitudes - Compute gaussian latitudes, given the N number\n" - "\n" - "SYNOPSIS\n" - " atlas-gaussian-latitudes [--help] [-N] [OPTION]...\n" - "\n" - "DESCRIPTION\n" - " Compute gaussian latitudes, given the N number.\n" - " Latitudes start at the pole (+90), and decrease in value.\n" - "\n" - " -N Number of points between pole and equator\n" - "\n" - " --full If set, all latitudes will be given, otherwise only\n" - " between North pole and equator.\n" - "\n" - " --format \"table\" (default)\n" - " \"C\"\n" - "\n" - " --compact Write 5 latitudes per line if the format supports it\n" - "\n" - "AUTHOR\n" - " Written by Willem Deconinck.\n" - "\n" - "ECMWF December 2014" - ; - - N = Resource< int >("-N",0); - - full = Resource< bool >("--full",false); - - compact = Resource< bool >("--compact",false); - - format = Resource< std::string >("--format", std::string("table") ); - - if( N > 0 ) do_run = true; - - if( do_run == false ) - { - if( help ) - Log::info() << help_str << std::endl; - else - Log::info() << "usage: atlas-gaussian-latitudes [--help] [-N] [OPTION]..." << std::endl; + AtlasGaussianLatitudes( int argc, char** argv ) : eckit::Tool( argc, argv ) { + do_run = false; + + bool help = Resource( "--help", false ); + + std::string help_str = + "NAME\n" + " atlas-gaussian-latitudes - Compute gaussian latitudes, given " + "the N number\n" + "\n" + "SYNOPSIS\n" + " atlas-gaussian-latitudes [--help] [-N] [OPTION]...\n" + "\n" + "DESCRIPTION\n" + " Compute gaussian latitudes, given the N number.\n" + " Latitudes start at the pole (+90), and decrease in value.\n" + "\n" + " -N Number of points between pole and equator\n" + "\n" + " --full If set, all latitudes will be given, otherwise " + "only\n" + " between North pole and equator.\n" + "\n" + " --format \"table\" (default)\n" + " \"C\"\n" + "\n" + " --compact Write 5 latitudes per line if the format supports " + "it\n" + "\n" + "AUTHOR\n" + " Written by Willem Deconinck.\n" + "\n" + "ECMWF December 2014"; + + N = Resource( "-N", 0 ); + + full = Resource( "--full", false ); + + compact = Resource( "--compact", false ); + + format = Resource( "--format", std::string( "table" ) ); + + if ( N > 0 ) do_run = true; + + if ( do_run == false ) { + if ( help ) + Log::info() << help_str << std::endl; + else + Log::info() << "usage: atlas-gaussian-latitudes [--help] [-N] [OPTION]..." << std::endl; + } } - } private: - - int N; - bool full; - bool compact; - std::string format; - bool do_run; + int N; + bool full; + bool compact; + std::string format; + bool do_run; }; //------------------------------------------------------------------------------ -void AtlasGaussianLatitudes::run() -{ - if( !do_run ) return; - - GaussianSpacing lats(2*N); - - int end = full ? 2*N : N; - - if( format == "table" ) - { - for( int jlat=0; jlat #include -#include -#include -#include #include -#include -#include +#include #include +#include +#include +#include +#include -#include "eckit/exception/Exceptions.h" #include "eckit/config/Resource.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/filesystem/PathName.h" #include "eckit/runtime/Main.h" #include "eckit/runtime/Tool.h" -#include "eckit/filesystem/PathName.h" #include "atlas/library/Library.h" @@ -34,206 +34,189 @@ using namespace atlas; //------------------------------------------------------------------------------------------------------ class gmsh_extract : public eckit::Tool { - - virtual void run(); + virtual void run(); public: - - gmsh_extract(int argc,char **argv): eckit::Tool(argc,argv) - { - do_run = true; - - bool help = Resource< bool >("-h",false); - - std::string help_str = - "NAME\n" - " gmsh_extract - extract fields from gmsh files\n" - "\n" - "SYNOPSIS\n" - " gmsh_extract [OPTION]... -i SOURCE\n" - "\n" - "DESCRIPTION\n" - " Extract fields from SOURCE depending on OPTION\n" - "\n" - " -i (Required) space-separated list of gmsh files to process\n" - "\n" - " -f (Optional) comma-separated list of field names\n" - " If not present, all fields will be extracted\n" - "\n" - " -l (Optional) comma-separated list of levels\n" - " If not present, all levels will be extracted\n" - "\n" - " -o (Optional) newly created output file\n" - " If not present, the output will go to stdout\n" - "\n" - "EXAMPLES\n" - " gmsh_extract -f theta,VelocityZ -l 0,3 -i data/fields*.msh -o extracted.msh\n" - " # create/overwrite file extracted.msh\n" - "\n" - " gmsh_extract -f theta,VelocityZ -l 0,3 -i data/fields*.msh > extracted.msh\n" - " # create/overwrite file extracted.msh\n" - "\n" - " gmsh_extract -f theta,VelocityZ -l 0,3 -i data/fields*.msh >> extracted.msh\n" - " # append to file extracted.msh\n" - "\n" - "AUTHOR\n" - " Written by Willem Deconinck.\n" - "\n" - "ECMWF October 2014" - ; - - if( help ) - { - std::cout << help_str << std::endl; - do_run = false; - return; - } - - - fields = Resource< std::vector >("-f",std::vector()); - levels = Resource< std::vector >("-l",std::vector()); - out_filename = Resource< std::string >("-o",std::string("")); - - // Parse in_files manually, as Resource does not allow space separated file list, - // as a wildcard would return - //in_files = Resource< std::vector >("-i",std::vector()); - - for( int i=0; i( "-h", false ); + + std::string help_str = + "NAME\n" + " gmsh_extract - extract fields from gmsh files\n" + "\n" + "SYNOPSIS\n" + " gmsh_extract [OPTION]... -i SOURCE\n" + "\n" + "DESCRIPTION\n" + " Extract fields from SOURCE depending on OPTION\n" + "\n" + " -i (Required) space-separated list of gmsh files to " + "process\n" + "\n" + " -f (Optional) comma-separated list of field names\n" + " If not present, all fields will be extracted\n" + "\n" + " -l (Optional) comma-separated list of levels\n" + " If not present, all levels will be extracted\n" + "\n" + " -o (Optional) newly created output file\n" + " If not present, the output will go to stdout\n" + "\n" + "EXAMPLES\n" + " gmsh_extract -f theta,VelocityZ -l 0,3 -i data/fields*.msh -o " + "extracted.msh\n" + " # create/overwrite file extracted.msh\n" + "\n" + " gmsh_extract -f theta,VelocityZ -l 0,3 -i data/fields*.msh > " + "extracted.msh\n" + " # create/overwrite file extracted.msh\n" + "\n" + " gmsh_extract -f theta,VelocityZ -l 0,3 -i data/fields*.msh >> " + "extracted.msh\n" + " # append to file extracted.msh\n" + "\n" + "AUTHOR\n" + " Written by Willem Deconinck.\n" + "\n" + "ECMWF October 2014"; + + if ( help ) { + std::cout << help_str << std::endl; + do_run = false; + return; + } + + fields = Resource>( "-f", std::vector() ); + levels = Resource>( "-l", std::vector() ); + out_filename = Resource( "-o", std::string( "" ) ); + + // Parse in_files manually, as Resource does not allow space separated file + // list, + // as a wildcard would return + // in_files = Resource< std::vector + // >("-i",std::vector()); + + for ( int i = 0; i < argc; ++i ) { + 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; + in_files.push_back( in_file ); + } + } + } + + if ( in_files.empty() ) throw UserError( "missing input filename, parameter -i\n" + help_str, Here() ); + } private: - - std::vector fields; - std::vector levels; - std::vector in_files; - std::string out_filename; - bool do_run; + std::vector fields; + std::vector levels; + std::vector in_files; + std::string out_filename; + bool do_run; }; //------------------------------------------------------------------------------------------------------ -void gmsh_extract::run() -{ - if( !do_run ) return; - atlas::Library::instance().initialise(argc(),argv()); - Log::debug() << "Command line:" << std::endl; - 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() ) - throw eckit::CantOpenFile(out_filename); - } - - std::ostream& out = out_filename.empty() ? std::cout : out_file; - - for (size_t i = 0; i < in_files.size(); ++i) - { - PathName gmsh_file(in_files[i]); - Log::debug() << "Processing " << gmsh_file << std::endl; - std::set search_fields; - std::set search_levels; - search_fields.insert(fields.begin(),fields.end()); - search_levels.insert(levels.begin(),levels.end()); - - std::ifstream in_file; - in_file.open( gmsh_file.localPath() , std::ios::in | std::ios::binary ); - if( !in_file.is_open() ) - throw eckit::CantOpenFile(gmsh_file); - - std::string line; - std::string ctxt = ""; - while (true) - { - std::getline(in_file,line); - if( in_file.eof() ) break; - if( line == "$MeshFormat" ) - { - out<< line << "\n"; - std::getline(in_file,line); out<< line << "\n"; - std::getline(in_file,line); out<< line << "\n"; - std::getline(in_file,line); - } - if( line == "$NodeData" ) ctxt = "NodeData"; - if( line == "$ElementData") ctxt = "ElementData"; - if( line == "$ElementNodeData") ctxt = "ElementNodeData"; - - if( !ctxt.empty() ) - { - std::string end_ctxt = "$End"+ctxt; - std::getline(in_file,line); // useless line - std::getline(in_file,line); // field name - std::string field_name_read; - std::string field_name; - int lev(-1); - bool extract = false; - - field_name_read.assign(line,1,line.size()-2); - field_name = field_name_read; +void gmsh_extract::run() { + if ( !do_run ) return; + atlas::Library::instance().initialise( argc(), argv() ); + Log::debug() << "Command line:" << std::endl; + 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() ) throw eckit::CantOpenFile( out_filename ); + } + + std::ostream& out = out_filename.empty() ? std::cout : out_file; + + for ( size_t i = 0; i < in_files.size(); ++i ) { + PathName gmsh_file( in_files[i] ); + Log::debug() << "Processing " << gmsh_file << std::endl; + std::set search_fields; + std::set search_levels; + search_fields.insert( fields.begin(), fields.end() ); + search_levels.insert( levels.begin(), levels.end() ); + + std::ifstream in_file; + in_file.open( gmsh_file.localPath(), std::ios::in | std::ios::binary ); + if ( !in_file.is_open() ) throw eckit::CantOpenFile( gmsh_file ); + + std::string line; + std::string ctxt = ""; + while ( true ) { + std::getline( in_file, line ); + if ( in_file.eof() ) break; + if ( line == "$MeshFormat" ) { + out << line << "\n"; + std::getline( in_file, line ); + out << line << "\n"; + std::getline( in_file, line ); + out << line << "\n"; + std::getline( in_file, line ); + } + if ( line == "$NodeData" ) ctxt = "NodeData"; + if ( line == "$ElementData" ) ctxt = "ElementData"; + if ( line == "$ElementNodeData" ) ctxt = "ElementNodeData"; + + if ( !ctxt.empty() ) { + std::string end_ctxt = "$End" + ctxt; + std::getline( in_file, line ); // useless line + std::getline( in_file, line ); // field name + std::string field_name_read; + std::string field_name; + int lev( -1 ); + bool extract = false; + + field_name_read.assign( line, 1, line.size() - 2 ); + field_name = field_name_read; Log::debug() << "Found field " << field_name << std::endl; - if( field_name[field_name.size()-1] == ']' ) - { - std::string lev_str; - lev_str.assign(field_name,field_name.size()-4,3); - field_name.assign(field_name,0,field_name.size()-5); - lev = Translator()(lev_str); - } - if( search_fields.size() == 0 || search_fields.find(field_name) != search_fields.end() ) - { - if( lev==-1 ) - { - Log::debug() << "Extracting field " << field_name << std::endl; - extract = true; - } - else if( search_levels.size() == 0 || search_levels.find(lev) != search_levels.end() ) - { - Log::debug() << "Extracting field " << field_name << "[" << lev << "]" << std::endl; - extract = true; - } - } - if( extract ) - { - out << "$"<()( lev_str ); + } + if ( search_fields.size() == 0 || search_fields.find( field_name ) != search_fields.end() ) { + if ( lev == -1 ) { + Log::debug() << "Extracting field " << field_name << std::endl; + extract = true; + } + else if ( search_levels.size() == 0 || search_levels.find( lev ) != search_levels.end() ) { + Log::debug() << "Extracting field " << field_name << "[" << lev << "]" << std::endl; + extract = true; + } + } + if ( extract ) { + out << "$" << ctxt << "\n1\n" + << "\"" << field_name_read << "\"\n"; + while ( true ) { + std::getline( in_file, line ); + out << line << "\n"; + if ( line == end_ctxt ) { + out << std::flush; + break; + } + } + } + ctxt.clear(); + } + } + } + if ( !out_filename.empty() ) out_file.close(); + atlas::Library::instance().finalise(); } //------------------------------------------------------------------------------------------------------ -int main( int argc, char **argv ) -{ - gmsh_extract tool(argc,argv); - return tool.start(); +int main( int argc, char** argv ) { + gmsh_extract tool( argc, argv ); + return tool.start(); } - diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index 155c861f3..c3cf8c5fc 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -4,212 +4,190 @@ * 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 + * 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 -#include +#include +#include +#include #include +#include +#include -#include "atlas/library/Library.h" -#include "atlas/runtime/Log.h" #include "atlas/grid.h" +#include "atlas/library/Library.h" #include "atlas/runtime/AtlasTool.h" +#include "atlas/runtime/Log.h" -#include "eckit/exception/Exceptions.h" #include "eckit/config/Resource.h" -#include "eckit/runtime/Main.h" +#include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" -#include "eckit/memory/Factory.h" -#include "eckit/memory/Builder.h" -#include "eckit/log/Log.h" #include "eckit/log/Bytes.h" +#include "eckit/log/Log.h" +#include "eckit/memory/Builder.h" +#include "eckit/memory/Factory.h" #include "eckit/parser/JSON.h" #include "eckit/parser/Tokenizer.h" +#include "eckit/runtime/Main.h" using namespace atlas; using namespace atlas::grid; -using eckit::JSON; using eckit::Factory; +using eckit::JSON; //---------------------------------------------------------------------------------------------------------------------- class AtlasGrids : public AtlasTool { - - virtual bool serial() { return true; } - virtual void 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() { - return "Catalogue of available built-in grids\n" - "\n" - " Browse catalogue of grids\n" - "\n" - " GRID: unique identifier for grid \n" - " Example values: N80, F40, O24, L32\n"; - } + virtual bool serial() { return true; } + virtual void 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() { + return "Catalogue of available built-in grids\n" + "\n" + " Browse catalogue of grids\n" + "\n" + " GRID: unique identifier for grid \n" + " 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" ) ); - 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( "info", "List information about GRID" ) ); - add_option( new SimpleOption("json","Export json") ); + add_option( new SimpleOption( "json", "Export json" ) ); - add_option( new SimpleOption("rtable","Export IFS rtable") ); - - } + add_option( new SimpleOption( "rtable", "Export IFS rtable" ) ); + } private: - - bool list; - std::string key; - bool info; - bool json; - bool rtable; - bool do_run; + bool list; + std::string key; + bool info; + bool json; + bool rtable; + bool do_run; }; //------------------------------------------------------------------------------------------------------ -void AtlasGrids::execute(const Args& args) -{ - key = ""; - if( args.count() ) key = args(0); - - info = false; - args.get("info",info); - - if( info && !key.empty() ) do_run = true; - - json = false; - args.get("json",json); - if( json && !key.empty() ) do_run = true; - - rtable = false; - args.get("rtable",rtable); - if( rtable && !key.empty() ) do_run = true; - - list = false; - args.get("list",list); - if( list) do_run = true; - - if( !key.empty() && do_run == false ) - { - Log::error() << "Option wrong or missing after '" << key << "'" << std::endl; - } - if( list ) - { - std::vector keys = Factory::instance().keys(); - Log::info() << "usage: atlas-grids GRID [OPTION]... [--help]\n" << std::endl; - Log::info() << "Available grids:" << std::endl; - for(size_t i = 0; i < keys.size(); ++i) - { - Log::info() << " -- " << keys[i] << std::endl; - } - } - - if( !key.empty() ) - { - StructuredGrid grid; - try{ grid = Grid(key); } - catch( eckit::BadParameter& err ){} - - if( !grid ) return; - - 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; - if( auto gaussian = GaussianGrid(grid) ) { - 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; +void AtlasGrids::execute( const Args& args ) { + key = ""; + if ( args.count() ) key = args( 0 ); + + info = false; + args.get( "info", info ); + + if ( info && !key.empty() ) do_run = true; + + json = false; + args.get( "json", json ); + if ( json && !key.empty() ) do_run = true; + + rtable = false; + args.get( "rtable", rtable ); + if ( rtable && !key.empty() ) do_run = true; + + list = false; + args.get( "list", list ); + if ( list ) do_run = true; + if ( !key.empty() && do_run == false ) { + Log::error() << "Option wrong or missing after '" << key << "'" << std::endl; } - if( json ) - { - std::stringstream stream; - JSON js(stream); - js.precision(16); - js << grid.spec(); - std::cout << stream.str() << std::endl; + if ( list ) { + std::vector keys = Factory::instance().keys(); + Log::info() << "usage: atlas-grids GRID [OPTION]... [--help]\n" << std::endl; + Log::info() << "Available grids:" << std::endl; + for ( size_t i = 0; i < keys.size(); ++i ) { + Log::info() << " -- " << keys[i] << std::endl; + } } - if( rtable ) - { - std::stringstream stream; - stream << "&NAMRGRI\n"; - for(size_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 ( !key.empty() ) { + StructuredGrid grid; + try { + grid = Grid( key ); + } + catch ( eckit::BadParameter& err ) { + } + + if ( !grid ) return; + + 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; + if ( auto gaussian = GaussianGrid( grid ) ) { + 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; + } + if ( json ) { + std::stringstream stream; + JSON js( stream ); + js.precision( 16 ); + js << grid.spec(); + std::cout << stream.str() << std::endl; + } + + if ( rtable ) { + std::stringstream stream; + stream << "&NAMRGRI\n"; + for ( size_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; + } } - } } //------------------------------------------------------------------------------------------------------ -int main( int argc, char **argv ) -{ - AtlasGrids tool(argc,argv); - return tool.start(); +int main( int argc, char** argv ) { + AtlasGrids tool( argc, argv ); + return tool.start(); } diff --git a/src/apps/atlas-loadbalance.cc b/src/apps/atlas-loadbalance.cc index db03f3997..300b113dc 100644 --- a/src/apps/atlas-loadbalance.cc +++ b/src/apps/atlas-loadbalance.cc @@ -4,25 +4,26 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include +#include -#include "eckit/exception/Exceptions.h" -#include "eckit/config/Resource.h" -#include "eckit/runtime/Tool.h" +#include "atlas/functionspace/NodeColumns.h" +#include "atlas/grid.h" #include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/grid.h" -#include "atlas/runtime/Log.h" -#include "atlas/functionspace/NodeColumns.h" -#include "atlas/meshgenerator/MeshGenerator.h" #include "atlas/mesh/actions/WriteLoadBalanceReport.h" +#include "atlas/meshgenerator/MeshGenerator.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Log.h" +#include "eckit/config/Resource.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/runtime/Tool.h" //------------------------------------------------------------------------------------------------------ using eckit::Resource; @@ -35,110 +36,92 @@ using namespace atlas::mesh; //------------------------------------------------------------------------------------------------------ class AtlasLoadbalance : public eckit::Tool { - - virtual void run(); + virtual void run(); public: - - AtlasLoadbalance(int argc,char **argv): eckit::Tool(argc,argv) - { - bool help = Resource< bool >("--help",false); - - do_run = true; - - std::string help_str = - "NAME\n" - " atlas-loadbalance - \n" - "\n" - "SYNOPSIS\n" - " atlas-loadbalance GRID [OPTION]... [--help] \n" - "\n" - "DESCRIPTION\n" - "\n" - " GRID: unique identifier for grid \n" - " Example values: N80, F40, O24, L32\n" - "\n" - " --halo Output file for mesh\n" - "\n" - "AUTHOR\n" - " Written by Willem Deconinck.\n" - "\n" - "ECMWF September 2015" - ; - if( help ) - { - atlas::Log::info() << help_str << std::endl; - do_run = false; - } - - if( argc == 1 ) - { - atlas::Log::info() << "usage: atlas-loadbalance GRID [OPTION]... [--help]" << std::endl; - do_run = false; - } - - atlas::Library::instance().initialise(argc,argv); - - key = ""; - for( int i=0; i( "--help", false ); + + do_run = true; + + std::string help_str = + "NAME\n" + " atlas-loadbalance - \n" + "\n" + "SYNOPSIS\n" + " atlas-loadbalance GRID [OPTION]... [--help] \n" + "\n" + "DESCRIPTION\n" + "\n" + " GRID: unique identifier for grid \n" + " Example values: N80, F40, O24, L32\n" + "\n" + " --halo Output file for mesh\n" + "\n" + "AUTHOR\n" + " Written by Willem Deconinck.\n" + "\n" + "ECMWF September 2015"; + if ( help ) { + atlas::Log::info() << help_str << std::endl; + do_run = false; + } + + if ( argc == 1 ) { + atlas::Log::info() << "usage: atlas-loadbalance GRID [OPTION]... [--help]" << std::endl; + do_run = false; + } + + atlas::Library::instance().initialise( argc, argv ); + + key = ""; + for ( int i = 0; i < argc; ++i ) { + if ( i == 1 && argv[i][0] != '-' ) { key = std::string( argv[i] ); } + } + + halo = Resource( "--halo", 1 ); + output = Resource( "--output", "" ); } - halo = Resource< int > ( "--halo", 1 ); - output = Resource ("--output",""); - } - private: - - bool do_run; - std::string key; - int halo; - std::string output; - std::string identifier; + bool do_run; + std::string key; + int halo; + std::string output; + std::string identifier; }; //------------------------------------------------------------------------------------------------------ -void AtlasLoadbalance::run() -{ - if( !do_run ) return; +void AtlasLoadbalance::run() { + if ( !do_run ) return; - StructuredGrid grid; - try{ grid = Grid(key); } - catch( eckit::BadParameter& err ){} - - if( !grid ) return; - MeshGenerator meshgenerator("structured"); - Mesh mesh = meshgenerator.generate(grid); + StructuredGrid grid; + try { + grid = Grid( key ); + } + catch ( eckit::BadParameter& err ) { + } - functionspace::NodeColumns nodes(mesh,option::halo(halo)); + 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); - } - else - { - std::stringstream s; - write_load_balance_report(mesh,s); + 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(); + atlas::Library::instance().finalise(); } //------------------------------------------------------------------------------------------------------ -int main( int argc, char **argv ) -{ - AtlasLoadbalance tool(argc,argv); - return tool.start(); +int main( int argc, char** argv ) { + AtlasLoadbalance tool( argc, argv ); + return tool.start(); } diff --git a/src/apps/atlas-meshgen.cc b/src/apps/atlas-meshgen.cc index e90ba7f49..536769a6a 100644 --- a/src/apps/atlas-meshgen.cc +++ b/src/apps/atlas-meshgen.cc @@ -4,47 +4,47 @@ * 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 + * 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 -#include +#include +#include +#include #include +#include +#include -#include "atlas/library/Library.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/grid.h" -#include "atlas/runtime/AtlasTool.h" +#include "atlas/library/Library.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildDualMesh.h" #include "atlas/mesh/actions/BuildEdges.h" #include "atlas/mesh/actions/BuildHalo.h" #include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildPeriodicBoundaries.h" #include "atlas/mesh/actions/BuildStatistics.h" -#include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/mesh/actions/BuildTorusXYZField.h" +#include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/meshgenerator/MeshGenerator.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/mesh/Nodes.h" #include "atlas/output/Gmsh.h" -#include "atlas/runtime/Log.h" +#include "atlas/output/detail/GmshIO.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/AtlasTool.h" +#include "atlas/runtime/Log.h" #include "atlas/util/Config.h" -#include "atlas/output/detail/GmshIO.h" #include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" -#include "eckit/parser/Tokenizer.h" #include "eckit/log/Bytes.h" +#include "eckit/parser/Tokenizer.h" #include "eckit/runtime/Main.h" #include "eckit/runtime/Tool.h" - //------------------------------------------------------------------------------ using namespace atlas; @@ -58,213 +58,200 @@ using eckit::PathName; //------------------------------------------------------------------------------ class Meshgen2Gmsh : public AtlasTool { - - virtual void 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]"; - } + virtual void 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]"; } public: - - Meshgen2Gmsh(int argc,char **argv); + Meshgen2Gmsh( int argc, char** argv ); private: - - std::string key; - long halo; - bool edges; - bool brick; - bool stats; - bool info; - bool with_pole; - bool stitch_pole; - bool ghost; - bool binary; - std::string identifier; - std::vector reg_nlon_nlat; - std::vector fgg_nlon_nlat; - std::vector rgg_nlon; - PathName path_in; - PathName path_out; - + std::string key; + long halo; + bool edges; + bool brick; + bool stats; + bool info; + bool with_pole; + bool stitch_pole; + bool ghost; + bool binary; + std::string identifier; + std::vector reg_nlon_nlat; + std::vector fgg_nlon_nlat; + std::vector rgg_nlon; + PathName path_in; + PathName path_out; }; //----------------------------------------------------------------------------- -Meshgen2Gmsh::Meshgen2Gmsh(int argc,char **argv): AtlasTool(argc,argv) -{ - add_option( new SimpleOption("grid.name","Grid unique identifier\n" - +indent()+" Example values: N80, F40, O24, L32") ); - add_option( new SimpleOption("grid.json","Grid described by json file") ); - add_option( new SimpleOption("angle","Maximum element-edge slant deviation from meridian in degrees. \n" - +indent()+" Value range between 0 and 30\n" - +indent()+" 0: Mostly triangular, with only perfect quads\n" - +indent()+" 30: Mostly skewed quads with only triags when skewness becomes too large\n" - +indent()+" -1: Only triangles") ); - - add_option( new SimpleOption("include_pole","Include pole point") ); - add_option( new SimpleOption("patch_pole","Patch poles with elements.") ); - add_option( new SimpleOption("ghost","Output ghost elements") ); - add_option( new Separator("Advanced") ); - add_option( new SimpleOption("halo","Halo size") ); - add_option( new SimpleOption("edges","Build edge datastructure") ); - add_option( new SimpleOption("brick","Build brick dual mesh") ); - add_option( new SimpleOption("stats","Write statistics file") ); - add_option( new SimpleOption("info","Write Info") ); - add_option( new SimpleOption("binary","Write binary file") ); - add_option( new SimpleOption("generator","Mesh generator") ); - add_option( new SimpleOption("partitioner","Mesh partitioner") ); - add_option( new SimpleOption("periodic_x","periodic mesh in x-direction") ); - add_option( new SimpleOption("periodic_y","periodic mesh in y-direction") ); - add_option( new SimpleOption("torus","Output mesh as torus") ); - add_option( new SimpleOption("lonlat","Output mesh in lon-lat coordinates") ); - add_option( new SimpleOption("3d","Output mesh as sphere, and generate mesh connecting East and West in case serial") ); +Meshgen2Gmsh::Meshgen2Gmsh( int argc, char** argv ) : AtlasTool( argc, argv ) { + add_option( new SimpleOption( + "grid.name", "Grid unique identifier\n" + indent() + " Example values: N80, F40, O24, L32" ) ); + add_option( new SimpleOption( "grid.json", "Grid described by json file" ) ); + add_option( new SimpleOption( "angle", "Maximum element-edge slant deviation from meridian in degrees. \n" + + indent() + " Value range between 0 and 30\n" + indent() + + " 0: Mostly triangular, with only perfect quads\n" + + indent() + + " 30: Mostly skewed quads with only triags when " + "skewness becomes too large\n" + + indent() + " -1: Only triangles" ) ); + + add_option( new SimpleOption( "include_pole", "Include pole point" ) ); + add_option( new SimpleOption( "patch_pole", "Patch poles with elements." ) ); + add_option( new SimpleOption( "ghost", "Output ghost elements" ) ); + add_option( new Separator( "Advanced" ) ); + add_option( new SimpleOption( "halo", "Halo size" ) ); + add_option( new SimpleOption( "edges", "Build edge datastructure" ) ); + add_option( new SimpleOption( "brick", "Build brick dual mesh" ) ); + add_option( new SimpleOption( "stats", "Write statistics file" ) ); + add_option( new SimpleOption( "info", "Write Info" ) ); + add_option( new SimpleOption( "binary", "Write binary file" ) ); + add_option( new SimpleOption( "generator", "Mesh generator" ) ); + add_option( new SimpleOption( "partitioner", "Mesh partitioner" ) ); + add_option( new SimpleOption( "periodic_x", "periodic mesh in x-direction" ) ); + add_option( new SimpleOption( "periodic_y", "periodic mesh in y-direction" ) ); + add_option( new SimpleOption( "torus", "Output mesh as torus" ) ); + add_option( new SimpleOption( "lonlat", "Output mesh in lon-lat coordinates" ) ); + add_option( new SimpleOption( "3d", + "Output mesh as sphere, and generate " + "mesh connecting East and West in " + "case serial" ) ); } //----------------------------------------------------------------------------- -void Meshgen2Gmsh::execute(const Args& args) -{ - key = ""; - args.get("grid.name",key); - - edges = false; - args.get("edges",edges); - stats = false; - args.get("stats",stats); - info = false; - args.get("info",info); - halo = 0; - args.get("halo",halo); - bool dim_3d=false; - args.get("3d",dim_3d); - brick = false; - args.get("brick",brick); - ghost = false; - args.get("ghost",ghost); - binary = false; - args.get("binary",binary); - - std::string path_in_str = ""; - if( args.get("grid.json",path_in_str) ) path_in = path_in_str; - - if( args.count() ) - path_out = args(0); - else - path_out = "mesh.msh"; - - 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; - } - - - if( edges ) - halo = std::max(halo,1l); - - StructuredGrid grid; - if( key.size() ) - { - try{ grid = Grid(key); } - catch( eckit::BadParameter& e ){} - } - else if( path_in.path().size() ) - { - Log::info() << "Creating grid from file " << path_in << std::endl; - Log::debug() << Config(path_in) << std::endl; - try{ grid = Grid( Config(path_in) ); } - catch( eckit::BadParameter& e ){} - } - else - { - Log::error() << "No grid specified." << std::endl; - } - - if( !grid ) return; - - Log::debug() << "Domain: " << grid.domain() << std::endl; - Log::debug() << "Periodic: " << grid.periodic() << std::endl; - Log::debug() << "Spec: " << grid.spec() << std::endl; - - - 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); - - MeshGenerator meshgenerator(Implementationype,meshgenerator_config); - - Mesh mesh; - try { - mesh = meshgenerator.generate(grid); - } - catch ( eckit::BadParameter& e) - { - Log::error() << e.what() << std::endl; - Log::error() << e.callStack() << std::endl; - throw e; - } - - 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" << std::endl; - Log::warning() << "units: " << grid.projection().units() << std::endl; - } - if( edges ) - { - build_edges(mesh); - build_pole_edges(mesh); - build_edges_parallel_fields(mesh); - if( brick ) - build_brick_dual_mesh(grid, mesh); +void Meshgen2Gmsh::execute( const Args& args ) { + key = ""; + args.get( "grid.name", key ); + + edges = false; + args.get( "edges", edges ); + stats = false; + args.get( "stats", stats ); + info = false; + args.get( "info", info ); + halo = 0; + args.get( "halo", halo ); + bool dim_3d = false; + args.get( "3d", dim_3d ); + brick = false; + args.get( "brick", brick ); + ghost = false; + args.get( "ghost", ghost ); + binary = false; + args.get( "binary", binary ); + + std::string path_in_str = ""; + if ( args.get( "grid.json", path_in_str ) ) path_in = path_in_str; + + if ( args.count() ) + path_out = args( 0 ); else - build_median_dual_mesh(mesh); - } - - if( stats ) { - build_statistics(mesh); - } - - bool torus=false; - args.get("torus",torus); - if( torus ) { - dim_3d = true; - Log::debug() << "Building xyz representation for nodes on torus" << std::endl; - mesh::actions::BuildTorusXYZField("xyz")(mesh,grid.domain(),5.,2.,grid.nxmax(),grid.ny()); - } - - bool lonlat = false; - args.get("lonlat",lonlat); - - atlas::output::Gmsh gmsh( path_out , Config - ("info",info) - ("ghost",ghost) - ("coordinates", dim_3d ? "xyz" : lonlat ? "lonlat" : "xy" ) - ("edges",edges ) - ("binary",binary ) - ); - Log::info() << "Writing mesh to gmsh file \"" << path_out << "\" generated from grid \"" << grid.name() << "\"" << std::endl; - gmsh.write( mesh ); - - if( info ) { - Log::info() << "Partitioning graph: \n" << mesh.partitionGraph() << std::endl; - Log::info() << "Mesh partition footprint: " << eckit::Bytes(mesh.footprint()) << std::endl; - for( size_t jhalo=0; jhalo<=halo; ++jhalo ) { - mesh.polygon(jhalo).outputPythonScript("polygon_halo"+std::to_string(jhalo)+".py"); + path_out = "mesh.msh"; + + 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; + } + + if ( edges ) halo = std::max( halo, 1l ); + + StructuredGrid grid; + if ( key.size() ) { + try { + grid = Grid( key ); + } + catch ( eckit::BadParameter& e ) { + } + } + else if ( path_in.path().size() ) { + Log::info() << "Creating grid from file " << path_in << std::endl; + Log::debug() << Config( path_in ) << std::endl; + try { + grid = Grid( Config( path_in ) ); + } + catch ( eckit::BadParameter& e ) { + } + } + else { + Log::error() << "No grid specified." << std::endl; + } + + if ( !grid ) return; + + Log::debug() << "Domain: " << grid.domain() << std::endl; + Log::debug() << "Periodic: " << grid.periodic() << std::endl; + Log::debug() << "Spec: " << grid.spec() << std::endl; + + 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 ); + + MeshGenerator meshgenerator( Implementationype, meshgenerator_config ); + + Mesh mesh; + try { + mesh = meshgenerator.generate( grid ); + } + catch ( eckit::BadParameter& e ) { + Log::error() << e.what() << std::endl; + Log::error() << e.callStack() << std::endl; + throw e; + } + + 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" + << std::endl; + Log::warning() << "units: " << grid.projection().units() << std::endl; + } + if ( edges ) { + build_edges( mesh ); + build_pole_edges( mesh ); + build_edges_parallel_fields( mesh ); + if ( brick ) + build_brick_dual_mesh( grid, mesh ); + else + build_median_dual_mesh( mesh ); + } + + if ( stats ) { build_statistics( mesh ); } + + bool torus = false; + args.get( "torus", torus ); + if ( torus ) { + dim_3d = true; + Log::debug() << "Building xyz representation for nodes on torus" << std::endl; + mesh::actions::BuildTorusXYZField( "xyz" )( mesh, grid.domain(), 5., 2., grid.nxmax(), grid.ny() ); + } + + bool lonlat = false; + args.get( "lonlat", lonlat ); + + atlas::output::Gmsh gmsh( + path_out, Config( "info", info )( "ghost", ghost )( "coordinates", dim_3d ? "xyz" : lonlat ? "lonlat" : "xy" )( + "edges", edges )( "binary", binary ) ); + Log::info() << "Writing mesh to gmsh file \"" << path_out << "\" generated from grid \"" << grid.name() << "\"" + << std::endl; + gmsh.write( mesh ); + + if ( info ) { + Log::info() << "Partitioning graph: \n" << mesh.partitionGraph() << std::endl; + Log::info() << "Mesh partition footprint: " << eckit::Bytes( mesh.footprint() ) << std::endl; + for ( size_t jhalo = 0; jhalo <= halo; ++jhalo ) { + mesh.polygon( jhalo ).outputPythonScript( "polygon_halo" + std::to_string( jhalo ) + ".py" ); + } } - } } //------------------------------------------------------------------------------ -int main( int argc, char **argv ) -{ - Meshgen2Gmsh tool(argc,argv); - return tool.start(); +int main( int argc, char** argv ) { + Meshgen2Gmsh tool( argc, argv ); + return tool.start(); } diff --git a/src/apps/atlas.cc b/src/apps/atlas.cc index ba28ee409..920956b6e 100644 --- a/src/apps/atlas.cc +++ b/src/apps/atlas.cc @@ -4,15 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - -#include "eckit/runtime/Tool.h" -#include "eckit/config/Resource.h" #include "atlas/library/Library.h" #include "atlas/runtime/Log.h" +#include "eckit/config/Resource.h" +#include "eckit/runtime/Tool.h" using namespace eckit; namespace atlas { @@ -21,73 +21,66 @@ namespace atlas { class Version : public Tool { public: - - Version(int argc,char **argv): Tool(argc,argv) {} + Version( int argc, char** argv ) : Tool( argc, argv ) {} ~Version() {} virtual void run(); }; -void Version::run() -{ - if( Resource("--version",false) ) - { - Log::info() << atlas::Library::instance().version() << std::endl; - return; - } - else if( Resource("--git",false) ) - { - Log::info() << atlas::Library::instance().gitsha1(12) << std::endl; - return; - } - else if( Resource("--info",false) ) - { - Log::info() << atlas::Library::instance().information() << std::endl; - return; - } - else if( Resource("--help",false) ) - { - Log::info() << - "NAME\n" - " atlas - Framework for parallel flexible data structures on the sphere\n" - "\n" - "SYNOPSIS\n" - " atlas [--help] [--version] [--git] [--info]\n" - "\n" - "DESCRIPTION\n" - " Framework for parallel flexible data structures on the sphere.\n" - "\n" - "OPTIONS\n" - " --help\n" - " Print this help\n" - "\n" - " --version\n" - " Print short version string 'MAJOR.MINOR.PATCH' \n" - "\n" - " --info\n" - " Print build configuration anad features\n" - "\n" - "AUTHOR\n" - " Written by Willem Deconinck.\n" - "\n" - "ECMWF December 2014" - << std::endl; - return; - } - else - Log::info() << "usage: atlas [--help] [--version] [--git] [--info]" << std::endl; +void Version::run() { + if ( Resource( "--version", false ) ) { + Log::info() << atlas::Library::instance().version() << std::endl; + return; + } + else if ( Resource( "--git", false ) ) { + Log::info() << atlas::Library::instance().gitsha1( 12 ) << std::endl; + return; + } + else if ( Resource( "--info", false ) ) { + Log::info() << atlas::Library::instance().information() << std::endl; + return; + } + else if ( Resource( "--help", false ) ) { + Log::info() << "NAME\n" + " atlas - Framework for parallel flexible data structures on " + "the sphere\n" + "\n" + "SYNOPSIS\n" + " atlas [--help] [--version] [--git] [--info]\n" + "\n" + "DESCRIPTION\n" + " Framework for parallel flexible data structures on the " + "sphere.\n" + "\n" + "OPTIONS\n" + " --help\n" + " Print this help\n" + "\n" + " --version\n" + " Print short version string 'MAJOR.MINOR.PATCH' \n" + "\n" + " --info\n" + " Print build configuration anad features\n" + "\n" + "AUTHOR\n" + " Written by Willem Deconinck.\n" + "\n" + "ECMWF December 2014" + << std::endl; + return; + } + else + Log::info() << "usage: atlas [--help] [--version] [--git] [--info]" << std::endl; } -} // namespace atlas +} // namespace atlas //---------------------------------------------------------------------------------------------------------------------- using namespace atlas; -int main(int argc,char **argv) -{ - Version tool(argc,argv); +int main( int argc, char** argv ) { + Version tool( argc, argv ); return tool.start(); } - diff --git a/src/atlas/array.h b/src/atlas/array.h index 1daa3b2ad..b492b9276 100644 --- a/src/atlas/array.h +++ b/src/atlas/array.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -23,5 +24,3 @@ #include "atlas/array/MakeView.h" #include "atlas/array/Table.h" //#include "atlas/array/TableView.h" - - diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index e6b5235b9..e12183f0d 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -4,18 +4,19 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include "eckit/memory/Owned.h" -#include "atlas/library/config.h" -#include "atlas/array_fwd.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" +#include "atlas/array_fwd.h" +#include "atlas/library/config.h" +#include "eckit/memory/Owned.h" namespace atlas { namespace array { @@ -23,154 +24,182 @@ namespace array { // -------------------------------------------------------------------------------------------- // Forward declarations -template class ArrayT; -template class ArrayT_impl; +template +class ArrayT; +template +class ArrayT_impl; // -------------------------------------------------------------------------------------------- class Array : public eckit::Owned { public: - virtual ~Array(); + virtual ~Array(); - static Array* create( array::DataType, const ArrayShape& ); + static Array* create( array::DataType, const ArrayShape& ); - static Array* create( array::DataType, const ArrayShape&, const ArrayLayout& ); + static Array* create( array::DataType, const ArrayShape&, const ArrayLayout& ); - virtual size_t footprint() const = 0; + virtual size_t footprint() const = 0; - template static Array* create(size_t size0); - template static Array* create(size_t size0, size_t size1); - template static Array* create(size_t size0, size_t size1, size_t size2); - template static Array* create(size_t size0, size_t size1, size_t size2, size_t size3); - template static Array* create(size_t size0, size_t size1, size_t size2, size_t size3, size_t size4); + template + static Array* create( size_t size0 ); + template + static Array* create( size_t size0, size_t size1 ); + template + static Array* create( size_t size0, size_t size1, size_t size2 ); + template + static Array* create( size_t size0, size_t size1, size_t size2, size_t size3 ); + template + static Array* create( size_t size0, size_t size1, size_t size2, size_t size3, size_t size4 ); - template static Array* create(const ArrayShape& shape); + template + static Array* create( const ArrayShape& shape ); - template static Array* create(const ArrayShape& shape, const ArrayLayout& layout); + template + static Array* create( const ArrayShape& shape, const ArrayLayout& layout ); - template static Array* wrap(Value* data, const ArrayShape& shape); + template + static Array* wrap( Value* data, const ArrayShape& shape ); - template static Array* wrap(Value* data, const ArraySpec& spec); + template + static Array* wrap( Value* data, const ArraySpec& spec ); - size_t bytes() const { return sizeof_data() * spec().allocatedSize();} + size_t bytes() const { return sizeof_data() * spec().allocatedSize(); } - size_t size() const { return spec_.size(); } + size_t size() const { return spec_.size(); } - size_t rank() const { return spec_.rank(); } + size_t rank() const { return spec_.rank(); } - size_t stride(size_t i) const { return spec_.strides()[i]; } + size_t stride( size_t i ) const { return spec_.strides()[i]; } - size_t shape(size_t i) const { return spec_.shape()[i]; } + size_t shape( size_t i ) const { return spec_.shape()[i]; } - const ArrayStrides& strides() const { return spec_.strides(); } + const ArrayStrides& strides() const { return spec_.strides(); } - const ArrayShape& shape() const { return spec_.shape(); } + const ArrayShape& shape() const { return spec_.shape(); } - const std::vector& shapef() const { return spec_.shapef(); } + const std::vector& shapef() const { return spec_.shapef(); } - const std::vector& stridesf() const { return spec_.stridesf(); } + const std::vector& stridesf() const { return spec_.stridesf(); } - bool contiguous() const { return spec_.contiguous(); } + bool contiguous() const { return spec_.contiguous(); } - bool hasDefaultLayout() const { return spec_.hasDefaultLayout(); } + bool hasDefaultLayout() const { return spec_.hasDefaultLayout(); } - virtual array::DataType datatype() const = 0; + virtual array::DataType datatype() const = 0; - virtual size_t sizeof_data() const = 0; + virtual size_t sizeof_data() const = 0; - virtual void resize(const ArrayShape& shape) = 0; + virtual void resize( const ArrayShape& shape ) = 0; - virtual void resize(size_t size0) = 0; - virtual void resize(size_t size0, size_t size1) = 0; - virtual void resize(size_t size0, size_t size1, size_t size2) = 0; - virtual void resize(size_t size0, size_t size1, size_t size2, size_t size3) = 0; - virtual void resize(size_t size0, size_t size1, size_t size2, size_t size3, size_t size4) = 0; + virtual void resize( size_t size0 ) = 0; + virtual void resize( size_t size0, size_t size1 ) = 0; + virtual void resize( size_t size0, size_t size1, size_t size2 ) = 0; + virtual void resize( size_t size0, size_t size1, size_t size2, size_t size3 ) = 0; + virtual void resize( size_t size0, size_t size1, size_t size2, size_t size3, size_t size4 ) = 0; - virtual void insert(size_t idx1, size_t size1) = 0; + virtual void insert( size_t idx1, size_t size1 ) = 0; - virtual void dump(std::ostream& os) const = 0; + virtual void dump( std::ostream& os ) const = 0; - virtual bool accMap() const = 0; + virtual bool accMap() const = 0; - virtual void* storage() { return data_store_->voidDataStore();} + virtual void* storage() { return data_store_->voidDataStore(); } - virtual const void* storage() const { return data_store_->voidDataStore();} + virtual const void* storage() const { return data_store_->voidDataStore(); } - void cloneToDevice() const { data_store_->cloneToDevice(); } + void cloneToDevice() const { data_store_->cloneToDevice(); } - void cloneFromDevice() const { data_store_->cloneFromDevice(); } + void cloneFromDevice() const { data_store_->cloneFromDevice(); } - bool valid() const { return data_store_->valid(); } + bool valid() const { return data_store_->valid(); } - void syncHostDevice() const { data_store_->syncHostDevice(); } + void syncHostDevice() const { data_store_->syncHostDevice(); } - bool hostNeedsUpdate() const { return data_store_->hostNeedsUpdate(); } + bool hostNeedsUpdate() const { return data_store_->hostNeedsUpdate(); } - bool deviceNeedsUpdate() const { return data_store_->deviceNeedsUpdate(); } + bool deviceNeedsUpdate() const { return data_store_->deviceNeedsUpdate(); } - void reactivateDeviceWriteViews() const { data_store_->reactivateDeviceWriteViews(); } + void reactivateDeviceWriteViews() const { data_store_->reactivateDeviceWriteViews(); } - void reactivateHostWriteViews() const { data_store_->reactivateHostWriteViews(); } + void reactivateHostWriteViews() const { data_store_->reactivateHostWriteViews(); } - const ArraySpec& spec() const {return spec_;} + const ArraySpec& spec() const { return spec_; } - // -- dangerous methods... You're on your own interpreting the raw data - template DATATYPE const* host_data() const { return data_store_->hostData(); } - template DATATYPE* host_data() { return data_store_->hostData(); } - template DATATYPE const* device_data() const { return data_store_->deviceData(); } - template DATATYPE* device_data() { return data_store_->deviceData(); } - template DATATYPE const* data() const { return data_store_->hostData(); } - template DATATYPE* data() { return data_store_->hostData(); } + // -- dangerous methods... You're on your own interpreting the raw data + template + DATATYPE const* host_data() const { + return data_store_->hostData(); + } + template + DATATYPE* host_data() { + return data_store_->hostData(); + } + template + DATATYPE const* device_data() const { + return data_store_->deviceData(); + } + template + DATATYPE* device_data() { + return data_store_->deviceData(); + } + template + DATATYPE const* data() const { + return data_store_->hostData(); + } + template + DATATYPE* data() { + return data_store_->hostData(); + } - ArrayDataStore const* data_store() const { return data_store_.get();} + ArrayDataStore const* data_store() const { return data_store_.get(); } protected: + ArraySpec spec_; + std::unique_ptr data_store_; - ArraySpec spec_; - std::unique_ptr data_store_; - - void replace(Array& array) { - data_store_.swap(array.data_store_); - spec_ = array.spec_; - } - + void replace( Array& array ) { + data_store_.swap( array.data_store_ ); + spec_ = array.spec_; + } }; // -------------------------------------------------------------------------------------------- -template class ArrayT : public Array { +template +class ArrayT : public Array { public: + ArrayT( size_t size0 ); + ArrayT( size_t size0, size_t size1 ); + ArrayT( size_t size0, size_t size1, size_t size2 ); + ArrayT( size_t size0, size_t size1, size_t size2, size_t size3 ); + ArrayT( size_t size0, size_t size1, size_t size2, size_t size3, size_t size4 ); - ArrayT(size_t size0); - ArrayT(size_t size0, size_t size1); - ArrayT(size_t size0, size_t size1, size_t size2); - ArrayT(size_t size0, size_t size1, size_t size2, size_t size3); - ArrayT(size_t size0, size_t size1, size_t size2, size_t size3, size_t size4); - - ArrayT(const ArraySpec&); + ArrayT( const ArraySpec& ); - ArrayT(const ArrayShape&); + ArrayT( const ArrayShape& ); - ArrayT(const ArrayShape&, const ArrayLayout&); + ArrayT( const ArrayShape&, const ArrayLayout& ); - virtual void insert(size_t idx1, size_t size1); + virtual void insert( size_t idx1, size_t size1 ); - virtual void resize(const ArrayShape&); + virtual void resize( const ArrayShape& ); - virtual void resize(size_t size0); - virtual void resize(size_t size0, size_t size1); - virtual void resize(size_t size0, size_t size1, size_t size2); - virtual void resize(size_t size0, size_t size1, size_t size2, size_t size3); - virtual void resize(size_t size0, size_t size1, size_t size2, size_t size3, size_t size4); + virtual void resize( size_t size0 ); + virtual void resize( size_t size0, size_t size1 ); + virtual void resize( size_t size0, size_t size1, size_t size2 ); + virtual void resize( size_t size0, size_t size1, size_t size2, size_t size3 ); + virtual void resize( size_t size0, size_t size1, size_t size2, size_t size3, size_t size4 ); virtual array::DataType datatype() const { return array::DataType::create(); } - virtual size_t sizeof_data() const {return sizeof(Value);} + virtual size_t sizeof_data() const { return sizeof( Value ); } - virtual void dump(std::ostream& os) const; + virtual void dump( std::ostream& os ) const; - // This constructor is used through the Array::create() or the Array::wrap() methods - ArrayT(ArrayDataStore*, const ArraySpec&); + // This constructor is used through the Array::create() or the Array::wrap() + // methods + ArrayT( ArrayDataStore*, const ArraySpec& ); virtual size_t footprint() const; @@ -182,5 +211,5 @@ template class ArrayT : public Array { mutable bool acc_map_{false}; }; -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArrayIdx.h b/src/atlas/array/ArrayIdx.h index e97ba05c7..ebb59df8c 100644 --- a/src/atlas/array/ArrayIdx.h +++ b/src/atlas/array/ArrayIdx.h @@ -4,7 +4,8 @@ * 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 size_tergovernmental organisation nor + * granted to it by virtue of its status as an size_tergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -20,12 +21,32 @@ namespace array { typedef std::vector ArrayIdx; -inline ArrayIdx make_idx(size_t size1) { return std::vector(1,size1); } -inline ArrayIdx make_idx(size_t size1, size_t size2) { std::vector v(2); v[0]=size1; v[1]=size2; return v; } -inline ArrayIdx make_idx(size_t size1, size_t size2, size_t size3) { std::vector v(3); v[0]=size1; v[1]=size2; v[2]=size3; return v; } -inline ArrayIdx make_idx(size_t size1, size_t size2, size_t size3, size_t size4) { std::vector v(4); v[0]=size1; v[1]=size2; v[2]=size3; v[3]=size4; return v; } +inline ArrayIdx make_idx( size_t size1 ) { + return std::vector( 1, size1 ); +} +inline ArrayIdx make_idx( size_t size1, size_t size2 ) { + std::vector v( 2 ); + v[0] = size1; + v[1] = size2; + return v; +} +inline ArrayIdx make_idx( size_t size1, size_t size2, size_t size3 ) { + std::vector v( 3 ); + v[0] = size1; + v[1] = size2; + v[2] = size3; + return v; +} +inline ArrayIdx make_idx( size_t size1, size_t size2, size_t size3, size_t size4 ) { + std::vector v( 4 ); + v[0] = size1; + v[1] = size2; + v[2] = size3; + v[3] = size4; + return v; +} //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArrayLayout.h b/src/atlas/array/ArrayLayout.h index 5e9dbfb9f..f8bef5b3d 100644 --- a/src/atlas/array/ArrayLayout.h +++ b/src/atlas/array/ArrayLayout.h @@ -4,7 +4,8 @@ * 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 size_tergovernmental organisation nor + * granted to it by virtue of its status as an size_tergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -20,20 +21,31 @@ namespace array { class ArrayLayout : public std::vector { private: - using Base = std::vector; + using Base = std::vector; + public: ArrayLayout() {} - ArrayLayout( std::initializer_list list ) : Base(list) {} - ArrayLayout( Base&& base ) : Base( std::forward(base) ) {} + ArrayLayout( std::initializer_list list ) : Base( list ) {} + ArrayLayout( Base&& base ) : Base( std::forward( base ) ) {} }; -inline ArrayLayout make_layout(size_t size1) { return ArrayLayout{size1}; } -inline ArrayLayout make_layout(size_t size1, size_t size2) { return ArrayLayout{size1,size2}; } -inline ArrayLayout make_layout(size_t size1, size_t size2, size_t size3) { return ArrayLayout{size1,size2,size3}; } -inline ArrayLayout make_layout(size_t size1, size_t size2, size_t size3, size_t size4) { return ArrayLayout{size1,size2,size3,size4}; } -inline ArrayLayout make_layout(size_t size1, size_t size2, size_t size3, size_t size4, size_t size5) { return ArrayLayout{size1,size2,size3,size4,size5}; } +inline ArrayLayout make_layout( size_t size1 ) { + return ArrayLayout{size1}; +} +inline ArrayLayout make_layout( size_t size1, size_t size2 ) { + return ArrayLayout{size1, size2}; +} +inline ArrayLayout make_layout( size_t size1, size_t size2, size_t size3 ) { + return ArrayLayout{size1, size2, size3}; +} +inline ArrayLayout make_layout( size_t size1, size_t size2, size_t size3, size_t size4 ) { + return ArrayLayout{size1, size2, size3, size4}; +} +inline ArrayLayout make_layout( size_t size1, size_t size2, size_t size3, size_t size4, size_t size5 ) { + return ArrayLayout{size1, size2, size3, size4, size5}; +} //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArrayShape.h b/src/atlas/array/ArrayShape.h index 1876dc62c..bf1dca01e 100644 --- a/src/atlas/array/ArrayShape.h +++ b/src/atlas/array/ArrayShape.h @@ -4,7 +4,8 @@ * 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 size_tergovernmental organisation nor + * granted to it by virtue of its status as an size_tergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -20,30 +21,44 @@ namespace array { class ArrayAlignment { public: - ArrayAlignment() : alignment_(1) {} - ArrayAlignment( int alignment ) : alignment_(alignment) {} - operator int() const { return alignment_; } + ArrayAlignment() : alignment_( 1 ) {} + ArrayAlignment( int alignment ) : alignment_( alignment ) {} + operator int() const { return alignment_; } + private: - int alignment_; + int alignment_; }; class ArrayShape : public std::vector { private: - using Base = std::vector; + using Base = std::vector; + public: ArrayShape() {} - ArrayShape( Base&& base ) : Base( std::forward(base) ) {} - ArrayShape( std::initializer_list list ) : Base(list) {} + ArrayShape( Base&& base ) : Base( std::forward( base ) ) {} + ArrayShape( std::initializer_list list ) : Base( list ) {} }; -inline ArrayShape make_shape(std::initializer_list sizes) { return ArrayShape(sizes); } -inline ArrayShape make_shape(size_t size1) { return ArrayShape{size1}; } -inline ArrayShape make_shape(size_t size1, size_t size2) { return ArrayShape{size1,size2}; } -inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3) { return ArrayShape{size1,size2,size3}; } -inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3, size_t size4) { return ArrayShape{size1,size2,size3,size4}; } -inline ArrayShape make_shape(size_t size1, size_t size2, size_t size3, size_t size4, size_t size5) { return ArrayShape{size1,size2,size3,size4,size5}; } +inline ArrayShape make_shape( std::initializer_list sizes ) { + return ArrayShape( sizes ); +} +inline ArrayShape make_shape( size_t size1 ) { + return ArrayShape{size1}; +} +inline ArrayShape make_shape( size_t size1, size_t size2 ) { + return ArrayShape{size1, size2}; +} +inline ArrayShape make_shape( size_t size1, size_t size2, size_t size3 ) { + return ArrayShape{size1, size2, size3}; +} +inline ArrayShape make_shape( size_t size1, size_t size2, size_t size3, size_t size4 ) { + return ArrayShape{size1, size2, size3, size4}; +} +inline ArrayShape make_shape( size_t size1, size_t size2, size_t size3, size_t size4, size_t size5 ) { + return ArrayShape{size1, size2, size3, size4, size5}; +} //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArraySpec.cc b/src/atlas/array/ArraySpec.cc index 7f88c5065..055e9ea6f 100644 --- a/src/atlas/array/ArraySpec.cc +++ b/src/atlas/array/ArraySpec.cc @@ -4,134 +4,116 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include -#include "eckit/exception/Exceptions.h" #include "atlas/array/ArrayUtil.h" +#include "eckit/exception/Exceptions.h" namespace atlas { namespace array { namespace { - size_t compute_allocated_size( size_t size, int alignment ) { - int div = size/alignment; - int mod = size%alignment; - size_t _allocated_size = div*alignment; - if( mod > 0 ) _allocated_size += alignment; +size_t compute_allocated_size( size_t size, int alignment ) { + int div = size / alignment; + int mod = size % alignment; + size_t _allocated_size = div * alignment; + if ( mod > 0 ) _allocated_size += alignment; return _allocated_size; - } } +} // namespace -ArraySpec::ArraySpec(): - size_(), - rank_(), - allocated_size_(), - contiguous_(true), - default_layout_(true) -{ -} +ArraySpec::ArraySpec() : size_(), rank_(), allocated_size_(), contiguous_( true ), default_layout_( true ) {} -ArraySpec::ArraySpec( const ArrayShape& shape ) : - ArraySpec( shape, ArrayAlignment() ) { -} +ArraySpec::ArraySpec( const ArrayShape& shape ) : ArraySpec( shape, ArrayAlignment() ) {} -ArraySpec::ArraySpec( const ArrayShape& shape, ArrayAlignment&& alignment ) -{ - if( int(alignment) > 1 ) NOTIMP; // innermost dimension needs to be padded - - rank_ = shape.size(); - size_ = 1; - shape_.resize(rank_); - strides_.resize(rank_); - layout_.resize(rank_); - for( int j=rank_-1; j>=0; --j ) { - shape_[j] = shape[j]; - strides_[j] = size_; - layout_[j] = j; - size_ *= shape_[j]; - } - allocated_size_ = compute_allocated_size(size_,alignment); - contiguous_ = true; - default_layout_ = true; -}; - -ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides ) : - ArraySpec( shape, strides, ArrayAlignment() ) { -} +ArraySpec::ArraySpec( const ArrayShape& shape, ArrayAlignment&& alignment ) { + if ( int( alignment ) > 1 ) NOTIMP; // innermost dimension needs to be padded -ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, ArrayAlignment&& alignment ) -{ - if( shape.size() != strides.size() ) - throw eckit::BadParameter("dimensions of shape and stride don't match", Here()); - - rank_ = shape.size(); - size_ = 1; - shape_.resize(rank_); - strides_.resize(rank_); - layout_.resize(rank_); - for( int j=rank_-1; j>=0; --j ) { - shape_[j] = shape[j]; - strides_[j] = strides[j]; - layout_[j] = j; - size_ *= shape_[j]; - } - allocated_size_ = compute_allocated_size(shape_[0]*strides_[0],alignment); - contiguous_ = (size_ == allocated_size_); - default_layout_ = true; -} + rank_ = shape.size(); + size_ = 1; + shape_.resize( rank_ ); + strides_.resize( rank_ ); + layout_.resize( rank_ ); + for ( int j = rank_ - 1; j >= 0; --j ) { + shape_[j] = shape[j]; + strides_[j] = size_; + layout_[j] = j; + size_ *= shape_[j]; + } + allocated_size_ = compute_allocated_size( size_, alignment ); + contiguous_ = true; + default_layout_ = true; +}; -ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, const ArrayLayout& layout ) : - ArraySpec( shape, strides, layout, ArrayAlignment() ) { +ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides ) : + ArraySpec( shape, strides, ArrayAlignment() ) {} + +ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, ArrayAlignment&& alignment ) { + if ( shape.size() != strides.size() ) + throw eckit::BadParameter( "dimensions of shape and stride don't match", Here() ); + + rank_ = shape.size(); + size_ = 1; + shape_.resize( rank_ ); + strides_.resize( rank_ ); + layout_.resize( rank_ ); + for ( int j = rank_ - 1; j >= 0; --j ) { + shape_[j] = shape[j]; + strides_[j] = strides[j]; + layout_[j] = j; + size_ *= shape_[j]; + } + allocated_size_ = compute_allocated_size( shape_[0] * strides_[0], alignment ); + contiguous_ = ( size_ == allocated_size_ ); + default_layout_ = true; } -ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, const ArrayLayout& layout, ArrayAlignment&& alignment ) -{ - if( shape.size() != strides.size() ) - throw eckit::BadParameter("dimensions of shape and stride don't match", Here()); - - rank_ = shape.size(); - size_ = 1; - shape_.resize(rank_); - strides_.resize(rank_); - layout_.resize(rank_); - default_layout_ = true; - for( int j=rank_-1; j>=0; --j ) { - shape_[j] = shape[j]; - strides_[j] = strides[j]; - layout_[j] = layout[j]; - size_ *= shape_[j]; - if( layout_[j] != size_t(j) ) { - default_layout_ = false; +ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, const ArrayLayout& layout ) : + ArraySpec( shape, strides, layout, ArrayAlignment() ) {} + +ArraySpec::ArraySpec( const ArrayShape& shape, const ArrayStrides& strides, const ArrayLayout& layout, + ArrayAlignment&& alignment ) { + if ( shape.size() != strides.size() ) + throw eckit::BadParameter( "dimensions of shape and stride don't match", Here() ); + + rank_ = shape.size(); + size_ = 1; + shape_.resize( rank_ ); + strides_.resize( rank_ ); + layout_.resize( rank_ ); + default_layout_ = true; + for ( int j = rank_ - 1; j >= 0; --j ) { + shape_[j] = shape[j]; + strides_[j] = strides[j]; + layout_[j] = layout[j]; + size_ *= shape_[j]; + if ( layout_[j] != size_t( j ) ) { default_layout_ = false; } } - } - allocated_size_ = compute_allocated_size(shape_[layout_[0]]*strides_[layout_[0]],alignment); - contiguous_ = (size_ == allocated_size_); + allocated_size_ = compute_allocated_size( shape_[layout_[0]] * strides_[layout_[0]], alignment ); + contiguous_ = ( size_ == allocated_size_ ); } -const std::vector& ArraySpec::shapef() const -{ - if( shapef_.empty() ) { - shapef_.resize(rank_); - for( size_t j=0; j& ArraySpec::shapef() const { + if ( shapef_.empty() ) { + shapef_.resize( rank_ ); + for ( size_t j = 0; j < rank_; ++j ) { + shapef_[j] = shape_[rank_ - 1 - layout_[j]]; + } } - } - return shapef_; + return shapef_; } -const std::vector& ArraySpec::stridesf() const -{ - if( stridesf_.empty() ) - { - stridesf_.resize(strides().size()); - std::reverse_copy( strides().begin(), strides().end(), stridesf_.begin() ); - } - return stridesf_; +const std::vector& ArraySpec::stridesf() const { + if ( stridesf_.empty() ) { + stridesf_.resize( strides().size() ); + std::reverse_copy( strides().begin(), strides().end(), stridesf_.begin() ); + } + return stridesf_; } - -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArraySpec.h b/src/atlas/array/ArraySpec.h index db6274cf7..4f13e4fdb 100644 --- a/src/atlas/array/ArraySpec.h +++ b/src/atlas/array/ArraySpec.h @@ -4,7 +4,8 @@ * 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 size_tergovernmental organisation nor + * granted to it by virtue of its status as an size_tergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,10 +14,10 @@ #include #include +#include "atlas/array/ArrayIdx.h" +#include "atlas/array/ArrayLayout.h" #include "atlas/array/ArrayShape.h" #include "atlas/array/ArrayStrides.h" -#include "atlas/array/ArrayLayout.h" -#include "atlas/array/ArrayIdx.h" //------------------------------------------------------------------------------------------------------ @@ -25,39 +26,40 @@ namespace array { class ArraySpec { private: - size_t size_; - size_t rank_; - size_t allocated_size_; - ArrayShape shape_; - ArrayStrides strides_; - ArrayLayout layout_; - ArrayAlignment alignment_; - mutable std::vector shapef_; - mutable std::vector stridesf_; - bool contiguous_; - bool default_layout_; + size_t size_; + size_t rank_; + size_t allocated_size_; + ArrayShape shape_; + ArrayStrides strides_; + ArrayLayout layout_; + ArrayAlignment alignment_; + mutable std::vector shapef_; + mutable std::vector stridesf_; + bool contiguous_; + bool default_layout_; + public: - ArraySpec(); - ArraySpec( const ArrayShape& ); - ArraySpec( const ArrayShape&, const ArrayStrides& ); - ArraySpec( const ArrayShape&, const ArrayStrides&, const ArrayLayout& ); - ArraySpec( const ArrayShape&, ArrayAlignment&& ); - ArraySpec( const ArrayShape&, const ArrayStrides&, ArrayAlignment&& ); - ArraySpec( const ArrayShape&, const ArrayStrides&, const ArrayLayout&, ArrayAlignment&& ); - size_t allocatedSize() const { return allocated_size_; } - size_t size() const { return size_; } - size_t rank() const { return rank_; } - const ArrayShape& shape() const { return shape_; } - const ArrayAlignment& alignment() const { return alignment_; } - const ArrayStrides& strides() const { return strides_; } - const ArrayLayout& layout() const { return layout_; } - const std::vector& shapef() const; - const std::vector& stridesf() const; - bool contiguous() const { return contiguous_; } - bool hasDefaultLayout() const { return default_layout_; } + ArraySpec(); + ArraySpec( const ArrayShape& ); + ArraySpec( const ArrayShape&, const ArrayStrides& ); + ArraySpec( const ArrayShape&, const ArrayStrides&, const ArrayLayout& ); + ArraySpec( const ArrayShape&, ArrayAlignment&& ); + ArraySpec( const ArrayShape&, const ArrayStrides&, ArrayAlignment&& ); + ArraySpec( const ArrayShape&, const ArrayStrides&, const ArrayLayout&, ArrayAlignment&& ); + size_t allocatedSize() const { return allocated_size_; } + size_t size() const { return size_; } + size_t rank() const { return rank_; } + const ArrayShape& shape() const { return shape_; } + const ArrayAlignment& alignment() const { return alignment_; } + const ArrayStrides& strides() const { return strides_; } + const ArrayLayout& layout() const { return layout_; } + const std::vector& shapef() const; + const std::vector& stridesf() const; + bool contiguous() const { return contiguous_; } + bool hasDefaultLayout() const { return default_layout_; } }; //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArrayStrides.h b/src/atlas/array/ArrayStrides.h index 91ce60754..4c087c9c8 100644 --- a/src/atlas/array/ArrayStrides.h +++ b/src/atlas/array/ArrayStrides.h @@ -4,15 +4,16 @@ * 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 size_tergovernmental organisation nor + * granted to it by virtue of its status as an size_tergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include #include +#include //------------------------------------------------------------------------------------------------------ @@ -21,21 +22,34 @@ namespace array { class ArrayStrides : public std::vector { private: - using Base = std::vector; + using Base = std::vector; + public: ArrayStrides() {} - ArrayStrides( std::initializer_list list) : Base(list) {} - ArrayStrides( Base&& base ) : Base( std::forward(base) ) {} + ArrayStrides( std::initializer_list list ) : Base( list ) {} + ArrayStrides( Base&& base ) : Base( std::forward( base ) ) {} }; -inline ArrayStrides make_strides(std::initializer_list list) { return ArrayStrides(list); } -inline ArrayStrides make_strides(size_t size1) { return ArrayStrides{size1}; } -inline ArrayStrides make_strides(size_t size1, size_t size2) { return ArrayStrides{size1,size2}; } -inline ArrayStrides make_strides(size_t size1, size_t size2, size_t size3) { return ArrayStrides{size1,size2,size3}; } -inline ArrayStrides make_strides(size_t size1, size_t size2, size_t size3, size_t size4) { return ArrayStrides{size1,size2,size3,size4}; } -inline ArrayStrides make_strides(size_t size1, size_t size2, size_t size3, size_t size4, size_t size5) { return ArrayStrides{size1,size2,size3,size4,size5}; } +inline ArrayStrides make_strides( std::initializer_list list ) { + return ArrayStrides( list ); +} +inline ArrayStrides make_strides( size_t size1 ) { + return ArrayStrides{size1}; +} +inline ArrayStrides make_strides( size_t size1, size_t size2 ) { + return ArrayStrides{size1, size2}; +} +inline ArrayStrides make_strides( size_t size1, size_t size2, size_t size3 ) { + return ArrayStrides{size1, size2, size3}; +} +inline ArrayStrides make_strides( size_t size1, size_t size2, size_t size3, size_t size4 ) { + return ArrayStrides{size1, size2, size3, size4}; +} +inline ArrayStrides make_strides( size_t size1, size_t size2, size_t size3, size_t size4, size_t size5 ) { + return ArrayStrides{size1, size2, size3, size4, size5}; +} //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArrayUtil.cc b/src/atlas/array/ArrayUtil.cc index ce7487034..de53cb3d4 100644 --- a/src/atlas/array/ArrayUtil.cc +++ b/src/atlas/array/ArrayUtil.cc @@ -4,21 +4,23 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/array/ArrayUtil.h" #include #include "eckit/exception/Exceptions.h" -#include "atlas/array/ArrayUtil.h" namespace atlas { namespace array { void throw_OutOfRange( const std::string& class_name, char idx_str, int idx, int max ) { - std::ostringstream msg; msg << class_name << " index " << idx << " out of bounds: " << idx << " >= " << max; - throw eckit::OutOfRange(msg.str(),Here()); + std::ostringstream msg; + msg << class_name << " index " << idx << " out of bounds: " << idx << " >= " << max; + throw eckit::OutOfRange( msg.str(), Here() ); } -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArrayUtil.h b/src/atlas/array/ArrayUtil.h index 49ff013ee..d455cb9ad 100644 --- a/src/atlas/array/ArrayUtil.h +++ b/src/atlas/array/ArrayUtil.h @@ -4,63 +4,75 @@ * 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 size_tergovernmental organisation nor + * granted to it by virtue of its status as an size_tergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include "atlas/array/ArrayShape.h" -#include "atlas/array/ArrayStrides.h" -#include "atlas/array/ArrayLayout.h" #include "atlas/array/ArrayIdx.h" +#include "atlas/array/ArrayLayout.h" +#include "atlas/array/ArrayShape.h" #include "atlas/array/ArraySpec.h" +#include "atlas/array/ArrayStrides.h" //------------------------------------------------------------------------------------------------------ namespace atlas { namespace array { -template struct remove_const { typedef T type; }; -template struct remove_const { typedef T type; }; +template +struct remove_const { + typedef T type; +}; +template +struct remove_const { + typedef T type; +}; -template struct add_const { typedef const typename remove_const::type type; }; -template struct add_const { typedef const T type; }; +template +struct add_const { + typedef const typename remove_const::type type; +}; +template +struct add_const { + typedef const T type; +}; -class ArrayDataStore -{ +class ArrayDataStore { public: - virtual ~ArrayDataStore() {} - virtual void cloneToDevice() const = 0; - virtual void cloneFromDevice() const = 0; - virtual bool valid() const = 0; - virtual void syncHostDevice() const = 0; - virtual bool hostNeedsUpdate() const = 0; - virtual bool deviceNeedsUpdate() const = 0; - virtual void reactivateDeviceWriteViews() const = 0; - virtual void reactivateHostWriteViews() const = 0; - virtual void* voidDataStore() = 0; - virtual void* voidHostData() = 0; - virtual void* voidDeviceData() = 0; - template Value* hostData() { return static_cast(voidHostData()); } - template Value* deviceData() { return static_cast(voidDeviceData()); } + virtual ~ArrayDataStore() {} + virtual void cloneToDevice() const = 0; + virtual void cloneFromDevice() const = 0; + virtual bool valid() const = 0; + virtual void syncHostDevice() const = 0; + virtual bool hostNeedsUpdate() const = 0; + virtual bool deviceNeedsUpdate() const = 0; + virtual void reactivateDeviceWriteViews() const = 0; + virtual void reactivateHostWriteViews() const = 0; + virtual void* voidDataStore() = 0; + virtual void* voidHostData() = 0; + virtual void* voidDeviceData() = 0; + template + Value* hostData() { + return static_cast( voidHostData() ); + } + template + Value* deviceData() { + return static_cast( voidDeviceData() ); + } }; -template < int Dim > +template static constexpr char array_dim() { - return - Dim == 0 ? 'i' :( - Dim == 1 ? 'j' :( - Dim == 2 ? 'k' :( - Dim == 3 ? 'l' :( - Dim == 4 ? 'm' :( - '*'))))); + return Dim == 0 ? 'i' : ( Dim == 1 ? 'j' : ( Dim == 2 ? 'k' : ( Dim == 3 ? 'l' : ( Dim == 4 ? 'm' : ( '*' ) ) ) ) ); } void throw_OutOfRange( const std::string& class_name, char idx_str, int idx, int max ); //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArrayView.h b/src/atlas/array/ArrayView.h index 41843fc8a..535eb5eeb 100644 --- a/src/atlas/array/ArrayView.h +++ b/src/atlas/array/ArrayView.h @@ -4,17 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @file ArrayView.h -/// This file contains the ArrayView class, a class that allows to wrap any contiguous raw data into +/// This file contains the ArrayView class, a class that allows to wrap any +/// contiguous raw data into /// a view which is accessible with multiple indices. /// All it needs is the strides for each index, and the shape of each index. /// ATTENTION: The last index is stride 1 /// -/// Bounds-checking can be turned ON by defining "ATLAS_ARRAYVIEW_BOUNDS_CHECKING" +/// Bounds-checking can be turned ON by defining +/// "ATLAS_ARRAYVIEW_BOUNDS_CHECKING" /// before including this header. /// /// Example 1: diff --git a/src/atlas/array/ArrayViewDefs.h b/src/atlas/array/ArrayViewDefs.h index 67f9865ca..c5e54610a 100644 --- a/src/atlas/array/ArrayViewDefs.h +++ b/src/atlas/array/ArrayViewDefs.h @@ -4,7 +4,8 @@ * 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 size_tergovernmental organisation nor + * granted to it by virtue of its status as an size_tergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,21 +15,29 @@ namespace atlas { namespace array { - enum class Intent {ReadOnly, ReadWrite}; +enum class Intent +{ + ReadOnly, + ReadWrite +}; - template - struct Dim{ - static constexpr int cdim = cDim; - }; +template +struct Dim { + static constexpr int cdim = cDim; +}; - struct LastDim{}; - struct FirstDim{}; +struct LastDim {}; +struct FirstDim {}; - template struct is_dim_policy : std::false_type {}; - template struct is_dim_policy > : std::true_type {}; +template +struct is_dim_policy : std::false_type {}; +template +struct is_dim_policy> : std::true_type {}; - template<> struct is_dim_policy : std::true_type {}; - template<> struct is_dim_policy : std::true_type {}; +template <> +struct is_dim_policy : std::true_type {}; +template <> +struct is_dim_policy : std::true_type {}; -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/ArrayViewUtil.h b/src/atlas/array/ArrayViewUtil.h index 28a6dd1dc..09aed9501 100644 --- a/src/atlas/array/ArrayViewUtil.h +++ b/src/atlas/array/ArrayViewUtil.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once @@ -13,38 +14,41 @@ namespace atlas { namespace array { -template -constexpr typename std::enable_if< (cnt == RANK), size_t >::type get_var_size_impl( array::ArrayView& field) { +template +constexpr typename std::enable_if<( cnt == RANK ), size_t>::type get_var_size_impl( + array::ArrayView& field ) { return 1; } -template -constexpr typename std::enable_if< (cnt != RANK), size_t >::type get_var_size_impl( array::ArrayView& field) { - return (cnt == DimSkip) ? get_var_size_impl(field) : get_var_size_impl(field) * field.template shape(); +template +constexpr typename std::enable_if<( cnt != RANK ), size_t>::type get_var_size_impl( + array::ArrayView& field ) { + return ( cnt == DimSkip ) ? get_var_size_impl( field ) + : get_var_size_impl( field ) * field.template shape(); } -template -constexpr size_t get_var_size( array::ArrayView& field) { - return get_var_size_impl<0, DimSkip>(field); +template +constexpr size_t get_var_size( array::ArrayView& field ) { + return get_var_size_impl<0, DimSkip>( field ); } -template struct get_dim { +template +struct get_dim { static constexpr int value = -1; }; -template struct get_dim > -{ +template +struct get_dim> { static constexpr int value = cDim; }; -template -constexpr unsigned int get_parallel_dim(array::ArrayView& field) { - static_assert(is_dim_policy::value, "DimPolicy required"); - return std::is_same::value ? 0 : - ( std::is_same::value ? RANK - 1 : - (get_dim::value) - ); +template +constexpr unsigned int get_parallel_dim( array::ArrayView& field ) { + static_assert( is_dim_policy::value, "DimPolicy required" ); + return std::is_same::value + ? 0 + : ( std::is_same::value ? RANK - 1 : ( get_dim::value ) ); } -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/DataType.h b/src/atlas/array/DataType.h index d1d579150..8e3465472 100644 --- a/src/atlas/array/DataType.h +++ b/src/atlas/array/DataType.h @@ -4,14 +4,15 @@ * 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 size_tergovernmental organisation nor + * granted to it by virtue of its status as an size_tergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include #include +#include #include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------------------------------ @@ -21,168 +22,230 @@ namespace array { class DataType { public: - typedef long kind_t; - static const kind_t KIND_INT32 = -4; - static const kind_t KIND_INT64 = -8; - static const kind_t KIND_REAL32 = 4; - static const kind_t KIND_REAL64 = 8; - static const kind_t KIND_UINT64 = -16; + typedef long kind_t; + static const kind_t KIND_INT32 = -4; + static const kind_t KIND_INT64 = -8; + static const kind_t KIND_REAL32 = 4; + static const kind_t KIND_REAL64 = 8; + static const kind_t KIND_UINT64 = -16; + + template + static DataType create(); + + static DataType int32() { return DataType( KIND_INT32 ); } + static DataType int64() { return DataType( KIND_INT64 ); } + static DataType real32() { return DataType( KIND_REAL32 ); } + static DataType real64() { return DataType( KIND_REAL64 ); } + + template + static kind_t kind(); + template + static kind_t kind( const DATATYPE& ); + + template + static std::string str(); + template + static std::string str( const DATATYPE ); + + static long str_to_kind( const std::string& ); + static std::string kind_to_str( kind_t ); + static bool kind_valid( kind_t ); + +private: + static std::string int32_str() { return "int32"; } + static std::string int64_str() { return "int64"; } + static std::string real32_str() { return "real32"; } + static std::string real64_str() { return "real64"; } + static std::string uint64_str() { return "uint64"; } + +public: + DataType( const std::string& ); + DataType( long ); + DataType( const DataType& ); + std::string str() const { return kind_to_str( kind_ ); } + kind_t kind() const { return kind_; } + + friend bool operator==( DataType dt1, DataType dt2 ); + friend bool operator!=( DataType dt1, DataType dt2 ); + friend bool operator==( DataType dt, kind_t kind ); + friend bool operator!=( DataType dt, kind_t kind ); + friend bool operator==( kind_t kind, DataType dt ); + friend bool operator!=( kind_t kind, DataType dt2 ); + +private: + kind_t kind_; +}; + +template <> +inline std::string DataType::str() { + return int32_str(); +} +template <> +inline std::string DataType::str() { + return int64_str(); +} +template <> +inline std::string DataType::str() { + return real32_str(); +} +template <> +inline std::string DataType::str() { + return real64_str(); +} +template <> +inline std::string DataType::str() { + return uint64_str(); +} +template <> +inline std::string DataType::str( const int& ) { + return int32_str(); +} +template <> +inline std::string DataType::str( const long& ) { + return int64_str(); +} +template <> +inline std::string DataType::str( const unsigned long& ) { + return uint64_str(); +} +template <> +inline std::string DataType::str( const float& ) { + return real32_str(); +} +template <> +inline std::string DataType::str( const double& ) { + return real64_str(); +} +template <> +inline DataType::kind_t DataType::kind() { + return KIND_INT32; +} +template <> +inline DataType::kind_t DataType::kind() { + return KIND_INT64; +} +template <> +inline DataType::kind_t DataType::kind() { + return KIND_UINT64; +} +template <> +inline DataType::kind_t DataType::kind() { + return KIND_REAL32; +} +template <> +inline DataType::kind_t DataType::kind() { + return KIND_REAL64; +} +template <> +inline DataType::kind_t DataType::kind( const int& ) { + return KIND_INT32; +} +template <> +inline DataType::kind_t DataType::kind( const long& ) { + return KIND_INT64; +} +template <> +inline DataType::kind_t DataType::kind( const unsigned long& ) { + return KIND_UINT64; +} +template <> +inline DataType::kind_t DataType::kind( const float& ) { + return KIND_REAL32; +} +template <> +inline DataType::kind_t DataType::kind( const double& ) { + return KIND_REAL64; +} - template< typename DATATYPE > static DataType create(); +inline DataType::kind_t DataType::str_to_kind( const std::string& datatype ) { + DataType::kind_t kind = 0; + if ( datatype == "int32" ) + kind = KIND_INT32; + else if ( datatype == "int64" ) + kind = KIND_INT64; + else if ( datatype == "uint64" ) + kind = KIND_UINT64; + else if ( datatype == "real32" ) + kind = KIND_REAL32; + else if ( datatype == "real64" ) + kind = KIND_REAL64; + else { + throw eckit::Exception( "datatype " + datatype + " not recognised.", Here() ); + } + return kind; +} +inline std::string DataType::kind_to_str( kind_t kind ) { + switch ( kind ) { + case KIND_INT32: + return int32_str(); + case KIND_INT64: + return int64_str(); + case KIND_UINT64: + return uint64_str(); + case KIND_REAL32: + return real32_str(); + case KIND_REAL64: + return real64_str(); + default: + std::stringstream msg; + msg << "kind " << kind << " not recognised."; + throw eckit::Exception( msg.str(), Here() ); + } +} +inline bool DataType::kind_valid( kind_t kind ) { + switch ( kind ) { + case KIND_INT32: + case KIND_INT64: + case KIND_UINT64: + case KIND_REAL32: + case KIND_REAL64: + return true; + default: + return false; + } +} - static DataType int32() { return DataType(KIND_INT32); } - static DataType int64() { return DataType(KIND_INT64); } - static DataType real32() { return DataType(KIND_REAL32); } - static DataType real64() { return DataType(KIND_REAL64); } +inline DataType::DataType( const DataType& other ) : kind_( other.kind_ ) {} - template< typename DATATYPE > static kind_t kind(); - template< typename DATATYPE > static kind_t kind(const DATATYPE&); +inline DataType::DataType( const std::string& datatype ) : kind_( str_to_kind( datatype ) ) {} - template< typename DATATYPE > static std::string str(); - template< typename DATATYPE > static std::string str(const DATATYPE); +inline DataType::DataType( long kind ) : kind_( kind ) {} - static long str_to_kind(const std::string&); - static std::string kind_to_str(kind_t); - static bool kind_valid(kind_t); +inline bool operator==( DataType dt1, DataType dt2 ) { + return dt1.kind_ == dt2.kind_; +} -private: - static std::string int32_str() { return "int32"; } - static std::string int64_str() { return "int64"; } - static std::string real32_str() { return "real32"; } - static std::string real64_str() { return "real64"; } - static std::string uint64_str() { return "uint64"; } +inline bool operator!=( DataType dt1, DataType dt2 ) { + return dt1.kind_ != dt2.kind_; +} -public: - DataType(const std::string&); - DataType(long); - DataType(const DataType&); - std::string str() const { return kind_to_str(kind_); } - kind_t kind() const { return kind_; } - - friend bool operator== (DataType dt1, DataType dt2); - friend bool operator!= (DataType dt1, DataType dt2); - friend bool operator== (DataType dt, kind_t kind); - friend bool operator!= (DataType dt, kind_t kind); - friend bool operator== (kind_t kind, DataType dt); - friend bool operator!= (kind_t kind, DataType dt2); +inline bool operator==( DataType dt, DataType::kind_t kind ) { + return dt.kind_ == kind; +} -private: - kind_t kind_; -}; +inline bool operator!=( DataType dt, DataType::kind_t kind ) { + return dt.kind_ != kind; +} + +inline bool operator==( DataType::kind_t kind, DataType dt ) { + return dt.kind_ == kind; +} + +inline bool operator!=( DataType::kind_t kind, DataType dt ) { + return dt.kind_ != kind; +} -template<> inline std::string DataType::str() { return int32_str(); } -template<> inline std::string DataType::str() { return int64_str(); } -template<> inline std::string DataType::str() { return real32_str(); } -template<> inline std::string DataType::str() { return real64_str(); } -template<> inline std::string DataType::str() { return uint64_str(); } -template<> inline std::string DataType::str(const int&) { return int32_str(); } -template<> inline std::string DataType::str(const long&) { return int64_str(); } -template<> inline std::string DataType::str(const unsigned long&) { return uint64_str(); } -template<> inline std::string DataType::str(const float&) { return real32_str(); } -template<> inline std::string DataType::str(const double&) { return real64_str(); } -template<> inline DataType::kind_t DataType::kind() { return KIND_INT32; } -template<> inline DataType::kind_t DataType::kind() { return KIND_INT64; } -template<> inline DataType::kind_t DataType::kind() { return KIND_UINT64; } -template<> inline DataType::kind_t DataType::kind() { return KIND_REAL32; } -template<> inline DataType::kind_t DataType::kind() { return KIND_REAL64; } -template<> inline DataType::kind_t DataType::kind(const int&) { return KIND_INT32; } -template<> inline DataType::kind_t DataType::kind(const long&) { return KIND_INT64; } -template<> inline DataType::kind_t DataType::kind(const unsigned long&) { return KIND_UINT64; } -template<> inline DataType::kind_t DataType::kind(const float&) { return KIND_REAL32; } -template<> inline DataType::kind_t DataType::kind(const double&) { return KIND_REAL64; } - -inline DataType::kind_t DataType::str_to_kind(const std::string& datatype) -{ - DataType::kind_t kind = 0; - if ( datatype == "int32" ) kind = KIND_INT32; - else if ( datatype == "int64" ) kind = KIND_INT64; - else if ( datatype == "uint64" ) kind = KIND_UINT64; - else if ( datatype == "real32" ) kind = KIND_REAL32; - else if ( datatype == "real64" ) kind = KIND_REAL64; - else { - throw eckit::Exception("datatype "+datatype+" not recognised.",Here()); - } - return kind; -} -inline std::string DataType::kind_to_str(kind_t kind) -{ - switch( kind ) - { - case KIND_INT32: return int32_str(); - case KIND_INT64: return int64_str(); - case KIND_UINT64: return uint64_str(); - case KIND_REAL32: return real32_str(); - case KIND_REAL64: return real64_str(); - default: - std::stringstream msg; - msg << "kind "< -inline DataType DataType::create() { return DataType(DataType::kind()); } - -template< typename DATATYPE > -inline DataType make_datatype() { return DataType(DataType::kind()); } +template +inline DataType DataType::create() { + return DataType( DataType::kind() ); +} + +template +inline DataType make_datatype() { + return DataType( DataType::kind() ); +} //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/IndexView.h b/src/atlas/array/IndexView.h index 88ab45258..3ccc7f80a 100644 --- a/src/atlas/array/IndexView.h +++ b/src/atlas/array/IndexView.h @@ -4,18 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @file IndexView.h -/// This file contains the IndexView class, a class that allows to wrap any contiguous raw data into +/// This file contains the IndexView class, a class that allows to wrap any +/// contiguous raw data into /// a view which is accessible with multiple indices. -/// This view is intended to work with Connectivity Tables storing Fortran Numbering internally +/// This view is intended to work with Connectivity Tables storing Fortran +/// Numbering internally /// All it needs is the strides for each index, and the shape of each index. /// ATTENTION: The last index is stride 1 /// -/// Bounds-checking can be turned ON by defining "ATLAS_INDEXVIEW_BOUNDS_CHECKING" +/// Bounds-checking can be turned ON by defining +/// "ATLAS_INDEXVIEW_BOUNDS_CHECKING" /// before including this header. /// /// Example: diff --git a/src/atlas/array/LocalView.cc b/src/atlas/array/LocalView.cc index 885daf17e..1bc952217 100644 --- a/src/atlas/array/LocalView.cc +++ b/src/atlas/array/LocalView.cc @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include -#include "eckit/exception/Exceptions.h" #include "atlas/array/LocalView.h" +#include #include "atlas/array/helpers/ArrayAssigner.h" +#include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------------------------------ @@ -21,57 +22,55 @@ namespace array { //------------------------------------------------------------------------------------------------------ template -void LocalView::assign(const value_type& value) { - helpers::array_assigner::apply(*this,value); +void LocalView::assign( const value_type& value ) { + helpers::array_assigner::apply( *this, value ); } //------------------------------------------------------------------------------------------------------ template -void LocalView::dump(std::ostream& os) const { -ASSERT( contiguous() ); -const value_type* data_ = data(); -os << "size: " << size() << " , values: "; -os << "[ "; -for( size_t j=0; j::dump( std::ostream& os ) const { + ASSERT( contiguous() ); + const value_type* data_ = data(); + os << "size: " << size() << " , values: "; + os << "[ "; + for ( size_t j = 0; j < size(); ++j ) + os << data_[j] << " "; + os << "]"; } - //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas - +} // namespace array +} // namespace atlas //----------------------------------------------------------------------- // Explicit instantiation namespace atlas { namespace array { -#define EXPLICIT_TEMPLATE_INSTANTIATION(Rank) \ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ -template class LocalView;\ +#define EXPLICIT_TEMPLATE_INSTANTIATION( Rank ) \ + template class LocalView; \ + template class LocalView; \ + template class LocalView; \ + template class LocalView; \ + template class LocalView; \ + template class LocalView; \ + template class LocalView; \ + template class LocalView; \ + template class LocalView; \ + template class LocalView; // For each NDims in [1..9] -EXPLICIT_TEMPLATE_INSTANTIATION(1) -EXPLICIT_TEMPLATE_INSTANTIATION(2) -EXPLICIT_TEMPLATE_INSTANTIATION(3) -EXPLICIT_TEMPLATE_INSTANTIATION(4) -EXPLICIT_TEMPLATE_INSTANTIATION(5) -EXPLICIT_TEMPLATE_INSTANTIATION(6) -EXPLICIT_TEMPLATE_INSTANTIATION(7) -EXPLICIT_TEMPLATE_INSTANTIATION(8) -EXPLICIT_TEMPLATE_INSTANTIATION(9) +EXPLICIT_TEMPLATE_INSTANTIATION( 1 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 2 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 3 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 4 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 5 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 6 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 7 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 8 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 9 ) #undef EXPLICIT_TEMPLATE_INSTANTIATION } -} +} // namespace atlas diff --git a/src/atlas/array/LocalView.h b/src/atlas/array/LocalView.h index b66c2e78c..0eeba3668 100644 --- a/src/atlas/array/LocalView.h +++ b/src/atlas/array/LocalView.h @@ -4,17 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @file LocalView.h -/// This file contains the LocalView class, a class that allows to wrap any contiguous raw data into +/// This file contains the LocalView class, a class that allows to wrap any +/// contiguous raw data into /// a view which is accessible with multiple indices. /// All it needs is the strides for each index, and the shape of each index. /// ATTENTION: The last index is stride 1 /// -/// Bounds-checking can be turned ON by defining "ATLAS_ARRAYVIEW_BOUNDS_CHECKING" +/// Bounds-checking can be turned ON by defining +/// "ATLAS_ARRAYVIEW_BOUNDS_CHECKING" /// before including this header. /// /// Example 1: @@ -42,182 +45,171 @@ #include #include -#include "atlas/library/config.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/ArrayViewDefs.h" #include "atlas/array/helpers/ArraySlicer.h" +#include "atlas/library/config.h" //------------------------------------------------------------------------------------------------------ namespace atlas { namespace array { -template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > +template class LocalView { public: - -// -- Type definitions + // -- Type definitions using value_type = typename remove_const::type; - using return_type = typename std::conditional< (AccessMode==Intent::ReadOnly), const value_type, value_type >::type; + using return_type = + typename std::conditional<( AccessMode == Intent::ReadOnly ), const value_type, value_type>::type; static constexpr Intent ACCESS{AccessMode}; static constexpr int RANK{Rank}; private: + using slicer_t = typename helpers::ArraySlicer>; + using const_slicer_t = typename helpers::ArraySlicer>; - using slicer_t = typename helpers::ArraySlicer< LocalView >; - using const_slicer_t = typename helpers::ArraySlicer< const LocalView >; - - template< typename ...Args > + template struct slice_t { - using type = typename slicer_t::template Slice::type; + using type = typename slicer_t::template Slice::type; }; - template< typename ...Args > + template struct const_slice_t { - using type = typename const_slicer_t::template Slice::type; + using type = typename const_slicer_t::template Slice::type; }; public: - -// -- Constructors + // -- Constructors LocalView( const value_type* data, const size_t shape[], const size_t strides[] ) : - data_(const_cast(data)) { + data_( const_cast( data ) ) { size_ = 1; - for( size_t j=0; j(data)) { + LocalView( const value_type* data, const size_t shape[] ) : data_( const_cast( data ) ) { size_ = 1; - for( int j=Rank-1; j>=0; --j ) { - shape_[j] = shape[j]; + for ( int j = Rank - 1; j >= 0; --j ) { + shape_[j] = shape[j]; strides_[j] = size_; size_ *= shape_[j]; } } - LocalView( const value_type* data, const ArrayShape& shape ) : - data_(const_cast(data)) { + LocalView( const value_type* data, const ArrayShape& shape ) : data_( const_cast( data ) ) { size_ = 1; - for( int j=Rank-1; j>=0; --j ) { + for ( int j = Rank - 1; j >= 0; --j ) { shape_[j] = shape[j]; strides_[j] = size_; size_ *= shape_[j]; } } -// -- Access methods + // -- Access methods - template < typename... Ints > - return_type& operator()(Ints... idx) { - check_bounds(idx...); - return data_[index(idx...)]; + template + return_type& operator()( Ints... idx ) { + check_bounds( idx... ); + return data_[index( idx... )]; } - template < typename... Ints > - const value_type& operator()(Ints... idx) const { - check_bounds(idx...); - return data_[index(idx...)]; + template + const value_type& operator()( Ints... idx ) const { + check_bounds( idx... ); + return data_[index( idx... )]; } - size_t size() const { return size_;} + size_t size() const { return size_; } - size_t shape(size_t idx) const { return shape_[idx]; } + size_t shape( size_t idx ) const { return shape_[idx]; } - size_t stride(size_t idx) const { return strides_[idx]; } + size_t stride( size_t idx ) const { return strides_[idx]; } value_type const* data() const { return data_; } - return_type* data() { return data_; } + return_type* data() { return data_; } - bool contiguous() const { - return (size_ == shape_[0]*strides_[0] ? true : false); - } + bool contiguous() const { return ( size_ == shape_[0] * strides_[0] ? true : false ); } - void assign(const value_type& value); + void assign( const value_type& value ); - void dump(std::ostream& os) const; + void dump( std::ostream& os ) const; static constexpr size_t rank() { return Rank; } - template< typename ...Args > - typename slice_t::type slice(Args... args) { - return slicer_t(*this).apply(args...); + template + typename slice_t::type slice( Args... args ) { + return slicer_t( *this ).apply( args... ); } - template< typename ...Args > - typename const_slice_t::type slice(Args... args) const { - return const_slicer_t(*this).apply(args...); + template + typename const_slice_t::type slice( Args... args ) const { + return const_slicer_t( *this ).apply( args... ); } private: + // -- Private methods -// -- Private methods - - template < int Dim, typename Int, typename... Ints > - constexpr int index_part(Int idx, Ints... next_idx) const { - return idx*strides_[Dim] + index_part( next_idx... ); + template + constexpr int index_part( Int idx, Ints... next_idx ) const { + return idx * strides_[Dim] + index_part( next_idx... ); } - template < int Dim, typename Int > - constexpr int index_part(Int last_idx) const { - return last_idx*strides_[Dim]; + template + constexpr int index_part( Int last_idx ) const { + return last_idx * strides_[Dim]; } - template < typename... Ints > - constexpr int index(Ints... idx) const { - return index_part<0>(idx...); + template + constexpr int index( Ints... idx ) const { + return index_part<0>( idx... ); } #ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING - template < typename... Ints > - void check_bounds(Ints... idx) const { - static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); - return check_bounds_part<0>(idx...); + template + void check_bounds( Ints... idx ) const { + static_assert( sizeof...( idx ) == Rank, "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>( idx... ); } #else - template < typename... Ints > - void check_bounds(Ints...) const {} + template + void check_bounds( Ints... ) const {} #endif - template < typename... Ints > - void check_bounds_force(Ints... idx) const { - static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); - return check_bounds_part<0>(idx...); + template + void check_bounds_force( Ints... idx ) const { + static_assert( sizeof...( idx ) == Rank, "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>( idx... ); } - template < int Dim, typename Int, typename... Ints > - void check_bounds_part(Int idx, Ints... next_idx) const { - if( size_t(idx) >= shape_[Dim] ) { - throw_OutOfRange( "LocalView", array_dim(), idx, shape_[Dim] ); - } - check_bounds_part( next_idx... ); + template + void check_bounds_part( Int idx, Ints... next_idx ) const { + if ( size_t( idx ) >= shape_[Dim] ) { throw_OutOfRange( "LocalView", array_dim(), idx, shape_[Dim] ); } + check_bounds_part( next_idx... ); } - template < int Dim, typename Int > - void check_bounds_part(Int last_idx) const { - if( size_t(last_idx) >= shape_[Dim] ) { + template + void check_bounds_part( Int last_idx ) const { + if ( size_t( last_idx ) >= shape_[Dim] ) { throw_OutOfRange( "LocalView", array_dim(), last_idx, shape_[Dim] ); } } private: + // -- Private data -// -- Private data - - value_type *data_; - size_t size_; - size_t shape_[Rank]; - size_t strides_[Rank]; - + value_type* data_; + size_t size_; + size_t shape_[Rank]; + size_t strides_[Rank]; }; -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/MakeView.h b/src/atlas/array/MakeView.h index 7e5381bae..b6062ae6a 100644 --- a/src/atlas/array/MakeView.h +++ b/src/atlas/array/MakeView.h @@ -1,5 +1,5 @@ #pragma once -#include "atlas/array_fwd.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" +#include "atlas/array_fwd.h" diff --git a/src/atlas/array/Range.h b/src/atlas/array/Range.h index 46f5d05a0..36fba4cfe 100644 --- a/src/atlas/array/Range.h +++ b/src/atlas/array/Range.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -27,88 +28,88 @@ class RangeBase {}; class RangeFrom : public RangeBase { public: - RangeFrom(int start) : start_(start) {} + RangeFrom( int start ) : start_( start ) {} - int start() const { return start_; } + int start() const { return start_; } - template < int Dim, typename View > - int end(const View& view) const { return view.shape(Dim); } + template + int end( const View& view ) const { + return view.shape( Dim ); + } - template < typename View > - int end(const View& view, int i) const { return view.shape(i); } + template + int end( const View& view, int i ) const { + return view.shape( i ); + } private: - int start_; + int start_; }; //------------------------------------------------------------------------------ class RangeTo : public RangeBase { public: - RangeTo(int end) : end_(end) {} + RangeTo( int end ) : end_( end ) {} - int start() const { return 0; } + int start() const { return 0; } - int end() const { return end_; } + int end() const { return end_; } private: - int end_; + int end_; }; //------------------------------------------------------------------------------ class RangeAll : public RangeBase { public: + int start() const { return 0; } - int start() const { return 0; } - - template < int Dim, typename View > - int end(const View& view) const { return view.shape(Dim); } - - template < typename View > - int end(const View& view, int i) const { return view.shape(i); } + template + int end( const View& view ) const { + return view.shape( Dim ); + } + template + int end( const View& view, int i ) const { + return view.shape( i ); + } }; -class RangeDummy : public RangeBase { -}; +class RangeDummy : public RangeBase {}; //------------------------------------------------------------------------------ -} // helpers +} // namespace helpers //------------------------------------------------------------------------------ -class Range : public helpers::RangeBase{ +class Range : public helpers::RangeBase { private: - using From = helpers::RangeFrom; - using To = helpers::RangeTo; - using All = helpers::RangeAll; - using Dummy = helpers::RangeDummy; + using From = helpers::RangeFrom; + using To = helpers::RangeTo; + using All = helpers::RangeAll; + using Dummy = helpers::RangeDummy; public: - - static From from(int start) { return From(start); } - static To to(int end) { return To(end); } - static All all() { return All(); } - static Dummy dummy() { return Dummy(); } + static From from( int start ) { return From( start ); } + static To to( int end ) { return To( end ); } + static All all() { return All(); } + static Dummy dummy() { return Dummy(); } public: - - template< typename Start, typename End > - Range(Start start, End end ) : - start_( static_cast(start) ), - end_( static_cast(end) ) { - } - int start() const { return start_; } - int end() const { return end_; } + template + Range( Start start, End end ) : start_( static_cast( start ) ), end_( static_cast( end ) ) {} + int start() const { return start_; } + int end() const { return end_; } private: - int start_; - int end_; + int start_; + int end_; }; //------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/SVector.h b/src/atlas/array/SVector.h index a6113ced8..01e71d6b3 100644 --- a/src/atlas/array/SVector.h +++ b/src/atlas/array/SVector.h @@ -10,8 +10,8 @@ #pragma once -#include #include +#include #include "atlas/library/config.h" @@ -19,8 +19,8 @@ #include #endif -#include "atlas/runtime/ErrorHandling.h" #include "atlas/library/config.h" +#include "atlas/runtime/ErrorHandling.h" namespace atlas { namespace array { @@ -30,107 +30,105 @@ namespace array { template class SVector { public: - SVector() : data_(nullptr), size_(0), externally_allocated_(false) {} + SVector() : data_( nullptr ), size_( 0 ), externally_allocated_( false ) {} - ATLAS_HOST_DEVICE - SVector(SVector const & other) : data_(other.data_), size_(other.size_), externally_allocated_(other.externally_allocated_){} + ATLAS_HOST_DEVICE + SVector( SVector const& other ) : + data_( other.data_ ), + size_( other.size_ ), + externally_allocated_( other.externally_allocated_ ) {} - ATLAS_HOST_DEVICE - SVector(T* data, size_t size): data_(data), size_(size) {} + ATLAS_HOST_DEVICE + SVector( T* data, size_t size ) : data_( data ), size_( size ) {} - SVector(size_t N) : size_(N) { + SVector( size_t N ) : size_( N ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - cudaError_t err = cudaMallocManaged(&data_, N * sizeof(T)); - if(err != cudaSuccess) - throw eckit::AssertionFailed("failed to allocate GPU memory"); + cudaError_t err = cudaMallocManaged( &data_, N * sizeof( T ) ); + if ( err != cudaSuccess ) throw eckit::AssertionFailed( "failed to allocate GPU memory" ); #else - data_ = (T*)malloc(N*sizeof(T)); + data_ = (T*)malloc( N * sizeof( T ) ); #endif - } - ATLAS_HOST_DEVICE - ~SVector(){ + } + ATLAS_HOST_DEVICE + ~SVector() { #ifndef __CUDA_ARCH__ - if(!externally_allocated_) - delete_managedmem(data_); + if ( !externally_allocated_ ) delete_managedmem( data_ ); #endif - } + } - void delete_managedmem(T*& data) { - if( data ) { + void delete_managedmem( T*& data ) { + if ( data ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - cudaError_t err = cudaDeviceSynchronize(); - if(err != cudaSuccess) - throw eckit::AssertionFailed("failed to synchronize memory"); + cudaError_t err = cudaDeviceSynchronize(); + if ( err != cudaSuccess ) throw eckit::AssertionFailed( "failed to synchronize memory" ); - err = cudaFree(data); -// The following throws an invalid device memory + err = cudaFree( data ); + // The following throws an invalid device memory - if(err != cudaSuccess) - throw eckit::AssertionFailed("failed to free GPU memory"); + if ( err != cudaSuccess ) throw eckit::AssertionFailed( "failed to free GPU memory" ); #else - free(data_); + free( data_ ); #endif - data_ = NULL; + data_ = NULL; + } + } + T* data() { return data_; } + T const* data() const { return data_; } + + ATLAS_HOST_DEVICE + T& operator()( const size_t idx ) { + assert( data_ && idx < size_ ); + return data_[idx]; + } + ATLAS_HOST_DEVICE + T const& operator()( const size_t idx ) const { + assert( data_ && idx < size_ ); + return data_[idx]; } - } - T* data() { return data_; } - T const * data() const { return data_; } - - ATLAS_HOST_DEVICE - T& operator()(const size_t idx) { - assert(data_ && idx < size_); - return data_[idx]; - } - ATLAS_HOST_DEVICE - T const& operator()(const size_t idx) const { - assert(data_ && idx < size_); - return data_[idx]; - } - - ATLAS_HOST_DEVICE - T& operator[](const size_t idx) { - assert(data_ && idx < size_); - return data_[idx]; - } - ATLAS_HOST_DEVICE - T const& operator[](const size_t idx) const { - assert(data_ && idx < size_); - return data_[idx]; - } - - ATLAS_HOST_DEVICE - size_t size() const { return size_; } - - void resize_impl(size_t N) { - assert(N >= size_); - if (N == size_) return; - - T* d_; + + ATLAS_HOST_DEVICE + T& operator[]( const size_t idx ) { + assert( data_ && idx < size_ ); + return data_[idx]; + } + ATLAS_HOST_DEVICE + T const& operator[]( const size_t idx ) const { + assert( data_ && idx < size_ ); + return data_[idx]; + } + + ATLAS_HOST_DEVICE + size_t size() const { return size_; } + + void resize_impl( size_t N ) { + assert( N >= size_ ); + if ( N == size_ ) return; + + T* d_; #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - cudaError_t err = cudaMallocManaged(&d_, sizeof(T)*N ); - if(err != cudaSuccess) - throw eckit::AssertionFailed("failed to allocate GPU memory"); + cudaError_t err = cudaMallocManaged( &d_, sizeof( T ) * N ); + if ( err != cudaSuccess ) throw eckit::AssertionFailed( "failed to allocate GPU memory" ); #else - d_ = (T*)malloc(sizeof(T)*N ); + d_ = (T*)malloc( sizeof( T ) * N ); #endif - for(unsigned int c=0; c < size_; ++c) { - d_[c] = data_[c]; - } - delete_managedmem(data_); - data_ = d_; - } - - void resize(size_t N) { - resize_impl(N); - size_ = N; - } + for ( unsigned int c = 0; c < size_; ++c ) { + d_[c] = data_[c]; + } + delete_managedmem( data_ ); + data_ = d_; + } + + void resize( size_t N ) { + resize_impl( N ); + size_ = N; + } private: - T* data_; - size_t size_; - bool externally_allocated_; + T* data_; + size_t size_; + bool externally_allocated_; }; //------------------------------------------------------------------------------ diff --git a/src/atlas/array/Table.cc b/src/atlas/array/Table.cc index ee4cf8525..c189ddad1 100644 --- a/src/atlas/array/Table.cc +++ b/src/atlas/array/Table.cc @@ -4,15 +4,16 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include "atlas/array/Table.h" -#include "atlas/runtime/ErrorHandling.h" +#include #include "atlas/array.h" #include "atlas/array/DataType.h" +#include "atlas/runtime/ErrorHandling.h" #ifdef ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 @@ -27,80 +28,79 @@ namespace array { // ---------------------------------------------------------------------------- -Table::Table(const std::string& name ) : - name_(name), - owns_(true), - data_{ - Array::create(0), // values - Array::create(1), // displs - Array::create(1)}, // counts +Table::Table( const std::string& name ) : + name_( name ), + owns_( true ), + data_{Array::create( 0 ), // values + Array::create( 1 ), // displs + Array::create( 1 )}, // counts missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), - rows_(0), - maxcols_(0), - mincols_(std::numeric_limits::max()), - displs_(make_host_view(*(data_[_displs_]))), - counts_(make_host_view(*(data_[_counts_]))), - values_(make_host_view(*(data_[_values_]))) { - displs_(0) = 0; - counts_(0) = 0; + rows_( 0 ), + maxcols_( 0 ), + mincols_( std::numeric_limits::max() ), + displs_( make_host_view( *( data_[_displs_] ) ) ), + counts_( make_host_view( *( data_[_counts_] ) ) ), + values_( make_host_view( *( data_[_values_] ) ) ) { + displs_( 0 ) = 0; + counts_( 0 ) = 0; } // ---------------------------------------------------------------------------- namespace { -static size_t get_total_size_counts(size_t rows, size_t counts[]) { +static size_t get_total_size_counts( size_t rows, size_t counts[] ) { size_t total_size = 0; - for( size_t j=0; j(values, array::ArrayShape{get_total_size_counts(rows, counts)}), - Array::wrap(displs, array::ArrayShape{rows}), - Array::wrap(counts, array::ArrayShape{rows})}, + owns_( false ), + data_{Array::wrap( values, array::ArrayShape{get_total_size_counts( rows, counts )} ), + Array::wrap( displs, array::ArrayShape{rows} ), + Array::wrap( counts, array::ArrayShape{rows} )}, missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), - rows_(rows), - maxcols_(0), - mincols_(std::numeric_limits::max()), - displs_(make_host_view(*(data_[_displs_]))), - counts_(make_host_view(*(data_[_counts_]))), - values_(make_host_view(*(data_[_values_]))) { - for( size_t j=0; j::max() ), + displs_( make_host_view( *( data_[_displs_] ) ) ), + counts_( make_host_view( *( data_[_counts_] ) ) ), + values_( make_host_view( *( data_[_values_] ) ) ) { + for ( size_t j = 0; j < rows; ++j ) { + maxcols_ = std::max( maxcols_, counts[j] ); + mincols_ = std::min( mincols_, counts[j] ); } } // ---------------------------------------------------------------------------- Table::~Table() { - if(owns_) { - std::for_each(data_.begin(), data_.end(), [](array::Array* a){ - assert(a); - delete a; - a = 0; - }); - } + if ( owns_ ) { + std::for_each( data_.begin(), data_.end(), []( array::Array* a ) { + assert( a ); + delete a; + a = 0; + } ); + } } // ---------------------------------------------------------------------------- void Table::clear() { - if( owns() ) { - resize_values(0); - resize_counts_and_displs(1); - displs_(0) = 0; - counts_(0) = 0; - } else { - std::for_each(data_.begin(), data_.end(), [](array::Array* a){ a=0;}); + if ( owns() ) { + resize_values( 0 ); + resize_counts_and_displs( 1 ); + displs_( 0 ) = 0; + counts_( 0 ) = 0; + } + else { + std::for_each( data_.begin(), data_.end(), []( array::Array* a ) { a = 0; } ); // data_ and host_views will be invalid now! } maxcols_ = 0; @@ -109,163 +109,158 @@ void Table::clear() { // ---------------------------------------------------------------------------- -void Table::resize_values( size_t old_size, size_t new_size, bool initialize, const idx_t values[], bool fortran_array) { - resize_values(new_size); +void Table::resize_values( size_t old_size, size_t new_size, bool initialize, const idx_t values[], + bool fortran_array ) { + resize_values( new_size ); idx_t add_base = fortran_array ? 0 : FORTRAN_BASE; - if (initialize) { - for (size_t j=0, c=old_size; cresize(size); - data_[_counts_]->resize(size); - displs_ = make_host_view(*(data_[_displs_])); - counts_ = make_host_view(*(data_[_counts_])); + data_[_displs_]->resize( size ); + data_[_counts_]->resize( size ); + displs_ = make_host_view( *( data_[_displs_] ) ); + counts_ = make_host_view( *( data_[_counts_] ) ); } // ---------------------------------------------------------------------------- -void Table::insert_counts_and_displs(size_t position, size_t rows) { +void Table::insert_counts_and_displs( size_t position, size_t rows ) { ASSERT( data_[_displs_] != 0 ); ASSERT( data_[_counts_] != 0 ); - data_[_displs_]->insert( position, rows); - data_[_counts_]->insert( position, rows); - displs_ = make_host_view(*(data_[_displs_])); - counts_ = make_host_view(*(data_[_counts_])); + data_[_displs_]->insert( position, rows ); + data_[_counts_]->insert( position, rows ); + displs_ = make_host_view( *( data_[_displs_] ) ); + counts_ = make_host_view( *( data_[_counts_] ) ); } // ---------------------------------------------------------------------------- -void Table::resize_values(size_t size) { +void Table::resize_values( size_t size ) { ASSERT( data_[_values_] != 0 ); - data_[_values_]->resize(size); - values_ = make_host_view(*(data_[_values_])); + data_[_values_]->resize( size ); + values_ = make_host_view( *( data_[_values_] ) ); } // ---------------------------------------------------------------------------- -void Table::insert_values(size_t position, size_t size) { +void Table::insert_values( size_t position, size_t size ) { ASSERT( data_[_values_] != 0 ); - data_[_values_]->insert(position,size); - values_ = make_host_view(*(data_[_values_])); + data_[_values_]->insert( position, size ); + values_ = make_host_view( *( data_[_values_] ) ); } // ---------------------------------------------------------------------------- -void Table::add( size_t rows, size_t cols, const idx_t values[], bool fortran_array ) -{ - if( !owns_ ) throw eckit::AssertionFailed("HybridConnectivity must be owned to be resized directly"); +void Table::add( size_t rows, size_t cols, const idx_t values[], bool fortran_array ) { + if ( !owns_ ) throw eckit::AssertionFailed( "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; + size_t new_size = old_size + rows * cols; + size_t new_rows = rows_ + rows; - resize_counts_and_displs(new_rows+1); + resize_counts_and_displs( new_rows + 1 ); - for(size_t j=0; rows_1) { - insert_counts_and_displs( position-1, rows ); - } - } else { + if ( rows_ == 0 ) { + if ( position > 1 ) { insert_counts_and_displs( position - 1, rows ); } + } + else { insert_counts_and_displs( position, rows ); } - displs_(position) = position_displs; - for( size_t jrow=position; jrowcloneToDevice();} ); + std::for_each( data_.begin(), data_.end(), []( array::Array* a ) { a->cloneToDevice(); } ); } // ---------------------------------------------------------------------------- void Table::cloneFromDevice() const { - std::for_each( data_.begin(), data_.end(), [](array::Array* a){ a->cloneFromDevice();} ); + std::for_each( data_.begin(), data_.end(), []( array::Array* a ) { a->cloneFromDevice(); } ); } // ---------------------------------------------------------------------------- void Table::syncHostDevice() const { - std::for_each( data_.begin(), data_.end(), [](array::Array* a){ a->syncHostDevice();} ); + std::for_each( data_.begin(), data_.end(), []( array::Array* a ) { a->syncHostDevice(); } ); } // ---------------------------------------------------------------------------- bool Table::valid() const { bool res = true; - std::for_each( data_.begin(), data_.end(), [&](array::Array* a){ res &= a->valid();} ); + std::for_each( data_.begin(), data_.end(), [&]( array::Array* a ) { res &= a->valid(); } ); return res; } // ---------------------------------------------------------------------------- bool Table::hostNeedsUpdate() const { - bool res=true; - std::for_each( data_.begin(), data_.end(), [&](array::Array* a){ res &= a->hostNeedsUpdate();} ); + bool res = true; + std::for_each( data_.begin(), data_.end(), [&]( array::Array* a ) { res &= a->hostNeedsUpdate(); } ); return res; } // ---------------------------------------------------------------------------- bool Table::deviceNeedsUpdate() const { - bool res=true; - std::for_each( data_.begin(), data_.end(), [&](array::Array* a){ res &= a->deviceNeedsUpdate();} ); + bool res = true; + std::for_each( data_.begin(), data_.end(), [&]( array::Array* a ) { res &= a->deviceNeedsUpdate(); } ); return res; } // ---------------------------------------------------------------------------- size_t Table::footprint() const { - size_t size = sizeof(*this); - if( owns_ ) { - std::for_each( data_.begin(), data_.end(), [&](array::Array* a){ size += a->footprint();} ); - } - return size; + size_t size = sizeof( *this ); + if ( owns_ ) { + std::for_each( data_.begin(), data_.end(), [&]( array::Array* a ) { size += a->footprint(); } ); + } + return size; } // ---------------------------------------------------------------------------- -void Table::dump(std::ostream& os) const { - values_.dump(os); +void Table::dump( std::ostream& os ) const { + values_.dump( os ); } // ---------------------------------------------------------------------------- -} // namespace array -} // namespace atlas - +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/Table.h b/src/atlas/array/Table.h index ee46a420d..8abf4450c 100644 --- a/src/atlas/array/Table.h +++ b/src/atlas/array/Table.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -19,8 +20,8 @@ #include #include -#include "atlas/library/config.h" #include "atlas/array.h" +#include "atlas/library/config.h" #include "eckit/memory/Owned.h" namespace atlas { @@ -53,139 +54,138 @@ namespace array { class Table : public eckit::Owned { private: - static constexpr unsigned short _values_=0; - static constexpr unsigned short _displs_=1; - static constexpr unsigned short _counts_=2; + static constexpr unsigned short _values_ = 0; + static constexpr unsigned short _displs_ = 1; + static constexpr unsigned short _counts_ = 2; + public: -//-- Constructors + //-- Constructors - /// @brief Construct connectivity table that needs resizing a-posteriori - /// Data is owned - Table( const std::string& name = "" ); + /// @brief Construct connectivity table that needs resizing a-posteriori + /// Data is owned + Table( const std::string& name = "" ); - ~Table(); + ~Table(); private: - - /// @brief Construct connectivity table wrapping existing raw data. - /// No resizing can be performed as data is not owned. - Table( idx_t values[], size_t rows, size_t displs[], size_t counts[] ); + /// @brief Construct connectivity table wrapping existing raw data. + /// No resizing can be performed as data is not owned. + Table( idx_t values[], size_t rows, size_t displs[], size_t counts[] ); public: -//-- Accessors + //-- Accessors - /// @brief Name associated to this Connetivity - const std::string& name() const { return name_; } + /// @brief Name associated to this Connetivity + const std::string& name() const { return name_; } - /// @brief Rename this Connectivity - void rename(const std::string& name) { name_ = name; } + /// @brief Rename this Connectivity + void rename( const std::string& name ) { name_ = name; } - /// @brief Number of rows in the connectivity table - size_t rows() const { return rows_; } + /// @brief Number of rows in the connectivity table + size_t rows() const { return rows_; } - /// @brief Number of columns for specified row in the connectivity table - size_t cols( size_t row_idx ) const { return counts_(row_idx); } + /// @brief Number of columns for specified row in the connectivity table + size_t cols( size_t row_idx ) const { return counts_( row_idx ); } - /// @brief Maximum value for number of columns over all rows - size_t maxcols() const { return maxcols_; } + /// @brief Maximum value for number of columns over all rows + size_t maxcols() const { return maxcols_; } - /// @brief Minimum value for number of columns over all rows - size_t mincols() const { return mincols_; } + /// @brief Minimum value for number of columns over all rows + size_t mincols() const { return mincols_; } - /// @brief Value that is given to unassigned entries - idx_t missing_value() const { return missing_value_; } + /// @brief Value that is given to unassigned entries + idx_t missing_value() const { return missing_value_; } - /// @brief Number of values stored in the table - size_t size() const { return data_[_values_]->size(); } + /// @brief Number of values stored in the table + size_t size() const { return data_[_values_]->size(); } - /// @brief Return memory footprint of table - virtual size_t footprint() const; + /// @brief Return memory footprint of table + virtual size_t footprint() const; - /// @brief Clone data to device - virtual void cloneToDevice() const; + /// @brief Clone data to device + virtual void cloneToDevice() const; - /// @brief Clone data from device - virtual void cloneFromDevice() const; + /// @brief Clone data from device + virtual void cloneFromDevice() const; - /// @brief Synchronise data between host and device - virtual void syncHostDevice() const; + /// @brief Synchronise data between host and device + virtual void syncHostDevice() const; - /// @brief Check if data is valid - virtual bool valid() const; + /// @brief Check if data is valid + virtual bool valid() const; - /// @brief Check if data is present on host - virtual bool hostNeedsUpdate() const; + /// @brief Check if data is present on host + virtual bool hostNeedsUpdate() const; - /// @brief Check if data is present on device - virtual bool deviceNeedsUpdate() const; + /// @brief Check if data is present on device + virtual bool deviceNeedsUpdate() const; - /// @brief Print all values unformatted to output stream - void dump(std::ostream&) const; + /// @brief Print all values unformatted to output stream + void dump( std::ostream& ) const; - /// @brief Check if data is owned or wrapped - bool owns() { return owns_; } + /// @brief Check if data is owned or wrapped + bool owns() { return owns_; } -///-- Modifiers + ///-- Modifiers - /// @brief Resize connectivity, and add given rows - /// @note Can only be used when data is owned. - virtual void add( size_t rows, size_t cols, const idx_t values[], bool fortran_array=false ); + /// @brief Resize connectivity, and add given rows + /// @note Can only be used when data is owned. + virtual void add( size_t rows, size_t cols, const idx_t values[], bool fortran_array = false ); - /// @brief Resize connectivity, and add given rows with missing values - /// @note Can only be used when data is owned. - virtual void add( size_t rows, size_t cols ); + /// @brief Resize connectivity, and add given rows with missing values + /// @note Can only be used when data is owned. + virtual void add( size_t rows, size_t cols ); - /// @brief Resize connectivity, and add given rows with missing values - /// @note Can only be used when data is owned. - virtual void add( size_t rows, const size_t cols[] ); + /// @brief Resize connectivity, and add given rows with missing values + /// @note Can only be used when data is owned. + virtual void add( size_t rows, const size_t cols[] ); - /// @brief Resize connectivity, and insert given rows - /// @note Can only be used when data is owned. - virtual void insert( size_t position, size_t rows, size_t cols, const idx_t values[], bool fortran_array=false ); + /// @brief Resize connectivity, and insert given rows + /// @note Can only be used when data is owned. + virtual void insert( size_t position, size_t rows, size_t cols, const idx_t values[], bool fortran_array = false ); - /// @brief Resize connectivity, and insert given rows with missing values - /// @note Can only be used when data is owned. - virtual void insert( size_t position, size_t rows, size_t cols ); + /// @brief Resize connectivity, and insert given rows with missing values + /// @note Can only be used when data is owned. + virtual void insert( size_t position, size_t rows, size_t cols ); - /// @brief Resize connectivity, and insert given rows with missing values - /// @note Can only be used when data is owned. - virtual void insert( size_t position, size_t rows, const size_t cols[] ); + /// @brief Resize connectivity, and insert given rows with missing values + /// @note Can only be used when data is owned. + virtual void insert( size_t position, size_t rows, const size_t cols[] ); - /// @brief Resize connectivity, and insert given rows with missing values - /// @note Invalidates non-owned Table - virtual void clear(); + /// @brief Resize connectivity, and insert given rows with missing values + /// @note Invalidates non-owned Table + virtual void clear(); private: + ///-- Internal helper functions -///-- Internal helper functions - - void resize_values(size_t old_size, size_t size, bool initialize, const idx_t values[], bool fortran_array); + void resize_values( size_t old_size, size_t size, bool initialize, const idx_t values[], bool fortran_array ); - void resize_counts_and_displs(size_t size); + void resize_counts_and_displs( size_t size ); - void insert_counts_and_displs(size_t position, size_t rows); + void insert_counts_and_displs( size_t position, size_t rows ); - void resize_values(size_t size); + void resize_values( size_t size ); - void insert_values(size_t position, size_t size); + void insert_values( size_t position, size_t size ); private: - - template friend class TableView; - - std::string name_; - bool owns_; - std::array data_; - idx_t missing_value_; - size_t rows_; - size_t maxcols_; - size_t mincols_; - ArrayView displs_; - ArrayView counts_; - ArrayView values_; + template + friend class TableView; + + std::string name_; + bool owns_; + std::array data_; + idx_t missing_value_; + size_t rows_; + size_t maxcols_; + size_t mincols_; + ArrayView displs_; + ArrayView counts_; + ArrayView values_; }; //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/TableView.cc b/src/atlas/array/TableView.cc index e5e22f0d8..c7f4f09ad 100644 --- a/src/atlas/array/TableView.cc +++ b/src/atlas/array/TableView.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,72 +17,66 @@ namespace array { // ---------------------------------------------------------------------------- template -TableView::TableView(const Table &table,bool host) : - host_(host), - missing_value_(table.missing_value()), - rows_(table.rows()), - maxcols_(table.maxcols()), - mincols_(table.mincols()), - values_( - host_ ? make_host_view (*(table.data_[_values_])) - : make_device_view(*(table.data_[_values_]))), - displs_( - host_ ? make_host_view (*(table.data_[_displs_])) - : make_device_view(*(table.data_[_displs_]))), - counts_( - host_ ? make_host_view (*(table.data_[_counts_])) - : make_device_view(*(table.data_[_counts_]))), - const_access_(this), - access_(this) -{} +TableView::TableView( const Table& table, bool host ) : + host_( host ), + missing_value_( table.missing_value() ), + rows_( table.rows() ), + maxcols_( table.maxcols() ), + mincols_( table.mincols() ), + values_( host_ ? make_host_view( *( table.data_[_values_] ) ) + : make_device_view( *( table.data_[_values_] ) ) ), + displs_( host_ ? make_host_view( *( table.data_[_displs_] ) ) + : make_device_view( *( table.data_[_displs_] ) ) ), + counts_( host_ ? make_host_view( *( table.data_[_counts_] ) ) + : make_device_view( *( table.data_[_counts_] ) ) ), + const_access_( this ), + access_( this ) {} // ---------------------------------------------------------------------------- template -TableView::TableView(const TableView& other) : - host_(other.host_), - missing_value_(other.missing_value_), - rows_(other.rows_), - maxcols_(other.maxcols_), - mincols_(other.mincols_), - values_(other.values_), - displs_(other.displs_), - counts_(other.counts_), - const_access_(this), - access_(this) -{} +TableView::TableView( const TableView& other ) : + host_( other.host_ ), + missing_value_( other.missing_value_ ), + rows_( other.rows_ ), + maxcols_( other.maxcols_ ), + mincols_( other.mincols_ ), + values_( other.values_ ), + displs_( other.displs_ ), + counts_( other.counts_ ), + const_access_( this ), + access_( this ) {} // ---------------------------------------------------------------------------- template -TableView TableView::operator=(const TableView& other) { - host_ = other.host_; +TableView TableView::operator=( const TableView& other ) { + host_ = other.host_; missing_value_ = other.missing_value_; - rows_ = other.rows_; - maxcols_ = other.maxcols_; - mincols_ = other.mincols_; - values_ = other.values_; - displs_ = other.displs_; - counts_ = other.counts_; + rows_ = other.rows_; + maxcols_ = other.maxcols_; + mincols_ = other.mincols_; + values_ = other.values_; + displs_ = other.displs_; + counts_ = other.counts_; return *this; } // ---------------------------------------------------------------------------- -template -TableView make_table_view(const Table& table) { - return TableView(table); +template +TableView make_table_view( const Table& table ) { + return TableView( table ); } // ---------------------------------------------------------------------------- template class TableView; template class TableView; -template TableView make_table_view(const Table&); -template TableView make_table_view(const Table&); +template TableView make_table_view( const Table& ); +template TableView make_table_view( const Table& ); // ---------------------------------------------------------------------------- -} // namespace array -} // namespace atlas - +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/TableView.h b/src/atlas/array/TableView.h index f125b1dfd..2e8045f95 100644 --- a/src/atlas/array/TableView.h +++ b/src/atlas/array/TableView.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -22,8 +23,8 @@ #pragma once #include -#include "atlas/library/config.h" #include "atlas/array/Table.h" +#include "atlas/library/config.h" namespace atlas { namespace array { @@ -33,7 +34,7 @@ namespace array { #ifdef ATLAS_HAVE_FORTRAN #define INDEX_REF Index #define FROM_FORTRAN -1 -#define TO_FORTRAN +1 +#define TO_FORTRAN +1 #else #define INDEX_REF * #define FROM_FORTRAN @@ -45,70 +46,93 @@ namespace detail { // TableIndex: // Helper class that does +1 and -1 operations on stored values -class TableIndex -{ +class TableIndex { public: - enum { BASE = 1 }; + enum + { + BASE = 1 + }; + public: - TableIndex(idx_t* idx): idx_(idx) {} - void set(const idx_t& value) { *(idx_) = value+BASE; } - idx_t get() const { return *(idx_)-BASE; } - void operator=(const idx_t& value) { set(value); } - TableIndex& operator=(const TableIndex& other) { set(other.get()); return *this; } - TableIndex& operator+(const idx_t& value) { *(idx_)+=value; return *this; } - TableIndex& operator-(const idx_t& value) { *(idx_)-=value; return *this; } - TableIndex& operator--() { --(*(idx_)); return *this; } - TableIndex& operator++() { ++(*(idx_)); return *this; } - TableIndex& operator+=(const idx_t& value) { *(idx_)+=value; return *this; } - TableIndex& operator-=(const idx_t& value) { *(idx_)-=value; return *this; } - - //implicit conversion - operator idx_t() const { return get(); } + TableIndex( idx_t* idx ) : idx_( idx ) {} + void set( const idx_t& value ) { *( idx_ ) = value + BASE; } + idx_t get() const { return *(idx_)-BASE; } + void operator =( const idx_t& value ) { set( value ); } + TableIndex& operator=( const TableIndex& other ) { + set( other.get() ); + return *this; + } + TableIndex& operator+( const idx_t& value ) { + *( idx_ ) += value; + return *this; + } + TableIndex& operator-( const idx_t& value ) { + *( idx_ ) -= value; + return *this; + } + TableIndex& operator--() { + --( *( idx_ ) ); + return *this; + } + TableIndex& operator++() { + ++( *( idx_ ) ); + return *this; + } + TableIndex& operator+=( const idx_t& value ) { + *( idx_ ) += value; + return *this; + } + TableIndex& operator-=( const idx_t& value ) { + *( idx_ ) -= value; + return *this; + } + + // implicit conversion + operator idx_t() const { return get(); } private: - idx_t* idx_; + idx_t* idx_; }; -} +} // namespace detail // ------------------------------------------------------------------------------------------------------ -template +template class TableRow { - - #ifdef ATLAS_HAVE_FORTRAN +#ifdef ATLAS_HAVE_FORTRAN typedef detail::TableIndex Index; - #else +#else typedef idx_t Index; - #endif +#endif - using ReturnType = typename std::conditional::type; + using ReturnType = typename std::conditional::type; public: - ATLAS_HOST_DEVICE - TableRow(const idx_t *data, size_t size) : data_(const_cast(data)), size_(size) {} + TableRow( const idx_t* data, size_t size ) : data_( const_cast( data ) ), size_( size ) {} ATLAS_HOST_DEVICE - idx_t operator()(size_t i) const { return data_[i] FROM_FORTRAN; } + idx_t operator()( size_t i ) const { return data_[i] FROM_FORTRAN; } ATLAS_HOST_DEVICE - ReturnType operator()(size_t i) { return INDEX_REF(data_+i); } + ReturnType operator()( size_t i ) { return INDEX_REF( data_ + i ); } ATLAS_HOST_DEVICE size_t size() const { return size_; } - // TODO: Following function should only be allowed to compile if ReadOnly=false (SFINAE?) + // TODO: Following function should only be allowed to compile if + // ReadOnly=false (SFINAE?) TableRow& operator=( const idx_t column_values[] ) { assert( not ReadOnly ); - for( size_t n=0; n class TableView : public eckit::Owned { - #ifdef ATLAS_HAVE_FORTRAN - using Index = typename std::conditional::type; + using Index = typename std::conditional::type; #else - using Index = idx_t; + using Index = idx_t; #endif public: - typedef TableRow Row; - typedef TableRow ConstRow; + typedef TableRow Row; + typedef TableRow ConstRow; + + static constexpr unsigned short _values_ = 0; + static constexpr unsigned short _displs_ = 1; + static constexpr unsigned short _counts_ = 2; - static constexpr unsigned short _values_=0; - static constexpr unsigned short _displs_=1; - static constexpr unsigned short _counts_=2; public: - using value_type = idx_t; - using Data = typename std::conditional::type; + using value_type = idx_t; + using Data = typename std::conditional::type; - template - struct Access_t {}; + template + struct Access_t {}; - template struct Access_t { - Access_t(const TableView* tv) : tv_(const_cast*>(tv)) {} - TableView* tv_; - idx_t apply(size_t row, size_t col) const { - return tv_->values_(tv_->displs_(row) + col) FROM_FORTRAN; - } - }; + template + struct Access_t { + Access_t( const TableView* tv ) : tv_( const_cast*>( tv ) ) {} + TableView* tv_; + idx_t apply( size_t row, size_t col ) const { return tv_->values_( tv_->displs_( row ) + col ) FROM_FORTRAN; } + }; - template struct Access_t { - Access_t(const TableView* tv) : tv_(const_cast*>(tv)) {} - TableView* tv_; - Index apply(size_t row, size_t col) const { - return Index( &tv_->values_(tv_->displs_(row) + col) ); - } - }; + template + struct Access_t { + Access_t( const TableView* tv ) : tv_( const_cast*>( tv ) ) {} + TableView* tv_; + Index apply( size_t row, size_t col ) const { return Index( &tv_->values_( tv_->displs_( row ) + col ) ); } + }; - using Access = Access_t; - using ConstAccess = Access_t; + using Access = Access_t; + using ConstAccess = Access_t; -//-- Constructors + //-- Constructors - TableView(const Table &table,bool host=true); + TableView( const Table& table, bool host = true ); - TableView(const TableView& other); + TableView( const TableView& other ); - TableView operator=(const TableView& other); + TableView operator=( const TableView& other ); - ~TableView(){} + ~TableView() {} -//-- Accessors + //-- Accessors - /// @brief Number of rows in the connectivity table - ATLAS_HOST_DEVICE - size_t rows() const { return rows_; } + /// @brief Number of rows in the connectivity table + ATLAS_HOST_DEVICE + size_t rows() const { return rows_; } - /// @brief Number of columns for specified row in the connectivity table - ATLAS_HOST_DEVICE - size_t cols( size_t row_idx ) const { return counts_(row_idx); } + /// @brief Number of columns for specified row in the connectivity table + ATLAS_HOST_DEVICE + size_t cols( size_t row_idx ) const { return counts_( row_idx ); } - /// @brief Maximum value for number of columns over all rows - ATLAS_HOST_DEVICE - size_t maxcols() const { return maxcols_; } + /// @brief Maximum value for number of columns over all rows + ATLAS_HOST_DEVICE + size_t maxcols() const { return maxcols_; } - /// @brief Minimum value for number of columns over all rows - ATLAS_HOST_DEVICE - size_t mincols() const { return mincols_; } + /// @brief Minimum value for number of columns over all rows + ATLAS_HOST_DEVICE + size_t mincols() const { return mincols_; } - /// @brief Access to connectivity table elements for given row and column - /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. - ATLAS_HOST_DEVICE - idx_t operator()( size_t row_idx, size_t col_idx ) const { - assert(counts_(row_idx) > col_idx); - return const_access_.apply(row_idx,col_idx); - } + /// @brief Access to connectivity table elements for given row and column + /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. + ATLAS_HOST_DEVICE + idx_t operator()( size_t row_idx, size_t col_idx ) const { + assert( counts_( row_idx ) > col_idx ); + return const_access_.apply( row_idx, col_idx ); + } - /// @brief Access to connectivity table elements for given row and column - /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. - ATLAS_HOST_DEVICE - Index operator()( size_t row_idx, size_t col_idx ) { - assert(counts_(row_idx) > col_idx); - return access_.apply(row_idx,col_idx); - } + /// @brief Access to connectivity table elements for given row and column + /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. + ATLAS_HOST_DEVICE + Index operator()( size_t row_idx, size_t col_idx ) { + assert( counts_( row_idx ) > col_idx ); + return access_.apply( row_idx, col_idx ); + } - /// @brief Access to raw data. - /// Note that the connectivity base is 1 in case ATLAS_HAVE_FORTRAN is defined. - const idx_t* data() const { return values_.data(); } - Data* data() { return values_.data(); } + /// @brief Access to raw data. + /// Note that the connectivity base is 1 in case ATLAS_HAVE_FORTRAN is + /// defined. + const idx_t* data() const { return values_.data(); } + Data* data() { return values_.data(); } - ATLAS_HOST_DEVICE - size_t size() const { return values_.size();} + ATLAS_HOST_DEVICE + size_t size() const { return values_.size(); } - ATLAS_HOST_DEVICE - idx_t missing_value() const { return missing_value_; } + ATLAS_HOST_DEVICE + idx_t missing_value() const { return missing_value_; } - ATLAS_HOST_DEVICE - ConstRow row( size_t row_idx ) const { - return ConstRow( values_.data()+displs_(row_idx) , counts_(row_idx) ); - } + ATLAS_HOST_DEVICE + ConstRow row( size_t row_idx ) const { return ConstRow( values_.data() + displs_( row_idx ), counts_( row_idx ) ); } - ATLAS_HOST_DEVICE - Row row( size_t row_idx ) { - return Row( values_.data()+displs_(row_idx) , counts_(row_idx) ); - } + ATLAS_HOST_DEVICE + Row row( size_t row_idx ) { return Row( values_.data() + displs_( row_idx ), counts_( row_idx ) ); } -///-- Modifiers + ///-- Modifiers - ATLAS_HOST_DEVICE - size_t displs(const size_t row) const { return displs_(row); } + ATLAS_HOST_DEVICE + size_t displs( const size_t row ) const { return displs_( row ); } private: - const size_t *displs() const { return displs_.data(); } - const size_t *counts() const { return counts_.data(); } + const size_t* displs() const { return displs_.data(); } + const size_t* counts() const { return counts_.data(); } private: - bool host_; - idx_t missing_value_; - size_t rows_; - size_t maxcols_; - size_t mincols_; - ArrayView values_; - ArrayView displs_; - ArrayView counts_; - ConstAccess const_access_; - Access access_; + bool host_; + idx_t missing_value_; + size_t rows_; + size_t maxcols_; + size_t mincols_; + ArrayView values_; + ArrayView displs_; + ArrayView counts_; + ConstAccess const_access_; + Access access_; }; // ----------------------------------------------------------------------------------------------------- @@ -251,5 +270,5 @@ class TableView : public eckit::Owned { //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/Vector.h b/src/atlas/array/Vector.h index df42f5190..94953ebad 100644 --- a/src/atlas/array/Vector.h +++ b/src/atlas/array/Vector.h @@ -10,17 +10,17 @@ #pragma once -#include #include +#include #include "atlas/library/config.h" #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - #include +#include #endif -#include "atlas/runtime/ErrorHandling.h" #include "atlas/library/config.h" +#include "atlas/runtime/ErrorHandling.h" namespace atlas { namespace array { @@ -30,134 +30,131 @@ namespace array { template class Vector { public: - Vector(size_t N = 0) : data_(N ? new T[N] : nullptr), data_gpu_(nullptr), size_(N) {} - - void resize_impl(size_t N) { - if( data_gpu_ ) throw eckit::AssertionFailed("we can not resize a vector after has been cloned to device"); - assert(N >= size_); - if (N == size_) return; - - T* d_ = new T[N]; - for(unsigned int c=0; c < size_; ++c) { - d_[c] = data_[c]; - } - if( data_ ) delete[] data_; - data_ = d_; - } - - void resize(size_t N) { - resize_impl(N); - size_ = N; - } - - void resize(size_t N, T val) { - resize_impl(N); - for(unsigned int c=size_; c < N; ++c) { - data_[c] = val; + Vector( size_t N = 0 ) : data_( N ? new T[N] : nullptr ), data_gpu_( nullptr ), size_( N ) {} + + void resize_impl( size_t N ) { + if ( data_gpu_ ) throw eckit::AssertionFailed( "we can not resize a vector after has been cloned to device" ); + assert( N >= size_ ); + if ( N == size_ ) return; + + T* d_ = new T[N]; + for ( unsigned int c = 0; c < size_; ++c ) { + d_[c] = data_[c]; + } + if ( data_ ) delete[] data_; + data_ = d_; } - size_ = N; - } + void resize( size_t N ) { + resize_impl( N ); + size_ = N; + } + + void resize( size_t N, T val ) { + resize_impl( N ); + for ( unsigned int c = size_; c < N; ++c ) { + data_[c] = val; + } - void cloneToDevice() { - if(!data_gpu_) { + size_ = N; + } + + void cloneToDevice() { + if ( !data_gpu_ ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - ::cudaMalloc((void**)(&data_gpu_), sizeof(T*)*size_); + ::cudaMalloc( (void**)( &data_gpu_ ), sizeof( T* ) * size_ ); - T* buff = new T[size_]; + T* buff = new T[size_]; - for(size_t i=0; i < size(); ++i) { - data_[i]->cloneToDevice(); - buff[i] = data_[i]->gpu_object_ptr(); - } - ::cudaMemcpy(data_gpu_, buff, sizeof(T*)*size_, cudaMemcpyHostToDevice); - delete buff; + for ( size_t i = 0; i < size(); ++i ) { + data_[i]->cloneToDevice(); + buff[i] = data_[i]->gpu_object_ptr(); + } + ::cudaMemcpy( data_gpu_, buff, sizeof( T* ) * size_, cudaMemcpyHostToDevice ); + delete buff; #else - data_gpu_ = data_; + data_gpu_ = data_; #endif - size_gpu_ = size_; - } - else { - assert(size_gpu_ == size_); -#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - for(size_t i=0; i < size(); ++i) { - data_[i]->cloneToDevice(); - assert(data_gpu_[i] == data_[i]->gpu_object_ptr()); + size_gpu_ = size_; } + else { + assert( size_gpu_ == size_ ); +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA + for ( size_t i = 0; i < size(); ++i ) { + data_[i]->cloneToDevice(); + assert( data_gpu_[i] == data_[i]->gpu_object_ptr() ); + } #endif + } } - } - void cloneFromDevice() { - assert(data_gpu_); + void cloneFromDevice() { + assert( data_gpu_ ); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - for(size_t i=0; i < size(); ++i) { - data_[i]->cloneFromDevice(); - } + for ( size_t i = 0; i < size(); ++i ) { + data_[i]->cloneFromDevice(); + } #endif - } + } - T* gpu_object_ptr() { return data_gpu_;} + T* gpu_object_ptr() { return data_gpu_; } - T* data() { return data_;} - T* data_gpu() { return data_gpu_;} + T* data() { return data_; } + T* data_gpu() { return data_gpu_; } - size_t size() const { return size_;} + size_t size() const { return size_; } private: - T* data_; - T* data_gpu_; - size_t size_; - size_t size_gpu_; + T* data_; + T* data_gpu_; + size_t size_; + size_t size_gpu_; }; template class VectorView { public: - VectorView() : vector_(NULL),data_(NULL), size_(0) {} - VectorView(Vector const& vector, T* data) : vector_(&vector), data_(data), size_(vector.size()) {} - - ATLAS_HOST_DEVICE - T& operator[](size_t idx) { - assert(idx < size_); - - return data_[idx]; - } - - ATLAS_HOST_DEVICE - T const& operator[](size_t idx) const { - assert(idx < size_); - return data_[idx]; - } - ATLAS_HOST_DEVICE - T base() { return *data_; } - - ATLAS_HOST_DEVICE - size_t size() const { return size_;} - - bool is_valid(Vector& vector) { - return (&vector) == vector_ && (data_ != NULL); - } + VectorView() : vector_( NULL ), data_( NULL ), size_( 0 ) {} + VectorView( Vector const& vector, T* data ) : vector_( &vector ), data_( data ), size_( vector.size() ) {} + + ATLAS_HOST_DEVICE + T& operator[]( size_t idx ) { + assert( idx < size_ ); + + return data_[idx]; + } + + ATLAS_HOST_DEVICE + T const& operator[]( size_t idx ) const { + assert( idx < size_ ); + return data_[idx]; + } + ATLAS_HOST_DEVICE + T base() { return *data_; } + + ATLAS_HOST_DEVICE + size_t size() const { return size_; } + + bool is_valid( Vector& vector ) { return ( &vector ) == vector_ && ( data_ != NULL ); } + public: - Vector const* vector_; - T* data_; - size_t size_; + Vector const* vector_; + T* data_; + size_t size_; }; template -VectorView -make_host_vector_view(Vector vector_) { - return VectorView(vector_, vector_.data()); +VectorView make_host_vector_view( Vector vector_ ) { + return VectorView( vector_, vector_.data() ); } template -VectorView -make_device_vector_view(Vector vector_) { - return VectorView(vector_, vector_.data_gpu()); +VectorView make_device_vector_view( Vector vector_ ) { + return VectorView( vector_, vector_.data_gpu() ); } //------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/gridtools/GPUClonable.h b/src/atlas/array/gridtools/GPUClonable.h index e2fba61c6..6beaa5b61 100644 --- a/src/atlas/array/gridtools/GPUClonable.h +++ b/src/atlas/array/gridtools/GPUClonable.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,42 +17,38 @@ namespace atlas { namespace array { namespace gridtools { -template +template struct GPUClonable { - - GPUClonable(Base * base_ptr) : - base_ptr_(base_ptr), - gpu_object_ptr_(nullptr) { + GPUClonable( Base* base_ptr ) : base_ptr_( base_ptr ), gpu_object_ptr_( nullptr ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - cudaMalloc(&gpu_object_ptr_, sizeof(Base)); + cudaMalloc( &gpu_object_ptr_, sizeof( Base ) ); #endif } ~GPUClonable() { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - assert(gpu_object_ptr_); - cudaFree(gpu_object_ptr_); + assert( gpu_object_ptr_ ); + cudaFree( gpu_object_ptr_ ); #endif } - Base* gpu_object_ptr() { return static_cast(gpu_object_ptr_); } + Base* gpu_object_ptr() { return static_cast( gpu_object_ptr_ ); } void cloneToDevice() { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - cudaMemcpy(gpu_object_ptr_, base_ptr_, sizeof(Base), cudaMemcpyHostToDevice); + cudaMemcpy( gpu_object_ptr_, base_ptr_, sizeof( Base ), cudaMemcpyHostToDevice ); #endif } void cloneFromDevice() { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - cudaMemcpy(base_ptr_, gpu_object_ptr_, sizeof(Base), cudaMemcpyDeviceToHost); + cudaMemcpy( base_ptr_, gpu_object_ptr_, sizeof( Base ), cudaMemcpyDeviceToHost ); #endif } Base* base_ptr_; void* gpu_object_ptr_; - }; -} // namespace gridtools -} // namespace array -} // namespace gridtools +} // namespace gridtools +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 7fe7dcc01..960fa5d91 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -4,24 +4,25 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include #include +#include -#include "atlas/array_fwd.h" #include "atlas/array.h" #include "atlas/array/ArrayUtil.h" -#include "atlas/array/DataType.h" #include "atlas/array/ArrayView.h" +#include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" -#include "atlas/array/gridtools/GridToolsTraits.h" -#include "atlas/array/gridtools/GridToolsDataStore.h" #include "atlas/array/gridtools/GridToolsArrayHelpers.h" +#include "atlas/array/gridtools/GridToolsDataStore.h" +#include "atlas/array/gridtools/GridToolsTraits.h" #include "atlas/array/helpers/ArrayInitializer.h" +#include "atlas/array_fwd.h" #ifdef ATLAS_HAVE_ACC #include "atlas_acc_support/atlas_acc_map_data.h" #endif @@ -41,384 +42,471 @@ namespace gridtools { //------------------------------------------------------------------------------ -template using UintSequence = ::gridtools::make_gt_integer_sequence; +template +using UintSequence = ::gridtools::make_gt_integer_sequence; template class Storage, typename StorageInfo> -static Array* wrap_array(::gridtools::data_store< Storage, StorageInfo> * ds, const ArraySpec& spec) { - assert(ds); - using data_store_t = typename std::remove_pointer::type; - ArrayDataStore* data_store = new GridToolsDataStore(ds); - return new ArrayT(data_store,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 ); + return new ArrayT( data_store, spec ); } //------------------------------------------------------------------------------ -} // namespace gridtools +} // namespace gridtools template class ArrayT_impl { public: - ArrayT_impl(ArrayT& array) : array_(array) {} - - template > - void construct(UInts... dims) - { - auto gt_storage = create_gt_storage::type>(dims...); - using data_store_t = typename std::remove_pointer::type; - array_.data_store_ = std::unique_ptr(new GridToolsDataStore(gt_storage)); - array_.spec_ = make_spec(gt_storage,dims...); - } - - void construct(const ArrayShape& shape) { - assert(shape.size() > 0); - switch (shape.size()) { - case 1: return construct(shape[0]); - case 2: return construct(shape[0],shape[1]); - case 3: return construct(shape[0],shape[1],shape[2]); - case 4: return construct(shape[0],shape[1],shape[2],shape[3]); - case 5: return construct(shape[0],shape[1],shape[2],shape[3],shape[4]); - default: { - std::stringstream err; - err << "shape not recognized"; - throw eckit::BadParameter(err.str(), Here()); - } + ArrayT_impl( ArrayT& array ) : array_( array ) {} + + template > + void construct( UInts... dims ) { + auto gt_storage = create_gt_storage::type>( dims... ); + using data_store_t = typename std::remove_pointer::type; + array_.data_store_ = std::unique_ptr( new GridToolsDataStore( gt_storage ) ); + array_.spec_ = make_spec( gt_storage, dims... ); } - } - - void construct(const ArrayShape& shape, const ArrayLayout& layout) { - ASSERT( shape.size() > 0 ); - ASSERT( shape.size() == layout.size() ); - switch (shape.size()) { - case 1: return construct(shape[0]); - case 2: { - if( layout[0]==0 && layout[1]==1 ) - return construct_with_layout<::gridtools::layout_map<0,1>>(shape[0],shape[1]); - if( layout[0]==1 && layout[1]==0 ) - return construct_with_layout<::gridtools::layout_map<1,0>>(shape[0],shape[1]); - } - case 3: { - if( layout[0]==0 && layout[1]==1 && layout[2] == 2) - return construct_with_layout<::gridtools::layout_map<0,1,2>>(shape[0],shape[1],shape[2]); - if( layout[0]==0 && layout[1]==2 && layout[2] == 1) - return construct_with_layout<::gridtools::layout_map<0,2,1>>(shape[0],shape[1],shape[2]); - if( layout[0]==1 && layout[1]==0 && layout[2] == 2) - return construct_with_layout<::gridtools::layout_map<1,0,2>>(shape[0],shape[1],shape[2]); - if( layout[0]==1 && layout[1]==2 && layout[2] == 0) - return construct_with_layout<::gridtools::layout_map<1,2,0>>(shape[0],shape[1],shape[2]); - if( layout[0]==2 && layout[1]==0 && layout[2] == 1) - return construct_with_layout<::gridtools::layout_map<2,0,1>>(shape[0],shape[1],shape[2]); - if( layout[0]==2 && layout[1]==1 && layout[2] == 0) - return construct_with_layout<::gridtools::layout_map<2,1,0>>(shape[0],shape[1],shape[2]); - } - case 4: { - if( layout[0]==0 && layout[1]==1 && layout[2] == 2 && layout[3] == 3) - return construct_with_layout<::gridtools::layout_map<0,1,2,3>>(shape[0],shape[1],shape[2],shape[3]); - if( layout[0]==3 && layout[1]==2 && layout[2] == 1 && layout[3] == 0) - return construct_with_layout<::gridtools::layout_map<3,2,1,0>>(shape[0],shape[1],shape[2],shape[3]); - } - case 5: { - if( layout[0]==0 && layout[1]==1 && layout[2] == 2 && layout[3] == 3 && layout[4] == 4) - return construct_with_layout<::gridtools::layout_map<0,1,2,3,4>>(shape[0],shape[1],shape[2],shape[3],shape[4]); - if( layout[0]==4 && layout[1]==3 && layout[2] == 2 && layout[3] == 1 && layout[4] == 0) - return construct_with_layout<::gridtools::layout_map<4,3,2,1,0>>(shape[0],shape[1],shape[2],shape[3],shape[4]); - } - default: { - std::stringstream err; - if( shape.size() > 5 ) - err << "shape not recognized"; - else { - err << "Layout < "; - for( size_t j=0; j not implemented in Atlas."; + + void construct( const ArrayShape& shape ) { + assert( shape.size() > 0 ); + switch ( shape.size() ) { + case 1: + return construct( shape[0] ); + case 2: + return construct( shape[0], shape[1] ); + case 3: + return construct( shape[0], shape[1], shape[2] ); + case 4: + return construct( shape[0], shape[1], shape[2], shape[3] ); + case 5: + return construct( shape[0], shape[1], shape[2], shape[3], shape[4] ); + default: { + std::stringstream err; + err << "shape not recognized"; + throw eckit::BadParameter( err.str(), Here() ); + } } - throw eckit::BadParameter(err.str(), Here()); - } } - } - - template > - void construct_with_layout(UInts... dims) { - auto gt_data_store_ptr = create_gt_storage(dims...); - using data_store_t = typename std::remove_pointer::type; - array_.data_store_ = std::unique_ptr( new GridToolsDataStore(gt_data_store_ptr) ); - array_.spec_ = make_spec(gt_data_store_ptr, dims...); - } - - - template < typename... Ints > - void resize_variadic(Ints... c) { - if(sizeof...(c) != array_.rank()){ - std::stringstream err; err << - "Trying to resize an array of Rank " << array_.rank() << - " by dimensions with Rank " << sizeof...(c) << std::endl; - throw eckit::BadParameter(err.str(),Here()); - } - - check_dimension_lengths(array_.shape(), c...); - - if(array_.valid()) - array_.syncHostDevice(); - - Array* resized = Array::create(ArrayShape{(unsigned int)c...}); - - array_initializer::apply( array_, *resized); - array_.replace(*resized); - delete resized; + + void construct( const ArrayShape& shape, const ArrayLayout& layout ) { + ASSERT( shape.size() > 0 ); + ASSERT( shape.size() == layout.size() ); + switch ( shape.size() ) { + case 1: + return construct( shape[0] ); + case 2: { + if ( layout[0] == 0 && layout[1] == 1 ) + return construct_with_layout<::gridtools::layout_map<0, 1>>( shape[0], shape[1] ); + if ( layout[0] == 1 && layout[1] == 0 ) + return construct_with_layout<::gridtools::layout_map<1, 0>>( shape[0], shape[1] ); + } + case 3: { + if ( layout[0] == 0 && layout[1] == 1 && layout[2] == 2 ) + return construct_with_layout<::gridtools::layout_map<0, 1, 2>>( shape[0], shape[1], shape[2] ); + if ( layout[0] == 0 && layout[1] == 2 && layout[2] == 1 ) + return construct_with_layout<::gridtools::layout_map<0, 2, 1>>( shape[0], shape[1], shape[2] ); + if ( layout[0] == 1 && layout[1] == 0 && layout[2] == 2 ) + return construct_with_layout<::gridtools::layout_map<1, 0, 2>>( shape[0], shape[1], shape[2] ); + if ( layout[0] == 1 && layout[1] == 2 && layout[2] == 0 ) + return construct_with_layout<::gridtools::layout_map<1, 2, 0>>( shape[0], shape[1], shape[2] ); + if ( layout[0] == 2 && layout[1] == 0 && layout[2] == 1 ) + return construct_with_layout<::gridtools::layout_map<2, 0, 1>>( shape[0], shape[1], shape[2] ); + if ( layout[0] == 2 && layout[1] == 1 && layout[2] == 0 ) + return construct_with_layout<::gridtools::layout_map<2, 1, 0>>( shape[0], shape[1], shape[2] ); + } + case 4: { + if ( layout[0] == 0 && layout[1] == 1 && layout[2] == 2 && layout[3] == 3 ) + return construct_with_layout<::gridtools::layout_map<0, 1, 2, 3>>( shape[0], shape[1], shape[2], + shape[3] ); + if ( layout[0] == 3 && layout[1] == 2 && layout[2] == 1 && layout[3] == 0 ) + return construct_with_layout<::gridtools::layout_map<3, 2, 1, 0>>( shape[0], shape[1], shape[2], + shape[3] ); + } + case 5: { + if ( layout[0] == 0 && layout[1] == 1 && layout[2] == 2 && layout[3] == 3 && layout[4] == 4 ) + return construct_with_layout<::gridtools::layout_map<0, 1, 2, 3, 4>>( shape[0], shape[1], shape[2], + shape[3], shape[4] ); + if ( layout[0] == 4 && layout[1] == 3 && layout[2] == 2 && layout[3] == 1 && layout[4] == 0 ) + return construct_with_layout<::gridtools::layout_map<4, 3, 2, 1, 0>>( shape[0], shape[1], shape[2], + shape[3], shape[4] ); + } + default: { + std::stringstream err; + if ( shape.size() > 5 ) + err << "shape not recognized"; + else { + err << "Layout < "; + for ( size_t j = 0; j < layout.size(); ++j ) + err << layout[j] << " "; + err << "> not implemented in Atlas."; + } + throw eckit::BadParameter( err.str(), Here() ); + } + } } + template > + void construct_with_layout( UInts... dims ) { + auto gt_data_store_ptr = create_gt_storage( dims... ); + using data_store_t = typename std::remove_pointer::type; + array_.data_store_ = + std::unique_ptr( new GridToolsDataStore( gt_data_store_ptr ) ); + array_.spec_ = make_spec( gt_data_store_ptr, dims... ); + } - template - void apply_resize(const ArrayShape& shape, ::gridtools::gt_integer_sequence ) { - return resize_variadic(shape[Indices]...); - } + template + void resize_variadic( Ints... c ) { + if ( sizeof...( c ) != array_.rank() ) { + std::stringstream err; + err << "Trying to resize an array of Rank " << array_.rank() << " by dimensions with Rank " + << sizeof...( c ) << std::endl; + throw eckit::BadParameter( err.str(), Here() ); + } + + check_dimension_lengths( array_.shape(), c... ); + + if ( array_.valid() ) array_.syncHostDevice(); + + Array* resized = Array::create( ArrayShape{(unsigned int)c...} ); + + array_initializer::apply( array_, *resized ); + array_.replace( *resized ); + delete resized; + } + + template + void apply_resize( const ArrayShape& shape, ::gridtools::gt_integer_sequence ) { + return resize_variadic( shape[Indices]... ); + } private: - ArrayT& array_; + ArrayT& array_; }; //------------------------------------------------------------------------------ -template Array* Array::create( size_t dim0 ) { +template +Array* Array::create( size_t dim0 ) { return new ArrayT( dim0 ); } -template Array* Array::create( size_t dim0, size_t dim1 ) { +template +Array* Array::create( size_t dim0, size_t dim1 ) { return new ArrayT( dim0, dim1 ); } -template Array* Array::create( size_t dim0, size_t dim1, size_t dim2 ) { +template +Array* Array::create( size_t dim0, size_t dim1, size_t dim2 ) { return new ArrayT( dim0, dim1, dim2 ); } -template Array* Array::create( size_t dim0, size_t dim1, size_t dim2, size_t dim3 ) { +template +Array* Array::create( size_t dim0, size_t dim1, size_t dim2, size_t dim3 ) { return new ArrayT( dim0, dim1, dim2, dim3 ); } -template Array* Array::create( size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4 ) { +template +Array* Array::create( size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4 ) { return new ArrayT( dim0, dim1, dim2, dim3, dim4 ); } -template Array* Array::create( const ArrayShape& shape ) { +template +Array* Array::create( const ArrayShape& shape ) { return new ArrayT( shape ); } -template Array* Array::create( const ArrayShape& shape, const ArrayLayout& layout ) { - return new ArrayT( shape,layout ); +template +Array* Array::create( const ArrayShape& shape, const ArrayLayout& layout ) { + return new ArrayT( shape, layout ); } -template Array* Array::wrap( Value* data, const ArraySpec& spec ) { - ArrayShape const& shape = spec.shape(); +template +Array* Array::wrap( Value* data, const ArraySpec& spec ) { + ArrayShape const& shape = spec.shape(); ArrayStrides const& strides = spec.strides(); - assert(shape.size() > 0); - - switch (shape.size()) { - case 1: return wrap_array( wrap_gt_storage(data, get_array_from_vector<1>(shape), get_array_from_vector<1>(strides)), spec); - case 2: return wrap_array( wrap_gt_storage(data, get_array_from_vector<2>(shape), get_array_from_vector<2>(strides)), spec); - case 3: return wrap_array( wrap_gt_storage(data, get_array_from_vector<3>(shape), get_array_from_vector<3>(strides)), spec); - case 4: return wrap_array( wrap_gt_storage(data, get_array_from_vector<4>(shape), get_array_from_vector<4>(strides)), spec); - case 5: return wrap_array( wrap_gt_storage(data, get_array_from_vector<5>(shape), get_array_from_vector<5>(strides)), spec); - case 6: return wrap_array( wrap_gt_storage(data, get_array_from_vector<6>(shape), get_array_from_vector<6>(strides)), spec); - case 7: return wrap_array( wrap_gt_storage(data, get_array_from_vector<7>(shape), get_array_from_vector<7>(strides)), spec); - case 8: return wrap_array( wrap_gt_storage(data, get_array_from_vector<8>(shape), get_array_from_vector<8>(strides)), spec); - case 9: return wrap_array( wrap_gt_storage(data, get_array_from_vector<9>(shape), get_array_from_vector<9>(strides)), spec); + assert( shape.size() > 0 ); + + switch ( shape.size() ) { + case 1: + return wrap_array( wrap_gt_storage( data, get_array_from_vector<1>( shape ), + get_array_from_vector<1>( strides ) ), + spec ); + case 2: + return wrap_array( wrap_gt_storage( data, get_array_from_vector<2>( shape ), + get_array_from_vector<2>( strides ) ), + spec ); + case 3: + return wrap_array( wrap_gt_storage( data, get_array_from_vector<3>( shape ), + get_array_from_vector<3>( strides ) ), + spec ); + case 4: + return wrap_array( wrap_gt_storage( data, get_array_from_vector<4>( shape ), + get_array_from_vector<4>( strides ) ), + spec ); + case 5: + return wrap_array( wrap_gt_storage( data, get_array_from_vector<5>( shape ), + get_array_from_vector<5>( strides ) ), + spec ); + case 6: + return wrap_array( wrap_gt_storage( data, get_array_from_vector<6>( shape ), + get_array_from_vector<6>( strides ) ), + spec ); + case 7: + return wrap_array( wrap_gt_storage( data, get_array_from_vector<7>( shape ), + get_array_from_vector<7>( strides ) ), + spec ); + case 8: + return wrap_array( wrap_gt_storage( data, get_array_from_vector<8>( shape ), + get_array_from_vector<8>( strides ) ), + spec ); + case 9: + return wrap_array( wrap_gt_storage( data, get_array_from_vector<9>( shape ), + get_array_from_vector<9>( strides ) ), + spec ); default: { std::stringstream err; err << "shape not recognized"; - throw eckit::BadParameter(err.str(), Here()); + throw eckit::BadParameter( err.str(), Here() ); } } } -template Array* Array::wrap( Value* data, const ArrayShape& shape ) { - return wrap(data,ArraySpec(shape)); -} - -Array* Array::create(DataType datatype, const ArrayShape& shape) -{ - switch( datatype.kind() ) - { - case DataType::KIND_REAL64: return create(shape); - case DataType::KIND_REAL32: return create(shape); - case DataType::KIND_INT32: return create(shape); - case DataType::KIND_INT64: return create(shape); - case DataType::KIND_UINT64: return create(shape); - default: - { - std::stringstream err; err << "data kind " << datatype.kind() << " not recognised."; - throw eckit::BadParameter(err.str(),Here()); +template +Array* Array::wrap( Value* data, const ArrayShape& shape ) { + return wrap( data, ArraySpec( shape ) ); +} + +Array* Array::create( DataType datatype, const ArrayShape& shape ) { + switch ( datatype.kind() ) { + case DataType::KIND_REAL64: + return create( shape ); + case DataType::KIND_REAL32: + return create( shape ); + case DataType::KIND_INT32: + return create( shape ); + case DataType::KIND_INT64: + return create( shape ); + case DataType::KIND_UINT64: + return create( shape ); + default: { + std::stringstream err; + err << "data kind " << datatype.kind() << " not recognised."; + throw eckit::BadParameter( err.str(), Here() ); + } } - } - return 0; -} + return 0; +} + +Array* Array::create( DataType datatype, const ArrayShape& shape, const ArrayLayout& layout ) { + switch ( datatype.kind() ) { + case DataType::KIND_REAL64: + return create( shape, layout ); + case DataType::KIND_REAL32: + return create( shape, layout ); + case DataType::KIND_INT32: + return create( shape, layout ); + case DataType::KIND_INT64: + return create( shape, layout ); + case DataType::KIND_UINT64: + return create( shape, layout ); -Array* Array::create(DataType datatype, const ArrayShape& shape, const ArrayLayout& layout) -{ - switch( datatype.kind() ) - { - case DataType::KIND_REAL64: return create(shape,layout); - case DataType::KIND_REAL32: return create(shape,layout); - case DataType::KIND_INT32: return create(shape,layout); - case DataType::KIND_INT64: return create(shape,layout); - case DataType::KIND_UINT64: return create(shape,layout); - - default: - { - std::stringstream err; err << "data kind " << datatype.kind() << " not recognised."; - throw eckit::BadParameter(err.str(),Here()); + default: { + std::stringstream err; + err << "data kind " << datatype.kind() << " not recognised."; + throw eckit::BadParameter( err.str(), Here() ); + } } - } - return 0; + return 0; } //------------------------------------------------------------------------------ -Array::~Array() { -} +Array::~Array() {} //------------------------------------------------------------------------------ template size_t ArrayT::footprint() const { - size_t size = sizeof(*this); - size += bytes(); - return size; + size_t size = sizeof( *this ); + size += bytes(); + return size; } //------------------------------------------------------------------------------ template bool ArrayT::accMap() const { - if( not acc_map_ ) { -#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA && defined(ATLAS_HAVE_ACC) - atlas_acc_map_data( (void*) host_data(), (void*) device_data(), spec_.allocatedSize()*sizeof(Value) ); - acc_map_ = true; + if ( not acc_map_ ) { +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA && defined( ATLAS_HAVE_ACC ) + atlas_acc_map_data( (void*)host_data(), (void*)device_data(), + spec_.allocatedSize() * sizeof( Value ) ); + acc_map_ = true; #endif - } - return acc_map_; + } + return acc_map_; } //------------------------------------------------------------------------------ -template void ArrayT::insert(size_t idx1, size_t size1) { - - //if( hostNeedsUpdate() ) { +template +void ArrayT::insert( size_t idx1, size_t size1 ) { + // if( hostNeedsUpdate() ) { // cloneFromDevice(); //} - if( not hasDefaultLayout() ) - NOTIMP; + if ( not hasDefaultLayout() ) NOTIMP; ArrayShape nshape = shape(); - if(idx1 > nshape[0]) { - throw eckit::BadParameter("can not insert into an array at a position beyond its size", Here()); + if ( idx1 > nshape[0] ) { + throw eckit::BadParameter( "can not insert into an array at a position beyond its size", Here() ); } nshape[0] += size1; - Array* resized = Array::create(nshape); + Array* resized = Array::create( nshape ); - array_initializer_partitioned<0>::apply( *this, *resized, idx1, size1); + array_initializer_partitioned<0>::apply( *this, *resized, idx1, size1 ); - replace(*resized); + replace( *resized ); delete resized; } //------------------------------------------------------------------------------ -template void ArrayT::resize(size_t dim0) { - ArrayT_impl(*this).resize_variadic(dim0); +template +void ArrayT::resize( size_t dim0 ) { + ArrayT_impl( *this ).resize_variadic( dim0 ); } -template void ArrayT::resize(size_t dim0, size_t dim1) { - ArrayT_impl(*this).resize_variadic(dim0,dim1); +template +void ArrayT::resize( size_t dim0, size_t dim1 ) { + ArrayT_impl( *this ).resize_variadic( dim0, dim1 ); } -template void ArrayT::resize(size_t dim0, size_t dim1, size_t dim2) { - ArrayT_impl(*this).resize_variadic(dim0,dim1,dim2); +template +void ArrayT::resize( size_t dim0, size_t dim1, size_t dim2 ) { + ArrayT_impl( *this ).resize_variadic( dim0, dim1, dim2 ); } -template void ArrayT::resize(size_t dim0, size_t dim1, size_t dim2, size_t dim3) { - ArrayT_impl(*this).resize_variadic(dim0,dim1,dim2,dim3); +template +void ArrayT::resize( size_t dim0, size_t dim1, size_t dim2, size_t dim3 ) { + ArrayT_impl( *this ).resize_variadic( dim0, dim1, dim2, dim3 ); } -template void ArrayT::resize(size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4) { - ArrayT_impl(*this).resize_variadic(dim0,dim1,dim2,dim3,dim4); +template +void ArrayT::resize( size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4 ) { + ArrayT_impl( *this ).resize_variadic( dim0, dim1, dim2, dim3, dim4 ); } -template< typename Value > -void ArrayT::dump(std::ostream& out) const { - switch( rank() ) { - case 1: make_host_view(*this).dump(out); break; - case 2: make_host_view(*this).dump(out); break; - case 3: make_host_view(*this).dump(out); break; - case 4: make_host_view(*this).dump(out); break; - case 5: make_host_view(*this).dump(out); break; - case 6: make_host_view(*this).dump(out); break; - case 7: make_host_view(*this).dump(out); break; - case 8: make_host_view(*this).dump(out); break; - case 9: make_host_view(*this).dump(out); break; - default: NOTIMP; - } +template +void ArrayT::dump( std::ostream& out ) const { + switch ( rank() ) { + case 1: + make_host_view( *this ).dump( out ); + break; + case 2: + make_host_view( *this ).dump( out ); + break; + case 3: + make_host_view( *this ).dump( out ); + break; + case 4: + make_host_view( *this ).dump( out ); + break; + case 5: + make_host_view( *this ).dump( out ); + break; + case 6: + make_host_view( *this ).dump( out ); + break; + case 7: + make_host_view( *this ).dump( out ); + break; + case 8: + make_host_view( *this ).dump( out ); + break; + case 9: + make_host_view( *this ).dump( out ); + break; + default: + NOTIMP; + } } template -void ArrayT::resize(const ArrayShape& shape) -{ - assert(shape.size() > 0); - switch (shape.size()) { - case 1: return ArrayT_impl(*this).apply_resize(shape, UintSequence<1>()); - case 2: return ArrayT_impl(*this).apply_resize(shape, UintSequence<2>()); - case 3: return ArrayT_impl(*this).apply_resize(shape, UintSequence<3>()); - case 4: return ArrayT_impl(*this).apply_resize(shape, UintSequence<4>()); - case 5: return ArrayT_impl(*this).apply_resize(shape, UintSequence<5>()); - case 6: return ArrayT_impl(*this).apply_resize(shape, UintSequence<6>()); - case 7: return ArrayT_impl(*this).apply_resize(shape, UintSequence<7>()); - case 8: return ArrayT_impl(*this).apply_resize(shape, UintSequence<8>()); - case 9: return ArrayT_impl(*this).apply_resize(shape, UintSequence<9>()); +void ArrayT::resize( const ArrayShape& shape ) { + assert( shape.size() > 0 ); + switch ( shape.size() ) { + case 1: + return ArrayT_impl( *this ).apply_resize( shape, UintSequence<1>() ); + case 2: + return ArrayT_impl( *this ).apply_resize( shape, UintSequence<2>() ); + case 3: + return ArrayT_impl( *this ).apply_resize( shape, UintSequence<3>() ); + case 4: + return ArrayT_impl( *this ).apply_resize( shape, UintSequence<4>() ); + case 5: + return ArrayT_impl( *this ).apply_resize( shape, UintSequence<5>() ); + case 6: + return ArrayT_impl( *this ).apply_resize( shape, UintSequence<6>() ); + case 7: + return ArrayT_impl( *this ).apply_resize( shape, UintSequence<7>() ); + case 8: + return ArrayT_impl( *this ).apply_resize( shape, UintSequence<8>() ); + case 9: + return ArrayT_impl( *this ).apply_resize( shape, UintSequence<9>() ); default: { std::stringstream err; err << "shape not recognized"; - throw eckit::BadParameter(err.str(), Here()); + throw eckit::BadParameter( err.str(), Here() ); } } } //------------------------------------------------------------------------------ - -template ArrayT::ArrayT(ArrayDataStore* ds, const ArraySpec& spec) { - data_store_ = std::unique_ptr(ds); +template +ArrayT::ArrayT( ArrayDataStore* ds, const ArraySpec& spec ) { + data_store_ = std::unique_ptr( ds ); spec_ = spec; } -template ArrayT::ArrayT(size_t dim0) { - ArrayT_impl(*this).construct(dim0); +template +ArrayT::ArrayT( size_t dim0 ) { + ArrayT_impl( *this ).construct( dim0 ); } -template ArrayT::ArrayT(size_t dim0, size_t dim1) { - ArrayT_impl(*this).construct(dim0,dim1); +template +ArrayT::ArrayT( size_t dim0, size_t dim1 ) { + ArrayT_impl( *this ).construct( dim0, dim1 ); } -template ArrayT::ArrayT(size_t dim0, size_t dim1, size_t dim2) { - ArrayT_impl(*this).construct(dim0,dim1,dim2); +template +ArrayT::ArrayT( size_t dim0, size_t dim1, size_t dim2 ) { + ArrayT_impl( *this ).construct( dim0, dim1, dim2 ); } -template ArrayT::ArrayT(size_t dim0, size_t dim1, size_t dim2, size_t dim3) { - ArrayT_impl(*this).construct(dim0,dim1,dim2,dim3); +template +ArrayT::ArrayT( size_t dim0, size_t dim1, size_t dim2, size_t dim3 ) { + ArrayT_impl( *this ).construct( dim0, dim1, dim2, dim3 ); } -template ArrayT::ArrayT(size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4) { - ArrayT_impl(*this).construct(dim0,dim1,dim2,dim3,dim4); +template +ArrayT::ArrayT( size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4 ) { + ArrayT_impl( *this ).construct( dim0, dim1, dim2, dim3, dim4 ); } -template ArrayT::ArrayT(const ArrayShape& shape) { - ArrayT_impl(*this).construct(shape); +template +ArrayT::ArrayT( const ArrayShape& shape ) { + ArrayT_impl( *this ).construct( shape ); } -template ArrayT::ArrayT(const ArrayShape& shape, const ArrayLayout& layout) { - ArrayT_impl(*this).construct(shape,layout); +template +ArrayT::ArrayT( const ArrayShape& shape, const ArrayLayout& layout ) { + ArrayT_impl( *this ).construct( shape, layout ); } -template ArrayT::ArrayT(const ArraySpec& spec) { - if( not spec.contiguous() ) NOTIMP; - ArrayT_impl(*this).construct(spec.shape(),spec.layout()); +template +ArrayT::ArrayT( const ArraySpec& spec ) { + if ( not spec.contiguous() ) NOTIMP; + ArrayT_impl( *this ).construct( spec.shape(), spec.layout() ); } //------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas //------------------------------------------------------------------------------ // Explicit template instantiations @@ -431,59 +519,59 @@ template class ArrayT; template class ArrayT; template class ArrayT; -template Array* Array::create(size_t); -template Array* Array::create(size_t); -template Array* Array::create(size_t); -template Array* Array::create(size_t); -template Array* Array::create(size_t); - -template Array* Array::create(size_t,size_t); -template Array* Array::create(size_t,size_t); -template Array* Array::create(size_t,size_t); -template Array* Array::create(size_t,size_t); -template Array* Array::create(size_t,size_t); - -template Array* Array::create(size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t); - -template Array* Array::create(size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t); - -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); - -template Array* Array::create(const ArrayShape&); -template Array* Array::create(const ArrayShape&); -template Array* Array::create(const ArrayShape&); -template Array* Array::create(const ArrayShape&); -template Array* Array::create(const ArrayShape&); - -template Array* Array::create(const ArrayShape&, const ArrayLayout&); -template Array* Array::create(const ArrayShape&, const ArrayLayout&); -template Array* Array::create(const ArrayShape&, const ArrayLayout&); -template Array* Array::create(const ArrayShape&, const ArrayLayout&); -template Array* Array::create(const ArrayShape&, const ArrayLayout&); - -template Array* Array::wrap(int*, const ArrayShape&); -template Array* Array::wrap(long*, const ArrayShape&); -template Array* Array::wrap(float*, const ArrayShape&); -template Array* Array::wrap(double*, const ArrayShape&); -template Array* Array::wrap(long unsigned*, const ArrayShape&); - -template Array* Array::wrap(int*, const ArraySpec&); -template Array* Array::wrap(long*, const ArraySpec&); -template Array* Array::wrap(float*, const ArraySpec&); -template Array* Array::wrap(double*, const ArraySpec&); -template Array* Array::wrap(long unsigned*, const ArraySpec&); - -} // namespace array -} // namespace atlas +template Array* Array::create( size_t ); +template Array* Array::create( size_t ); +template Array* Array::create( size_t ); +template Array* Array::create( size_t ); +template Array* Array::create( size_t ); + +template Array* Array::create( size_t, size_t ); +template Array* Array::create( size_t, size_t ); +template Array* Array::create( size_t, size_t ); +template Array* Array::create( size_t, size_t ); +template Array* Array::create( size_t, size_t ); + +template Array* Array::create( size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t ); + +template Array* Array::create( size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t ); + +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); + +template Array* Array::create( const ArrayShape& ); +template Array* Array::create( const ArrayShape& ); +template Array* Array::create( const ArrayShape& ); +template Array* Array::create( const ArrayShape& ); +template Array* Array::create( const ArrayShape& ); + +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); + +template Array* Array::wrap( int*, const ArrayShape& ); +template Array* Array::wrap( long*, const ArrayShape& ); +template Array* Array::wrap( float*, const ArrayShape& ); +template Array* Array::wrap( double*, const ArrayShape& ); +template Array* Array::wrap( long unsigned*, const ArrayShape& ); + +template Array* Array::wrap( int*, const ArraySpec& ); +template Array* Array::wrap( long*, const ArraySpec& ); +template Array* Array::wrap( float*, const ArraySpec& ); +template Array* Array::wrap( double*, const ArraySpec& ); +template Array* Array::wrap( long unsigned*, const ArraySpec& ); + +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index 62d592075..167b28891 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -4,22 +4,23 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include #include #include #include -#include "atlas/library/config.h" -#include "atlas/array_fwd.h" +#include #include "atlas/array.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" #include "atlas/array/gridtools/GridToolsTraits.h" +#include "atlas/array_fwd.h" +#include "atlas/library/config.h" #include "atlas/runtime/Log.h" #include "eckit/exception/Exceptions.h" @@ -30,237 +31,218 @@ namespace array { namespace gridtools { template -std::array get_array_from_vector(std::vector const& values) { +std::array get_array_from_vector( std::vector const& values ) { std::array array; - std::copy(values.begin(), values.end(), array.begin()); + std::copy( values.begin(), values.end(), array.begin() ); return array; } template struct check_dimension_lengths_impl { - template - static void apply(ArrayShape const& shape, FirstDim first_dim, Dims... d) { - if (first_dim < shape[Dim]) { - std::stringstream err; - err << "Attempt to resize array with original size for dimension " << Dim << " of " << shape[Dim] << " by " - << first_dim << std::endl; - throw eckit::BadParameter(err.str(), Here()); + template + static void apply( ArrayShape const& shape, FirstDim first_dim, Dims... d ) { + if ( first_dim < shape[Dim] ) { + std::stringstream err; + err << "Attempt to resize array with original size for dimension " << Dim << " of " << shape[Dim] << " by " + << first_dim << std::endl; + throw eckit::BadParameter( err.str(), Here() ); + } + check_dimension_lengths_impl::apply( shape, d... ); } - check_dimension_lengths_impl::apply(shape, d...); - } }; template -struct check_dimension_lengths_impl 1) >::type > { - template - static void apply(ArrayShape const& shape, FirstDim first_dim) { - if (first_dim < shape[Dim]) { - std::stringstream err; - err << "Attempt to resize array with original size for dimension " << Dim - 1 << " of " - << shape[Dim - 1] << " by " << first_dim << std::endl; - throw eckit::BadParameter(err.str(), Here()); +struct check_dimension_lengths_impl 1 )>::type> { + template + static void apply( ArrayShape const& shape, FirstDim first_dim ) { + if ( first_dim < shape[Dim] ) { + std::stringstream err; + err << "Attempt to resize array with original size for dimension " << Dim - 1 << " of " << shape[Dim - 1] + << " by " << first_dim << std::endl; + throw eckit::BadParameter( err.str(), Here() ); + } } - } }; template -struct check_dimension_lengths_impl::type > { - template - static void apply(ArrayShape const& shape, FirstDim first_dim) { - if (first_dim < shape[Dim]) { - std::stringstream err; - err << "Attempt to resize array with original size for dimension " << Dim << " of " << shape[Dim] << " by " - << first_dim << std::endl; - throw eckit::BadParameter(err.str(), Here()); +struct check_dimension_lengths_impl::type> { + template + static void apply( ArrayShape const& shape, FirstDim first_dim ) { + if ( first_dim < shape[Dim] ) { + std::stringstream err; + err << "Attempt to resize array with original size for dimension " << Dim << " of " << shape[Dim] << " by " + << first_dim << std::endl; + throw eckit::BadParameter( err.str(), Here() ); + } } - } }; -template -void check_dimension_lengths(ArrayShape const& shape, Dims...d) { - check_dimension_lengths_impl::apply(shape, d...); +template +void check_dimension_lengths( ArrayShape const& shape, Dims... d ) { + check_dimension_lengths_impl::apply( shape, d... ); } -template +template struct default_layout_t { - - template + template struct get_layout; - template - struct get_layout<::gridtools::gt_integer_sequence > - { + template + struct get_layout<::gridtools::gt_integer_sequence> { using type = ::gridtools::layout_map; }; - using type = typename get_layout< typename ::gridtools::make_gt_integer_sequence::type >::type; + using type = typename get_layout::type>::type; }; - - template - struct get_layout_map_component { - // TODO: static_assert( ::gridtools::is_layout_map(), "Error: not a layout_map" ); +template +struct get_layout_map_component { + // TODO: static_assert( ::gridtools::is_layout_map(), "Error: not a + // layout_map" ); template struct get_component { - ATLAS_HOST_DEVICE - constexpr get_component() {} + ATLAS_HOST_DEVICE + constexpr get_component() {} - ATLAS_HOST_DEVICE constexpr static Value apply() { - return LayoutMap::template at(); - } + ATLAS_HOST_DEVICE constexpr static Value apply() { return LayoutMap::template at(); } }; - }; +}; - template - struct get_stride_component { +template +struct get_stride_component { template struct get_component { - ATLAS_HOST_DEVICE - constexpr get_component() {} - - template - ATLAS_HOST_DEVICE constexpr static Value apply(StorageInfoPtr a) { - static_assert((::gridtools::is_storage_info::type>::value), - "Error: not a storage_info"); - return a->template stride(); - } - }; - }; - - template < int Idx > - struct get_shape_component { - - ATLAS_HOST_DEVICE - constexpr get_shape_component() {} - - template < typename StorageInfoPtr> - ATLAS_HOST_DEVICE constexpr static size_t apply(StorageInfoPtr a) { - static_assert((::gridtools::is_storage_info::type >::value ), "Error: not a storage_info"); - return a->template unaligned_dim(); - } - }; - - //indirection around C++11 sizeof... since it is buggy for nvcc and cray - template - struct get_pack_size { - using type = ::gridtools::static_uint< sizeof...(T) >; - }; - - template - static gridtools::storage_traits::data_store_t< - Value, - gridtools::storage_traits::custom_layout_storage_info_t< - 0, - LayoutMap, - ::gridtools::zero_halo::type::value> - > - >* - create_gt_storage(UInts... dims) { - static_assert((sizeof...(dims) > 0), "Error: can not create storages without any dimension"); - - constexpr static unsigned int rank = get_pack_size::type::value; - typedef gridtools::storage_traits::custom_layout_storage_info_t< - 0, - LayoutMap, - ::gridtools::zero_halo - > storage_info_ty; - 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(); - } - else { - storage_info_ty si(dims...); - ds = new data_store_t(si); - } - return ds; - } - - template - static gridtools::storage_traits::data_store_t< - Value, gridtools::storage_traits::storage_info_t<0, Rank> >* - wrap_gt_storage( - Value* data, - std::array&& shape, std::array&& strides) - { - static_assert((Rank > 0), "Error: can not create storages without any dimension"); - typedef gridtools::storage_traits::storage_info_t< - 0, Rank, ::gridtools::zero_halo > storage_info_ty; - typedef gridtools::storage_traits::data_store_t data_store_t; - - storage_info_ty si(shape, strides); - data_store_t* ds = new data_store_t(si, data); - - return ds; - } - - constexpr size_t zero(std::size_t) {return 0;} - - template - ArrayShape make_null_strides(::gridtools::gt_integer_sequence) { - return make_strides({zero(Is)...}); - } - - template < typename UInt > - struct my_apply_gt_integer_sequence { - template < typename Container, template < UInt T > class Lambda, typename... ExtraTypes > - ATLAS_HOST_DEVICE static constexpr Container apply(ExtraTypes const &... args_) { - static_assert((boost::is_same< Container, Container >::value), - "ERROR: apply_gt_integer_sequence only accepts a gt_integer_sequence type. Check the call"); - return Container(args_...); + ATLAS_HOST_DEVICE + constexpr get_component() {} + + template + ATLAS_HOST_DEVICE constexpr static Value apply( StorageInfoPtr a ) { + static_assert( (::gridtools::is_storage_info::type>::value ), + "Error: not a storage_info" ); + return a->template stride(); } }; +}; - template < typename UInt, UInt... Indices > - struct my_apply_gt_integer_sequence< ::gridtools::gt_integer_sequence< UInt, Indices... > > { - - /** - @brief duplicated interface for the case in which the container is an aggregator - */ - template < typename Container, - template < UInt T > class Lambda, - typename... ExtraTypes > - ATLAS_HOST_DEVICE static constexpr Container apply(ExtraTypes const &... args_) { - return Container{Lambda< Indices >::apply(args_...)...}; - } - }; - - - - template - ArraySpec make_spec(DataStore* gt_data_store_ptr, Dims...dims) { - 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(); - using Layout = typename DataStore::storage_info_t::layout_t; - using Alignment = typename DataStore::storage_info_t::alignment_t; - - using seq = my_apply_gt_integer_sequence::type>; - - ArraySpec spec( - ArrayShape{(unsigned long)dims...}, - seq::template apply< - ArrayStrides, - get_stride_component::type>::template get_component>( - storage_info_ptr), - seq::template apply< - ArrayLayout, - get_layout_map_component::template get_component>(), - ArrayAlignment( Alignment::value ) - ); - ASSERT( spec.allocatedSize() == storage_info_ptr->padded_total_length() ); - return spec; - } else { - return ArraySpec( make_shape({dims...}), make_null_strides(typename ::gridtools::make_gt_integer_sequence::type())); - } - } +template +struct get_shape_component { + ATLAS_HOST_DEVICE + constexpr get_shape_component() {} + + template + ATLAS_HOST_DEVICE constexpr static size_t apply( StorageInfoPtr a ) { + static_assert( (::gridtools::is_storage_info::type>::value ), + "Error: not a storage_info" ); + return a->template unaligned_dim(); + } +}; + +// indirection around C++11 sizeof... since it is buggy for nvcc and cray +template +struct get_pack_size { + using type = ::gridtools::static_uint; +}; + +template +static gridtools::storage_traits::data_store_t< + Value, gridtools::storage_traits::custom_layout_storage_info_t< + 0, LayoutMap, ::gridtools::zero_halo::type::value>>>* +create_gt_storage( UInts... dims ) { + static_assert( ( sizeof...( dims ) > 0 ), "Error: can not create storages without any dimension" ); + + constexpr static unsigned int rank = get_pack_size::type::value; + typedef gridtools::storage_traits::custom_layout_storage_info_t<0, LayoutMap, ::gridtools::zero_halo> + storage_info_ty; + 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(); } + else { + storage_info_ty si( dims... ); + ds = new data_store_t( si ); + } + return ds; +} + +template +static gridtools::storage_traits::data_store_t>* +wrap_gt_storage( Value* data, std::array&& shape, std::array&& strides ) { + static_assert( ( Rank > 0 ), "Error: can not create storages without any dimension" ); + typedef gridtools::storage_traits::storage_info_t<0, Rank, ::gridtools::zero_halo> storage_info_ty; + typedef gridtools::storage_traits::data_store_t data_store_t; + + storage_info_ty si( shape, strides ); + data_store_t* ds = new data_store_t( si, data ); + + return ds; +} + +constexpr size_t zero( std::size_t ) { + return 0; +} + +template +ArrayShape make_null_strides(::gridtools::gt_integer_sequence ) { + return make_strides( {zero( Is )...} ); +} + +template +struct my_apply_gt_integer_sequence { + template class Lambda, typename... ExtraTypes> + ATLAS_HOST_DEVICE static constexpr Container apply( ExtraTypes const&... args_ ) { + static_assert( ( boost::is_same::value ), + "ERROR: apply_gt_integer_sequence only accepts a " + "gt_integer_sequence type. Check the call" ); + return Container( args_... ); + } +}; + +template +struct my_apply_gt_integer_sequence<::gridtools::gt_integer_sequence> { + /** + @brief duplicated interface for the case in which the container is an + aggregator + */ + template class Lambda, typename... ExtraTypes> + ATLAS_HOST_DEVICE static constexpr Container apply( ExtraTypes const&... args_ ) { + return Container{Lambda::apply( args_... )...}; + } +}; + +template +ArraySpec make_spec( DataStore* gt_data_store_ptr, Dims... dims ) { + 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(); + using Layout = typename DataStore::storage_info_t::layout_t; + using Alignment = typename DataStore::storage_info_t::alignment_t; + + using seq = + my_apply_gt_integer_sequence::type>; + + ArraySpec spec( + ArrayShape{(unsigned long)dims...}, + seq::template apply< + ArrayStrides, + get_stride_component::type>::template get_component>( + storage_info_ptr ), + seq::template apply::template get_component>(), + ArrayAlignment( Alignment::value ) ); + ASSERT( spec.allocatedSize() == storage_info_ptr->padded_total_length() ); + return spec; + } + else { + return ArraySpec( + make_shape( {dims...} ), + make_null_strides( typename ::gridtools::make_gt_integer_sequence::type() ) ); + } +} //------------------------------------------------------------------------------ -} // namespace gridtools -} // namespace array -} // namespace atlas +} // namespace gridtools +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index 3669ecf55..fd3c8a16f 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -4,142 +4,142 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include "atlas/array/gridtools/GridToolsArrayView.h" +#include #include "atlas/array/gridtools/GridToolsArrayHelpers.h" -#include "atlas/array/helpers/ArrayInitializer.h" #include "atlas/array/helpers/ArrayAssigner.h" +#include "atlas/array/helpers/ArrayInitializer.h" #include "atlas/array/helpers/ArrayWriter.h" #include "eckit/exception/Exceptions.h" namespace atlas { namespace array { -template< typename T, size_t Rank > +template struct host_device_array { - ATLAS_HOST_DEVICE host_device_array( std::initializer_list list ) { - size_t i(0); - for( const T v : list ) { + size_t i( 0 ); + for ( const T v : list ) { data_[i++] = v; } } - ATLAS_HOST_DEVICE ~host_device_array() { - } + ATLAS_HOST_DEVICE ~host_device_array() {} - ATLAS_HOST_DEVICE const T* data() const { - return data_; - } + ATLAS_HOST_DEVICE const T* data() const { return data_; } T data_[Rank]; }; -template< typename Value, int Rank, Intent AccessMode > -ArrayView::ArrayView( const ArrayView& other ) : - gt_data_view_(other.gt_data_view_), data_store_orig_(other.data_store_orig_), array_(other.array_) { - std::memcpy(shape_,other.shape_,sizeof(size_t)*Rank); - std::memcpy(strides_,other.strides_,sizeof(size_t)*Rank); +template +ArrayView::ArrayView( const ArrayView& other ) : + gt_data_view_( other.gt_data_view_ ), + data_store_orig_( other.data_store_orig_ ), + array_( other.array_ ) { + std::memcpy( shape_, other.shape_, sizeof( size_t ) * Rank ); + std::memcpy( strides_, other.strides_, sizeof( size_t ) * Rank ); size_ = other.size_; // TODO: check compatibility } -template< typename Value, int Rank, Intent AccessMode > -ArrayView::ArrayView(data_view_t data_view, const Array& array) : - gt_data_view_(data_view), data_store_orig_(array.data_store()), array_(&array) { - if(data_view.valid()) { - using seq = ::gridtools::apply_gt_integer_sequence::type>; +template +ArrayView::ArrayView( data_view_t data_view, const Array& array ) : + gt_data_view_( data_view ), + data_store_orig_( array.data_store() ), + array_( &array ) { + if ( data_view.valid() ) { + using seq = + ::gridtools::apply_gt_integer_sequence::type>; constexpr static unsigned int ndims = data_view_t::data_store_t::storage_info_t::ndims; using storage_info_ty = gridtools::storage_traits::storage_info_t<0, ndims>; using data_store_t = gridtools::storage_traits::data_store_t; - auto storage_info_ = *((reinterpret_cast(const_cast(array.storage())))->get_storage_info_ptr()); + auto storage_info_ = + *( ( reinterpret_cast( const_cast( array.storage() ) ) )->get_storage_info_ptr() ); - auto stridest = seq::template apply< - host_device_array, - atlas::array::gridtools::get_stride_component >::template get_component>( - &(storage_info_)); - auto shapet = seq::template apply< - host_device_array, - atlas::array::gridtools::get_shape_component>(&(storage_info_)); + auto stridest = seq::template apply, + atlas::array::gridtools::get_stride_component< + unsigned long, ::gridtools::static_uint>::template get_component>( + &( storage_info_ ) ); + auto shapet = + seq::template apply, atlas::array::gridtools::get_shape_component>( + &( storage_info_ ) ); - std::memcpy(strides_, stridest.data(), sizeof(size_t)*Rank); - std::memcpy(shape_, shapet.data(), sizeof(size_t)*Rank); + std::memcpy( strides_, stridest.data(), sizeof( size_t ) * Rank ); + std::memcpy( shape_, shapet.data(), sizeof( size_t ) * Rank ); size_ = storage_info_.total_length(); } else { - - std::fill_n(shape_, Rank, 0 ); - std::fill_n(strides_, Rank, 0 ); + std::fill_n( shape_, Rank, 0 ); + std::fill_n( strides_, Rank, 0 ); size_ = 0; } } -template< typename Value, int Rank, Intent AccessMode> -bool ArrayView::valid() const { - return gt_data_view_.valid() && (array_->data_store() == data_store_orig_); +template +bool ArrayView::valid() const { + return gt_data_view_.valid() && ( array_->data_store() == data_store_orig_ ); } - - -template< typename Value, int Rank, Intent AccessMode> -void ArrayView::assign(const value_type& value) { - helpers::array_assigner::apply(*this,value); +template +void ArrayView::assign( const value_type& value ) { + helpers::array_assigner::apply( *this, value ); } template -void ArrayView::assign(const std::initializer_list& list) { +void ArrayView::assign( const std::initializer_list& list ) { ASSERT( list.size() == size_ ); - helpers::array_assigner::apply(*this,list); + helpers::array_assigner::apply( *this, list ); } -template< typename Value, int Rank, Intent AccessMode > -void ArrayView::dump(std::ostream& os) const { - os << "size: " << size() << " , values: "; - os << "[ "; - helpers::array_writer::apply(*this,os); - os << " ]"; +template +void ArrayView::dump( std::ostream& os ) const { + os << "size: " << size() << " , values: "; + os << "[ "; + helpers::array_writer::apply( *this, os ); + os << " ]"; } //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas //----------------------------------------------------------------------- // Explicit instantiation namespace atlas { namespace array { -#define EXPLICIT_TEMPLATE_INSTANTIATION(Rank) \ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ +#define EXPLICIT_TEMPLATE_INSTANTIATION( Rank ) \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; // For each NDims in [1..9] -EXPLICIT_TEMPLATE_INSTANTIATION(1) -EXPLICIT_TEMPLATE_INSTANTIATION(2) -EXPLICIT_TEMPLATE_INSTANTIATION(3) -EXPLICIT_TEMPLATE_INSTANTIATION(4) -EXPLICIT_TEMPLATE_INSTANTIATION(5) -EXPLICIT_TEMPLATE_INSTANTIATION(6) -EXPLICIT_TEMPLATE_INSTANTIATION(7) -EXPLICIT_TEMPLATE_INSTANTIATION(8) -EXPLICIT_TEMPLATE_INSTANTIATION(9) +EXPLICIT_TEMPLATE_INSTANTIATION( 1 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 2 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 3 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 4 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 5 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 6 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 7 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 8 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 9 ) #undef EXPLICIT_TEMPLATE_INSTANTIATION } -} +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 90a466ac7..049903d17 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -4,89 +4,86 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once +#include #include #include -#include -#include "atlas/library/config.h" #include "atlas/array/ArrayUtil.h" +#include "atlas/array/ArrayViewDefs.h" #include "atlas/array/LocalView.h" -#include "atlas/array/gridtools/GridToolsTraits.h" #include "atlas/array/gridtools/GridToolsMakeView.h" -#include "atlas/array/ArrayViewDefs.h" +#include "atlas/array/gridtools/GridToolsTraits.h" +#include "atlas/library/config.h" //------------------------------------------------------------------------------------------------------ namespace atlas { namespace array { -template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > class ArrayView { +template +class ArrayView { public: - // -- Type definitions - using value_type = typename remove_const::type; - using return_type = typename std::conditional< (AccessMode == Intent::ReadWrite), value_type, value_type const>::type; + // -- Type definitions + using value_type = typename remove_const::type; + using return_type = + typename std::conditional<( AccessMode == Intent::ReadWrite ), value_type, value_type const>::type; static constexpr Intent ACCESS{AccessMode}; static constexpr int RANK{Rank}; - using data_view_t = gridtools::data_view_tt; + using data_view_t = gridtools::data_view_tt; - private: - using slicer_t = typename helpers::ArraySlicer< ArrayView >; - using const_slicer_t = typename helpers::ArraySlicer< const ArrayView >; +private: + using slicer_t = typename helpers::ArraySlicer>; + using const_slicer_t = typename helpers::ArraySlicer>; - template< typename ...Args > - struct slice_t { + template + struct slice_t { using type = typename slicer_t::template Slice::type; - }; + }; - template< typename ...Args > - struct const_slice_t { + template + struct const_slice_t { using type = typename const_slicer_t::template Slice::type; - }; + }; public: - ATLAS_HOST_DEVICE ArrayView( const ArrayView& other ); - ArrayView(data_view_t data_view, const Array& array); + ArrayView( data_view_t data_view, const Array& array ); value_type* data() { return gt_data_view_.data(); } value_type const* data() const { return gt_data_view_.data(); } - template < typename... Coords, typename = typename boost::enable_if_c<(sizeof...(Coords) == Rank), int>::type > - ATLAS_HOST_DEVICE - return_type& - operator()(Coords... c) { - assert(sizeof...(Coords) == Rank); - return gt_data_view_(c...); + template ::type> + ATLAS_HOST_DEVICE return_type& operator()( Coords... c ) { + assert( sizeof...( Coords ) == Rank ); + return gt_data_view_( c... ); } - template ::type> - ATLAS_HOST_DEVICE - value_type const& operator()(Coords... c) const { - assert(sizeof...(Coords) == Rank); - return gt_data_view_(c...); + template ::type> + ATLAS_HOST_DEVICE value_type const& operator()( Coords... c ) const { + assert( sizeof...( Coords ) == Rank ); + return gt_data_view_( c... ); } - template - ATLAS_HOST_DEVICE - size_t shape() const { + template + ATLAS_HOST_DEVICE size_t shape() const { return gt_data_view_.template length(); } ATLAS_HOST_DEVICE - data_view_t& data_view() { return gt_data_view_;} + data_view_t& data_view() { return gt_data_view_; } ATLAS_HOST_DEVICE - data_view_t const & data_view() const { return gt_data_view_;} + data_view_t const& data_view() const { return gt_data_view_; } - template - ATLAS_HOST_DEVICE - size_t stride() const { + template + ATLAS_HOST_DEVICE size_t stride() const { return gt_data_view_.storage_info().template stride(); } @@ -94,36 +91,33 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas size_t size() const { return size_; } bool valid() const; - bool contiguous() const { - return (size_ == shape_[0]*strides_[0] ? true : false); - } + bool contiguous() const { return ( size_ == shape_[0] * strides_[0] ? true : false ); } - void dump(std::ostream& os) const; + void dump( std::ostream& os ) const; - void assign(const value_type& value); + void assign( const value_type& value ); - void assign(const std::initializer_list&); + void assign( const std::initializer_list& ); const size_t* strides() const { return strides_; } const size_t* shape() const { return shape_; } - size_t shape(size_t idx) const { return shape_[idx]; } + size_t shape( size_t idx ) const { return shape_[idx]; } - size_t stride(size_t idx) const { return strides_[idx]; } + size_t stride( size_t idx ) const { return strides_[idx]; } - template< typename ...Args > - typename slice_t::type slice(Args... args) { - return slicer_t(*this).apply(args...); + template + typename slice_t::type slice( Args... args ) { + return slicer_t( *this ).apply( args... ); } - template< typename ...Args > - typename const_slice_t::type slice(Args... args) const { - return const_slicer_t(*this).apply(args...); + template + typename const_slice_t::type slice( Args... args ) const { + return const_slicer_t( *this ).apply( args... ); } private: - data_view_t gt_data_view_; size_t shape_[Rank]; size_t strides_[Rank]; @@ -134,5 +128,5 @@ template< typename Value, int Rank, Intent AccessMode = Intent::ReadWrite > clas //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsDataStore.h b/src/atlas/array/gridtools/GridToolsDataStore.h index 1f9408627..29023f56c 100644 --- a/src/atlas/array/gridtools/GridToolsDataStore.h +++ b/src/atlas/array/gridtools/GridToolsDataStore.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -19,62 +20,45 @@ namespace atlas { namespace array { namespace gridtools { -template -struct GridToolsDataStore : ArrayDataStore -{ - explicit GridToolsDataStore(gt_DataStore const *ds) : data_store_(ds) {} +template +struct GridToolsDataStore : ArrayDataStore { + explicit GridToolsDataStore( gt_DataStore const* ds ) : data_store_( ds ) {} ~GridToolsDataStore() { - assert(data_store_); + assert( data_store_ ); delete data_store_; } void cloneToDevice() const { - assert(data_store_); + assert( data_store_ ); data_store_->clone_to_device(); } - void cloneFromDevice() const { - data_store_->clone_from_device(); - } + void cloneFromDevice() const { data_store_->clone_from_device(); } - bool valid() const { - return data_store_->valid(); - } + bool valid() const { return data_store_->valid(); } - void syncHostDevice() const { - data_store_->sync(); - } + void syncHostDevice() const { data_store_->sync(); } - bool hostNeedsUpdate() const { - return data_store_->host_needs_update(); - } + bool hostNeedsUpdate() const { return data_store_->host_needs_update(); } - bool deviceNeedsUpdate() const { - return data_store_->device_needs_update(); - } + bool deviceNeedsUpdate() const { return data_store_->device_needs_update(); } - void reactivateDeviceWriteViews() const { - data_store_->reactivate_device_write_views(); - } + void reactivateDeviceWriteViews() const { data_store_->reactivate_device_write_views(); } - void reactivateHostWriteViews() const { - data_store_->reactivate_host_write_views(); - } + void reactivateHostWriteViews() const { data_store_->reactivate_host_write_views(); } - void* voidDataStore() { - return static_cast(const_cast(data_store_)); - } + void* voidDataStore() { return static_cast( const_cast( data_store_ ) ); } void* voidHostData() { - return ::gridtools::make_host_view<::gridtools::access_mode::ReadOnly>(*data_store_).data(); + return ::gridtools::make_host_view<::gridtools::access_mode::ReadOnly>( *data_store_ ).data(); } void* voidDeviceData() { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - return ::gridtools::make_device_view<::gridtools::access_mode::ReadOnly>(*data_store_).data(); + return ::gridtools::make_device_view<::gridtools::access_mode::ReadOnly>( *data_store_ ).data(); #else - return ::gridtools::make_host_view<::gridtools::access_mode::ReadOnly>(*data_store_).data(); + return ::gridtools::make_host_view<::gridtools::access_mode::ReadOnly>( *data_store_ ).data(); #endif } @@ -82,6 +66,6 @@ struct GridToolsDataStore : ArrayDataStore gt_DataStore const* data_store_; }; -} // namespace gridtools -} // namespace array -} // namespace atlas +} // namespace gridtools +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsIndexView.cc b/src/atlas/array/gridtools/GridToolsIndexView.cc index 92825f1e7..92fd60b9b 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.cc +++ b/src/atlas/array/gridtools/GridToolsIndexView.cc @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include -#include "atlas/field/Field.h" #include "atlas/array.h" #include "atlas/array/IndexView.h" +#include "atlas/field/Field.h" //------------------------------------------------------------------------------------------------------ @@ -21,25 +22,24 @@ namespace array { //------------------------------------------------------------------------------------------------------ template -void IndexView::dump(std::ostream& os) const { - os << "size: " << size() << " , values: "; - os << "[ "; - for( size_t j=0; j::dump( std::ostream& os ) const { + os << "size: " << size() << " , values: "; + os << "[ "; + for ( size_t j = 0; j < size(); ++j ) + os << ( *this )( j ) << " "; + os << "]" << std::endl; } //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas //------------------------------------------------------------------------------------------------------ // Explicit instantiation namespace atlas { namespace array { -template class IndexView; - -} +template class IndexView; } +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsIndexView.h b/src/atlas/array/gridtools/GridToolsIndexView.h index a57cf876f..8da6980ae 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.h +++ b/src/atlas/array/gridtools/GridToolsIndexView.h @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "atlas/library/config.h" #include "atlas/array/gridtools/GridToolsTraits.h" +#include "atlas/library/config.h" //------------------------------------------------------------------------------------------------------ @@ -24,87 +25,100 @@ namespace detail { // FortranIndex: // Helper class that does +1 and -1 operations on stored values -template< typename Value > -class FortranIndex -{ +template +class FortranIndex { public: - enum { BASE = 1 }; + enum + { + BASE = 1 + }; + public: - ATLAS_HOST_DEVICE - FortranIndex(Value* idx): idx_(idx) {} - ATLAS_HOST_DEVICE - void set(const Value& value) { *(idx_) = value+BASE; } - ATLAS_HOST_DEVICE - Value get() const { return *(idx_)-BASE; } - ATLAS_HOST_DEVICE - void operator=(const Value& value) { set(value); } - ATLAS_HOST_DEVICE - FortranIndex& operator=(const FortranIndex& other) { set(other.get()); return *this; } - ATLAS_HOST_DEVICE - FortranIndex& operator+(const Value& value) { *(idx_)+=value; return *this; } - ATLAS_HOST_DEVICE - FortranIndex& operator-(const Value& value) { *(idx_)-=value; return *this; } - ATLAS_HOST_DEVICE - FortranIndex& operator--() { --(*(idx_)); return *this; } - ATLAS_HOST_DEVICE - FortranIndex& operator++() { ++(*(idx_)); return *this; } - - //implicit conversion - ATLAS_HOST_DEVICE - operator Value() const { return get(); } + ATLAS_HOST_DEVICE + FortranIndex( Value* idx ) : idx_( idx ) {} + ATLAS_HOST_DEVICE + void set( const Value& value ) { *( idx_ ) = value + BASE; } + ATLAS_HOST_DEVICE + Value get() const { return *(idx_)-BASE; } + ATLAS_HOST_DEVICE + void operator=( const Value& value ) { set( value ); } + ATLAS_HOST_DEVICE + FortranIndex& operator=( const FortranIndex& other ) { + set( other.get() ); + return *this; + } + ATLAS_HOST_DEVICE + FortranIndex& operator+( const Value& value ) { + *( idx_ ) += value; + return *this; + } + ATLAS_HOST_DEVICE + FortranIndex& operator-( const Value& value ) { + *( idx_ ) -= value; + return *this; + } + ATLAS_HOST_DEVICE + FortranIndex& operator--() { + --( *( idx_ ) ); + return *this; + } + ATLAS_HOST_DEVICE + FortranIndex& operator++() { + ++( *( idx_ ) ); + return *this; + } + + // implicit conversion + ATLAS_HOST_DEVICE + operator Value() const { return get(); } private: - Value* idx_; + Value* idx_; }; -} +} // namespace detail //------------------------------------------------------------------------------------------------------ -template< typename Value, int Rank > -class IndexView -{ +template +class IndexView { public: // -- Type definitions #ifdef ATLAS_HAVE_FORTRAN typedef detail::FortranIndex Index; - #define INDEX_REF Index - #define FROM_FORTRAN -1 - #define TO_FORTRAN +1 +#define INDEX_REF Index +#define FROM_FORTRAN -1 +#define TO_FORTRAN +1 #else typedef Value& Index; - #define INDEX_REF * - #define FROM_FORTRAN - #define TO_FORTRAN +#define INDEX_REF * +#define FROM_FORTRAN +#define TO_FORTRAN #endif - using data_view_t = gridtools::data_view_tt; + using data_view_t = gridtools::data_view_tt; public: - - IndexView(data_view_t data_view) : gt_data_view_(data_view) { - if(data_view.valid()) + IndexView( data_view_t data_view ) : gt_data_view_( data_view ) { + if ( data_view.valid() ) size_ = gt_data_view_.storage_info().total_length(); else size_ = 0; } - template < typename... Coords > - Index - ATLAS_HOST_DEVICE - operator()(Coords... c) { - assert(sizeof...(Coords) == Rank); - return INDEX_REF( >_data_view_(c...) ); + template + Index ATLAS_HOST_DEVICE operator()( Coords... c ) { + assert( sizeof...( Coords ) == Rank ); + return INDEX_REF( >_data_view_( c... ) ); } - template ::type> - ATLAS_HOST_DEVICE - Value const operator()(Coords... c) const { - return gt_data_view_(c...) FROM_FORTRAN; + template ::type> + ATLAS_HOST_DEVICE Value const operator()( Coords... c ) const { + return gt_data_view_( c... ) FROM_FORTRAN; } size_t size() const { return size_; } - void dump(std::ostream& os) const; + void dump( std::ostream& os ) const; private: data_view_t gt_data_view_; @@ -117,5 +131,5 @@ class IndexView //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsMakeView.cc b/src/atlas/array/gridtools/GridToolsMakeView.cc index 1ba618127..d63a726bd 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.cc +++ b/src/atlas/array/gridtools/GridToolsMakeView.cc @@ -1,6 +1,6 @@ -#include #include "atlas/array/gridtools/GridToolsMakeView.h" +#include #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" @@ -15,178 +15,197 @@ namespace atlas { namespace array { namespace { - template - static void check_metadata(const Array& array) - { - if(array.rank() != Rank ) { - std::stringstream err; - err << "Number of dimensions do not match: template argument " << Rank << " expected to be " << array.rank(); - throw eckit::BadParameter(err.str(), Here()); - } - if(array.datatype() != array::DataType::create() ) { - std::stringstream err; - err << "Data Type does not match: template argument expected to be " << array.datatype().str(); - throw eckit::BadParameter(err.str(), Here()); - } +template +static void check_metadata( const Array& array ) { + if ( array.rank() != Rank ) { + std::stringstream err; + err << "Number of dimensions do not match: template argument " << Rank << " expected to be " << array.rank(); + throw eckit::BadParameter( err.str(), Here() ); + } + if ( array.datatype() != array::DataType::create() ) { + std::stringstream err; + err << "Data Type does not match: template argument expected to be " << array.datatype().str(); + throw eckit::BadParameter( err.str(), Here() ); } } +} // namespace namespace gridtools { template -data_view_tt -make_gt_host_view(const Array& array) { - - using storage_info_ty = storage_traits::storage_info_t<0, Rank>; - using data_store_t = storage_traits::data_store_t; +data_view_tt make_gt_host_view( const Array& array ) { + using storage_info_ty = storage_traits::storage_info_t<0, Rank>; + using data_store_t = storage_traits::data_store_t; - data_store_t* ds = reinterpret_cast(const_cast(array.storage())); + data_store_t* ds = reinterpret_cast( const_cast( array.storage() ) ); - return ::gridtools::make_host_view< get_access_mode(AccessMode) >(*ds); + return ::gridtools::make_host_view( *ds ); } template -data_view_tt -make_gt_device_view(const Array& array) { - typedef storage_traits::storage_info_t<0, Rank> storage_info_ty; - typedef storage_traits::data_store_t data_store_t; +data_view_tt make_gt_device_view( const Array& array ) { + typedef storage_traits::storage_info_t<0, Rank> storage_info_ty; + typedef storage_traits::data_store_t data_store_t; - data_store_t* ds = reinterpret_cast(const_cast(array.storage())); + data_store_t* ds = reinterpret_cast( const_cast( array.storage() ) ); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - return ::gridtools::make_device_view< get_access_mode(AccessMode) >(*ds); + return ::gridtools::make_device_view( *ds ); #else - return ::gridtools::make_host_view< get_access_mode(AccessMode) >(*ds); + return ::gridtools::make_host_view( *ds ); #endif } -} +} // namespace gridtools template -ArrayView -make_host_view(const Array& array) { - check_metadata(array); - return ArrayView(gridtools::make_gt_host_view(array), array); +ArrayView make_host_view( const Array& array ) { + check_metadata( array ); + return ArrayView( gridtools::make_gt_host_view( array ), array ); } template -ArrayView -make_device_view(const Array& array) { - check_metadata(array); - return ArrayView(gridtools::make_gt_device_view(array), array); +ArrayView make_device_view( const Array& array ) { + check_metadata( array ); + return ArrayView( gridtools::make_gt_device_view( array ), + array ); } template -IndexView -make_host_indexview(const Array& array) { - typedef gridtools::storage_traits::storage_info_t<0, Rank> storage_info_ty; - typedef gridtools::storage_traits::data_store_t data_store_t; +IndexView make_host_indexview( const Array& array ) { + typedef gridtools::storage_traits::storage_info_t<0, Rank> storage_info_ty; + typedef gridtools::storage_traits::data_store_t data_store_t; - data_store_t* ds = reinterpret_cast(const_cast(array.storage())); + 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 ) ); } // -------------------------------------------------------------------------------------------- template -IndexView -make_indexview(const Array& array) { - check_metadata(array); - return make_host_indexview(array); +IndexView make_indexview( const Array& array ) { + check_metadata( array ); + return make_host_indexview( array ); } template -ArrayView -make_view(const Array& array) { - check_metadata(array); +ArrayView make_view( const Array& array ) { + check_metadata( array ); - return make_host_view(array); + return make_host_view( array ); } -} -} +} // namespace array +} // namespace atlas //----------------------------------------------------------------------- // Explicit instantiation namespace atlas { namespace array { -#define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -\ -template IndexView make_indexview(const Array&);\ -template IndexView make_indexview(const Array&);\ -\ -template IndexView make_host_indexview(const Array&);\ -template IndexView make_host_indexview(const Array&);\ -\ -namespace gridtools { \ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ - template data_view_tt make_gt_host_view(const Array& array);\ -\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ - template data_view_tt make_gt_device_view(const Array& array);\ -} +#define EXPLICIT_TEMPLATE_INSTANTIATION( RANK ) \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( \ + const Array& ); \ + template ArrayView make_view( \ + const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( \ + const Array& ); \ + template ArrayView make_host_view( \ + const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( \ + const Array& ); \ + \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( \ + const Array& ); \ + template ArrayView \ + make_device_view( const Array& ); \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( \ + const Array& ); \ + template ArrayView make_device_view( \ + const Array& ); \ + template ArrayView make_device_view( \ + const Array& ); \ + \ + template IndexView make_indexview( const Array& ); \ + template IndexView make_indexview( const Array& ); \ + \ + template IndexView make_host_indexview( const Array& ); \ + template IndexView make_host_indexview( const Array& ); \ + \ + namespace gridtools { \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + template data_view_tt \ + make_gt_host_view( const Array& array ); \ + \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + template data_view_tt \ + make_gt_device_view( const Array& array ); \ + } // For each Rank in [1..9] -EXPLICIT_TEMPLATE_INSTANTIATION(1) -EXPLICIT_TEMPLATE_INSTANTIATION(2) -EXPLICIT_TEMPLATE_INSTANTIATION(3) -EXPLICIT_TEMPLATE_INSTANTIATION(4) -EXPLICIT_TEMPLATE_INSTANTIATION(5) -EXPLICIT_TEMPLATE_INSTANTIATION(6) -EXPLICIT_TEMPLATE_INSTANTIATION(7) -EXPLICIT_TEMPLATE_INSTANTIATION(8) -EXPLICIT_TEMPLATE_INSTANTIATION(9) +EXPLICIT_TEMPLATE_INSTANTIATION( 1 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 2 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 3 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 4 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 5 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 6 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 7 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 8 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 9 ) #undef EXPLICIT_TEMPLATE_INSTANTIATION } -} - - - +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsMakeView.h b/src/atlas/array/gridtools/GridToolsMakeView.h index 2537497af..cfc44d918 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.h +++ b/src/atlas/array/gridtools/GridToolsMakeView.h @@ -4,26 +4,25 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "atlas/array_fwd.h" #include "atlas/array/gridtools/GridToolsTraits.h" +#include "atlas/array_fwd.h" namespace atlas { namespace array { namespace gridtools { template -data_view_tt -make_gt_host_view(const Array& array); +data_view_tt make_gt_host_view( const Array& array ); template -data_view_tt -make_gt_device_view(const Array& array); +data_view_tt make_gt_device_view( const Array& array ); -} // namespace gridtools -} // namespace array -} // namespace atlas +} // namespace gridtools +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/gridtools/GridToolsTraits.h b/src/atlas/array/gridtools/GridToolsTraits.h index 7a1584ec5..b7033573d 100644 --- a/src/atlas/array/gridtools/GridToolsTraits.h +++ b/src/atlas/array/gridtools/GridToolsTraits.h @@ -1,7 +1,7 @@ #pragma once -#include "atlas/library/config.h" #include "atlas/array/ArrayViewDefs.h" +#include "atlas/library/config.h" #include "gridtools/common/generic_metafunctions/all_integrals.hpp" #include "gridtools/storage/storage-facility.hpp" @@ -14,28 +14,25 @@ namespace gridtools { //------------------------------------------------------------------------------ #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA -using storage_traits = ::gridtools::storage_traits< ::gridtools::enumtype::Cuda >; +using storage_traits = ::gridtools::storage_traits<::gridtools::enumtype::Cuda>; #elif ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST -using storage_traits = ::gridtools::storage_traits< ::gridtools::enumtype::Host >; +using storage_traits = ::gridtools::storage_traits<::gridtools::enumtype::Host>; #else #error ATLAS_GRIDTOOLS_STORAGE_BACKEND_ not set #endif //------------------------------------------------------------------------------ -template +template using data_view_tt = ::gridtools::data_view< - gridtools::storage_traits::data_store_t< - Value, - gridtools::storage_traits::storage_info_t<0, Rank> >, - AccessMode>; + gridtools::storage_traits::data_store_t>, AccessMode>; -inline constexpr ::gridtools::access_mode get_access_mode(Intent kind) { - return (kind == Intent::ReadOnly) ? ::gridtools::access_mode::ReadOnly : ::gridtools::access_mode::ReadWrite; +inline constexpr ::gridtools::access_mode get_access_mode( Intent kind ) { + return ( kind == Intent::ReadOnly ) ? ::gridtools::access_mode::ReadOnly : ::gridtools::access_mode::ReadWrite; } //------------------------------------------------------------------------------ -} // namespace gridtools -} // namespace array -} // namespace atlas +} // namespace gridtools +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/helpers/ArrayAssigner.h b/src/atlas/array/helpers/ArrayAssigner.h index cc0aae196..393298304 100644 --- a/src/atlas/array/helpers/ArrayAssigner.h +++ b/src/atlas/array/helpers/ArrayAssigner.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -29,90 +30,81 @@ struct array_assigner; // Recursive function to apply value to every index template struct array_assigner_impl { - - template - static void apply(View& arr, Value value, DimIndex... idxs) { - for(size_t i=0; i < arr.shape(Dim); ++i) { - array_assigner_impl::apply( arr, value, idxs..., i ); + template + static void apply( View& arr, Value value, DimIndex... idxs ) { + for ( size_t i = 0; i < arr.shape( Dim ); ++i ) { + array_assigner_impl::apply( arr, value, idxs..., i ); + } } - } - template - static void apply(View& arr, Iterator& it, DimIndex... idxs) { - for(size_t i=0; i < arr.shape(Dim); ++i) { - array_assigner_impl::apply( arr, it, idxs..., i ); + template + static void apply( View& arr, Iterator& it, DimIndex... idxs ) { + for ( size_t i = 0; i < arr.shape( Dim ); ++i ) { + array_assigner_impl::apply( arr, it, idxs..., i ); + } } - } - }; // End of recursion when Dim == Rank template struct array_assigner_impl { + template + static void apply( View& arr, Value value, DimIndex... idxs ) { + arr( idxs... ) = value; + } - template - static void apply(View& arr, Value value, DimIndex... idxs) { - arr(idxs...) = value; - } - - template - static void apply(View& arr, Iterator& it, DimIndex... idxs) { - arr(idxs...) = *it; - ++it; - } - + template + static void apply( View& arr, Iterator& it, DimIndex... idxs ) { + arr( idxs... ) = *it; + ++it; + } }; - //------------------------------------------------------------------------------ - template struct array_assigner { + template + static void apply( Array& arr, Value value ) { + return apply( make_host_view( arr ), value ); + } - template - static void apply(Array& arr, Value value) { - return apply( make_host_view(arr), value ); - } - - static void apply(ArrayView&, Value) { - throw eckit::AssertionFailed("Cannot assign ReadOnly array",Here()); - // TODO use SFINAE to disallow at compile time - } - - template - static void apply(ArrayView&, const Iterable&) { - throw eckit::AssertionFailed("Cannot assign ReadOnly array",Here()); - // TODO use SFINAE to disallow at compile time - } - - - static void apply(ArrayView& arr, Value value) { - array_assigner_impl::apply( arr, value ); - // Note: no need to apply variadic pack (idxs...) - } - - template - static void apply(ArrayView& arr, const Iterable& iterable) { - typename Iterable::const_iterator it = iterable.begin(); - array_assigner_impl::apply( arr, it ); - ASSERT( it = iterable.end() ); - } - - static void apply(LocalView&, Value value) { - throw eckit::AssertionFailed("Cannot assign ReadOnly array",Here()); - // TODO use SFINAE to disallow at compile time - } - - static void apply(LocalView& arr, Value value) { - array_assigner_impl::apply( arr, value ); - // Note: no need to apply variadic pack (idxs...) - } + static void apply( ArrayView&, Value ) { + throw eckit::AssertionFailed( "Cannot assign ReadOnly array", Here() ); + // TODO use SFINAE to disallow at compile time + } + template + static void apply( ArrayView&, const Iterable& ) { + throw eckit::AssertionFailed( "Cannot assign ReadOnly array", Here() ); + // TODO use SFINAE to disallow at compile time + } + + static void apply( ArrayView& arr, Value value ) { + array_assigner_impl::apply( arr, value ); + // Note: no need to apply variadic pack (idxs...) + } + + template + static void apply( ArrayView& arr, const Iterable& iterable ) { + typename Iterable::const_iterator it = iterable.begin(); + array_assigner_impl::apply( arr, it ); + ASSERT( it = iterable.end() ); + } + + static void apply( LocalView&, Value value ) { + throw eckit::AssertionFailed( "Cannot assign ReadOnly array", Here() ); + // TODO use SFINAE to disallow at compile time + } + + static void apply( LocalView& arr, Value value ) { + array_assigner_impl::apply( arr, value ); + // Note: no need to apply variadic pack (idxs...) + } }; //------------------------------------------------------------------------------ -} // namespace helpers -} // namespace array -} // namespace atlas +} // namespace helpers +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/helpers/ArrayInitializer.h b/src/atlas/array/helpers/ArrayInitializer.h index f3133edf6..697ca6e1f 100644 --- a/src/atlas/array/helpers/ArrayInitializer.h +++ b/src/atlas/array/helpers/ArrayInitializer.h @@ -4,17 +4,18 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include "eckit/exception/Exceptions.h" +#include "atlas/array.h" #include "atlas/array/DataType.h" #include "atlas/array_fwd.h" -#include "atlas/array.h" +#include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------ @@ -27,103 +28,84 @@ namespace helpers { template struct array_initializer; -template +template struct array_initializer_partitioned; //------------------------------------------------------------------------------ template struct array_initializer_impl { - - - static void apply(Array const& orig, Array& array_resized) { - array_initializer_impl::apply( - make_view(orig), - make_view(array_resized) ); - } - - - template - static void apply(ArrayView const&& orig, ArrayView&& array_resized, DimIndex... idxs) { - - for(size_t i=0; i < orig.shape(Dim); ++i) { - array_initializer_impl::apply( - std::move(orig), - std::move(array_resized), - idxs..., - i ); + static void apply( Array const& orig, Array& array_resized ) { + array_initializer_impl::apply( make_view( orig ), + make_view( array_resized ) ); } - } - - + template + static void apply( ArrayView const&& orig, ArrayView&& array_resized, DimIndex... idxs ) { + for ( size_t i = 0; i < orig.shape( Dim ); ++i ) { + array_initializer_impl::apply( std::move( orig ), std::move( array_resized ), idxs..., + i ); + } + } }; //------------------------------------------------------------------------------ template struct array_initializer_impl { - - template - static void apply(ArrayView const&& orig,ArrayView&& array_resized, DimIndex... idxs) { - array_resized(idxs...) = orig(idxs...); - } - + template + static void apply( ArrayView const&& orig, ArrayView&& array_resized, DimIndex... idxs ) { + array_resized( idxs... ) = orig( idxs... ); + } }; //------------------------------------------------------------------------------ template struct array_initializer { - static void apply(Array const& orig, Array& array_resized) { - switch (orig.datatype().kind()) { - case DataType::KIND_REAL64: return array_initializer_impl::apply(orig, array_resized); - case DataType::KIND_REAL32: return array_initializer_impl::apply(orig, array_resized); - case DataType::KIND_INT32: return array_initializer_impl::apply(orig, array_resized); - case DataType::KIND_INT64: return array_initializer_impl::apply(orig, array_resized); - case DataType::KIND_UINT64: return array_initializer_impl::apply(orig, array_resized); - default: { - std::stringstream err; - err << "data kind " << orig.datatype().kind() << " not recognised."; - throw eckit::BadParameter(err.str(), Here()); - } + static void apply( Array const& orig, Array& array_resized ) { + switch ( orig.datatype().kind() ) { + case DataType::KIND_REAL64: + return array_initializer_impl::apply( orig, array_resized ); + case DataType::KIND_REAL32: + return array_initializer_impl::apply( orig, array_resized ); + case DataType::KIND_INT32: + return array_initializer_impl::apply( orig, array_resized ); + case DataType::KIND_INT64: + return array_initializer_impl::apply( orig, array_resized ); + case DataType::KIND_UINT64: + return array_initializer_impl::apply( orig, array_resized ); + default: { + std::stringstream err; + err << "data kind " << orig.datatype().kind() << " not recognised."; + throw eckit::BadParameter( err.str(), Here() ); + } + } } - } }; //------------------------------------------------------------------------------ -template +template struct array_initializer_partitioned_val_impl { + static void apply( Array const& orig, Array& dest, unsigned int pos, unsigned int offset ) { + array_initializer_partitioned_val_impl::apply( + make_view( orig ), make_view( dest ), pos, offset ); + } - static void apply( Array const& orig, Array& dest, unsigned int pos, unsigned int offset ) { - array_initializer_partitioned_val_impl::apply( - make_view(orig), - make_view(dest), - pos, offset); - } - - template - static void apply( ArrayView const&& orig, - ArrayView&& dest, - unsigned int pos, unsigned int offset, DimIndexPair... idxs) { - for(size_t i=0; i < orig.shape(Dim); ++i) - { - unsigned int displ = i; - 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); - } - } - + template + static void apply( ArrayView const&& orig, ArrayView&& dest, unsigned int pos, + unsigned int offset, DimIndexPair... idxs ) { + for ( size_t i = 0; i < orig.shape( Dim ); ++i ) { + unsigned int displ = i; + 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 ); + } + } }; - // template< typename stdarray > // inline std::string print_array(const stdarray& v) // { @@ -141,59 +123,79 @@ struct array_initializer_partitioned_val_impl { template struct array_initializer_partitioned_val_impl { - template - static void apply(ArrayView const&& orig, ArrayView&& dest, unsigned int pos, unsigned int offset, DimIndexPair... idxs) { -// Log::info() << print_array(std::array{std::get<0>(idxs)...}) << " --> " << print_array(std::array{std::get<1>(idxs)...}) << " " << orig(std::get<0>(idxs)...) << std::endl; - dest(std::get<1>(idxs)...) = orig(std::get<0>(idxs)...); + template + static void apply( ArrayView const&& orig, ArrayView&& dest, unsigned int pos, + unsigned int offset, DimIndexPair... idxs ) { + // Log::info() << print_array(std::array{std::get<0>(idxs)...}) << + // " --> " << print_array(std::array{std::get<1>(idxs)...}) << " + // " << orig(std::get<0>(idxs)...) << std::endl; + dest( std::get<1>( idxs )... ) = orig( std::get<0>( idxs )... ); } }; //------------------------------------------------------------------------------ -template +template struct array_initializer_partitioned_impl { - static void apply( Array const& orig, Array& dest, unsigned int pos, unsigned int offset) { - switch (orig.datatype().kind()) { - case DataType::KIND_REAL64: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); - case DataType::KIND_REAL32: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); - case DataType::KIND_INT32: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); - case DataType::KIND_INT64: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); - case DataType::KIND_UINT64: return array_initializer_partitioned_val_impl::apply(orig, dest, pos, offset); - default: { - std::stringstream err; - err << "data kind " << orig.datatype().kind() << " not recognised."; - throw eckit::BadParameter(err.str(), Here()); + static void apply( Array const& orig, Array& dest, unsigned int pos, unsigned int offset ) { + switch ( orig.datatype().kind() ) { + case DataType::KIND_REAL64: + return array_initializer_partitioned_val_impl::apply( orig, dest, pos, + offset ); + case DataType::KIND_REAL32: + return array_initializer_partitioned_val_impl::apply( orig, dest, pos, + offset ); + case DataType::KIND_INT32: + return array_initializer_partitioned_val_impl::apply( orig, dest, pos, offset ); + case DataType::KIND_INT64: + return array_initializer_partitioned_val_impl::apply( orig, dest, pos, offset ); + case DataType::KIND_UINT64: + return array_initializer_partitioned_val_impl::apply( orig, dest, pos, + offset ); + default: { + std::stringstream err; + err << "data kind " << orig.datatype().kind() << " not recognised."; + throw eckit::BadParameter( err.str(), Here() ); + } } - } - } + } }; //------------------------------------------------------------------------------ -template +template struct array_initializer_partitioned { - static void apply(Array const& orig, Array& dest, unsigned int pos, unsigned int offset) { - switch (orig.rank()) { - case 1: return array_initializer_partitioned_impl<1, PartDim>::apply(orig, dest, pos, offset); - case 2: return array_initializer_partitioned_impl<2, PartDim>::apply(orig, dest, pos, offset); - case 3: return array_initializer_partitioned_impl<3, PartDim>::apply(orig, dest, pos, offset); - case 4: return array_initializer_partitioned_impl<4, PartDim>::apply(orig, dest, pos, offset); - case 5: return array_initializer_partitioned_impl<5, PartDim>::apply(orig, dest, pos, offset); - case 6: return array_initializer_partitioned_impl<6, PartDim>::apply(orig, dest, pos, offset); - case 7: return array_initializer_partitioned_impl<7, PartDim>::apply(orig, dest, pos, offset); - case 8: return array_initializer_partitioned_impl<8, PartDim>::apply(orig, dest, pos, offset); - case 9: return array_initializer_partitioned_impl<9, PartDim>::apply(orig, dest, pos, offset); - default: { - std::stringstream err; - err << "too high Rank"; - throw eckit::BadParameter(err.str(), Here()); - } + static void apply( Array const& orig, Array& dest, unsigned int pos, unsigned int offset ) { + switch ( orig.rank() ) { + case 1: + return array_initializer_partitioned_impl<1, PartDim>::apply( orig, dest, pos, offset ); + case 2: + return array_initializer_partitioned_impl<2, PartDim>::apply( orig, dest, pos, offset ); + case 3: + return array_initializer_partitioned_impl<3, PartDim>::apply( orig, dest, pos, offset ); + case 4: + return array_initializer_partitioned_impl<4, PartDim>::apply( orig, dest, pos, offset ); + case 5: + return array_initializer_partitioned_impl<5, PartDim>::apply( orig, dest, pos, offset ); + case 6: + return array_initializer_partitioned_impl<6, PartDim>::apply( orig, dest, pos, offset ); + case 7: + return array_initializer_partitioned_impl<7, PartDim>::apply( orig, dest, pos, offset ); + case 8: + return array_initializer_partitioned_impl<8, PartDim>::apply( orig, dest, pos, offset ); + case 9: + return array_initializer_partitioned_impl<9, PartDim>::apply( orig, dest, pos, offset ); + default: { + std::stringstream err; + err << "too high Rank"; + throw eckit::BadParameter( err.str(), Here() ); + } + } } - } }; //------------------------------------------------------------------------------ -} // namespace helpers -} // namespace array -} // namespace atlas +} // namespace helpers +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/helpers/ArraySlicer.h b/src/atlas/array/helpers/ArraySlicer.h index 537389016..d2b1a2cc2 100644 --- a/src/atlas/array/helpers/ArraySlicer.h +++ b/src/atlas/array/helpers/ArraySlicer.h @@ -4,320 +4,310 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "atlas/runtime/Log.h" #include "atlas/array/ArrayViewDefs.h" #include "atlas/array/Range.h" +#include "atlas/runtime/Log.h" namespace atlas { namespace array { -template< typename Value, int Rank, Intent AccessMode > +template class LocalView; - -template +template struct Reference { - Value& value; - operator Value&() { return value; } - template < typename T > void operator=(const T a) { value = a; } - template < typename T > Reference& operator+(const T a) { value+=a; return *this; } - template < typename T > Reference& operator-(const T a) { value-=a; return *this; } - Reference& operator--() { --value; return *this; } - Reference& operator++() { ++value; return *this; } + Value& value; + operator Value&() { return value; } + template + void operator=( const T a ) { + value = a; + } + template + Reference& operator+( const T a ) { + value += a; + return *this; + } + template + Reference& operator-( const T a ) { + value -= a; + return *this; + } + Reference& operator--() { + --value; + return *this; + } + Reference& operator++() { + ++value; + return *this; + } }; - -template +template struct get_slice_type { - using type = - typename std::conditional<(Rank==0), - typename std::conditional<(Access==Intent::ReadOnly), - Reference, - Reference - >::type, - LocalView - >::type; + using type = typename std::conditional< + ( Rank == 0 ), + typename std::conditional<( Access == Intent::ReadOnly ), Reference, Reference>::type, + LocalView>::type; }; //------------------------------------------------------------------------------ namespace helpers { -template< int Dim > +template struct deduce_slice_rank; -template< int Rank, typename ...Args > +template struct SliceRank_impl; -template<> +template <> struct deduce_slice_rank<1> { - - template - static constexpr int apply() { - return std::is_base_of::value; - } - + template + static constexpr int apply() { + return std::is_base_of::value; + } }; -template -struct SliceRank_impl<1,Args...> { - static constexpr int value{ deduce_slice_rank<1>::apply() }; +template +struct SliceRank_impl<1, Args...> { + static constexpr int value{deduce_slice_rank<1>::apply()}; }; +#define ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( RANK ) \ + template <> \ + struct deduce_slice_rank { \ + template \ + static constexpr int apply() { \ + return std::is_base_of::value + deduce_slice_rank::apply(); \ + } \ + }; \ + template \ + struct SliceRank_impl { \ + static constexpr int value{deduce_slice_rank::apply()}; \ + } -#define ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(RANK) \ -template<> \ -struct deduce_slice_rank { \ -\ - template \ - static constexpr int apply() { \ - return std::is_base_of::value + deduce_slice_rank::apply(); \ - } \ - \ -}; \ -template \ -struct SliceRank_impl \ -{ \ - static constexpr int value{ deduce_slice_rank::apply() }; \ -} - -ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(2); -ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(3); -ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(4); -ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(5); -ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(6); -ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(7); -ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(8); -ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION(9); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 2 ); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 3 ); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 4 ); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 5 ); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 6 ); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 7 ); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 8 ); +ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION( 9 ); #undef ATLAS_ARRAY_SLICER_EXPLICIT_TEMPLATE_SPECIALISATION -template +template struct SliceRank { - static constexpr int value{ SliceRank_impl::value }; + static constexpr int value{SliceRank_impl::value}; }; - -template< typename View, bool constness = false > +template struct get_access { - static constexpr Intent value{ View::ACCESS }; + static constexpr Intent value{View::ACCESS}; }; -template< typename View > -struct get_access { - static constexpr Intent value{ Intent::ReadOnly }; +template +struct get_access { + static constexpr Intent value{Intent::ReadOnly}; }; - -//template +// template template class ArraySlicer { public: + ArraySlicer( View& view ) : view_( view ) {} - ArraySlicer(View& view) : - view_(view) { - } - - template + template struct Slice { - using type = typename get_slice_type< - typename View::value_type, - SliceRank::value, - get_access::value>::value >::type; + using type = typename get_slice_type::value, + get_access::value>::value>::type; }; - template - typename Slice::type apply(const Args ...args) const { - using slicer_t = Slicer< typename Slice::type, (SliceRank::value==0) >; + template + typename Slice::type apply( const Args... args ) const { + using slicer_t = Slicer::type, ( SliceRank::value == 0 )>; return slicer_t::apply( view_, args... ); } private: - - template + template struct array { - using type = typename std::array::value >; + using type = typename std::array::value>; }; template struct Slicer { - template< typename ...Args > - static ReturnType apply(View& view, const Args...args) { - return ReturnType( - view.data()+offset(view,args...), - shape(view,args...).data(), - strides(view,args...).data() - ); + template + static ReturnType apply( View& view, const Args... args ) { + return ReturnType( view.data() + offset( view, args... ), shape( view, args... ).data(), + strides( view, args... ).data() ); } }; template - struct Slicer { - template< typename ...Args > - static ReturnType apply(View& view, const Args...args) { - return ReturnType{*(view.data()+offset(view,args...))}; - } + struct Slicer { + template + static ReturnType apply( View& view, const Args... args ) { + return ReturnType{*( view.data() + offset( view, args... ) )}; + } }; - template< typename Int > + template static int offset_part( View& view, int& i_view, Int idx ) { - return idx * view.stride(i_view++); + return idx * view.stride( i_view++ ); } - static int offset_part( View& view, int& i_view, Range range ) { - return range.start() * view.stride(i_view++); - } + static int offset_part( View& view, int& i_view, Range range ) { return range.start() * view.stride( i_view++ ); } static int offset_part( View& view, int& i_view, RangeAll range ) { - return range.start() * view.stride(i_view++); + return range.start() * view.stride( i_view++ ); } - static int offset_part( View& view, int& i_view, RangeTo range ) { - return range.start() * view.stride(i_view++); - } + static int offset_part( View& view, int& i_view, RangeTo range ) { return range.start() * view.stride( i_view++ ); } static int offset_part( View& view, int& i_view, RangeFrom range ) { - return range.start() * view.stride(i_view++); + return range.start() * view.stride( i_view++ ); } - static int offset_part( View& , int& /*i_view*/, RangeDummy ) { - return 0; - } + static int offset_part( View&, int& /*i_view*/, RangeDummy ) { return 0; } - template < int Dim, typename Int, typename... Ints > - static int offset_remaining(View& view, int& i_view, const Int idx, const Ints... next_idx) { - return offset_part(view,i_view,idx) + offset_remaining( view, i_view, next_idx... ); + template + static int offset_remaining( View& view, int& i_view, const Int idx, const Ints... next_idx ) { + return offset_part( view, i_view, idx ) + offset_remaining( view, i_view, next_idx... ); } - template < int Dim, typename Int > - static int offset_remaining(View& view, int& i_view, const Int last_idx) { - return offset_part(view,i_view,last_idx); + template + static int offset_remaining( View& view, int& i_view, const Int last_idx ) { + return offset_part( view, i_view, last_idx ); } - template < typename... Args > - static int offset(View& view, const Args... args) { - int i_view(0); - return offset_remaining<0>(view,i_view,args...); + template + static int offset( View& view, const Args... args ) { + int i_view( 0 ); + return offset_remaining<0>( view, i_view, args... ); } - - template< int Dim, typename Shape, typename Int > - static void update_shape( View&, Shape&, int& i_view, int& /*i_slice*/, const Int& /*index*/ ){ - // do nothing - ++i_view; + template + static void update_shape( View&, Shape&, int& i_view, int& /*i_slice*/, const Int& /*index*/ ) { + // do nothing + ++i_view; } - template< int Dim, typename Shape > - static void update_shape( View&, Shape& shape, int& i_view, int& i_slice, const Range range ){ - shape[i_slice] = range.end()-range.start(); - ++i_slice; - ++i_view; + template + static void update_shape( View&, Shape& shape, int& i_view, int& i_slice, const Range range ) { + shape[i_slice] = range.end() - range.start(); + ++i_slice; + ++i_view; } - template< int Dim, typename Shape > - static void update_shape( View& view, Shape& shape, int& i_view, int& i_slice, const RangeAll range ){ - shape[i_slice] = range.end(view,i_view)-range.start(); - ++i_slice; - ++i_view; + template + static void update_shape( View& view, Shape& shape, int& i_view, int& i_slice, const RangeAll range ) { + shape[i_slice] = range.end( view, i_view ) - range.start(); + ++i_slice; + ++i_view; } - template< int Dim, typename Shape > - static void update_shape( View& view, Shape& shape, int& i_view, int& i_slice, const RangeFrom range ){ - shape[i_slice] = range.end(view,i_view)-range.start(); - ++i_slice; - ++i_view; + template + static void update_shape( View& view, Shape& shape, int& i_view, int& i_slice, const RangeFrom range ) { + shape[i_slice] = range.end( view, i_view ) - range.start(); + ++i_slice; + ++i_view; } - template< int Dim, typename Shape > - static void update_shape( View&, Shape& shape, int& i_view, int& i_slice, const RangeTo range ){ - shape[i_slice] = range.end()-range.start(); - ++i_slice; - ++i_view; + template + static void update_shape( View&, Shape& shape, int& i_view, int& i_slice, const RangeTo range ) { + shape[i_slice] = range.end() - range.start(); + ++i_slice; + ++i_view; } - template< int Dim, typename Shape > - static void update_shape( View&, Shape& shape, int& /*i_view*/, int& i_slice, const RangeDummy ){ - shape[i_slice] = 1; - ++i_slice; - // no update of i_view for dummy-dimension + template + static void update_shape( View&, Shape& shape, int& /*i_view*/, int& i_slice, const RangeDummy ) { + shape[i_slice] = 1; + ++i_slice; + // no update of i_view for dummy-dimension } - template< int Dim, typename Shape, typename Int, typename... Ints > - static void shape_part( View& view, Shape& shape, int& i_view, int& i_slice, const Int idx, const Ints... next_idx ) { - update_shape(view,shape,i_view,i_slice,idx); - shape_part(view,shape,i_view,i_slice,next_idx...); + template + static void shape_part( View& view, Shape& shape, int& i_view, int& i_slice, const Int idx, + const Ints... next_idx ) { + update_shape( view, shape, i_view, i_slice, idx ); + shape_part( view, shape, i_view, i_slice, next_idx... ); } - template< int Dim, typename Shape, typename Int > - static void shape_part( View& view, Shape& shape, int& i_view, int& i_slice, const Int idx) { - update_shape(view,shape,i_view,i_slice,idx); + template + static void shape_part( View& view, Shape& shape, int& i_view, int& i_slice, const Int idx ) { + update_shape( view, shape, i_view, i_slice, idx ); } - template< typename... Args > + template static typename array::type shape( View& view, const Args... args ) { - typename array::type result; - int i_slice(0); - int i_view(0); - shape_part<0>(view,result,i_view,i_slice,args...); - ASSERT( i_view == view.rank() ); - return result; + typename array::type result; + int i_slice( 0 ); + int i_view( 0 ); + shape_part<0>( view, result, i_view, i_slice, args... ); + ASSERT( i_view == view.rank() ); + return result; } - - template - static void update_strides( View&, Strides&, int& i_view, int& /*i_slice*/, const Int& /*idx*/) { - // do nothing - ++i_view; - } - template + template + static void update_strides( View&, Strides&, int& i_view, int& /*i_slice*/, const Int& /*idx*/ ) { + // do nothing + ++i_view; + } + template static void update_strides( View& view, Strides& strides, int& i_view, int& i_slice, const Range& /*range*/ ) { - strides[i_slice] = view.stride(i_view); - ++i_slice; - ++i_view; + strides[i_slice] = view.stride( i_view ); + ++i_slice; + ++i_view; } - template + template static void update_strides( View& view, Strides& strides, int& i_view, int& i_slice, const RangeFrom& /*range*/ ) { - strides[i_slice] = view.stride(i_view); - ++i_slice; - ++i_view; + strides[i_slice] = view.stride( i_view ); + ++i_slice; + ++i_view; } - template + template static void update_strides( View& view, Strides& strides, int& i_view, int& i_slice, const RangeTo& /*range*/ ) { - strides[i_slice] = view.stride(i_view); - ++i_slice; - ++i_view; + strides[i_slice] = view.stride( i_view ); + ++i_slice; + ++i_view; } - template + template static void update_strides( View& view, Strides& strides, int& i_view, int& i_slice, const RangeAll& /*range*/ ) { - strides[i_slice] = view.stride(i_view); - ++i_slice; - ++i_view; + strides[i_slice] = view.stride( i_view ); + ++i_slice; + ++i_view; } - template - static void update_strides( View& view, Strides& strides, int& /*i_view*/, int& i_slice, const RangeDummy& /*range*/ ) { - strides[i_slice] = 0; - ++i_slice; + template + static void update_strides( View& view, Strides& strides, int& /*i_view*/, int& i_slice, + const RangeDummy& /*range*/ ) { + strides[i_slice] = 0; + ++i_slice; } - template< int Dim, typename Strides, typename Int, typename... Ints > - static void strides_part( View& view, Strides& strides, int& i_view, int& i_slice, const Int idx, const Ints... next_idx ) { - update_strides(view,strides,i_view,i_slice,idx); - strides_part(view,strides,i_view,i_slice,next_idx...); + template + static void strides_part( View& view, Strides& strides, int& i_view, int& i_slice, const Int idx, + const Ints... next_idx ) { + update_strides( view, strides, i_view, i_slice, idx ); + strides_part( view, strides, i_view, i_slice, next_idx... ); } - template< int Dim, typename Strides, typename Int > - static void strides_part( View& view, Strides& strides, int& i_view, int& i_slice, const Int idx) { - update_strides(view,strides,i_view,i_slice,idx); + template + static void strides_part( View& view, Strides& strides, int& i_view, int& i_slice, const Int idx ) { + update_strides( view, strides, i_view, i_slice, idx ); } - template< typename... Args > - static typename array::type strides(View& view, const Args... args ) { - typename array::type result; - int i_slice(0); - int i_view(0); - strides_part<0>(view,result,i_view,i_slice,args...); - ASSERT( i_view == view.rank() ); - return result; + template + static typename array::type strides( View& view, const Args... args ) { + typename array::type result; + int i_slice( 0 ); + int i_view( 0 ); + strides_part<0>( view, result, i_view, i_slice, args... ); + ASSERT( i_view == view.rank() ); + return result; } private: @@ -326,6 +316,6 @@ class ArraySlicer { //------------------------------------------------------------------------------ -} // namespace helpers -} // namespace array -} // namespace atlas +} // namespace helpers +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/helpers/ArrayWriter.h b/src/atlas/array/helpers/ArrayWriter.h index fc2d9736c..ff92ba7a8 100644 --- a/src/atlas/array/helpers/ArrayWriter.h +++ b/src/atlas/array/helpers/ArrayWriter.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -21,7 +22,7 @@ namespace helpers { //------------------------------------------------------------------------------ /// Helper to assign a value to an array or arrayview -//template +// template struct array_writer; //------------------------------------------------------------------------------ @@ -29,50 +30,42 @@ struct array_writer; // Recursive function to apply value to every index template struct array_writer_impl { - - template - static void apply( View& arr, std::ostream& out, DimIndex... idxs ) { - for(size_t i=0; i < arr.shape(Dim); ++i) { - array_writer_impl::apply( arr, out, idxs..., i ); - if( i + static void apply( View& arr, std::ostream& out, DimIndex... idxs ) { + for ( size_t i = 0; i < arr.shape( Dim ); ++i ) { + array_writer_impl::apply( arr, out, idxs..., i ); + if ( i < arr.shape( Dim ) - 1 ) out << " "; + } } - } - }; // End of recursion when Dim == Rank template struct array_writer_impl { - - template - static void apply(View& arr, std::ostream& out, DimIndex... idxs) { - out << arr(idxs...); - } - + template + static void apply( View& arr, std::ostream& out, DimIndex... idxs ) { + out << arr( idxs... ); + } }; - //------------------------------------------------------------------------------ - struct array_writer { + template + static void apply( const ArrayView& arr, std::ostream& out ) { + array_writer_impl::apply( arr, out ); + // Note: no need to apply variadic pack (idxs...) + } - template - static void apply( const ArrayView& arr, std::ostream& out ) { - array_writer_impl::apply( arr, out ); - // Note: no need to apply variadic pack (idxs...) - } - - template - static void apply( const LocalView& arr, std::ostream& out ) { - array_writer_impl::apply( arr, out ); - // Note: no need to apply variadic pack (idxs...) - } - + template + static void apply( const LocalView& arr, std::ostream& out ) { + array_writer_impl::apply( arr, out ); + // Note: no need to apply variadic pack (idxs...) + } }; //------------------------------------------------------------------------------ -} // namespace helpers -} // namespace array -} // namespace atlas +} // namespace helpers +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index a54331fd3..0b7be6b56 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -12,257 +12,322 @@ using namespace atlas::array::helpers; namespace atlas { namespace array { -template Array* Array::create( size_t dim0 ) { - return new ArrayT( dim0 ); +template +Array* Array::create( size_t dim0 ) { + return new ArrayT( dim0 ); } -template Array* Array::create( size_t dim0, size_t dim1 ) { - return new ArrayT( dim0, dim1 ); +template +Array* Array::create( size_t dim0, size_t dim1 ) { + return new ArrayT( dim0, dim1 ); } -template Array* Array::create( size_t dim0, size_t dim1, size_t dim2 ) { - return new ArrayT( dim0, dim1, dim2 ); +template +Array* Array::create( size_t dim0, size_t dim1, size_t dim2 ) { + return new ArrayT( dim0, dim1, dim2 ); } -template Array* Array::create( size_t dim0, size_t dim1, size_t dim2, size_t dim3 ) { - return new ArrayT( dim0, dim1, dim2, dim3 ); +template +Array* Array::create( size_t dim0, size_t dim1, size_t dim2, size_t dim3 ) { + return new ArrayT( dim0, dim1, dim2, dim3 ); } -template Array* Array::create( size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4 ) { - return new ArrayT( dim0, dim1, dim2, dim3, dim4 ); +template +Array* Array::create( size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4 ) { + return new ArrayT( dim0, dim1, dim2, dim3, dim4 ); } -template Array* Array::create( const ArrayShape& shape ) { - return new ArrayT( shape ); +template +Array* Array::create( const ArrayShape& shape ) { + return new ArrayT( shape ); } -template Array* Array::create( const ArrayShape& shape, const ArrayLayout& layout ) { - return new ArrayT( shape,layout ); +template +Array* Array::create( const ArrayShape& shape, const ArrayLayout& layout ) { + return new ArrayT( shape, layout ); } -template Array* Array::wrap( Value* data, const ArrayShape& shape ) { - return new ArrayT( new native::WrappedDataStore(data), shape ); +template +Array* Array::wrap( Value* data, const ArrayShape& shape ) { + return new ArrayT( new native::WrappedDataStore( data ), shape ); } -template Array* Array::wrap( Value* data, const ArraySpec& spec ) { - return new ArrayT( new native::WrappedDataStore(data), spec ); +template +Array* Array::wrap( Value* data, const ArraySpec& spec ) { + return new ArrayT( new native::WrappedDataStore( data ), spec ); } Array::~Array() {} -Array* Array::create( DataType datatype, const ArrayShape& shape ) -{ - switch( datatype.kind() ) - { - case DataType::KIND_REAL64: return new ArrayT(shape); - case DataType::KIND_REAL32: return new ArrayT(shape); - case DataType::KIND_INT32: return new ArrayT(shape); - case DataType::KIND_INT64: return new ArrayT(shape); - case DataType::KIND_UINT64: return new ArrayT(shape); - default: - { - std::stringstream err; err << "data kind " << datatype.kind() << " not recognised."; - throw eckit::BadParameter(err.str(),Here()); +Array* Array::create( DataType datatype, const ArrayShape& shape ) { + switch ( datatype.kind() ) { + case DataType::KIND_REAL64: + return new ArrayT( shape ); + case DataType::KIND_REAL32: + return new ArrayT( shape ); + case DataType::KIND_INT32: + return new ArrayT( shape ); + case DataType::KIND_INT64: + return new ArrayT( shape ); + case DataType::KIND_UINT64: + return new ArrayT( shape ); + default: { + std::stringstream err; + err << "data kind " << datatype.kind() << " not recognised."; + throw eckit::BadParameter( err.str(), Here() ); + } } - } - return 0; + return 0; } -template ArrayT::ArrayT(ArrayDataStore* ds, const ArraySpec& spec) { - data_store_ = std::unique_ptr(ds); - spec_ = spec; +template +ArrayT::ArrayT( ArrayDataStore* ds, const ArraySpec& spec ) { + data_store_ = std::unique_ptr( ds ); + spec_ = spec; } -template ArrayT::ArrayT(size_t dim0) { - spec_ = ArraySpec(make_shape(dim0)); - data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); +template +ArrayT::ArrayT( size_t dim0 ) { + spec_ = ArraySpec( make_shape( dim0 ) ); + data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); } -template ArrayT::ArrayT(size_t dim0, size_t dim1) { - spec_ = ArraySpec(make_shape(dim0,dim1)); - data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); +template +ArrayT::ArrayT( size_t dim0, size_t dim1 ) { + spec_ = ArraySpec( make_shape( dim0, dim1 ) ); + data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); } -template ArrayT::ArrayT(size_t dim0, size_t dim1, size_t dim2) { - spec_ = ArraySpec(make_shape(dim0,dim1,dim2)); - data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); +template +ArrayT::ArrayT( size_t dim0, size_t dim1, size_t dim2 ) { + spec_ = ArraySpec( make_shape( dim0, dim1, dim2 ) ); + data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); } -template ArrayT::ArrayT(size_t dim0, size_t dim1, size_t dim2, size_t dim3) { - spec_ = ArraySpec(make_shape(dim0,dim1,dim2,dim3)); - data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); +template +ArrayT::ArrayT( size_t dim0, size_t dim1, size_t dim2, size_t dim3 ) { + spec_ = ArraySpec( make_shape( dim0, dim1, dim2, dim3 ) ); + data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); } -template ArrayT::ArrayT(size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4) { - spec_ = ArraySpec(make_shape(dim0,dim1,dim2,dim3,dim4)); - data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); +template +ArrayT::ArrayT( size_t dim0, size_t dim1, size_t dim2, size_t dim3, size_t dim4 ) { + spec_ = ArraySpec( make_shape( dim0, dim1, dim2, dim3, dim4 ) ); + data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); } -template ArrayT::ArrayT(const ArrayShape& shape) { - ASSERT(shape.size()>0); - size_t size = 1; - for( size_t j=0; j( new native::DataStore( size ) ); - spec_ = ArraySpec(shape); +template +ArrayT::ArrayT( const ArrayShape& shape ) { + ASSERT( shape.size() > 0 ); + size_t size = 1; + for ( size_t j = 0; j < shape.size(); ++j ) + size *= shape[j]; + data_store_ = std::unique_ptr( new native::DataStore( size ) ); + spec_ = ArraySpec( shape ); } -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 +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 ) + ASSERT( spec_.layout()[j] == layout[j] ); } -template ArrayT::ArrayT(const ArraySpec& spec) { - if( not spec.contiguous() ) NOTIMP; - spec_ = spec; - data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); +template +ArrayT::ArrayT( const ArraySpec& spec ) { + if ( not spec.contiguous() ) NOTIMP; + spec_ = spec; + data_store_ = std::unique_ptr( new native::DataStore( spec_.size() ) ); } +template +void ArrayT::resize( const ArrayShape& _shape ) { + if ( rank() != _shape.size() ) { + std::stringstream msg; + msg << "Cannot resize existing Array with rank " << rank() << " with a shape of rank " << _shape.size(); + throw eckit::BadParameter( msg.str(), Here() ); + } + for ( size_t j = 0; j < rank(); ++j ) { + if ( _shape[j] < shape( j ) ) { + std::stringstream msg; + msg << "Cannot resize existing array by shrinking dimension " << j << " from " << shape( j ) << " to " + << _shape[j]; + throw eckit::BadParameter( msg.str(), Here() ); + } + } + Array* resized = Array::create( _shape ); + + switch ( rank() ) { + case 1: + array_initializer<1>::apply( *this, *resized ); + break; + case 2: + array_initializer<2>::apply( *this, *resized ); + break; + case 3: + array_initializer<3>::apply( *this, *resized ); + break; + case 4: + array_initializer<4>::apply( *this, *resized ); + break; + case 5: + array_initializer<5>::apply( *this, *resized ); + break; + case 6: + array_initializer<6>::apply( *this, *resized ); + break; + case 7: + array_initializer<7>::apply( *this, *resized ); + break; + case 8: + array_initializer<8>::apply( *this, *resized ); + break; + case 9: + array_initializer<9>::apply( *this, *resized ); + break; + default: + NOTIMP; + } + replace( *resized ); + delete resized; +} - -template< typename Value > -void ArrayT::resize( const ArrayShape& _shape ) -{ - if( rank() != _shape.size() ) { - std::stringstream msg; - msg << "Cannot resize existing Array with rank " << rank() << " with a shape of rank " << _shape.size(); - throw eckit::BadParameter(msg.str(),Here()); - } - for( size_t j=0; j +void ArrayT::insert( size_t idx1, size_t size1 ) { + ArrayShape nshape = shape(); + if ( idx1 > nshape[0] ) { + throw eckit::BadParameter( "Cannot insert into an array at a position beyond its size", Here() ); } - } - - Array* resized = Array::create(_shape); - - switch( rank() ) { - case 1: array_initializer<1>::apply( *this, *resized ); break; - case 2: array_initializer<2>::apply( *this, *resized ); break; - case 3: array_initializer<3>::apply( *this, *resized ); break; - case 4: array_initializer<4>::apply( *this, *resized ); break; - case 5: array_initializer<5>::apply( *this, *resized ); break; - case 6: array_initializer<6>::apply( *this, *resized ); break; - case 7: array_initializer<7>::apply( *this, *resized ); break; - case 8: array_initializer<8>::apply( *this, *resized ); break; - case 9: array_initializer<9>::apply( *this, *resized ); break; - default: NOTIMP; - } - - replace(*resized); - delete resized; + nshape[0] += size1; + + Array* resized = Array::create( nshape ); + + array_initializer_partitioned<0>::apply( *this, *resized, idx1, size1 ); + replace( *resized ); + delete resized; +} + +template +void ArrayT::resize( size_t size1 ) { + resize( make_shape( size1 ) ); } -template< typename Value > -void ArrayT::insert(size_t idx1, size_t size1) -{ - ArrayShape nshape = shape(); - if(idx1 > nshape[0]) { - throw eckit::BadParameter("Cannot insert into an array at a position beyond its size", Here()); - } - nshape[0] += size1; +template +void ArrayT::resize( size_t size1, size_t size2 ) { + resize( make_shape( size1, size2 ) ); +} + +template +void ArrayT::resize( size_t size1, size_t size2, size_t size3 ) { + resize( make_shape( size1, size2, size3 ) ); +} - Array* resized = Array::create(nshape); +template +void ArrayT::resize( size_t size1, size_t size2, size_t size3, size_t size4 ) { + resize( make_shape( size1, size2, size3, size4 ) ); +} - array_initializer_partitioned<0>::apply( *this, *resized, idx1, size1); - replace(*resized); - delete resized; +template +void ArrayT::resize( size_t size1, size_t size2, size_t size3, size_t size4, size_t size5 ) { + resize( make_shape( size1, size2, size3, size4, size5 ) ); } -template< typename Value > -void ArrayT::resize(size_t size1) { resize( make_shape(size1) ); } - -template< typename Value > -void ArrayT::resize(size_t size1, size_t size2) { resize( make_shape(size1,size2) ); } - -template< typename Value > -void ArrayT::resize(size_t size1, size_t size2, size_t size3) { resize( make_shape(size1,size2,size3) ); } - -template< typename Value > -void ArrayT::resize(size_t size1, size_t size2, size_t size3, size_t size4) { resize( make_shape(size1,size2,size3,size4) ); } - -template< typename Value > -void ArrayT::resize(size_t size1, size_t size2, size_t size3, size_t size4, size_t size5) { resize( make_shape(size1,size2,size3,size4,size5) ); } - -template< typename Value > -void ArrayT::dump(std::ostream& out) const { - switch( rank() ) { - case 1: make_host_view(*this).dump(out); break; - case 2: make_host_view(*this).dump(out); break; - case 3: make_host_view(*this).dump(out); break; - case 4: make_host_view(*this).dump(out); break; - case 5: make_host_view(*this).dump(out); break; - case 6: make_host_view(*this).dump(out); break; - case 7: make_host_view(*this).dump(out); break; - case 8: make_host_view(*this).dump(out); break; - case 9: make_host_view(*this).dump(out); break; - default: NOTIMP; - } +template +void ArrayT::dump( std::ostream& out ) const { + switch ( rank() ) { + case 1: + make_host_view( *this ).dump( out ); + break; + case 2: + make_host_view( *this ).dump( out ); + break; + case 3: + make_host_view( *this ).dump( out ); + break; + case 4: + make_host_view( *this ).dump( out ); + break; + case 5: + make_host_view( *this ).dump( out ); + break; + case 6: + make_host_view( *this ).dump( out ); + break; + case 7: + make_host_view( *this ).dump( out ); + break; + case 8: + make_host_view( *this ).dump( out ); + break; + case 9: + make_host_view( *this ).dump( out ); + break; + default: + NOTIMP; + } } //------------------------------------------------------------------------------ template size_t ArrayT::footprint() const { - size_t size = sizeof(*this); - size += bytes(); - if( not contiguous() ) NOTIMP; - return size; + size_t size = sizeof( *this ); + size += bytes(); + if ( not contiguous() ) NOTIMP; + return size; } template bool ArrayT::accMap() const { - return false; + return false; } //------------------------------------------------------------------------------ -template Array* Array::create(size_t); -template Array* Array::create(size_t); -template Array* Array::create(size_t); -template Array* Array::create(size_t); -template Array* Array::create(size_t); - -template Array* Array::create(size_t,size_t); -template Array* Array::create(size_t,size_t); -template Array* Array::create(size_t,size_t); -template Array* Array::create(size_t,size_t); -template Array* Array::create(size_t,size_t); - -template Array* Array::create(size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t); - -template Array* Array::create(size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t); - -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); -template Array* Array::create(size_t,size_t,size_t,size_t,size_t); - -template Array* Array::create(const ArrayShape&); -template Array* Array::create(const ArrayShape&); -template Array* Array::create(const ArrayShape&); -template Array* Array::create(const ArrayShape&); -template Array* Array::create(const ArrayShape&); - -template Array* Array::create(const ArrayShape&, const ArrayLayout&); -template Array* Array::create(const ArrayShape&, const ArrayLayout&); -template Array* Array::create(const ArrayShape&, const ArrayLayout&); -template Array* Array::create(const ArrayShape&, const ArrayLayout&); -template Array* Array::create(const ArrayShape&, const ArrayLayout&); - -template Array* Array::wrap(int*, const ArrayShape&); -template Array* Array::wrap(long*, const ArrayShape&); -template Array* Array::wrap(float*, const ArrayShape&); -template Array* Array::wrap(double*, const ArrayShape&); -template Array* Array::wrap(long unsigned*, const ArrayShape&); - -template Array* Array::wrap(int*, const ArraySpec&); -template Array* Array::wrap(long*, const ArraySpec&); -template Array* Array::wrap(float*, const ArraySpec&); -template Array* Array::wrap(double*, const ArraySpec&); -template Array* Array::wrap(long unsigned*, const ArraySpec&); +template Array* Array::create( size_t ); +template Array* Array::create( size_t ); +template Array* Array::create( size_t ); +template Array* Array::create( size_t ); +template Array* Array::create( size_t ); + +template Array* Array::create( size_t, size_t ); +template Array* Array::create( size_t, size_t ); +template Array* Array::create( size_t, size_t ); +template Array* Array::create( size_t, size_t ); +template Array* Array::create( size_t, size_t ); + +template Array* Array::create( size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t ); + +template Array* Array::create( size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t ); + +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); +template Array* Array::create( size_t, size_t, size_t, size_t, size_t ); + +template Array* Array::create( const ArrayShape& ); +template Array* Array::create( const ArrayShape& ); +template Array* Array::create( const ArrayShape& ); +template Array* Array::create( const ArrayShape& ); +template Array* Array::create( const ArrayShape& ); + +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); +template Array* Array::create( const ArrayShape&, const ArrayLayout& ); + +template Array* Array::wrap( int*, const ArrayShape& ); +template Array* Array::wrap( long*, const ArrayShape& ); +template Array* Array::wrap( float*, const ArrayShape& ); +template Array* Array::wrap( double*, const ArrayShape& ); +template Array* Array::wrap( long unsigned*, const ArrayShape& ); + +template Array* Array::wrap( int*, const ArraySpec& ); +template Array* Array::wrap( long*, const ArraySpec& ); +template Array* Array::wrap( float*, const ArraySpec& ); +template Array* Array::wrap( double*, const ArraySpec& ); +template Array* Array::wrap( long unsigned*, const ArraySpec& ); template class ArrayT; template class ArrayT; @@ -270,5 +335,5 @@ template class ArrayT; template class ArrayT; template class ArrayT; -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/native/NativeArrayView.cc b/src/atlas/array/native/NativeArrayView.cc index 3df23c548..ef006e800 100644 --- a/src/atlas/array/native/NativeArrayView.cc +++ b/src/atlas/array/native/NativeArrayView.cc @@ -4,15 +4,16 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include -#include "eckit/exception/Exceptions.h" #include "atlas/array/ArrayView.h" #include "atlas/array/helpers/ArrayAssigner.h" #include "atlas/array/helpers/ArrayWriter.h" +#include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------------------------------ @@ -22,60 +23,59 @@ namespace array { //------------------------------------------------------------------------------------------------------ template -void ArrayView::assign(const value_type& value) { - helpers::array_assigner::apply(*this,value); +void ArrayView::assign( const value_type& value ) { + helpers::array_assigner::apply( *this, value ); } //------------------------------------------------------------------------------------------------------ template -void ArrayView::assign(const std::initializer_list& list) { - helpers::array_assigner::apply(*this,list); +void ArrayView::assign( const std::initializer_list& list ) { + helpers::array_assigner::apply( *this, list ); } //------------------------------------------------------------------------------------------------------ template -void ArrayView::dump(std::ostream& os) const { - os << "size: " << size() << " , values: "; - os << "[ "; - helpers::array_writer::apply(*this,os); - os << " ]"; +void ArrayView::dump( std::ostream& os ) const { + os << "size: " << size() << " , values: "; + os << "[ "; + helpers::array_writer::apply( *this, os ); + os << " ]"; } //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas - +} // namespace array +} // namespace atlas //----------------------------------------------------------------------- // Explicit instantiation namespace atlas { namespace array { -#define EXPLICIT_TEMPLATE_INSTANTIATION(Rank) \ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ -template class ArrayView;\ +#define EXPLICIT_TEMPLATE_INSTANTIATION( Rank ) \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; \ + template class ArrayView; // For each NDims in [1..9] -EXPLICIT_TEMPLATE_INSTANTIATION(1) -EXPLICIT_TEMPLATE_INSTANTIATION(2) -EXPLICIT_TEMPLATE_INSTANTIATION(3) -EXPLICIT_TEMPLATE_INSTANTIATION(4) -EXPLICIT_TEMPLATE_INSTANTIATION(5) -EXPLICIT_TEMPLATE_INSTANTIATION(6) -EXPLICIT_TEMPLATE_INSTANTIATION(7) -EXPLICIT_TEMPLATE_INSTANTIATION(8) -EXPLICIT_TEMPLATE_INSTANTIATION(9) +EXPLICIT_TEMPLATE_INSTANTIATION( 1 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 2 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 3 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 4 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 5 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 6 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 7 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 8 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 9 ) #undef EXPLICIT_TEMPLATE_INSTANTIATION } -} +} // namespace atlas diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 0b821247d..41fae7c28 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -4,17 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @file ArrayView.h -/// This file contains the ArrayView class, a class that allows to wrap any contiguous raw data into +/// This file contains the ArrayView class, a class that allows to wrap any +/// contiguous raw data into /// a view which is accessible with multiple indices. /// All it needs is the strides for each index, and the shape of each index. /// ATTENTION: The last index is stride 1 /// -/// Bounds-checking can be turned ON by defining "ATLAS_ARRAYVIEW_BOUNDS_CHECKING" +/// Bounds-checking can be turned ON by defining +/// "ATLAS_ARRAYVIEW_BOUNDS_CHECKING" /// before including this header. /// /// Example 1: @@ -47,17 +50,16 @@ #pragma once - -#include -#include #include +#include #include -#include "atlas/library/config.h" +#include #include "atlas/array/ArrayUtil.h" +#include "atlas/array/ArrayViewDefs.h" +#include "atlas/array/LocalView.h" #include "atlas/array/Range.h" #include "atlas/array/helpers/ArraySlicer.h" -#include "atlas/array/LocalView.h" -#include "atlas/array/ArrayViewDefs.h" +#include "atlas/library/config.h" //------------------------------------------------------------------------------------------------------ @@ -66,72 +68,74 @@ namespace array { //------------------------------------------------------------------------------------------------------ -template class ArrayView { +template +class ArrayView { public: - -// -- Type definitions + // -- Type definitions using value_type = typename remove_const::type; - using return_type = typename std::conditional< (AccessMode == Intent::ReadWrite), value_type, value_type const>::type; + using return_type = + typename std::conditional<( AccessMode == Intent::ReadWrite ), value_type, value_type const>::type; static constexpr Intent ACCESS{AccessMode}; static constexpr int RANK{Rank}; private: - using slicer_t = typename helpers::ArraySlicer< ArrayView >; - using const_slicer_t = typename helpers::ArraySlicer< const ArrayView >; + using slicer_t = typename helpers::ArraySlicer>; + using const_slicer_t = typename helpers::ArraySlicer>; - template< typename ...Args > + template struct slice_t { - using type = typename slicer_t::template Slice::type; + using type = typename slicer_t::template Slice::type; }; - template< typename ...Args > + template struct const_slice_t { - using type = typename const_slicer_t::template Slice::type; + using type = typename const_slicer_t::template Slice::type; }; public: - - // -- Constructors + // -- Constructors ArrayView( const ArrayView& other ) : data_( other.data_ ), size_( other.size_ ), - shape_(other.shape_), - strides_(other.strides_) { - } + shape_( other.shape_ ), + strides_( other.strides_ ) {} ArrayView( const value_type* data, const ArrayShape& shape, const ArrayStrides& strides ) : - data_(const_cast(data)) { + data_( const_cast( data ) ) { size_ = 1; - for( int j=0; j - return_type& operator()(Idx... idx) { - check_bounds(idx...); - return data_[index(idx...)]; + template + return_type& operator()( Idx... idx ) { + check_bounds( idx... ); + return data_[index( idx... )]; } - template < typename... Ints > - const value_type& operator()(Ints... idx) const { - - return data_[index(idx...)]; + template + const value_type& operator()( Ints... idx ) const { + return data_[index( idx... )]; } - template - size_t shape() const { return shape(Dim);} + template + size_t shape() const { + return shape( Dim ); + } - template - size_t stride() const { return stride(Dim); } + template + size_t stride() const { + return stride( Dim ); + } - size_t size() const { return size_;} + size_t size() const { return size_; } static constexpr size_t rank() { return Rank; } @@ -139,95 +143,91 @@ template class const size_t* shape() const { return shape_.data(); } - size_t shape(size_t idx) const { return shape_[idx]; } + size_t shape( size_t idx ) const { return shape_[idx]; } - size_t stride(size_t idx) const { return strides_[idx]; } + size_t stride( size_t idx ) const { return strides_[idx]; } value_type const* data() const { return data_; } - value_type* data() { return data_; } + value_type* data() { return data_; } bool valid() const { return true; } - bool contiguous() const { return (size_ == shape_[0]*strides_[0] ? true : false); } + bool contiguous() const { return ( size_ == shape_[0] * strides_[0] ? true : false ); } - void assign(const value_type& value); + void assign( const value_type& value ); - void assign(const std::initializer_list& list); + void assign( const std::initializer_list& list ); - void dump(std::ostream& os) const; + void dump( std::ostream& os ) const; - template< typename ...Args > - typename slice_t::type slice(Args... args) { - return slicer_t(*this).apply(args...); + template + typename slice_t::type slice( Args... args ) { + return slicer_t( *this ).apply( args... ); } - template< typename ...Args > - typename const_slice_t::type slice(Args... args) const { - return const_slicer_t(*this).apply(args...); + template + typename const_slice_t::type slice( Args... args ) const { + return const_slicer_t( *this ).apply( args... ); } - private: + // -- Private methods -// -- Private methods - - template < int Dim, typename Int, typename... Ints > - constexpr int index_part(Int idx, Ints... next_idx) const { - return idx*strides_[Dim] + index_part( next_idx... ); + template + constexpr int index_part( Int idx, Ints... next_idx ) const { + return idx * strides_[Dim] + index_part( next_idx... ); } - template < int Dim, typename Int > - constexpr int index_part(Int last_idx) const { - return last_idx*strides_[Dim]; + template + constexpr int index_part( Int last_idx ) const { + return last_idx * strides_[Dim]; } - template < typename... Ints > - constexpr int index(Ints... idx) const { - return index_part<0>(idx...); + template + constexpr int index( Ints... idx ) const { + return index_part<0>( idx... ); } #ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING - template < typename... Ints > - void check_bounds(Ints... idx) const { - static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); - return check_bounds_part<0>(idx...); + template + void check_bounds( Ints... idx ) const { + static_assert( sizeof...( idx ) == Rank, "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>( idx... ); } #else - template < typename... Ints > - void check_bounds(Ints...) const {} + template + void check_bounds( Ints... ) const {} #endif - template < typename... Ints > - void check_bounds_force(Ints... idx) const { - static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); - return check_bounds_part<0>(idx...); + template + void check_bounds_force( Ints... idx ) const { + static_assert( sizeof...( idx ) == Rank, "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>( idx... ); } - template < int Dim, typename Int, typename... Ints > - void check_bounds_part(Int idx, Ints... next_idx) const { - if( size_t(idx) >= shape_[Dim] ) { - throw_OutOfRange( "ArrayView", array_dim(), idx, shape_[Dim] ); - } - check_bounds_part( next_idx... ); + template + void check_bounds_part( Int idx, Ints... next_idx ) const { + if ( size_t( idx ) >= shape_[Dim] ) { throw_OutOfRange( "ArrayView", array_dim(), idx, shape_[Dim] ); } + check_bounds_part( next_idx... ); } - template < int Dim, typename Int > - void check_bounds_part(Int last_idx) const { - if( size_t(last_idx) >= shape_[Dim] ) { + template + void check_bounds_part( Int last_idx ) const { + if ( size_t( last_idx ) >= shape_[Dim] ) { throw_OutOfRange( "ArrayView", array_dim(), last_idx, shape_[Dim] ); } } -// -- Private data + // -- Private data - value_type *data_; - size_t size_; - std::array shape_; - std::array strides_; + value_type* data_; + size_t size_; + std::array shape_; + std::array strides_; }; //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/native/NativeDataStore.h b/src/atlas/array/native/NativeDataStore.h index b430dadd6..3e9599b59 100644 --- a/src/atlas/array/native/NativeDataStore.h +++ b/src/atlas/array/native/NativeDataStore.h @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "atlas/library/config.h" #include "atlas/array/ArrayUtil.h" +#include "atlas/library/config.h" //------------------------------------------------------------------------------ @@ -19,52 +20,32 @@ namespace atlas { namespace array { namespace native { -template +template class DataStore : public ArrayDataStore { public: + DataStore( size_t size ) : data_store_( size ) {} - DataStore(size_t size) : - data_store_(size) { - } - - void cloneToDevice() const { - } + void cloneToDevice() const {} - void cloneFromDevice() const { - } + void cloneFromDevice() const {} - bool valid() const { - return true; - } + bool valid() const { return true; } - void syncHostDevice() const { - } + void syncHostDevice() const {} - bool hostNeedsUpdate() const { - return false; - } + bool hostNeedsUpdate() const { return false; } - bool deviceNeedsUpdate() const { - return false; - } + bool deviceNeedsUpdate() const { return false; } - void reactivateDeviceWriteViews() const { - } + void reactivateDeviceWriteViews() const {} - void reactivateHostWriteViews() const { - } + void reactivateHostWriteViews() const {} - void* voidDataStore() { - return static_cast( &data_store_.front() ); - } + void* voidDataStore() { return static_cast( &data_store_.front() ); } - void* voidHostData() { - return static_cast( &data_store_.front() ); - } + void* voidHostData() { return static_cast( &data_store_.front() ); } - void* voidDeviceData() { - return static_cast( &data_store_.front() ); - } + void* voidDeviceData() { return static_cast( &data_store_.front() ); } private: std::vector data_store_; @@ -72,58 +53,37 @@ class DataStore : public ArrayDataStore { //------------------------------------------------------------------------------ -template +template class WrappedDataStore : public ArrayDataStore { public: + WrappedDataStore( Value* data_store ) : data_store_( data_store ) {} - WrappedDataStore(Value* data_store) : - data_store_(data_store) { - } + void cloneToDevice() const {} - void cloneToDevice() const { - } + void cloneFromDevice() const {} - void cloneFromDevice() const { - } + bool valid() const { return true; } - bool valid() const { - return true; - } + void syncHostDevice() const {} - void syncHostDevice() const { - } + bool hostNeedsUpdate() const { return true; } - bool hostNeedsUpdate() const { - return true; - } + bool deviceNeedsUpdate() const { return false; } - bool deviceNeedsUpdate() const { - return false; - } + void reactivateDeviceWriteViews() const {} - void reactivateDeviceWriteViews() const { - } + void reactivateHostWriteViews() const {} - void reactivateHostWriteViews() const { - } + void* voidDataStore() { return static_cast( data_store_ ); } - void* voidDataStore() { - return static_cast( data_store_ ); - } + void* voidHostData() { return static_cast( data_store_ ); } - void* voidHostData() { - return static_cast( data_store_ ); - } - - void* voidDeviceData() { - return static_cast( data_store_ ); - } + void* voidDeviceData() { return static_cast( data_store_ ); } private: Value* data_store_; }; -} // namespace native -} // namespace array -} // namespace atlas - +} // namespace native +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/native/NativeIndexView.cc b/src/atlas/array/native/NativeIndexView.cc index 3a0b090e4..dc2c642ea 100644 --- a/src/atlas/array/native/NativeIndexView.cc +++ b/src/atlas/array/native/NativeIndexView.cc @@ -4,12 +4,13 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include "atlas/array/native/NativeIndexView.h" +#include //------------------------------------------------------------------------------------------------------ @@ -19,29 +20,27 @@ namespace array { //------------------------------------------------------------------------------------------------------ template -IndexView::IndexView( Value* data, const size_t shape[1] ) : - data_( const_cast(data) ) { - strides_[0]=1; - shape_[0]=shape[0]; +IndexView::IndexView( Value* data, const size_t shape[1] ) : data_( const_cast( data ) ) { + strides_[0] = 1; + shape_[0] = shape[0]; } template -void IndexView::dump(std::ostream& os) const -{ - os << "size: " << size() << " , values: "; - os << "[ "; - for( size_t j=0; j::dump( std::ostream& os ) const { + os << "size: " << size() << " , values: "; + os << "[ "; + for ( size_t j = 0; j < size(); ++j ) + os << ( *this )( j ) << " "; + os << "]" << std::endl; } //------------------------------------------------------------------------------------------------------ // Explicit template instatiation -template class IndexView; -template class IndexView; +template class IndexView; +template class IndexView; //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/native/NativeIndexView.h b/src/atlas/array/native/NativeIndexView.h index bf97cf3a6..7bead54d7 100644 --- a/src/atlas/array/native/NativeIndexView.h +++ b/src/atlas/array/native/NativeIndexView.h @@ -4,18 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @file IndexView.h -/// This file contains the IndexView class, a class that allows to wrap any contiguous raw data into +/// This file contains the IndexView class, a class that allows to wrap any +/// contiguous raw data into /// a view which is accessible with multiple indices. -/// This view is intended to work with Connectivity Tables storing Fortran Numbering internally +/// This view is intended to work with Connectivity Tables storing Fortran +/// Numbering internally /// All it needs is the strides for each index, and the shape of each index. /// ATTENTION: The last index is stride 1 /// -/// Bounds-checking can be turned ON by defining "ATLAS_INDEXVIEW_BOUNDS_CHECKING" +/// Bounds-checking can be turned ON by defining +/// "ATLAS_INDEXVIEW_BOUNDS_CHECKING" /// before including this header. /// /// Example: @@ -35,7 +39,6 @@ #pragma once - #include #include "atlas/array/ArrayUtil.h" #include "atlas/library/config.h" @@ -50,36 +53,53 @@ namespace array { namespace detail { // FortranIndex: // Helper class that does +1 and -1 operations on stored values -template< typename Value > -class FortranIndex -{ +template +class FortranIndex { public: - enum { BASE = 1 }; + enum + { + BASE = 1 + }; + public: - FortranIndex(Value* idx): idx_(idx) {} - void set(const Value& value) { *(idx_) = value+BASE; } - Value get() const { return *(idx_)-BASE; } - void operator=(const Value& value) { set(value); } - FortranIndex& operator=(const FortranIndex& other) { set(other.get()); return *this; } - FortranIndex& operator+(const Value& value) { *(idx_)+=value; return *this; } - FortranIndex& operator-(const Value& value) { *(idx_)-=value; return *this; } - FortranIndex& operator--() { --(*(idx_)); return *this; } - FortranIndex& operator++() { ++(*(idx_)); return *this; } - - //implicit conversion - operator Value() const { return get(); } + FortranIndex( Value* idx ) : idx_( idx ) {} + void set( const Value& value ) { *( idx_ ) = value + BASE; } + Value get() const { return *(idx_)-BASE; } + void operator =( const Value& value ) { set( value ); } + FortranIndex& operator=( const FortranIndex& other ) { + set( other.get() ); + return *this; + } + FortranIndex& operator+( const Value& value ) { + *( idx_ ) += value; + return *this; + } + FortranIndex& operator-( const Value& value ) { + *( idx_ ) -= value; + return *this; + } + FortranIndex& operator--() { + --( *( idx_ ) ); + return *this; + } + FortranIndex& operator++() { + ++( *( idx_ ) ); + return *this; + } + + // implicit conversion + operator Value() const { return get(); } private: - Value* idx_; + Value* idx_; }; -} - +} // namespace detail #ifdef ATLAS_HAVE_FORTRAN #define INDEX_REF Index #define FROM_FORTRAN -1 -#define TO_FORTRAN +1 +#define TO_FORTRAN +1 #else #define INDEX_REF * #define FROM_FORTRAN @@ -88,10 +108,9 @@ class FortranIndex //------------------------------------------------------------------------------------------------------ -template< typename Value, int Rank > +template class IndexView { public: - using value_type = typename remove_const::type; #ifdef ATLAS_HAVE_FORTRAN @@ -101,85 +120,80 @@ class IndexView { #endif public: - IndexView( Value* data, const size_t shape[Rank] ); + // -- Access methods -// -- Access methods - - template < typename... Idx > - Index operator()(Idx... idx) { - check_bounds(idx...); - return INDEX_REF(&data_[index(idx...)]); + template + Index operator()( Idx... idx ) { + check_bounds( idx... ); + return INDEX_REF( &data_[index( idx... )] ); } - template < typename... Ints > - const value_type operator()(Ints... idx) const { - return data_[index(idx...)] FROM_FORTRAN; + template + const value_type operator()( Ints... idx ) const { + return data_[index( idx... )] FROM_FORTRAN; } private: + // -- Private methods -// -- Private methods - - template < int Dim, typename Int, typename... Ints > - constexpr int index_part(Int idx, Ints... next_idx) const { - return idx*strides_[Dim] + index_part( next_idx... ); + template + constexpr int index_part( Int idx, Ints... next_idx ) const { + return idx * strides_[Dim] + index_part( next_idx... ); } - template < int Dim, typename Int > - constexpr int index_part(Int last_idx) const { - return last_idx*strides_[Dim]; + template + constexpr int index_part( Int last_idx ) const { + return last_idx * strides_[Dim]; } - template < typename... Ints > - constexpr int index(Ints... idx) const { - return index_part<0>(idx...); + template + constexpr int index( Ints... idx ) const { + return index_part<0>( idx... ); } #ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING - template < typename... Ints > - void check_bounds(Ints... idx) const { - static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); - return check_bounds_part<0>(idx...); + template + void check_bounds( Ints... idx ) const { + static_assert( sizeof...( idx ) == Rank, "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>( idx... ); } #else - template < typename... Ints > - void check_bounds(Ints...) const {} + template + void check_bounds( Ints... ) const {} #endif - template < typename... Ints > - void check_bounds_force(Ints... idx) const { - static_assert ( sizeof...(idx) == Rank , "Expected number of indices is different from rank of array" ); - return check_bounds_part<0>(idx...); + template + void check_bounds_force( Ints... idx ) const { + static_assert( sizeof...( idx ) == Rank, "Expected number of indices is different from rank of array" ); + return check_bounds_part<0>( idx... ); } - template < int Dim, typename Int, typename... Ints > - void check_bounds_part(Int idx, Ints... next_idx) const { - if( size_t(idx) >= shape_[Dim] ) { - throw_OutOfRange( "IndexView", array_dim(), idx, shape_[Dim] ); - } - check_bounds_part( next_idx... ); + template + void check_bounds_part( Int idx, Ints... next_idx ) const { + if ( size_t( idx ) >= shape_[Dim] ) { throw_OutOfRange( "IndexView", array_dim(), idx, shape_[Dim] ); } + check_bounds_part( next_idx... ); } - template < int Dim, typename Int > - void check_bounds_part(Int last_idx) const { - if( size_t(last_idx) >= shape_[Dim] ) { + template + void check_bounds_part( Int last_idx ) const { + if ( size_t( last_idx ) >= shape_[Dim] ) { throw_OutOfRange( "IndexView", array_dim(), last_idx, shape_[Dim] ); } } - size_t size() const { return shape_[0]; } + size_t size() const { return shape_[0]; } - void dump(std::ostream& os) const; + void dump( std::ostream& os ) const; private: - Value* data_; - size_t strides_[Rank]; - size_t shape_[Rank]; + Value* data_; + size_t strides_[Rank]; + size_t shape_[Rank]; }; //------------------------------------------------------------------------------------------------------ -} // namespace array -} // namespace atlas +} // namespace array +} // namespace atlas diff --git a/src/atlas/array/native/NativeMakeView.cc b/src/atlas/array/native/NativeMakeView.cc index adb990fce..80645fab0 100644 --- a/src/atlas/array/native/NativeMakeView.cc +++ b/src/atlas/array/native/NativeMakeView.cc @@ -1,134 +1,133 @@ -#include "atlas/array_fwd.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" +#include "atlas/array_fwd.h" #include "atlas/library/config.h" #include "atlas/array.h" - namespace atlas { namespace array { namespace { - template - inline static void check_metadata(const Array& array) - { - if(array.rank() != Rank ) { - std::stringstream err; - err << "Number of dimensions do not match: template argument " << Rank << " expected to be " << array.rank(); - throw eckit::BadParameter(err.str(), Here()); - } - if(array.datatype() != array::DataType::create() ) { - std::stringstream err; - err << "Data Type does not match: template argument expected to be " << array.datatype().str(); - throw eckit::BadParameter(err.str(), Here()); - } +template +inline static void check_metadata( const Array& array ) { + if ( array.rank() != Rank ) { + std::stringstream err; + err << "Number of dimensions do not match: template argument " << Rank << " expected to be " << array.rank(); + throw eckit::BadParameter( err.str(), Here() ); + } + if ( array.datatype() != array::DataType::create() ) { + std::stringstream err; + err << "Data Type does not match: template argument expected to be " << array.datatype().str(); + throw eckit::BadParameter( err.str(), Here() ); } } +} // namespace //------------------------------------------------------------------------------ template -ArrayView -make_host_view(const Array& array) { - return ArrayView((const Value*)(array.storage()),array.shape(), array.strides()); +ArrayView make_host_view( const Array& array ) { + return ArrayView( (const Value*)( array.storage() ), array.shape(), array.strides() ); } - template -ArrayView -make_device_view(const Array& array) { - return make_host_view(array); +ArrayView make_device_view( const Array& array ) { + return make_host_view( array ); } - template -IndexView -make_host_indexview(const Array& array) { - return IndexView( (Value*)(array.storage()),array.shape().data() ); +IndexView make_host_indexview( const Array& array ) { + return IndexView( (Value*)( array.storage() ), array.shape().data() ); } template -IndexView -make_indexview(const Array& array) { - check_metadata(array); - return make_host_indexview(array); +IndexView make_indexview( const Array& array ) { + check_metadata( array ); + return make_host_indexview( array ); } template -ArrayView -make_view(const Array& array) { - check_metadata(array); - return make_host_view(array); +ArrayView make_view( const Array& array ) { + check_metadata( array ); + return make_host_view( array ); } // -------------------------------------------------------------------------------------------- -} // namespace array -} // namespace atlas - +} // namespace array +} // namespace atlas //----------------------------------------------------------------------- // Explicit instantiation namespace atlas { namespace array { -#define EXPLICIT_TEMPLATE_INSTANTIATION(RANK) \ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -template ArrayView make_view(const Array&);\ -\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -template ArrayView make_host_view(const Array&);\ -\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ -template ArrayView make_device_view(const Array&);\ - -template IndexView make_indexview(const Array&);\ -template IndexView make_indexview(const Array&);\ -template IndexView make_indexview(const Array&);\ -template IndexView make_indexview(const Array&);\ - -template IndexView make_host_indexview(const Array&);\ -template IndexView make_host_indexview(const Array&);\ -template IndexView make_host_indexview(const Array&);\ -template IndexView make_host_indexview(const Array&);\ +#define EXPLICIT_TEMPLATE_INSTANTIATION( RANK ) \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( \ + const Array& ); \ + template ArrayView make_view( \ + const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + template ArrayView make_view( const Array& ); \ + \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( \ + const Array& ); \ + template ArrayView make_host_view( \ + const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( const Array& ); \ + template ArrayView make_host_view( \ + const Array& ); \ + \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( \ + const Array& ); \ + template ArrayView \ + make_device_view( const Array& ); \ + template ArrayView make_device_view( const Array& ); \ + template ArrayView make_device_view( \ + const Array& ); \ + template ArrayView make_device_view( \ + const Array& ); \ + template ArrayView make_device_view( \ + const Array& ); + +template IndexView make_indexview( const Array& ); +template IndexView make_indexview( const Array& ); +template IndexView make_indexview( const Array& ); +template IndexView make_indexview( const Array& ); + +template IndexView make_host_indexview( const Array& ); +template IndexView make_host_indexview( const Array& ); +template IndexView make_host_indexview( const Array& ); +template IndexView make_host_indexview( const Array& ); // For each Rank in [1..9] -EXPLICIT_TEMPLATE_INSTANTIATION(1) -EXPLICIT_TEMPLATE_INSTANTIATION(2) -EXPLICIT_TEMPLATE_INSTANTIATION(3) -EXPLICIT_TEMPLATE_INSTANTIATION(4) -EXPLICIT_TEMPLATE_INSTANTIATION(5) -EXPLICIT_TEMPLATE_INSTANTIATION(6) -EXPLICIT_TEMPLATE_INSTANTIATION(7) -EXPLICIT_TEMPLATE_INSTANTIATION(8) -EXPLICIT_TEMPLATE_INSTANTIATION(9) +EXPLICIT_TEMPLATE_INSTANTIATION( 1 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 2 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 3 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 4 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 5 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 6 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 7 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 8 ) +EXPLICIT_TEMPLATE_INSTANTIATION( 9 ) #undef EXPLICIT_TEMPLATE_INSTANTIATION -} // namespace array -} // namespace atlas - +} // namespace array +} // namespace atlas diff --git a/src/atlas/array_fwd.h b/src/atlas/array_fwd.h index afb5827f3..01f236e53 100644 --- a/src/atlas/array_fwd.h +++ b/src/atlas/array_fwd.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -32,24 +33,19 @@ template class IndexView; template -ArrayView -make_view(const Array& array); +ArrayView make_view( const Array& array ); template -ArrayView -make_host_view(const Array& array); +ArrayView make_host_view( const Array& array ); template -ArrayView -make_device_view(const Array& array); +ArrayView make_device_view( const Array& array ); template -IndexView -make_indexview(const Array& array); +IndexView make_indexview( const Array& array ); template -IndexView -make_host_indexview(const Array& array); +IndexView make_host_indexview( const Array& array ); class Table; @@ -59,9 +55,8 @@ class TableView; template class TableRow; -template -TableView -make_table_view(const Table& table); +template +TableView make_table_view( const Table& table ); -} -} +} // namespace array +} // namespace atlas diff --git a/src/atlas/domain.h b/src/atlas/domain.h index 580b0c0d1..9f9fa19c4 100644 --- a/src/atlas/domain.h +++ b/src/atlas/domain.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ diff --git a/src/atlas/domain/Domain.cc b/src/atlas/domain/Domain.cc index 63d42ceb7..8d46a37e4 100644 --- a/src/atlas/domain/Domain.cc +++ b/src/atlas/domain/Domain.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,52 +13,39 @@ #include "atlas/domain/detail/Domain.h" #include "atlas/domain/detail/EmptyDomain.h" +#include "atlas/domain/detail/GlobalDomain.h" #include "atlas/domain/detail/RectangularDomain.h" #include "atlas/domain/detail/ZonalBandDomain.h" -#include "atlas/domain/detail/GlobalDomain.h" using RD = atlas::domain::RectangularDomain; using ZD = atlas::domain::ZonalBandDomain; namespace atlas { -Domain::Domain(): - domain_( new domain::EmptyDomain() ) { -} +Domain::Domain() : domain_( new domain::EmptyDomain() ) {} -Domain::Domain( const Domain& domain): - domain_( domain.domain_ ) { -} +Domain::Domain( const Domain& domain ) : domain_( domain.domain_ ) {} -Domain::Domain( const Implementation* domain): - domain_( domain ) { -} +Domain::Domain( const Implementation* domain ) : domain_( domain ) {} -Domain::Domain( const eckit::Parametrisation& p ): - domain_( atlas::domain::Domain::create(p) ) { -} +Domain::Domain( const eckit::Parametrisation& p ) : domain_( atlas::domain::Domain::create( p ) ) {} RectangularDomain::RectangularDomain( const Interval& x, const Interval& y, const std::string& units ) : - 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) ) ) { -} + 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 ) ) ) {} RectangularDomain::RectangularDomain( const Domain& domain ) : - Domain(domain), - domain_( dynamic_cast(domain.get()) ) { -} + Domain( domain ), + domain_( dynamic_cast( domain.get() ) ) {} ZonalBandDomain::ZonalBandDomain( const Interval& y ) : - RectangularDomain( - ( ZD::is_global(y) ) ? new atlas::domain::GlobalDomain() : - new atlas::domain::ZonalBandDomain(y) ) { -} + RectangularDomain( ( ZD::is_global( y ) ) ? new atlas::domain::GlobalDomain() + : new atlas::domain::ZonalBandDomain( y ) ) {} ZonalBandDomain::ZonalBandDomain( const Domain& domain ) : - RectangularDomain(domain), - domain_( dynamic_cast(domain.get()) ) { -} + RectangularDomain( domain ), + domain_( dynamic_cast( domain.get() ) ) {} -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/domain/Domain.h b/src/atlas/domain/Domain.h index 4e9edb3e5..f7d785098 100644 --- a/src/atlas/domain/Domain.h +++ b/src/atlas/domain/Domain.h @@ -4,18 +4,19 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include "eckit/memory/SharedPtr.h" #include "atlas/domain/detail/Domain.h" -#include "atlas/projection/Projection.h" #include "atlas/domain/detail/RectangularDomain.h" #include "atlas/domain/detail/ZonalBandDomain.h" +#include "atlas/projection/Projection.h" +#include "eckit/memory/SharedPtr.h" //--------------------------------------------------------------------------------------------------------------------- @@ -23,7 +24,7 @@ namespace eckit { class Parametrisation; class Hash; -} +} // namespace eckit //--------------------------------------------------------------------------------------------------------------------- @@ -32,14 +33,11 @@ namespace atlas { //--------------------------------------------------------------------------------------------------------------------- class Domain { - public: - using Implementation = atlas::domain::Domain; - using Spec = atlas::domain::Domain::Spec; + using Spec = atlas::domain::Domain::Spec; public: - Domain(); Domain( const Domain& ); Domain( const Implementation* ); @@ -51,10 +49,10 @@ class Domain { std::string type() const; /// Checks if the point is contained in the domain - bool contains(double x, double y) const; + bool contains( double x, double y ) const; /// Checks if the point is contained in the domain - bool contains(const PointXY& p) const; + bool contains( const PointXY& p ) const; // Specification of Domain Spec spec() const; @@ -66,12 +64,14 @@ class Domain { bool empty() const; /// Add domain to the given hash - void hash(eckit::Hash&) const; + void hash( eckit::Hash& ) const; - /// Check if grid includes the North pole (can only be true when units are in degrees) + /// Check if grid includes the North pole (can only be true when units are in + /// degrees) bool containsNorthPole() const; - /// Check if grid includes the South pole (can only be true when units are in degrees) + /// Check if grid includes the South pole (can only be true when units are in + /// degrees) bool containsSouthPole() const; /// String that defines units of the domain ("degrees" or "meters") @@ -81,91 +81,104 @@ class Domain { const Implementation* get() const { return domain_.get(); } private: - /// Output to stream - void print(std::ostream&) const; + void print( std::ostream& ) const; - friend std::ostream& operator<<(std::ostream& s, const Domain& d); + friend std::ostream& operator<<( std::ostream& s, const Domain& d ); eckit::SharedPtr domain_; }; //--------------------------------------------------------------------------------------------------------------------- -inline std::string Domain::type() const { return domain_.get()->type(); } -inline bool Domain::contains(double x, double y) const { return domain_.get()->contains(x,y); } -inline bool Domain::contains(const PointXY& p) const { return domain_.get()->contains(p); } -inline Domain::Spec Domain::spec() const { return domain_.get()->spec(); } -inline bool Domain::global() const { return domain_.get()->global(); } -inline bool Domain::empty() const { return domain_.get()->empty(); } -inline void Domain::hash(eckit::Hash& h) const { domain_.get()->hash(h); } -inline bool Domain::containsNorthPole() const { return domain_.get()->containsNorthPole(); } -inline bool Domain::containsSouthPole() const { return domain_.get()->containsSouthPole(); } -inline void Domain::print(std::ostream& os) const { return domain_.get()->print(os); } -inline std::ostream& operator<<(std::ostream& os, const Domain& d) { - d.print(os); +inline std::string Domain::type() const { + return domain_.get()->type(); +} +inline bool Domain::contains( double x, double y ) const { + return domain_.get()->contains( x, y ); +} +inline bool Domain::contains( const PointXY& p ) const { + return domain_.get()->contains( p ); +} +inline Domain::Spec Domain::spec() const { + return domain_.get()->spec(); +} +inline bool Domain::global() const { + return domain_.get()->global(); +} +inline bool Domain::empty() const { + return domain_.get()->empty(); +} +inline void Domain::hash( eckit::Hash& h ) const { + domain_.get()->hash( h ); +} +inline bool Domain::containsNorthPole() const { + return domain_.get()->containsNorthPole(); +} +inline bool Domain::containsSouthPole() const { + return domain_.get()->containsSouthPole(); +} +inline void Domain::print( std::ostream& os ) const { + return domain_.get()->print( os ); +} +inline std::ostream& operator<<( std::ostream& os, const Domain& d ) { + d.print( os ); return os; } -inline std::string Domain::units() const { return domain_.get()->units(); } +inline std::string Domain::units() const { + return domain_.get()->units(); +} //--------------------------------------------------------------------------------------------------------------------- class RectangularDomain : public Domain { - public: - - using Interval=std::array; + using Interval = std::array; public: + using Domain::Domain; + RectangularDomain( const Interval& x, const Interval& y, const std::string& units = "degrees" ); - using Domain::Domain; - RectangularDomain( const Interval& x, const Interval& y, const std::string& units = "degrees" ); - - RectangularDomain( const Domain& ); + RectangularDomain( const Domain& ); - operator bool() { return domain_; } + operator bool() { return domain_; } - /// Checks if the x-value is contained in the domain - bool contains_x(double x) const { return domain_.get()->contains_x(x); } + /// Checks if the x-value is contained in the domain + bool contains_x( double x ) const { return domain_.get()->contains_x( x ); } - /// Checks if the y-value is contained in the domain - bool contains_y(double y) const { return domain_.get()->contains_y(y); } + /// Checks if the y-value is contained in the domain + bool contains_y( double y ) const { return domain_.get()->contains_y( y ); } - double xmin() const { return domain_.get()->xmin(); } - double xmax() const { return domain_.get()->xmax(); } - double ymin() const { return domain_.get()->ymin(); } - double ymax() const { return domain_.get()->ymax(); } + double xmin() const { return domain_.get()->xmin(); } + double xmax() const { return domain_.get()->xmax(); } + double ymin() const { return domain_.get()->ymin(); } + double ymax() const { return domain_.get()->ymax(); } private: - - eckit::SharedPtr domain_; + eckit::SharedPtr domain_; }; //--------------------------------------------------------------------------------------------------------------------- namespace domain { - class ZonalBandDomain; +class ZonalBandDomain; } class ZonalBandDomain : public RectangularDomain { - public: - - using Interval=std::array; + using Interval = std::array; public: + using RectangularDomain::RectangularDomain; + ZonalBandDomain( const Interval& y ); + ZonalBandDomain( const Domain& ); - using RectangularDomain::RectangularDomain; - ZonalBandDomain( const Interval& y ); - ZonalBandDomain( const Domain& ); - - operator bool() { return domain_; } + operator bool() { return domain_; } private: - - eckit::SharedPtr domain_; + eckit::SharedPtr domain_; }; //--------------------------------------------------------------------------------------------------------------------- -} // namespace +} // namespace atlas diff --git a/src/atlas/domain/detail/Domain.cc b/src/atlas/domain/detail/Domain.cc index 7483df045..85b8e6f2f 100644 --- a/src/atlas/domain/detail/Domain.cc +++ b/src/atlas/domain/detail/Domain.cc @@ -5,22 +5,19 @@ namespace atlas { namespace domain { -Domain *Domain::create() { - // default: global domain - util::Config projParams; - projParams.set("type","global"); - return Domain::create(projParams); +Domain* Domain::create() { + // default: global domain + util::Config projParams; + projParams.set( "type", "global" ); + return Domain::create( projParams ); } -Domain *Domain::create(const eckit::Parametrisation &p) { +Domain* Domain::create( const eckit::Parametrisation& p ) { + std::string domain_type; + if ( p.get( "type", domain_type ) ) { return eckit::Factory::instance().get( domain_type ).create( p ); } - std::string domain_type; - if (p.get("type",domain_type)) { - return eckit::Factory::instance().get(domain_type).create(p); - } - - // should return error here - throw eckit::BadParameter("type missing in Params",Here()); + // should return error here + throw eckit::BadParameter( "type missing in Params", Here() ); } } // namespace domain diff --git a/src/atlas/domain/detail/Domain.h b/src/atlas/domain/detail/Domain.h index 0c329b9c9..c579c061a 100644 --- a/src/atlas/domain/detail/Domain.h +++ b/src/atlas/domain/detail/Domain.h @@ -3,77 +3,74 @@ The Domain class describes the extent of a grid in projected "grid coordinates" daand: - - I simply removed the original Domain.h, which only described boxes in (lon,lat)-space. - - The Domain class has become a purely abstract class to allow for other domain shapes (circular, frame, and what not...) + - I simply removed the original Domain.h, which only described boxes in +(lon,lat)-space. + - The Domain class has become a purely abstract class to allow for other +domain shapes (circular, frame, and what not...) - I didn't implement hashes, (copy) constructors, comparators, etc. for now. */ #pragma once +#include "atlas/util/Config.h" +#include "atlas/util/Point.h" #include "eckit/config/Parametrisation.h" -#include "eckit/memory/Owned.h" #include "eckit/memory/Builder.h" -#include "atlas/util/Point.h" -#include "atlas/util/Config.h" +#include "eckit/memory/Owned.h" namespace atlas { - class Projection; +class Projection; namespace domain { class Domain : public eckit::Owned { - public: - using Spec = util::Config; typedef const eckit::Parametrisation& ARG1; typedef eckit::BuilderT1 builder_t; - static std::string className() {return "atlas.Domain";} + static std::string className() { return "atlas.Domain"; } public: + static Domain* create(); // Create a global domain - static Domain* create(); // Create a global domain + static Domain* create( const eckit::Parametrisation& ); - static Domain* create(const eckit::Parametrisation&); - - virtual std::string type() const=0; + virtual std::string type() const = 0; /// Checks if the point is contained in the domain - virtual bool contains(double x, double y) const =0; + virtual bool contains( double x, double y ) const = 0; - bool contains(const PointXY& p) const { - return contains(p.x(),p.y()); - } + bool contains( const PointXY& p ) const { return contains( p.x(), p.y() ); } // Specification of grid - virtual Spec spec() const =0; + virtual Spec spec() const = 0; /// Check if domain represents the complete globe surface - virtual bool global() const =0; + virtual bool global() const = 0; /// Check if domain does not represent any area on the globe surface - virtual bool empty() const =0; + virtual bool empty() const = 0; -// Unless the domain is global, we can never be sure about these functions -// without knowing also the projection + // Unless the domain is global, we can never be sure about these functions + // without knowing also the projection /// Check if grid includes the North pole - virtual bool containsNorthPole() const =0; + virtual bool containsNorthPole() const = 0; /// Check if grid includes the South pole - virtual bool containsSouthPole() const =0; + virtual bool containsSouthPole() const = 0; /// Output to stream - virtual void print(std::ostream&) const =0; + virtual void print( std::ostream& ) const = 0; - friend std::ostream& operator<<(std::ostream& s, const Domain& d) { - d.print(s); + friend std::ostream& operator<<( std::ostream& s, const Domain& d ) { + d.print( s ); return s; } - virtual std::string units() const =0; + virtual std::string units() const = 0; - virtual void hash(eckit::Hash&) const =0; + virtual void hash( eckit::Hash& ) const = 0; }; } // namespace domain diff --git a/src/atlas/domain/detail/EmptyDomain.cc b/src/atlas/domain/detail/EmptyDomain.cc index f399bb9a8..7be5bc250 100644 --- a/src/atlas/domain/detail/EmptyDomain.cc +++ b/src/atlas/domain/detail/EmptyDomain.cc @@ -1,35 +1,31 @@ #include "atlas/domain/detail/EmptyDomain.h" - namespace atlas { namespace domain { -EmptyDomain::EmptyDomain() { -} +EmptyDomain::EmptyDomain() {} -EmptyDomain::EmptyDomain(const eckit::Parametrisation& p) { -} +EmptyDomain::EmptyDomain( const eckit::Parametrisation& p ) {} EmptyDomain::Spec EmptyDomain::spec() const { - Spec domain_spec; - domain_spec.set("type",type()); - return domain_spec; + Spec domain_spec; + domain_spec.set( "type", type() ); + return domain_spec; } -void EmptyDomain::print(std::ostream& os) const { - os << "EmptyDomain"; +void EmptyDomain::print( std::ostream& os ) const { + os << "EmptyDomain"; } -void EmptyDomain::hash(eckit::Hash& h) const { - h.add(type()); +void EmptyDomain::hash( eckit::Hash& h ) const { + h.add( type() ); } std::string EmptyDomain::units() const { - NOTIMP; + NOTIMP; } -register_BuilderT1(Domain,EmptyDomain,EmptyDomain::static_type()); +register_BuilderT1( Domain, EmptyDomain, EmptyDomain::static_type() ); } // namespace domain } // namespace atlas - diff --git a/src/atlas/domain/detail/EmptyDomain.h b/src/atlas/domain/detail/EmptyDomain.h index 745f649dc..d9a5358b5 100644 --- a/src/atlas/domain/detail/EmptyDomain.h +++ b/src/atlas/domain/detail/EmptyDomain.h @@ -5,17 +5,15 @@ namespace atlas { namespace domain { -class EmptyDomain: public Domain { - +class EmptyDomain : public Domain { public: - EmptyDomain(); - EmptyDomain(const eckit::Parametrisation& p); + EmptyDomain( const eckit::Parametrisation& p ); /// Checks if the point is contained in the domain - virtual bool contains(double x, double y) const override { return false; } + virtual bool contains( double x, double y ) const override { return false; } - static std::string static_type() {return "empty";} + static std::string static_type() { return "empty"; } virtual std::string type() const override { return static_type(); } virtual bool empty() const override { return true; } @@ -23,11 +21,11 @@ class EmptyDomain: public Domain { virtual Spec spec() const override; - virtual void print(std::ostream&) const override; + virtual void print( std::ostream& ) const override; - virtual std::string units() const override; // Not implemented + virtual std::string units() const override; // Not implemented - virtual void hash(eckit::Hash&) const override; + virtual void hash( eckit::Hash& ) const override; /// Check if grid includes the North pole virtual bool containsNorthPole() const override { return false; } @@ -36,6 +34,5 @@ class EmptyDomain: public Domain { virtual bool containsSouthPole() const override { return false; } }; - } // namespace domain } // namespace atlas diff --git a/src/atlas/domain/detail/GlobalDomain.cc b/src/atlas/domain/detail/GlobalDomain.cc index 0739a4f85..cb7cb7c97 100644 --- a/src/atlas/domain/detail/GlobalDomain.cc +++ b/src/atlas/domain/detail/GlobalDomain.cc @@ -4,40 +4,32 @@ namespace atlas { namespace domain { namespace { - constexpr std::array yrange() { - return { -90., 90. }; - } +constexpr std::array yrange() { + return {-90., 90.}; } +} // namespace -GlobalDomain::GlobalDomain(const double west) : - ZonalBandDomain( yrange(), west ) { -} +GlobalDomain::GlobalDomain( const double west ) : ZonalBandDomain( yrange(), west ) {} -GlobalDomain::GlobalDomain() : - ZonalBandDomain( yrange() ) { -} +GlobalDomain::GlobalDomain() : ZonalBandDomain( yrange() ) {} -GlobalDomain::GlobalDomain(const eckit::Parametrisation& p) : - GlobalDomain() { -} +GlobalDomain::GlobalDomain( const eckit::Parametrisation& p ) : GlobalDomain() {} GlobalDomain::Spec GlobalDomain::spec() const { - Spec domain_spec; - domain_spec.set("type",type()); - return domain_spec; + Spec domain_spec; + domain_spec.set( "type", type() ); + return domain_spec; } -void GlobalDomain::hash(eckit::Hash& h) const { - h.add(type()); +void GlobalDomain::hash( eckit::Hash& h ) const { + h.add( type() ); } - -void GlobalDomain::print(std::ostream& os) const { - os << "GlobalDomain"; +void GlobalDomain::print( std::ostream& os ) const { + os << "GlobalDomain"; } -register_BuilderT1(Domain,GlobalDomain,GlobalDomain::static_type()); +register_BuilderT1( Domain, GlobalDomain, GlobalDomain::static_type() ); } // namespace domain } // namespace atlas - diff --git a/src/atlas/domain/detail/GlobalDomain.h b/src/atlas/domain/detail/GlobalDomain.h index d075593b5..1446f0b3d 100644 --- a/src/atlas/domain/detail/GlobalDomain.h +++ b/src/atlas/domain/detail/GlobalDomain.h @@ -1,33 +1,31 @@ #pragma once -#include "atlas/domain/detail/ZonalBandDomain.h" #include "atlas/domain/Domain.h" +#include "atlas/domain/detail/ZonalBandDomain.h" namespace atlas { namespace domain { -class GlobalDomain: public ZonalBandDomain { - +class GlobalDomain : public ZonalBandDomain { public: - GlobalDomain(); - GlobalDomain(const eckit::Parametrisation& p); + GlobalDomain( const eckit::Parametrisation& p ); - static std::string static_type() {return "global";} + static std::string static_type() { return "global"; } virtual std::string type() const override { return static_type(); } /// Checks if the point is contained in the domain - virtual bool contains(double x, double y) const override { return true; } + virtual bool contains( double x, double y ) const override { return true; } // Domain properties virtual bool global() const override { return true; } - virtual bool empty() const override { return false; } + virtual bool empty() const override { return false; } virtual Spec spec() const override; - virtual void print(std::ostream&) const override; + virtual void print( std::ostream& ) const override; - virtual void hash(eckit::Hash&) const override; + virtual void hash( eckit::Hash& ) const override; /// Check if grid includes the North pole virtual bool containsNorthPole() const override { return true; } @@ -36,12 +34,9 @@ class GlobalDomain: public ZonalBandDomain { virtual bool containsSouthPole() const override { return true; } private: - friend class ::atlas::RectangularDomain; - GlobalDomain(const double west); - + GlobalDomain( const double west ); }; - } // namespace domain } // namespace atlas diff --git a/src/atlas/domain/detail/RectangularDomain.cc b/src/atlas/domain/detail/RectangularDomain.cc index da3d1e48d..09e6e8eb7 100644 --- a/src/atlas/domain/detail/RectangularDomain.cc +++ b/src/atlas/domain/detail/RectangularDomain.cc @@ -1,6 +1,5 @@ -#include #include "atlas/domain/detail/RectangularDomain.h" - +#include namespace atlas { namespace domain { @@ -9,130 +8,105 @@ using Interval = RectangularDomain::Interval; namespace { - static std::array get_interval_x(const eckit::Parametrisation& params) { +static std::array get_interval_x( const eckit::Parametrisation& params ) { double xmin, xmax; - if( ! params.get("xmin",xmin) ) - throw eckit::BadParameter("xmin missing in Params",Here()); + if ( !params.get( "xmin", xmin ) ) throw eckit::BadParameter( "xmin missing in Params", Here() ); - if( ! params.get("xmax",xmax) ) - throw eckit::BadParameter("xmax missing in Params",Here()); + if ( !params.get( "xmax", xmax ) ) throw eckit::BadParameter( "xmax missing in Params", Here() ); - return {xmin,xmax}; - } + return {xmin, xmax}; +} - static std::array get_interval_y(const eckit::Parametrisation& params) { +static std::array get_interval_y( const eckit::Parametrisation& params ) { double ymin, ymax; - if( ! params.get("ymin",ymin) ) - throw eckit::BadParameter("ymin missing in Params",Here()); + if ( !params.get( "ymin", ymin ) ) throw eckit::BadParameter( "ymin missing in Params", Here() ); - if( ! params.get("ymax",ymax) ) - throw eckit::BadParameter("ymax missing in Params",Here()); + if ( !params.get( "ymax", ymax ) ) throw eckit::BadParameter( "ymax missing in Params", Here() ); - return {ymin,ymax}; - } + return {ymin, ymax}; +} - static std::string get_units(const eckit::Parametrisation& params) { +static std::string get_units( const eckit::Parametrisation& params ) { std::string units; - if( ! params.get("units",units) ) - throw eckit::BadParameter("units missing in Params",Here()); + if ( !params.get( "units", units ) ) throw eckit::BadParameter( "units missing in Params", Here() ); return units; - } - } -bool RectangularDomain::is_global( - const Interval& x, - const Interval& y, - const std::string& units ) { +} // namespace - if( units != "degrees" ) - return false; +bool RectangularDomain::is_global( const Interval& x, const Interval& y, const std::string& units ) { + if ( units != "degrees" ) return false; - const double eps = 1.e-12; - return std::abs( (x[1]-x[0]) - 360. ) < eps - && std::abs( (y[1]-y[0]) - 180. ) < eps ; + const double eps = 1.e-12; + return std::abs( ( x[1] - x[0] ) - 360. ) < eps && std::abs( ( y[1] - y[0] ) - 180. ) < eps; } -bool RectangularDomain::is_zonal_band( - const Interval& x, - const std::string& units) { +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; + const double eps = 1.e-12; + return std::abs( ( x[1] - x[0] ) - 360. ) < eps; } - -RectangularDomain::RectangularDomain(const eckit::Parametrisation& params) : - RectangularDomain( get_interval_x(params), get_interval_y(params), get_units(params) ) { -} +RectangularDomain::RectangularDomain( const eckit::Parametrisation& params ) : + RectangularDomain( get_interval_x( params ), get_interval_y( params ), get_units( params ) ) {} RectangularDomain::RectangularDomain( const Interval& x, const Interval& y, const std::string& units ) : - xmin_(x[0]), - xmax_(x[1]), - ymin_(y[0]), - ymax_(y[1]), - units_(units) { - - 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_); - global_ = is_global( {xmin_,xmax_}, {ymin_,ymax_} ,units_); - - const double tol = 1.e-6; - xmin_tol_ = xmin_-tol; - ymin_tol_ = ymin_-tol; - xmax_tol_ = xmax_+tol; - ymax_tol_ = ymax_+tol; - + xmin_( x[0] ), + xmax_( x[1] ), + ymin_( y[0] ), + ymax_( y[1] ), + units_( units ) { + 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_ ); + global_ = is_global( {xmin_, xmax_}, {ymin_, ymax_}, units_ ); + + const double tol = 1.e-6; + xmin_tol_ = xmin_ - tol; + ymin_tol_ = ymin_ - tol; + xmax_tol_ = xmax_ + tol; + ymax_tol_ = ymax_ + tol; } - -bool RectangularDomain::contains(double x, double y) const { - return contains_x(x) and contains_y(y); +bool RectangularDomain::contains( double x, double y ) const { + return contains_x( x ) and contains_y( y ); } RectangularDomain::Spec RectangularDomain::spec() const { - Spec domain_spec; - domain_spec.set("type",type()); - domain_spec.set("xmin",xmin()); - domain_spec.set("xmax",xmax()); - domain_spec.set("ymin",ymin()); - domain_spec.set("ymax",ymax()); - domain_spec.set("units",units()); - return domain_spec; + Spec domain_spec; + domain_spec.set( "type", type() ); + domain_spec.set( "xmin", xmin() ); + domain_spec.set( "xmax", xmax() ); + domain_spec.set( "ymin", ymin() ); + domain_spec.set( "ymax", ymax() ); + domain_spec.set( "units", units() ); + return domain_spec; } -void RectangularDomain::print(std::ostream& os) const { - os << "RectangularDomain[" - << "xmin=" << xmin() - << ",xmax=" << xmax() - << ",ymin=" << ymin() - << ",ymax=" << ymax() - << ",units=" << units() - << "]"; +void RectangularDomain::print( std::ostream& os ) const { + os << "RectangularDomain[" + << "xmin=" << xmin() << ",xmax=" << xmax() << ",ymin=" << ymin() << ",ymax=" << ymax() << ",units=" << units() + << "]"; } -void RectangularDomain::hash(eckit::Hash& h) const { - spec().hash(h); +void RectangularDomain::hash( eckit::Hash& h ) const { + spec().hash( h ); } bool RectangularDomain::containsNorthPole() const { - return unit_degrees_ && ymax_tol_ >= 90.; + return unit_degrees_ && ymax_tol_ >= 90.; } bool RectangularDomain::containsSouthPole() const { - return unit_degrees_ && ymin_tol_ <= -90.; + return unit_degrees_ && ymin_tol_ <= -90.; } -register_BuilderT1(Domain,RectangularDomain,RectangularDomain::static_type()); +register_BuilderT1( Domain, RectangularDomain, RectangularDomain::static_type() ); } // namespace domain } // namespace atlas - diff --git a/src/atlas/domain/detail/RectangularDomain.h b/src/atlas/domain/detail/RectangularDomain.h index 574cb8b0f..85e45a857 100644 --- a/src/atlas/domain/detail/RectangularDomain.h +++ b/src/atlas/domain/detail/RectangularDomain.h @@ -1,40 +1,36 @@ #pragma once -#include #include +#include #include "atlas/domain/detail/Domain.h" namespace atlas { namespace domain { -class RectangularDomain: public Domain { - +class RectangularDomain : public Domain { public: - - using Interval = std::array; + using Interval = std::array; public: - -static bool is_global( const Interval& x, const Interval& y, const std::string& units = "degrees" ); -static bool is_zonal_band( const Interval& x, const std::string& units = "degrees" ); + static bool is_global( const Interval& x, const Interval& y, const std::string& units = "degrees" ); + static bool is_zonal_band( const Interval& x, const std::string& units = "degrees" ); public: - - // constructor + // constructor RectangularDomain( const eckit::Parametrisation& ); RectangularDomain( const Interval& x, const Interval& y, const std::string& units ); - static std::string static_type() {return "rectangular";} + static std::string static_type() { return "rectangular"; } virtual std::string type() const override { return static_type(); } /// Checks if the point is contained in the domain - virtual bool contains(double x, double y) const override; + virtual bool contains( double x, double y ) const override; /// Checks if the x-value is contained in the domain - bool contains_x(double x) const { return ( xmin_tol_ <= x && x <= xmax_tol_ ); } + bool contains_x( double x ) const { return ( xmin_tol_ <= x && x <= xmax_tol_ ); } /// Checks if the y-value is contained in the domain - bool contains_y(double y) const { return ( ymin_tol_ <= y && y <= ymax_tol_ ); } + bool contains_y( double y ) const { return ( ymin_tol_ <= y && y <= ymax_tol_ ); } /// Check if grid includes the North pole virtual bool containsNorthPole() const override; @@ -43,13 +39,13 @@ static bool is_zonal_band( const Interval& x, const std::string& units = "degree virtual bool containsSouthPole() const override; virtual bool global() const override { return global_; } - virtual bool empty() const override { return (xmin_ == xmax_) or (ymin_ == ymax_); } + virtual bool empty() const override { return ( xmin_ == xmax_ ) or ( ymin_ == ymax_ ); } virtual Spec spec() const override; - virtual void print(std::ostream&) const override; + virtual void print( std::ostream& ) const override; - virtual void hash(eckit::Hash&) const override; + virtual void hash( eckit::Hash& ) const override; virtual std::string units() const override { return units_; } @@ -59,13 +55,11 @@ static bool is_zonal_band( const Interval& x, const std::string& units = "degree double ymax() const { return ymax_; } private: - double xmin_, xmax_, ymin_, ymax_; double xmin_tol_, xmax_tol_, ymin_tol_, ymax_tol_; bool global_; std::string units_; bool unit_degrees_; - }; } // namespace domain diff --git a/src/atlas/domain/detail/ZonalBandDomain.cc b/src/atlas/domain/detail/ZonalBandDomain.cc index 201fb54e5..0f9d57eb1 100644 --- a/src/atlas/domain/detail/ZonalBandDomain.cc +++ b/src/atlas/domain/detail/ZonalBandDomain.cc @@ -1,92 +1,79 @@ #include "atlas/domain/detail/ZonalBandDomain.h" - namespace atlas { namespace domain { namespace { - static bool _is_global(double ymin, double ymax) { +static bool _is_global( double ymin, double ymax ) { const double eps = 1.e-12; - return std::abs( (ymax-ymin) - 180. ) < eps ; - } + return std::abs( ( ymax - ymin ) - 180. ) < eps; +} - static std::array get_interval_y(const eckit::Parametrisation& params) { +static std::array get_interval_y( const eckit::Parametrisation& params ) { double ymin, ymax; - if( ! params.get("ymin",ymin) ) - throw eckit::BadParameter("ymin missing in Params",Here()); + if ( !params.get( "ymin", ymin ) ) throw eckit::BadParameter( "ymin missing in Params", Here() ); - if( ! params.get("ymax",ymax) ) - throw eckit::BadParameter("ymax missing in Params",Here()); + if ( !params.get( "ymax", ymax ) ) throw eckit::BadParameter( "ymax missing in Params", Here() ); - return {ymin,ymax}; - } + return {ymin, ymax}; +} - constexpr std::array interval_x() { - return { 0., 360. }; - } +constexpr std::array interval_x() { + return {0., 360.}; } +} // namespace constexpr char ZonalBandDomain::units_[]; -bool ZonalBandDomain::is_global( - const Interval& y ) { - const double eps = 1.e-12; - return std::abs( std::abs(y[1]-y[0]) - 180. ) < eps ; +bool ZonalBandDomain::is_global( const Interval& y ) { + const double eps = 1.e-12; + return std::abs( std::abs( y[1] - y[0] ) - 180. ) < eps; } +ZonalBandDomain::ZonalBandDomain( const eckit::Parametrisation& params ) : + ZonalBandDomain( get_interval_y( params ) ) {} -ZonalBandDomain::ZonalBandDomain(const eckit::Parametrisation& params) : - ZonalBandDomain( get_interval_y(params) ) { -} - -ZonalBandDomain::ZonalBandDomain( const Interval& interval_y ) : - ZonalBandDomain( interval_y, /*west*/ 0. ) { -} +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_ ) { - global_ = _is_global(ymin(),ymax()); - ymin_tol_ = ymin()-1.e-6; - ymax_tol_ = ymax()+1.e-6; + RectangularDomain( {west, west + 360.}, interval_y, units_ ) { + global_ = _is_global( ymin(), ymax() ); + ymin_tol_ = ymin() - 1.e-6; + ymax_tol_ = ymax() + 1.e-6; } - -bool ZonalBandDomain::contains(double x, double y) const { - return contains_y(y); +bool ZonalBandDomain::contains( double x, double y ) const { + return contains_y( y ); } ZonalBandDomain::Spec ZonalBandDomain::spec() const { - Spec domain_spec; - domain_spec.set("type",type()); - domain_spec.set("ymin",ymin()); - domain_spec.set("ymax",ymax()); - return domain_spec; + Spec domain_spec; + domain_spec.set( "type", type() ); + domain_spec.set( "ymin", ymin() ); + domain_spec.set( "ymax", ymax() ); + return domain_spec; } -void ZonalBandDomain::hash(eckit::Hash& h) const { - spec().hash(h); +void ZonalBandDomain::hash( eckit::Hash& h ) const { + spec().hash( h ); } -void ZonalBandDomain::print(std::ostream& os) const { - os << "ZonalBandDomain[" - << "ymin=" << ymin() - << ",ymax=" << ymax() - << "]"; +void ZonalBandDomain::print( std::ostream& os ) const { + os << "ZonalBandDomain[" + << "ymin=" << ymin() << ",ymax=" << ymax() << "]"; } - bool ZonalBandDomain::containsNorthPole() const { - return ymax_tol_ >= 90.; + return ymax_tol_ >= 90.; } bool ZonalBandDomain::containsSouthPole() const { - return ymin_tol_ <= -90.; + return ymin_tol_ <= -90.; } -register_BuilderT1(Domain,ZonalBandDomain,ZonalBandDomain::static_type()); +register_BuilderT1( Domain, ZonalBandDomain, ZonalBandDomain::static_type() ); } // namespace domain } // namespace atlas - diff --git a/src/atlas/domain/detail/ZonalBandDomain.h b/src/atlas/domain/detail/ZonalBandDomain.h index 35ff7a33e..345134d71 100644 --- a/src/atlas/domain/detail/ZonalBandDomain.h +++ b/src/atlas/domain/detail/ZonalBandDomain.h @@ -1,48 +1,44 @@ #pragma once -#include #include +#include #include "atlas/domain/Domain.h" #include "atlas/domain/detail/RectangularDomain.h" namespace atlas { - class RectangularDomain; - class ZonalBandDomain; -} +class RectangularDomain; +class ZonalBandDomain; +} // namespace atlas namespace atlas { namespace domain { -class ZonalBandDomain: public atlas::domain::RectangularDomain { - +class ZonalBandDomain : public atlas::domain::RectangularDomain { protected: - static constexpr char units_[] = "degrees"; public: - static bool is_global( const Interval& y ); public: - - // constructor + // constructor ZonalBandDomain( const eckit::Parametrisation& ); ZonalBandDomain( const Interval& ); - static std::string static_type() {return "zonal_band";} + static std::string static_type() { return "zonal_band"; } virtual std::string type() const override { return static_type(); } /// Checks if the point is contained in the domain - virtual bool contains(double x, double y) const override; + virtual bool contains( double x, double y ) const override; virtual bool global() const override { return global_; } - virtual bool empty() const override { return (ymin() == ymax()); } + virtual bool empty() const override { return ( ymin() == ymax() ); } virtual Spec spec() const override; - virtual void print(std::ostream&) const override; + virtual void print( std::ostream& ) const override; - virtual void hash(eckit::Hash&) const override; + virtual void hash( eckit::Hash& ) const override; virtual std::string units() const override { return units_; } @@ -52,14 +48,11 @@ class ZonalBandDomain: public atlas::domain::RectangularDomain { /// Check if grid includes the South pole virtual bool containsSouthPole() const override; - protected: - friend class ::atlas::RectangularDomain; ZonalBandDomain( const Interval&, const double west ); private: - bool global_; double ymin_tol_; double ymax_tol_; diff --git a/src/atlas/field.h b/src/atlas/field.h index bce9ecf23..d7987f3cd 100644 --- a/src/atlas/field.h +++ b/src/atlas/field.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ diff --git a/src/atlas/field/Field.cc b/src/atlas/field/Field.cc index c0fab1cc5..043b255db 100644 --- a/src/atlas/field/Field.cc +++ b/src/atlas/field/Field.cc @@ -4,12 +4,13 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include +#include #include "atlas/field/Field.h" #include "atlas/field/detail/FieldImpl.h" @@ -18,242 +19,332 @@ namespace atlas { // ------------------------------------------------------------------ -std::ostream& operator<<( std::ostream& os, const Field& f) -{ - os << (*f.field_); - return os; +std::ostream& operator<<( std::ostream& os, const Field& f ) { + os << ( *f.field_ ); + return os; } -Field::Field() : - field_(nullptr) { -} +Field::Field() : field_( nullptr ) {} -Field::Field( const Field& field ) : - field_( field.field_ ) { - field_->attach(); +Field::Field( const Field& field ) : field_( field.field_ ) { + field_->attach(); } -Field::Field( const Implementation* field ) : - field_( const_cast(field) ) { - field_->attach(); +Field::Field( const Implementation* field ) : field_( const_cast( field ) ) { + field_->attach(); } -Field::Field(const eckit::Parametrisation& config) : - field_( Implementation::create(config) ) { - field_->attach(); -} - -Field::Field( - const std::string& name, array::DataType datatype, - const array::ArrayShape& shape) : - field_( Implementation::create(name, datatype, shape) ) { - field_->attach(); +Field::Field( const eckit::Parametrisation& config ) : field_( Implementation::create( config ) ) { + field_->attach(); } -Field::Field( const std::string& name, array::Array* array ) : - field_( Implementation::create(name,array) ) { - field_->attach(); +Field::Field( const std::string& name, array::DataType datatype, const array::ArrayShape& shape ) : + field_( Implementation::create( name, datatype, shape ) ) { + field_->attach(); } -template<> -Field::Field( - const std::string& name, - double *data, - const array::ArraySpec& spec) : - field_( Implementation::wrap(name,data,spec) ) { +Field::Field( const std::string& name, array::Array* array ) : field_( Implementation::create( name, array ) ) { field_->attach(); } -template<> -Field::Field( - const std::string& name, - double *data, - const array::ArrayShape& shape) : - field_( Implementation::wrap(name, data, shape) ) { +template <> +Field::Field( const std::string& name, double* data, const array::ArraySpec& spec ) : + field_( Implementation::wrap( name, data, spec ) ) { field_->attach(); } - -template<> -Field::Field( - const std::string& name, - float *data, - const array::ArraySpec& spec) : - field_( Implementation::wrap(name,data,spec) ) { +template <> +Field::Field( const std::string& name, double* data, const array::ArrayShape& shape ) : + field_( Implementation::wrap( name, data, shape ) ) { field_->attach(); } -template<> -Field::Field( - const std::string& name, - float *data, - const array::ArrayShape& shape) : - field_( Implementation::wrap(name, data, shape) ) { +template <> +Field::Field( const std::string& name, float* data, const array::ArraySpec& spec ) : + field_( Implementation::wrap( name, data, spec ) ) { field_->attach(); } - -template<> -Field::Field( - const std::string& name, - long *data, - const array::ArraySpec& spec) : - field_( Implementation::wrap(name,data,spec) ) { +template <> +Field::Field( const std::string& name, float* data, const array::ArrayShape& shape ) : + field_( Implementation::wrap( name, data, shape ) ) { field_->attach(); } -template<> -Field::Field( - const std::string& name, - long *data, - const array::ArrayShape& shape) : - field_( Implementation::wrap(name, data, shape) ) { +template <> +Field::Field( const std::string& name, long* data, const array::ArraySpec& spec ) : + field_( Implementation::wrap( name, data, spec ) ) { field_->attach(); } +template <> +Field::Field( const std::string& name, long* data, const array::ArrayShape& shape ) : + field_( Implementation::wrap( name, data, shape ) ) { + field_->attach(); +} -template<> -Field::Field( - const std::string& name, - int *data, - const array::ArraySpec& spec) : - field_( Implementation::wrap(name,data,spec) ) { +template <> +Field::Field( const std::string& name, int* data, const array::ArraySpec& spec ) : + field_( Implementation::wrap( name, data, spec ) ) { field_->attach(); } -template<> -Field::Field( - const std::string& name, - int *data, - const array::ArrayShape& shape) : - field_( Implementation::wrap(name, data, shape) ) { +template <> +Field::Field( const std::string& name, int* data, const array::ArrayShape& shape ) : + field_( Implementation::wrap( name, data, shape ) ) { field_->attach(); } Field::~Field() { - if (field_) { - field_->detach(); - if( not field_->owners() ) { - delete field_; + if ( field_ ) { + field_->detach(); + if ( not field_->owners() ) { delete field_; } } - } } -const Field& Field::operator= ( const Field& other ) { - if( field_ != other.field_ ) { - if( field_ ) { - if( not field_->owners() ) { - delete field_; +const Field& Field::operator=( const Field& other ) { + if ( field_ != other.field_ ) { + if ( field_ ) { + if ( not field_->owners() ) { delete field_; } } - } - field_ = other.field_; - field_->attach(); + field_ = other.field_; + field_->attach(); } return *this; } /// @brief Implicit conversion to Array -Field::operator const array::Array&() const { return field_->array(); } -Field::operator array::Array&() { return field_->array(); } +Field::operator const array::Array&() const { + return field_->array(); +} +Field::operator array::Array&() { + return field_->array(); +} -const array::Array& Field::array() const { return field_->array(); } - array::Array& Field::array() { return field_->array(); } +const array::Array& Field::array() const { + return field_->array(); +} +array::Array& Field::array() { + return field_->array(); +} // -- Accessors /// @brief Access to raw data -void* Field::storage() { return field_->storage(); } +void* Field::storage() { + return field_->storage(); +} /// @brief Internal data type of field -array::DataType Field::datatype() const { return field_->datatype(); } +array::DataType Field::datatype() const { + return field_->datatype(); +} /// @brief Name associated to this field -const std::string& Field::name() const { return field_->name(); } +const std::string& Field::name() const { + return field_->name(); +} /// @brief Rename this field -void Field::rename(const std::string& name) { field_->rename(name); } +void Field::rename( const std::string& name ) { + field_->rename( name ); +} /// @brief Access to metadata associated to this field -const util::Metadata& Field::metadata() const { return field_->metadata(); } - util::Metadata& Field::metadata() { return field_->metadata(); } +const util::Metadata& Field::metadata() const { + return field_->metadata(); +} +util::Metadata& Field::metadata() { + return field_->metadata(); +} /// @brief Resize field to given shape -void Field::resize(const array::ArrayShape& shape ) { field_->resize(shape); } +void Field::resize( const array::ArrayShape& shape ) { + field_->resize( shape ); +} -void Field::insert(size_t idx1, size_t size1 ) { field_->insert(idx1,size1); } +void Field::insert( size_t idx1, size_t size1 ) { + field_->insert( idx1, size1 ); +} /// @brief Shape of this field in Fortran style (reverse order of C style) -const std::vector& Field::shapef() const { return field_->shapef(); } +const std::vector& Field::shapef() const { + return field_->shapef(); +} /// @brief Strides of this field in Fortran style (reverse order of C style) -const std::vector& Field::stridesf() const { return field_->stridesf(); } +const std::vector& Field::stridesf() const { + return field_->stridesf(); +} /// @brief Shape of this field (reverse order of Fortran style) -const array::ArrayShape& Field::shape() const { return field_->shape(); } +const array::ArrayShape& Field::shape() const { + return field_->shape(); +} /// @brief Strides of this field -const array::ArrayStrides& Field::strides() const { return field_->strides(); } +const array::ArrayStrides& Field::strides() const { + return field_->strides(); +} /// @brief Shape of this field associated to index 'i' -size_t Field::shape (size_t i) const { return field_->shape(i); } +size_t Field::shape( size_t i ) const { + return field_->shape( i ); +} /// @brief Stride of this field associated to index 'i' -size_t Field::stride(size_t i) const { return field_->stride(i); } +size_t Field::stride( size_t i ) const { + return field_->stride( i ); +} /// @brief Number of values stored in this field -size_t Field::size() const { return field_->size(); } +size_t Field::size() const { + return field_->size(); +} /// @brief Rank of field -size_t Field::rank() const { return field_->rank(); } +size_t Field::rank() const { + return field_->rank(); +} /// @brief Number of bytes occupied by the values of this field -double Field::bytes() const { return field_->bytes(); } +double Field::bytes() const { + return field_->bytes(); +} /// @brief Output information of field plus raw data -void Field::dump(std::ostream& os) const { field_->dump(os); } +void Field::dump( std::ostream& os ) const { + field_->dump( os ); +} /// Metadata that is more intrinsic to the Field, and queried often -void Field::set_levels(size_t n) { field_->set_levels(n); } -size_t Field::levels() const { return field_->levels(); } +void Field::set_levels( size_t n ) { + field_->set_levels( n ); +} +size_t Field::levels() const { + return field_->levels(); +} /// Metadata that is more intrinsic to the Field, and queried often -void Field::set_variables(size_t n) { field_->set_variables(n); } -size_t Field::variables() const { return field_->variables(); } +void Field::set_variables( size_t n ) { + field_->set_variables( n ); +} +size_t Field::variables() const { + return field_->variables(); +} -void Field::set_functionspace(const FunctionSpace& functionspace ) { field_->set_functionspace(functionspace); } -const FunctionSpace& Field::functionspace() const { return field_->functionspace(); } +void Field::set_functionspace( const FunctionSpace& functionspace ) { + field_->set_functionspace( functionspace ); +} +const FunctionSpace& Field::functionspace() const { + return field_->functionspace(); +} /// @brief Return the memory footprint of the Field -size_t Field::footprint() const { return field_->footprint(); } +size_t Field::footprint() const { + return field_->footprint(); +} // -- dangerous methods -template<> double const* Field::host_data() const { return field_->host_data (); } -template<> double* Field::host_data() { return field_->host_data (); } -template<> double const* Field::device_data() const { return field_->device_data(); } -template<> double* Field::device_data() { return field_->device_data(); } -template<> double const* Field::data() const { return field_->host_data (); } -template<> double* Field::data() { return field_->host_data (); } - -template<> float const* Field::host_data() const { return field_->host_data (); } -template<> float* Field::host_data() { return field_->host_data (); } -template<> float const* Field::device_data() const { return field_->device_data(); } -template<> float* Field::device_data() { return field_->device_data(); } -template<> float const* Field::data() const { return field_->host_data (); } -template<> float* Field::data() { return field_->host_data (); } - -template<> long const* Field::host_data() const { return field_->host_data (); } -template<> long* Field::host_data() { return field_->host_data (); } -template<> long const* Field::device_data() const { return field_->device_data(); } -template<> long* Field::device_data() { return field_->device_data(); } -template<> long const* Field::data() const { return field_->host_data (); } -template<> long* Field::data() { return field_->host_data (); } - -template<> int const* Field::host_data() const { return field_->host_data (); } -template<> int* Field::host_data() { return field_->host_data (); } -template<> int const* Field::device_data() const { return field_->device_data(); } -template<> int* Field::device_data() { return field_->device_data(); } -template<> int const* Field::data() const { return field_->host_data (); } -template<> int* Field::data() { return field_->host_data (); } +template <> +double const* Field::host_data() const { + return field_->host_data(); +} +template <> +double* Field::host_data() { + return field_->host_data(); +} +template <> +double const* Field::device_data() const { + return field_->device_data(); +} +template <> +double* Field::device_data() { + return field_->device_data(); +} +template <> +double const* Field::data() const { + return field_->host_data(); +} +template <> +double* Field::data() { + return field_->host_data(); +} + +template <> +float const* Field::host_data() const { + return field_->host_data(); +} +template <> +float* Field::host_data() { + return field_->host_data(); +} +template <> +float const* Field::device_data() const { + return field_->device_data(); +} +template <> +float* Field::device_data() { + return field_->device_data(); +} +template <> +float const* Field::data() const { + return field_->host_data(); +} +template <> +float* Field::data() { + return field_->host_data(); +} + +template <> +long const* Field::host_data() const { + return field_->host_data(); +} +template <> +long* Field::host_data() { + return field_->host_data(); +} +template <> +long const* Field::device_data() const { + return field_->device_data(); +} +template <> +long* Field::device_data() { + return field_->device_data(); +} +template <> +long const* Field::data() const { + return field_->host_data(); +} +template <> +long* Field::data() { + return field_->host_data(); +} + +template <> +int const* Field::host_data() const { + return field_->host_data(); +} +template <> +int* Field::host_data() { + return field_->host_data(); +} +template <> +int const* Field::device_data() const { + return field_->device_data(); +} +template <> +int* Field::device_data() { + return field_->device_data(); +} +template <> +int const* Field::data() const { + return field_->host_data(); +} +template <> +int* Field::data() { + return field_->host_data(); +} // -- Methods related to host-device synchronisation, requires gridtools_storage void Field::cloneToDevice() const { @@ -280,5 +371,4 @@ void Field::reactivateHostWriteViews() const { // ------------------------------------------------------------------ -} // namespace atlas - +} // namespace atlas diff --git a/src/atlas/field/Field.h b/src/atlas/field/Field.h index e5294bbab..78def69ba 100644 --- a/src/atlas/field/Field.h +++ b/src/atlas/field/Field.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,162 +14,189 @@ #pragma once -#include "atlas/array_fwd.h" #include "atlas/array/ArrayShape.h" #include "atlas/array/DataType.h" +#include "atlas/array_fwd.h" - -namespace eckit { class Parametrisation; } -namespace atlas { namespace field { class FieldImpl; } } -namespace atlas { namespace array { class Array; } } -namespace atlas { namespace array { class ArraySpec; } } -namespace atlas { namespace array { class ArrayStrides; } } -namespace atlas { namespace util { class Metadata; } } -namespace atlas { class FunctionSpace; } +namespace eckit { +class Parametrisation; +} +namespace atlas { +namespace field { +class FieldImpl; +} +} // namespace atlas +namespace atlas { +namespace array { +class Array; +} +} // namespace atlas +namespace atlas { +namespace array { +class ArraySpec; +} +} // namespace atlas +namespace atlas { +namespace array { +class ArrayStrides; +} +} // namespace atlas +namespace atlas { +namespace util { +class Metadata; +} +} // namespace atlas +namespace atlas { +class FunctionSpace; +} namespace atlas { class Field { public: - - using Implementation = field::FieldImpl; - -private: + using Implementation = field::FieldImpl; - Implementation* field_{ nullptr }; +private: + Implementation* field_{nullptr}; public: + Field(); + Field( const Field& ); + Field( const Implementation* ); - Field(); - Field( const Field& ); - Field( const Implementation* ); - - /// @brief Create field from parametrisation - Field( const eckit::Parametrisation& ); + /// @brief Create field from parametrisation + Field( const eckit::Parametrisation& ); - /// @brief Create field with given name, Datatype and ArrayShape - Field( - const std::string& name, array::DataType, - const array::ArrayShape& = array::ArrayShape()); + /// @brief Create field with given name, Datatype and ArrayShape + Field( const std::string& name, array::DataType, const array::ArrayShape& = array::ArrayShape() ); - /// @brief Create field with given name, and take ownership of given Array - Field( const std::string& name, array::Array* ); + /// @brief Create field with given name, and take ownership of given Array + Field( const std::string& name, array::Array* ); - /// @brief Create field by wrapping existing data, Datatype of template and ArraySpec - template - Field( const std::string& name, DATATYPE *data, const array::ArraySpec& ); + /// @brief Create field by wrapping existing data, Datatype of template and + /// ArraySpec + template + Field( const std::string& name, DATATYPE* data, const array::ArraySpec& ); - /// @brief Create field by wrapping existing data, Datatype of template and ArrayShape - template - Field( const std::string& name, DATATYPE *data, const array::ArrayShape& ); + /// @brief Create field by wrapping existing data, Datatype of template and + /// ArrayShape + template + Field( const std::string& name, DATATYPE* data, const array::ArrayShape& ); - ~Field(); + ~Field(); -// -- Conversion + // -- Conversion - /// @brief Implicit conversion to Array - operator const array::Array&() const; - operator array::Array&(); + /// @brief Implicit conversion to Array + operator const array::Array&() const; + operator array::Array&(); - const array::Array& array() const; - array::Array& array(); + const array::Array& array() const; + array::Array& array(); - bool valid() const { return field_; } - operator bool() const { return valid(); } + bool valid() const { return field_; } + operator bool() const { return valid(); } - Implementation* get() { return field_; } - const Implementation* get() const { return field_; } + Implementation* get() { return field_; } + const Implementation* get() const { return field_; } - const Field& operator= ( const Field& ); + const Field& operator=( const Field& ); -// -- Accessors + // -- Accessors - /// @brief Access to raw data - void* storage(); + /// @brief Access to raw data + void* storage(); - /// @brief Internal data type of field - array::DataType datatype() const; + /// @brief Internal data type of field + array::DataType datatype() const; - /// @brief Name associated to this field - const std::string& name() const; + /// @brief Name associated to this field + const std::string& name() const; - /// @brief Rename this field - void rename(const std::string& name); + /// @brief Rename this field + void rename( const std::string& name ); - /// @brief Access to metadata associated to this field - const util::Metadata& metadata() const; - util::Metadata& metadata(); + /// @brief Access to metadata associated to this field + const util::Metadata& metadata() const; + util::Metadata& metadata(); - /// @brief Resize field to given shape - void resize(const array::ArrayShape& shape ); + /// @brief Resize field to given shape + void resize( const array::ArrayShape& shape ); - void insert(size_t idx1, size_t size1 ); + void insert( size_t idx1, size_t size1 ); - /// @brief Shape of this field in Fortran style (reverse order of C style) - const std::vector& shapef() const; + /// @brief Shape of this field in Fortran style (reverse order of C style) + const std::vector& shapef() const; - /// @brief Strides of this field in Fortran style (reverse order of C style) - const std::vector& stridesf() const; + /// @brief Strides of this field in Fortran style (reverse order of C style) + const std::vector& stridesf() const; - /// @brief Shape of this field (reverse order of Fortran style) - const array::ArrayShape& shape() const; + /// @brief Shape of this field (reverse order of Fortran style) + const array::ArrayShape& shape() const; - /// @brief Strides of this field - const array::ArrayStrides& strides() const; + /// @brief Strides of this field + const array::ArrayStrides& strides() const; - /// @brief Shape of this field associated to index 'i' - size_t shape (size_t i) const; + /// @brief Shape of this field associated to index 'i' + size_t shape( size_t i ) const; - /// @brief Stride of this field associated to index 'i' - size_t stride(size_t i) const; + /// @brief Stride of this field associated to index 'i' + size_t stride( size_t i ) const; - /// @brief Number of values stored in this field - size_t size() const; + /// @brief Number of values stored in this field + size_t size() const; - /// @brief Rank of field - size_t rank() const; + /// @brief Rank of field + size_t rank() const; - /// @brief Number of bytes occupied by the values of this field - double bytes() const; + /// @brief Number of bytes occupied by the values of this field + double bytes() const; - /// @brief Output information of field - friend std::ostream& operator<<( std::ostream& os, const Field& v); + /// @brief Output information of field + friend std::ostream& operator<<( std::ostream& os, const Field& v ); - /// @brief Output information of field plus raw data - void dump(std::ostream& os) const; + /// @brief Output information of field plus raw data + void dump( std::ostream& os ) const; - /// Metadata that is more intrinsic to the Field, and queried often - void set_levels(size_t n); - size_t levels() const; + /// Metadata that is more intrinsic to the Field, and queried often + void set_levels( size_t n ); + size_t levels() const; - /// Metadata that is more intrinsic to the Field, and queried often - void set_variables(size_t n); - size_t variables() const; + /// Metadata that is more intrinsic to the Field, and queried often + void set_variables( size_t n ); + size_t variables() const; - void set_functionspace(const FunctionSpace& functionspace ); - const FunctionSpace& functionspace() const; + void set_functionspace( const FunctionSpace& functionspace ); + const FunctionSpace& functionspace() const; - /// @brief Return the memory footprint of the Field - size_t footprint() const; + /// @brief Return the memory footprint of the Field + size_t footprint() const; -// -- dangerous methods - template DATATYPE const* host_data() const; - template DATATYPE* host_data(); - template DATATYPE const* device_data() const; - template DATATYPE* device_data(); - template DATATYPE const* data() const; - template DATATYPE* data(); + // -- dangerous methods + template + DATATYPE const* host_data() const; + template + DATATYPE* host_data(); + template + DATATYPE const* device_data() const; + template + DATATYPE* device_data(); + template + DATATYPE const* data() const; + template + DATATYPE* data(); -// -- Methods related to host-device synchronisation, requires gridtools_storage - void cloneToDevice() const; - void cloneFromDevice() const; - void syncHostDevice() const; - bool hostNeedsUpdate() const; - bool deviceNeedsUpdate() const; - void reactivateDeviceWriteViews() const; - void reactivateHostWriteViews() const; + // -- Methods related to host-device synchronisation, requires + // gridtools_storage + void cloneToDevice() const; + void cloneFromDevice() const; + void syncHostDevice() const; + bool hostNeedsUpdate() const; + bool deviceNeedsUpdate() const; + void reactivateDeviceWriteViews() const; + void reactivateHostWriteViews() const; }; //------------------------------------------------------------------------------------------------------ -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/field/FieldCreator.cc b/src/atlas/field/FieldCreator.cc index a0ed11bcb..5435fdaa3 100644 --- a/src/atlas/field/FieldCreator.cc +++ b/src/atlas/field/FieldCreator.cc @@ -4,146 +4,131 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include +#include "atlas/field/FieldCreator.h" #include +#include #include +#include "atlas/field/Field.h" +#include "atlas/field/FieldCreatorArraySpec.h" +#include "atlas/field/FieldCreatorIFS.h" +#include "atlas/grid/Grid.h" +#include "atlas/runtime/Log.h" #include "eckit/exception/Exceptions.h" #include "eckit/os/BackTrace.h" #include "eckit/thread/AutoLock.h" #include "eckit/thread/Mutex.h" -#include "atlas/grid/Grid.h" -#include "atlas/field/FieldCreator.h" -#include "atlas/field/FieldCreatorArraySpec.h" -#include "atlas/field/FieldCreatorIFS.h" -#include "atlas/field/Field.h" -#include "atlas/runtime/Log.h" namespace { - static eckit::Mutex *local_mutex = 0; - static std::map *m = 0; - static pthread_once_t once = PTHREAD_ONCE_INIT; +static eckit::Mutex* local_mutex = 0; +static std::map* m = 0; +static pthread_once_t once = PTHREAD_ONCE_INIT; - static void init() { - local_mutex = new eckit::Mutex(); - m = new std::map(); - } +static void init() { + local_mutex = new eckit::Mutex(); + m = new std::map(); } - +} // namespace namespace atlas { namespace field { namespace { -template void load_builder(const std::string& name) { FieldCreatorBuilder tmp(name); } +template +void load_builder( const std::string& name ) { + FieldCreatorBuilder tmp( name ); +} struct force_link { - force_link() - { - load_builder< FieldCreatorIFS >("tmp_IFS"); - load_builder< FieldCreatorArraySpec >("tmp_ArraySpec"); + force_link() { + load_builder( "tmp_IFS" ); + load_builder( "tmp_ArraySpec" ); } }; -} - - - - +} // namespace // ------------------------------------------------------------------ -FieldCreator::FieldCreator() -{ -} - -FieldCreator::~FieldCreator() -{ -} +FieldCreator::FieldCreator() {} -FieldCreatorFactory::FieldCreatorFactory(const std::string &name): - name_(name) { +FieldCreator::~FieldCreator() {} - pthread_once(&once, init); +FieldCreatorFactory::FieldCreatorFactory( const std::string& name ) : name_( name ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); - if( m->find(name) != m->end() ) - { - std::string backtrace = eckit::BackTrace::dump(); - throw eckit::SeriousBug("FieldCreatorFactory ["+name+"] already registered\n\nBacktrace:\n"+backtrace,Here()); + if ( m->find( name ) != m->end() ) { + std::string backtrace = eckit::BackTrace::dump(); + throw eckit::SeriousBug( "FieldCreatorFactory [" + name + "] already registered\n\nBacktrace:\n" + backtrace, + Here() ); } - (*m)[name] = this; + ( *m )[name] = this; } - FieldCreatorFactory::~FieldCreatorFactory() { - eckit::AutoLock lock(local_mutex); - m->erase(name_); + eckit::AutoLock lock( local_mutex ); + m->erase( name_ ); } +void FieldCreatorFactory::list( std::ostream& out ) { + pthread_once( &once, init ); -void FieldCreatorFactory::list(std::ostream& out) { - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; const char* sep = ""; - for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { - out << sep << (*j).first; + for ( std::map::const_iterator j = m->begin(); j != m->end(); ++j ) { + out << sep << ( *j ).first; sep = ", "; } } +FieldCreator* FieldCreatorFactory::build( const std::string& name ) { + pthread_once( &once, init ); -FieldCreator *FieldCreatorFactory::build(const std::string &name) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::map::const_iterator j = m->find(name); + std::map::const_iterator j = m->find( name ); - if (j == m->end()) { + if ( j == m->end() ) { Log::error() << "No FieldCreatorFactory for [" << name << "]" << '\n'; Log::error() << "FieldCreatorFactories are:" << '\n'; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << '\n'; - throw eckit::SeriousBug(std::string("No FieldCreatorFactory called ") + name); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << '\n'; + throw eckit::SeriousBug( std::string( "No FieldCreatorFactory called " ) + name ); } - return (*j).second->make(); + return ( *j ).second->make(); } +FieldCreator* FieldCreatorFactory::build( const std::string& name, const eckit::Parametrisation& param ) { + pthread_once( &once, init ); -FieldCreator *FieldCreatorFactory::build(const std::string& name, const eckit::Parametrisation& param) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::map::const_iterator j = m->find(name); + std::map::const_iterator j = m->find( name ); - if (j == m->end()) { + if ( j == m->end() ) { Log::error() << "No FieldCreatorFactory for [" << name << "]" << '\n'; Log::error() << "FieldCreatorFactories are:" << '\n'; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << '\n'; - throw eckit::SeriousBug(std::string("No FieldCreatorFactory called ") + name); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << '\n'; + throw eckit::SeriousBug( std::string( "No FieldCreatorFactory called " ) + name ); } - return (*j).second->make(param); + return ( *j ).second->make( param ); } -} // namespace field -} // namespace atlas - +} // namespace field +} // namespace atlas diff --git a/src/atlas/field/FieldCreator.h b/src/atlas/field/FieldCreator.h index dcda32dce..21cf48936 100644 --- a/src/atlas/field/FieldCreator.h +++ b/src/atlas/field/FieldCreator.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,10 +16,12 @@ #define atlas_field_FieldCreator_h #include -#include "eckit/memory/Owned.h" #include "atlas/field/Field.h" +#include "eckit/memory/Owned.h" -namespace eckit { class Parametrisation; } +namespace eckit { +class Parametrisation; +} //------------------------------------------------------------------------------------------------------ @@ -34,70 +37,63 @@ namespace field { * FieldImpl* field = Field::create( * Config * ("creator","ArraySpec") // ArraySpec FieldCreator - * ("shape",array::make_shape(100,3)) // Rank 2 field with indexing [100][3] + * ("shape",array::make_shape(100,3)) // Rank 2 field with indexing + * [100][3] * ); * \endcode */ class FieldCreator : public eckit::Owned { - public: - FieldCreator(); virtual ~FieldCreator(); virtual FieldImpl* createField( const eckit::Parametrisation& ) const = 0; - }; //------------------------------------------------------------------------------------------------------ class FieldCreatorFactory { - public: +public: /*! - * \brief build FieldCreator with factory key, and default options - * \return FieldCreator - */ - static FieldCreator* build(const std::string&); + * \brief build FieldCreator with factory key, and default options + * \return FieldCreator + */ + static FieldCreator* build( const std::string& ); /*! - * \brief build FieldCreator with options specified in parametrisation - * \return mesh generator - */ - static FieldCreator* build(const std::string&, const eckit::Parametrisation&); + * \brief build FieldCreator with options specified in parametrisation + * \return mesh generator + */ + static FieldCreator* build( const std::string&, const eckit::Parametrisation& ); /*! - * \brief list all registered field creators - */ - static void list(std::ostream &); + * \brief list all registered field creators + */ + static void list( std::ostream& ); - private: +private: std::string name_; - virtual FieldCreator* make() = 0 ; - virtual FieldCreator* make(const eckit::Parametrisation&) = 0 ; - - protected: + virtual FieldCreator* make() = 0; + virtual FieldCreator* make( const eckit::Parametrisation& ) = 0; - FieldCreatorFactory(const std::string&); +protected: + FieldCreatorFactory( const std::string& ); virtual ~FieldCreatorFactory(); }; - -template +template class FieldCreatorBuilder : public FieldCreatorFactory { - virtual FieldCreator* make() { - return new T(); - } - virtual FieldCreator* make(const eckit::Parametrisation& param) { - return new T(param); - } - public: - FieldCreatorBuilder(const std::string& name) : FieldCreatorFactory(name) {} + virtual FieldCreator* make() { return new T(); } + virtual FieldCreator* make( const eckit::Parametrisation& param ) { return new T( param ); } + +public: + FieldCreatorBuilder( const std::string& name ) : FieldCreatorFactory( name ) {} }; //------------------------------------------------------------------------------------------------------ -} // namespace field -} // namespace atlas +} // namespace field +} // namespace atlas #endif diff --git a/src/atlas/field/FieldCreatorArraySpec.cc b/src/atlas/field/FieldCreatorArraySpec.cc index 9d4f9caae..7dbefdebf 100644 --- a/src/atlas/field/FieldCreatorArraySpec.cc +++ b/src/atlas/field/FieldCreatorArraySpec.cc @@ -4,65 +4,60 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/field/FieldCreatorArraySpec.h" #include #include -#include "eckit/exception/Exceptions.h" -#include "eckit/config/Parametrisation.h" -#include "atlas/field/detail/FieldImpl.h" -#include "atlas/field/FieldCreatorArraySpec.h" #include "atlas/array/DataType.h" +#include "atlas/field/detail/FieldImpl.h" +#include "eckit/config/Parametrisation.h" +#include "eckit/exception/Exceptions.h" namespace atlas { namespace field { -FieldImpl* FieldCreatorArraySpec::createField( const eckit::Parametrisation& params ) const -{ - std::vector shape; - if( !params.get("shape",shape) ) - throw eckit::Exception("Could not find parameter 'shape' in Parametrisation"); - - std::vector s(shape.size()); - - bool fortran (false); - params.get("fortran",fortran); - if( fortran ) std::reverse_copy( shape.begin(),shape.end(), s.begin() ); - else s.assign(shape.begin(),shape.end()); - - - array::DataType datatype = array::DataType::create(); - std::string 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); - if( ! array::DataType::kind_valid(kind) ) - { - std::stringstream msg; - msg << "Could not create field. kind parameter unrecognized"; - throw eckit::Exception(msg.str()); +FieldImpl* FieldCreatorArraySpec::createField( const eckit::Parametrisation& params ) const { + std::vector shape; + if ( !params.get( "shape", shape ) ) + throw eckit::Exception( "Could not find parameter 'shape' in Parametrisation" ); + + std::vector s( shape.size() ); + + bool fortran( false ); + params.get( "fortran", fortran ); + if ( fortran ) + std::reverse_copy( shape.begin(), shape.end(), s.begin() ); + else + s.assign( shape.begin(), shape.end() ); + + array::DataType datatype = array::DataType::create(); + std::string 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 ); + if ( !array::DataType::kind_valid( kind ) ) { + std::stringstream msg; + msg << "Could not create field. kind parameter unrecognized"; + throw eckit::Exception( msg.str() ); + } + datatype = array::DataType( kind ); } - datatype = array::DataType(kind); - } - std::string name; - params.get("name",name); - return FieldImpl::create( name,datatype,array::ArrayShape( std::move(s) ) ); + std::string name; + params.get( "name", name ); + return FieldImpl::create( name, datatype, array::ArrayShape( std::move( s ) ) ); } namespace { -static FieldCreatorBuilder< FieldCreatorArraySpec > __ArraySpec("ArraySpec"); +static FieldCreatorBuilder __ArraySpec( "ArraySpec" ); } // ------------------------------------------------------------------ -} // namespace field -} // namespace atlas - +} // namespace field +} // namespace atlas diff --git a/src/atlas/field/FieldCreatorArraySpec.h b/src/atlas/field/FieldCreatorArraySpec.h index 9a963a326..378c2c491 100644 --- a/src/atlas/field/FieldCreatorArraySpec.h +++ b/src/atlas/field/FieldCreatorArraySpec.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,8 +17,14 @@ #include "atlas/field/FieldCreator.h" -namespace eckit { class Parametrisation; } -namespace atlas { namespace field { class Field; } } +namespace eckit { +class Parametrisation; +} +namespace atlas { +namespace field { +class Field; +} +} // namespace atlas namespace atlas { namespace field { @@ -30,23 +37,22 @@ namespace field { * FieldImpl* field = Field::create( * Config * ("creator","ArraySpec") // ArraySpec FieldCreator - * ("shape",array::make_shape(100,3)) // Rank 2 field with indexing [100][3] + * ("shape",array::make_shape(100,3)) // Rank 2 field with indexing + * [100][3] * ("datatype",array::DataType::real64()) // Field internal data type * ); * \endcode */ -class FieldCreatorArraySpec: public FieldCreator -{ +class FieldCreatorArraySpec : public FieldCreator { public: - FieldCreatorArraySpec() {} - FieldCreatorArraySpec(const eckit::Parametrisation&) {} - virtual FieldImpl* createField( const eckit::Parametrisation& ) const; + FieldCreatorArraySpec() {} + FieldCreatorArraySpec( const eckit::Parametrisation& ) {} + virtual FieldImpl* createField( const eckit::Parametrisation& ) const; }; // ------------------------------------------------------------------ -} // namespace field -} // namespace atlas +} // namespace field +} // namespace atlas #endif - diff --git a/src/atlas/field/FieldCreatorIFS.cc b/src/atlas/field/FieldCreatorIFS.cc index 1e6b2d711..2894fb7cb 100644 --- a/src/atlas/field/FieldCreatorIFS.cc +++ b/src/atlas/field/FieldCreatorIFS.cc @@ -4,78 +4,74 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include -#include "eckit/exception/Exceptions.h" -#include "eckit/config/Parametrisation.h" -#include "atlas/grid/Grid.h" #include "atlas/field/FieldCreatorIFS.h" -#include "atlas/field/detail/FieldImpl.h" +#include #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" +#include "atlas/field/detail/FieldImpl.h" +#include "atlas/grid/Grid.h" #include "atlas/runtime/Log.h" +#include "eckit/config/Parametrisation.h" +#include "eckit/exception/Exceptions.h" namespace atlas { namespace field { -FieldImpl* FieldCreatorIFS::createField( const eckit::Parametrisation& params ) const -{ - size_t ngptot; - size_t nblk; - size_t nvar = 1; - size_t nproma = 1; - size_t nlev = 1; +FieldImpl* FieldCreatorIFS::createField( const eckit::Parametrisation& params ) const { + size_t ngptot; + size_t nblk; + size_t nvar = 1; + size_t nproma = 1; + size_t nlev = 1; - if( !params.get("ngptot",ngptot) ) - throw eckit::Exception("Could not find parameter 'ngptot' in Parametrisation"); - params.get("nproma",nproma); - params.get("nlev",nlev); - params.get("nvar",nvar); + if ( !params.get( "ngptot", ngptot ) ) + throw eckit::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); - } - else - { - array::DataType::kind_t kind(array::DataType::kind()); - params.get("kind",kind); - if( ! array::DataType::kind_valid(kind) ) - { - std::stringstream msg; - msg << "Could not create field. kind parameter unrecognized"; - throw eckit::Exception(msg.str()); + array::DataType datatype = array::DataType::create(); + std::string 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 ); + if ( !array::DataType::kind_valid( kind ) ) { + std::stringstream msg; + msg << "Could not create field. kind parameter unrecognized"; + throw eckit::Exception( msg.str() ); + } + datatype = array::DataType( kind ); } - datatype = array::DataType(kind); - } - - nblk = std::ceil(static_cast(ngptot)/static_cast(nproma)); - array::ArrayShape s; - bool fortran (false); - params.get("fortran",fortran); - if( fortran ) s = array::make_shape(nproma,nlev,nvar,nblk); - else s = array::make_shape(nblk,nvar,nlev,nproma); + nblk = std::ceil( static_cast( ngptot ) / static_cast( nproma ) ); - std::string name; - params.get("name",name); - Log::debug() << "Creating IFS "< __IFS("IFS"); +static FieldCreatorBuilder __IFS( "IFS" ); } // ------------------------------------------------------------------ -} // namespace field -} // namespace atlas - +} // namespace field +} // namespace atlas diff --git a/src/atlas/field/FieldCreatorIFS.h b/src/atlas/field/FieldCreatorIFS.h index ae86dee14..b43c474cf 100644 --- a/src/atlas/field/FieldCreatorIFS.h +++ b/src/atlas/field/FieldCreatorIFS.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,8 +17,14 @@ #include "atlas/field/FieldCreator.h" -namespace eckit { class Parametrisation; } -namespace atlas { namespace field { class FieldImpl; } } +namespace eckit { +class Parametrisation; +} +namespace atlas { +namespace field { +class FieldImpl; +} +} // namespace atlas namespace atlas { namespace field { @@ -41,17 +48,16 @@ namespace field { * ); * \endcode */ -class FieldCreatorIFS: public FieldCreator -{ +class FieldCreatorIFS : public FieldCreator { public: - FieldCreatorIFS() {} - FieldCreatorIFS(const eckit::Parametrisation&) {} - virtual FieldImpl* createField( const eckit::Parametrisation& ) const; + FieldCreatorIFS() {} + FieldCreatorIFS( const eckit::Parametrisation& ) {} + virtual FieldImpl* createField( const eckit::Parametrisation& ) const; }; // ------------------------------------------------------------------ -} // namespace field -} // namespace atlas +} // namespace field +} // namespace atlas #endif diff --git a/src/atlas/field/FieldSet.cc b/src/atlas/field/FieldSet.cc index 9f53f3975..ca60e9302 100644 --- a/src/atlas/field/FieldSet.cc +++ b/src/atlas/field/FieldSet.cc @@ -4,160 +4,111 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/grid/Grid.h" -#include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" +#include "atlas/field/Field.h" +#include "atlas/grid/Grid.h" #include "atlas/runtime/ErrorHandling.h" namespace atlas { namespace field { - -//------------------------------------------------------------------------------------------------------ +//------------------------------------------------------------------------------------------------------ -FieldSetImpl::FieldSetImpl(const std::string &name) : - name_() -{} +FieldSetImpl::FieldSetImpl( const std::string& name ) : name_() {} -void FieldSetImpl::clear() -{ +void FieldSetImpl::clear() { index_.clear(); fields_.clear(); } -Field FieldSetImpl::add(const Field& field) -{ - if( field.name().size() ) { - index_[field.name()] = fields_.size(); - } else { - std::stringstream name; name << name_ << "["<(fields_[ index_.at(name) ]); +Field& FieldSetImpl::field( const std::string& name ) const { + if ( !has_field( name ) ) { + const std::string msg( "FieldSet" + ( name_.length() ? " \"" + name_ + "\"" : "" ) + ": cannot find field \"" + + name + "\"" ); + throw eckit::OutOfRange( msg, Here() ); + } + return const_cast( fields_[index_.at( name )] ); } +std::vector FieldSetImpl::field_names() const { + std::vector ret; -std::vector< std::string > FieldSetImpl::field_names() const -{ - std::vector< std::string > ret; + for ( const_iterator field = cbegin(); field != cend(); ++field ) + ret.push_back( field->name() ); - for( const_iterator field = cbegin(); field!=cend(); ++field ) - ret.push_back(field->name()); - - return ret; + return ret; } //----------------------------------------------------------------------------- // C wrapper interfaces to C++ routines -extern "C"{ - +extern "C" { -FieldSetImpl* atlas__FieldSet__new (char* name) -{ - ATLAS_ERROR_HANDLING( - FieldSetImpl* fset = new FieldSetImpl( std::string(name) ); - fset->name() = name; - return fset; - ); - return NULL; +FieldSetImpl* atlas__FieldSet__new( char* name ) { + ATLAS_ERROR_HANDLING( FieldSetImpl* fset = new FieldSetImpl( std::string( name ) ); fset->name() = name; + return fset; ); + return NULL; } - -void atlas__FieldSet__delete(FieldSetImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This!= NULL ); - delete This; - ); +void atlas__FieldSet__delete( FieldSetImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); delete This; ); } -void atlas__FieldSet__add_field (FieldSetImpl* This, FieldImpl* field) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This != NULL); - This->add(field); - ); +void atlas__FieldSet__add_field( FieldSetImpl* This, FieldImpl* field ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); This->add( field ); ); } -int atlas__FieldSet__has_field (const FieldSetImpl* This, char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This != NULL); - return This->has_field( std::string(name) ); - ); - return 0; +int atlas__FieldSet__has_field( const FieldSetImpl* This, char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); return This->has_field( std::string( name ) ); ); + return 0; } -size_t atlas__FieldSet__size (const FieldSetImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This != NULL); - return This->size(); - ); - return 0; +size_t atlas__FieldSet__size( const FieldSetImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); return This->size(); ); + return 0; } -FieldImpl* atlas__FieldSet__field_by_name (FieldSetImpl* This, char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This != NULL); - return This->field( std::string(name) ).get(); - ); - return NULL; +FieldImpl* atlas__FieldSet__field_by_name( FieldSetImpl* This, char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); return This->field( std::string( name ) ).get(); ); + return NULL; } -FieldImpl* atlas__FieldSet__field_by_idx (FieldSetImpl* This, size_t idx) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This != NULL); - return This->operator[](idx).get(); - ); - return NULL; +FieldImpl* atlas__FieldSet__field_by_idx( FieldSetImpl* This, size_t idx ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); return This->operator[]( idx ).get(); ); + return NULL; } - - } //----------------------------------------------------------------------------- -} // namespace field +} // namespace field //------------------------------------------------------------------------------------------------------ +FieldSet::FieldSet( const std::string& name ) : fieldset_( new Implementation( name ) ) {} -FieldSet::FieldSet( const std::string& name ) : - fieldset_( new Implementation(name) ) { -} - -FieldSet::FieldSet( const Implementation* fieldset ) : - fieldset_( const_cast(fieldset) ) { -} +FieldSet::FieldSet( const Implementation* fieldset ) : fieldset_( const_cast( fieldset ) ) {} -FieldSet::FieldSet( const FieldSet& fieldset ) : - fieldset_( fieldset.fieldset_ ) { -} +FieldSet::FieldSet( const FieldSet& fieldset ) : fieldset_( fieldset.fieldset_ ) {} //------------------------------------------------------------------------------------------------------ -} // namespace atlas - +} // namespace atlas diff --git a/src/atlas/field/FieldSet.h b/src/atlas/field/FieldSet.h index 395a8f7f8..d48122d04 100644 --- a/src/atlas/field/FieldSet.h +++ b/src/atlas/field/FieldSet.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,88 +15,87 @@ #pragma once -#include #include +#include - +#include "atlas/field/Field.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" -#include "atlas/field/Field.h" namespace atlas { - class FieldSet; +class FieldSet; namespace field { - /** * @brief Represents a set of fields, where order is preserved */ class FieldSetImpl : public eckit::Owned { +public: // types + typedef std::vector::iterator iterator; + typedef std::vector::const_iterator const_iterator; -public: // types - - typedef std::vector::iterator iterator; - typedef std::vector::const_iterator const_iterator; +public: // methods + /// Constructs an empty FieldSet + FieldSetImpl( const std::string& name = "untitled" ); -public: // methods + size_t size() const { return fields_.size(); } + bool empty() const { return !fields_.size(); } - /// Constructs an empty FieldSet - FieldSetImpl(const std::string& name = "untitled"); + void clear(); - size_t size() const { return fields_.size(); } - bool empty() const { return !fields_.size(); } + const std::string& name() const { return name_; } + std::string& name() { return name_; } - void clear(); + const Field& operator[]( const size_t& i ) const { return field( i ); } + Field& operator[]( const size_t& i ) { return field( i ); } - const std::string& name() const { return name_; } - std::string& name() { return name_; } + const Field& operator[]( const std::string& name ) const { return field( name ); } + Field& operator[]( const std::string& name ) { return field( name ); } - const Field& operator[](const size_t &i) const { return field(i); } - Field& operator[](const size_t &i) { return field(i); } + const Field& field( const size_t& i ) const { + ASSERT( i < size() ); + return fields_[i]; + } + Field& field( const size_t& i ) { + ASSERT( i < size() ); + return fields_[i]; + } - const Field& operator[](const std::string &name) const { return field(name); } - Field& operator[](const std::string &name) { return field(name); } + std::vector field_names() const; - const Field& field(const size_t& i) const { ASSERT(i field_names() const; + bool has_field( const std::string& name ) const; - Field add(const Field&); + Field& field( const std::string& name ) const; - bool has_field(const std::string& name) const; + iterator begin() { return fields_.begin(); } + iterator end() { return fields_.end(); } + const_iterator begin() const { return fields_.begin(); } + const_iterator end() const { return fields_.end(); } + const_iterator cbegin() const { return fields_.begin(); } + const_iterator cend() const { return fields_.end(); } - Field& field(const std::string& name) const; - - iterator begin() { return fields_.begin(); } - iterator end() { return fields_.end(); } - const_iterator begin() const { return fields_.begin(); } - const_iterator end() const { return fields_.end(); } - const_iterator cbegin() const { return fields_.begin(); } - const_iterator cend() const { return fields_.end(); } - -protected: // data - - std::vector< Field > fields_; ///< field storage - std::string name_; ///< internal name - std::map< std::string, size_t > index_; ///< name-to-index map, to refer fields by name +protected: // data + std::vector fields_; ///< field storage + std::string name_; ///< internal name + std::map index_; ///< name-to-index map, to refer fields by name }; // C wrapper interfaces to C++ routines -extern "C" -{ - FieldSetImpl* atlas__FieldSet__new (char* name); - void atlas__FieldSet__delete (FieldSetImpl* This); - void atlas__FieldSet__add_field (FieldSetImpl* This, FieldImpl* field); - int atlas__FieldSet__has_field (const FieldSetImpl* This, char* name); - size_t atlas__FieldSet__size (const FieldSetImpl* This); - FieldImpl* atlas__FieldSet__field_by_name (FieldSetImpl* This, char* name); - FieldImpl* atlas__FieldSet__field_by_idx (FieldSetImpl* This, size_t idx); +extern "C" { +FieldSetImpl* atlas__FieldSet__new( char* name ); +void atlas__FieldSet__delete( FieldSetImpl* This ); +void atlas__FieldSet__add_field( FieldSetImpl* This, FieldImpl* field ); +int atlas__FieldSet__has_field( const FieldSetImpl* This, char* name ); +size_t atlas__FieldSet__size( const FieldSetImpl* This ); +FieldImpl* atlas__FieldSet__field_by_name( FieldSetImpl* This, char* name ); +FieldImpl* atlas__FieldSet__field_by_idx( FieldSetImpl* This, size_t idx ); } -} // namespace field +} // namespace field //--------------------------------------------------------------------------------------------------------------------- @@ -103,54 +103,50 @@ extern "C" * @brief Represents a set of fields, where order is preserved */ class FieldSet { +public: // types + using Implementation = field::FieldSetImpl; + using iterator = Implementation::iterator; + using const_iterator = Implementation::const_iterator; -public: // types - - using Implementation = field::FieldSetImpl; - using iterator = Implementation::iterator; - using const_iterator = Implementation::const_iterator; - -public: // methods - - FieldSet( const std::string& name = "untitled" ); - FieldSet( const Implementation* ); - FieldSet( const FieldSet& ); - - size_t size() const { return fieldset_->size(); } - bool empty() const { return fieldset_->empty(); } +public: // methods + FieldSet( const std::string& name = "untitled" ); + FieldSet( const Implementation* ); + FieldSet( const FieldSet& ); - void clear() { fieldset_->clear(); } + size_t size() const { return fieldset_->size(); } + bool empty() const { return fieldset_->empty(); } - const std::string& name() const { return fieldset_->name(); } - std::string& name() { return fieldset_->name(); } + void clear() { fieldset_->clear(); } - const Field& operator[](const size_t &i) const { return fieldset_->operator[](i); } - Field& operator[](const size_t &i) { return fieldset_->operator[](i); } + const std::string& name() const { return fieldset_->name(); } + std::string& name() { return fieldset_->name(); } - const Field& operator[](const std::string &name) const { return fieldset_->operator[](name); } - Field& operator[](const std::string &name) { return fieldset_->operator[](name); } + const Field& operator[]( const size_t& i ) const { return fieldset_->operator[]( i ); } + Field& operator[]( const size_t& i ) { return fieldset_->operator[]( i ); } - const Field& field(const size_t& i) const { return fieldset_->field(i); } - Field& field(const size_t& i) { return fieldset_->field(i); } + const Field& operator[]( const std::string& name ) const { return fieldset_->operator[]( name ); } + Field& operator[]( const std::string& name ) { return fieldset_->operator[]( name ); } - std::vector< std::string > field_names() const { return fieldset_->field_names(); } + const Field& field( const size_t& i ) const { return fieldset_->field( i ); } + Field& field( const size_t& i ) { return fieldset_->field( i ); } - Field add( const Field& field ) { return fieldset_->add(field); } + std::vector field_names() const { return fieldset_->field_names(); } - bool has_field(const std::string& name) const { return fieldset_->has_field(name); } + Field add( const Field& field ) { return fieldset_->add( field ); } - Field& field(const std::string& name) const { return fieldset_->field(name); } + bool has_field( const std::string& name ) const { return fieldset_->has_field( name ); } - iterator begin() { return fieldset_->begin(); } - iterator end() { return fieldset_->end(); } - const_iterator begin() const { return fieldset_->begin(); } - const_iterator end() const { return fieldset_->end(); } - const_iterator cbegin() const { return fieldset_->begin(); } - const_iterator cend() const { return fieldset_->end(); } + Field& field( const std::string& name ) const { return fieldset_->field( name ); } -private: // data + iterator begin() { return fieldset_->begin(); } + iterator end() { return fieldset_->end(); } + const_iterator begin() const { return fieldset_->begin(); } + const_iterator end() const { return fieldset_->end(); } + const_iterator cbegin() const { return fieldset_->begin(); } + const_iterator cend() const { return fieldset_->end(); } - eckit::SharedPtr fieldset_; +private: // data + eckit::SharedPtr fieldset_; }; -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/field/State.cc b/src/atlas/field/State.cc index 0911b4560..3fbd68ff7 100644 --- a/src/atlas/field/State.cc +++ b/src/atlas/field/State.cc @@ -4,306 +4,270 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/field/State.h" #include -#include #include #include -#include "eckit/thread/AutoLock.h" -#include "eckit/thread/Mutex.h" +#include +#include "atlas/field/Field.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" -#include "atlas/field/Field.h" -#include "atlas/field/State.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" namespace atlas { namespace field { namespace { - static eckit::Mutex *local_mutex = 0; - static std::map *m = 0; - static pthread_once_t once = PTHREAD_ONCE_INIT; - - static void init() { - local_mutex = new eckit::Mutex(); - m = new std::map(); - } +static eckit::Mutex* local_mutex = 0; +static std::map* m = 0; +static pthread_once_t once = PTHREAD_ONCE_INIT; - template void load_builder() { StateGeneratorBuilder("tmp"); } +static void init() { + local_mutex = new eckit::Mutex(); + m = new std::map(); +} - struct force_link { - force_link() - { - // load_builder< A DERIVED TYPE >(); - // ... - } - }; +template +void load_builder() { + StateGeneratorBuilder( "tmp" ); } -void State::initialize( const std::string& generator, const eckit::Parametrisation& params ) -{ - std::unique_ptr state_generator ( StateGeneratorFactory::build(generator, params) ); - state_generator->generate( *this, params ); +struct force_link { + force_link() { + // load_builder< A DERIVED TYPE >(); + // ... + } +}; +} // namespace + +void State::initialize( const std::string& generator, const eckit::Parametrisation& params ) { + std::unique_ptr state_generator( StateGeneratorFactory::build( generator, params ) ); + state_generator->generate( *this, params ); } //------------------------------------------------------------------------------------------------------ -State::State() -{ -} +State::State() {} -State::State( const std::string& generator, const eckit::Parametrisation& params ) -{ - initialize(generator,params); +State::State( const std::string& generator, const eckit::Parametrisation& params ) { + initialize( generator, params ); } -const util::Metadata& State::metadata() const -{ - return metadata_; +const util::Metadata& State::metadata() const { + return metadata_; } -util::Metadata& State::metadata() -{ - return metadata_; +util::Metadata& State::metadata() { + return metadata_; } -Field State::add( Field field ) -{ - ASSERT( field ); - - if( field.name().empty() ) - { - std::stringstream new_name; - new_name << "field_" << std::setw(5) << std::setfill('0') << fields_.size(); - ASSERT( !has(new_name.str() ) ); - field.rename(new_name.str()); - } - - if( has(field.name()) ) { - std::stringstream msg; - msg << "Trying to add field '"<second; + if ( field.name().empty() ) { + std::stringstream new_name; + new_name << "field_" << std::setw( 5 ) << std::setfill( '0' ) << fields_.size(); + ASSERT( !has( new_name.str() ) ); + field.rename( new_name.str() ); + } + + if ( has( field.name() ) ) { + std::stringstream msg; + msg << "Trying to add field '" << field.name() << "' to State, but State already has a field with this name."; + throw eckit::Exception( msg.str(), Here() ); + } + fields_[field.name()] = field; + return field; } -Field& State::field(const std::string& name) -{ - return const_cast(static_cast(this)->field(name)); +const Field& State::field( const std::string& name ) const { + if ( !has( name ) ) { + std::stringstream msg; + msg << "Trying to access field `" << name << "' in State, but no field with this name is present in State."; + throw eckit::Exception( msg.str(), Here() ); + } + return fields_.find( name )->second; } -const Field& State::field(const size_t idx) const -{ - if( idx >= fields_.size() ) - { - std::stringstream msg; - msg << "Trying to access field in State with index "<second; +Field& State::field( const std::string& name ) { + return const_cast( static_cast( this )->field( name ) ); } -Field& State::field(const size_t idx) -{ - return const_cast(static_cast(this)->field(idx)); +const Field& State::field( const size_t idx ) const { + if ( idx >= fields_.size() ) { + std::stringstream msg; + msg << "Trying to access field in State with index " << idx << ", but there exist only " << fields_.size() + << " fields in State."; + throw eckit::Exception( msg.str(), Here() ); + } + FieldMap::const_iterator it = fields_.begin(); + for ( size_t i = 0; i < idx; ++i ) + ++it; + return it->second; } -std::vector< std::string > State::field_names() const -{ - std::vector< std::string > ret; - if (fields_.size()) - ret.reserve(fields_.size()); - - for( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) - { - ret.push_back( it->first ); - } - return ret; +Field& State::field( const size_t idx ) { + return const_cast( static_cast( this )->field( idx ) ); } +std::vector State::field_names() const { + std::vector ret; + if ( fields_.size() ) ret.reserve( fields_.size() ); -void State::remove(const std::string& name) -{ - if( fields_.find(name)==fields_.end() ) { - std::stringstream msg; - msg << "Trying to remove field '"<first ); + } + return ret; } -//----------------------------------------------------------------------------- +void State::remove( const std::string& name ) { + if ( fields_.find( name ) == fields_.end() ) { + std::stringstream msg; + msg << "Trying to remove field '" << name << "' from State, but it is not present in State."; + throw eckit::Exception( msg.str(), Here() ); + } + fields_.erase( name ); +} -StateGenerator::StateGenerator( const eckit::Parametrisation& ) -{} +//----------------------------------------------------------------------------- -StateGenerator::~StateGenerator() -{} +StateGenerator::StateGenerator( const eckit::Parametrisation& ) {} -StateGenerator* StateGeneratorFactory::build(const std::string& name, const eckit::Parametrisation& param) { +StateGenerator::~StateGenerator() {} - pthread_once(&once, init); +StateGenerator* StateGeneratorFactory::build( const std::string& name, const eckit::Parametrisation& param ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::map::const_iterator j = m->find(name); + std::map::const_iterator j = m->find( name ); Log::debug() << "Looking for StateGeneratorFactory [" << name << "]" << std::endl; - if (j == m->end()) { + 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) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No StateGeneratorFactory called ") + name); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << std::endl; + throw eckit::SeriousBug( std::string( "No StateGeneratorFactory called " ) + name ); } - return (*j).second->make(param); + return ( *j ).second->make( param ); } -void StateGeneratorFactory::list(std::ostream& out) { - pthread_once(&once, init); +void StateGeneratorFactory::list( std::ostream& out ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; const char* sep = ""; - for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { - out << sep << (*j).first; + for ( std::map::const_iterator j = m->begin(); j != m->end(); ++j ) { + out << sep << ( *j ).first; sep = ", "; } } -bool StateGeneratorFactory::has(const std::string& name) -{ - pthread_once(&once, init); +bool StateGeneratorFactory::has( const std::string& name ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); - static force_link static_linking; + static force_link static_linking; - return ( m->find(name) != m->end() ); + return ( m->find( name ) != m->end() ); } -StateGeneratorFactory::StateGeneratorFactory(const std::string &name): - name_(name) { - - pthread_once(&once, init); +StateGeneratorFactory::StateGeneratorFactory( const std::string& name ) : name_( name ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); - ASSERT(m->find(name) == m->end()); - (*m)[name] = this; + ASSERT( m->find( name ) == m->end() ); + ( *m )[name] = this; } - StateGeneratorFactory::~StateGeneratorFactory() { - eckit::AutoLock lock(local_mutex); - m->erase(name_); + eckit::AutoLock lock( local_mutex ); + m->erase( name_ ); } - - //----------------------------------------------------------------------------- // C wrapper interfaces to C++ routines -extern "C"{ +extern "C" { -State* atlas__State__new() -{ - return new State; +State* atlas__State__new() { + return new State; } -void atlas__State__initialize(State* This, const char* generator, const eckit::Parametrisation* params) -{ - ASSERT( This ); - ASSERT( params ); - ATLAS_ERROR_HANDLING( This->initialize(std::string(generator),*params) ); +void atlas__State__initialize( State* This, const char* generator, const eckit::Parametrisation* params ) { + ASSERT( This ); + ASSERT( params ); + ATLAS_ERROR_HANDLING( This->initialize( std::string( generator ), *params ) ); } -void atlas__State__delete (State* This) -{ - ASSERT( This ); - delete This; +void atlas__State__delete( State* This ) { + ASSERT( This ); + delete This; } -void atlas__State__add (State* This, FieldImpl* field) -{ - ASSERT( This ); - ATLAS_ERROR_HANDLING( This->add(field); ); +void atlas__State__add( State* This, FieldImpl* field ) { + ASSERT( This ); + ATLAS_ERROR_HANDLING( This->add( field ); ); } -void atlas__State__remove (State* This, const char* name) -{ - ASSERT( This ); - ATLAS_ERROR_HANDLING( This->remove(name); ); +void atlas__State__remove( State* This, const char* name ) { + ASSERT( This ); + ATLAS_ERROR_HANDLING( This->remove( name ); ); } -int atlas__State__has (State* This, const char* name) -{ - ASSERT( This ); - int has_field(0); - ATLAS_ERROR_HANDLING( has_field = This->has(name); ); - return has_field; +int atlas__State__has( State* This, const char* name ) { + ASSERT( This ); + int has_field( 0 ); + ATLAS_ERROR_HANDLING( has_field = This->has( name ); ); + return has_field; } -FieldImpl* atlas__State__field_by_name (State* This, const char* name) -{ - ASSERT( This ); - FieldImpl* field(0); - ATLAS_ERROR_HANDLING ( field = This->field( std::string(name) ).get(); ); - return field; +FieldImpl* atlas__State__field_by_name( State* This, const char* name ) { + ASSERT( This ); + FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( field = This->field( std::string( name ) ).get(); ); + return field; } -FieldImpl* atlas__State__field_by_index (State* This, int index) -{ - ASSERT( This ); - FieldImpl* field(0); - ATLAS_ERROR_HANDLING( field = This->field( index ).get() ); - return field; +FieldImpl* atlas__State__field_by_index( State* This, int index ) { + ASSERT( This ); + FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( field = This->field( index ).get() ); + return field; } -int atlas__State__size(const State* This) -{ - ASSERT( This ); - int nb_fields(0); - ATLAS_ERROR_HANDLING( nb_fields = This->size(); ); - return nb_fields; +int atlas__State__size( const State* This ) { + ASSERT( This ); + int nb_fields( 0 ); + ATLAS_ERROR_HANDLING( nb_fields = This->size(); ); + return nb_fields; } -util::Metadata* atlas__State__metadata (State* This) -{ - ASSERT( This ); - return &This->metadata(); +util::Metadata* atlas__State__metadata( State* This ) { + ASSERT( This ); + return &This->metadata(); } - - } //----------------------------------------------------------------------------- -} // namespace field -} // namespace atlas - +} // namespace field +} // namespace atlas diff --git a/src/atlas/field/State.h b/src/atlas/field/State.h index 9de6c95d1..98decd278 100644 --- a/src/atlas/field/State.h +++ b/src/atlas/field/State.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,13 +15,15 @@ #ifndef atlas_State_H #define atlas_State_H -#include "eckit/memory/Owned.h" -#include "eckit/memory/SharedPtr.h" +#include "atlas/field/Field.h" #include "atlas/util/Config.h" #include "atlas/util/Metadata.h" -#include "atlas/field/Field.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" -namespace eckit { class Parametrisation; } +namespace eckit { +class Parametrisation; +} namespace atlas { namespace field { @@ -29,131 +32,113 @@ namespace field { * \brief State class that owns a collection of fields */ class State : public eckit::Owned { +public: // types + typedef eckit::SharedPtr Ptr; -public: // types - - typedef eckit::SharedPtr< State > Ptr; - -public: // methods +public: // methods + //-- Constructors + State(); -//-- Constructors + State( const std::string& generator, const eckit::Parametrisation& = util::Config() ); - State(); + //-- Accessors - State(const std::string& generator, const eckit::Parametrisation& = util::Config()); + const Field& field( const std::string& name ) const; + Field& field( const std::string& name ); + bool has( const std::string& name ) const { return ( fields_.find( name ) != fields_.end() ); } + std::vector field_names() const; -//-- Accessors + const Field& field( const size_t idx ) const; + Field& field( const size_t idx ); + size_t size() const { return fields_.size(); } - const Field& field(const std::string& name) const; - Field& field(const std::string& name); - bool has(const std::string& name) const { return (fields_.find(name) != fields_.end()); } - std::vector< std::string > field_names() const; + const Field& operator[]( const size_t idx ) const { return field( idx ); } + Field& operator[]( const size_t idx ) { return field( idx ); } - const Field& field(const size_t idx) const; - Field& field(const size_t idx); - size_t size() const { return fields_.size(); } + const Field& operator[]( const std::string& name ) const { return field( name ); } + Field& operator[]( const std::string& name ) { return field( name ); } - const Field& operator[](const size_t idx) const { return field(idx); } - Field& operator[](const size_t idx) { return field(idx); } + const util::Metadata& metadata() const; + util::Metadata& metadata(); - const Field& operator[](const std::string& name) const { return field(name); } - Field& operator[](const std::string& name) { return field(name); } + // -- Modifiers - const util::Metadata& metadata() const; - util::Metadata& metadata(); + void initialize( const std::string& generator, const eckit::Parametrisation& = util::Config() ); -// -- Modifiers + Field add( Field ); - void initialize(const std::string& generator, const eckit::Parametrisation& = util::Config() ); - - Field add( Field ); - - void remove(const std::string& name); + void remove( const std::string& name ); private: - - typedef std::map< std::string, Field > FieldMap; + typedef std::map FieldMap; private: - - FieldMap fields_; - util::Metadata metadata_; - + FieldMap fields_; + util::Metadata metadata_; }; //------------------------------------------------------------------------------------------------------ class StateGenerator : public eckit::Owned { - public: - StateGenerator( const eckit::Parametrisation& = util::Config() ); virtual ~StateGenerator(); virtual void generate( State&, const eckit::Parametrisation& = util::Config() ) const = 0; - }; //------------------------------------------------------------------------------------------------------ class StateGeneratorFactory { - public: - +public: /*! - * \brief build StateCreator with options specified in parametrisation - * \return mesh generator - */ - static StateGenerator* build(const std::string& state_generator, - const eckit::Parametrisation& = util::Config() ); + * \brief build StateCreator with options specified in parametrisation + * \return mesh generator + */ + static StateGenerator* build( const std::string& state_generator, const eckit::Parametrisation& = util::Config() ); /*! - * \brief list all registered field creators - */ - static void list(std::ostream &); - static bool has(const std::string& name); - - private: + * \brief list all registered field creators + */ + static void list( std::ostream& ); + static bool has( const std::string& name ); - virtual StateGenerator* make(const eckit::Parametrisation& = util::Config() ) = 0 ; +private: + virtual StateGenerator* make( const eckit::Parametrisation& = util::Config() ) = 0; std::string name_; - protected: - - StateGeneratorFactory(const std::string&); +protected: + StateGeneratorFactory( const std::string& ); virtual ~StateGeneratorFactory(); }; - -template +template class StateGeneratorBuilder : public StateGeneratorFactory { + virtual StateGenerator* make( const eckit::Parametrisation& param = util::Config() ) { return new T( param ); } - virtual StateGenerator* make(const eckit::Parametrisation& param = util::Config() ) { - return new T(param); - } - public: - StateGeneratorBuilder(const std::string& name) : StateGeneratorFactory(name) {} +public: + StateGeneratorBuilder( const std::string& name ) : StateGeneratorFactory( name ) {} }; // ------------------------------------------------------------------------------------ // C wrapper interfaces to C++ routines -extern "C" -{ - State* atlas__State__new (); - void atlas__State__initialize (State* This, const char* generator, const eckit::Parametrisation* params); - void atlas__State__delete (State* This); - void atlas__State__add (State* This, FieldImpl* field); - void atlas__State__remove (State* This, const char* name); - int atlas__State__has (State* This, const char* name); - FieldImpl* atlas__State__field_by_name (State* This, const char* name); - FieldImpl* atlas__State__field_by_index (State* This, int index); - int atlas__State__size(const State* This); - util::Metadata* atlas__State__metadata (State* This); +extern "C" { +State* atlas__State__new(); +void atlas__State__initialize( State* This, const char* generator, const eckit::Parametrisation* params ); +void atlas__State__delete( State* This ); +void atlas__State__add( State* This, FieldImpl* field ); +void atlas__State__remove( State* This, const char* name ); +int atlas__State__has( State* This, const char* name ); +FieldImpl* atlas__State__field_by_name( State* This, const char* name ); +FieldImpl* atlas__State__field_by_index( State* This, int index ); +int atlas__State__size( const State* This ); +util::Metadata* atlas__State__metadata( State* This ); } -} // namespace field -} // namespace atlas +} // namespace field +} // namespace atlas #endif diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index 825d4b62e..1959c570d 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -4,24 +4,25 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include #include +#include -#include "eckit/exception/Exceptions.h" -#include "eckit/memory/ScopedPtr.h" -#include "atlas/grid/Grid.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/field/detail/FieldImpl.h" +#include "atlas/array/MakeView.h" #include "atlas/field/FieldCreator.h" +#include "atlas/field/detail/FieldImpl.h" #include "atlas/functionspace/FunctionSpace.h" +#include "atlas/grid/Grid.h" +#include "atlas/mesh/Mesh.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "atlas/array/MakeView.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/memory/ScopedPtr.h" namespace atlas { namespace field { @@ -29,511 +30,337 @@ namespace field { // ------------------------------------------------------------------------- // Static functions -FieldImpl* FieldImpl::create(const eckit::Parametrisation& params) -{ - std::string creator_factory; - if( params.get("creator",creator_factory) ) - { - eckit::ScopedPtr creator - (field::FieldCreatorFactory::build(creator_factory,params) ); - return creator->createField(params); - } - else - throw eckit::Exception("Could not find parameter 'creator' " - "in Parametrisation for call to FieldImpl::create()"); +FieldImpl* FieldImpl::create( const eckit::Parametrisation& params ) { + std::string creator_factory; + if ( params.get( "creator", creator_factory ) ) { + eckit::ScopedPtr creator( field::FieldCreatorFactory::build( creator_factory, params ) ); + return creator->createField( params ); + } + else + throw eckit::Exception( + "Could not find parameter 'creator' " + "in Parametrisation for call to FieldImpl::create()" ); - return 0; + return 0; } -FieldImpl* FieldImpl::create( - const std::string& name, - array::DataType datatype, - const array::ArrayShape& shape) -{ - return new FieldImpl(name,datatype,shape); +FieldImpl* FieldImpl::create( const std::string& name, array::DataType datatype, const array::ArrayShape& shape ) { + return new FieldImpl( name, datatype, shape ); } -FieldImpl* FieldImpl::create( const std::string& name, array::Array* array ) -{ - return new FieldImpl(name,array); +FieldImpl* FieldImpl::create( const std::string& name, array::Array* array ) { + return new FieldImpl( name, array ); } // ------------------------------------------------------------------------- -FieldImpl::FieldImpl( - const std::string& name, - array::DataType datatype, - const array::ArrayShape& shape) -{ - array_ = array::Array::create(datatype,shape); - array_->attach(); - rename(name); - set_levels(0); - set_variables(0); +FieldImpl::FieldImpl( const std::string& name, array::DataType datatype, const array::ArrayShape& shape ) { + array_ = array::Array::create( datatype, shape ); + array_->attach(); + rename( name ); + set_levels( 0 ); + set_variables( 0 ); } - -FieldImpl::FieldImpl(const std::string& name, array::Array* array) -{ - array_ = array; - array_->attach(); - rename(name); - set_levels(0); - set_variables(0); +FieldImpl::FieldImpl( const std::string& name, array::Array* array ) { + array_ = array; + array_->attach(); + rename( name ); + set_levels( 0 ); + set_variables( 0 ); } -FieldImpl::~FieldImpl() -{ - array_->detach(); - if( array_->owners() == 0 ) - delete array_; +FieldImpl::~FieldImpl() { + array_->detach(); + if ( array_->owners() == 0 ) delete array_; } size_t FieldImpl::footprint() const { - size_t size = sizeof(*this); - size += functionspace_.footprint(); - size += array_->footprint(); - size += metadata_.footprint(); - size += name_.capacity() * sizeof(std::string::value_type); - return size; + size_t size = sizeof( *this ); + size += functionspace_.footprint(); + size += array_->footprint(); + size += metadata_.footprint(); + size += name_.capacity() * sizeof( std::string::value_type ); + return size; } -void FieldImpl::dump(std::ostream& os) const -{ - print(os,true); +void FieldImpl::dump( std::ostream& os ) const { + print( os, true ); } namespace { -template< typename T > -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 << ','; - s << t[i]; - } - s << ']'; - return s.str(); -} - - -} - -const std::string& FieldImpl::name() const -{ - name_ = metadata().get("name"); - return name_; -} - -void FieldImpl::print(std::ostream& os, bool dump) const -{ - os << "FieldImpl[name=" << name() - << ",datatype=" << datatype().str() - << ",size=" << size() - << ",shape=" << vector_to_str( shape() ) - << ",strides=" << vector_to_str( strides() ) - #ifndef ATLAS_HAVE_GRIDTOOLS_STORAGE - << ",bytes=" << bytes() - #endif - << ",metadata=" << metadata(); - if( dump ) { - os << ",array=["; - array_->dump(os); - os << "]"; - } - os << "]"; +template +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 << ','; + s << t[i]; + } + s << ']'; + return s.str(); +} + +} // namespace + +const std::string& FieldImpl::name() const { + name_ = metadata().get( "name" ); + return name_; } -std::ostream& operator<<( std::ostream& os, const FieldImpl& f) -{ - f.print(os); - return os; +void FieldImpl::print( std::ostream& os, bool dump ) const { + os << "FieldImpl[name=" << name() << ",datatype=" << datatype().str() << ",size=" << size() + << ",shape=" << vector_to_str( shape() ) << ",strides=" << vector_to_str( strides() ) +#ifndef ATLAS_HAVE_GRIDTOOLS_STORAGE + << ",bytes=" << bytes() +#endif + << ",metadata=" << metadata(); + if ( dump ) { + os << ",array=["; + array_->dump( os ); + os << "]"; + } + os << "]"; } -void FieldImpl::resize(const array::ArrayShape& shape) -{ - array_->resize(shape); +std::ostream& operator<<( std::ostream& os, const FieldImpl& f ) { + f.print( os ); + return os; } -void FieldImpl::insert(size_t idx1, size_t size1 ) -{ - array_->insert(idx1,size1); +void FieldImpl::resize( const array::ArrayShape& shape ) { + array_->resize( shape ); } +void FieldImpl::insert( size_t idx1, size_t size1 ) { + array_->insert( idx1, size1 ); +} -void FieldImpl::set_functionspace(const FunctionSpace& functionspace) -{ - functionspace_ = functionspace; +void FieldImpl::set_functionspace( const FunctionSpace& functionspace ) { + functionspace_ = functionspace; } // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines namespace { - template< typename Value > - void atlas__Field__host_data_specf (FieldImpl* This, Value* &data, int &rank, int* &shapef, int* &stridesf) { - ATLAS_ERROR_HANDLING( - ASSERT(This); - This->array().accMap(); - data = This->host_data(); - shapef = const_cast(This->shapef().data()); - stridesf = const_cast(This->stridesf().data()); - rank = This->shapef().size(); - ); - } -} - -extern "C" -{ - -FieldImpl* atlas__Field__wrap_int_specf(const char* name, int data[], int rank, int shapef[], int stridesf[]) -{ - ATLAS_ERROR_HANDLING( - array::ArrayShape shape; shape.resize(rank); - array::ArrayStrides strides; strides.resize(rank); - size_t jf = rank-1; - for( int j=0; jattach(); - } - field->detach(); - ASSERT(field); - return field; - ); - return 0; -} - -FieldImpl* atlas__Field__wrap_long_specf(const char* name, long data[], int rank, int shapef[], int stridesf[]) -{ - ATLAS_ERROR_HANDLING( - array::ArrayShape shape; shape.resize(rank); - array::ArrayStrides strides; strides.resize(rank); - size_t jf = rank-1; - for( int j=0; jattach(); - } - field->detach(); - ASSERT(field); - return field; - ); - return 0; -} - -FieldImpl* atlas__Field__wrap_float_specf(const char* name, float data[], int rank, int shapef[], int stridesf[]) -{ - ATLAS_ERROR_HANDLING( - array::ArrayShape shape; shape.resize(rank); - array::ArrayStrides strides; strides.resize(rank); - size_t jf = rank-1; - for( int j=0; jattach(); - } - field->detach(); - ASSERT(field); - return field; - ); - return 0; -} - -FieldImpl* atlas__Field__wrap_double_specf(const char* name, double data[], int rank, int shapef[], int stridesf[]) -{ - ATLAS_ERROR_HANDLING( - array::ArrayShape shape; shape.resize(rank); - array::ArrayStrides strides; strides.resize(rank); - size_t jf = rank-1; - for( int j=0; jattach(); - } - field->detach(); - ASSERT(field); - return field; - ); - return 0; -} - -FieldImpl* atlas__Field__create(eckit::Parametrisation* params) -{ - ATLAS_ERROR_HANDLING( - ASSERT(params); - FieldImpl* field; - { - Field f(*params); - field = f.get(); - field->attach(); - } - field->detach(); - - ASSERT(field); - return field; - ); - return 0; +template +void atlas__Field__host_data_specf( FieldImpl* This, Value*& data, int& rank, int*& shapef, int*& stridesf ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); This->array().accMap(); data = This->host_data(); + shapef = const_cast( This->shapef().data() ); + stridesf = const_cast( This->stridesf().data() ); rank = This->shapef().size(); ); +} +} // namespace + +extern "C" { + +FieldImpl* atlas__Field__wrap_int_specf( const char* name, int data[], int rank, int shapef[], int stridesf[] ) { + ATLAS_ERROR_HANDLING( array::ArrayShape shape; shape.resize( rank ); array::ArrayStrides strides; + strides.resize( rank ); size_t jf = rank - 1; for ( int j = 0; j < rank; ++j ) { + shape[j] = shapef[jf]; + strides[j] = stridesf[jf]; + --jf; + } FieldImpl * field; + { + Field wrapped( std::string( name ), data, array::ArraySpec( shape, strides ) ); + field = wrapped.get(); + field->attach(); + } field->detach(); + ASSERT( field ); return field; ); + return 0; +} + +FieldImpl* atlas__Field__wrap_long_specf( const char* name, long data[], int rank, int shapef[], int stridesf[] ) { + ATLAS_ERROR_HANDLING( array::ArrayShape shape; shape.resize( rank ); array::ArrayStrides strides; + strides.resize( rank ); size_t jf = rank - 1; for ( int j = 0; j < rank; ++j ) { + shape[j] = shapef[jf]; + strides[j] = stridesf[jf]; + --jf; + } FieldImpl * field; + { + Field wrapped( std::string( name ), data, array::ArraySpec( shape, strides ) ); + field = wrapped.get(); + field->attach(); + } field->detach(); + ASSERT( field ); return field; ); + return 0; } -void atlas__Field__delete (FieldImpl* This) -{ - delete This; -} - -const char* atlas__Field__name (FieldImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->name().c_str(); - ); - return 0; +FieldImpl* atlas__Field__wrap_float_specf( const char* name, float data[], int rank, int shapef[], int stridesf[] ) { + ATLAS_ERROR_HANDLING( array::ArrayShape shape; shape.resize( rank ); array::ArrayStrides strides; + strides.resize( rank ); size_t jf = rank - 1; for ( int j = 0; j < rank; ++j ) { + shape[j] = shapef[jf]; + strides[j] = stridesf[jf]; + --jf; + } FieldImpl * field; + { + Field wrapped( std::string( name ), data, array::ArraySpec( shape, strides ) ); + field = wrapped.get(); + field->attach(); + } field->detach(); + ASSERT( field ); return field; ); + return 0; } -void atlas__Field__datatype (FieldImpl* This, char* &datatype, int &size, int &allocated) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - std::string s = This->datatype().str(); - size = s.size()+1; - datatype = new char[size]; - strcpy(datatype,s.c_str()); - allocated = true; - ); +FieldImpl* atlas__Field__wrap_double_specf( const char* name, double data[], int rank, int shapef[], int stridesf[] ) { + ATLAS_ERROR_HANDLING( array::ArrayShape shape; shape.resize( rank ); array::ArrayStrides strides; + strides.resize( rank ); size_t jf = rank - 1; for ( int j = 0; j < rank; ++j ) { + shape[j] = shapef[jf]; + strides[j] = stridesf[jf]; + --jf; + } FieldImpl * field; + { + Field wrapped( std::string( name ), data, array::ArraySpec( shape, strides ) ); + field = wrapped.get(); + field->attach(); + } field->detach(); + ASSERT( field ); return field; ); + return 0; } -int atlas__Field__size (FieldImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->size(); - ); - return 0; +FieldImpl* atlas__Field__create( eckit::Parametrisation* params ) { + ATLAS_ERROR_HANDLING( ASSERT( params ); FieldImpl * field; { + Field f( *params ); + field = f.get(); + field->attach(); + } field->detach(); + + ASSERT( field ); return field; ); + return 0; } -int atlas__Field__rank (FieldImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->rank(); - ); - return 0; +void atlas__Field__delete( FieldImpl* This ) { + delete This; } -int atlas__Field__kind (FieldImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->datatype().kind(); - ); - return 0; +const char* atlas__Field__name( FieldImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->name().c_str(); ); + return 0; } +void atlas__Field__datatype( FieldImpl* This, char*& datatype, int& size, int& allocated ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); std::string s = This->datatype().str(); size = s.size() + 1; + datatype = new char[size]; strcpy( datatype, s.c_str() ); allocated = true; ); +} -double atlas__Field__bytes (FieldImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->bytes(); - ); - return 0; +int atlas__Field__size( FieldImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->size(); ); + return 0; } -int atlas__Field__levels (FieldImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->levels(); - ); - return 0; +int atlas__Field__rank( FieldImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->rank(); ); + return 0; } -util::Metadata* atlas__Field__metadata (FieldImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return &This->metadata(); - ); - return 0; +int atlas__Field__kind( FieldImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->datatype().kind(); ); + return 0; } -int atlas__Field__has_functionspace(FieldImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return (This->functionspace() != 0); - ); - return 0; +double atlas__Field__bytes( FieldImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->bytes(); ); + return 0; } -const functionspace::FunctionSpaceImpl* atlas__Field__functionspace (FieldImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->functionspace().get(); - ); - return 0; +int atlas__Field__levels( FieldImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->levels(); ); + return 0; } +util::Metadata* atlas__Field__metadata( FieldImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->metadata(); ); + return 0; +} -void atlas__Field__shapef (FieldImpl* This, int* &shape, int &rank) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - shape = const_cast(&This->shapef().front()); - rank = This->shapef().size(); - ); +int atlas__Field__has_functionspace( FieldImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return ( This->functionspace() != 0 ); ); + return 0; } -void atlas__Field__host_data_int_specf (FieldImpl* This, int* &data, int &rank, int* &shapef, int* &stridesf) -{ - atlas__Field__host_data_specf(This,data,rank,shapef,stridesf); +const functionspace::FunctionSpaceImpl* atlas__Field__functionspace( FieldImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->functionspace().get(); ); + return 0; } -void atlas__Field__host_data_long_specf (FieldImpl* This, long* &data, int &rank, int* &shapef, int* &stridesf) -{ - atlas__Field__host_data_specf(This,data,rank,shapef,stridesf); +void atlas__Field__shapef( FieldImpl* This, int*& shape, int& rank ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); shape = const_cast( &This->shapef().front() ); + rank = This->shapef().size(); ); } -void atlas__Field__host_data_float_specf (FieldImpl* This, float* &data, int &rank, int* &shapef, int* &stridesf) -{ - atlas__Field__host_data_specf(This,data,rank,shapef,stridesf); +void atlas__Field__host_data_int_specf( FieldImpl* This, int*& data, int& rank, int*& shapef, int*& stridesf ) { + atlas__Field__host_data_specf( This, data, rank, shapef, stridesf ); +} +void atlas__Field__host_data_long_specf( FieldImpl* This, long*& data, int& rank, int*& shapef, int*& stridesf ) { + atlas__Field__host_data_specf( This, data, rank, shapef, stridesf ); } -void atlas__Field__host_data_double_specf (FieldImpl* This, double* &data, int &rank, int* &shapef, int* &stridesf) -{ - atlas__Field__host_data_specf(This,data,rank,shapef,stridesf); +void atlas__Field__host_data_float_specf( FieldImpl* This, float*& data, int& rank, int*& shapef, int*& stridesf ) { + atlas__Field__host_data_specf( This, data, rank, shapef, stridesf ); +} +void atlas__Field__host_data_double_specf( FieldImpl* This, double*& data, int& rank, int*& shapef, int*& stridesf ) { + atlas__Field__host_data_specf( This, data, rank, shapef, stridesf ); } -void atlas__Field__device_data_int_specf (FieldImpl* This, int* &data, int &rank, int* &shapef, int* &stridesf) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - data = This->device_data(); - shapef = const_cast(This->shapef().data()); - stridesf = const_cast(This->stridesf().data()); - rank = This->shapef().size(); - ); +void atlas__Field__device_data_int_specf( FieldImpl* This, int*& data, int& rank, int*& shapef, int*& stridesf ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); data = This->device_data(); + shapef = const_cast( This->shapef().data() ); + stridesf = const_cast( This->stridesf().data() ); rank = This->shapef().size(); ); } -void atlas__Field__device_data_long_specf (FieldImpl* This, long* &data, int &rank, int* &shapef, int* &stridesf) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - data = This->device_data(); - shapef = const_cast(This->shapef().data()); - stridesf = const_cast(This->stridesf().data()); - rank = This->shapef().size(); - ); +void atlas__Field__device_data_long_specf( FieldImpl* This, long*& data, int& rank, int*& shapef, int*& stridesf ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); data = This->device_data(); + shapef = const_cast( This->shapef().data() ); + stridesf = const_cast( This->stridesf().data() ); rank = This->shapef().size(); ); } -void atlas__Field__device_data_float_specf (FieldImpl* This, float* &data, int &rank, int* &shapef, int* &stridesf) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - data = This->device_data(); - shapef = const_cast(This->shapef().data()); - stridesf = const_cast(This->stridesf().data()); - rank = This->shapef().size(); - ); +void atlas__Field__device_data_float_specf( FieldImpl* This, float*& data, int& rank, int*& shapef, int*& stridesf ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); data = This->device_data(); + shapef = const_cast( This->shapef().data() ); + stridesf = const_cast( This->stridesf().data() ); rank = This->shapef().size(); ); } -void atlas__Field__device_data_double_specf (FieldImpl* This, double* &data, int &rank, int* &shapef, int* &stridesf) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - data = This->device_data(); - shapef = const_cast(This->shapef().data()); - stridesf = const_cast(This->stridesf().data()); - rank = This->shapef().size(); - ); +void atlas__Field__device_data_double_specf( FieldImpl* This, double*& data, int& rank, int*& shapef, int*& stridesf ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); data = This->device_data(); + shapef = const_cast( This->shapef().data() ); + stridesf = const_cast( This->stridesf().data() ); rank = This->shapef().size(); ); } -int atlas__Field__host_needs_update(const FieldImpl* This) -{ - return This->hostNeedsUpdate(); +int atlas__Field__host_needs_update( const FieldImpl* This ) { + return This->hostNeedsUpdate(); } -int atlas__Field__device_needs_update(const FieldImpl* This) -{ - return This->deviceNeedsUpdate(); +int atlas__Field__device_needs_update( const FieldImpl* This ) { + return This->deviceNeedsUpdate(); } -void atlas__Field__rename(FieldImpl* This, const char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - This->rename( std::string(name) ); - ); +void atlas__Field__rename( FieldImpl* This, const char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); This->rename( std::string( name ) ); ); } -void atlas__Field__set_levels(FieldImpl* This, int levels) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - This->set_levels(levels); - ); +void atlas__Field__set_levels( FieldImpl* This, int levels ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); This->set_levels( levels ); ); } -void atlas__Field__set_functionspace(FieldImpl* This, const functionspace::FunctionSpaceImpl* functionspace) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(functionspace); - This->set_functionspace( functionspace ); - ); +void atlas__Field__set_functionspace( FieldImpl* This, const functionspace::FunctionSpaceImpl* functionspace ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( functionspace ); This->set_functionspace( functionspace ); ); } -void atlas__Field__clone_to_device(FieldImpl* This) -{ - This->cloneToDevice(); +void atlas__Field__clone_to_device( FieldImpl* This ) { + This->cloneToDevice(); } -void atlas__Field__clone_from_device(FieldImpl* This) -{ - This->cloneFromDevice(); +void atlas__Field__clone_from_device( FieldImpl* This ) { + This->cloneFromDevice(); } -void atlas__Field__sync_host_device(FieldImpl* This) -{ - This->syncHostDevice(); +void atlas__Field__sync_host_device( FieldImpl* This ) { + This->syncHostDevice(); } - } // ------------------------------------------------------------------ -} // namespace field -} // namespace atlas - +} // namespace field +} // namespace atlas diff --git a/src/atlas/field/detail/FieldImpl.h b/src/atlas/field/detail/FieldImpl.h index 9a57144ff..66fe26f36 100644 --- a/src/atlas/field/detail/FieldImpl.h +++ b/src/atlas/field/detail/FieldImpl.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,16 +14,18 @@ #pragma once -#include #include -#include "eckit/memory/Owned.h" -#include "atlas/functionspace/FunctionSpace.h" -#include "atlas/array/DataType.h" -#include "atlas/array/ArrayUtil.h" +#include #include "atlas/array.h" +#include "atlas/array/ArrayUtil.h" +#include "atlas/array/DataType.h" +#include "atlas/functionspace/FunctionSpace.h" #include "atlas/util/Metadata.h" +#include "eckit/memory/Owned.h" -namespace eckit { class Parametrisation; } +namespace eckit { +class Parametrisation; +} namespace atlas { namespace field { @@ -30,241 +33,239 @@ namespace field { //---------------------------------------------------------------------------------------------------------------------- class FieldImpl : public eckit::Owned { +public: // Static methods + /// @brief Create field from parametrisation + static FieldImpl* create( const eckit::Parametrisation& ); -public: // Static methods - - /// @brief Create field from parametrisation - static FieldImpl* create(const eckit::Parametrisation&); - - /// @brief Create field with given name, Datatype and ArrayShape - static FieldImpl* create( - const std::string& name, array::DataType, - const array::ArrayShape& = array::ArrayShape()); - - /// @brief Create field with given name, Datatype of template and ArrayShape - template - static FieldImpl* create( const std::string& name, const array::ArrayShape& = array::ArrayShape() ); - - /// @brief Create field with given name, and take ownership of given Array - static FieldImpl* create( const std::string& name, array::Array* ); - - /// @brief Create field with given name, and share ownership of given Array - /// @note nawd: Not so sure we should go this route - /// static FieldImpl* create( const std::string& name, const eckit::SharedPtr& ); - - /// @brief Create field by wrapping existing data, Datatype of template and ArraySpec - template - static FieldImpl* wrap( const std::string& name, DATATYPE *data, const array::ArraySpec& ); - - /// @brief Create field by wrapping existing data, Datatype of template and ArrayShape - template - static FieldImpl* wrap( const std::string& name, DATATYPE *data, const array::ArrayShape& ); - -private: // Private constructors to force use of static create functions - - /// Allocate new Array internally - FieldImpl(const std::string& name, array::DataType, const array::ArrayShape&); - - /// Transfer ownership of Array - FieldImpl(const std::string& name, array::Array* ); - - /// Share ownership of Array - /// @note We could go this route... - /// Field(const std::string& name, const eckit::SharedPtr& ); - -public: // Destructor - virtual ~FieldImpl(); - -// -- Conversion - - /// @brief Implicit conversion to Array - operator const array::Array&() const { return *array_; } - operator array::Array&() { return *array_; } - - const array::Array& array() const { return *array_; } - array::Array& array() { return *array_; } - -// -- Accessors - - /// @brief Access to raw data - void* storage() { return array_->storage(); } - - /// @brief Internal data type of field - array::DataType datatype() const { return array_->datatype(); } - - /// @brief Name associated to this field - const std::string& name() const; - - /// @brief Rename this field - void rename(const std::string& name) { metadata().set("name",name); } - - /// @brief Access to metadata associated to this field - const util::Metadata& metadata() const { return metadata_; } - util::Metadata& metadata() { return metadata_; } - - /// @brief Resize field to given shape - void resize(const array::ArrayShape&); - - void insert(size_t idx1, size_t size1 ); - - /// @brief Shape of this field in Fortran style (reverse order of C style) - const std::vector& shapef() const { return array_->shapef(); } - - /// @brief Strides of this field in Fortran style (reverse order of C style) - const std::vector& stridesf() const { return array_->stridesf(); } - - /// @brief Shape of this field (reverse order of Fortran style) - const array::ArrayShape& shape() const { return array_->shape(); } - - /// @brief Strides of this field - const array::ArrayStrides& strides() const { return array_->strides(); } - - /// @brief Shape of this field associated to index 'i' - size_t shape (size_t i) const { return array_->shape(i); } - - /// @brief Stride of this field associated to index 'i' - size_t stride(size_t i) const { return array_->stride(i); } - - /// @brief Number of values stored in this field - size_t size() const { return array_->size(); } - - /// @brief Rank of field - size_t rank() const { return array_->rank(); } + /// @brief Create field with given name, Datatype and ArrayShape + static FieldImpl* create( const std::string& name, array::DataType, + const array::ArrayShape& = array::ArrayShape() ); - /// @brief Number of bytes occupied by the values of this field - double bytes() const { return array_->bytes(); } + /// @brief Create field with given name, Datatype of template and ArrayShape + template + static FieldImpl* create( const std::string& name, const array::ArrayShape& = array::ArrayShape() ); - /// @brief Output information of field - friend std::ostream& operator<<( std::ostream& os, const FieldImpl& v); + /// @brief Create field with given name, and take ownership of given Array + static FieldImpl* create( const std::string& name, array::Array* ); - /// @brief Output information of field plus raw data - void dump(std::ostream& os) const; + /// @brief Create field with given name, and share ownership of given Array + /// @note nawd: Not so sure we should go this route + /// static FieldImpl* create( const std::string& name, const + /// eckit::SharedPtr& ); - /// Metadata that is more intrinsic to the Field, and queried often - void set_levels(size_t n) { metadata().set("levels",n); } - void set_variables(size_t n) { metadata().set("variables",n); } - size_t levels() const { return metadata().get("levels"); } - size_t variables() const { return metadata().get("variables"); } + /// @brief Create field by wrapping existing data, Datatype of template and + /// ArraySpec + template + static FieldImpl* wrap( const std::string& name, DATATYPE* data, const array::ArraySpec& ); - void set_functionspace(const FunctionSpace &); - const FunctionSpace& functionspace() const { return functionspace_; } + /// @brief Create field by wrapping existing data, Datatype of template and + /// ArrayShape + template + static FieldImpl* wrap( const std::string& name, DATATYPE* data, const array::ArrayShape& ); - /// @brief Return the memory footprint of the Field - size_t footprint() const; +private: // Private constructors to force use of static create functions + /// Allocate new Array internally + FieldImpl( const std::string& name, array::DataType, const array::ArrayShape& ); -// -- dangerous methods - template DATATYPE const* host_data() const { return array_->host_data(); } - template DATATYPE* host_data() { return array_->host_data(); } - template DATATYPE const* device_data() const { return array_->device_data(); } - template DATATYPE* device_data() { return array_->device_data(); } - template DATATYPE const* data() const { return array_->host_data(); } - template DATATYPE* data() { return array_->host_data(); } + /// Transfer ownership of Array + FieldImpl( const std::string& name, array::Array* ); -// -- Methods related to host-device synchronisation, requires gridtools_storage - void cloneToDevice() const { - array_->cloneToDevice(); - } - void cloneFromDevice() const { - array_->cloneFromDevice(); - } - void syncHostDevice() const { - array_->syncHostDevice(); - } - bool hostNeedsUpdate() const { - return array_->hostNeedsUpdate(); - } - bool deviceNeedsUpdate() const { - return array_->deviceNeedsUpdate(); - } - void reactivateDeviceWriteViews() const { - array_->reactivateDeviceWriteViews(); - } - void reactivateHostWriteViews() const { - array_->reactivateHostWriteViews(); - } + /// Share ownership of Array + /// @note We could go this route... + /// Field(const std::string& name, const eckit::SharedPtr& ); -private: // methods +public: // Destructor + virtual ~FieldImpl(); - void print(std::ostream& os, bool dump=false) const; + // -- Conversion -private: // members + /// @brief Implicit conversion to Array + operator const array::Array&() const { return *array_; } + operator array::Array&() { return *array_; } - mutable std::string name_; - util::Metadata metadata_; - array::Array* array_; - FunctionSpace functionspace_; + const array::Array& array() const { return *array_; } + array::Array& array() { return *array_; } + + // -- Accessors + + /// @brief Access to raw data + void* storage() { return array_->storage(); } + + /// @brief Internal data type of field + array::DataType datatype() const { return array_->datatype(); } + + /// @brief Name associated to this field + const std::string& name() const; + + /// @brief Rename this field + void rename( const std::string& name ) { metadata().set( "name", name ); } + + /// @brief Access to metadata associated to this field + const util::Metadata& metadata() const { return metadata_; } + util::Metadata& metadata() { return metadata_; } + + /// @brief Resize field to given shape + void resize( const array::ArrayShape& ); + + void insert( size_t idx1, size_t size1 ); + + /// @brief Shape of this field in Fortran style (reverse order of C style) + const std::vector& shapef() const { return array_->shapef(); } + + /// @brief Strides of this field in Fortran style (reverse order of C style) + const std::vector& stridesf() const { return array_->stridesf(); } + + /// @brief Shape of this field (reverse order of Fortran style) + const array::ArrayShape& shape() const { return array_->shape(); } + + /// @brief Strides of this field + const array::ArrayStrides& strides() const { return array_->strides(); } + + /// @brief Shape of this field associated to index 'i' + size_t shape( size_t i ) const { return array_->shape( i ); } + + /// @brief Stride of this field associated to index 'i' + size_t stride( size_t i ) const { return array_->stride( i ); } + + /// @brief Number of values stored in this field + size_t size() const { return array_->size(); } + + /// @brief Rank of field + size_t rank() const { return array_->rank(); } + + /// @brief Number of bytes occupied by the values of this field + double bytes() const { return array_->bytes(); } + + /// @brief Output information of field + friend std::ostream& operator<<( std::ostream& os, const FieldImpl& v ); + + /// @brief Output information of field plus raw data + void dump( std::ostream& os ) const; + + /// Metadata that is more intrinsic to the Field, and queried often + void set_levels( size_t n ) { metadata().set( "levels", n ); } + void set_variables( size_t n ) { metadata().set( "variables", n ); } + size_t levels() const { return metadata().get( "levels" ); } + size_t variables() const { return metadata().get( "variables" ); } + + void set_functionspace( const FunctionSpace& ); + const FunctionSpace& functionspace() const { return functionspace_; } + + /// @brief Return the memory footprint of the Field + size_t footprint() const; + + // -- dangerous methods + template + DATATYPE const* host_data() const { + return array_->host_data(); + } + template + DATATYPE* host_data() { + return array_->host_data(); + } + template + DATATYPE const* device_data() const { + return array_->device_data(); + } + template + DATATYPE* device_data() { + return array_->device_data(); + } + template + DATATYPE const* data() const { + return array_->host_data(); + } + template + DATATYPE* data() { + return array_->host_data(); + } + + // -- Methods related to host-device synchronisation, requires + // gridtools_storage + void cloneToDevice() const { array_->cloneToDevice(); } + void cloneFromDevice() const { array_->cloneFromDevice(); } + void syncHostDevice() const { array_->syncHostDevice(); } + bool hostNeedsUpdate() const { return array_->hostNeedsUpdate(); } + bool deviceNeedsUpdate() const { return array_->deviceNeedsUpdate(); } + void reactivateDeviceWriteViews() const { array_->reactivateDeviceWriteViews(); } + void reactivateHostWriteViews() const { array_->reactivateHostWriteViews(); } + +private: // methods + void print( std::ostream& os, bool dump = false ) const; + +private: // members + mutable std::string name_; + util::Metadata metadata_; + array::Array* array_; + FunctionSpace functionspace_; }; //---------------------------------------------------------------------------------------------------------------------- -template -FieldImpl* FieldImpl::create( - const std::string& name, - const array::ArrayShape& shape ) -{ - return create(name, array::DataType::create(), shape); +template +FieldImpl* FieldImpl::create( const std::string& name, const array::ArrayShape& shape ) { + return create( name, array::DataType::create(), shape ); } -template -FieldImpl* FieldImpl::wrap( - const std::string& name, - DATATYPE *data, - const array::ArraySpec& spec) -{ - return create(name, array::Array::wrap(data,spec)); +template +FieldImpl* FieldImpl::wrap( const std::string& name, DATATYPE* data, const array::ArraySpec& spec ) { + return create( name, array::Array::wrap( data, spec ) ); } -template -FieldImpl* FieldImpl::wrap( - const std::string& name, - DATATYPE *data, - const array::ArrayShape& shape) -{ - return create(name, array::Array::wrap(data,shape)); +template +FieldImpl* FieldImpl::wrap( const std::string& name, DATATYPE* data, const array::ArrayShape& shape ) { + return create( name, array::Array::wrap( data, shape ) ); } //---------------------------------------------------------------------------------------------------------------------- // C wrapper interfaces to C++ routines // #define Char char -extern "C" -{ - FieldImpl* atlas__Field__wrap_int_specf(const char* name, int data[], int rank, int shapef[], int stridesf[]); - FieldImpl* atlas__Field__wrap_long_specf(const char* name, long data[], int rank, int shapef[], int stridesf[]); - FieldImpl* atlas__Field__wrap_float_specf(const char* name, float data[], int rank, int shapef[], int stridesf[]); - FieldImpl* atlas__Field__wrap_double_specf(const char* name, double data[], int rank, int shapef[], int stridesf[]); - FieldImpl* atlas__Field__create(eckit::Parametrisation* params); - void atlas__Field__delete (FieldImpl* This); - const char* atlas__Field__name (FieldImpl* This); - void atlas__Field__datatype (FieldImpl* This, char* &datatype, int &size, int &allocated); - int atlas__Field__kind (FieldImpl* This); - int atlas__Field__rank (FieldImpl* This); - int atlas__Field__size (FieldImpl* This); - int atlas__Field__levels (FieldImpl* This); - double atlas__Field__bytes (FieldImpl* This); - void atlas__Field__shapef (FieldImpl* This, int* &shape, int &rank); - void atlas__Field__host_data_int_specf (FieldImpl* This, int* &field_data, int &rank, int* &field_shapef, int* &field_stridesf); - void atlas__Field__host_data_long_specf (FieldImpl* This, long* &field_data, int &rank, int* &field_shapef, int* &field_stridesf); - void atlas__Field__host_data_float_specf (FieldImpl* This, float* &field_data, int &rank, int* &field_shapef, int* &field_stridesf); - void atlas__Field__host_data_double_specf (FieldImpl* This, double* &field_data, int &rank, int* &field_shapef, int* &field_stridesf); - void atlas__Field__device_data_int_specf (FieldImpl* This, int* &field_data, int &rank, int* &field_shapef, int* &field_stridesf); - void atlas__Field__device_data_long_specf (FieldImpl* This, long* &field_data, int &rank, int* &field_shapef, int* &field_stridesf); - void atlas__Field__device_data_float_specf (FieldImpl* This, float* &field_data, int &rank, int* &field_shapef, int* &field_stridesf); - void atlas__Field__device_data_double_specf (FieldImpl* This, double* &field_data, int &rank, int* &field_shapef, int* &field_stridesf); - util::Metadata* atlas__Field__metadata (FieldImpl* This); - const functionspace::FunctionSpaceImpl* atlas__Field__functionspace (FieldImpl* This); - void atlas__Field__rename(FieldImpl* This, const char* name); - void atlas__Field__set_levels(FieldImpl* This, int levels); - void atlas__Field__set_functionspace(FieldImpl* This, const functionspace::FunctionSpaceImpl* functionspace); - int atlas__Field__host_needs_update(const FieldImpl* This); - int atlas__Field__device_needs_update(const FieldImpl* This); - void atlas__Field__clone_to_device(FieldImpl* This); - void atlas__Field__clone_from_device(FieldImpl* This); - void atlas__Field__sync_host_device(FieldImpl* This); +extern "C" { +FieldImpl* atlas__Field__wrap_int_specf( const char* name, int data[], int rank, int shapef[], int stridesf[] ); +FieldImpl* atlas__Field__wrap_long_specf( const char* name, long data[], int rank, int shapef[], int stridesf[] ); +FieldImpl* atlas__Field__wrap_float_specf( const char* name, float data[], int rank, int shapef[], int stridesf[] ); +FieldImpl* atlas__Field__wrap_double_specf( const char* name, double data[], int rank, int shapef[], int stridesf[] ); +FieldImpl* atlas__Field__create( eckit::Parametrisation* params ); +void atlas__Field__delete( FieldImpl* This ); +const char* atlas__Field__name( FieldImpl* This ); +void atlas__Field__datatype( FieldImpl* This, char*& datatype, int& size, int& allocated ); +int atlas__Field__kind( FieldImpl* This ); +int atlas__Field__rank( FieldImpl* This ); +int atlas__Field__size( FieldImpl* This ); +int atlas__Field__levels( FieldImpl* This ); +double atlas__Field__bytes( FieldImpl* This ); +void atlas__Field__shapef( FieldImpl* This, int*& shape, int& rank ); +void atlas__Field__host_data_int_specf( FieldImpl* This, int*& field_data, int& rank, int*& field_shapef, + int*& field_stridesf ); +void atlas__Field__host_data_long_specf( FieldImpl* This, long*& field_data, int& rank, int*& field_shapef, + int*& field_stridesf ); +void atlas__Field__host_data_float_specf( FieldImpl* This, float*& field_data, int& rank, int*& field_shapef, + int*& field_stridesf ); +void atlas__Field__host_data_double_specf( FieldImpl* This, double*& field_data, int& rank, int*& field_shapef, + int*& field_stridesf ); +void atlas__Field__device_data_int_specf( FieldImpl* This, int*& field_data, int& rank, int*& field_shapef, + int*& field_stridesf ); +void atlas__Field__device_data_long_specf( FieldImpl* This, long*& field_data, int& rank, int*& field_shapef, + int*& field_stridesf ); +void atlas__Field__device_data_float_specf( FieldImpl* This, float*& field_data, int& rank, int*& field_shapef, + int*& field_stridesf ); +void atlas__Field__device_data_double_specf( FieldImpl* This, double*& field_data, int& rank, int*& field_shapef, + int*& field_stridesf ); +util::Metadata* atlas__Field__metadata( FieldImpl* This ); +const functionspace::FunctionSpaceImpl* atlas__Field__functionspace( FieldImpl* This ); +void atlas__Field__rename( FieldImpl* This, const char* name ); +void atlas__Field__set_levels( FieldImpl* This, int levels ); +void atlas__Field__set_functionspace( FieldImpl* This, const functionspace::FunctionSpaceImpl* functionspace ); +int atlas__Field__host_needs_update( const FieldImpl* This ); +int atlas__Field__device_needs_update( const FieldImpl* This ); +void atlas__Field__clone_to_device( FieldImpl* This ); +void atlas__Field__clone_from_device( FieldImpl* This ); +void atlas__Field__sync_host_device( FieldImpl* This ); } // #undef Char //---------------------------------------------------------------------------------------------------------------------- -} // namespace field -} // namespace atlas +} // namespace field +} // namespace atlas diff --git a/src/atlas/functionspace.h b/src/atlas/functionspace.h index 99a07ac9a..bbe881141 100644 --- a/src/atlas/functionspace.h +++ b/src/atlas/functionspace.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,9 +13,9 @@ #pragma once +#include "atlas/functionspace/EdgeColumns.h" #include "atlas/functionspace/FunctionSpace.h" #include "atlas/functionspace/NodeColumns.h" -#include "atlas/functionspace/EdgeColumns.h" -#include "atlas/functionspace/StructuredColumns.h" -#include "atlas/functionspace/Spectral.h" #include "atlas/functionspace/PointCloud.h" +#include "atlas/functionspace/Spectral.h" +#include "atlas/functionspace/StructuredColumns.h" diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 81558c9af..58c4b57ab 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -17,12 +18,12 @@ #include "atlas/array/MakeView.h" #include "atlas/functionspace/EdgeColumns.h" #include "atlas/library/config.h" -#include "atlas/mesh/actions/BuildHalo.h" -#include "atlas/mesh/actions/BuildParallelFields.h" -#include "atlas/mesh/actions/BuildPeriodicBoundaries.h" #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/IsGhostNode.h" #include "atlas/mesh/Mesh.h" +#include "atlas/mesh/actions/BuildHalo.h" +#include "atlas/mesh/actions/BuildParallelFields.h" +#include "atlas/mesh/actions/BuildPeriodicBoundaries.h" #include "atlas/parallel/Checksum.h" #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/HaloExchange.h" @@ -32,584 +33,523 @@ #include "atlas/runtime/Trace.h" #include "atlas/util/detail/Cache.h" - #ifdef ATLAS_HAVE_FORTRAN #define REMOTE_IDX_BASE 1 #else #define REMOTE_IDX_BASE 0 #endif - namespace atlas { namespace functionspace { namespace detail { namespace { 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() ); - } else { - return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); +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() ); } + else { + return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); + } } - } - else { - if( field.variables() ) { - return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); - } else { - return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + else { + if ( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); + } + else { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + } } - } -} } +} // namespace -class EdgeColumnsHaloExchangeCache : - public util::Cache, - public mesh::detail::MeshObserver -{ +class EdgeColumnsHaloExchangeCache : public util::Cache, + public mesh::detail::MeshObserver { private: - using Base = util::Cache; - EdgeColumnsHaloExchangeCache() : Base("EdgeColumnsHaloExchangeCache") {} + using Base = util::Cache; + EdgeColumnsHaloExchangeCache() : Base( "EdgeColumnsHaloExchangeCache" ) {} + public: - static EdgeColumnsHaloExchangeCache& instance() { - static EdgeColumnsHaloExchangeCache inst; - return inst; - } - eckit::SharedPtr get_or_create( const Mesh& mesh ) { - creator_type creator = std::bind( &EdgeColumnsHaloExchangeCache::create, mesh ); - return Base::get_or_create( key(*mesh.get()), creator ); - } - virtual void onMeshDestruction(mesh::detail::MeshImpl& mesh) { - remove( key(mesh) ); - } + static EdgeColumnsHaloExchangeCache& instance() { + static EdgeColumnsHaloExchangeCache inst; + return inst; + } + eckit::SharedPtr get_or_create( const Mesh& mesh ) { + creator_type creator = std::bind( &EdgeColumnsHaloExchangeCache::create, mesh ); + return Base::get_or_create( key( *mesh.get() ), creator ); + } + virtual void onMeshDestruction( mesh::detail::MeshImpl& mesh ) { remove( key( mesh ) ); } private: + static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { + std::ostringstream key; + key << "mesh[address=" << &mesh << "]"; + return key.str(); + } - static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { - std::ostringstream key ; - key << "mesh[address="<<&mesh<<"]"; - return key.str(); - } - - static value_type* create( const Mesh& mesh ) { - mesh.get()->attachObserver(instance()); - value_type* value = new value_type(); - value->setup( array::make_view(mesh.edges().partition()).data(), - array::make_view(mesh.edges().remote_index()).data(), - REMOTE_IDX_BASE, - mesh.edges().size()); - return value; - } + static value_type* create( const Mesh& mesh ) { + mesh.get()->attachObserver( instance() ); + value_type* value = new value_type(); + value->setup( array::make_view( mesh.edges().partition() ).data(), + array::make_view( mesh.edges().remote_index() ).data(), REMOTE_IDX_BASE, + mesh.edges().size() ); + return value; + } }; -class EdgeColumnsGatherScatterCache : - public util::Cache, - public mesh::detail::MeshObserver -{ +class EdgeColumnsGatherScatterCache : public util::Cache, + public mesh::detail::MeshObserver { private: - using Base = util::Cache; - EdgeColumnsGatherScatterCache() : Base("EdgeColumnsGatherScatterCache"){} + using Base = util::Cache; + EdgeColumnsGatherScatterCache() : Base( "EdgeColumnsGatherScatterCache" ) {} + public: - static EdgeColumnsGatherScatterCache& instance() { - static EdgeColumnsGatherScatterCache inst; - return inst; - } - eckit::SharedPtr get_or_create( const Mesh& mesh ) { - creator_type creator = std::bind( &EdgeColumnsGatherScatterCache::create, mesh ); - return Base::get_or_create( key(*mesh.get()), creator ); - } - virtual void onMeshDestruction(mesh::detail::MeshImpl& mesh) { - remove( key(mesh) ); - } + static EdgeColumnsGatherScatterCache& instance() { + static EdgeColumnsGatherScatterCache inst; + return inst; + } + eckit::SharedPtr get_or_create( const Mesh& mesh ) { + creator_type creator = std::bind( &EdgeColumnsGatherScatterCache::create, mesh ); + return Base::get_or_create( key( *mesh.get() ), creator ); + } + virtual void onMeshDestruction( mesh::detail::MeshImpl& mesh ) { remove( key( mesh ) ); } private: + static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { + std::ostringstream key; + key << "mesh[address=" << &mesh << "]"; + return key.str(); + } - static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { - std::ostringstream key ; - key << "mesh[address="<<&mesh<<"]"; - return key.str(); - } - - static value_type* create( const Mesh& mesh ) { - mesh.get()->attachObserver(instance()); - value_type* value = new value_type(); - value->setup(array::make_view(mesh.edges().partition()).data(), - array::make_view(mesh.edges().remote_index()).data(), - REMOTE_IDX_BASE, - array::make_view(mesh.edges().global_index()).data(), - mesh.edges().size()); - return value; - } + static value_type* create( const Mesh& mesh ) { + mesh.get()->attachObserver( instance() ); + value_type* value = new value_type(); + value->setup( array::make_view( mesh.edges().partition() ).data(), + array::make_view( mesh.edges().remote_index() ).data(), REMOTE_IDX_BASE, + array::make_view( mesh.edges().global_index() ).data(), mesh.edges().size() ); + return value; + } }; -class EdgeColumnsChecksumCache : - public util::Cache, - public mesh::detail::MeshObserver -{ +class EdgeColumnsChecksumCache : public util::Cache, + public mesh::detail::MeshObserver { private: - using Base = util::Cache; - EdgeColumnsChecksumCache() : Base("EdgeColumnsChecksumCache") {} + using Base = util::Cache; + EdgeColumnsChecksumCache() : Base( "EdgeColumnsChecksumCache" ) {} + public: - static EdgeColumnsChecksumCache& instance() { - static EdgeColumnsChecksumCache inst; - return inst; - } - eckit::SharedPtr get_or_create( const Mesh& mesh ) { - creator_type creator = std::bind( &EdgeColumnsChecksumCache::create, mesh ); - return Base::get_or_create( key(*mesh.get()), creator ); - } - virtual void onMeshDestruction(mesh::detail::MeshImpl& mesh) { - remove( key(mesh) ); - } + static EdgeColumnsChecksumCache& instance() { + static EdgeColumnsChecksumCache inst; + return inst; + } + eckit::SharedPtr get_or_create( const Mesh& mesh ) { + creator_type creator = std::bind( &EdgeColumnsChecksumCache::create, mesh ); + return Base::get_or_create( key( *mesh.get() ), creator ); + } + virtual void onMeshDestruction( mesh::detail::MeshImpl& mesh ) { remove( key( mesh ) ); } private: + static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { + std::ostringstream key; + key << "mesh[address=" << &mesh << "]"; + return key.str(); + } - static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { - std::ostringstream key ; - key << "mesh[address="<<&mesh<<"]"; - return key.str(); - } - - static value_type* create( const Mesh& mesh ) { - mesh.get()->attachObserver(instance()); - value_type* value = new value_type(); - eckit::SharedPtr gather( EdgeColumnsGatherScatterCache::instance().get_or_create(mesh) ); - value->setup( gather ); - return value; - } + static value_type* create( const Mesh& mesh ) { + mesh.get()->attachObserver( instance() ); + value_type* value = new value_type(); + eckit::SharedPtr gather( + EdgeColumnsGatherScatterCache::instance().get_or_create( mesh ) ); + value->setup( gather ); + return value; + } }; -void EdgeColumns::set_field_metadata(const eckit::Configuration& config, Field& field) const -{ - field.set_functionspace(this); +void EdgeColumns::set_field_metadata( const eckit::Configuration& config, Field& field ) const { + field.set_functionspace( this ); - bool global(false); - if( config.get("global",global) ) - { - if( global ) - { - size_t owner(0); - config.get("owner",owner); - field.metadata().set("owner",owner); + bool global( false ); + if ( config.get( "global", global ) ) { + if ( global ) { + size_t owner( 0 ); + config.get( "owner", owner ); + field.metadata().set( "owner", owner ); + } } - } - field.metadata().set("global",global); - - size_t levels(nb_levels_); - config.get("levels",levels); - field.set_levels(levels); - - size_t variables(0); - config.get("variables",variables); - field.set_variables(variables); -} - -size_t EdgeColumns::config_size(const eckit::Configuration& config) const -{ - size_t size = nb_edges(); - bool global(false); - if( config.get("global",global) ) - { - if( global ) - { - size_t owner(0); - config.get("owner",owner); - size_t _nb_edges_global( nb_edges_global() ); - size = (mpi::comm().rank() == owner ? _nb_edges_global : 0); + field.metadata().set( "global", global ); + + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + field.set_levels( levels ); + + size_t variables( 0 ); + config.get( "variables", variables ); + field.set_variables( variables ); +} + +size_t EdgeColumns::config_size( const eckit::Configuration& config ) const { + size_t size = nb_edges(); + bool global( false ); + if ( config.get( "global", global ) ) { + if ( global ) { + size_t owner( 0 ); + config.get( "owner", owner ); + size_t _nb_edges_global( nb_edges_global() ); + size = ( mpi::comm().rank() == owner ? _nb_edges_global : 0 ); + } } - } - return size; + return size; } -array::DataType EdgeColumns::config_datatype(const eckit::Configuration& config) const -{ - array::DataType::kind_t kind; - if( ! config.get("datatype",kind) ) throw eckit::AssertionFailed("datatype missing",Here()); - return array::DataType(kind); +array::DataType EdgeColumns::config_datatype( const eckit::Configuration& config ) const { + array::DataType::kind_t kind; + if ( !config.get( "datatype", kind ) ) throw eckit::AssertionFailed( "datatype missing", Here() ); + return array::DataType( kind ); } -std::string EdgeColumns::config_name(const eckit::Configuration& config) const -{ - std::string name; - config.get("name",name); - return name; +std::string EdgeColumns::config_name( const eckit::Configuration& config ) const { + std::string name; + config.get( "name", name ); + return name; } -size_t EdgeColumns::config_levels(const eckit::Configuration& config) const -{ - size_t levels(nb_levels_); - config.get("levels",levels); - return levels; +size_t EdgeColumns::config_levels( const eckit::Configuration& config ) const { + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + return levels; } -array::ArrayShape EdgeColumns::config_shape(const eckit::Configuration& config) const { - array::ArrayShape shape; +array::ArrayShape EdgeColumns::config_shape( const eckit::Configuration& config ) const { + array::ArrayShape shape; - shape.push_back(config_size(config)); + shape.push_back( config_size( config ) ); - size_t levels(nb_levels_); - config.get("levels",levels); - if( levels > 0 ) shape.push_back(levels); + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + if ( levels > 0 ) shape.push_back( levels ); - size_t variables(0); - config.get("variables",variables); - if( variables > 0 ) shape.push_back(variables); + size_t variables( 0 ); + config.get( "variables", variables ); + if ( variables > 0 ) shape.push_back( variables ); - return shape; + return shape; } -EdgeColumns::EdgeColumns( const Mesh& mesh, const eckit::Configuration ¶ms ) : - mesh_(mesh), - nb_levels_(0), - edges_(mesh_.edges()), - nb_edges_(0) -{ - nb_levels_ = config_levels(params); +EdgeColumns::EdgeColumns( const Mesh& mesh, const eckit::Configuration& params ) : + mesh_( mesh ), + nb_levels_( 0 ), + edges_( mesh_.edges() ), + nb_edges_( 0 ) { + nb_levels_ = config_levels( params ); - size_t mesh_halo(0); - mesh.metadata().get("halo",mesh_halo); + size_t mesh_halo( 0 ); + mesh.metadata().get( "halo", mesh_halo ); - size_t halo = mesh_halo; - params.get("halo",halo); + size_t halo = mesh_halo; + params.get( "halo", halo ); - ASSERT( mesh_halo == halo ); + ASSERT( mesh_halo == halo ); - constructor(); + constructor(); } -EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo &halo, const eckit::Configuration ¶ms ) : - mesh_(mesh), - nb_levels_(0), - edges_(mesh_.edges()), - nb_edges_(0) -{ - size_t mesh_halo_size_; - mesh.metadata().get("halo",mesh_halo_size_); - ASSERT( mesh_halo_size_ == halo.size() ); +EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo& halo, const eckit::Configuration& params ) : + mesh_( mesh ), + nb_levels_( 0 ), + edges_( mesh_.edges() ), + nb_edges_( 0 ) { + size_t mesh_halo_size_; + mesh.metadata().get( "halo", mesh_halo_size_ ); + ASSERT( mesh_halo_size_ == halo.size() ); - nb_levels_ = config_levels(params); + nb_levels_ = config_levels( params ); - constructor(); + constructor(); } -EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo &halo) : - mesh_(mesh), - nb_levels_(0), - edges_(mesh_.edges()), - nb_edges_(0) -{ - size_t mesh_halo_size_; - mesh.metadata().get("halo",mesh_halo_size_); - ASSERT( mesh_halo_size_ == halo.size() ); - constructor(); +EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo& halo ) : + mesh_( mesh ), + nb_levels_( 0 ), + edges_( mesh_.edges() ), + nb_edges_( 0 ) { + size_t mesh_halo_size_; + mesh.metadata().get( "halo", mesh_halo_size_ ); + ASSERT( mesh_halo_size_ == halo.size() ); + constructor(); } +void EdgeColumns::constructor() { + ATLAS_TRACE( "EdgeColumns()" ); -void EdgeColumns::constructor() -{ - ATLAS_TRACE("EdgeColumns()"); - - nb_edges_ = mesh().edges().size(); + nb_edges_ = mesh().edges().size(); -// ATLAS_TRACE_SCOPE("HaloExchange") { -// halo_exchange_ = EdgeColumnsHaloExchangeCache::instance().get( mesh_ ); -// } + // ATLAS_TRACE_SCOPE("HaloExchange") { + // halo_exchange_ = EdgeColumnsHaloExchangeCache::instance().get( mesh_ ); + // } -// ATLAS_TRACE_SCOPE("Setup gather_scatter") { -// gather_scatter_.reset( EdgeColumnsGatherScatterCache::instance().get( mesh_ ) ); -// } - - // ATLAS_TRACE_SCOPE("Setup checksum") { - // checksum_.reset( EdgeColumnsChecksumCache::instance().get( mesh_ ) ); - // } + // ATLAS_TRACE_SCOPE("Setup gather_scatter") { + // gather_scatter_.reset( EdgeColumnsGatherScatterCache::instance().get( + // mesh_ ) ); + // } + // ATLAS_TRACE_SCOPE("Setup checksum") { + // checksum_.reset( EdgeColumnsChecksumCache::instance().get( mesh_ ) ); + // } } EdgeColumns::~EdgeColumns() {} size_t EdgeColumns::footprint() const { - size_t size = sizeof(*this); - // TODO - return size; + size_t size = sizeof( *this ); + // TODO + return size; } std::string EdgeColumns::distribution() const { - return mesh().metadata().getString("distribution"); + return mesh().metadata().getString( "distribution" ); } -size_t EdgeColumns::nb_edges() const -{ - return nb_edges_; +size_t EdgeColumns::nb_edges() const { + return nb_edges_; } -size_t EdgeColumns::nb_edges_global() const -{ - if( nb_edges_global_ >= 0 ) return nb_edges_global_; - nb_edges_global_ = gather().glb_dof(); - return nb_edges_global_; +size_t EdgeColumns::nb_edges_global() const { + if ( nb_edges_global_ >= 0 ) return nb_edges_global_; + nb_edges_global_ = gather().glb_dof(); + return nb_edges_global_; } -Field EdgeColumns::createField(const eckit::Configuration& options) const -{ - size_t nb_edges = config_size(options); - Field field( config_name(options), config_datatype(options), config_shape(options) ); - set_field_metadata(options,field); - return field; +Field EdgeColumns::createField( const eckit::Configuration& options ) const { + size_t nb_edges = config_size( options ); + Field field( config_name( options ), config_datatype( options ), config_shape( options ) ); + set_field_metadata( options, field ); + return field; } -Field EdgeColumns::createField( - const Field& other, - const eckit::Configuration& config ) const -{ - return createField( - option::datatype ( other.datatype() ) | - option::levels ( other.levels() ) | - option::variables( other.variables() ) | - config ); +Field EdgeColumns::createField( const Field& other, const eckit::Configuration& config ) const { + return createField( option::datatype( other.datatype() ) | option::levels( other.levels() ) | + option::variables( other.variables() ) | config ); } - -void EdgeColumns::haloExchange( FieldSet& fieldset ) const -{ - for( size_t f=0; f() ) { - halo_exchange().execute( field.array(), false ); - } - else if( field.datatype() == array::DataType::kind() ) { - halo_exchange().execute( field.array(), false ); - } - else if( field.datatype() == array::DataType::kind() ) { - halo_exchange().execute( field.array(), false ); - } - else if( field.datatype() == array::DataType::kind() ) { - halo_exchange().execute( field.array(), false ); +void EdgeColumns::haloExchange( FieldSet& fieldset ) const { + for ( size_t f = 0; f < fieldset.size(); ++f ) { + Field& field = fieldset[f]; + if ( field.datatype() == array::DataType::kind() ) { + halo_exchange().execute( field.array(), false ); + } + else if ( field.datatype() == array::DataType::kind() ) { + halo_exchange().execute( field.array(), false ); + } + else if ( field.datatype() == array::DataType::kind() ) { + halo_exchange().execute( field.array(), false ); + } + else if ( field.datatype() == array::DataType::kind() ) { + halo_exchange().execute( field.array(), false ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); } - else throw eckit::Exception("datatype not supported",Here()); - } } -void EdgeColumns::haloExchange( Field& field ) const -{ +void EdgeColumns::haloExchange( Field& field ) const { FieldSet fieldset; - fieldset.add(field); - haloExchange(fieldset); + fieldset.add( field ); + haloExchange( fieldset ); } -const parallel::HaloExchange& EdgeColumns::halo_exchange() const -{ - if (halo_exchange_) return *halo_exchange_; - halo_exchange_ = EdgeColumnsHaloExchangeCache::instance().get_or_create( mesh_ ); - return *halo_exchange_; -} - - -void EdgeColumns::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset ) const -{ - ASSERT(local_fieldset.size() == global_fieldset.size()); - - for( size_t f=0; f() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather().gather( &loc_field, &glb_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather().gather( &loc_field, &glb_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather().gather( &loc_field, &glb_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather().gather( &loc_field, &glb_field, nb_fields, root ); +const parallel::HaloExchange& EdgeColumns::halo_exchange() const { + if ( halo_exchange_ ) return *halo_exchange_; + halo_exchange_ = EdgeColumnsHaloExchangeCache::instance().get_or_create( mesh_ ); + return *halo_exchange_; +} + +void EdgeColumns::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset ) const { + ASSERT( local_fieldset.size() == global_fieldset.size() ); + + for ( size_t f = 0; f < local_fieldset.size(); ++f ) { + const Field& loc = local_fieldset[f]; + Field& glb = global_fieldset[f]; + const size_t nb_fields = 1; + size_t root( 0 ); + glb.metadata().get( "owner", root ); + if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather().gather( &loc_field, &glb_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather().gather( &loc_field, &glb_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather().gather( &loc_field, &glb_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather().gather( &loc_field, &glb_field, nb_fields, root ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); } - else throw eckit::Exception("datatype not supported",Here()); - } } -void EdgeColumns::gather( const Field& local, Field& global ) const -{ - FieldSet local_fields; - FieldSet global_fields; - local_fields.add(local); - global_fields.add(global); - gather(local_fields,global_fields); +void EdgeColumns::gather( const Field& local, Field& global ) const { + FieldSet local_fields; + FieldSet global_fields; + local_fields.add( local ); + global_fields.add( global ); + gather( local_fields, global_fields ); } -const parallel::GatherScatter& EdgeColumns::gather() const -{ - if( gather_scatter_ ) +const parallel::GatherScatter& EdgeColumns::gather() const { + if ( gather_scatter_ ) return *gather_scatter_; + gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; - gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); - return *gather_scatter_; } -const parallel::GatherScatter& EdgeColumns::scatter() const -{ - if( gather_scatter_ ) +const parallel::GatherScatter& EdgeColumns::scatter() const { + if ( gather_scatter_ ) return *gather_scatter_; + gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); return *gather_scatter_; - gather_scatter_ = EdgeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); - return *gather_scatter_; } - -void EdgeColumns::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldset ) const -{ - ASSERT(local_fieldset.size() == global_fieldset.size()); - - for( size_t f=0; f() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - scatter().scatter( &glb_field, &loc_field, nb_fields, root ); +void EdgeColumns::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldset ) const { + ASSERT( local_fieldset.size() == global_fieldset.size() ); + + for ( size_t f = 0; f < local_fieldset.size(); ++f ) { + const Field& glb = global_fieldset[f]; + Field& loc = local_fieldset[f]; + const size_t nb_fields = 1; + size_t root( 0 ); + glb.metadata().get( "owner", root ); + + if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + scatter().scatter( &glb_field, &loc_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + scatter().scatter( &glb_field, &loc_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + scatter().scatter( &glb_field, &loc_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + scatter().scatter( &glb_field, &loc_field, nb_fields, root ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); + + glb.metadata().broadcast( loc.metadata(), root ); + loc.metadata().set( "global", false ); } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - scatter().scatter( &glb_field, &loc_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - scatter().scatter( &glb_field, &loc_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - scatter().scatter( &glb_field, &loc_field, nb_fields, root ); - } - else throw eckit::Exception("datatype not supported",Here()); - - glb.metadata().broadcast(loc.metadata(),root); - loc.metadata().set("global",false); - } } -void EdgeColumns::scatter( const Field& global, Field& local ) const -{ - FieldSet global_fields; - FieldSet local_fields; - global_fields.add(global); - local_fields.add(local); - scatter(global_fields,local_fields); +void EdgeColumns::scatter( const Field& global, Field& local ) const { + FieldSet global_fields; + FieldSet local_fields; + global_fields.add( global ); + local_fields.add( local ); + scatter( global_fields, local_fields ); } namespace { template -std::string checksum_3d_field(const parallel::Checksum& checksum, const Field& field ) -{ - array::ArrayView values = array::make_view(field); - array::ArrayT surface_field( field.shape(0),field.shape(2) ); - array::ArrayView surface = array::make_view(surface_field); - for( size_t n=0; n values = array::make_view( field ); + array::ArrayT surface_field( field.shape( 0 ), field.shape( 2 ) ); + array::ArrayView surface = array::make_view( surface_field ); + for ( size_t n = 0; n < values.shape( 0 ); ++n ) { + for ( size_t j = 0; j < surface.shape( 1 ); ++j ) { + surface( n, j ) = 0.; + for ( size_t l = 0; l < values.shape( 1 ); ++l ) + surface( n, j ) += values( n, l, j ); + } } - } - return checksum.execute( surface.data(), surface_field.stride(0) ); + return checksum.execute( surface.data(), surface_field.stride( 0 ) ); } template -std::string checksum_2d_field(const parallel::Checksum& checksum, const Field& field ) -{ - array::ArrayView values = array::make_view(field); - return checksum.execute( values.data(), field.stride(0) ); +std::string checksum_2d_field( const parallel::Checksum& checksum, const Field& field ) { + array::ArrayView values = array::make_view( field ); + return checksum.execute( values.data(), field.stride( 0 ) ); } -} +} // namespace std::string EdgeColumns::checksum( const FieldSet& fieldset ) const { - eckit::MD5 md5; - for( size_t f=0; f() ) { - if( field.levels() ) - md5 << checksum_3d_field(checksum(),field); - else - md5 << checksum_2d_field(checksum(),field); - } - else if( field.datatype() == array::DataType::kind() ) { - if( field.levels() ) - md5 << checksum_3d_field(checksum(),field); - else - md5 << checksum_2d_field(checksum(),field); - } - else if( field.datatype() == array::DataType::kind() ) { - if( field.levels() ) - md5 << checksum_3d_field(checksum(),field); - else - md5 << checksum_2d_field(checksum(),field); + eckit::MD5 md5; + for ( size_t f = 0; f < fieldset.size(); ++f ) { + const Field& field = fieldset[f]; + if ( field.datatype() == array::DataType::kind() ) { + if ( field.levels() ) + md5 << checksum_3d_field( checksum(), field ); + else + md5 << checksum_2d_field( checksum(), field ); + } + else if ( field.datatype() == array::DataType::kind() ) { + if ( field.levels() ) + md5 << checksum_3d_field( checksum(), field ); + else + md5 << checksum_2d_field( checksum(), field ); + } + else if ( field.datatype() == array::DataType::kind() ) { + if ( field.levels() ) + md5 << checksum_3d_field( checksum(), field ); + else + md5 << checksum_2d_field( checksum(), field ); + } + else if ( field.datatype() == array::DataType::kind() ) { + if ( field.levels() ) + md5 << checksum_3d_field( checksum(), field ); + else + md5 << checksum_2d_field( checksum(), field ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); } - else if( field.datatype() == array::DataType::kind() ) { - if( field.levels() ) - md5 << checksum_3d_field(checksum(),field); - else - md5 << checksum_2d_field(checksum(),field); - } - else throw eckit::Exception("datatype not supported",Here()); - } - return md5; + return md5; } std::string EdgeColumns::checksum( const Field& field ) const { - FieldSet fieldset; - fieldset.add(field); - return checksum(fieldset); + FieldSet fieldset; + fieldset.add( field ); + return checksum( fieldset ); } -const parallel::Checksum& EdgeColumns::checksum() const -{ - if (checksum_) return *checksum_; - checksum_ = EdgeColumnsChecksumCache::instance().get_or_create( mesh_ ) ; - return *checksum_; +const parallel::Checksum& EdgeColumns::checksum() const { + if ( checksum_ ) return *checksum_; + checksum_ = EdgeColumnsChecksumCache::instance().get_or_create( mesh_ ); + return *checksum_; } namespace { -void reverse_copy(const int variables[], const int size, std::vector &reverse) -{ - int r=size; - for( int i=0; i(variables[i]); - } +void reverse_copy( const int variables[], const int size, std::vector& reverse ) { + int r = size; + for ( int i = 0; i < size; ++i ) { + reverse[--r] = static_cast( variables[i] ); + } } -void copy(const int variables[], const int size, std::vector &cpy) -{ - for( int i=0; i(variables[i]); - } +void copy( const int variables[], const int size, std::vector& cpy ) { + for ( int i = 0; i < size; ++i ) { + cpy[i] = static_cast( variables[i] ); + } } -std::vector variables_to_vector( const int variables[], const int size, bool fortran_ordering ) -{ - std::vector vec(size); - if (fortran_ordering) - reverse_copy(variables,size,vec); - else - copy(variables,size,vec); - return vec; -} +std::vector variables_to_vector( const int variables[], const int size, bool fortran_ordering ) { + std::vector vec( size ); + if ( fortran_ordering ) + reverse_copy( variables, size, vec ); + else + copy( variables, size, vec ); + return vec; } +} // namespace //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ @@ -619,59 +559,37 @@ extern "C" { //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ - -EdgeColumns* atlas__fs__EdgeColumns__new ( Mesh::Implementation* mesh, const eckit::Configuration* config ) -{ - EdgeColumns* edges(0); - ATLAS_ERROR_HANDLING( - ASSERT(mesh); - Mesh m(mesh); - edges = new EdgeColumns(m,*config); - ); - return edges; +EdgeColumns* atlas__fs__EdgeColumns__new( Mesh::Implementation* mesh, const eckit::Configuration* config ) { + EdgeColumns* edges( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( mesh ); Mesh m( mesh ); edges = new EdgeColumns( m, *config ); ); + return edges; } //------------------------------------------------------------------------------ -void atlas__fs__EdgeColumns__delete (EdgeColumns* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - delete(This); - ); +void atlas__fs__EdgeColumns__delete( EdgeColumns* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); delete ( This ); ); } //------------------------------------------------------------------------------ -int atlas__fs__EdgeColumns__nb_edges(const EdgeColumns* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->nb_edges(); - ); - return 0; +int atlas__fs__EdgeColumns__nb_edges( const EdgeColumns* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->nb_edges(); ); + return 0; } //------------------------------------------------------------------------------ -Mesh::Implementation* atlas__fs__EdgeColumns__mesh(EdgeColumns* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->mesh().get(); - ); - return 0; +Mesh::Implementation* atlas__fs__EdgeColumns__mesh( EdgeColumns* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->mesh().get(); ); + return 0; } //------------------------------------------------------------------------------ -mesh::Edges* atlas__fs__EdgeColumns__edges(EdgeColumns* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return &This->edges(); - ); - return 0; +mesh::Edges* atlas__fs__EdgeColumns__edges( EdgeColumns* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->edges(); ); + return 0; } //------------------------------------------------------------------------------ @@ -679,309 +597,211 @@ mesh::Edges* atlas__fs__EdgeColumns__edges(EdgeColumns* This) using field::FieldImpl; using field::FieldSetImpl; -field::FieldImpl* atlas__fs__EdgeColumns__create_field ( - const EdgeColumns* This, - const eckit::Configuration* options ) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(options); - FieldImpl* field; - { - Field f = This->createField( *options ); - field = f.get(); - field->attach(); - } - field->detach(); - return field - ); - return 0; +field::FieldImpl* atlas__fs__EdgeColumns__create_field( const EdgeColumns* This, const eckit::Configuration* options ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( options ); FieldImpl * field; { + Field f = This->createField( *options ); + field = f.get(); + field->attach(); + } field->detach(); + return field ); + return 0; } //------------------------------------------------------------------------------ -field::FieldImpl* atlas__fs__EdgeColumns__create_field_template (const EdgeColumns* This, const field::FieldImpl* field_template, const eckit::Configuration* options ) -{ - ASSERT(This); - ASSERT(options); - FieldImpl* field; - { - Field f = This->createField( Field(field_template), *options); - field = f.get(); - field->attach(); - } - field->detach(); - return field; +field::FieldImpl* atlas__fs__EdgeColumns__create_field_template( const EdgeColumns* This, + const field::FieldImpl* field_template, + const eckit::Configuration* options ) { + ASSERT( This ); + ASSERT( options ); + FieldImpl* field; + { + Field f = This->createField( Field( field_template ), *options ); + field = f.get(); + field->attach(); + } + field->detach(); + return field; } // ----------------------------------------------------------------------------------- -void atlas__fs__EdgeColumns__halo_exchange_fieldset( - const EdgeColumns* This, - field::FieldSetImpl* fieldset) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(fieldset); - FieldSet f(fieldset); - This->haloExchange(f); - ); +void atlas__fs__EdgeColumns__halo_exchange_fieldset( const EdgeColumns* This, field::FieldSetImpl* fieldset ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( fieldset ); FieldSet f( fieldset ); This->haloExchange( f ); ); } // ----------------------------------------------------------------------------------- -void atlas__fs__EdgeColumns__halo_exchange_field(const EdgeColumns* This, field::FieldImpl* field) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(field); - Field f(field); - This->haloExchange(f); - ); +void atlas__fs__EdgeColumns__halo_exchange_field( const EdgeColumns* This, field::FieldImpl* field ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( field ); Field f( field ); This->haloExchange( f ); ); } // ----------------------------------------------------------------------------------- -const parallel::HaloExchange* atlas__fs__EdgeColumns__get_halo_exchange(const EdgeColumns* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return &This->halo_exchange(); - ); - return 0; +const parallel::HaloExchange* atlas__fs__EdgeColumns__get_halo_exchange( const EdgeColumns* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->halo_exchange(); ); + return 0; } // ----------------------------------------------------------------------------------- -void atlas__fs__EdgeColumns__gather_fieldset( - const EdgeColumns* This, - const field::FieldSetImpl* local, - field::FieldSetImpl* global) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(local); - ASSERT(global); - const FieldSet l(local); - FieldSet g(global); - This->gather(l,g); ); +void atlas__fs__EdgeColumns__gather_fieldset( const EdgeColumns* This, const field::FieldSetImpl* local, + field::FieldSetImpl* global ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( local ); ASSERT( global ); const FieldSet l( local ); + FieldSet g( global ); This->gather( l, g ); ); } // ----------------------------------------------------------------------------------- -void atlas__fs__EdgeColumns__gather_field( - const EdgeColumns* This, - const field::FieldImpl* local, - field::FieldImpl* global) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(local); - ASSERT(global); - const Field l(local); - Field g(global); - This->gather(l,g); ); +void atlas__fs__EdgeColumns__gather_field( const EdgeColumns* This, const field::FieldImpl* local, + field::FieldImpl* global ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( local ); ASSERT( global ); const Field l( local ); Field g( global ); + This->gather( l, g ); ); } // ----------------------------------------------------------------------------------- -const parallel::GatherScatter* atlas__fs__EdgeColumns__get_gather(const EdgeColumns* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return &This->gather(); ); - return 0; +const parallel::GatherScatter* atlas__fs__EdgeColumns__get_gather( const EdgeColumns* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->gather(); ); + return 0; } // ----------------------------------------------------------------------------------- -const parallel::GatherScatter* atlas__fs__EdgeColumns__get_scatter(const EdgeColumns* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return &This->scatter(); ); - return 0; +const parallel::GatherScatter* atlas__fs__EdgeColumns__get_scatter( const EdgeColumns* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->scatter(); ); + return 0; } // ----------------------------------------------------------------------------------- -void atlas__fs__EdgeColumns__scatter_fieldset(const EdgeColumns* This, const field::FieldSetImpl* global, field::FieldSetImpl* local) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(local); - ASSERT(global); - const FieldSet g(global); - FieldSet l(local); - This->scatter(g,l); ); +void atlas__fs__EdgeColumns__scatter_fieldset( const EdgeColumns* This, const field::FieldSetImpl* global, + field::FieldSetImpl* local ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( local ); ASSERT( global ); const FieldSet g( global ); + FieldSet l( local ); This->scatter( g, l ); ); } // ----------------------------------------------------------------------------------- -void atlas__fs__EdgeColumns__scatter_field(const EdgeColumns* This, const field::FieldImpl* global, field::FieldImpl* local) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(global); - ASSERT(local); - const Field g(global); - Field l(local); - This->scatter(g,l); ); +void atlas__fs__EdgeColumns__scatter_field( const EdgeColumns* This, const field::FieldImpl* global, + field::FieldImpl* local ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( global ); ASSERT( local ); const Field g( global ); Field l( local ); + This->scatter( g, l ); ); } // ----------------------------------------------------------------------------------- -const parallel::Checksum* atlas__fs__EdgeColumns__get_checksum(const EdgeColumns* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return &This->checksum(); - ); - return 0; +const parallel::Checksum* atlas__fs__EdgeColumns__get_checksum( const EdgeColumns* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->checksum(); ); + return 0; } // ----------------------------------------------------------------------------------- - -void atlas__fs__EdgeColumns__checksum_fieldset( - const EdgeColumns* This, - const field::FieldSetImpl* fieldset, - char* &checksum, - int &size, - int &allocated) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(fieldset); - std::string checksum_str (This->checksum(fieldset)); - size = checksum_str.size(); - checksum = new char[size+1]; allocated = true; - strcpy(checksum,checksum_str.c_str()); - ); +void atlas__fs__EdgeColumns__checksum_fieldset( const EdgeColumns* This, const field::FieldSetImpl* fieldset, + char*& checksum, int& size, int& allocated ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( fieldset ); std::string checksum_str( This->checksum( fieldset ) ); + size = checksum_str.size(); checksum = new char[size + 1]; allocated = true; + strcpy( checksum, checksum_str.c_str() ); ); } // ----------------------------------------------------------------------------------- -void atlas__fs__EdgeColumns__checksum_field( - const EdgeColumns* This, - const field::FieldImpl* field, - char* &checksum, - int &size, - int &allocated) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(field); - std::string checksum_str (This->checksum(field)); - size = checksum_str.size(); - checksum = new char[size+1]; allocated = true; - strcpy(checksum,checksum_str.c_str()); - ); +void atlas__fs__EdgeColumns__checksum_field( const EdgeColumns* This, const field::FieldImpl* field, char*& checksum, + int& size, int& allocated ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( field ); std::string checksum_str( This->checksum( field ) ); + size = checksum_str.size(); checksum = new char[size + 1]; allocated = true; + strcpy( checksum, checksum_str.c_str() ); ); } - } // ----------------------------------------------------------------------------------- -} // namespace detail +} // namespace detail // ----------------------------------------------------------------------------------- -EdgeColumns::EdgeColumns() : - FunctionSpace(), - functionspace_(nullptr) { -} +EdgeColumns::EdgeColumns() : FunctionSpace(), functionspace_( nullptr ) {} EdgeColumns::EdgeColumns( const FunctionSpace& functionspace ) : - FunctionSpace(functionspace), - functionspace_( dynamic_cast< const detail::EdgeColumns* >( get() ) ) { -} + FunctionSpace( functionspace ), + functionspace_( dynamic_cast( get() ) ) {} -EdgeColumns::EdgeColumns( - const Mesh& mesh, - const mesh::Halo& halo, - const eckit::Configuration& config ) : - FunctionSpace( new detail::EdgeColumns(mesh,halo,config) ), - functionspace_( dynamic_cast< const detail::EdgeColumns* >( get() ) ) { -} +EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo& halo, const eckit::Configuration& config ) : + FunctionSpace( new detail::EdgeColumns( mesh, halo, config ) ), + functionspace_( dynamic_cast( get() ) ) {} -EdgeColumns::EdgeColumns( - const Mesh& mesh, - const mesh::Halo& halo) : - FunctionSpace( new detail::EdgeColumns(mesh,halo) ), - functionspace_( dynamic_cast< const detail::EdgeColumns* >( get() ) ) { -} +EdgeColumns::EdgeColumns( const Mesh& mesh, const mesh::Halo& halo ) : + FunctionSpace( new detail::EdgeColumns( mesh, halo ) ), + functionspace_( dynamic_cast( get() ) ) {} -EdgeColumns::EdgeColumns( - const Mesh& mesh) : - FunctionSpace( new detail::EdgeColumns(mesh) ), - functionspace_( dynamic_cast< const detail::EdgeColumns* >( get() ) ) { -} +EdgeColumns::EdgeColumns( const Mesh& mesh ) : + FunctionSpace( new detail::EdgeColumns( mesh ) ), + functionspace_( dynamic_cast( get() ) ) {} size_t EdgeColumns::nb_edges() const { - return functionspace_->nb_edges(); + return functionspace_->nb_edges(); } -size_t EdgeColumns::nb_edges_global() const { // Only on MPI rank 0, will this be different from 0 - return functionspace_->nb_edges_global(); +size_t EdgeColumns::nb_edges_global() const { // Only on MPI rank 0, will this be different from 0 + return functionspace_->nb_edges_global(); } const Mesh& EdgeColumns::mesh() const { - return functionspace_->mesh(); + return functionspace_->mesh(); } const mesh::HybridElements& EdgeColumns::edges() const { - return functionspace_->edges(); + return functionspace_->edges(); } void EdgeColumns::haloExchange( FieldSet& fieldset ) const { - functionspace_->haloExchange(fieldset); + functionspace_->haloExchange( fieldset ); } -void EdgeColumns::haloExchange( Field& field) const { - functionspace_->haloExchange(field); +void EdgeColumns::haloExchange( Field& field ) const { + functionspace_->haloExchange( field ); } const parallel::HaloExchange& EdgeColumns::halo_exchange() const { - return functionspace_->halo_exchange(); + return functionspace_->halo_exchange(); } void EdgeColumns::gather( const FieldSet& local, FieldSet& global ) const { - functionspace_->gather(local,global); + functionspace_->gather( local, global ); } void EdgeColumns::gather( const Field& local, Field& global ) const { - functionspace_->gather(local,global); + functionspace_->gather( local, global ); } const parallel::GatherScatter& EdgeColumns::gather() const { - return functionspace_->gather(); + return functionspace_->gather(); } void EdgeColumns::scatter( const FieldSet& global, FieldSet& local ) const { - functionspace_->scatter(global,local); + functionspace_->scatter( global, local ); } void EdgeColumns::scatter( const Field& global, Field& local ) const { - functionspace_->scatter(global,local); + functionspace_->scatter( global, local ); } const parallel::GatherScatter& EdgeColumns::scatter() const { - return functionspace_->scatter(); + return functionspace_->scatter(); } std::string EdgeColumns::checksum( const FieldSet& fieldset ) const { - return functionspace_->checksum(fieldset); + return functionspace_->checksum( fieldset ); } std::string EdgeColumns::checksum( const Field& field ) const { - return functionspace_->checksum(field); + return functionspace_->checksum( field ); } const parallel::Checksum& EdgeColumns::checksum() const { - return functionspace_->checksum(); + return functionspace_->checksum(); } -} // namespace functionspace -} // namespace atlas - +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/EdgeColumns.h b/src/atlas/functionspace/EdgeColumns.h index d1dec3252..5883e9cfc 100644 --- a/src/atlas/functionspace/EdgeColumns.h +++ b/src/atlas/functionspace/EdgeColumns.h @@ -4,34 +4,35 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "eckit/memory/SharedPtr.h" +#include "atlas/field/FieldSet.h" +#include "atlas/functionspace/FunctionSpace.h" #include "atlas/mesh/Halo.h" #include "atlas/mesh/Mesh.h" -#include "atlas/field/FieldSet.h" #include "atlas/option.h" -#include "atlas/functionspace/FunctionSpace.h" #include "atlas/util/Config.h" +#include "eckit/memory/SharedPtr.h" // ---------------------------------------------------------------------------- // Forward declarations namespace atlas { - class FieldSet; +class FieldSet; } namespace atlas { namespace parallel { - class HaloExchange; - class GatherScatter; - class Checksum; -} -} +class HaloExchange; +class GatherScatter; +class Checksum; +} // namespace parallel +} // namespace atlas namespace atlas { namespace functionspace { @@ -39,12 +40,10 @@ namespace detail { // ---------------------------------------------------------------------------- -class EdgeColumns : public FunctionSpaceImpl -{ +class EdgeColumns : public FunctionSpaceImpl { public: - - EdgeColumns( const Mesh&, const mesh::Halo &, const eckit::Configuration & ); - EdgeColumns( const Mesh&, const mesh::Halo & ); + EdgeColumns( const Mesh&, const mesh::Halo&, const eckit::Configuration& ); + EdgeColumns( const Mesh&, const mesh::Halo& ); EdgeColumns( const Mesh&, const eckit::Configuration& = util::NoConfig() ); virtual ~EdgeColumns(); @@ -54,22 +53,22 @@ class EdgeColumns : public FunctionSpaceImpl virtual std::string distribution() const; size_t nb_edges() const; - size_t nb_edges_global() const; // Only on MPI rank 0, will this be different from 0 + size_t nb_edges_global() const; // Only on MPI rank 0, will this be different from 0 std::vector nb_edges_global_foreach_rank() const; const Mesh& mesh() const { return mesh_; } - Mesh& mesh() { return mesh_; } + Mesh& mesh() { return mesh_; } const mesh::HybridElements& edges() const { return edges_; } - mesh::HybridElements& edges() { return edges_; } + mesh::HybridElements& edges() { return edges_; } -// -- Field creation methods + // -- Field creation methods - virtual Field createField( const eckit::Configuration&) const; + virtual Field createField( const eckit::Configuration& ) const; - virtual Field createField(const Field&, const eckit::Configuration& ) const; + virtual Field createField( const Field&, const eckit::Configuration& ) const; -// -- Parallelisation aware methods + // -- Parallelisation aware methods void haloExchange( FieldSet& ) const; void haloExchange( Field& ) const; @@ -87,67 +86,70 @@ class EdgeColumns : public FunctionSpaceImpl std::string checksum( const Field& ) const; const parallel::Checksum& checksum() const; -private: // methods - +private: // methods void constructor(); - size_t config_size(const eckit::Configuration& config) const; - array::DataType config_datatype(const eckit::Configuration&) const; - std::string config_name(const eckit::Configuration&) const; - size_t config_levels(const eckit::Configuration&) const; - array::ArrayShape config_shape(const eckit::Configuration&) const; - void set_field_metadata(const eckit::Configuration&, Field& ) const; + size_t config_size( const eckit::Configuration& config ) const; + array::DataType config_datatype( const eckit::Configuration& ) const; + std::string config_name( const eckit::Configuration& ) const; + size_t config_levels( const eckit::Configuration& ) const; + array::ArrayShape config_shape( const eckit::Configuration& ) const; + void set_field_metadata( const eckit::Configuration&, Field& ) const; size_t footprint() const; -private: // data - - Mesh mesh_; // non-const because functionspace may modify mesh +private: // data + Mesh mesh_; // non-const because functionspace may modify mesh size_t nb_levels_; - mesh::HybridElements& edges_; // non-const because functionspace may modify mesh + mesh::HybridElements& edges_; // non-const because functionspace may modify mesh size_t nb_edges_; mutable long nb_edges_global_{-1}; - mutable eckit::SharedPtr gather_scatter_; // without ghost - mutable eckit::SharedPtr halo_exchange_; - mutable eckit::SharedPtr checksum_; + mutable eckit::SharedPtr gather_scatter_; // without ghost + mutable eckit::SharedPtr halo_exchange_; + mutable eckit::SharedPtr checksum_; }; // ------------------------------------------------------------------- extern "C" { -EdgeColumns* atlas__fs__EdgeColumns__new (Mesh::Implementation* mesh, const eckit::Configuration* config); -void atlas__fs__EdgeColumns__delete (EdgeColumns* This); -int atlas__fs__EdgeColumns__nb_edges(const EdgeColumns* This); -Mesh::Implementation* atlas__fs__EdgeColumns__mesh(EdgeColumns* This); -mesh::Edges* atlas__fs__EdgeColumns__edges(EdgeColumns* This); -field::FieldImpl* atlas__fs__EdgeColumns__create_field (const EdgeColumns* This, const eckit::Configuration* options); -field::FieldImpl* atlas__fs__EdgeColumns__create_field_template (const EdgeColumns* This, const field::FieldImpl* field_template, const eckit::Configuration* options); - - -void atlas__fs__EdgeColumns__halo_exchange_fieldset(const EdgeColumns* This, field::FieldSetImpl* fieldset); -void atlas__fs__EdgeColumns__halo_exchange_field(const EdgeColumns* This, field::FieldImpl* field); -const parallel::HaloExchange* atlas__fs__EdgeColumns__get_halo_exchange(const EdgeColumns* This); - -void atlas__fs__EdgeColumns__gather_fieldset(const EdgeColumns* This, const field::FieldSetImpl* local, field::FieldSetImpl* global); -void atlas__fs__EdgeColumns__gather_field(const EdgeColumns* This, const field::FieldImpl* local, field::FieldImpl* global); -const parallel::GatherScatter* atlas__fs__EdgeColumns__get_gather(const EdgeColumns* This); - -void atlas__fs__EdgeColumns__scatter_fieldset(const EdgeColumns* This, const field::FieldSetImpl* global, field::FieldSetImpl* local); -void atlas__fs__EdgeColumns__scatter_field(const EdgeColumns* This, const field::FieldImpl* global, field::FieldImpl* local); -const parallel::GatherScatter* atlas__fs__EdgeColumns__get_scatter(const EdgeColumns* This); - -void atlas__fs__EdgeColumns__checksum_fieldset(const EdgeColumns* This, const field::FieldSetImpl* fieldset, char* &checksum, int &size, int &allocated); -void atlas__fs__EdgeColumns__checksum_field(const EdgeColumns* This, const field::FieldImpl* field, char* &checksum, int &size, int &allocated); -const parallel::Checksum* atlas__fs__EdgeColumns__get_checksum(const EdgeColumns* This); +EdgeColumns* atlas__fs__EdgeColumns__new( Mesh::Implementation* mesh, const eckit::Configuration* config ); +void atlas__fs__EdgeColumns__delete( EdgeColumns* This ); +int atlas__fs__EdgeColumns__nb_edges( const EdgeColumns* This ); +Mesh::Implementation* atlas__fs__EdgeColumns__mesh( EdgeColumns* This ); +mesh::Edges* atlas__fs__EdgeColumns__edges( EdgeColumns* This ); +field::FieldImpl* atlas__fs__EdgeColumns__create_field( const EdgeColumns* This, const eckit::Configuration* options ); +field::FieldImpl* atlas__fs__EdgeColumns__create_field_template( const EdgeColumns* This, + const field::FieldImpl* field_template, + const eckit::Configuration* options ); + +void atlas__fs__EdgeColumns__halo_exchange_fieldset( const EdgeColumns* This, field::FieldSetImpl* fieldset ); +void atlas__fs__EdgeColumns__halo_exchange_field( const EdgeColumns* This, field::FieldImpl* field ); +const parallel::HaloExchange* atlas__fs__EdgeColumns__get_halo_exchange( const EdgeColumns* This ); + +void atlas__fs__EdgeColumns__gather_fieldset( const EdgeColumns* This, const field::FieldSetImpl* local, + field::FieldSetImpl* global ); +void atlas__fs__EdgeColumns__gather_field( const EdgeColumns* This, const field::FieldImpl* local, + field::FieldImpl* global ); +const parallel::GatherScatter* atlas__fs__EdgeColumns__get_gather( const EdgeColumns* This ); + +void atlas__fs__EdgeColumns__scatter_fieldset( const EdgeColumns* This, const field::FieldSetImpl* global, + field::FieldSetImpl* local ); +void atlas__fs__EdgeColumns__scatter_field( const EdgeColumns* This, const field::FieldImpl* global, + field::FieldImpl* local ); +const parallel::GatherScatter* atlas__fs__EdgeColumns__get_scatter( const EdgeColumns* This ); + +void atlas__fs__EdgeColumns__checksum_fieldset( const EdgeColumns* This, const field::FieldSetImpl* fieldset, + char*& checksum, int& size, int& allocated ); +void atlas__fs__EdgeColumns__checksum_field( const EdgeColumns* This, const field::FieldImpl* field, char*& checksum, + int& size, int& allocated ); +const parallel::Checksum* atlas__fs__EdgeColumns__get_checksum( const EdgeColumns* This ); } -} // namespace detail +} // namespace detail // ------------------------------------------------------------------- class EdgeColumns : public FunctionSpace { - public: - EdgeColumns(); EdgeColumns( const FunctionSpace& ); EdgeColumns( const Mesh&, const mesh::Halo&, const eckit::Configuration& ); @@ -158,13 +160,13 @@ class EdgeColumns : public FunctionSpace { bool valid() const { return functionspace_; } size_t nb_edges() const; - size_t nb_edges_global() const; // Only on MPI rank 0, will this be different from 0 + size_t nb_edges_global() const; // Only on MPI rank 0, will this be different from 0 const Mesh& mesh() const; const mesh::HybridElements& edges() const; -// -- Parallelisation aware methods + // -- Parallelisation aware methods void haloExchange( FieldSet& ) const; void haloExchange( Field& ) const; @@ -183,10 +185,8 @@ class EdgeColumns : public FunctionSpace { const parallel::Checksum& checksum() const; private: - - const detail::EdgeColumns* functionspace_; + const detail::EdgeColumns* functionspace_; }; -} // namespace functionspace -} // namespace atlas - +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/FunctionSpace.cc b/src/atlas/functionspace/FunctionSpace.cc index ac241bbe8..078c5a1b6 100644 --- a/src/atlas/functionspace/FunctionSpace.cc +++ b/src/atlas/functionspace/FunctionSpace.cc @@ -4,23 +4,24 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/functionspace/FunctionSpace.h" #include #include -#include #include -#include "eckit/exception/Exceptions.h" -#include "eckit/types/Types.h" -#include "atlas/library/config.h" -#include "atlas/mesh/actions/BuildParallelFields.h" +#include +#include "atlas/array/DataType.h" #include "atlas/field/Field.h" #include "atlas/field/detail/FieldImpl.h" -#include "atlas/functionspace/FunctionSpace.h" -#include "atlas/array/DataType.h" +#include "atlas/library/config.h" +#include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/runtime/ErrorHandling.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/types/Types.h" namespace atlas { namespace functionspace { @@ -29,121 +30,93 @@ namespace functionspace { // C wrapper interfaces to C++ routines extern "C" { - void atlas__FunctionSpace__delete (FunctionSpaceImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - delete This; - This = 0; - ); +void atlas__FunctionSpace__delete( FunctionSpaceImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); delete This; This = 0; ); } -void atlas__FunctionSpace__name( const FunctionSpaceImpl* This, char* &name, int &size ) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - std::string s = This->type(); - size = s.size()+1; - name = new char[size]; - strcpy(name,s.c_str()); - ); +void atlas__FunctionSpace__name( const FunctionSpaceImpl* This, char*& name, int& size ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); std::string s = This->type(); size = s.size() + 1; name = new char[size]; + strcpy( name, s.c_str() ); ); +} + +field::FieldImpl* atlas__FunctionSpace__create_field( const FunctionSpaceImpl* This, + const eckit::Configuration* options ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( options ); field::FieldImpl * field; { + Field f = This->createField( *options ); + field = f.get(); + field->attach(); + } field->detach(); + return field ); + return 0; } +//------------------------------------------------------------------------------ -field::FieldImpl* atlas__FunctionSpace__create_field ( - const FunctionSpaceImpl* This, - const eckit::Configuration* options ) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(options); +field::FieldImpl* atlas__FunctionSpace__create_field_template( const FunctionSpaceImpl* This, + const field::FieldImpl* field_template, + const eckit::Configuration* options ) { + ASSERT( This ); + ASSERT( options ); field::FieldImpl* field; { - Field f = This->createField( *options ); - field = f.get(); - field->attach(); + Field f = This->createField( Field( field_template ), *options ); + field = f.get(); + field->attach(); } field->detach(); - return field - ); - return 0; + return field; } - -//------------------------------------------------------------------------------ - -field::FieldImpl* atlas__FunctionSpace__create_field_template (const FunctionSpaceImpl* This, const field::FieldImpl* field_template, const eckit::Configuration* options ) -{ - ASSERT(This); - ASSERT(options); - field::FieldImpl* field; - { - Field f = This->createField( Field(field_template), *options); - field = f.get(); - field->attach(); - } - field->detach(); - return field; -} - - } // ------------------------------------------------------------------ -atlas::Field FunctionSpaceImpl::createField( - const atlas::Field& field ) const { - return createField( field, util::NoConfig() ); +atlas::Field FunctionSpaceImpl::createField( const atlas::Field& field ) const { + return createField( field, util::NoConfig() ); } -Field NoFunctionSpace::createField( const eckit::Configuration& ) const { NOTIMP; } -Field NoFunctionSpace::createField( const Field&, const eckit::Configuration& ) const { NOTIMP; } - +Field NoFunctionSpace::createField( const eckit::Configuration& ) const { + NOTIMP; +} +Field NoFunctionSpace::createField( const Field&, const eckit::Configuration& ) const { + NOTIMP; +} // ------------------------------------------------------------------ -} // namespace functionspace +} // namespace functionspace // ------------------------------------------------------------------ -FunctionSpace::FunctionSpace() : - functionspace_( new functionspace::NoFunctionSpace() ) { -} +FunctionSpace::FunctionSpace() : functionspace_( new functionspace::NoFunctionSpace() ) {} -FunctionSpace::FunctionSpace( const Implementation* functionspace ) : - functionspace_( functionspace ) { -} +FunctionSpace::FunctionSpace( const Implementation* functionspace ) : functionspace_( functionspace ) {} -FunctionSpace::FunctionSpace( const FunctionSpace& functionspace ) : - functionspace_( functionspace.functionspace_ ) { -} +FunctionSpace::FunctionSpace( const FunctionSpace& functionspace ) : functionspace_( functionspace.functionspace_ ) {} std::string FunctionSpace::type() const { - return functionspace_->type(); + return functionspace_->type(); } FunctionSpace::operator bool() const { - return functionspace_->operator bool(); + return functionspace_->operator bool(); } size_t FunctionSpace::footprint() const { - return functionspace_->footprint(); + return functionspace_->footprint(); } -Field FunctionSpace::createField(const eckit::Configuration& config) const { - return functionspace_->createField(config); +Field FunctionSpace::createField( const eckit::Configuration& config ) const { + return functionspace_->createField( config ); } -Field FunctionSpace::createField( - const Field& other, - const eckit::Configuration& config ) const { - return functionspace_->createField(other,config); +Field FunctionSpace::createField( const Field& other, const eckit::Configuration& config ) const { + return functionspace_->createField( other, config ); } std::string FunctionSpace::distribution() const { - return functionspace_->distribution(); + return functionspace_->distribution(); } // ------------------------------------------------------------------ - -} // namespace atlas - +} // namespace atlas diff --git a/src/atlas/functionspace/FunctionSpace.h b/src/atlas/functionspace/FunctionSpace.h index 43a9eee64..f10a9eb4c 100644 --- a/src/atlas/functionspace/FunctionSpace.h +++ b/src/atlas/functionspace/FunctionSpace.h @@ -4,99 +4,102 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include "eckit/memory/Owned.h" -#include "eckit/memory/SharedPtr.h" #include "atlas/field/Field.h" -#include "atlas/util/Config.h" #include "atlas/option.h" +#include "atlas/util/Config.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" namespace atlas { namespace functionspace { #define FunctionspaceT_nonconst typename FunctionSpaceImpl::remove_const::type -#define FunctionspaceT_const typename FunctionSpaceImpl::add_const::type +#define FunctionspaceT_const typename FunctionSpaceImpl::add_const::type /// @brief FunctionSpace class helps to interprete Fields. /// @note Abstract base class -class FunctionSpaceImpl : public eckit::Owned -{ +class FunctionSpaceImpl : public eckit::Owned { private: - template struct remove_const { typedef T type; }; - template struct remove_const { typedef T type; }; - - template struct add_const { typedef const typename remove_const::type type; }; - template struct add_const { typedef const T type; }; + template + struct remove_const { + typedef T type; + }; + template + struct remove_const { + typedef T type; + }; + + template + struct add_const { + typedef const typename remove_const::type type; + }; + template + struct add_const { + typedef const T type; + }; public: FunctionSpaceImpl() {} - virtual ~FunctionSpaceImpl() = 0; + virtual ~FunctionSpaceImpl() = 0; virtual std::string type() const = 0; virtual operator bool() const { return true; } virtual size_t footprint() const = 0; - virtual atlas::Field createField( - const eckit::Configuration& ) const = 0; + virtual atlas::Field createField( const eckit::Configuration& ) const = 0; - virtual atlas::Field createField( - const atlas::Field&, - const eckit::Configuration& ) const = 0; + virtual atlas::Field createField( const atlas::Field&, const eckit::Configuration& ) const = 0; - atlas::Field createField( - const atlas::Field& ) const; + atlas::Field createField( const atlas::Field& ) const; - template atlas::Field createField( - const eckit::Configuration& ) const; + template + atlas::Field createField( const eckit::Configuration& ) const; - template atlas::Field createField() const; + template + atlas::Field createField() const; const util::Metadata& metadata() const { return metadata_; } - util::Metadata& metadata() { return metadata_; } + util::Metadata& metadata() { return metadata_; } template - FunctionspaceT_nonconst *cast(); + FunctionspaceT_nonconst* cast(); template - FunctionspaceT_const *cast() const; + FunctionspaceT_const* cast() const; virtual std::string distribution() const = 0; private: util::Metadata metadata_; - }; inline FunctionSpaceImpl::~FunctionSpaceImpl() {} template -inline Field FunctionSpaceImpl::createField( - const eckit::Configuration& options) const -{ - return createField( option::datatypeT() | options ); +inline Field FunctionSpaceImpl::createField( const eckit::Configuration& options ) const { + return createField( option::datatypeT() | options ); } template -inline Field FunctionSpaceImpl::createField() const -{ - return createField( option::datatypeT() ); +inline Field FunctionSpaceImpl::createField() const { + return createField( option::datatypeT() ); } template -inline FunctionspaceT_nonconst *FunctionSpaceImpl::cast() -{ - return dynamic_cast (this); +inline FunctionspaceT_nonconst* FunctionSpaceImpl::cast() { + return dynamic_cast( this ); } template -inline FunctionspaceT_const *FunctionSpaceImpl::cast() const -{ - return dynamic_cast (this); +inline FunctionspaceT_const* FunctionSpaceImpl::cast() const { + return dynamic_cast( this ); } #undef FunctionspaceT_const @@ -105,76 +108,70 @@ inline FunctionspaceT_const *FunctionSpaceImpl::cast() const //------------------------------------------------------------------------------------------------------ /// @brief Dummy Functionspace class that evaluates to false -class NoFunctionSpace : public FunctionSpaceImpl -{ +class NoFunctionSpace : public FunctionSpaceImpl { public: NoFunctionSpace() {} virtual ~NoFunctionSpace() {} virtual std::string type() const { return "NoFunctionSpace"; } virtual operator bool() const { return false; } - virtual size_t footprint() const { return sizeof(*this); } + virtual size_t footprint() const { return sizeof( *this ); } virtual std::string distribution() const { return std::string(); } virtual Field createField( const eckit::Configuration& ) const; virtual Field createField( const Field&, const eckit::Configuration& ) const; - }; //------------------------------------------------------------------------------------------------------ // C wrapper interfaces to C++ routines -extern "C" -{ - void atlas__FunctionSpace__delete (FunctionSpaceImpl* This); - void atlas__FunctionSpace__name( const FunctionSpaceImpl* This, char* &name, int &size ); - field::FieldImpl* atlas__FunctionSpace__create_field (const FunctionSpaceImpl* This, const eckit::Configuration* options); - field::FieldImpl* atlas__FunctionSpace__create_field_template (const FunctionSpaceImpl* This, const field::FieldImpl* field_template, const eckit::Configuration* options); +extern "C" { +void atlas__FunctionSpace__delete( FunctionSpaceImpl* This ); +void atlas__FunctionSpace__name( const FunctionSpaceImpl* This, char*& name, int& size ); +field::FieldImpl* atlas__FunctionSpace__create_field( const FunctionSpaceImpl* This, + const eckit::Configuration* options ); +field::FieldImpl* atlas__FunctionSpace__create_field_template( const FunctionSpaceImpl* This, + const field::FieldImpl* field_template, + const eckit::Configuration* options ); } //------------------------------------------------------------------------------------------------------ -} // namespace functionspace +} // namespace functionspace //------------------------------------------------------------------------------------------------------ class FunctionSpace { - public: - - using Implementation = functionspace::FunctionSpaceImpl; + using Implementation = functionspace::FunctionSpaceImpl; private: - - eckit::SharedPtr< const Implementation > functionspace_; + eckit::SharedPtr functionspace_; public: + FunctionSpace(); + FunctionSpace( const Implementation* ); + FunctionSpace( const FunctionSpace& ); - FunctionSpace(); - FunctionSpace( const Implementation* ); - FunctionSpace( const FunctionSpace& ); - - std::string type() const; - operator bool() const; - size_t footprint() const; - std::string distribution() const; + std::string type() const; + operator bool() const; + size_t footprint() const; + std::string distribution() const; - const Implementation* get() const { return functionspace_.get(); } + const Implementation* get() const { return functionspace_.get(); } - atlas::Field createField( - const eckit::Configuration& ) const; + atlas::Field createField( const eckit::Configuration& ) const; - atlas::Field createField( - const atlas::Field&, const eckit::Configuration& = util::NoConfig() ) const; + atlas::Field createField( const atlas::Field&, const eckit::Configuration& = util::NoConfig() ) const; - template Field createField( - const eckit::Configuration& = util::NoConfig() ) const; + template + Field createField( const eckit::Configuration& = util::NoConfig() ) const; }; -template< typename DATATYPE > +template Field FunctionSpace::createField( const eckit::Configuration& options ) const { - return functionspace_->createField(options); + return functionspace_->createField( options ); } //------------------------------------------------------------------------------------------------------ -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 1b25d330a..d9b815b9d 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -4,28 +4,29 @@ * 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 + * 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 -#include "eckit/os/BackTrace.h" #include "eckit/utils/MD5.h" #include "atlas/array/ArrayView.h" #include "atlas/functionspace/NodeColumns.h" +#include "atlas/grid/Grid.h" #include "atlas/library/config.h" -#include "atlas/mesh/actions/BuildHalo.h" -#include "atlas/mesh/actions/BuildParallelFields.h" -#include "atlas/mesh/actions/BuildPeriodicBoundaries.h" #include "atlas/mesh/IsGhostNode.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/mesh/actions/BuildHalo.h" +#include "atlas/mesh/actions/BuildParallelFields.h" +#include "atlas/mesh/actions/BuildPeriodicBoundaries.h" #include "atlas/parallel/Checksum.h" #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/HaloExchange.h" @@ -34,7 +35,6 @@ #include "atlas/runtime/Trace.h" #include "atlas/util/detail/Cache.h" - #undef atlas_omp_critical_ordered #define atlas_omp_critical_ordered atlas_omp_critical @@ -44,7 +44,6 @@ #define REMOTE_IDX_BASE 0 #endif - namespace atlas { namespace functionspace { namespace detail { @@ -52,604 +51,547 @@ namespace detail { namespace { 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() ); - } else { - return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); +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() ); } + else { + return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); + } } - } - else { - if( field.variables() ) { - return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); - } else { - return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + else { + if ( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); + } + else { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + } } - } } template -array::LocalView make_leveled_scalar_view(const Field &field) -{ - using namespace array; - if( field.levels() ) - return make_view( field ).slice( Range::all(), Range::all() ); - else - return make_view( field ).slice( Range::all(), Range::dummy() ); +array::LocalView make_leveled_scalar_view( const Field& field ) { + using namespace array; + if ( field.levels() ) + return make_view( field ).slice( Range::all(), Range::all() ); + 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() ) - return make_view( field ).slice( Range::all(), Range::all() ); - else - return make_view( field ).slice( Range::all(), Range::dummy() ); +array::LocalView make_surface_view( const Field& field ) { + using namespace array; + if ( field.variables() ) + return make_view( field ).slice( Range::all(), Range::all() ); + 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 ) - return make_view( field ).slice( Range::all(), Range::all() ); - else - return make_view( field ).slice( Range::all(), Range::dummy() ); -} - +array::LocalView make_per_level_view( const Field& field ) { + using namespace array; + if ( field.rank() == 2 ) + return make_view( field ).slice( Range::all(), Range::all() ); + else + return make_view( field ).slice( Range::all(), Range::dummy() ); } +} // namespace -class NodeColumnsHaloExchangeCache : - public util::Cache, - public mesh::detail::MeshObserver -{ +class NodeColumnsHaloExchangeCache : public util::Cache, + public mesh::detail::MeshObserver { private: - using Base = util::Cache; - NodeColumnsHaloExchangeCache() : Base("NodeColumnsHaloExchangeCache") {} + using Base = util::Cache; + NodeColumnsHaloExchangeCache() : Base( "NodeColumnsHaloExchangeCache" ) {} + public: - static NodeColumnsHaloExchangeCache& instance() { - static NodeColumnsHaloExchangeCache inst; - return inst; - } - eckit::SharedPtr get_or_create( const Mesh& mesh, long halo ) { - creator_type creator = std::bind( &NodeColumnsHaloExchangeCache::create, mesh, halo ); - return Base::get_or_create( key(*mesh.get(),halo) , creator ); - } - virtual void onMeshDestruction(mesh::detail::MeshImpl& mesh) { - for( long jhalo=1; jhalo < mesh::Halo(mesh).size(); ++jhalo ) { - remove( key(mesh,jhalo) ); + static NodeColumnsHaloExchangeCache& instance() { + static NodeColumnsHaloExchangeCache inst; + return inst; + } + eckit::SharedPtr get_or_create( const Mesh& mesh, long halo ) { + creator_type creator = std::bind( &NodeColumnsHaloExchangeCache::create, mesh, halo ); + return Base::get_or_create( key( *mesh.get(), halo ), creator ); + } + virtual void onMeshDestruction( mesh::detail::MeshImpl& mesh ) { + for ( long jhalo = 1; jhalo < mesh::Halo( mesh ).size(); ++jhalo ) { + remove( key( mesh, jhalo ) ); + } } - } -private: - static Base::key_type key( const mesh::detail::MeshImpl& mesh, long halo ) { - std::ostringstream key ; - key << "mesh[address="<<&mesh<<"],halo[size="<attachObserver(instance()); + static value_type* create( const Mesh& mesh, long halo ) { + mesh.get()->attachObserver( instance() ); - value_type* value = new value_type(); + value_type* value = new value_type(); - std::ostringstream ss; - ss << "nb_nodes_including_halo["<setup( array::make_view(mesh.nodes().partition()).data(), - array::make_view(mesh.nodes().remote_index()).data(), - REMOTE_IDX_BASE,nb_nodes); + value->setup( array::make_view( mesh.nodes().partition() ).data(), + array::make_view( mesh.nodes().remote_index() ).data(), REMOTE_IDX_BASE, nb_nodes ); - return value; - } + return value; + } }; -class NodeColumnsGatherScatterCache : - public util::Cache, - public mesh::detail::MeshObserver -{ +class NodeColumnsGatherScatterCache : public util::Cache, + public mesh::detail::MeshObserver { private: - using Base = util::Cache; - NodeColumnsGatherScatterCache() : Base("NodeColumnsGatherScatterCache") {} + using Base = util::Cache; + NodeColumnsGatherScatterCache() : Base( "NodeColumnsGatherScatterCache" ) {} + public: - static NodeColumnsGatherScatterCache& instance() { - static NodeColumnsGatherScatterCache inst; - return inst; - } - eckit::SharedPtr get_or_create( const Mesh& mesh ) { - creator_type creator = std::bind( &NodeColumnsGatherScatterCache::create, mesh ); - return Base::get_or_create( key(*mesh.get()), creator ); - } - virtual void onMeshDestruction(mesh::detail::MeshImpl& mesh) { - remove( key(mesh) ); - } + static NodeColumnsGatherScatterCache& instance() { + static NodeColumnsGatherScatterCache inst; + return inst; + } + eckit::SharedPtr get_or_create( const Mesh& mesh ) { + creator_type creator = std::bind( &NodeColumnsGatherScatterCache::create, mesh ); + return Base::get_or_create( key( *mesh.get() ), creator ); + } + virtual void onMeshDestruction( mesh::detail::MeshImpl& mesh ) { remove( key( mesh ) ); } private: + static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { + std::ostringstream key; + key << "mesh[address=" << &mesh << "]"; + return key.str(); + } - static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { - std::ostringstream key ; - key << "mesh[address="<<&mesh<<"]"; - return key.str(); - } - - static value_type* create( const Mesh& mesh ) { + static value_type* create( const Mesh& mesh ) { + mesh.get()->attachObserver( instance() ); - mesh.get()->attachObserver(instance()); + value_type* value = new value_type(); - value_type* value = new value_type(); + mesh::IsGhostNode is_ghost( mesh.nodes() ); + std::vector mask( mesh.nodes().size() ); + const size_t npts = mask.size(); + atlas_omp_parallel_for( size_t n = 0; n < npts; ++n ) { + mask[n] = is_ghost( n ) ? 1 : 0; - mesh::IsGhostNode is_ghost(mesh.nodes()); - std::vector mask(mesh.nodes().size()); - const size_t npts = mask.size(); - atlas_omp_parallel_for( size_t n=0; n This would add periodic west-bc to the gather, but means that + // global-sums, means, etc are computed wrong + // if( mask[j] == 1 && + // internals::Topology::check(flags(j),internals::Topology::BC) ) { + // mask[j] = 0; + //} + } - // --> This would add periodic west-bc to the gather, but means that global-sums, means, etc are computed wrong - //if( mask[j] == 1 && internals::Topology::check(flags(j),internals::Topology::BC) ) { - // mask[j] = 0; - //} + value->setup( array::make_view( mesh.nodes().partition() ).data(), + array::make_view( mesh.nodes().remote_index() ).data(), REMOTE_IDX_BASE, + array::make_view( mesh.nodes().global_index() ).data(), mask.data(), + mesh.nodes().size() ); + return value; } - - value->setup(array::make_view(mesh.nodes().partition()).data(), - array::make_view(mesh.nodes().remote_index()).data(), - REMOTE_IDX_BASE, - array::make_view(mesh.nodes().global_index()).data(), - mask.data(),mesh.nodes().size()); - return value; - } }; -class NodeColumnsChecksumCache : - public util::Cache, - public mesh::detail::MeshObserver -{ +class NodeColumnsChecksumCache : public util::Cache, + public mesh::detail::MeshObserver { private: - using Base = util::Cache; - NodeColumnsChecksumCache(): Base("NodeColumnsChecksumCache"){} + using Base = util::Cache; + NodeColumnsChecksumCache() : Base( "NodeColumnsChecksumCache" ) {} + public: - static NodeColumnsChecksumCache& instance() { - static NodeColumnsChecksumCache inst; - return inst; - } - eckit::SharedPtr get_or_create( const Mesh& mesh ) { - creator_type creator = std::bind( &NodeColumnsChecksumCache::create, mesh ); - return Base::get_or_create( key(*mesh.get()), creator ); - } - virtual void onMeshDestruction(mesh::detail::MeshImpl& mesh) { - remove( key(mesh) ); - } -private: + static NodeColumnsChecksumCache& instance() { + static NodeColumnsChecksumCache inst; + return inst; + } + eckit::SharedPtr get_or_create( const Mesh& mesh ) { + creator_type creator = std::bind( &NodeColumnsChecksumCache::create, mesh ); + return Base::get_or_create( key( *mesh.get() ), creator ); + } + virtual void onMeshDestruction( mesh::detail::MeshImpl& mesh ) { remove( key( mesh ) ); } - static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { - std::ostringstream key ; - key << "mesh[address="<<&mesh<<"]"; - return key.str(); - } +private: + static Base::key_type key( const mesh::detail::MeshImpl& mesh ) { + std::ostringstream key; + key << "mesh[address=" << &mesh << "]"; + return key.str(); + } - static value_type* create( const Mesh& mesh ) { - mesh.get()->attachObserver(instance()); - value_type* value = new value_type(); - eckit::SharedPtr gather( NodeColumnsGatherScatterCache::instance().get_or_create(mesh) ); - value->setup( gather ); - return value; - } + static value_type* create( const Mesh& mesh ) { + mesh.get()->attachObserver( instance() ); + value_type* value = new value_type(); + eckit::SharedPtr gather( + NodeColumnsGatherScatterCache::instance().get_or_create( mesh ) ); + value->setup( gather ); + return value; + } }; -NodeColumns::NodeColumns( Mesh mesh ) : - NodeColumns( mesh, util::NoConfig() ) { -} +NodeColumns::NodeColumns( Mesh mesh ) : NodeColumns( mesh, util::NoConfig() ) {} -NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration & config ) : - mesh_(mesh), - nodes_(mesh_.nodes()), - nb_levels_( config.getInt("levels",0) ), - nb_nodes_(nodes_.size()) { +NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration& config ) : + mesh_( mesh ), + nodes_( mesh_.nodes() ), + nb_levels_( config.getInt( "levels", 0 ) ), + nb_nodes_( nodes_.size() ) { ATLAS_TRACE(); - if( config.has("halo") ) { - halo_ = mesh::Halo(config.getInt("halo") ); - } else { - halo_ = mesh::Halo(mesh); + if ( config.has( "halo" ) ) { halo_ = mesh::Halo( config.getInt( "halo" ) ); } + else { + halo_ = mesh::Halo( mesh ); } constructor(); } +void NodeColumns::constructor() { + ASSERT( mesh_ ); + mesh::actions::build_nodes_parallel_fields( mesh_.nodes() ); + mesh::actions::build_periodic_boundaries( mesh_ ); -void NodeColumns::constructor() -{ - ASSERT( mesh_ ); - mesh::actions::build_nodes_parallel_fields( mesh_.nodes() ); - mesh::actions::build_periodic_boundaries(mesh_); - - if( halo_.size() > 0) - { - mesh::actions::build_halo(mesh_,halo_.size()); - std::stringstream ss; - ss << "nb_nodes_including_halo["< 0 ) { + mesh::actions::build_halo( mesh_, halo_.size() ); + std::stringstream ss; + ss << "nb_nodes_including_halo[" << halo_.size() << "]"; + mesh_.metadata().get( ss.str(), nb_nodes_ ); + } + 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(); } } - } -// ATLAS_TRACE_SCOPE("HaloExchange") { -// halo_exchange_.reset( NodeColumnsHaloExchangeCache::instance().get(mesh_,halo_.size()) ); -// } + // ATLAS_TRACE_SCOPE("HaloExchange") { + // halo_exchange_.reset( + // NodeColumnsHaloExchangeCache::instance().get(mesh_,halo_.size()) ); + // } -// ATLAS_TRACE_SCOPE("GatherScatter") { -// gather_scatter_.reset( NodeColumnsGatherScatterCache::instance().get(mesh_) ); -// } + // ATLAS_TRACE_SCOPE("GatherScatter") { + // gather_scatter_.reset( + // NodeColumnsGatherScatterCache::instance().get(mesh_) ); + // } -// ATLAS_TRACE_SCOPE("Checksum") { -// checksum_.reset( NodeColumnsChecksumCache::instance().get(mesh_) ); -// } + // ATLAS_TRACE_SCOPE("Checksum") { + // checksum_.reset( NodeColumnsChecksumCache::instance().get(mesh_) ); + // } -// nb_nodes_global_ = gather().glb_dof(); + // nb_nodes_global_ = gather().glb_dof(); } NodeColumns::~NodeColumns() {} std::string NodeColumns::distribution() const { - return mesh().metadata().getString("distribution"); + return mesh().metadata().getString( "distribution" ); } size_t NodeColumns::footprint() const { - size_t size = sizeof(*this); - // TODO - return size; + size_t size = sizeof( *this ); + // TODO + return size; } -size_t NodeColumns::nb_nodes() const -{ - return nb_nodes_; +size_t NodeColumns::nb_nodes() const { + return nb_nodes_; } -size_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(); - } else { - nb_nodes_global_ = gather().glb_dof(); - } - return nb_nodes_global_; -} - -size_t NodeColumns::config_nb_nodes(const eckit::Configuration& config) const -{ - size_t size = nb_nodes(); - bool global(false); - if( config.get("global",global) ) - { - if( global ) - { - size_t owner(0); - config.get("owner",owner); - size_t _nb_nodes_global = nb_nodes_global(); - size = (mpi::comm().rank() == owner ? _nb_nodes_global : 0); +size_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(); } + else { + nb_nodes_global_ = gather().glb_dof(); } - } - return size; + return nb_nodes_global_; } -void NodeColumns::set_field_metadata(const eckit::Configuration& config, Field& field) const -{ - field.set_functionspace(this); +size_t NodeColumns::config_nb_nodes( const eckit::Configuration& config ) const { + size_t size = nb_nodes(); + bool global( false ); + if ( config.get( "global", global ) ) { + if ( global ) { + size_t owner( 0 ); + config.get( "owner", owner ); + size_t _nb_nodes_global = nb_nodes_global(); + size = ( mpi::comm().rank() == owner ? _nb_nodes_global : 0 ); + } + } + return size; +} - bool global(false); - if( config.get("global",global) ) - { - if( global ) - { - size_t owner(0); - config.get("owner",owner); - field.metadata().set("owner",owner); +void NodeColumns::set_field_metadata( const eckit::Configuration& config, Field& field ) const { + field.set_functionspace( this ); + + bool global( false ); + if ( config.get( "global", global ) ) { + if ( global ) { + size_t owner( 0 ); + config.get( "owner", owner ); + field.metadata().set( "owner", owner ); + } } - } - field.metadata().set("global",global); + field.metadata().set( "global", global ); - size_t levels(nb_levels_); - config.get("levels",levels); - field.set_levels(levels); + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + field.set_levels( levels ); - size_t variables(0); - config.get("variables",variables); - field.set_variables(variables); + size_t variables( 0 ); + config.get( "variables", variables ); + field.set_variables( variables ); } - -array::DataType NodeColumns::config_datatype(const eckit::Configuration& config) const -{ - array::DataType::kind_t kind; - if( ! config.get("datatype",kind) ) throw eckit::AssertionFailed("datatype missing",Here()); - return array::DataType(kind); +array::DataType NodeColumns::config_datatype( const eckit::Configuration& config ) const { + array::DataType::kind_t kind; + if ( !config.get( "datatype", kind ) ) throw eckit::AssertionFailed( "datatype missing", Here() ); + return array::DataType( kind ); } -std::string NodeColumns::config_name(const eckit::Configuration& config) const -{ - std::string name; - config.get("name",name); - return name; +std::string NodeColumns::config_name( const eckit::Configuration& config ) const { + std::string name; + config.get( "name", name ); + return name; } -size_t NodeColumns::config_levels(const eckit::Configuration& config) const -{ - size_t levels(nb_levels_); - config.get("levels",levels); - return levels; +size_t NodeColumns::config_levels( const eckit::Configuration& config ) const { + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + return levels; } -array::ArrayShape NodeColumns::config_shape(const eckit::Configuration& config) const { - array::ArrayShape shape; +array::ArrayShape NodeColumns::config_shape( const eckit::Configuration& config ) const { + array::ArrayShape shape; - shape.push_back(config_nb_nodes(config)); + shape.push_back( config_nb_nodes( config ) ); - size_t levels(nb_levels_); - config.get("levels",levels); - if( levels > 0 ) shape.push_back(levels); + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + if ( levels > 0 ) shape.push_back( levels ); - size_t variables(0); - config.get("variables",variables); - if( variables > 0 ) shape.push_back(variables); + size_t variables( 0 ); + config.get( "variables", variables ); + if ( variables > 0 ) shape.push_back( variables ); - return shape; + return shape; } -Field NodeColumns::createField( - const eckit::Configuration& config ) const -{ - Field field = Field(config_name(config),config_datatype(config),config_shape(config)); +Field NodeColumns::createField( const eckit::Configuration& config ) const { + Field field = Field( config_name( config ), config_datatype( config ), config_shape( config ) ); - set_field_metadata(config,field); + set_field_metadata( config, field ); - return field; + return field; } -Field NodeColumns::createField( - const Field& other, - const eckit::Configuration& config ) const -{ - return createField( - option::datatype ( other.datatype() ) | - option::levels ( other.levels() ) | - option::variables( other.variables() ) | - config ); +Field NodeColumns::createField( const Field& other, const eckit::Configuration& config ) const { + return createField( option::datatype( other.datatype() ) | option::levels( other.levels() ) | + option::variables( other.variables() ) | config ); } namespace { -template -array::ArrayView get_field_view(const Field& field, bool on_device) -{ - return on_device ? array::make_device_view(field) : array::make_view(field); +template +array::ArrayView get_field_view( const Field& field, bool on_device ) { + return on_device ? array::make_device_view( field ) : array::make_view( field ); } -template -void dispatch_haloExchange( Field& field, const parallel::HaloExchange& halo_exchange, bool on_device ) -{ - if ( field.datatype() == array::DataType::kind() ) { - halo_exchange.template execute( field.array(), on_device ); - } - else if( field.datatype() == array::DataType::kind() ) { - halo_exchange.template execute( field.array(), on_device ); - } - else if( field.datatype() == array::DataType::kind() ) { - halo_exchange.template execute( field.array(), on_device ); - } - else if( field.datatype() == array::DataType::kind() ) { - halo_exchange.template execute( field.array(), on_device ); - } - else throw eckit::Exception("datatype not supported",Here()); -} -} - -void NodeColumns::haloExchange( FieldSet& fieldset, bool on_device ) const -{ - for( size_t f=0; f(field,halo_exchange(), on_device); - break; - case 2: - dispatch_haloExchange<2>(field,halo_exchange(), on_device); - break; - case 3: - dispatch_haloExchange<3>(field,halo_exchange(), on_device); - break; - case 4: - dispatch_haloExchange<4>(field,halo_exchange(), on_device); - break; - default: - throw eckit::Exception("Rank not supported", Here()); - break; +template +void dispatch_haloExchange( Field& field, const parallel::HaloExchange& halo_exchange, bool on_device ) { + if ( field.datatype() == array::DataType::kind() ) { + halo_exchange.template execute( field.array(), on_device ); } - } + else if ( field.datatype() == array::DataType::kind() ) { + halo_exchange.template execute( field.array(), on_device ); + } + else if ( field.datatype() == array::DataType::kind() ) { + halo_exchange.template execute( field.array(), on_device ); + } + else if ( field.datatype() == array::DataType::kind() ) { + halo_exchange.template execute( field.array(), on_device ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); } +} // namespace -void NodeColumns::haloExchange( Field& field, bool on_device ) const -{ - FieldSet fieldset; - fieldset.add(field); - haloExchange(fieldset, on_device); -} -const parallel::HaloExchange& NodeColumns::halo_exchange() const -{ - if ( halo_exchange_ ) return *halo_exchange_; - halo_exchange_ = NodeColumnsHaloExchangeCache::instance().get_or_create( mesh_, halo_.size() ); - return *halo_exchange_; +void NodeColumns::haloExchange( FieldSet& fieldset, bool on_device ) const { + for ( size_t f = 0; f < fieldset.size(); ++f ) { + Field& field = fieldset[f]; + switch ( field.rank() ) { + case 1: + dispatch_haloExchange<1>( field, halo_exchange(), on_device ); + break; + case 2: + dispatch_haloExchange<2>( field, halo_exchange(), on_device ); + break; + case 3: + dispatch_haloExchange<3>( field, halo_exchange(), on_device ); + break; + case 4: + dispatch_haloExchange<4>( field, halo_exchange(), on_device ); + break; + default: + throw eckit::Exception( "Rank not supported", Here() ); + break; + } + } } +void NodeColumns::haloExchange( Field& field, bool on_device ) const { + FieldSet fieldset; + fieldset.add( field ); + haloExchange( fieldset, on_device ); +} +const parallel::HaloExchange& NodeColumns::halo_exchange() const { + if ( halo_exchange_ ) return *halo_exchange_; + halo_exchange_ = NodeColumnsHaloExchangeCache::instance().get_or_create( mesh_, halo_.size() ); + return *halo_exchange_; +} -void NodeColumns::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset ) const -{ - ASSERT(local_fieldset.size() == global_fieldset.size()); - - for( size_t f=0; f() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather().gather( &loc_field, &glb_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather().gather( &loc_field, &glb_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather().gather( &loc_field, &glb_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather().gather( &loc_field, &glb_field, nb_fields, root ); + if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather().gather( &loc_field, &glb_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather().gather( &loc_field, &glb_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather().gather( &loc_field, &glb_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather().gather( &loc_field, &glb_field, nb_fields, root ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); } - else throw eckit::Exception("datatype not supported",Here()); - } } -void NodeColumns::gather( const Field& local, Field& global ) const -{ - FieldSet local_fields; - FieldSet global_fields; - local_fields.add(local); - global_fields.add(global); - gather(local_fields,global_fields); +void NodeColumns::gather( const Field& local, Field& global ) const { + FieldSet local_fields; + FieldSet global_fields; + local_fields.add( local ); + global_fields.add( global ); + gather( local_fields, global_fields ); } -const parallel::GatherScatter& NodeColumns::gather() const -{ - if (gather_scatter_) return *gather_scatter_; - gather_scatter_ = NodeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); - return *gather_scatter_; +const parallel::GatherScatter& NodeColumns::gather() const { + 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_; - gather_scatter_ = NodeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); - return *gather_scatter_; +const parallel::GatherScatter& NodeColumns::scatter() const { + if ( gather_scatter_ ) return *gather_scatter_; + gather_scatter_ = NodeColumnsGatherScatterCache::instance().get_or_create( mesh_ ); + return *gather_scatter_; } +void NodeColumns::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldset ) const { + ASSERT( local_fieldset.size() == global_fieldset.size() ); -void NodeColumns::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldset ) const -{ - ASSERT(local_fieldset.size() == global_fieldset.size()); - - for( size_t f=0; f() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + scatter().scatter( &glb_field, &loc_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + scatter().scatter( &glb_field, &loc_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + scatter().scatter( &glb_field, &loc_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + scatter().scatter( &glb_field, &loc_field, nb_fields, root ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); - if ( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - scatter().scatter( &glb_field, &loc_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - scatter().scatter( &glb_field, &loc_field, nb_fields, root ); + glb.metadata().broadcast( loc.metadata(), root ); + loc.metadata().set( "global", false ); } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - scatter().scatter( &glb_field, &loc_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - scatter().scatter( &glb_field, &loc_field, nb_fields, root ); - } - else throw eckit::Exception("datatype not supported",Here()); - - glb.metadata().broadcast(loc.metadata(),root); - loc.metadata().set("global",false); - } } -void NodeColumns::scatter( const Field& global, Field& local ) const -{ - FieldSet global_fields; - FieldSet local_fields; - global_fields.add(global); - local_fields.add(local); - scatter(global_fields,local_fields); +void NodeColumns::scatter( const Field& global, Field& local ) const { + FieldSet global_fields; + FieldSet local_fields; + global_fields.add( global ); + local_fields.add( local ); + scatter( global_fields, local_fields ); } namespace { template -std::string checksum_3d_field(const parallel::Checksum& checksum, const Field& field ) -{ - array::LocalView values = make_leveled_view(field); - array::ArrayT surface_field( values.shape(0), values.shape(2) ); - array::ArrayView surface = array::make_view(surface_field); - const size_t npts = values.shape(0); - atlas_omp_for( size_t n=0; n values = make_leveled_view( field ); + array::ArrayT surface_field( values.shape( 0 ), values.shape( 2 ) ); + array::ArrayView surface = array::make_view( surface_field ); + const size_t npts = values.shape( 0 ); + atlas_omp_for( size_t n = 0; n < npts; ++n ) { + for ( size_t j = 0; j < surface.shape( 1 ); ++j ) { + surface( n, j ) = 0.; + for ( size_t l = 0; l < values.shape( 1 ); ++l ) + surface( n, j ) += values( n, l, j ); + } } - } - return checksum.execute( surface.data(), surface_field.stride(0) ); -} + return checksum.execute( surface.data(), surface_field.stride( 0 ) ); } +} // namespace std::string NodeColumns::checksum( const FieldSet& fieldset ) const { - eckit::MD5 md5; - for( size_t f=0; f() ) - md5 << checksum_3d_field(checksum(),field); - else if( field.datatype() == array::DataType::kind() ) - md5 << checksum_3d_field(checksum(),field); - else if( field.datatype() == array::DataType::kind() ) - md5 << checksum_3d_field(checksum(),field); - else if( field.datatype() == array::DataType::kind() ) - md5 << checksum_3d_field(checksum(),field); - else throw eckit::Exception("datatype not supported",Here()); - } - return md5; + eckit::MD5 md5; + for ( size_t f = 0; f < fieldset.size(); ++f ) { + const Field& field = fieldset[f]; + if ( field.datatype() == array::DataType::kind() ) + md5 << checksum_3d_field( checksum(), field ); + else if ( field.datatype() == array::DataType::kind() ) + md5 << checksum_3d_field( checksum(), field ); + else if ( field.datatype() == array::DataType::kind() ) + md5 << checksum_3d_field( checksum(), field ); + else if ( field.datatype() == array::DataType::kind() ) + md5 << checksum_3d_field( checksum(), field ); + else + throw eckit::Exception( "datatype not supported", Here() ); + } + return md5; } std::string NodeColumns::checksum( const Field& field ) const { - FieldSet fieldset; - fieldset.add(field); - return checksum(fieldset); + FieldSet fieldset; + fieldset.add( field ); + return checksum( fieldset ); } -const parallel::Checksum& NodeColumns::checksum() const -{ - if (checksum_) return *checksum_; - checksum_ = NodeColumnsChecksumCache::instance().get_or_create( mesh_ ); - return *checksum_; +const parallel::Checksum& NodeColumns::checksum() const { + if ( checksum_ ) return *checksum_; + checksum_ = NodeColumnsChecksumCache::instance().get_or_create( mesh_ ); + return *checksum_; } - - -//std::string NodesFunctionSpace::checksum( const FieldSet& fieldset ) const { +// std::string NodesFunctionSpace::checksum( const FieldSet& fieldset ) const { // const parallel::Checksum& checksum = mesh_.checksum().get(checksum_name()); // eckit::MD5 md5; @@ -667,1658 +609,1555 @@ const parallel::Checksum& NodeColumns::checksum() const // } // return md5; //} -//std::string NodesFunctionSpace::checksum( const Field& field ) const { +// std::string NodesFunctionSpace::checksum( const Field& field ) const { // FieldSet fieldset; // fieldset.add(field); // return checksum(fieldset); //} -namespace { inline double sqr(const double& val) { return val*val; } } - -namespace detail { // Collectives implementation - +namespace { +inline double sqr( const double& val ) { + return val * val; +} +} // namespace +namespace detail { // Collectives implementation -template< typename T > -void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, size_t& N ) -{ - const mesh::IsGhostNode is_ghost(fs.nodes()); - const array::LocalView arr = make_leveled_scalar_view( field ); - T local_sum = 0; - const size_t npts = std::min(arr.shape(0),fs.nb_nodes()); +template +void dispatch_sum( const NodeColumns& fs, const Field& field, T& result, size_t& N ) { + const mesh::IsGhostNode is_ghost( fs.nodes() ); + const array::LocalView arr = make_leveled_scalar_view( field ); + T local_sum = 0; + const size_t npts = std::min( arr.shape( 0 ), fs.nb_nodes() ); atlas_omp_pragma( omp parallel for default(shared) reduction(+:local_sum) ) for( size_t n=0; n -void sum( const NodeColumns& fs , const Field& field, T& result, size_t& N ) -{ - if( field.datatype() == array::DataType::kind() ) { - return dispatch_sum(fs,field,result,N); - } - else - { - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : { - int tmp; - dispatch_sum(fs,field,tmp,N); - result = tmp; - return; - } - case array::DataType::KIND_INT64 : { - long tmp; - dispatch_sum(fs,field,tmp,N); - result = tmp; - return; - } - case array::DataType::KIND_REAL32 : { - float tmp; - dispatch_sum(fs,field,tmp,N); - result = tmp; - return; - } - case array::DataType::KIND_REAL64 : { - double tmp; - dispatch_sum(fs,field,tmp,N); - result = tmp; - return; - } - default: throw eckit::Exception("datatype not supported",Here()); +template +void sum( const NodeColumns& fs, const Field& field, T& result, size_t& N ) { + if ( field.datatype() == array::DataType::kind() ) { return dispatch_sum( fs, field, result, N ); } + else { + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: { + int tmp; + dispatch_sum( fs, field, tmp, N ); + result = tmp; + return; + } + case array::DataType::KIND_INT64: { + long tmp; + dispatch_sum( fs, field, tmp, N ); + result = tmp; + return; + } + case array::DataType::KIND_REAL32: { + float tmp; + dispatch_sum( fs, field, tmp, N ); + result = tmp; + return; + } + case array::DataType::KIND_REAL64: { + double tmp; + dispatch_sum( fs, field, tmp, N ); + result = tmp; + return; + } + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - } } - - -template< typename T > -void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) -{ - const array::LocalView arr = make_leveled_view(field); - const mesh::IsGhostNode is_ghost(fs.nodes()); - const size_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 size_t npts = arr.shape(0); - atlas_omp_for( size_t n=0; n +void dispatch_sum( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) { + const array::LocalView arr = make_leveled_view( field ); + const mesh::IsGhostNode is_ghost( fs.nodes() ); + const size_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 size_t npts = arr.shape( 0 ); + atlas_omp_for( size_t n = 0; n < npts; ++n ) { + if ( !is_ghost( n ) ) { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < arr.shape( 2 ); ++j ) { + local_sum_private[j] += arr( n, l, j ); + } + } + } + } + atlas_omp_critical { + for ( size_t j = 0; j < nvar; ++j ) { + local_sum[j] += local_sum_private[j]; + } } - } - } - atlas_omp_critical - { - for( size_t j=0; j -void sum( const NodeColumns& fs , const Field& field, std::vector& result, size_t& N ) -{ - if( field.datatype() == array::DataType::kind() ) { - return dispatch_sum(fs,field,result,N); - } - else - { - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : { - std::vector tmp; - dispatch_sum(fs,field,tmp,N); - result.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_INT64 : { - std::vector tmp; - dispatch_sum(fs,field,tmp,N); - result.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL32 : { - std::vector tmp; - dispatch_sum(fs,field,tmp,N); - result.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL64 : { - std::vector tmp; - dispatch_sum(fs,field,tmp,N); - result.assign(tmp.begin(),tmp.end()); - return; - } - default: throw eckit::Exception("datatype not supported",Here()); +template +void sum( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) { + if ( field.datatype() == array::DataType::kind() ) { return dispatch_sum( fs, field, result, N ); } + else { + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: { + std::vector tmp; + dispatch_sum( fs, field, tmp, N ); + result.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_INT64: { + std::vector tmp; + dispatch_sum( fs, field, tmp, N ); + result.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL32: { + std::vector tmp; + dispatch_sum( fs, field, tmp, N ); + result.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL64: { + std::vector tmp; + dispatch_sum( fs, field, tmp, N ); + result.assign( tmp.begin(), tmp.end() ); + return; + } + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - } } +template +void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& sum, size_t& N ) { + mesh::IsGhostNode is_ghost( fs.nodes() ); -template< typename T > -void dispatch_sum_per_level( const NodeColumns& fs, const Field& field, Field& sum, size_t& N ) -{ - mesh::IsGhostNode is_ghost(fs.nodes()); - - array::ArrayShape shape; - shape.reserve(field.rank()-1); - for( size_t j=1; j(field); + auto arr = make_leveled_view( field ); - auto sum_per_level = make_per_level_view( sum ); + auto sum_per_level = make_per_level_view( sum ); - for( size_t l=0; l sum_per_level_private(sum_per_level.shape(0),sum_per_level.shape(1)); - array::ArrayView sum_per_level_private_view = array::make_view(sum_per_level_private); + atlas_omp_parallel { + array::ArrayT sum_per_level_private( sum_per_level.shape( 0 ), sum_per_level.shape( 1 ) ); + array::ArrayView sum_per_level_private_view = array::make_view( sum_per_level_private ); - for( size_t l=0; l(fs,field,sum,N); - case array::DataType::KIND_INT64 : - return dispatch_sum_per_level(fs,field,sum,N); - case array::DataType::KIND_REAL32 : - return dispatch_sum_per_level(fs,field,sum,N); - case array::DataType::KIND_REAL64 : - return dispatch_sum_per_level(fs,field,sum,N); - default: throw eckit::Exception("datatype not supported",Here()); - } +void sum_per_level( const NodeColumns& fs, const Field& field, Field& sum, size_t& N ) { + if ( field.datatype() != sum.datatype() ) { + throw eckit::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 ); + case array::DataType::KIND_INT64: + return dispatch_sum_per_level( fs, field, sum, N ); + case array::DataType::KIND_REAL32: + return dispatch_sum_per_level( fs, field, sum, N ); + case array::DataType::KIND_REAL64: + return dispatch_sum_per_level( fs, field, sum, N ); + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - -template< typename DATATYPE > -void dispatch_order_independent_sum_2d( const NodeColumns& fs , const Field& field, DATATYPE& result, size_t& N ) -{ - size_t root = 0; - Field global = fs.createField( field , option::global() ); - fs.gather(field,global); - result = 0; - auto glb = array::make_view( global ); - for( size_t jnode=0; jnode +void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& field, DATATYPE& result, size_t& N ) { + size_t root = 0; + Field global = fs.createField( field, option::global() ); + fs.gather( field, global ); + result = 0; + auto glb = array::make_view( global ); + for ( size_t jnode = 0; jnode < glb.size(); ++jnode ) { + result += glb( jnode ); + } + ATLAS_TRACE_MPI( BROADCAST ) { mpi::comm().broadcast( &result, 1, root ); } + N = fs.nb_nodes_global(); } -template< typename T > -void dispatch_order_independent_sum( const NodeColumns& fs , const Field& field, T& result, size_t& N ) -{ - if( field.levels() ) - { - const array::LocalView arr = make_leveled_scalar_view(field); - - Field surface_field = fs.createField(option::name("surface") | option::levels(false)); - auto surface = array::make_view( surface_field ); - - for( size_t n=0; n +void dispatch_order_independent_sum( const NodeColumns& fs, const Field& field, T& result, size_t& N ) { + if ( field.levels() ) { + const array::LocalView arr = make_leveled_scalar_view( field ); + + Field surface_field = fs.createField( option::name( "surface" ) | option::levels( false ) ); + auto surface = array::make_view( surface_field ); + + for ( size_t n = 0; n < arr.shape( 0 ); ++n ) { + surface( n ) = 0; + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + surface( n ) += arr( n, l ); + } + } + dispatch_order_independent_sum_2d( fs, surface_field, result, N ); + N *= arr.shape( 1 ); + } + else { + dispatch_order_independent_sum_2d( fs, field, result, N ); } - dispatch_order_independent_sum_2d( fs, surface_field, result, N ); - N *= arr.shape(1); - } - else - { - dispatch_order_independent_sum_2d( fs, field, result, N ); - } } -template< typename T > -void order_independent_sum( const NodeColumns& fs , const Field& field, T& result, size_t& N ) -{ - if( field.datatype() == array::DataType::kind() ) { - return dispatch_order_independent_sum(fs,field,result,N); - } - else - { - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : { - int tmp; - dispatch_order_independent_sum(fs,field,tmp,N); - result = tmp; - return; - } - case array::DataType::KIND_INT64 : { - long tmp; - dispatch_order_independent_sum(fs,field,tmp,N); - result = tmp; - return; - } - case array::DataType::KIND_REAL32 : { - float tmp; - dispatch_order_independent_sum(fs,field,tmp,N); - result = tmp; - return; - } - case array::DataType::KIND_REAL64 : { - double tmp; - dispatch_order_independent_sum(fs,field,tmp,N); - result = tmp; - return; - } - default: throw eckit::Exception("datatype not supported",Here()); +template +void order_independent_sum( const NodeColumns& fs, const Field& field, T& result, size_t& N ) { + if ( field.datatype() == array::DataType::kind() ) { + return dispatch_order_independent_sum( fs, field, result, N ); + } + else { + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: { + int tmp; + dispatch_order_independent_sum( fs, field, tmp, N ); + result = tmp; + return; + } + case array::DataType::KIND_INT64: { + long tmp; + dispatch_order_independent_sum( fs, field, tmp, N ); + result = tmp; + return; + } + case array::DataType::KIND_REAL32: { + float tmp; + dispatch_order_independent_sum( fs, field, tmp, N ); + result = tmp; + return; + } + case array::DataType::KIND_REAL64: { + double tmp; + dispatch_order_independent_sum( fs, field, tmp, N ); + result = tmp; + return; + } + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - } } -template< typename DATATYPE > -void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) -{ - size_t nvar = field.variables(); - result.resize(nvar); - for( size_t j=0; j( global ); - for( size_t n=0; n +void dispatch_order_independent_sum_2d( const NodeColumns& fs, const Field& field, std::vector& result, + size_t& N ) { + size_t nvar = field.variables(); + result.resize( nvar ); + for ( size_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 ) { + const auto glb = make_surface_view( global ); + for ( size_t n = 0; n < fs.nb_nodes_global(); ++n ) { + for ( size_t j = 0; j < nvar; ++j ) { + result[j] += glb( n, j ); + } + } } - } - size_t root = global.metadata().get("owner"); - ATLAS_TRACE_MPI( BROADCAST ) { - mpi::comm().broadcast(result,root); - } - N = fs.nb_nodes_global(); + size_t root = global.metadata().get( "owner" ); + ATLAS_TRACE_MPI( BROADCAST ) { mpi::comm().broadcast( result, root ); } + N = fs.nb_nodes_global(); } -template< typename T > -void dispatch_order_independent_sum( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) -{ - if( field.levels() ) - { - const size_t nvar = field.variables(); - const auto arr = make_leveled_view(field); +template +void dispatch_order_independent_sum( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) { + if ( field.levels() ) { + const size_t nvar = field.variables(); + const auto arr = make_leveled_view( field ); + + Field surface_field = + fs.createField( option::name( "surface" ) | option::variables( nvar ) | option::levels( false ) ); + auto surface = make_surface_view( surface_field ); + + atlas_omp_for( size_t n = 0; n < arr.shape( 0 ); ++n ) { + for ( size_t j = 0; j < arr.shape( 2 ); ++j ) { + surface( n, j ) = 0; + } + } - Field surface_field = fs.createField(option::name("surface")|option::variables(nvar)|option::levels(false)); - auto surface = make_surface_view( surface_field ); + for ( size_t n = 0; n < arr.shape( 0 ); ++n ) { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < arr.shape( 2 ); ++j ) { + surface( n, j ) += arr( n, l, j ); + } + } + } - atlas_omp_for( size_t n=0; n -void order_independent_sum( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) -{ - if( field.datatype() == array::DataType::kind() ) { - return dispatch_order_independent_sum(fs,field,result,N); - } - else - { - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : { - std::vector tmp; - dispatch_order_independent_sum(fs,field,tmp,N); - result.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_INT64 : { - std::vector tmp; - dispatch_order_independent_sum(fs,field,tmp,N); - result.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL32 : { - std::vector tmp; - dispatch_order_independent_sum(fs,field,tmp,N); - result.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL64 : { - std::vector tmp; - dispatch_order_independent_sum(fs,field,tmp,N); - result.assign(tmp.begin(),tmp.end()); - return; - } - default: throw eckit::Exception("datatype not supported",Here()); +template +void order_independent_sum( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) { + if ( field.datatype() == array::DataType::kind() ) { + return dispatch_order_independent_sum( fs, field, result, N ); + } + else { + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: { + std::vector tmp; + dispatch_order_independent_sum( fs, field, tmp, N ); + result.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_INT64: { + std::vector tmp; + dispatch_order_independent_sum( fs, field, tmp, N ); + result.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL32: { + std::vector tmp; + dispatch_order_independent_sum( fs, field, tmp, N ); + result.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL64: { + std::vector tmp; + dispatch_order_independent_sum( fs, field, tmp, N ); + result.assign( tmp.begin(), tmp.end() ); + return; + } + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - } } - -template< typename T > -void dispatch_order_independent_sum_per_level( const NodeColumns& fs, const Field& field, Field& sumfield, size_t& N ) -{ - array::ArrayShape shape; - shape.reserve(field.rank()-1); - for( size_t j=1; j( sumfield ); - for( size_t l=0; l +void dispatch_order_independent_sum_per_level( const NodeColumns& fs, const Field& field, Field& sumfield, size_t& N ) { + array::ArrayShape shape; + shape.reserve( field.rank() - 1 ); + for ( size_t j = 1; j < field.rank(); ++j ) + shape.push_back( field.shape( j ) ); + sumfield.resize( shape ); + + auto sum = make_per_level_view( sumfield ); + for ( size_t l = 0; l < sum.shape( 0 ); ++l ) { + for ( size_t j = 0; j < sum.shape( 1 ); ++j ) { + sum( l, j ) = 0.; + } } - } - size_t root = 0; - Field global = fs.createField( field , option::name("global")|option::global()); + size_t root = 0; + Field global = fs.createField( field, option::name( "global" ) | option::global() ); - fs.gather(field,global); - if( mpi::comm().rank() == 0 ) { - const array::LocalView glb = make_leveled_view(global); + fs.gather( field, global ); + if ( mpi::comm().rank() == 0 ) { + const array::LocalView glb = make_leveled_view( global ); - for( size_t n=0; n sum_array(sumfield.size()); - if( mpi::comm().rank() == root ) { - size_t c(0); - for( size_t l=0; l sum_array( sumfield.size() ); + if ( mpi::comm().rank() == root ) { + size_t c( 0 ); + for ( size_t l = 0; l < sum.shape( 0 ); ++l ) { + for ( size_t j = 0; j < sum.shape( 1 ); ++j ) { + sum_array[c++] = sum( l, j ); + } + } } - } - } - mpi::comm().broadcast( sum_array, root); - if( mpi::comm().rank() != root ) { - size_t c(0); - for( size_t l=0; l(fs,field,sum,N); - case array::DataType::KIND_INT64 : - return dispatch_order_independent_sum_per_level(fs,field,sum,N); - case array::DataType::KIND_REAL32 : - return dispatch_order_independent_sum_per_level(fs,field,sum,N); - case array::DataType::KIND_REAL64 : - return dispatch_order_independent_sum_per_level(fs,field,sum,N); - default: throw eckit::Exception("datatype not supported",Here()); - } +void order_independent_sum_per_level( const NodeColumns& fs, const Field& field, Field& sum, size_t& N ) { + if ( field.datatype() != sum.datatype() ) { + throw eckit::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 ); + case array::DataType::KIND_INT64: + return dispatch_order_independent_sum_per_level( fs, field, sum, N ); + case array::DataType::KIND_REAL32: + return dispatch_order_independent_sum_per_level( fs, field, sum, N ); + case array::DataType::KIND_REAL64: + return dispatch_order_independent_sum_per_level( fs, field, sum, N ); + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } -template< typename T > -void dispatch_minimum( const NodeColumns& fs, const Field& field, std::vector& min ) -{ - const array::LocalView arr = make_leveled_view(field); - const size_t nvar = arr.shape(2); - min.resize(nvar); - std::vector local_minimum(nvar,std::numeric_limits::max()); - atlas_omp_parallel - { - std::vector local_minimum_private(nvar,std::numeric_limits::max()); - const size_t npts = arr.shape(0); - atlas_omp_for( size_t n=0; n +void dispatch_minimum( const NodeColumns& fs, const Field& field, std::vector& min ) { + const array::LocalView arr = make_leveled_view( field ); + const size_t nvar = arr.shape( 2 ); + min.resize( nvar ); + std::vector local_minimum( nvar, std::numeric_limits::max() ); + atlas_omp_parallel { + std::vector local_minimum_private( nvar, std::numeric_limits::max() ); + const size_t npts = arr.shape( 0 ); + atlas_omp_for( size_t n = 0; n < npts; ++n ) { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < arr.shape( 2 ); ++j ) { + local_minimum_private[j] = std::min( arr( n, l, j ), local_minimum_private[j] ); + } + } + } + atlas_omp_critical { + for ( size_t j = 0; j < arr.shape( 2 ); ++j ) { + local_minimum[j] = std::min( local_minimum_private[j], local_minimum[j] ); + } } - } - } - atlas_omp_critical - { - for( size_t j=0; j -void minimum( const NodeColumns& fs, const Field& field, std::vector& min ) -{ - if( field.datatype() == array::DataType::kind() ) { - return dispatch_minimum(fs,field,min); - } - else - { - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : { - std::vector tmp; - dispatch_minimum(fs,field,tmp); - min.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_INT64 : { - std::vector tmp; - dispatch_minimum(fs,field,tmp); - min.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL32 : { - std::vector tmp; - dispatch_minimum(fs,field,tmp); - min.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL64 : { - std::vector tmp; - dispatch_minimum(fs,field,tmp); - min.assign(tmp.begin(),tmp.end()); - return; - } - default: throw eckit::Exception("datatype not supported",Here()); +template +void minimum( const NodeColumns& fs, const Field& field, std::vector& min ) { + if ( field.datatype() == array::DataType::kind() ) { return dispatch_minimum( fs, field, min ); } + else { + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: { + std::vector tmp; + dispatch_minimum( fs, field, tmp ); + min.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_INT64: { + std::vector tmp; + dispatch_minimum( fs, field, tmp ); + min.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL32: { + std::vector tmp; + dispatch_minimum( fs, field, tmp ); + min.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL64: { + std::vector tmp; + dispatch_minimum( fs, field, tmp ); + min.assign( tmp.begin(), tmp.end() ); + return; + } + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - } } -template< typename T > -void dispatch_maximum( const NodeColumns& fs, const Field& field, std::vector& max ) -{ - const array::LocalView arr = make_leveled_view(field); - const size_t nvar = arr.shape(2); - max.resize(nvar); - std::vector local_maximum(nvar,-std::numeric_limits::max()); - atlas_omp_parallel - { - std::vector local_maximum_private(nvar,-std::numeric_limits::max()); - const size_t npts = arr.shape(0); - atlas_omp_for( size_t n=0; n +void dispatch_maximum( const NodeColumns& fs, const Field& field, std::vector& max ) { + const array::LocalView arr = make_leveled_view( field ); + const size_t nvar = arr.shape( 2 ); + max.resize( nvar ); + std::vector local_maximum( nvar, -std::numeric_limits::max() ); + atlas_omp_parallel { + std::vector local_maximum_private( nvar, -std::numeric_limits::max() ); + const size_t npts = arr.shape( 0 ); + atlas_omp_for( size_t n = 0; n < npts; ++n ) { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + local_maximum_private[j] = std::max( arr( n, l, j ), local_maximum_private[j] ); + } + } + } + atlas_omp_critical { + for ( size_t j = 0; j < nvar; ++j ) { + local_maximum[j] = std::max( local_maximum_private[j], local_maximum[j] ); + } } - } - } - atlas_omp_critical - { - for( size_t j=0; j -void maximum( const NodeColumns& fs, const Field& field, std::vector& max ) -{ - if( field.datatype() == array::DataType::kind() ) { - return dispatch_maximum(fs,field,max); - } - else - { - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : { - std::vector tmp; - dispatch_maximum(fs,field,tmp); - max.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_INT64 : { - std::vector tmp; - dispatch_maximum(fs,field,tmp); - max.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL32 : { - std::vector tmp; - dispatch_maximum(fs,field,tmp); - max.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL64 : { - std::vector tmp; - dispatch_maximum(fs,field,tmp); - max.assign(tmp.begin(),tmp.end()); - return; - } - default: throw eckit::Exception("datatype not supported",Here()); +template +void maximum( const NodeColumns& fs, const Field& field, std::vector& max ) { + if ( field.datatype() == array::DataType::kind() ) { return dispatch_maximum( fs, field, max ); } + else { + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: { + std::vector tmp; + dispatch_maximum( fs, field, tmp ); + max.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_INT64: { + std::vector tmp; + dispatch_maximum( fs, field, tmp ); + max.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL32: { + std::vector tmp; + dispatch_maximum( fs, field, tmp ); + max.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL64: { + std::vector tmp; + dispatch_maximum( fs, field, tmp ); + max.assign( tmp.begin(), tmp.end() ); + return; + } + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - } } -template< typename T > -void minimum( const NodeColumns& fs, const Field& field, T& min ) -{ - std::vector v; - minimum(fs,field,v); - min = v[0]; +template +void minimum( const NodeColumns& fs, const Field& field, T& min ) { + std::vector v; + minimum( fs, field, v ); + min = v[0]; } -template< typename T > -void maximum( const NodeColumns& fs, const Field& field, T& max ) -{ - std::vector v; - maximum(fs,field,v); - max = v[0]; +template +void maximum( const NodeColumns& fs, const Field& field, T& max ) { + std::vector v; + maximum( fs, field, v ); + max = v[0]; } -template< typename T > -void dispatch_minimum_per_level( const NodeColumns& fs, const Field& field, Field& min_field ) -{ - array::ArrayShape shape; - shape.reserve(field.rank()-1); - for( size_t j=1; j( min_field ); - - for( size_t l=0; l::max(); +template +void dispatch_minimum_per_level( const NodeColumns& fs, const Field& field, Field& min_field ) { + array::ArrayShape shape; + shape.reserve( field.rank() - 1 ); + for ( size_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 ); + + for ( size_t l = 0; l < min.shape( 0 ); ++l ) { + for ( size_t j = 0; j < min.shape( 1 ); ++j ) { + min( l, j ) = std::numeric_limits::max(); + } } - } - const array::LocalView arr = make_leveled_view(field); - atlas_omp_parallel - { - array::ArrayT min_private( min.shape(0),min.shape(1) ); - array::ArrayView min_private_view = array::make_view(min_private); - for( size_t l=0; l::max(); - } - } + const array::LocalView arr = make_leveled_view( field ); + atlas_omp_parallel { + array::ArrayT min_private( min.shape( 0 ), min.shape( 1 ) ); + array::ArrayView min_private_view = array::make_view( min_private ); + for ( size_t l = 0; l < min.shape( 0 ); ++l ) { + for ( size_t j = 0; j < min.shape( 1 ); ++j ) { + min_private_view( l, j ) = std::numeric_limits::max(); + } + } - const size_t npts = arr.shape(0); - atlas_omp_for( size_t n=0; n(fs,field,min); - case array::DataType::KIND_INT64 : - return dispatch_minimum_per_level(fs,field,min); - case array::DataType::KIND_REAL32 : - return dispatch_minimum_per_level(fs,field,min); - case array::DataType::KIND_REAL64 : - return dispatch_minimum_per_level(fs,field,min); - default: throw eckit::Exception("datatype not supported",Here()); - } +void minimum_per_level( const NodeColumns& fs, const Field& field, Field& min ) { + if ( field.datatype() != min.datatype() ) { + throw eckit::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 ); + case array::DataType::KIND_INT64: + return dispatch_minimum_per_level( fs, field, min ); + case array::DataType::KIND_REAL32: + return dispatch_minimum_per_level( fs, field, min ); + case array::DataType::KIND_REAL64: + return dispatch_minimum_per_level( fs, field, min ); + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } -template< typename T > -void dispatch_maximum_per_level( const NodeColumns& fs, const Field& field, Field& max_field ) -{ - array::ArrayShape shape; - shape.reserve(field.rank()-1); - for( size_t j=1; j( max_field ); - - for( size_t l=0; l::max(); +template +void dispatch_maximum_per_level( const NodeColumns& fs, const Field& field, Field& max_field ) { + array::ArrayShape shape; + shape.reserve( field.rank() - 1 ); + for ( size_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 ); + + for ( size_t l = 0; l < max.shape( 0 ); ++l ) { + for ( size_t j = 0; j < max.shape( 1 ); ++j ) { + max( l, j ) = -std::numeric_limits::max(); + } } - } - const array::LocalView arr = make_leveled_view(field); - atlas_omp_parallel - { - array::ArrayT max_private(max.shape(0),max.shape(1)); - array::ArrayView max_private_view = array::make_view(max_private); + const array::LocalView arr = make_leveled_view( field ); + atlas_omp_parallel { + array::ArrayT max_private( max.shape( 0 ), max.shape( 1 ) ); + array::ArrayView max_private_view = array::make_view( max_private ); - for( size_t l=0; l::max(); - } - } + for ( size_t l = 0; l < max_private_view.shape( 0 ); ++l ) { + for ( size_t j = 0; j < max_private_view.shape( 1 ); ++j ) { + max_private_view( l, j ) = -std::numeric_limits::max(); + } + } - const size_t npts = arr.shape(0); - atlas_omp_for( size_t n=0; n(fs,field,max); - case array::DataType::KIND_INT64 : - return dispatch_maximum_per_level(fs,field,max); - case array::DataType::KIND_REAL32 : - return dispatch_maximum_per_level(fs,field,max); - case array::DataType::KIND_REAL64 : - return dispatch_maximum_per_level(fs,field,max); - default: throw eckit::Exception("datatype not supported",Here()); - } +void maximum_per_level( const NodeColumns& fs, const Field& field, Field& max ) { + if ( field.datatype() != max.datatype() ) { + throw eckit::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 ); + case array::DataType::KIND_INT64: + return dispatch_maximum_per_level( fs, field, max ); + case array::DataType::KIND_REAL32: + return dispatch_maximum_per_level( fs, field, max ); + case array::DataType::KIND_REAL64: + return dispatch_maximum_per_level( fs, field, max ); + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - -template< typename T > -void dispatch_minimum_and_location( const NodeColumns& fs, const Field& field, std::vector& min, std::vector& glb_idx, std::vector& level ) -{ - array::LocalView arr = make_leveled_view(field); - size_t nvar = arr.shape(2); - min.resize(nvar); - glb_idx.resize(nvar); - level.resize(nvar); - std::vector local_minimum(nvar,std::numeric_limits::max()); - std::vector loc_node(nvar); - std::vector loc_level(nvar); - atlas_omp_parallel - { - std::vector local_minimum_private(nvar,std::numeric_limits::max()); - std::vector loc_node_private(nvar); - std::vector loc_level_private(nvar); - const size_t npts = arr.shape(0); - atlas_omp_for( size_t n=0; n +void dispatch_minimum_and_location( const NodeColumns& fs, const Field& field, std::vector& min, + std::vector& glb_idx, std::vector& level ) { + array::LocalView arr = make_leveled_view( field ); + size_t nvar = arr.shape( 2 ); + min.resize( nvar ); + glb_idx.resize( nvar ); + level.resize( nvar ); + std::vector local_minimum( nvar, std::numeric_limits::max() ); + std::vector loc_node( nvar ); + std::vector loc_level( nvar ); + atlas_omp_parallel { + std::vector local_minimum_private( nvar, std::numeric_limits::max() ); + std::vector loc_node_private( nvar ); + std::vector loc_level_private( nvar ); + const size_t npts = arr.shape( 0 ); + atlas_omp_for( size_t n = 0; n < npts; ++n ) { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + if ( arr( n, l, j ) < local_minimum_private[j] ) { + local_minimum_private[j] = arr( n, l, j ); + loc_node_private[j] = n; + loc_level_private[j] = l; + } + } + } } - } - } - atlas_omp_critical_ordered - { - for( size_t l=0; l > min_and_gidx_loc(nvar); - std::vector< std::pair > min_and_level_loc(nvar); - std::vector< std::pair > min_and_gidx_glb(nvar); - std::vector< std::pair > min_and_level_glb(nvar); - const array::ArrayView global_index = array::make_view(fs.nodes().global_index()); - for( size_t j=0; j::max() ); // pairs with 64bit integer for second not implemented - min_and_gidx_loc[j] = std::make_pair(local_minimum[j],glb_idx); - min_and_level_loc[j] = std::make_pair(local_minimum[j],loc_level[j]); - } - - ATLAS_TRACE_MPI( ALLREDUCE ) { - mpi::comm().allReduce(min_and_gidx_loc, min_and_gidx_glb, eckit::mpi::minloc()); - mpi::comm().allReduce(min_and_level_loc,min_and_level_glb,eckit::mpi::minloc()); - } + std::vector> min_and_gidx_loc( nvar ); + std::vector> min_and_level_loc( nvar ); + std::vector> min_and_gidx_glb( nvar ); + std::vector> min_and_level_glb( nvar ); + const array::ArrayView global_index = array::make_view( fs.nodes().global_index() ); + for ( size_t j = 0; j < nvar; ++j ) { + gidx_t glb_idx = global_index( loc_node[j] ); + ASSERT( glb_idx < std::numeric_limits::max() ); // pairs with 64bit + // integer for second not + // implemented + min_and_gidx_loc[j] = std::make_pair( local_minimum[j], glb_idx ); + min_and_level_loc[j] = std::make_pair( local_minimum[j], loc_level[j] ); + } - for( size_t j=0; j -void minimum_and_location( const NodeColumns& fs, const Field& field, std::vector& min, std::vector& glb_idx, std::vector& level ) -{ - if( field.datatype() == array::DataType::kind() ) { - return dispatch_minimum_and_location(fs,field,min,glb_idx,level); - } - else - { - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : { - std::vector tmp; - dispatch_minimum_and_location(fs,field,tmp,glb_idx,level); - min.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_INT64 : { - std::vector tmp; - dispatch_minimum_and_location(fs,field,tmp,glb_idx,level); - min.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL32 : { - std::vector tmp; - dispatch_minimum_and_location(fs,field,tmp,glb_idx,level); - min.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL64 : { - std::vector tmp; - dispatch_minimum_and_location(fs,field,tmp,glb_idx,level); - min.assign(tmp.begin(),tmp.end()); - return; - } - default: throw eckit::Exception("datatype not supported",Here()); +template +void minimum_and_location( const NodeColumns& fs, const Field& field, std::vector& min, std::vector& glb_idx, + std::vector& level ) { + if ( field.datatype() == array::DataType::kind() ) { + return dispatch_minimum_and_location( fs, field, min, glb_idx, level ); + } + else { + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: { + std::vector tmp; + dispatch_minimum_and_location( fs, field, tmp, glb_idx, level ); + min.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_INT64: { + std::vector tmp; + dispatch_minimum_and_location( fs, field, tmp, glb_idx, level ); + min.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL32: { + std::vector tmp; + dispatch_minimum_and_location( fs, field, tmp, glb_idx, level ); + min.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL64: { + std::vector tmp; + dispatch_minimum_and_location( fs, field, tmp, glb_idx, level ); + min.assign( tmp.begin(), tmp.end() ); + return; + } + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - } } - -template< typename T > -void dispatch_maximum_and_location( const NodeColumns& fs, const Field& field, std::vector& max, std::vector& glb_idx, std::vector& level ) -{ - array::LocalView arr = make_leveled_view(field); - size_t nvar = arr.shape(2); - max.resize(nvar); - glb_idx.resize(nvar); - level.resize(nvar); - std::vector local_maximum(nvar,-std::numeric_limits::max()); - std::vector loc_node(nvar); - std::vector loc_level(nvar); - atlas_omp_parallel - { - std::vector local_maximum_private(nvar,-std::numeric_limits::max()); - std::vector loc_node_private(nvar); - std::vector loc_level_private(nvar); - const size_t npts = arr.shape(0); - atlas_omp_for( size_t n=0; n local_maximum_private[j] ) { - local_maximum_private[j] = arr(n,l,j); - loc_node_private[j] = n; - loc_level_private[j] = l; - } +template +void dispatch_maximum_and_location( const NodeColumns& fs, const Field& field, std::vector& max, + std::vector& glb_idx, std::vector& level ) { + array::LocalView arr = make_leveled_view( field ); + size_t nvar = arr.shape( 2 ); + max.resize( nvar ); + glb_idx.resize( nvar ); + level.resize( nvar ); + std::vector local_maximum( nvar, -std::numeric_limits::max() ); + std::vector loc_node( nvar ); + std::vector loc_level( nvar ); + atlas_omp_parallel { + std::vector local_maximum_private( nvar, -std::numeric_limits::max() ); + std::vector loc_node_private( nvar ); + std::vector loc_level_private( nvar ); + const size_t npts = arr.shape( 0 ); + atlas_omp_for( size_t n = 0; n < npts; ++n ) { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + if ( arr( n, l, j ) > local_maximum_private[j] ) { + local_maximum_private[j] = arr( n, l, j ); + loc_node_private[j] = n; + loc_level_private[j] = l; + } + } + } } - } - } - atlas_omp_critical_ordered - { - for( size_t l=0; l local_maximum[j] ) { - local_maximum[j] = local_maximum_private[j]; - loc_node[j] = loc_node_private[j]; - loc_level[j] = loc_level_private[j]; - } + atlas_omp_critical_ordered { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + if ( local_maximum_private[j] > local_maximum[j] ) { + local_maximum[j] = local_maximum_private[j]; + loc_node[j] = loc_node_private[j]; + loc_level[j] = loc_level_private[j]; + } + } + } } - } } - } - std::vector< std::pair > max_and_gidx_loc(nvar); - std::vector< std::pair > max_and_level_loc(nvar); - std::vector< std::pair > max_and_gidx_glb(nvar); - std::vector< std::pair > max_and_level_glb(nvar); - const array::ArrayView global_index = array::make_view( fs.nodes().global_index() ); - for( size_t j=0; j::max() ); // pairs with 64bit integer for second not implemented - max_and_gidx_loc[j] = std::make_pair(local_maximum[j],glb_idx); - max_and_level_loc[j] = std::make_pair(local_maximum[j],loc_level[j]); - } + std::vector> max_and_gidx_loc( nvar ); + std::vector> max_and_level_loc( nvar ); + std::vector> max_and_gidx_glb( nvar ); + std::vector> max_and_level_glb( nvar ); + const array::ArrayView global_index = array::make_view( fs.nodes().global_index() ); + for ( size_t j = 0; j < nvar; ++j ) { + gidx_t glb_idx = global_index( loc_node[j] ); + ASSERT( glb_idx < std::numeric_limits::max() ); // pairs with 64bit + // integer for second not + // implemented + max_and_gidx_loc[j] = std::make_pair( local_maximum[j], glb_idx ); + max_and_level_loc[j] = std::make_pair( local_maximum[j], loc_level[j] ); + } - ATLAS_TRACE_MPI( ALLREDUCE ) { - mpi::comm().allReduce(max_and_gidx_loc, max_and_gidx_glb, eckit::mpi::maxloc()); - mpi::comm().allReduce(max_and_level_loc,max_and_level_glb,eckit::mpi::maxloc()); - } + ATLAS_TRACE_MPI( ALLREDUCE ) { + mpi::comm().allReduce( max_and_gidx_loc, max_and_gidx_glb, eckit::mpi::maxloc() ); + mpi::comm().allReduce( max_and_level_loc, max_and_level_glb, eckit::mpi::maxloc() ); + } - for( size_t j=0; j -void maximum_and_location( const NodeColumns& fs, const Field& field, std::vector& max, std::vector& glb_idx, std::vector& level ) -{ - if( field.datatype() == array::DataType::kind() ) { - return dispatch_maximum_and_location(fs,field,max,glb_idx,level); - } - else - { - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : { - std::vector tmp; - dispatch_maximum_and_location(fs,field,tmp,glb_idx,level); - max.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_INT64 : { - std::vector tmp; - dispatch_maximum_and_location(fs,field,tmp,glb_idx,level); - max.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL32 : { - std::vector tmp; - dispatch_maximum_and_location(fs,field,tmp,glb_idx,level); - max.assign(tmp.begin(),tmp.end()); - return; - } - case array::DataType::KIND_REAL64 : { - std::vector tmp; - dispatch_maximum_and_location(fs,field,tmp,glb_idx,level); - max.assign(tmp.begin(),tmp.end()); - return; - } - default: throw eckit::Exception("datatype not supported",Here()); +template +void maximum_and_location( const NodeColumns& fs, const Field& field, std::vector& max, std::vector& glb_idx, + std::vector& level ) { + if ( field.datatype() == array::DataType::kind() ) { + return dispatch_maximum_and_location( fs, field, max, glb_idx, level ); + } + else { + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: { + std::vector tmp; + dispatch_maximum_and_location( fs, field, tmp, glb_idx, level ); + max.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_INT64: { + std::vector tmp; + dispatch_maximum_and_location( fs, field, tmp, glb_idx, level ); + max.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL32: { + std::vector tmp; + dispatch_maximum_and_location( fs, field, tmp, glb_idx, level ); + max.assign( tmp.begin(), tmp.end() ); + return; + } + case array::DataType::KIND_REAL64: { + std::vector tmp; + dispatch_maximum_and_location( fs, field, tmp, glb_idx, level ); + max.assign( tmp.begin(), tmp.end() ); + return; + } + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - } } -template< typename T > -void minimum_and_location( const NodeColumns& fs, const Field& field, std::vector& min, std::vector& glb_idx) -{ - std::vector level; - minimum_and_location(fs,field,min,glb_idx,level); -} - -template< typename T > -void maximum_and_location( const NodeColumns& fs, const Field& field, std::vector& max, std::vector& glb_idx) -{ - std::vector level; - maximum_and_location(fs,field,max,glb_idx,level); -} - -template< typename T > -void minimum_and_location( const NodeColumns& fs, const Field& field, T& min, gidx_t& glb_idx, size_t& level) -{ - std::vector minv; - std::vector gidxv; - std::vector levelv; - minimum_and_location(fs,field,minv,gidxv,levelv); - min = minv[0]; - glb_idx = gidxv[0]; - level = levelv[0]; -} - -template< typename T > -void maximum_and_location( const NodeColumns& fs, const Field& field, T& max, gidx_t& glb_idx, size_t& level) -{ - std::vector maxv; - std::vector gidxv; - std::vector levelv; - maximum_and_location(fs,field,maxv,gidxv,levelv); - max = maxv[0]; - glb_idx = gidxv[0]; - level = levelv[0]; -} - -template< typename T > -void minimum_and_location( const NodeColumns& fs, const Field& field, T& min, gidx_t& glb_idx) -{ - size_t level; - minimum_and_location(fs,field,min,glb_idx,level); -} - -template< typename T > -void maximum_and_location( const NodeColumns& fs, const Field& field, T& max, gidx_t& glb_idx) -{ - size_t level; - maximum_and_location(fs,field,max,glb_idx,level); -} - -template< typename T > -void dispatch_minimum_and_location_per_level( const NodeColumns& fs, const Field& field, Field& min_field, Field& glb_idx_field ) -{ - const array::LocalView arr = make_leveled_view(field); - array::ArrayShape shape; - shape.reserve(field.rank()-1); - for( size_t j=1; j( min_field ); - auto glb_idx = make_per_level_view( glb_idx_field ); - - for( size_t l=0; l::max(); - } - } +template +void minimum_and_location( const NodeColumns& fs, const Field& field, std::vector& min, + std::vector& glb_idx ) { + std::vector level; + minimum_and_location( fs, field, min, glb_idx, level ); +} - atlas_omp_parallel - { - array::ArrayT min_private(min.shape(0),min.shape(1)); - array::ArrayView min_private_view = array::make_view(min_private); +template +void maximum_and_location( const NodeColumns& fs, const Field& field, std::vector& max, + std::vector& glb_idx ) { + std::vector level; + maximum_and_location( fs, field, max, glb_idx, level ); +} - for( size_t l=0; l::max(); - } - } +template +void minimum_and_location( const NodeColumns& fs, const Field& field, T& min, gidx_t& glb_idx, size_t& level ) { + std::vector minv; + std::vector gidxv; + std::vector levelv; + minimum_and_location( fs, field, minv, gidxv, levelv ); + min = minv[0]; + glb_idx = gidxv[0]; + level = levelv[0]; +} + +template +void maximum_and_location( const NodeColumns& fs, const Field& field, T& max, gidx_t& glb_idx, size_t& level ) { + std::vector maxv; + std::vector gidxv; + std::vector levelv; + maximum_and_location( fs, field, maxv, gidxv, levelv ); + max = maxv[0]; + glb_idx = gidxv[0]; + level = levelv[0]; +} - array::ArrayT glb_idx_private(glb_idx.shape(0),glb_idx.shape(1)); - array::ArrayView glb_idx_private_view = array::make_view(glb_idx_private); - const size_t npts = arr.shape(0); - atlas_omp_for( size_t n=0; n +void minimum_and_location( const NodeColumns& fs, const Field& field, T& min, gidx_t& glb_idx ) { + size_t level; + minimum_and_location( fs, field, min, glb_idx, level ); +} + +template +void maximum_and_location( const NodeColumns& fs, const Field& field, T& max, gidx_t& glb_idx ) { + size_t level; + maximum_and_location( fs, field, max, glb_idx, level ); +} + +template +void dispatch_minimum_and_location_per_level( const NodeColumns& fs, const Field& field, Field& min_field, + Field& glb_idx_field ) { + const array::LocalView arr = make_leveled_view( field ); + array::ArrayShape shape; + shape.reserve( field.rank() - 1 ); + for ( size_t j = 1; j < field.rank(); ++j ) + shape.push_back( field.shape( j ) ); + min_field.resize( shape ); + glb_idx_field.resize( shape ); + const size_t nvar = arr.shape( 2 ); + auto min = make_per_level_view( min_field ); + auto glb_idx = make_per_level_view( glb_idx_field ); + + for ( size_t l = 0; l < min.shape( 0 ); ++l ) { + for ( size_t j = 0; j < min.shape( 1 ); ++j ) { + min( l, j ) = std::numeric_limits::max(); } - } } - atlas_omp_critical_ordered - { - for( size_t l=0; l min_private( min.shape( 0 ), min.shape( 1 ) ); + array::ArrayView min_private_view = array::make_view( min_private ); + + for ( size_t l = 0; l < min_private_view.shape( 0 ); ++l ) { + for ( size_t j = 0; j < min_private_view.shape( 1 ); ++j ) { + min_private_view( l, j ) = std::numeric_limits::max(); + } + } + + array::ArrayT glb_idx_private( glb_idx.shape( 0 ), glb_idx.shape( 1 ) ); + array::ArrayView glb_idx_private_view = array::make_view( glb_idx_private ); + const size_t npts = arr.shape( 0 ); + atlas_omp_for( size_t n = 0; n < npts; ++n ) { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + if ( arr( n, l, j ) < min( l, j ) ) { + min_private_view( l, j ) = arr( n, l, j ); + glb_idx_private_view( l, j ) = n; + } + } + } + } + atlas_omp_critical_ordered { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + if ( min_private_view( l, j ) < min( l, j ) ) { + min( l, j ) = min_private_view( l, j ); + glb_idx( l, j ) = glb_idx_private_view( l, j ); + } + } + } } - } } - } - const size_t nlev = arr.shape(1); - std::vector< std::pair > min_and_gidx_loc(nlev*nvar); - std::vector< std::pair > min_and_gidx_glb(nlev*nvar); - const array::ArrayView global_index = array::make_view( fs.nodes().global_index() ); - atlas_omp_parallel_for( size_t l=0; l::max() ); // pairs with 64bit integer for second not implemented - min_and_gidx_loc[j+nvar*l] = std::make_pair(min(l,j),gidx); + const size_t nlev = arr.shape( 1 ); + std::vector> min_and_gidx_loc( nlev * nvar ); + std::vector> min_and_gidx_glb( nlev * nvar ); + const array::ArrayView global_index = array::make_view( fs.nodes().global_index() ); + atlas_omp_parallel_for( size_t l = 0; l < nlev; ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + gidx_t gidx = global_index( glb_idx( l, j ) ); + ASSERT( gidx < std::numeric_limits::max() ); // pairs with 64bit + // integer for second not + // implemented + min_and_gidx_loc[j + nvar * l] = std::make_pair( min( l, j ), gidx ); + } } - } - ATLAS_TRACE_MPI( ALLREDUCE ) { - mpi::comm().allReduce(min_and_gidx_loc,min_and_gidx_glb,eckit::mpi::minloc()); - } + ATLAS_TRACE_MPI( ALLREDUCE ) { mpi::comm().allReduce( min_and_gidx_loc, min_and_gidx_glb, eckit::mpi::minloc() ); } - atlas_omp_parallel_for( size_t l=0; l() ) { - throw eckit::Exception("glb_idx Field is not of correct datatype",Here()); - } - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : - return dispatch_minimum_and_location_per_level(fs,field,min,glb_idx); - case array::DataType::KIND_INT64 : - return dispatch_minimum_and_location_per_level(fs,field,min,glb_idx); - case array::DataType::KIND_REAL32 : - return dispatch_minimum_and_location_per_level(fs,field,min,glb_idx); - case array::DataType::KIND_REAL64 : - return dispatch_minimum_and_location_per_level(fs,field,min,glb_idx); - default: throw eckit::Exception("datatype not supported",Here()); - } +void minimum_and_location_per_level( const NodeColumns& fs, const Field& field, Field& min, Field& glb_idx ) { + if ( field.datatype() != min.datatype() ) { + throw eckit::Exception( "Field and min are not of same datatype.", Here() ); + } + if ( glb_idx.datatype() != array::DataType::kind() ) { + throw eckit::Exception( "glb_idx Field is not of correct datatype", Here() ); + } + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: + return dispatch_minimum_and_location_per_level( fs, field, min, glb_idx ); + case array::DataType::KIND_INT64: + return dispatch_minimum_and_location_per_level( fs, field, min, glb_idx ); + case array::DataType::KIND_REAL32: + return dispatch_minimum_and_location_per_level( fs, field, min, glb_idx ); + case array::DataType::KIND_REAL64: + return dispatch_minimum_and_location_per_level( fs, field, min, glb_idx ); + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - -template< typename T > -void dispatch_maximum_and_location_per_level( const NodeColumns& fs, const Field& field, Field& max_field, Field& glb_idx_field ) -{ - const array::LocalView arr = make_leveled_view(field); - array::ArrayShape shape; - shape.reserve(field.rank()-1); - for( size_t j=1; j( max_field ); - auto glb_idx = make_per_level_view( glb_idx_field ); - - for( size_t l=0; l::max(); +template +void dispatch_maximum_and_location_per_level( const NodeColumns& fs, const Field& field, Field& max_field, + Field& glb_idx_field ) { + const array::LocalView arr = make_leveled_view( field ); + array::ArrayShape shape; + shape.reserve( field.rank() - 1 ); + for ( size_t j = 1; j < field.rank(); ++j ) + shape.push_back( field.shape( j ) ); + max_field.resize( shape ); + glb_idx_field.resize( shape ); + const size_t nvar = arr.shape( 2 ); + auto max = make_per_level_view( max_field ); + auto glb_idx = make_per_level_view( glb_idx_field ); + + for ( size_t l = 0; l < max.shape( 0 ); ++l ) { + for ( size_t j = 0; j < max.shape( 1 ); ++j ) { + max( l, j ) = -std::numeric_limits::max(); + } } - } - atlas_omp_parallel - { - array::ArrayT max_private(max.shape(0),max.shape(1)); - array::ArrayView max_private_view = array::make_view(max_private); + atlas_omp_parallel { + array::ArrayT max_private( max.shape( 0 ), max.shape( 1 ) ); + array::ArrayView max_private_view = array::make_view( max_private ); - for( size_t l=0; l::max(); - } - } + for ( size_t l = 0; l < max_private_view.shape( 0 ); ++l ) { + for ( size_t j = 0; j < max_private_view.shape( 1 ); ++j ) { + max_private_view( l, j ) = -std::numeric_limits::max(); + } + } - array::ArrayT glb_idx_private(glb_idx.shape(0),glb_idx.shape(1)); - array::ArrayView glb_idx_private_view = array::make_view(glb_idx_private); - const size_t npts = arr.shape(0); - atlas_omp_for( size_t n=0; n max(l,j) ) { - max_private_view(l,j) = arr(n,l,j); - glb_idx_private_view(l,j) = n; - } + array::ArrayT glb_idx_private( glb_idx.shape( 0 ), glb_idx.shape( 1 ) ); + array::ArrayView glb_idx_private_view = array::make_view( glb_idx_private ); + const size_t npts = arr.shape( 0 ); + atlas_omp_for( size_t n = 0; n < npts; ++n ) { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + if ( arr( n, l, j ) > max( l, j ) ) { + max_private_view( l, j ) = arr( n, l, j ); + glb_idx_private_view( l, j ) = n; + } + } + } } - } - } - atlas_omp_critical_ordered - { - for( size_t l=0; l max(l,j) ) { - max(l,j) = max_private_view(l,j); - glb_idx(l,j) = glb_idx_private_view(l,j); - } + atlas_omp_critical_ordered { + for ( size_t l = 0; l < arr.shape( 1 ); ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + if ( max_private_view( l, j ) > max( l, j ) ) { + max( l, j ) = max_private_view( l, j ); + glb_idx( l, j ) = glb_idx_private_view( l, j ); + } + } + } } - } } - } - const size_t nlev = arr.shape(1); - std::vector< std::pair > max_and_gidx_loc(nlev*nvar); - std::vector< std::pair > max_and_gidx_glb(nlev*nvar); - const array::ArrayView global_index = array::make_view( fs.nodes().global_index() ); - atlas_omp_parallel_for( size_t l=0; l::max() ); // pairs with 64bit integer for second not implemented - max_and_gidx_loc[j+nvar*l] = std::make_pair(max(l,j),gidx); + const size_t nlev = arr.shape( 1 ); + std::vector> max_and_gidx_loc( nlev * nvar ); + std::vector> max_and_gidx_glb( nlev * nvar ); + const array::ArrayView global_index = array::make_view( fs.nodes().global_index() ); + atlas_omp_parallel_for( size_t l = 0; l < nlev; ++l ) { + for ( size_t j = 0; j < nvar; ++j ) { + gidx_t gidx = global_index( glb_idx( l, j ) ); + ASSERT( gidx < std::numeric_limits::max() ); // pairs with 64bit + // integer for second not + // implemented + max_and_gidx_loc[j + nvar * l] = std::make_pair( max( l, j ), gidx ); + } } - } - ATLAS_TRACE_MPI( ALLREDUCE ) { - mpi::comm().allReduce(max_and_gidx_loc,max_and_gidx_glb,eckit::mpi::maxloc()); - } + ATLAS_TRACE_MPI( ALLREDUCE ) { mpi::comm().allReduce( max_and_gidx_loc, max_and_gidx_glb, eckit::mpi::maxloc() ); } - atlas_omp_parallel_for( size_t l=0; l() ) { - throw eckit::Exception("glb_idx Field is not of correct datatype",Here()); - } - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : - return dispatch_maximum_and_location_per_level(fs,field,max,glb_idx); - case array::DataType::KIND_INT64 : - return dispatch_maximum_and_location_per_level(fs,field,max,glb_idx); - case array::DataType::KIND_REAL32 : - return dispatch_maximum_and_location_per_level(fs,field,max,glb_idx); - case array::DataType::KIND_REAL64 : - return dispatch_maximum_and_location_per_level(fs,field,max,glb_idx); - default: throw eckit::Exception("datatype not supported",Here()); - } +void maximum_and_location_per_level( const NodeColumns& fs, const Field& field, Field& max, Field& glb_idx ) { + if ( field.datatype() != max.datatype() ) { + throw eckit::Exception( "Field and max are not of same datatype.", Here() ); + } + if ( glb_idx.datatype() != array::DataType::kind() ) { + throw eckit::Exception( "glb_idx Field is not of correct datatype", Here() ); + } + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: + return dispatch_maximum_and_location_per_level( fs, field, max, glb_idx ); + case array::DataType::KIND_INT64: + return dispatch_maximum_and_location_per_level( fs, field, max, glb_idx ); + case array::DataType::KIND_REAL32: + return dispatch_maximum_and_location_per_level( fs, field, max, glb_idx ); + case array::DataType::KIND_REAL64: + return dispatch_maximum_and_location_per_level( fs, field, max, glb_idx ); + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } - -template< typename T > -void mean( const NodeColumns& fs, const Field& field, T& result, size_t& N ) -{ - sum(fs,field,result,N); - result /= static_cast(N); +template +void mean( const NodeColumns& fs, const Field& field, T& result, size_t& N ) { + sum( fs, field, result, N ); + result /= static_cast( N ); } -template< typename T > -void mean( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) -{ - sum(fs,field,result,N); - for( size_t j=0; j(N); - } +template +void mean( const NodeColumns& fs, const Field& field, std::vector& result, size_t& N ) { + sum( fs, field, result, N ); + for ( size_t j = 0; j < result.size(); ++j ) { + result[j] /= static_cast( N ); + } } -template< typename T > -void dispatch_mean_per_level( const NodeColumns& fs, const Field& field, Field& mean, size_t& N ) -{ - dispatch_sum_per_level(fs,field,mean,N); - auto view = make_per_level_view( mean ); - for( size_t l=0; l(N); +template +void dispatch_mean_per_level( const NodeColumns& fs, const Field& field, Field& mean, size_t& N ) { + dispatch_sum_per_level( fs, field, mean, N ); + auto view = make_per_level_view( mean ); + for ( size_t l = 0; l < view.shape( 0 ); ++l ) { + for ( size_t j = 0; j < view.shape( 1 ); ++j ) { + view( l, j ) /= static_cast( N ); + } } - } } - -void mean_per_level( const NodeColumns& fs, const Field& field, Field& mean, size_t& N ) -{ - if( field.datatype() != mean.datatype() ) { - throw eckit::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); - case array::DataType::KIND_INT64 : - return dispatch_mean_per_level(fs,field,mean,N); - case array::DataType::KIND_REAL32 : - return dispatch_mean_per_level(fs,field,mean,N); - case array::DataType::KIND_REAL64 : - return dispatch_mean_per_level(fs,field,mean,N); - default: throw eckit::Exception("datatype not supported",Here()); - } +void mean_per_level( const NodeColumns& fs, const Field& field, Field& mean, size_t& N ) { + if ( field.datatype() != mean.datatype() ) { + throw eckit::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 ); + case array::DataType::KIND_INT64: + return dispatch_mean_per_level( fs, field, mean, N ); + case array::DataType::KIND_REAL32: + return dispatch_mean_per_level( fs, field, mean, N ); + case array::DataType::KIND_REAL64: + return dispatch_mean_per_level( fs, field, mean, N ); + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } -template< typename T > -void mean_and_standard_deviation( const NodeColumns& fs, const Field& field, T& mu, T& sigma, size_t& N ) -{ - mean(fs,field,mu,N); - Field squared_diff_field = fs.createField( - option::name("sqr_diff") | - option::datatype(field.datatype()) | - option::levels( field.levels() ) ); - - array::LocalView squared_diff = make_leveled_scalar_view( squared_diff_field ); - array::LocalView values = make_leveled_scalar_view( field ); +template +void mean_and_standard_deviation( const NodeColumns& fs, const Field& field, T& mu, T& sigma, size_t& N ) { + mean( fs, field, mu, N ); + Field squared_diff_field = fs.createField( option::name( "sqr_diff" ) | option::datatype( field.datatype() ) | + option::levels( field.levels() ) ); + + array::LocalView squared_diff = make_leveled_scalar_view( squared_diff_field ); + array::LocalView values = make_leveled_scalar_view( field ); + + const size_t npts = std::min( values.shape( 0 ), fs.nb_nodes() ); + atlas_omp_parallel_for( size_t n = 0; n < npts; ++n ) { + for ( size_t l = 0; l < values.shape( 1 ); ++l ) { + squared_diff( n, l ) = sqr( values( n, l ) - mu ); + } + } + mean( fs, squared_diff_field, sigma, N ); + sigma = std::sqrt( sigma ); +} - const size_t npts = std::min(values.shape(0),fs.nb_nodes()); - atlas_omp_parallel_for( size_t n=0; n +void mean_and_standard_deviation( const NodeColumns& fs, const Field& field, std::vector& mu, std::vector& sigma, + size_t& N ) { + mean( fs, field, mu, N ); + Field squared_diff_field = fs.createField( option::name( "sqr_diff" ) | option::levels( field.levels() ) | + option::variables( field.variables() ) ); + array::LocalView squared_diff = make_leveled_view( squared_diff_field ); + array::LocalView values = make_leveled_view( field ); + + const size_t npts = values.shape( 0 ); + atlas_omp_parallel_for( size_t n = 0; n < npts; ++n ) { + for ( size_t l = 0; l < values.shape( 1 ); ++l ) { + for ( size_t j = 0; j < values.shape( 2 ); ++j ) { + squared_diff( n, l, j ) = sqr( values( n, l, j ) - mu[j] ); + } + } } - } - mean(fs,squared_diff_field,sigma,N); - sigma = std::sqrt(sigma); -} - -template< typename T > -void mean_and_standard_deviation( const NodeColumns& fs, const Field& field, std::vector& mu, std::vector& sigma, size_t& N ) -{ - mean(fs,field,mu,N); - Field squared_diff_field = fs.createField(option::name("sqr_diff")|option::levels(field.levels())|option::variables(field.variables())); - array::LocalView squared_diff = make_leveled_view( squared_diff_field ); - array::LocalView values = make_leveled_view( field ); - - const size_t npts = values.shape(0); - atlas_omp_parallel_for( size_t n=0; n -void dispatch_mean_and_standard_deviation_per_level( const NodeColumns& fs, const Field& field, Field& mean, Field& stddev, size_t& N ) -{ - dispatch_mean_per_level(fs,field,mean,N); - Field squared_diff_field = fs.createField(option::name("sqr_diff")|option::levels(field.levels())|option::variables(field.variables())); - auto squared_diff = make_leveled_view( squared_diff_field ); - auto values = make_leveled_view( field ); - auto mu = make_per_level_view( mean ); - - const size_t npts = values.shape(0); - atlas_omp_parallel_for( size_t n=0; n +void dispatch_mean_and_standard_deviation_per_level( const NodeColumns& fs, const Field& field, Field& mean, + Field& stddev, size_t& N ) { + dispatch_mean_per_level( fs, field, mean, N ); + Field squared_diff_field = fs.createField( option::name( "sqr_diff" ) | option::levels( field.levels() ) | + option::variables( field.variables() ) ); + auto squared_diff = make_leveled_view( squared_diff_field ); + auto values = make_leveled_view( field ); + auto mu = make_per_level_view( mean ); + + const size_t npts = values.shape( 0 ); + atlas_omp_parallel_for( size_t n = 0; n < npts; ++n ) { + for ( size_t l = 0; l < values.shape( 1 ); ++l ) { + for ( size_t j = 0; j < values.shape( 2 ); ++j ) { + squared_diff( n, l, j ) = sqr( values( n, l, j ) - mu( l, j ) ); + } + } } - } - dispatch_mean_per_level(fs,squared_diff_field,stddev,N); - auto sigma = make_per_level_view( stddev ); - atlas_omp_for( size_t l=0; l( fs, squared_diff_field, stddev, N ); + auto sigma = make_per_level_view( stddev ); + atlas_omp_for( size_t l = 0; l < sigma.shape( 0 ); ++l ) { + for ( size_t j = 0; j < sigma.shape( 1 ); ++j ) { + sigma( l, j ) = std::sqrt( sigma( l, j ) ); + } } - } } - -void mean_and_standard_deviation_per_level( const NodeColumns& fs, const Field& field, Field& mean, Field& stddev, size_t& N ) -{ - if( field.datatype() != mean.datatype() ) { - throw eckit::Exception("Field and mean are not of same datatype.",Here()); - } - if( field.datatype() != stddev.datatype() ) { - throw eckit::Exception("Field and stddev are not of same datatype.",Here()); - } - switch( field.datatype().kind() ) - { - case array::DataType::KIND_INT32 : - return dispatch_mean_and_standard_deviation_per_level(fs,field,mean,stddev,N); - case array::DataType::KIND_INT64 : - return dispatch_mean_and_standard_deviation_per_level(fs,field,mean,stddev,N); - case array::DataType::KIND_REAL32 : - return dispatch_mean_and_standard_deviation_per_level(fs,field,mean,stddev,N); - case array::DataType::KIND_REAL64 : - return dispatch_mean_and_standard_deviation_per_level(fs,field,mean,stddev,N); - default: throw eckit::Exception("datatype not supported",Here()); - } +void mean_and_standard_deviation_per_level( const NodeColumns& fs, const Field& field, Field& mean, Field& stddev, + size_t& N ) { + if ( field.datatype() != mean.datatype() ) { + throw eckit::Exception( "Field and mean are not of same datatype.", Here() ); + } + if ( field.datatype() != stddev.datatype() ) { + throw eckit::Exception( "Field and stddev are not of same datatype.", Here() ); + } + switch ( field.datatype().kind() ) { + case array::DataType::KIND_INT32: + return dispatch_mean_and_standard_deviation_per_level( fs, field, mean, stddev, N ); + case array::DataType::KIND_INT64: + return dispatch_mean_and_standard_deviation_per_level( fs, field, mean, stddev, N ); + case array::DataType::KIND_REAL32: + return dispatch_mean_and_standard_deviation_per_level( fs, field, mean, stddev, N ); + case array::DataType::KIND_REAL64: + return dispatch_mean_and_standard_deviation_per_level( fs, field, mean, stddev, N ); + default: + throw eckit::Exception( "datatype not supported", Here() ); + } } +} // namespace detail -} // end collectives implementation - - - - -template< typename Value > -NodeColumns::FieldStatisticsT::FieldStatisticsT(const NodeColumns* f) : - functionspace(*f) { -} +template +NodeColumns::FieldStatisticsT::FieldStatisticsT( const NodeColumns* f ) : functionspace( *f ) {} -template< typename Vector > -NodeColumns::FieldStatisticsVectorT::FieldStatisticsVectorT(const NodeColumns* f) : - functionspace(*f) { -} +template +NodeColumns::FieldStatisticsVectorT::FieldStatisticsVectorT( const NodeColumns* f ) : functionspace( *f ) {} -NodeColumns::FieldStatistics::FieldStatistics(const NodeColumns* f) : - functionspace(*f) { -} +NodeColumns::FieldStatistics::FieldStatistics( const NodeColumns* f ) : functionspace( *f ) {} -template< typename Value > +template void NodeColumns::FieldStatisticsT::sum( const Field& field, Value& result, size_t& N ) const { - detail::sum(functionspace,field,result,N); + detail::sum( functionspace, field, result, N ); } -template< typename Vector > +template void NodeColumns::FieldStatisticsVectorT::sum( const Field& field, Vector& result, size_t& N ) const { - detail::sum(functionspace,field,result,N); + detail::sum( functionspace, field, result, N ); } void NodeColumns::FieldStatistics::sumPerLevel( const Field& field, Field& result, size_t& N ) const { - detail::sum_per_level(functionspace,field,result,N); + detail::sum_per_level( functionspace, field, result, N ); } -template< typename Value > +template void NodeColumns::FieldStatisticsT::orderIndependentSum( const Field& field, Value& result, size_t& N ) const { - detail::order_independent_sum(functionspace,field,result,N); + detail::order_independent_sum( functionspace, field, result, N ); } -template< typename Vector > -void NodeColumns::FieldStatisticsVectorT::orderIndependentSum( const Field& field, Vector& result, size_t& N ) const { - detail::order_independent_sum(functionspace,field,result,N); +template +void NodeColumns::FieldStatisticsVectorT::orderIndependentSum( const Field& field, Vector& result, + size_t& N ) const { + detail::order_independent_sum( functionspace, field, result, N ); } void NodeColumns::FieldStatistics::orderIndependentSumPerLevel( const Field& field, Field& result, size_t& N ) const { - detail::order_independent_sum_per_level(functionspace,field,result,N); + detail::order_independent_sum_per_level( functionspace, field, result, N ); } -template< typename Value > +template void NodeColumns::FieldStatisticsT::minimum( const Field& field, Value& minimum ) const { - detail::minimum(functionspace,field,minimum); + detail::minimum( functionspace, field, minimum ); } -template< typename Value > +template void NodeColumns::FieldStatisticsT::maximum( const Field& field, Value& maximum ) const { - detail::maximum(functionspace,field,maximum); - + detail::maximum( functionspace, field, maximum ); } -template< typename Vector > +template void NodeColumns::FieldStatisticsVectorT::minimum( const Field& field, Vector& minimum ) const { - detail::minimum(functionspace,field,minimum); + detail::minimum( functionspace, field, minimum ); } -template< typename Vector > -void NodeColumns::FieldStatisticsVectorT::maximum( const Field& field, Vector& maximum) const { - detail::maximum(functionspace,field,maximum); +template +void NodeColumns::FieldStatisticsVectorT::maximum( const Field& field, Vector& maximum ) const { + detail::maximum( functionspace, field, maximum ); } void NodeColumns::FieldStatistics::minimumPerLevel( const Field& field, Field& minimum ) const { - detail::minimum_per_level(functionspace,field,minimum); + detail::minimum_per_level( functionspace, field, minimum ); } void NodeColumns::FieldStatistics::maximumPerLevel( const Field& field, Field& maximum ) const { - detail::maximum_per_level(functionspace,field,maximum); + detail::maximum_per_level( functionspace, field, maximum ); } -template< typename Value > -void NodeColumns::FieldStatisticsT::minimumAndLocation( const Field& field, Value& minimum, gidx_t& glb_idx ) const { - detail::minimum_and_location(functionspace,field,minimum,glb_idx); - +template +void NodeColumns::FieldStatisticsT::minimumAndLocation( const Field& field, Value& minimum, + gidx_t& glb_idx ) const { + detail::minimum_and_location( functionspace, field, minimum, glb_idx ); } -template< typename Value > -void NodeColumns::FieldStatisticsT::maximumAndLocation( const Field& field, Value& maximum, gidx_t& glb_idx ) const { - detail::maximum_and_location(functionspace,field,maximum,glb_idx); +template +void NodeColumns::FieldStatisticsT::maximumAndLocation( const Field& field, Value& maximum, + gidx_t& glb_idx ) const { + detail::maximum_and_location( functionspace, field, maximum, glb_idx ); } -template< typename Value > -void NodeColumns::FieldStatisticsT::minimumAndLocation( const Field& field, Value& minimum, gidx_t& glb_idx, size_t& level ) const { - detail::minimum_and_location(functionspace,field,minimum,glb_idx,level); +template +void NodeColumns::FieldStatisticsT::minimumAndLocation( const Field& field, Value& minimum, gidx_t& glb_idx, + size_t& level ) const { + detail::minimum_and_location( functionspace, field, minimum, glb_idx, level ); } -template< typename Value > -void NodeColumns::FieldStatisticsT::maximumAndLocation( const Field& field, Value& maximum, gidx_t& glb_idx, size_t& level ) const { - detail::maximum_and_location(functionspace,field,maximum,glb_idx,level); +template +void NodeColumns::FieldStatisticsT::maximumAndLocation( const Field& field, Value& maximum, gidx_t& glb_idx, + size_t& level ) const { + detail::maximum_and_location( functionspace, field, maximum, glb_idx, level ); } -template< typename Vector > -void NodeColumns::FieldStatisticsVectorT::minimumAndLocation( const Field& field, Vector& minimum, std::vector& glb_idx ) const { - detail::minimum_and_location(functionspace,field,minimum,glb_idx); +template +void NodeColumns::FieldStatisticsVectorT::minimumAndLocation( const Field& field, Vector& minimum, + std::vector& glb_idx ) const { + detail::minimum_and_location( functionspace, field, minimum, glb_idx ); } -template< typename Vector > -void NodeColumns::FieldStatisticsVectorT::maximumAndLocation( const Field& field, Vector& maximum, std::vector& glb_idx ) const { - detail::maximum_and_location(functionspace,field,maximum,glb_idx); +template +void NodeColumns::FieldStatisticsVectorT::maximumAndLocation( const Field& field, Vector& maximum, + std::vector& glb_idx ) const { + detail::maximum_and_location( functionspace, field, maximum, glb_idx ); } -template< typename Vector > -void NodeColumns::FieldStatisticsVectorT::minimumAndLocation( const Field& field, Vector& minimum, std::vector& glb_idx, std::vector& level ) const { - detail::minimum_and_location(functionspace,field,minimum,glb_idx,level); +template +void NodeColumns::FieldStatisticsVectorT::minimumAndLocation( const Field& field, Vector& minimum, + std::vector& glb_idx, + std::vector& level ) const { + detail::minimum_and_location( functionspace, field, minimum, glb_idx, level ); } -template< typename Vector > -void NodeColumns::FieldStatisticsVectorT::maximumAndLocation( const Field& field, Vector& maximum, std::vector& glb_idx, std::vector& level ) const { - detail::maximum_and_location(functionspace,field,maximum,glb_idx,level); +template +void NodeColumns::FieldStatisticsVectorT::maximumAndLocation( const Field& field, Vector& maximum, + std::vector& glb_idx, + std::vector& level ) const { + detail::maximum_and_location( functionspace, field, maximum, glb_idx, level ); } -void NodeColumns::FieldStatistics::minimumAndLocationPerLevel( const Field& field, Field& column, Field& glb_idx ) const { - detail::minimum_and_location_per_level(functionspace,field,column,glb_idx); +void NodeColumns::FieldStatistics::minimumAndLocationPerLevel( const Field& field, Field& column, + Field& glb_idx ) const { + detail::minimum_and_location_per_level( functionspace, field, column, glb_idx ); } -void NodeColumns::FieldStatistics::maximumAndLocationPerLevel( const Field& field, Field& column, Field& glb_idx ) const { - detail::maximum_and_location_per_level(functionspace,field,column,glb_idx); +void NodeColumns::FieldStatistics::maximumAndLocationPerLevel( const Field& field, Field& column, + Field& glb_idx ) const { + detail::maximum_and_location_per_level( functionspace, field, column, glb_idx ); } -template< typename Value > +template void NodeColumns::FieldStatisticsT::mean( const Field& field, Value& mean, size_t& N ) const { - detail::mean(functionspace,field,mean,N); + detail::mean( functionspace, field, mean, N ); } -template< typename Vector > +template void NodeColumns::FieldStatisticsVectorT::mean( const Field& field, Vector& mean, size_t& N ) const { - detail::mean(functionspace,field,mean,N); + detail::mean( functionspace, field, mean, N ); } -void NodeColumns::FieldStatistics::meanPerLevel(const Field &field, Field &mean, size_t &N) const { - detail::mean_per_level(functionspace,field,mean,N); +void NodeColumns::FieldStatistics::meanPerLevel( const Field& field, Field& mean, size_t& N ) const { + detail::mean_per_level( functionspace, field, mean, N ); } -template< typename Value > -void NodeColumns::FieldStatisticsT::meanAndStandardDeviation( const Field& field, Value& mean, Value& stddev, size_t& N ) const { - detail::mean_and_standard_deviation(functionspace,field,mean,stddev,N); +template +void NodeColumns::FieldStatisticsT::meanAndStandardDeviation( const Field& field, Value& mean, Value& stddev, + size_t& N ) const { + detail::mean_and_standard_deviation( functionspace, field, mean, stddev, N ); } -template< typename Vector > -void NodeColumns::FieldStatisticsVectorT::meanAndStandardDeviation( const Field& field, Vector& mean, Vector& stddev, size_t& N ) const { - detail::mean_and_standard_deviation(functionspace,field,mean,stddev,N); +template +void NodeColumns::FieldStatisticsVectorT::meanAndStandardDeviation( const Field& field, Vector& mean, + Vector& stddev, size_t& N ) const { + detail::mean_and_standard_deviation( functionspace, field, mean, stddev, N ); } -void NodeColumns::FieldStatistics::meanAndStandardDeviationPerLevel( const Field& field, Field& mean, Field& stddev, size_t& N ) const { - detail::mean_and_standard_deviation_per_level(functionspace,field,mean,stddev,N); +void NodeColumns::FieldStatistics::meanAndStandardDeviationPerLevel( const Field& field, Field& mean, Field& stddev, + size_t& N ) const { + detail::mean_and_standard_deviation_per_level( functionspace, field, mean, stddev, N ); } template class NodeColumns::FieldStatisticsT; template class NodeColumns::FieldStatisticsT; template class NodeColumns::FieldStatisticsT; template class NodeColumns::FieldStatisticsT; -//template class NodeColumns::FieldStatisticsT; -template class NodeColumns::FieldStatisticsVectorT< std::vector >; -template class NodeColumns::FieldStatisticsVectorT< std::vector >; -template class NodeColumns::FieldStatisticsVectorT< std::vector >; -template class NodeColumns::FieldStatisticsVectorT< std::vector >; -//template class NodeColumns::FieldStatisticsVectorT< std::vector >; +// template class NodeColumns::FieldStatisticsT; +template class NodeColumns::FieldStatisticsVectorT>; +template class NodeColumns::FieldStatisticsVectorT>; +template class NodeColumns::FieldStatisticsVectorT>; +template class NodeColumns::FieldStatisticsVectorT>; +// template class NodeColumns::FieldStatisticsVectorT< std::vector >; -} // namespace detail +} // namespace detail - -NodeColumns::NodeColumns() : - FunctionSpace(), - functionspace_(nullptr) { -} +NodeColumns::NodeColumns() : FunctionSpace(), functionspace_( nullptr ) {} NodeColumns::NodeColumns( const FunctionSpace& functionspace ) : - FunctionSpace( functionspace ), - functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { -} - + FunctionSpace( functionspace ), + functionspace_( dynamic_cast( get() ) ) {} namespace { detail::NodeColumns* make_functionspace( Mesh mesh, const eckit::Configuration& config ) { - return new detail::NodeColumns(mesh, config); -} + return new detail::NodeColumns( mesh, config ); } +} // namespace NodeColumns::NodeColumns( Mesh mesh ) : - FunctionSpace( make_functionspace(mesh,util::NoConfig()) ), - functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { -} + FunctionSpace( make_functionspace( mesh, util::NoConfig() ) ), + functionspace_( dynamic_cast( get() ) ) {} NodeColumns::NodeColumns( Mesh mesh, const eckit::Configuration& config ) : - FunctionSpace( make_functionspace(mesh, config) ), - functionspace_( dynamic_cast< const detail::NodeColumns* >( get() ) ) { -} + FunctionSpace( make_functionspace( mesh, config ) ), + functionspace_( dynamic_cast( get() ) ) {} size_t NodeColumns::nb_nodes() const { - return functionspace_->nb_nodes(); + return functionspace_->nb_nodes(); } -size_t NodeColumns::nb_nodes_global() const { // All MPI ranks will have same output - return functionspace_->nb_nodes_global(); +size_t NodeColumns::nb_nodes_global() const { // All MPI ranks will have same output + return functionspace_->nb_nodes_global(); } const Mesh& NodeColumns::mesh() const { - return functionspace_->mesh(); + return functionspace_->mesh(); } -mesh::Nodes& NodeColumns::nodes() const{ - return functionspace_->nodes(); +mesh::Nodes& NodeColumns::nodes() const { + return functionspace_->nodes(); } // -- Parallelisation aware methods const mesh::Halo& NodeColumns::halo() const { - return functionspace_->halo(); + return functionspace_->halo(); } void NodeColumns::haloExchange( FieldSet& fieldset, bool on_device ) const { - functionspace_->haloExchange(fieldset, on_device); + functionspace_->haloExchange( fieldset, on_device ); } void NodeColumns::haloExchange( Field& field, bool on_device ) const { - functionspace_->haloExchange(field, on_device); + functionspace_->haloExchange( field, on_device ); } const parallel::HaloExchange& NodeColumns::halo_exchange() const { - return functionspace_->halo_exchange(); + return functionspace_->halo_exchange(); } void NodeColumns::gather( const FieldSet& local, FieldSet& global ) const { - functionspace_->gather(local,global); + functionspace_->gather( local, global ); } void NodeColumns::gather( const Field& local, Field& global ) const { - functionspace_->gather(local,global); + functionspace_->gather( local, global ); } const parallel::GatherScatter& NodeColumns::gather() const { - return functionspace_->gather(); + return functionspace_->gather(); } void NodeColumns::scatter( const FieldSet& global, FieldSet& local ) const { - functionspace_->scatter(global,local); + functionspace_->scatter( global, local ); } void NodeColumns::scatter( const Field& global, Field& local ) const { - functionspace_->scatter(global,local); + functionspace_->scatter( global, local ); } const parallel::GatherScatter& NodeColumns::scatter() const { - return functionspace_->scatter(); + return functionspace_->scatter(); } std::string NodeColumns::checksum( const FieldSet& fieldset ) const { - return functionspace_->checksum(fieldset); + return functionspace_->checksum( fieldset ); } std::string NodeColumns::checksum( const Field& field ) const { - return functionspace_->checksum(field); + return functionspace_->checksum( field ); } const parallel::Checksum& NodeColumns::checksum() const { - return functionspace_->checksum(); + return functionspace_->checksum(); } - - -} // namespace functionspace -} // namespace atlas - +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/NodeColumns.h b/src/atlas/functionspace/NodeColumns.h index d9ae00289..806afaecd 100644 --- a/src/atlas/functionspace/NodeColumns.h +++ b/src/atlas/functionspace/NodeColumns.h @@ -4,40 +4,41 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "eckit/memory/SharedPtr.h" +#include "atlas/field/FieldSet.h" +#include "atlas/functionspace/FunctionSpace.h" #include "atlas/library/config.h" #include "atlas/mesh/Halo.h" #include "atlas/mesh/Mesh.h" -#include "atlas/field/FieldSet.h" #include "atlas/option.h" -#include "atlas/functionspace/FunctionSpace.h" +#include "eckit/memory/SharedPtr.h" // ---------------------------------------------------------------------------- // Forward declarations namespace atlas { namespace mesh { - class Nodes; -} +class Nodes; } +} // namespace atlas namespace atlas { - class FieldSet; +class FieldSet; } namespace atlas { namespace parallel { - class HaloExchange; - class GatherScatter; - class Checksum; -} -} +class HaloExchange; +class GatherScatter; +class Checksum; +} // namespace parallel +} // namespace atlas namespace atlas { namespace functionspace { @@ -45,11 +46,9 @@ namespace detail { // ---------------------------------------------------------------------------- -class NodeColumns : public FunctionSpaceImpl -{ +class NodeColumns : public FunctionSpaceImpl { public: - - NodeColumns( Mesh mesh, const eckit::Configuration & ); + NodeColumns( Mesh mesh, const eckit::Configuration& ); NodeColumns( Mesh mesh ); virtual ~NodeColumns(); @@ -60,7 +59,7 @@ class NodeColumns : public FunctionSpaceImpl virtual std::string distribution() const; size_t nb_nodes() const; - size_t nb_nodes_global() const; // All MPI ranks will have same output + size_t nb_nodes_global() const; // All MPI ranks will have same output const Mesh& mesh() const { return mesh_; } @@ -68,16 +67,16 @@ class NodeColumns : public FunctionSpaceImpl mesh::Nodes& nodes() const { return nodes_; } -// -- Field creation methods + // -- Field creation methods using FunctionSpaceImpl::createField; /// @brief Create a field - virtual Field createField(const eckit::Configuration&) const; + virtual Field createField( const eckit::Configuration& ) const; - virtual Field createField(const Field&, const eckit::Configuration& ) const; + virtual Field createField( const Field&, const eckit::Configuration& ) const; -// -- Parallelisation aware methods + // -- Parallelisation aware methods const mesh::Halo& halo() const { return halo_; } @@ -97,18 +96,20 @@ class NodeColumns : public FunctionSpaceImpl std::string checksum( const Field& ) const; const parallel::Checksum& checksum() const; - /// @brief Compute sum of scalar field /// @param [out] sum Scalar value containing the sum of the full 3D field - /// @param [out] N Number of values that are contained in the sum (nodes*levels) - template< typename Value > + /// @param [out] N Number of values that are contained in the sum + /// (nodes*levels) + template void sum( const Field&, Value& sum, size_t& N ) const; -// /// @brief Compute sum of field for each variable -// /// @param [out] sum For each field-variable, the sum of the full 3D field -// /// @param [out] N Number of values that are contained in the sum (nodes*levels) -// template< typename Value > -// void sum( const Field&, std::vector& sum, size_t& N ) const; + // /// @brief Compute sum of field for each variable + // /// @param [out] sum For each field-variable, the sum of the full 3D + // field + // /// @param [out] N Number of values that are contained in the sum + // (nodes*levels) + // template< typename Value > + // void sum( const Field&, std::vector& sum, size_t& N ) const; /// @brief Compute sum of field for each vertical level separately /// @param [out] sum Field of dimension of input without the nodes index @@ -117,36 +118,41 @@ class NodeColumns : public FunctionSpaceImpl /// @brief Compute order independent sum of scalar field /// @param [out] sum Scalar value containing the sum of the full 3D field - /// @param [out] N Number of values that are contained in the sum (nodes*levels) - template< typename Value > + /// @param [out] N Number of values that are contained in the sum + /// (nodes*levels) + template void orderIndependentSum( const Field&, Value& sum, size_t& N ) const; -// /// @brief Compute order independent sum of field for each variable -// /// @param [out] sum For each field-variable, the sum of the full 3D field -// /// @param [out] N Number of values that are contained in the sum (nodes*levels) -// template< typename Value > -// void orderIndependentSum( const Field&, std::vector&, size_t& N ) const; - - /// @brief Compute order independent sum of field for each vertical level separately + // /// @brief Compute order independent sum of field for each variable + // /// @param [out] sum For each field-variable, the sum of the full 3D + // field + // /// @param [out] N Number of values that are contained in the sum + // (nodes*levels) + // template< typename Value > + // void orderIndependentSum( const Field&, std::vector&, size_t& N ) + // const; + + /// @brief Compute order independent sum of field for each vertical level + /// separately /// @param [out] sum Field of dimension of input without the nodes index /// @param [out] N Number of nodes used to sum each level void orderIndependentSumPerLevel( const Field&, Field& sum, size_t& N ) const; /// @brief Compute minimum of scalar field - template< typename Value > + template void minimum( const Field&, Value& minimum ) const; /// @brief Compute maximum of scalar field - template< typename Value > + template void maximum( const Field&, Value& maximum ) const; -// /// @brief Compute minimum of field for each field-variable -// template< typename Value > -// void minimum( const Field&, std::vector& ) const; + // /// @brief Compute minimum of field for each field-variable + // template< typename Value > + // void minimum( const Field&, std::vector& ) const; -// /// @brief Compute maximum of field for each field-variable -// template< typename Value > -// void maximum( const Field&, std::vector& ) const; + // /// @brief Compute maximum of field for each field-variable + // template< typename Value > + // void maximum( const Field&, std::vector& ) const; /// @brief Compute minimum of field for each vertical level separately /// @param [out] min Field of dimension of input without the nodes index @@ -156,55 +162,67 @@ class NodeColumns : public FunctionSpaceImpl /// @param [out] max Field of dimension of input without the nodes index void maximumPerLevel( const Field&, Field& max ) const; - /// @brief Compute minimum of scalar field, as well as the global index and level. - template< typename Value > + /// @brief Compute minimum of scalar field, as well as the global index and + /// level. + template void minimumAndLocation( const Field&, Value& minimum, gidx_t& glb_idx ) const; - /// @brief Compute maximum of scalar field, as well as the global index and level. - template< typename Value > + /// @brief Compute maximum of scalar field, as well as the global index and + /// level. + template void maximumAndLocation( const Field&, Value& maximum, gidx_t& glb_idx ) const; - /// @brief Compute minimum of scalar field, as well as the global index and level. - template< typename Value > + /// @brief Compute minimum of scalar field, as well as the global index and + /// level. + template void minimumAndLocation( const Field&, Value& minimum, gidx_t& glb_idx, size_t& level ) const; - /// @brief Compute maximum of scalar field, as well as the global index and level. - template< typename Value > + /// @brief Compute maximum of scalar field, as well as the global index and + /// level. + template void maximumAndLocation( const Field&, Value& maximum, gidx_t& glb_idx, size_t& level ) const; - /// @brief Compute minimum of field for each field-variable, as well as the global indices and levels. - template< typename Vector > + /// @brief Compute minimum of field for each field-variable, as well as the + /// global indices and levels. + template void minimumAndLocation( const Field&, Vector& minimum, std::vector& glb_idx ) const; - /// @brief Compute maximum of field for each field-variable, as well as the global indices and levels. - template< typename Vector > + /// @brief Compute maximum of field for each field-variable, as well as the + /// global indices and levels. + template void maximumAndLocation( const Field&, Vector& maximum, std::vector& glb_idx ) const; - /// @brief Compute minimum of field for each field-variable, as well as the global indices and levels. - template< typename Vector > - void minimumAndLocation( const Field&, Vector& minimum, std::vector& glb_idx, std::vector& level ) const; + /// @brief Compute minimum of field for each field-variable, as well as the + /// global indices and levels. + template + void minimumAndLocation( const Field&, Vector& minimum, std::vector& glb_idx, + std::vector& level ) const; - /// @brief Compute maximum of field for each field-variable, as well as the global indices and levels. - template< typename Vector > - void maximumAndLocation( const Field&, Vector& maximum, std::vector& glb_idx, std::vector& level ) const; + /// @brief Compute maximum of field for each field-variable, as well as the + /// global indices and levels. + template + void maximumAndLocation( const Field&, Vector& maximum, std::vector& glb_idx, + std::vector& level ) const; - /// @brief Compute minimum and its location of a field for each vertical level separately + /// @brief Compute minimum and its location of a field for each vertical level + /// separately void minimumAndLocationPerLevel( const Field&, Field& column, Field& glb_idx ) const; - /// @brief Compute maximum and its location of a field for each vertical level separately + /// @brief Compute maximum and its location of a field for each vertical level + /// separately void maximumAndLocationPerLevel( const Field&, Field& column, Field& glb_idx ) const; /// @brief Compute mean value of scalar field /// @param [out] mean Mean value /// @param [out] N Number of value used to create the mean - template< typename Value > + template void mean( const Field&, Value& mean, size_t& N ) const; -// /// @brief Compute mean value of field for each field-variable -// /// @param [out] mean Mean values for each variable -// /// @param [out] N Number of values used to create the means -// template< typename Value > -// void mean( const Field&, std::vector& mean, size_t& N ) const; + // /// @brief Compute mean value of field for each field-variable + // /// @param [out] mean Mean values for each variable + // /// @param [out] N Number of values used to create the means + // template< typename Value > + // void mean( const Field&, std::vector& mean, size_t& N ) const; /// @brief Compute mean values of field for vertical level separately /// @param [out] mean Field of dimension of input without the nodes index @@ -215,222 +233,222 @@ class NodeColumns : public FunctionSpaceImpl /// @param [out] mean Mean value /// @param [out] stddev Standard deviation /// @param [out] N Number of value used to create the mean - template< typename Value > + template void meanAndStandardDeviation( const Field&, Value& mean, Value& stddev, size_t& N ) const; -// /// @brief Compute mean values and standard deviations of scalar field for each field-variable -// /// @param [out] mean Mean values for each field-variable -// /// @param [out] stddev Standard deviation for each field-variable -// /// @param [out] N Number of value used to create the means -// template< typename Value > -// void meanAndStandardDeviation( const Field&, std::vector& mean, std::vector& stddev, size_t& N ) const; - - /// @brief Compute mean values and standard deviations of field for vertical level separately + // /// @brief Compute mean values and standard deviations of scalar field + // for each field-variable + // /// @param [out] mean Mean values for each field-variable + // /// @param [out] stddev Standard deviation for each field-variable + // /// @param [out] N Number of value used to create the means + // template< typename Value > + // void meanAndStandardDeviation( const Field&, std::vector& mean, + // std::vector& stddev, size_t& N ) const; + + /// @brief Compute mean values and standard deviations of field for vertical + /// level separately /// @param [out] mean Field of dimension of input without the nodes index /// @param [out] stddev Field of dimension of input without the nodes index /// @param [out] N Number of values used to create the means void meanAndStandardDeviationPerLevel( const Field&, Field& mean, Field& stddev, size_t& N ) const; -private: // methods - +private: // methods void constructor(); - size_t config_nb_nodes(const eckit::Configuration&) const; - array::DataType config_datatype(const eckit::Configuration&) const; - std::string config_name(const eckit::Configuration&) const; - size_t config_levels(const eckit::Configuration&) const; - array::ArrayShape config_shape(const eckit::Configuration&) const; - void set_field_metadata(const eckit::Configuration&, Field& ) const; + size_t config_nb_nodes( const eckit::Configuration& ) const; + array::DataType config_datatype( const eckit::Configuration& ) const; + std::string config_name( const eckit::Configuration& ) const; + size_t config_levels( const eckit::Configuration& ) const; + array::ArrayShape config_shape( const eckit::Configuration& ) const; + void set_field_metadata( const eckit::Configuration&, Field& ) const; size_t footprint() const; -private: // data - - Mesh mesh_; // non-const because functionspace may modify mesh - mesh::Nodes& nodes_; // non-const because functionspace may modify mesh +private: // data + Mesh mesh_; // non-const because functionspace may modify mesh + mesh::Nodes& nodes_; // non-const because functionspace may modify mesh mesh::Halo halo_; size_t nb_nodes_; mutable long nb_nodes_global_{-1}; size_t nb_levels_; - mutable eckit::SharedPtr gather_scatter_; // without ghost - mutable eckit::SharedPtr halo_exchange_; - mutable eckit::SharedPtr checksum_; + mutable eckit::SharedPtr gather_scatter_; // without ghost + mutable eckit::SharedPtr halo_exchange_; + mutable eckit::SharedPtr checksum_; private: - - template< typename Value > + template struct FieldStatisticsT { - FieldStatisticsT(const NodeColumns*); - void sum( const Field&, Value& sum, size_t& N ) const; - void orderIndependentSum( const Field&, Value& sum, size_t& N ) const; - void minimum( const Field&, Value& minimum ) const; - void maximum( const Field&, Value& maximum ) const; - void minimumAndLocation( const Field&, Value& minimum, gidx_t& glb_idx ) const; - void maximumAndLocation( const Field&, Value& maximum, gidx_t& glb_idx ) const; - void minimumAndLocation( const Field&, Value& minimum, gidx_t& glb_idx, size_t& level ) const; - void maximumAndLocation( const Field&, Value& maximum, gidx_t& glb_idx, size_t& level ) const; - void mean( const Field&, Value& mean, size_t& N ) const; - void meanAndStandardDeviation( const Field&, Value& mean, Value& stddev, size_t& N ) const; - const NodeColumns& functionspace; + FieldStatisticsT( const NodeColumns* ); + void sum( const Field&, Value& sum, size_t& N ) const; + void orderIndependentSum( const Field&, Value& sum, size_t& N ) const; + void minimum( const Field&, Value& minimum ) const; + void maximum( const Field&, Value& maximum ) const; + void minimumAndLocation( const Field&, Value& minimum, gidx_t& glb_idx ) const; + void maximumAndLocation( const Field&, Value& maximum, gidx_t& glb_idx ) const; + void minimumAndLocation( const Field&, Value& minimum, gidx_t& glb_idx, size_t& level ) const; + void maximumAndLocation( const Field&, Value& maximum, gidx_t& glb_idx, size_t& level ) const; + void mean( const Field&, Value& mean, size_t& N ) const; + void meanAndStandardDeviation( const Field&, Value& mean, Value& stddev, size_t& N ) const; + const NodeColumns& functionspace; }; - template< typename Vector > + template struct FieldStatisticsVectorT { - FieldStatisticsVectorT(const NodeColumns*); - void sum( const Field&, Vector& sum, size_t& N ) const; - void orderIndependentSum( const Field&, Vector&, size_t& N ) const; - void minimum( const Field&, Vector& ) const; - void maximum( const Field&, Vector& ) const; - void minimumAndLocation( const Field&, Vector& minimum, std::vector& glb_idx ) const; - void maximumAndLocation( const Field&, Vector& maximum, std::vector& glb_idx ) const; - void minimumAndLocation( const Field&, Vector& minimum, std::vector& glb_idx, std::vector& level ) const; - void maximumAndLocation( const Field&, Vector& maximum, std::vector& glb_idx, std::vector& level ) const; - void mean( const Field&, Vector& mean, size_t& N ) const; - void meanAndStandardDeviation( const Field&, Vector& mean, Vector& stddev, size_t& N ) const; - const NodeColumns& functionspace; + FieldStatisticsVectorT( const NodeColumns* ); + void sum( const Field&, Vector& sum, size_t& N ) const; + void orderIndependentSum( const Field&, Vector&, size_t& N ) const; + void minimum( const Field&, Vector& ) const; + void maximum( const Field&, Vector& ) const; + void minimumAndLocation( const Field&, Vector& minimum, std::vector& glb_idx ) const; + void maximumAndLocation( const Field&, Vector& maximum, std::vector& glb_idx ) const; + void minimumAndLocation( const Field&, Vector& minimum, std::vector& glb_idx, + std::vector& level ) const; + void maximumAndLocation( const Field&, Vector& maximum, std::vector& glb_idx, + std::vector& level ) const; + void mean( const Field&, Vector& mean, size_t& N ) const; + void meanAndStandardDeviation( const Field&, Vector& mean, Vector& stddev, size_t& N ) const; + const NodeColumns& functionspace; }; struct FieldStatistics { - FieldStatistics(const NodeColumns*); - void sumPerLevel( const Field&, Field& sum, size_t& N ) const; - void orderIndependentSumPerLevel( const Field&, Field& sum, size_t& N ) const; - void minimumPerLevel( const Field&, Field& min ) const; - void maximumPerLevel( const Field&, Field& max ) const; - void minimumAndLocationPerLevel( const Field&, Field& column, Field& glb_idx ) const; - void maximumAndLocationPerLevel( const Field&, Field& column, Field& glb_idx ) const; - void meanPerLevel( const Field&, Field& mean, size_t& N ) const; - void meanAndStandardDeviationPerLevel( const Field&, Field& mean, Field& stddev, size_t& N ) const; - const NodeColumns& functionspace; + FieldStatistics( const NodeColumns* ); + void sumPerLevel( const Field&, Field& sum, size_t& N ) const; + void orderIndependentSumPerLevel( const Field&, Field& sum, size_t& N ) const; + void minimumPerLevel( const Field&, Field& min ) const; + void maximumPerLevel( const Field&, Field& max ) const; + void minimumAndLocationPerLevel( const Field&, Field& column, Field& glb_idx ) const; + void maximumAndLocationPerLevel( const Field&, Field& column, Field& glb_idx ) const; + void meanPerLevel( const Field&, Field& mean, size_t& N ) const; + void meanAndStandardDeviationPerLevel( const Field&, Field& mean, Field& stddev, size_t& N ) const; + const NodeColumns& functionspace; }; - template< typename T > + template struct FieldStatisticsSelector { - using type = typename std::conditional< std::is_pod::value, - FieldStatisticsT, - FieldStatisticsVectorT - >::type; + using type = + typename std::conditional::value, FieldStatisticsT, FieldStatisticsVectorT>::type; }; }; // ------------------------------------------------------------------- -template< typename Value > +template void NodeColumns::sum( const Field& field, Value& sum, size_t& N ) const { - typename FieldStatisticsSelector::type(this).sum(field,sum,N); + typename FieldStatisticsSelector::type( this ).sum( field, sum, N ); } inline void NodeColumns::sumPerLevel( const Field& field, Field& sum, size_t& N ) const { - FieldStatistics(this).sumPerLevel(field,sum,N); + FieldStatistics( this ).sumPerLevel( field, sum, N ); } -template< typename Value > +template void NodeColumns::orderIndependentSum( const Field& field, Value& sum, size_t& N ) const { - typename FieldStatisticsSelector::type(this).orderIndependentSum(field,sum,N); + typename FieldStatisticsSelector::type( this ).orderIndependentSum( field, sum, N ); } inline void NodeColumns::orderIndependentSumPerLevel( const Field& field, Field& sum, size_t& N ) const { - FieldStatistics(this).orderIndependentSumPerLevel(field,sum,N); + FieldStatistics( this ).orderIndependentSumPerLevel( field, sum, N ); } -template< typename Value > +template void NodeColumns::minimum( const Field& field, Value& minimum ) const { - typename FieldStatisticsSelector::type(this).minimum(field,minimum); + typename FieldStatisticsSelector::type( this ).minimum( field, minimum ); } -template< typename Value > +template void NodeColumns::maximum( const Field& field, Value& maximum ) const { - typename FieldStatisticsSelector::type(this).maximum(field,maximum); + typename FieldStatisticsSelector::type( this ).maximum( field, maximum ); } inline void NodeColumns::minimumPerLevel( const Field& field, Field& minimum ) const { - return FieldStatistics(this).minimumPerLevel(field,minimum); + return FieldStatistics( this ).minimumPerLevel( field, minimum ); } inline void NodeColumns::maximumPerLevel( const Field& field, Field& maximum ) const { - FieldStatistics(this).maximumPerLevel(field,maximum); + FieldStatistics( this ).maximumPerLevel( field, maximum ); } -template< typename Value > +template void NodeColumns::minimumAndLocation( const Field& field, Value& minimum, gidx_t& glb_idx ) const { - FieldStatisticsT(this).minimumAndLocation(field,minimum,glb_idx); + FieldStatisticsT( this ).minimumAndLocation( field, minimum, glb_idx ); } -template< typename Value > +template void NodeColumns::maximumAndLocation( const Field& field, Value& maximum, gidx_t& glb_idx ) const { - FieldStatisticsT(this).maximumAndLocation(field,maximum,glb_idx); + FieldStatisticsT( this ).maximumAndLocation( field, maximum, glb_idx ); } -template< typename Value > +template void NodeColumns::minimumAndLocation( const Field& field, Value& minimum, gidx_t& glb_idx, size_t& level ) const { - FieldStatisticsT(this).minimumAndLocation(field,minimum,glb_idx,level); + FieldStatisticsT( this ).minimumAndLocation( field, minimum, glb_idx, level ); } -template< typename Value > +template void NodeColumns::maximumAndLocation( const Field& field, Value& maximum, gidx_t& glb_idx, size_t& level ) const { - FieldStatisticsT(this).maximumAndLocation(field,maximum,glb_idx,level); + FieldStatisticsT( this ).maximumAndLocation( field, maximum, glb_idx, level ); } -template< typename Vector > +template void NodeColumns::minimumAndLocation( const Field& field, Vector& minimum, std::vector& glb_idx ) const { - FieldStatisticsVectorT(this).minimumAndLocation(field,minimum,glb_idx); + FieldStatisticsVectorT( this ).minimumAndLocation( field, minimum, glb_idx ); } -template< typename Vector > +template void NodeColumns::maximumAndLocation( const Field& field, Vector& maximum, std::vector& glb_idx ) const { - FieldStatisticsVectorT(this).maximumAndLocation(field,maximum,glb_idx); + FieldStatisticsVectorT( this ).maximumAndLocation( field, maximum, glb_idx ); } -template< typename Vector > -void NodeColumns::minimumAndLocation( const Field& field, Vector& minimum, std::vector& glb_idx, std::vector& level ) const { - FieldStatisticsVectorT(this).minimumAndLocation(field,minimum,glb_idx,level); +template +void NodeColumns::minimumAndLocation( const Field& field, Vector& minimum, std::vector& glb_idx, + std::vector& level ) const { + FieldStatisticsVectorT( this ).minimumAndLocation( field, minimum, glb_idx, level ); } -template< typename Vector > -void NodeColumns::maximumAndLocation( const Field& field, Vector& maximum, std::vector& glb_idx, std::vector& level ) const { - FieldStatisticsVectorT(this).maximumAndLocation(field,maximum,glb_idx,level); +template +void NodeColumns::maximumAndLocation( const Field& field, Vector& maximum, std::vector& glb_idx, + std::vector& level ) const { + FieldStatisticsVectorT( this ).maximumAndLocation( field, maximum, glb_idx, level ); } inline void NodeColumns::minimumAndLocationPerLevel( const Field& field, Field& column, Field& glb_idx ) const { - FieldStatistics(this).minimumAndLocationPerLevel(field,column,glb_idx); + FieldStatistics( this ).minimumAndLocationPerLevel( field, column, glb_idx ); } inline void NodeColumns::maximumAndLocationPerLevel( const Field& field, Field& column, Field& glb_idx ) const { - FieldStatistics(this).maximumAndLocationPerLevel(field,column,glb_idx); + FieldStatistics( this ).maximumAndLocationPerLevel( field, column, glb_idx ); } -template< typename Value > +template void NodeColumns::mean( const Field& field, Value& mean, size_t& N ) const { - typename FieldStatisticsSelector::type(this).mean(field,mean,N); + typename FieldStatisticsSelector::type( this ).mean( field, mean, N ); } inline void NodeColumns::meanPerLevel( const Field& field, Field& mean, size_t& N ) const { - FieldStatistics(this).meanPerLevel(field,mean,N); + FieldStatistics( this ).meanPerLevel( field, mean, N ); } -template< typename Value > +template void NodeColumns::meanAndStandardDeviation( const Field& field, Value& mean, Value& stddev, size_t& N ) const { - typename FieldStatisticsSelector::type(this).meanAndStandardDeviation(field,mean,stddev,N); + typename FieldStatisticsSelector::type( this ).meanAndStandardDeviation( field, mean, stddev, N ); } -inline void NodeColumns::meanAndStandardDeviationPerLevel( const Field& field, Field& mean, Field& stddev, size_t& N ) const { - FieldStatistics(this).meanAndStandardDeviationPerLevel(field,mean,stddev,N); +inline void NodeColumns::meanAndStandardDeviationPerLevel( const Field& field, Field& mean, Field& stddev, + size_t& N ) const { + FieldStatistics( this ).meanAndStandardDeviationPerLevel( field, mean, stddev, N ); } -} // namespace detail +} // namespace detail // ------------------------------------------------------------------- -class NodeColumns : public FunctionSpace -{ +class NodeColumns : public FunctionSpace { public: - - NodeColumns(); NodeColumns( const FunctionSpace& ); NodeColumns( Mesh mesh ); - NodeColumns( Mesh mesh, const eckit::Configuration & ); + NodeColumns( Mesh mesh, const eckit::Configuration& ); static std::string type() { return detail::NodeColumns::static_type(); } @@ -438,7 +456,7 @@ class NodeColumns : public FunctionSpace bool valid() const { return functionspace_; } size_t nb_nodes() const; - size_t nb_nodes_global() const; // All MPI ranks will have same output + size_t nb_nodes_global() const; // All MPI ranks will have same output const Mesh& mesh() const; @@ -446,7 +464,7 @@ class NodeColumns : public FunctionSpace mesh::Nodes& nodes() const; -// -- Parallelisation aware methods + // -- Parallelisation aware methods const mesh::Halo& halo() const; @@ -466,18 +484,20 @@ class NodeColumns : public FunctionSpace std::string checksum( const Field& ) const; const parallel::Checksum& checksum() const; - /// @brief Compute sum of scalar field /// @param [out] sum Scalar value containing the sum of the full 3D field - /// @param [out] N Number of values that are contained in the sum (nodes*levels) - template< typename Value > + /// @param [out] N Number of values that are contained in the sum + /// (nodes*levels) + template void sum( const Field&, Value& sum, size_t& N ) const; -// /// @brief Compute sum of field for each variable -// /// @param [out] sum For each field-variable, the sum of the full 3D field -// /// @param [out] N Number of values that are contained in the sum (nodes*levels) -// template< typename Value > -// void sum( const Field&, std::vector& sum, size_t& N ) const; + // /// @brief Compute sum of field for each variable + // /// @param [out] sum For each field-variable, the sum of the full 3D + // field + // /// @param [out] N Number of values that are contained in the sum + // (nodes*levels) + // template< typename Value > + // void sum( const Field&, std::vector& sum, size_t& N ) const; /// @brief Compute sum of field for each vertical level separately /// @param [out] sum Field of dimension of input without the nodes index @@ -486,36 +506,41 @@ class NodeColumns : public FunctionSpace /// @brief Compute order independent sum of scalar field /// @param [out] sum Scalar value containing the sum of the full 3D field - /// @param [out] N Number of values that are contained in the sum (nodes*levels) - template< typename Value > + /// @param [out] N Number of values that are contained in the sum + /// (nodes*levels) + template void orderIndependentSum( const Field&, Value& sum, size_t& N ) const; -// /// @brief Compute order independent sum of field for each variable -// /// @param [out] sum For each field-variable, the sum of the full 3D field -// /// @param [out] N Number of values that are contained in the sum (nodes*levels) -// template< typename Value > -// void orderIndependentSum( const Field&, std::vector&, size_t& N ) const; - - /// @brief Compute order independent sum of field for each vertical level separately + // /// @brief Compute order independent sum of field for each variable + // /// @param [out] sum For each field-variable, the sum of the full 3D + // field + // /// @param [out] N Number of values that are contained in the sum + // (nodes*levels) + // template< typename Value > + // void orderIndependentSum( const Field&, std::vector&, size_t& N ) + // const; + + /// @brief Compute order independent sum of field for each vertical level + /// separately /// @param [out] sum Field of dimension of input without the nodes index /// @param [out] N Number of nodes used to sum each level void orderIndependentSumPerLevel( const Field&, Field& sum, size_t& N ) const; /// @brief Compute minimum of scalar field - template< typename Value > + template void minimum( const Field&, Value& minimum ) const; /// @brief Compute maximum of scalar field - template< typename Value > + template void maximum( const Field&, Value& maximum ) const; -// /// @brief Compute minimum of field for each field-variable -// template< typename Value > -// void minimum( const Field&, std::vector& ) const; + // /// @brief Compute minimum of field for each field-variable + // template< typename Value > + // void minimum( const Field&, std::vector& ) const; -// /// @brief Compute maximum of field for each field-variable -// template< typename Value > -// void maximum( const Field&, std::vector& ) const; + // /// @brief Compute maximum of field for each field-variable + // template< typename Value > + // void maximum( const Field&, std::vector& ) const; /// @brief Compute minimum of field for each vertical level separately /// @param [out] min Field of dimension of input without the nodes index @@ -525,55 +550,67 @@ class NodeColumns : public FunctionSpace /// @param [out] max Field of dimension of input without the nodes index void maximumPerLevel( const Field&, Field& max ) const; - /// @brief Compute minimum of scalar field, as well as the global index and level. - template< typename Value > + /// @brief Compute minimum of scalar field, as well as the global index and + /// level. + template void minimumAndLocation( const Field&, Value& minimum, gidx_t& glb_idx ) const; - /// @brief Compute maximum of scalar field, as well as the global index and level. - template< typename Value > + /// @brief Compute maximum of scalar field, as well as the global index and + /// level. + template void maximumAndLocation( const Field&, Value& maximum, gidx_t& glb_idx ) const; - /// @brief Compute minimum of scalar field, as well as the global index and level. - template< typename Value > + /// @brief Compute minimum of scalar field, as well as the global index and + /// level. + template void minimumAndLocation( const Field&, Value& minimum, gidx_t& glb_idx, size_t& level ) const; - /// @brief Compute maximum of scalar field, as well as the global index and level. - template< typename Value > + /// @brief Compute maximum of scalar field, as well as the global index and + /// level. + template void maximumAndLocation( const Field&, Value& maximum, gidx_t& glb_idx, size_t& level ) const; - /// @brief Compute minimum of field for each field-variable, as well as the global indices and levels. - template< typename Value > + /// @brief Compute minimum of field for each field-variable, as well as the + /// global indices and levels. + template void minimumAndLocation( const Field&, std::vector& minimum, std::vector& glb_idx ) const; - /// @brief Compute maximum of field for each field-variable, as well as the global indices and levels. - template< typename Value > + /// @brief Compute maximum of field for each field-variable, as well as the + /// global indices and levels. + template void maximumAndLocation( const Field&, std::vector& maximum, std::vector& glb_idx ) const; - /// @brief Compute minimum of field for each field-variable, as well as the global indices and levels. - template< typename Value > - void minimumAndLocation( const Field&, std::vector& minimum, std::vector& glb_idx, std::vector& level ) const; + /// @brief Compute minimum of field for each field-variable, as well as the + /// global indices and levels. + template + void minimumAndLocation( const Field&, std::vector& minimum, std::vector& glb_idx, + std::vector& level ) const; - /// @brief Compute maximum of field for each field-variable, as well as the global indices and levels. - template< typename Value > - void maximumAndLocation( const Field&, std::vector& maximum, std::vector& glb_idx, std::vector& level ) const; + /// @brief Compute maximum of field for each field-variable, as well as the + /// global indices and levels. + template + void maximumAndLocation( const Field&, std::vector& maximum, std::vector& glb_idx, + std::vector& level ) const; - /// @brief Compute minimum and its location of a field for each vertical level separately + /// @brief Compute minimum and its location of a field for each vertical level + /// separately void minimumAndLocationPerLevel( const Field&, Field& column, Field& glb_idx ) const; - /// @brief Compute maximum and its location of a field for each vertical level separately + /// @brief Compute maximum and its location of a field for each vertical level + /// separately void maximumAndLocationPerLevel( const Field&, Field& column, Field& glb_idx ) const; /// @brief Compute mean value of scalar field /// @param [out] mean Mean value /// @param [out] N Number of value used to create the mean - template< typename Value > + template void mean( const Field&, Value& mean, size_t& N ) const; -// /// @brief Compute mean value of field for each field-variable -// /// @param [out] mean Mean values for each variable -// /// @param [out] N Number of values used to create the means -// template< typename Value > -// void mean( const Field&, std::vector& mean, size_t& N ) const; + // /// @brief Compute mean value of field for each field-variable + // /// @param [out] mean Mean values for each variable + // /// @param [out] N Number of values used to create the means + // template< typename Value > + // void mean( const Field&, std::vector& mean, size_t& N ) const; /// @brief Compute mean values of field for vertical level separately /// @param [out] mean Field of dimension of input without the nodes index @@ -584,24 +621,26 @@ class NodeColumns : public FunctionSpace /// @param [out] mean Mean value /// @param [out] stddev Standard deviation /// @param [out] N Number of value used to create the mean - template< typename Value > + template void meanAndStandardDeviation( const Field&, Value& mean, Value& stddev, size_t& N ) const; -// /// @brief Compute mean values and standard deviations of scalar field for each field-variable -// /// @param [out] mean Mean values for each field-variable -// /// @param [out] stddev Standard deviation for each field-variable -// /// @param [out] N Number of value used to create the means -// template< typename Value > -// void meanAndStandardDeviation( const Field&, std::vector& mean, std::vector& stddev, size_t& N ) const; - - /// @brief Compute mean values and standard deviations of field for vertical level separately + // /// @brief Compute mean values and standard deviations of scalar field + // for each field-variable + // /// @param [out] mean Mean values for each field-variable + // /// @param [out] stddev Standard deviation for each field-variable + // /// @param [out] N Number of value used to create the means + // template< typename Value > + // void meanAndStandardDeviation( const Field&, std::vector& mean, + // std::vector& stddev, size_t& N ) const; + + /// @brief Compute mean values and standard deviations of field for vertical + /// level separately /// @param [out] mean Field of dimension of input without the nodes index /// @param [out] stddev Field of dimension of input without the nodes index /// @param [out] N Number of values used to create the means void meanAndStandardDeviationPerLevel( const Field&, Field& mean, Field& stddev, size_t& N ) const; private: - const detail::NodeColumns* functionspace_; }; @@ -611,109 +650,114 @@ inline size_t NodeColumns::levels() const { return functionspace_->levels(); } -template< typename Value > +template void NodeColumns::sum( const Field& field, Value& sum, size_t& N ) const { - functionspace_->sum(field,sum,N); + functionspace_->sum( field, sum, N ); } inline void NodeColumns::sumPerLevel( const Field& field, Field& sum, size_t& N ) const { - functionspace_->sumPerLevel(field,sum,N); + functionspace_->sumPerLevel( field, sum, N ); } -template< typename Value > +template void NodeColumns::orderIndependentSum( const Field& field, Value& sum, size_t& N ) const { - functionspace_->orderIndependentSum(field,sum,N); + functionspace_->orderIndependentSum( field, sum, N ); } inline void NodeColumns::orderIndependentSumPerLevel( const Field& field, Field& sum, size_t& N ) const { - functionspace_->orderIndependentSumPerLevel(field,sum,N); + functionspace_->orderIndependentSumPerLevel( field, sum, N ); } -template< typename Value > +template void NodeColumns::minimum( const Field& field, Value& minimum ) const { - functionspace_->minimum(field,minimum); + functionspace_->minimum( field, minimum ); } -template< typename Value > +template void NodeColumns::maximum( const Field& field, Value& maximum ) const { - functionspace_->maximum(field,maximum); + functionspace_->maximum( field, maximum ); } inline void NodeColumns::minimumPerLevel( const Field& field, Field& minimum ) const { - return functionspace_->minimumPerLevel(field,minimum); + return functionspace_->minimumPerLevel( field, minimum ); } inline void NodeColumns::maximumPerLevel( const Field& field, Field& maximum ) const { - functionspace_->maximumPerLevel(field,maximum); + functionspace_->maximumPerLevel( field, maximum ); } -template< typename Value > +template void NodeColumns::minimumAndLocation( const Field& field, Value& minimum, gidx_t& glb_idx ) const { - functionspace_->minimumAndLocation(field,minimum,glb_idx); + functionspace_->minimumAndLocation( field, minimum, glb_idx ); } -template< typename Value > +template void NodeColumns::maximumAndLocation( const Field& field, Value& maximum, gidx_t& glb_idx ) const { - functionspace_->maximumAndLocation(field,maximum,glb_idx); + functionspace_->maximumAndLocation( field, maximum, glb_idx ); } -template< typename Value > +template void NodeColumns::minimumAndLocation( const Field& field, Value& minimum, gidx_t& glb_idx, size_t& level ) const { - functionspace_->minimumAndLocation(field,minimum,glb_idx,level); + functionspace_->minimumAndLocation( field, minimum, glb_idx, level ); } -template< typename Value > +template void NodeColumns::maximumAndLocation( const Field& field, Value& maximum, gidx_t& glb_idx, size_t& level ) const { - functionspace_->maximumAndLocation(field,maximum,glb_idx,level); + functionspace_->maximumAndLocation( field, maximum, glb_idx, level ); } -template< typename Value > -void NodeColumns::minimumAndLocation( const Field& field, std::vector& minimum, std::vector& glb_idx ) const { - functionspace_->minimumAndLocation(field,minimum,glb_idx); +template +void NodeColumns::minimumAndLocation( const Field& field, std::vector& minimum, + std::vector& glb_idx ) const { + functionspace_->minimumAndLocation( field, minimum, glb_idx ); } -template< typename Value > -void NodeColumns::maximumAndLocation( const Field& field, std::vector& maximum, std::vector& glb_idx ) const { - functionspace_->maximumAndLocation(field,maximum,glb_idx); +template +void NodeColumns::maximumAndLocation( const Field& field, std::vector& maximum, + std::vector& glb_idx ) const { + functionspace_->maximumAndLocation( field, maximum, glb_idx ); } -template< typename Value > -void NodeColumns::minimumAndLocation( const Field& field, std::vector& minimum, std::vector& glb_idx, std::vector& level ) const { - functionspace_->minimumAndLocation(field,minimum,glb_idx,level); +template +void NodeColumns::minimumAndLocation( const Field& field, std::vector& minimum, std::vector& glb_idx, + std::vector& level ) const { + functionspace_->minimumAndLocation( field, minimum, glb_idx, level ); } -template< typename Value > -void NodeColumns::maximumAndLocation( const Field& field, std::vector& maximum, std::vector& glb_idx, std::vector& level ) const { - functionspace_->maximumAndLocation(field,maximum,glb_idx,level); +template +void NodeColumns::maximumAndLocation( const Field& field, std::vector& maximum, std::vector& glb_idx, + std::vector& level ) const { + functionspace_->maximumAndLocation( field, maximum, glb_idx, level ); } inline void NodeColumns::minimumAndLocationPerLevel( const Field& field, Field& column, Field& glb_idx ) const { - functionspace_->minimumAndLocationPerLevel(field,column,glb_idx); + functionspace_->minimumAndLocationPerLevel( field, column, glb_idx ); } inline void NodeColumns::maximumAndLocationPerLevel( const Field& field, Field& column, Field& glb_idx ) const { - functionspace_->maximumAndLocationPerLevel(field,column,glb_idx); + functionspace_->maximumAndLocationPerLevel( field, column, glb_idx ); } -template< typename Value > +template void NodeColumns::mean( const Field& field, Value& mean, size_t& N ) const { - functionspace_->mean(field,mean,N); + functionspace_->mean( field, mean, N ); } inline void NodeColumns::meanPerLevel( const Field& field, Field& mean, size_t& N ) const { - functionspace_->meanPerLevel(field,mean,N); + functionspace_->meanPerLevel( field, mean, N ); } -template< typename Value > +template void NodeColumns::meanAndStandardDeviation( const Field& field, Value& mean, Value& stddev, size_t& N ) const { - functionspace_->meanAndStandardDeviation(field,mean,stddev,N); + functionspace_->meanAndStandardDeviation( field, mean, stddev, N ); } -inline void NodeColumns::meanAndStandardDeviationPerLevel( const Field& field, Field& mean, Field& stddev, size_t& N ) const { - functionspace_->meanAndStandardDeviationPerLevel(field,mean,stddev,N); +inline void NodeColumns::meanAndStandardDeviationPerLevel( const Field& field, Field& mean, Field& stddev, + size_t& N ) const { + functionspace_->meanAndStandardDeviationPerLevel( field, mean, stddev, N ); } // ------------------------------------------------------------------- -} // namespace functionspace -} // namespace atlas +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/NodeColumnsInterface.cc b/src/atlas/functionspace/NodeColumnsInterface.cc index b8cc0742f..ec54e9b45 100644 --- a/src/atlas/functionspace/NodeColumnsInterface.cc +++ b/src/atlas/functionspace/NodeColumnsInterface.cc @@ -4,1208 +4,1001 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "atlas/functionspace/NodeColumnsInterface.h" -#include "atlas/runtime/ErrorHandling.h" #include "atlas/field/detail/FieldImpl.h" +#include "atlas/runtime/ErrorHandling.h" namespace atlas { namespace functionspace { namespace detail { - using atlas::field::FieldImpl; - using atlas::field::FieldSetImpl; - using atlas::FieldSet; +using atlas::FieldSet; +using atlas::field::FieldImpl; +using atlas::field::FieldSetImpl; // ---------------------------------------------------------------------- extern "C" { -const NodeColumns* atlas__NodesFunctionSpace__new ( Mesh::Implementation* mesh, const eckit::Configuration* config ) -{ - ASSERT(mesh); - Mesh m(mesh); - return new NodeColumns(m,*config); -} - -void atlas__NodesFunctionSpace__delete (NodeColumns* This) -{ - ASSERT(This); - delete(This); -} - -int atlas__NodesFunctionSpace__nb_nodes(const NodeColumns* This) -{ - ASSERT(This); - return This->nb_nodes(); +const NodeColumns* atlas__NodesFunctionSpace__new( Mesh::Implementation* mesh, const eckit::Configuration* config ) { + ASSERT( mesh ); + Mesh m( mesh ); + return new NodeColumns( m, *config ); +} + +void atlas__NodesFunctionSpace__delete( NodeColumns* This ) { + ASSERT( This ); + delete ( This ); +} + +int atlas__NodesFunctionSpace__nb_nodes( const NodeColumns* This ) { + ASSERT( This ); + return This->nb_nodes(); +} + +const Mesh::Implementation* atlas__NodesFunctionSpace__mesh( const NodeColumns* This ) { + ASSERT( This ); + return This->mesh().get(); +} + +mesh::Nodes* atlas__NodesFunctionSpace__nodes( const NodeColumns* This ) { + ASSERT( This ); + return &This->nodes(); +} + +field::FieldImpl* atlas__NodesFunctionSpace__create_field( const NodeColumns* This, + const eckit::Configuration* options ) { + ASSERT( This ); + ASSERT( options ); + FieldImpl* field; + { + Field f = This->createField( util::Config( *options ) ); + field = f.get(); + field->attach(); + } + field->detach(); + return field; +} + +field::FieldImpl* atlas__NodesFunctionSpace__create_field_template( const NodeColumns* This, + const field::FieldImpl* field_template, + const eckit::Configuration* options ) { + ASSERT( This ); + ASSERT( options ); + FieldImpl* field; + { + Field f = This->createField( Field( field_template ), *options ); + field = f.get(); + field->attach(); + } + field->detach(); + return field; +} + +void atlas__NodesFunctionSpace__halo_exchange_fieldset( const NodeColumns* This, field::FieldSetImpl* fieldset ) { + ASSERT( This ); + ASSERT( fieldset ); + FieldSet f( fieldset ); + ATLAS_ERROR_HANDLING( This->haloExchange( f ); ); +} + +void atlas__NodesFunctionSpace__halo_exchange_field( const NodeColumns* This, field::FieldImpl* field ) { + ASSERT( This ); + ASSERT( field ); + Field f( field ); + ATLAS_ERROR_HANDLING( This->haloExchange( f ); ); +} + +const parallel::HaloExchange* atlas__NodesFunctionSpace__get_halo_exchange( const NodeColumns* This ) { + ASSERT( This ); + ATLAS_ERROR_HANDLING( return &This->halo_exchange(); ); + return 0; } -const Mesh::Implementation* atlas__NodesFunctionSpace__mesh(const NodeColumns* This) -{ - ASSERT(This); - return This->mesh().get(); -} - -mesh::Nodes* atlas__NodesFunctionSpace__nodes(const NodeColumns* This) -{ - ASSERT(This); - return &This->nodes(); -} - -field::FieldImpl* atlas__NodesFunctionSpace__create_field (const NodeColumns* This, const eckit::Configuration* options ) -{ - ASSERT(This); - ASSERT(options); - FieldImpl* field; - { - Field f = This->createField( util::Config(*options) ); - field = f.get(); - field->attach(); - } - field->detach(); - return field; -} - -field::FieldImpl* atlas__NodesFunctionSpace__create_field_template (const NodeColumns* This, const field::FieldImpl* field_template, const eckit::Configuration* options ) -{ - ASSERT(This); - ASSERT(options); - FieldImpl* field; - { - Field f = This->createField( Field(field_template), *options ); - field = f.get(); - field->attach(); - } - field->detach(); - return field; -} - - -void atlas__NodesFunctionSpace__halo_exchange_fieldset(const NodeColumns* This, field::FieldSetImpl* fieldset) -{ - ASSERT(This); - ASSERT(fieldset); - FieldSet f(fieldset); - ATLAS_ERROR_HANDLING( This->haloExchange(f); ); -} - -void atlas__NodesFunctionSpace__halo_exchange_field(const NodeColumns* This, field::FieldImpl* field) -{ - ASSERT(This); - ASSERT(field); - Field f(field); - ATLAS_ERROR_HANDLING( This->haloExchange(f); ); -} - -const parallel::HaloExchange* atlas__NodesFunctionSpace__get_halo_exchange(const NodeColumns* This) -{ - ASSERT(This); - ATLAS_ERROR_HANDLING( return &This->halo_exchange(); ); - return 0; -} - -void atlas__NodesFunctionSpace__gather_fieldset(const NodeColumns* This, const field::FieldSetImpl* local, field::FieldSetImpl* global) -{ - ASSERT(This); - ASSERT(local); - ASSERT(global); - const FieldSet l(local); - FieldSet g(global); - ATLAS_ERROR_HANDLING( This->gather(l,g); ); -} - -void atlas__NodesFunctionSpace__gather_field(const NodeColumns* This, const field::FieldImpl* local, field::FieldImpl* global) -{ - ASSERT(This); - ASSERT(local); - ASSERT(global); - const Field l(local); - Field g(global); - ATLAS_ERROR_HANDLING( This->gather(l,g); ); -} - -const parallel::GatherScatter* atlas__NodesFunctionSpace__get_gather(const NodeColumns* This) -{ - ASSERT(This); - ATLAS_ERROR_HANDLING( return &This->gather(); ); - return 0; -} - -const parallel::GatherScatter* atlas__NodesFunctionSpace__get_scatter(const NodeColumns* This) -{ - ASSERT(This); - ATLAS_ERROR_HANDLING( return &This->scatter(); ); - return 0; -} - -void atlas__NodesFunctionSpace__scatter_fieldset(const NodeColumns* This, const field::FieldSetImpl* global, field::FieldSetImpl* local) -{ - ASSERT(This); - ASSERT(local); - ASSERT(global); - const FieldSet g(global); - FieldSet l(local); - ATLAS_ERROR_HANDLING( This->scatter(g,l); ); -} - -void atlas__NodesFunctionSpace__scatter_field(const NodeColumns* This, const field::FieldImpl* global, field::FieldImpl* local) -{ - ASSERT(This); - ASSERT(global); - ASSERT(local); - const Field g(global); - Field l(local); - ATLAS_ERROR_HANDLING( This->scatter(g,l); ); -} - -const parallel::Checksum* atlas__NodesFunctionSpace__get_checksum(const NodeColumns* This) -{ - ASSERT(This); - ATLAS_ERROR_HANDLING( return &This->checksum(); ); - return 0; -} - -void atlas__NodesFunctionSpace__checksum_fieldset(const NodeColumns* This, const field::FieldSetImpl* fieldset, char* &checksum, int &size, int &allocated) -{ - ASSERT(This); - ASSERT(fieldset); - ATLAS_ERROR_HANDLING( - std::string checksum_str (This->checksum(fieldset)); - size = checksum_str.size(); - checksum = new char[size+1]; allocated = true; - strcpy(checksum,checksum_str.c_str()); - ); -} - -void atlas__NodesFunctionSpace__checksum_field(const NodeColumns* This, const field::FieldImpl* field, char* &checksum, int &size, int &allocated) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::string checksum_str (This->checksum(field)); - size = checksum_str.size(); - checksum = new char[size+1]; allocated = true; - strcpy(checksum,checksum_str.c_str()); - ); -} - -void atlas__NodesFunctionSpace__sum_double(const NodeColumns* This, const field::FieldImpl* field, double &sum, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->sum(field,sum,size_t_N) ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__sum_float(const NodeColumns* This, const field::FieldImpl* field, float &sum, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->sum(field,sum,size_t_N) ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__sum_long(const NodeColumns* This, const field::FieldImpl* field, long &sum, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->sum(field,sum,size_t_N) ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__sum_int(const NodeColumns* This, const field::FieldImpl* field, int &sum, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->sum(field,sum,size_t_N) ); - N = size_t_N; -} - - -void atlas__NodesFunctionSpace__sum_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &sum, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector sumvec; - This->orderIndependentSum(field,sumvec,size_t_N); - size = sumvec.size(); - sum = new double[size]; - for( size_t j=0; j<(size_t)size; ++j ) sum[j] = sumvec[j]; - ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__sum_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &sum, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector sumvec; - This->orderIndependentSum(field,sumvec,size_t_N); - size = sumvec.size(); - sum = new float[size]; - for( size_t j=0; j<(size_t)size; ++j ) sum[j] = sumvec[j]; - ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__sum_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &sum, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector sumvec; - This->orderIndependentSum(field,sumvec,size_t_N); - size = sumvec.size(); - sum = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) sum[j] = sumvec[j]; - ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__sum_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &sum, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector sumvec; - This->orderIndependentSum(field,sumvec,size_t_N); - size = sumvec.size(); - sum = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) sum[j] = sumvec[j]; - ); - N = size_t_N; -} - - -void atlas__NodesFunctionSpace__oisum_double(const NodeColumns* This, const field::FieldImpl* field, double &sum, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->orderIndependentSum(field,sum,size_t_N) ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__oisum_float(const NodeColumns* This, const field::FieldImpl* field, float &sum, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->orderIndependentSum(field,sum,size_t_N) ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__oisum_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &sum, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector sumvec; - This->orderIndependentSum(field,sumvec,size_t_N); - size = sumvec.size(); - sum = new double[size]; - for( size_t j=0; j<(size_t)size; ++j ) sum[j] = sumvec[j]; - ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__oisum_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &sum, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector sumvec; - This->orderIndependentSum(field,sumvec,size_t_N); - size = sumvec.size(); - sum = new float[size]; - for( size_t j=0; j<(size_t)size; ++j ) sum[j] = sumvec[j]; - ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__min_double(const NodeColumns* This, const field::FieldImpl* field, double &minimum) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( This->minimum(field,minimum) ); -} - -void atlas__NodesFunctionSpace__min_float(const NodeColumns* This, const field::FieldImpl* field, float &minimum) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( This->minimum(field,minimum) ); -} - -void atlas__NodesFunctionSpace__min_long(const NodeColumns* This, const field::FieldImpl* field, long &minimum) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( This->minimum(field,minimum) ); -} - -void atlas__NodesFunctionSpace__min_int(const NodeColumns* This, const field::FieldImpl* field, int &minimum) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( This->minimum(field,minimum) ); -} - -void atlas__NodesFunctionSpace__max_double(const NodeColumns* This, const field::FieldImpl* field, double &maximum) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( This->maximum(field,maximum) ); -} - -void atlas__NodesFunctionSpace__max_float(const NodeColumns* This, const field::FieldImpl* field, float &maximum) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( This->maximum(field,maximum) ); -} - -void atlas__NodesFunctionSpace__max_long(const NodeColumns* This, const field::FieldImpl* field, long &maximum) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( This->maximum(field,maximum) ); -} - -void atlas__NodesFunctionSpace__max_int(const NodeColumns* This, const field::FieldImpl* field, int &maximum) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( This->maximum(field,maximum) ); -} - -void atlas__NodesFunctionSpace__min_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &minimum, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - This->minimum(field,minvec); - size = minvec.size(); - minimum = new double[size]; - for( size_t j=0; j<(size_t)size; ++j ) minimum[j] = minvec[j]; - ); -} - -void atlas__NodesFunctionSpace__min_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &minimum, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - This->minimum(field,minvec); - size = minvec.size(); - minimum = new float[size]; - for( size_t j=0; j<(size_t)size; ++j ) minimum[j] = minvec[j]; - ); -} - -void atlas__NodesFunctionSpace__min_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &minimum, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - This->minimum(field,minvec); - size = minvec.size(); - minimum = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) minimum[j] = minvec[j]; - ); -} - -void atlas__NodesFunctionSpace__min_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &minimum, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - This->minimum(field,minvec); - size = minvec.size(); - minimum = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) minimum[j] = minvec[j]; - ); -} - -void atlas__NodesFunctionSpace__max_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &maximum, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - This->maximum(field,maxvec); - size = maxvec.size(); - maximum = new double[size]; - for( size_t j=0; j<(size_t)size; ++j ) maximum[j] = maxvec[j]; - ); -} - -void atlas__NodesFunctionSpace__max_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &maximum, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - This->maximum(field,maxvec); - size = maxvec.size(); - maximum = new float[size]; - for( size_t j=0; j<(size_t)size; ++j ) maximum[j] = maxvec[j]; - ); -} - -void atlas__NodesFunctionSpace__max_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &maximum, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - This->maximum(field,maxvec); - size = maxvec.size(); - maximum = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) maximum[j] = maxvec[j]; - ); -} - -void atlas__NodesFunctionSpace__max_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &maximum, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - This->maximum(field,maxvec); - size = maxvec.size(); - maximum = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) maximum[j] = maxvec[j]; - ); -} - -void atlas__NodesFunctionSpace__minloc_double(const NodeColumns* This, const field::FieldImpl* field, double &minimum, long &glb_idx) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - ATLAS_ERROR_HANDLING( This->minimumAndLocation(field,minimum,gidx) ); - glb_idx = gidx; -} - -void atlas__NodesFunctionSpace__minloc_float(const NodeColumns* This, const field::FieldImpl* field, float &minimum, long &glb_idx) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - ATLAS_ERROR_HANDLING( This->minimumAndLocation(field,minimum,gidx) ); - glb_idx = gidx; -} - -void atlas__NodesFunctionSpace__minloc_long(const NodeColumns* This, const field::FieldImpl* field, long &minimum, long &glb_idx) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - ATLAS_ERROR_HANDLING( This->minimumAndLocation(field,minimum,gidx) ); - glb_idx = gidx; -} - -void atlas__NodesFunctionSpace__minloc_int(const NodeColumns* This, const field::FieldImpl* field, int &minimum, long &glb_idx) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - ATLAS_ERROR_HANDLING( This->minimumAndLocation(field,minimum,gidx) ); - glb_idx = gidx; -} - -void atlas__NodesFunctionSpace__maxloc_double(const NodeColumns* This, const field::FieldImpl* field, double &maximum, long &glb_idx) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - ATLAS_ERROR_HANDLING( This->maximumAndLocation(field,maximum,gidx) ); - glb_idx = gidx; -} - -void atlas__NodesFunctionSpace__maxloc_float(const NodeColumns* This, const field::FieldImpl* field, float &maximum, long &glb_idx) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - ATLAS_ERROR_HANDLING( This->maximumAndLocation(field,maximum,gidx) ); - glb_idx = gidx; -} - -void atlas__NodesFunctionSpace__maxloc_long(const NodeColumns* This, const field::FieldImpl* field, long &maximum, long &glb_idx) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - ATLAS_ERROR_HANDLING( This->maximumAndLocation(field,maximum,gidx) ); - glb_idx = gidx; -} - -void atlas__NodesFunctionSpace__maxloc_int(const NodeColumns* This, const field::FieldImpl* field, int &maximum, long &glb_idx) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - ATLAS_ERROR_HANDLING( This->maximumAndLocation(field,maximum,gidx) ); - glb_idx = gidx; -} - -void atlas__NodesFunctionSpace__minloc_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &minimum, long* &glb_idx, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - std::vector gidxvec; - This->minimumAndLocation(field,minvec,gidxvec); - size = minvec.size(); - minimum = new double[size]; - glb_idx = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - minimum[j] = minvec[j]; - glb_idx[j] = gidxvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__minloc_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &minimum, long* &glb_idx, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - std::vector gidxvec; - This->minimumAndLocation(field,minvec,gidxvec); - size = minvec.size(); - minimum = new float[size]; - glb_idx = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - minimum[j] = minvec[j]; - glb_idx[j] = gidxvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__minloc_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &minimum, long* &glb_idx, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - std::vector gidxvec; - This->minimumAndLocation(field,minvec,gidxvec); - size = minvec.size(); - minimum = new long[size]; - glb_idx = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - minimum[j] = minvec[j]; - glb_idx[j] = gidxvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__minloc_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &minimum, long* &glb_idx, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - std::vector gidxvec; - This->minimumAndLocation(field,minvec,gidxvec); - size = minvec.size(); - minimum = new int[size]; - glb_idx = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - minimum[j] = minvec[j]; - glb_idx[j] = gidxvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__maxloc_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &maximum, long* &glb_idx, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - std::vector gidxvec; - This->maximumAndLocation(field,maxvec,gidxvec); - size = maxvec.size(); - maximum = new double[size]; - glb_idx = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - maximum[j] = maxvec[j]; - glb_idx[j] = gidxvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__maxloc_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &maximum, long* &glb_idx, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - std::vector gidxvec; - This->maximumAndLocation(field,maxvec,gidxvec); - size = maxvec.size(); - maximum = new float[size]; - glb_idx = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - maximum[j] = maxvec[j]; - glb_idx[j] = gidxvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__maxloc_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &maximum, long* &glb_idx, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - std::vector gidxvec; - This->maximumAndLocation(field,maxvec,gidxvec); - size = maxvec.size(); - maximum = new long[size]; - glb_idx = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - maximum[j] = maxvec[j]; - glb_idx[j] = gidxvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__maxloc_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &maximum, long* &glb_idx, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - std::vector gidxvec; - This->maximumAndLocation(field,maxvec,gidxvec); - size = maxvec.size(); - maximum = new int[size]; - glb_idx = new long[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - maximum[j] = maxvec[j]; - glb_idx[j] = gidxvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__mean_double(const NodeColumns* This, const field::FieldImpl* field, double &mean, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->mean(field,mean,size_t_N) ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__mean_float(const NodeColumns* This, const field::FieldImpl* field, float &mean, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->mean(field,mean,size_t_N) ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__mean_long(const NodeColumns* This, const field::FieldImpl* field, long &mean, int &N) -{ -NOTIMP; -} - -void atlas__NodesFunctionSpace__mean_int(const NodeColumns* This, const field::FieldImpl* field, int &mean, int &N) -{ -NOTIMP; -} - -void atlas__NodesFunctionSpace__mean_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &mean, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector meanvec; - This->mean(field,meanvec,size_t_N); - size = meanvec.size(); - mean = new double[size]; - for( size_t j=0; j<(size_t)size; ++j ) mean[j] = meanvec[j]; - ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__mean_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &mean, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector meanvec; - This->mean(field,meanvec,size_t_N); - size = meanvec.size(); - mean = new float[size]; - for( size_t j=0; j<(size_t)size; ++j ) mean[j] = meanvec[j]; - ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__mean_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &mean, int &size, int &N) -{ -NOTIMP; -} - -void atlas__NodesFunctionSpace__mean_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &mean, int &size, int &N) -{ -NOTIMP; -} - -void atlas__NodesFunctionSpace__mean_and_stddev_double(const NodeColumns* This, const field::FieldImpl* field, double &mean, double &stddev, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->meanAndStandardDeviation(field,mean,stddev,size_t_N) ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__mean_and_stddev_float(const NodeColumns* This, const field::FieldImpl* field, float &mean, float &stddev, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( This->meanAndStandardDeviation(field,mean,stddev,size_t_N) ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__mean_and_stddev_long(const NodeColumns* This, const field::FieldImpl* field, long &mean, long &stddev, int &N) -{ -NOTIMP; -} - -void atlas__NodesFunctionSpace__mean_and_stddev_int(const NodeColumns* This, const field::FieldImpl* field, int &mean, int &stddev, int &N) -{ -NOTIMP; -} - -void atlas__NodesFunctionSpace__mean_and_stddev_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &mean, double* &stddev, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector meanvec; - std::vector stddevvec; - This->meanAndStandardDeviation(field,meanvec,stddevvec,size_t_N); - size = meanvec.size(); - mean = new double[size]; - stddev = new double[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - mean[j] = meanvec[j]; - stddev[j] = stddevvec[j]; - } - ); - N = size_t_N; -} - - -void atlas__NodesFunctionSpace__mean_and_stddev_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &mean, float* &stddev, int &size, int &N) -{ - ASSERT(This); - ASSERT(field); - size_t size_t_N; - ATLAS_ERROR_HANDLING( - std::vector meanvec; - std::vector stddevvec; - This->meanAndStandardDeviation(field,meanvec,stddevvec,size_t_N); - size = meanvec.size(); - mean = new float[size]; - stddev = new float[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - mean[j] = meanvec[j]; - stddev[j] = stddevvec[j]; - } - ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__mean_and_stddev_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &mean, long* &stddev, int &size, int &N) -{ -NOTIMP; -} - -void atlas__NodesFunctionSpace__mean_and_stddev_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &mean, int* &stddev, int &size, int &N) -{ -NOTIMP; -} - -void atlas__NodesFunctionSpace__minloclev_double(const NodeColumns* This, const field::FieldImpl* field, double &minimum, long &glb_idx, int &level) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - size_t lev; - ATLAS_ERROR_HANDLING( This->minimumAndLocation(field,minimum,gidx,lev) ); - glb_idx = gidx; - level = lev; -} - -void atlas__NodesFunctionSpace__minloclev_float(const NodeColumns* This, const field::FieldImpl* field, float &minimum, long &glb_idx, int &level) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - size_t lev; - ATLAS_ERROR_HANDLING( This->minimumAndLocation(field,minimum,gidx,lev) ); - glb_idx = gidx; - level = lev; -} - -void atlas__NodesFunctionSpace__minloclev_long(const NodeColumns* This, const field::FieldImpl* field, long &minimum, long &glb_idx, int &level) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - size_t lev; - ATLAS_ERROR_HANDLING( This->minimumAndLocation(field,minimum,gidx,lev) ); - glb_idx = gidx; - level = lev; -} - -void atlas__NodesFunctionSpace__minloclev_int(const NodeColumns* This, const field::FieldImpl* field, int &minimum, long &glb_idx, int &level) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - size_t lev; - ATLAS_ERROR_HANDLING( This->minimumAndLocation(field,minimum,gidx,lev) ); - glb_idx = gidx; - level = lev; -} - -void atlas__NodesFunctionSpace__maxloclev_double(const NodeColumns* This, const field::FieldImpl* field, double &maximum, long &glb_idx, int &level) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - size_t lev; - ATLAS_ERROR_HANDLING( This->maximumAndLocation(field,maximum,gidx,lev) ); - glb_idx = gidx; - level = lev; -} - -void atlas__NodesFunctionSpace__maxloclev_float(const NodeColumns* This, const field::FieldImpl* field, float &maximum, long &glb_idx, int &level) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - size_t lev; - ATLAS_ERROR_HANDLING( This->maximumAndLocation(field,maximum,gidx,lev) ); - glb_idx = gidx; - level = lev; -} - -void atlas__NodesFunctionSpace__maxloclev_long(const NodeColumns* This, const field::FieldImpl* field, long &maximum, long &glb_idx, int &level) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - size_t lev; - ATLAS_ERROR_HANDLING( This->maximumAndLocation(field,maximum,gidx,lev) ); - glb_idx = gidx; - level = lev; -} - -void atlas__NodesFunctionSpace__maxloclev_int(const NodeColumns* This, const field::FieldImpl* field, int &maximum, long &glb_idx, int &level) -{ - ASSERT(This); - ASSERT(field); - gidx_t gidx; - size_t lev; - ATLAS_ERROR_HANDLING( This->maximumAndLocation(field,maximum,gidx,lev) ); - glb_idx = gidx; - level = lev; -} - -void atlas__NodesFunctionSpace__minloclev_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &minimum, long* &glb_idx, int* &level, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - std::vector gidxvec; - std::vector levvec; - This->minimumAndLocation(field,minvec,gidxvec,levvec); - size = minvec.size(); - minimum = new double[size]; - glb_idx = new long[size]; - level = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - minimum[j] = minvec[j]; - glb_idx[j] = gidxvec[j]; - level[j] = levvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__minloclev_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &minimum, long* &glb_idx, int* &level, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - std::vector gidxvec; - std::vector levvec; - This->minimumAndLocation(field,minvec,gidxvec,levvec); - size = minvec.size(); - minimum = new float[size]; - glb_idx = new long[size]; - level = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - minimum[j] = minvec[j]; - glb_idx[j] = gidxvec[j]; - level[j] = levvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__minloclev_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &minimum, long* &glb_idx, int* &level, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - std::vector gidxvec; - std::vector levvec; - This->minimumAndLocation(field,minvec,gidxvec,levvec); - size = minvec.size(); - minimum = new long[size]; - glb_idx = new long[size]; - level = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - minimum[j] = minvec[j]; - glb_idx[j] = gidxvec[j]; - level[j] = levvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__minloclev_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &minimum, long* &glb_idx, int* &level, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector minvec; - std::vector gidxvec; - std::vector levvec; - This->minimumAndLocation(field,minvec,gidxvec,levvec); - size = minvec.size(); - minimum = new int[size]; - glb_idx = new long[size]; - level = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - minimum[j] = minvec[j]; - glb_idx[j] = gidxvec[j]; - level[j] = levvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__maxloclev_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &maximum, long* &glb_idx, int* &level, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - std::vector gidxvec; - std::vector levvec; - This->maximumAndLocation(field,maxvec,gidxvec,levvec); - size = maxvec.size(); - maximum = new double[size]; - glb_idx = new long[size]; - level = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - maximum[j] = maxvec[j]; - glb_idx[j] = gidxvec[j]; - level[j] = levvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__maxloclev_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &maximum, long* &glb_idx, int* &level, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - std::vector gidxvec; - std::vector levvec; - This->maximumAndLocation(field,maxvec,gidxvec,levvec); - size = maxvec.size(); - maximum = new float[size]; - glb_idx = new long[size]; - level = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - maximum[j] = maxvec[j]; - glb_idx[j] = gidxvec[j]; - level[j] = levvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__maxloclev_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &maximum, long* &glb_idx, int* &level, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - std::vector gidxvec; - std::vector levvec; - This->maximumAndLocation(field,maxvec,gidxvec,levvec); - size = maxvec.size(); - maximum = new long[size]; - glb_idx = new long[size]; - level = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - maximum[j] = maxvec[j]; - glb_idx[j] = gidxvec[j]; - level[j] = levvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__maxloclev_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &maximum, long* &glb_idx, int* &level, int &size) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::vector maxvec; - std::vector gidxvec; - std::vector levvec; - This->maximumAndLocation(field,maxvec,gidxvec,levvec); - size = maxvec.size(); - maximum = new int[size]; - glb_idx = new long[size]; - level = new int[size]; - for( size_t j=0; j<(size_t)size; ++j ) { - maximum[j] = maxvec[j]; - glb_idx[j] = gidxvec[j]; - level[j] = levvec[j]; - } - ); -} - -void atlas__NodesFunctionSpace__sum_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* column, int &N) -{ - ASSERT(This); - ASSERT(field); - ASSERT(column); - size_t size_t_N; - Field sum(column); - ATLAS_ERROR_HANDLING( This->sumPerLevel(field,sum,size_t_N); ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__oisum_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* column, int &N) -{ - ASSERT(This); - ASSERT(field); - ASSERT(column); - size_t size_t_N; - Field sum(column); - ATLAS_ERROR_HANDLING( This->orderIndependentSumPerLevel(field,sum,size_t_N); ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__min_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* min) -{ - ASSERT(This); - ASSERT(field); - ASSERT(min); - Field fmin(min); - ATLAS_ERROR_HANDLING( This->minimumPerLevel(field,fmin); ); -} - -void atlas__NodesFunctionSpace__max_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* max) -{ - ASSERT(This); - ASSERT(field); - ASSERT(max); - Field fmax(max); - ATLAS_ERROR_HANDLING( This->maximumPerLevel(field,fmax); ); -} - -void atlas__NodesFunctionSpace__minloc_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* min, field::FieldImpl* glb_idx) -{ - ASSERT(This); - ASSERT(field); - ASSERT(min); - ASSERT(glb_idx); - Field fmin(min); - Field fglb_idx(glb_idx); - ATLAS_ERROR_HANDLING( This->minimumAndLocationPerLevel(field,fmin,fglb_idx); ); -} - -void atlas__NodesFunctionSpace__maxloc_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* max, field::FieldImpl* glb_idx) -{ - ASSERT(This); - ASSERT(field); - ASSERT(max); - ASSERT(glb_idx); - Field fmax(max); - Field fglb_idx(glb_idx); - ATLAS_ERROR_HANDLING( This->maximumAndLocationPerLevel(field,fmax,fglb_idx); ); -} - -void atlas__NodesFunctionSpace__mean_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* mean, int &N) -{ - ASSERT(This); - ASSERT(field); - ASSERT(mean); - size_t size_t_N; - Field fmean(mean); - ATLAS_ERROR_HANDLING( This->meanPerLevel(field,fmean,size_t_N); ); - N = size_t_N; -} - -void atlas__NodesFunctionSpace__mean_and_stddev_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* mean, field::FieldImpl* stddev, int &N) -{ - ASSERT(This); - ASSERT(field); - ASSERT(mean); - ASSERT(stddev); - size_t size_t_N; - Field fmean(mean); - Field fstddev(stddev); - ATLAS_ERROR_HANDLING( This->meanAndStandardDeviationPerLevel(field,fmean,fstddev,size_t_N); ); - N = size_t_N; -} - - -} - -} // namespace detail -} // namespace functionspace -} // namespace atlas +void atlas__NodesFunctionSpace__gather_fieldset( const NodeColumns* This, const field::FieldSetImpl* local, + field::FieldSetImpl* global ) { + ASSERT( This ); + ASSERT( local ); + ASSERT( global ); + const FieldSet l( local ); + FieldSet g( global ); + ATLAS_ERROR_HANDLING( This->gather( l, g ); ); +} + +void atlas__NodesFunctionSpace__gather_field( const NodeColumns* This, const field::FieldImpl* local, + field::FieldImpl* global ) { + ASSERT( This ); + ASSERT( local ); + ASSERT( global ); + const Field l( local ); + Field g( global ); + ATLAS_ERROR_HANDLING( This->gather( l, g ); ); +} + +const parallel::GatherScatter* atlas__NodesFunctionSpace__get_gather( const NodeColumns* This ) { + ASSERT( This ); + ATLAS_ERROR_HANDLING( return &This->gather(); ); + return 0; +} + +const parallel::GatherScatter* atlas__NodesFunctionSpace__get_scatter( const NodeColumns* This ) { + ASSERT( This ); + ATLAS_ERROR_HANDLING( return &This->scatter(); ); + return 0; +} + +void atlas__NodesFunctionSpace__scatter_fieldset( const NodeColumns* This, const field::FieldSetImpl* global, + field::FieldSetImpl* local ) { + ASSERT( This ); + ASSERT( local ); + ASSERT( global ); + const FieldSet g( global ); + FieldSet l( local ); + ATLAS_ERROR_HANDLING( This->scatter( g, l ); ); +} + +void atlas__NodesFunctionSpace__scatter_field( const NodeColumns* This, const field::FieldImpl* global, + field::FieldImpl* local ) { + ASSERT( This ); + ASSERT( global ); + ASSERT( local ); + const Field g( global ); + Field l( local ); + ATLAS_ERROR_HANDLING( This->scatter( g, l ); ); +} + +const parallel::Checksum* atlas__NodesFunctionSpace__get_checksum( const NodeColumns* This ) { + ASSERT( This ); + ATLAS_ERROR_HANDLING( return &This->checksum(); ); + return 0; +} + +void atlas__NodesFunctionSpace__checksum_fieldset( const NodeColumns* This, const field::FieldSetImpl* fieldset, + char*& checksum, int& size, int& allocated ) { + ASSERT( This ); + ASSERT( fieldset ); + ATLAS_ERROR_HANDLING( std::string checksum_str( This->checksum( fieldset ) ); size = checksum_str.size(); + checksum = new char[size + 1]; allocated = true; strcpy( checksum, checksum_str.c_str() ); ); +} + +void atlas__NodesFunctionSpace__checksum_field( const NodeColumns* This, const field::FieldImpl* field, char*& checksum, + int& size, int& allocated ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::string checksum_str( This->checksum( field ) ); size = checksum_str.size(); + checksum = new char[size + 1]; allocated = true; strcpy( checksum, checksum_str.c_str() ); ); +} + +void atlas__NodesFunctionSpace__sum_double( const NodeColumns* This, const field::FieldImpl* field, double& sum, + int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->sum( field, sum, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__sum_float( const NodeColumns* This, const field::FieldImpl* field, float& sum, + int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->sum( field, sum, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__sum_long( const NodeColumns* This, const field::FieldImpl* field, long& sum, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->sum( field, sum, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__sum_int( const NodeColumns* This, const field::FieldImpl* field, int& sum, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->sum( field, sum, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__sum_arr_double( const NodeColumns* This, const field::FieldImpl* field, double*& sum, + int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector sumvec; This->orderIndependentSum( field, sumvec, size_t_N ); + size = sumvec.size(); sum = new double[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) sum[j] = sumvec[j]; ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__sum_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& sum, + int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector sumvec; This->orderIndependentSum( field, sumvec, size_t_N ); + size = sumvec.size(); sum = new float[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) sum[j] = sumvec[j]; ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__sum_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& sum, + int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector sumvec; This->orderIndependentSum( field, sumvec, size_t_N ); + size = sumvec.size(); sum = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) sum[j] = sumvec[j]; ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__sum_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& sum, + int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector sumvec; This->orderIndependentSum( field, sumvec, size_t_N ); + size = sumvec.size(); sum = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) sum[j] = sumvec[j]; ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__oisum_double( const NodeColumns* This, const field::FieldImpl* field, double& sum, + int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->orderIndependentSum( field, sum, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__oisum_float( const NodeColumns* This, const field::FieldImpl* field, float& sum, + int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->orderIndependentSum( field, sum, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__oisum_arr_double( const NodeColumns* This, const field::FieldImpl* field, double*& sum, + int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector sumvec; This->orderIndependentSum( field, sumvec, size_t_N ); + size = sumvec.size(); sum = new double[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) sum[j] = sumvec[j]; ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__oisum_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& sum, + int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector sumvec; This->orderIndependentSum( field, sumvec, size_t_N ); + size = sumvec.size(); sum = new float[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) sum[j] = sumvec[j]; ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__min_double( const NodeColumns* This, const field::FieldImpl* field, double& minimum ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( This->minimum( field, minimum ) ); +} + +void atlas__NodesFunctionSpace__min_float( const NodeColumns* This, const field::FieldImpl* field, float& minimum ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( This->minimum( field, minimum ) ); +} + +void atlas__NodesFunctionSpace__min_long( const NodeColumns* This, const field::FieldImpl* field, long& minimum ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( This->minimum( field, minimum ) ); +} + +void atlas__NodesFunctionSpace__min_int( const NodeColumns* This, const field::FieldImpl* field, int& minimum ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( This->minimum( field, minimum ) ); +} + +void atlas__NodesFunctionSpace__max_double( const NodeColumns* This, const field::FieldImpl* field, double& maximum ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( This->maximum( field, maximum ) ); +} + +void atlas__NodesFunctionSpace__max_float( const NodeColumns* This, const field::FieldImpl* field, float& maximum ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( This->maximum( field, maximum ) ); +} + +void atlas__NodesFunctionSpace__max_long( const NodeColumns* This, const field::FieldImpl* field, long& maximum ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( This->maximum( field, maximum ) ); +} + +void atlas__NodesFunctionSpace__max_int( const NodeColumns* This, const field::FieldImpl* field, int& maximum ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( This->maximum( field, maximum ) ); +} + +void atlas__NodesFunctionSpace__min_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& minimum, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; This->minimum( field, minvec ); size = minvec.size(); + minimum = new double[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) minimum[j] = minvec[j]; ); +} + +void atlas__NodesFunctionSpace__min_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& minimum, + int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; This->minimum( field, minvec ); size = minvec.size(); + minimum = new float[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) minimum[j] = minvec[j]; ); +} + +void atlas__NodesFunctionSpace__min_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& minimum, + int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; This->minimum( field, minvec ); size = minvec.size(); + minimum = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) minimum[j] = minvec[j]; ); +} + +void atlas__NodesFunctionSpace__min_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& minimum, + int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; This->minimum( field, minvec ); size = minvec.size(); + minimum = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) minimum[j] = minvec[j]; ); +} + +void atlas__NodesFunctionSpace__max_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& maximum, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; This->maximum( field, maxvec ); size = maxvec.size(); + maximum = new double[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) maximum[j] = maxvec[j]; ); +} +void atlas__NodesFunctionSpace__max_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& maximum, + int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; This->maximum( field, maxvec ); size = maxvec.size(); + maximum = new float[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) maximum[j] = maxvec[j]; ); +} + +void atlas__NodesFunctionSpace__max_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& maximum, + int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; This->maximum( field, maxvec ); size = maxvec.size(); + maximum = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) maximum[j] = maxvec[j]; ); +} + +void atlas__NodesFunctionSpace__max_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& maximum, + int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; This->maximum( field, maxvec ); size = maxvec.size(); + maximum = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) maximum[j] = maxvec[j]; ); +} + +void atlas__NodesFunctionSpace__minloc_double( const NodeColumns* This, const field::FieldImpl* field, double& minimum, + long& glb_idx ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + ATLAS_ERROR_HANDLING( This->minimumAndLocation( field, minimum, gidx ) ); + glb_idx = gidx; +} + +void atlas__NodesFunctionSpace__minloc_float( const NodeColumns* This, const field::FieldImpl* field, float& minimum, + long& glb_idx ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + ATLAS_ERROR_HANDLING( This->minimumAndLocation( field, minimum, gidx ) ); + glb_idx = gidx; +} + +void atlas__NodesFunctionSpace__minloc_long( const NodeColumns* This, const field::FieldImpl* field, long& minimum, + long& glb_idx ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + ATLAS_ERROR_HANDLING( This->minimumAndLocation( field, minimum, gidx ) ); + glb_idx = gidx; +} + +void atlas__NodesFunctionSpace__minloc_int( const NodeColumns* This, const field::FieldImpl* field, int& minimum, + long& glb_idx ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + ATLAS_ERROR_HANDLING( This->minimumAndLocation( field, minimum, gidx ) ); + glb_idx = gidx; +} + +void atlas__NodesFunctionSpace__maxloc_double( const NodeColumns* This, const field::FieldImpl* field, double& maximum, + long& glb_idx ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + ATLAS_ERROR_HANDLING( This->maximumAndLocation( field, maximum, gidx ) ); + glb_idx = gidx; +} + +void atlas__NodesFunctionSpace__maxloc_float( const NodeColumns* This, const field::FieldImpl* field, float& maximum, + long& glb_idx ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + ATLAS_ERROR_HANDLING( This->maximumAndLocation( field, maximum, gidx ) ); + glb_idx = gidx; +} + +void atlas__NodesFunctionSpace__maxloc_long( const NodeColumns* This, const field::FieldImpl* field, long& maximum, + long& glb_idx ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + ATLAS_ERROR_HANDLING( This->maximumAndLocation( field, maximum, gidx ) ); + glb_idx = gidx; +} + +void atlas__NodesFunctionSpace__maxloc_int( const NodeColumns* This, const field::FieldImpl* field, int& maximum, + long& glb_idx ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + ATLAS_ERROR_HANDLING( This->maximumAndLocation( field, maximum, gidx ) ); + glb_idx = gidx; +} + +void atlas__NodesFunctionSpace__minloc_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& minimum, long*& glb_idx, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; std::vector gidxvec; + This->minimumAndLocation( field, minvec, gidxvec ); size = minvec.size(); + minimum = new double[size]; glb_idx = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + minimum[j] = minvec[j]; + glb_idx[j] = gidxvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__minloc_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& minimum, long*& glb_idx, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; std::vector gidxvec; + This->minimumAndLocation( field, minvec, gidxvec ); size = minvec.size(); + minimum = new float[size]; glb_idx = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + minimum[j] = minvec[j]; + glb_idx[j] = gidxvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__minloc_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& minimum, + long*& glb_idx, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; std::vector gidxvec; + This->minimumAndLocation( field, minvec, gidxvec ); size = minvec.size(); + minimum = new long[size]; glb_idx = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + minimum[j] = minvec[j]; + glb_idx[j] = gidxvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__minloc_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& minimum, + long*& glb_idx, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; std::vector gidxvec; + This->minimumAndLocation( field, minvec, gidxvec ); size = minvec.size(); + minimum = new int[size]; glb_idx = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + minimum[j] = minvec[j]; + glb_idx[j] = gidxvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__maxloc_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& maximum, long*& glb_idx, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; std::vector gidxvec; + This->maximumAndLocation( field, maxvec, gidxvec ); size = maxvec.size(); + maximum = new double[size]; glb_idx = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + maximum[j] = maxvec[j]; + glb_idx[j] = gidxvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__maxloc_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& maximum, long*& glb_idx, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; std::vector gidxvec; + This->maximumAndLocation( field, maxvec, gidxvec ); size = maxvec.size(); + maximum = new float[size]; glb_idx = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + maximum[j] = maxvec[j]; + glb_idx[j] = gidxvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__maxloc_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& maximum, + long*& glb_idx, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; std::vector gidxvec; + This->maximumAndLocation( field, maxvec, gidxvec ); size = maxvec.size(); + maximum = new long[size]; glb_idx = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + maximum[j] = maxvec[j]; + glb_idx[j] = gidxvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__maxloc_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& maximum, + long*& glb_idx, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; std::vector gidxvec; + This->maximumAndLocation( field, maxvec, gidxvec ); size = maxvec.size(); + maximum = new int[size]; glb_idx = new long[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + maximum[j] = maxvec[j]; + glb_idx[j] = gidxvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__mean_double( const NodeColumns* This, const field::FieldImpl* field, double& mean, + int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->mean( field, mean, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__mean_float( const NodeColumns* This, const field::FieldImpl* field, float& mean, + int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->mean( field, mean, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__mean_long( const NodeColumns* This, const field::FieldImpl* field, long& mean, + int& N ) { + NOTIMP; +} + +void atlas__NodesFunctionSpace__mean_int( const NodeColumns* This, const field::FieldImpl* field, int& mean, int& N ) { + NOTIMP; +} + +void atlas__NodesFunctionSpace__mean_arr_double( const NodeColumns* This, const field::FieldImpl* field, double*& mean, + int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector meanvec; This->mean( field, meanvec, size_t_N ); size = meanvec.size(); + mean = new double[size]; for ( size_t j = 0; j < (size_t)size; ++j ) mean[j] = meanvec[j]; ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__mean_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& mean, + int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector meanvec; This->mean( field, meanvec, size_t_N ); size = meanvec.size(); + mean = new float[size]; for ( size_t j = 0; j < (size_t)size; ++j ) mean[j] = meanvec[j]; ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__mean_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& mean, + int& size, int& N ) { + NOTIMP; +} + +void atlas__NodesFunctionSpace__mean_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& mean, + int& size, int& N ) { + NOTIMP; +} + +void atlas__NodesFunctionSpace__mean_and_stddev_double( const NodeColumns* This, const field::FieldImpl* field, + double& mean, double& stddev, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->meanAndStandardDeviation( field, mean, stddev, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__mean_and_stddev_float( const NodeColumns* This, const field::FieldImpl* field, + float& mean, float& stddev, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( This->meanAndStandardDeviation( field, mean, stddev, size_t_N ) ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__mean_and_stddev_long( const NodeColumns* This, const field::FieldImpl* field, + long& mean, long& stddev, int& N ) { + NOTIMP; +} + +void atlas__NodesFunctionSpace__mean_and_stddev_int( const NodeColumns* This, const field::FieldImpl* field, int& mean, + int& stddev, int& N ) { + NOTIMP; +} + +void atlas__NodesFunctionSpace__mean_and_stddev_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& mean, double*& stddev, int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector meanvec; std::vector stddevvec; + This->meanAndStandardDeviation( field, meanvec, stddevvec, size_t_N ); size = meanvec.size(); + mean = new double[size]; stddev = new double[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + mean[j] = meanvec[j]; + stddev[j] = stddevvec[j]; + } ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__mean_and_stddev_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& mean, float*& stddev, int& size, int& N ) { + ASSERT( This ); + ASSERT( field ); + size_t size_t_N; + ATLAS_ERROR_HANDLING( std::vector meanvec; std::vector stddevvec; + This->meanAndStandardDeviation( field, meanvec, stddevvec, size_t_N ); size = meanvec.size(); + mean = new float[size]; stddev = new float[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + mean[j] = meanvec[j]; + stddev[j] = stddevvec[j]; + } ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__mean_and_stddev_arr_long( const NodeColumns* This, const field::FieldImpl* field, + long*& mean, long*& stddev, int& size, int& N ) { + NOTIMP; +} + +void atlas__NodesFunctionSpace__mean_and_stddev_arr_int( const NodeColumns* This, const field::FieldImpl* field, + int*& mean, int*& stddev, int& size, int& N ) { + NOTIMP; +} + +void atlas__NodesFunctionSpace__minloclev_double( const NodeColumns* This, const field::FieldImpl* field, + double& minimum, long& glb_idx, int& level ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + size_t lev; + ATLAS_ERROR_HANDLING( This->minimumAndLocation( field, minimum, gidx, lev ) ); + glb_idx = gidx; + level = lev; +} + +void atlas__NodesFunctionSpace__minloclev_float( const NodeColumns* This, const field::FieldImpl* field, float& minimum, + long& glb_idx, int& level ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + size_t lev; + ATLAS_ERROR_HANDLING( This->minimumAndLocation( field, minimum, gidx, lev ) ); + glb_idx = gidx; + level = lev; +} + +void atlas__NodesFunctionSpace__minloclev_long( const NodeColumns* This, const field::FieldImpl* field, long& minimum, + long& glb_idx, int& level ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + size_t lev; + ATLAS_ERROR_HANDLING( This->minimumAndLocation( field, minimum, gidx, lev ) ); + glb_idx = gidx; + level = lev; +} + +void atlas__NodesFunctionSpace__minloclev_int( const NodeColumns* This, const field::FieldImpl* field, int& minimum, + long& glb_idx, int& level ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + size_t lev; + ATLAS_ERROR_HANDLING( This->minimumAndLocation( field, minimum, gidx, lev ) ); + glb_idx = gidx; + level = lev; +} + +void atlas__NodesFunctionSpace__maxloclev_double( const NodeColumns* This, const field::FieldImpl* field, + double& maximum, long& glb_idx, int& level ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + size_t lev; + ATLAS_ERROR_HANDLING( This->maximumAndLocation( field, maximum, gidx, lev ) ); + glb_idx = gidx; + level = lev; +} + +void atlas__NodesFunctionSpace__maxloclev_float( const NodeColumns* This, const field::FieldImpl* field, float& maximum, + long& glb_idx, int& level ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + size_t lev; + ATLAS_ERROR_HANDLING( This->maximumAndLocation( field, maximum, gidx, lev ) ); + glb_idx = gidx; + level = lev; +} + +void atlas__NodesFunctionSpace__maxloclev_long( const NodeColumns* This, const field::FieldImpl* field, long& maximum, + long& glb_idx, int& level ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + size_t lev; + ATLAS_ERROR_HANDLING( This->maximumAndLocation( field, maximum, gidx, lev ) ); + glb_idx = gidx; + level = lev; +} + +void atlas__NodesFunctionSpace__maxloclev_int( const NodeColumns* This, const field::FieldImpl* field, int& maximum, + long& glb_idx, int& level ) { + ASSERT( This ); + ASSERT( field ); + gidx_t gidx; + size_t lev; + ATLAS_ERROR_HANDLING( This->maximumAndLocation( field, maximum, gidx, lev ) ); + glb_idx = gidx; + level = lev; +} + +void atlas__NodesFunctionSpace__minloclev_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& minimum, long*& glb_idx, int*& level, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; std::vector gidxvec; std::vector levvec; + This->minimumAndLocation( field, minvec, gidxvec, levvec ); size = minvec.size(); + minimum = new double[size]; glb_idx = new long[size]; level = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + minimum[j] = minvec[j]; + glb_idx[j] = gidxvec[j]; + level[j] = levvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__minloclev_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& minimum, long*& glb_idx, int*& level, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; std::vector gidxvec; std::vector levvec; + This->minimumAndLocation( field, minvec, gidxvec, levvec ); size = minvec.size(); + minimum = new float[size]; glb_idx = new long[size]; level = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + minimum[j] = minvec[j]; + glb_idx[j] = gidxvec[j]; + level[j] = levvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__minloclev_arr_long( const NodeColumns* This, const field::FieldImpl* field, + long*& minimum, long*& glb_idx, int*& level, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; std::vector gidxvec; std::vector levvec; + This->minimumAndLocation( field, minvec, gidxvec, levvec ); size = minvec.size(); + minimum = new long[size]; glb_idx = new long[size]; level = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + minimum[j] = minvec[j]; + glb_idx[j] = gidxvec[j]; + level[j] = levvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__minloclev_arr_int( const NodeColumns* This, const field::FieldImpl* field, + int*& minimum, long*& glb_idx, int*& level, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector minvec; std::vector gidxvec; std::vector levvec; + This->minimumAndLocation( field, minvec, gidxvec, levvec ); size = minvec.size(); + minimum = new int[size]; glb_idx = new long[size]; level = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + minimum[j] = minvec[j]; + glb_idx[j] = gidxvec[j]; + level[j] = levvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__maxloclev_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& maximum, long*& glb_idx, int*& level, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; std::vector gidxvec; std::vector levvec; + This->maximumAndLocation( field, maxvec, gidxvec, levvec ); size = maxvec.size(); + maximum = new double[size]; glb_idx = new long[size]; level = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + maximum[j] = maxvec[j]; + glb_idx[j] = gidxvec[j]; + level[j] = levvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__maxloclev_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& maximum, long*& glb_idx, int*& level, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; std::vector gidxvec; std::vector levvec; + This->maximumAndLocation( field, maxvec, gidxvec, levvec ); size = maxvec.size(); + maximum = new float[size]; glb_idx = new long[size]; level = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + maximum[j] = maxvec[j]; + glb_idx[j] = gidxvec[j]; + level[j] = levvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__maxloclev_arr_long( const NodeColumns* This, const field::FieldImpl* field, + long*& maximum, long*& glb_idx, int*& level, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; std::vector gidxvec; std::vector levvec; + This->maximumAndLocation( field, maxvec, gidxvec, levvec ); size = maxvec.size(); + maximum = new long[size]; glb_idx = new long[size]; level = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + maximum[j] = maxvec[j]; + glb_idx[j] = gidxvec[j]; + level[j] = levvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__maxloclev_arr_int( const NodeColumns* This, const field::FieldImpl* field, + int*& maximum, long*& glb_idx, int*& level, int& size ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::vector maxvec; std::vector gidxvec; std::vector levvec; + This->maximumAndLocation( field, maxvec, gidxvec, levvec ); size = maxvec.size(); + maximum = new int[size]; glb_idx = new long[size]; level = new int[size]; + for ( size_t j = 0; j < (size_t)size; ++j ) { + maximum[j] = maxvec[j]; + glb_idx[j] = gidxvec[j]; + level[j] = levvec[j]; + } ); +} + +void atlas__NodesFunctionSpace__sum_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* column, int& N ) { + ASSERT( This ); + ASSERT( field ); + ASSERT( column ); + size_t size_t_N; + Field sum( column ); + ATLAS_ERROR_HANDLING( This->sumPerLevel( field, sum, size_t_N ); ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__oisum_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* column, int& N ) { + ASSERT( This ); + ASSERT( field ); + ASSERT( column ); + size_t size_t_N; + Field sum( column ); + ATLAS_ERROR_HANDLING( This->orderIndependentSumPerLevel( field, sum, size_t_N ); ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__min_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* min ) { + ASSERT( This ); + ASSERT( field ); + ASSERT( min ); + Field fmin( min ); + ATLAS_ERROR_HANDLING( This->minimumPerLevel( field, fmin ); ); +} + +void atlas__NodesFunctionSpace__max_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* max ) { + ASSERT( This ); + ASSERT( field ); + ASSERT( max ); + Field fmax( max ); + ATLAS_ERROR_HANDLING( This->maximumPerLevel( field, fmax ); ); +} + +void atlas__NodesFunctionSpace__minloc_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* min, field::FieldImpl* glb_idx ) { + ASSERT( This ); + ASSERT( field ); + ASSERT( min ); + ASSERT( glb_idx ); + Field fmin( min ); + Field fglb_idx( glb_idx ); + ATLAS_ERROR_HANDLING( This->minimumAndLocationPerLevel( field, fmin, fglb_idx ); ); +} + +void atlas__NodesFunctionSpace__maxloc_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* max, field::FieldImpl* glb_idx ) { + ASSERT( This ); + ASSERT( field ); + ASSERT( max ); + ASSERT( glb_idx ); + Field fmax( max ); + Field fglb_idx( glb_idx ); + ATLAS_ERROR_HANDLING( This->maximumAndLocationPerLevel( field, fmax, fglb_idx ); ); +} + +void atlas__NodesFunctionSpace__mean_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* mean, int& N ) { + ASSERT( This ); + ASSERT( field ); + ASSERT( mean ); + size_t size_t_N; + Field fmean( mean ); + ATLAS_ERROR_HANDLING( This->meanPerLevel( field, fmean, size_t_N ); ); + N = size_t_N; +} + +void atlas__NodesFunctionSpace__mean_and_stddev_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* mean, field::FieldImpl* stddev, int& N ) { + ASSERT( This ); + ASSERT( field ); + ASSERT( mean ); + ASSERT( stddev ); + size_t size_t_N; + Field fmean( mean ); + Field fstddev( stddev ); + ATLAS_ERROR_HANDLING( This->meanAndStandardDeviationPerLevel( field, fmean, fstddev, size_t_N ); ); + N = size_t_N; +} +} + +} // namespace detail +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/NodeColumnsInterface.h b/src/atlas/functionspace/NodeColumnsInterface.h index 0715a4a55..a137ef105 100644 --- a/src/atlas/functionspace/NodeColumnsInterface.h +++ b/src/atlas/functionspace/NodeColumnsInterface.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,143 +14,223 @@ #include "atlas/functionspace/NodeColumns.h" #include "atlas/mesh/Mesh.h" -namespace atlas { namespace field { class FieldSetImpl; } } +namespace atlas { +namespace field { +class FieldSetImpl; +} +} // namespace atlas namespace atlas { namespace functionspace { namespace detail { extern "C" { -const NodeColumns* atlas__NodesFunctionSpace__new (Mesh::Implementation* mesh, const eckit::Configuration* config ); -void atlas__NodesFunctionSpace__delete (NodeColumns* This); -int atlas__NodesFunctionSpace__nb_nodes(const NodeColumns* This); -const Mesh::Implementation* atlas__NodesFunctionSpace__mesh(const NodeColumns* This); -mesh::Nodes* atlas__NodesFunctionSpace__nodes(const NodeColumns* This); -field::FieldImpl* atlas__NodesFunctionSpace__create_field (const NodeColumns* This, const eckit::Configuration* options); -field::FieldImpl* atlas__NodesFunctionSpace__create_field_template (const NodeColumns* This, const field::FieldImpl* field_template, const eckit::Configuration* options); - -void atlas__NodesFunctionSpace__halo_exchange_fieldset(const NodeColumns* This, field::FieldSetImpl* fieldset); -void atlas__NodesFunctionSpace__halo_exchange_field(const NodeColumns* This, field::FieldImpl* field); -const parallel::HaloExchange* atlas__NodesFunctionSpace__get_halo_exchange(const NodeColumns* This); - -void atlas__NodesFunctionSpace__gather_fieldset(const NodeColumns* This, const field::FieldSetImpl* local, field::FieldSetImpl* global); -void atlas__NodesFunctionSpace__gather_field(const NodeColumns* This, const field::FieldImpl* local, field::FieldImpl* global); -const parallel::GatherScatter* atlas__NodesFunctionSpace__get_gather(const NodeColumns* This); - -void atlas__NodesFunctionSpace__scatter_fieldset(const NodeColumns* This, const field::FieldSetImpl* global, field::FieldSetImpl* local); -void atlas__NodesFunctionSpace__scatter_field(const NodeColumns* This, const field::FieldImpl* global, field::FieldImpl* local); -const parallel::GatherScatter* atlas__NodesFunctionSpace__get_scatter(const NodeColumns* This); - -void atlas__NodesFunctionSpace__checksum_fieldset(const NodeColumns* This, const field::FieldSetImpl* fieldset, char* &checksum, int &size, int &allocated); -void atlas__NodesFunctionSpace__checksum_field(const NodeColumns* This, const field::FieldImpl* field, char* &checksum, int &size, int &allocated); -const parallel::Checksum* atlas__NodesFunctionSpace__get_checksum(const NodeColumns* This); - -void atlas__NodesFunctionSpace__sum_double(const NodeColumns* This, const field::FieldImpl* field, double &sum, int &N); -void atlas__NodesFunctionSpace__sum_float(const NodeColumns* This, const field::FieldImpl* field, float &sum, int &N); -void atlas__NodesFunctionSpace__sum_int(const NodeColumns* This, const field::FieldImpl* field, int &sum, int &N); -void atlas__NodesFunctionSpace__sum_long(const NodeColumns* This, const field::FieldImpl* field, long &sum, int &N); -void atlas__NodesFunctionSpace__sum_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &sum, int &size, int &N); -void atlas__NodesFunctionSpace__sum_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &sum, int &size, int &N); -void atlas__NodesFunctionSpace__sum_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &sum, int &size, int &N); -void atlas__NodesFunctionSpace__sum_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &sum, int &size, int &N); - -void atlas__NodesFunctionSpace__oisum_double(const NodeColumns* This, const field::FieldImpl* field, double &sum, int &N); -void atlas__NodesFunctionSpace__oisum_float(const NodeColumns* This, const field::FieldImpl* field, float &sum, int &N); -void atlas__NodesFunctionSpace__oisum_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &sum, int &size, int &N); -void atlas__NodesFunctionSpace__oisum_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &sum, int &size, int &N); - -void atlas__NodesFunctionSpace__min_double(const NodeColumns* This, const field::FieldImpl* field, double &minimum); -void atlas__NodesFunctionSpace__min_float(const NodeColumns* This, const field::FieldImpl* field, float &minimum); -void atlas__NodesFunctionSpace__min_int(const NodeColumns* This, const field::FieldImpl* field, int &minimum); -void atlas__NodesFunctionSpace__min_long(const NodeColumns* This, const field::FieldImpl* field, long &minimum); - -void atlas__NodesFunctionSpace__max_double(const NodeColumns* This, const field::FieldImpl* field, double &maximum); -void atlas__NodesFunctionSpace__max_float(const NodeColumns* This, const field::FieldImpl* field, float &maximum); -void atlas__NodesFunctionSpace__max_int(const NodeColumns* This, const field::FieldImpl* field, int &maximum); -void atlas__NodesFunctionSpace__max_long(const NodeColumns* This, const field::FieldImpl* field, long &maximum); - -void atlas__NodesFunctionSpace__min_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &minimum, int &size); -void atlas__NodesFunctionSpace__min_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &minimum, int &size); -void atlas__NodesFunctionSpace__min_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &minimum, int &size); -void atlas__NodesFunctionSpace__min_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &minimum, int &size); - -void atlas__NodesFunctionSpace__max_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &maximum, int &size); -void atlas__NodesFunctionSpace__max_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &maximum, int &size); -void atlas__NodesFunctionSpace__max_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &maximum, int &size); -void atlas__NodesFunctionSpace__max_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &maximum, int &size); - -void atlas__NodesFunctionSpace__minloc_double(const NodeColumns* This, const field::FieldImpl* field, double &minimum, long &glb_idx); -void atlas__NodesFunctionSpace__minloc_float(const NodeColumns* This, const field::FieldImpl* field, float &minimum, long &glb_idx); -void atlas__NodesFunctionSpace__minloc_int(const NodeColumns* This, const field::FieldImpl* field, int &minimum, long &glb_idx); -void atlas__NodesFunctionSpace__minloc_long(const NodeColumns* This, const field::FieldImpl* field, long &minimum, long &glb_idx); - -void atlas__NodesFunctionSpace__maxloc_double(const NodeColumns* This, const field::FieldImpl* field, double &maximum, long &glb_idx); -void atlas__NodesFunctionSpace__maxloc_float(const NodeColumns* This, const field::FieldImpl* field, float &maximum, long &glb_idx); -void atlas__NodesFunctionSpace__maxloc_int(const NodeColumns* This, const field::FieldImpl* field, int &maximum, long &glb_idx); -void atlas__NodesFunctionSpace__maxloc_long(const NodeColumns* This, const field::FieldImpl* field, long &maximum, long &glb_idx); - -void atlas__NodesFunctionSpace__minloc_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &minimum, long* &glb_idx, int &size); -void atlas__NodesFunctionSpace__minloc_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &minimum, long* &glb_idx, int &size); -void atlas__NodesFunctionSpace__minloc_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &minimum, long* &glb_idx, int &size); -void atlas__NodesFunctionSpace__minloc_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &minimum, long* &glb_idx, int &size); - -void atlas__NodesFunctionSpace__maxloc_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &maximum, long* &glb_idx, int &size); -void atlas__NodesFunctionSpace__maxloc_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &maximum, long* &glb_idx, int &size); -void atlas__NodesFunctionSpace__maxloc_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &maximum, long* &glb_idx, int &size); -void atlas__NodesFunctionSpace__maxloc_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &maximum, long* &glb_idx, int &size); - -void atlas__NodesFunctionSpace__mean_double(const NodeColumns* This, const field::FieldImpl* field, double &mean, int &N); -void atlas__NodesFunctionSpace__mean_float(const NodeColumns* This, const field::FieldImpl* field, float &mean, int &N); -void atlas__NodesFunctionSpace__mean_int(const NodeColumns* This, const field::FieldImpl* field, int &mean, int &N); -void atlas__NodesFunctionSpace__mean_long(const NodeColumns* This, const field::FieldImpl* field, long &mean, int &N); -void atlas__NodesFunctionSpace__mean_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &mean, int &size, int &N); -void atlas__NodesFunctionSpace__mean_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &mean, int &size, int &N); -void atlas__NodesFunctionSpace__mean_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &mean, int &size, int &N); -void atlas__NodesFunctionSpace__mean_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &mean, int &size, int &N); - -void atlas__NodesFunctionSpace__mean_and_stddev_double(const NodeColumns* This, const field::FieldImpl* field, double &mean, double &stddev, int &N); -void atlas__NodesFunctionSpace__mean_and_stddev_float(const NodeColumns* This, const field::FieldImpl* field, float &mean, float &stddev, int &N); -void atlas__NodesFunctionSpace__mean_and_stddev_int(const NodeColumns* This, const field::FieldImpl* field, int &mean, int &stddev, int &N); -void atlas__NodesFunctionSpace__mean_and_stddev_long(const NodeColumns* This, const field::FieldImpl* field, long &mean, long &stddev, int &N); -void atlas__NodesFunctionSpace__mean_and_stddev_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &mean, double* &stddev, int &size, int &N); -void atlas__NodesFunctionSpace__mean_and_stddev_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &mean, float* &stddev, int &size, int &N); -void atlas__NodesFunctionSpace__mean_and_stddev_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &mean, int* &stddev, int &size, int &N); -void atlas__NodesFunctionSpace__mean_and_stddev_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &mean, long* &stddev, int &size, int &N); - - -void atlas__NodesFunctionSpace__minloclev_double(const NodeColumns* This, const field::FieldImpl* field, double &minimum, long &glb_idx, int &level); -void atlas__NodesFunctionSpace__minloclev_float(const NodeColumns* This, const field::FieldImpl* field, float &minimum, long &glb_idx, int &level); -void atlas__NodesFunctionSpace__minloclev_int(const NodeColumns* This, const field::FieldImpl* field, int &minimum, long &glb_idx, int &level); -void atlas__NodesFunctionSpace__minloclev_long(const NodeColumns* This, const field::FieldImpl* field, long &minimum, long &glb_idx, int &level); - -void atlas__NodesFunctionSpace__maxloclev_double(const NodeColumns* This, const field::FieldImpl* field, double &maximum, long &glb_idx, int &level); -void atlas__NodesFunctionSpace__maxloclev_float(const NodeColumns* This, const field::FieldImpl* field, float &maximum, long &glb_idx, int &level); -void atlas__NodesFunctionSpace__maxloclev_int(const NodeColumns* This, const field::FieldImpl* field, int &maximum, long &glb_idx, int &level); -void atlas__NodesFunctionSpace__maxloclev_long(const NodeColumns* This, const field::FieldImpl* field, long &maximum, long &glb_idx, int &level); - -void atlas__NodesFunctionSpace__minloclev_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &minimum, long* &glb_idx, int* &level, int &size); -void atlas__NodesFunctionSpace__minloclev_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &minimum, long* &glb_idx, int* &level, int &size); -void atlas__NodesFunctionSpace__minloclev_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &minimum, long* &glb_idx, int* &level, int &size); -void atlas__NodesFunctionSpace__minloclev_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &minimum, long* &glb_idx, int* &level, int &size); - -void atlas__NodesFunctionSpace__maxloclev_arr_double(const NodeColumns* This, const field::FieldImpl* field, double* &maximum, long* &glb_idx, int* &level, int &size); -void atlas__NodesFunctionSpace__maxloclev_arr_float(const NodeColumns* This, const field::FieldImpl* field, float* &maximum, long* &glb_idx, int* &level, int &size); -void atlas__NodesFunctionSpace__maxloclev_arr_int(const NodeColumns* This, const field::FieldImpl* field, int* &maximum, long* &glb_idx, int* &level, int &size); -void atlas__NodesFunctionSpace__maxloclev_arr_long(const NodeColumns* This, const field::FieldImpl* field, long* &maximum, long* &glb_idx, int* &level, int &size); - -void atlas__NodesFunctionSpace__sum_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* sum, int &N); -void atlas__NodesFunctionSpace__oisum_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* sum, int &N); -void atlas__NodesFunctionSpace__min_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* min); -void atlas__NodesFunctionSpace__max_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* max); -void atlas__NodesFunctionSpace__minloc_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* min, field::FieldImpl* glb_idx); -void atlas__NodesFunctionSpace__maxloc_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* max, field::FieldImpl* glb_idx); -void atlas__NodesFunctionSpace__mean_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* mean, int &N); -void atlas__NodesFunctionSpace__mean_and_stddev_per_level(const NodeColumns* This, const field::FieldImpl* field, field::FieldImpl* mean, field::FieldImpl* stddev, int &N); - - - +const NodeColumns* atlas__NodesFunctionSpace__new( Mesh::Implementation* mesh, const eckit::Configuration* config ); +void atlas__NodesFunctionSpace__delete( NodeColumns* This ); +int atlas__NodesFunctionSpace__nb_nodes( const NodeColumns* This ); +const Mesh::Implementation* atlas__NodesFunctionSpace__mesh( const NodeColumns* This ); +mesh::Nodes* atlas__NodesFunctionSpace__nodes( const NodeColumns* This ); +field::FieldImpl* atlas__NodesFunctionSpace__create_field( const NodeColumns* This, + const eckit::Configuration* options ); +field::FieldImpl* atlas__NodesFunctionSpace__create_field_template( const NodeColumns* This, + const field::FieldImpl* field_template, + const eckit::Configuration* options ); + +void atlas__NodesFunctionSpace__halo_exchange_fieldset( const NodeColumns* This, field::FieldSetImpl* fieldset ); +void atlas__NodesFunctionSpace__halo_exchange_field( const NodeColumns* This, field::FieldImpl* field ); +const parallel::HaloExchange* atlas__NodesFunctionSpace__get_halo_exchange( const NodeColumns* This ); + +void atlas__NodesFunctionSpace__gather_fieldset( const NodeColumns* This, const field::FieldSetImpl* local, + field::FieldSetImpl* global ); +void atlas__NodesFunctionSpace__gather_field( const NodeColumns* This, const field::FieldImpl* local, + field::FieldImpl* global ); +const parallel::GatherScatter* atlas__NodesFunctionSpace__get_gather( const NodeColumns* This ); + +void atlas__NodesFunctionSpace__scatter_fieldset( const NodeColumns* This, const field::FieldSetImpl* global, + field::FieldSetImpl* local ); +void atlas__NodesFunctionSpace__scatter_field( const NodeColumns* This, const field::FieldImpl* global, + field::FieldImpl* local ); +const parallel::GatherScatter* atlas__NodesFunctionSpace__get_scatter( const NodeColumns* This ); + +void atlas__NodesFunctionSpace__checksum_fieldset( const NodeColumns* This, const field::FieldSetImpl* fieldset, + char*& checksum, int& size, int& allocated ); +void atlas__NodesFunctionSpace__checksum_field( const NodeColumns* This, const field::FieldImpl* field, char*& checksum, + int& size, int& allocated ); +const parallel::Checksum* atlas__NodesFunctionSpace__get_checksum( const NodeColumns* This ); + +void atlas__NodesFunctionSpace__sum_double( const NodeColumns* This, const field::FieldImpl* field, double& sum, + int& N ); +void atlas__NodesFunctionSpace__sum_float( const NodeColumns* This, const field::FieldImpl* field, float& sum, int& N ); +void atlas__NodesFunctionSpace__sum_int( const NodeColumns* This, const field::FieldImpl* field, int& sum, int& N ); +void atlas__NodesFunctionSpace__sum_long( const NodeColumns* This, const field::FieldImpl* field, long& sum, int& N ); +void atlas__NodesFunctionSpace__sum_arr_double( const NodeColumns* This, const field::FieldImpl* field, double*& sum, + int& size, int& N ); +void atlas__NodesFunctionSpace__sum_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& sum, + int& size, int& N ); +void atlas__NodesFunctionSpace__sum_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& sum, + int& size, int& N ); +void atlas__NodesFunctionSpace__sum_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& sum, + int& size, int& N ); + +void atlas__NodesFunctionSpace__oisum_double( const NodeColumns* This, const field::FieldImpl* field, double& sum, + int& N ); +void atlas__NodesFunctionSpace__oisum_float( const NodeColumns* This, const field::FieldImpl* field, float& sum, + int& N ); +void atlas__NodesFunctionSpace__oisum_arr_double( const NodeColumns* This, const field::FieldImpl* field, double*& sum, + int& size, int& N ); +void atlas__NodesFunctionSpace__oisum_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& sum, + int& size, int& N ); + +void atlas__NodesFunctionSpace__min_double( const NodeColumns* This, const field::FieldImpl* field, double& minimum ); +void atlas__NodesFunctionSpace__min_float( const NodeColumns* This, const field::FieldImpl* field, float& minimum ); +void atlas__NodesFunctionSpace__min_int( const NodeColumns* This, const field::FieldImpl* field, int& minimum ); +void atlas__NodesFunctionSpace__min_long( const NodeColumns* This, const field::FieldImpl* field, long& minimum ); + +void atlas__NodesFunctionSpace__max_double( const NodeColumns* This, const field::FieldImpl* field, double& maximum ); +void atlas__NodesFunctionSpace__max_float( const NodeColumns* This, const field::FieldImpl* field, float& maximum ); +void atlas__NodesFunctionSpace__max_int( const NodeColumns* This, const field::FieldImpl* field, int& maximum ); +void atlas__NodesFunctionSpace__max_long( const NodeColumns* This, const field::FieldImpl* field, long& maximum ); + +void atlas__NodesFunctionSpace__min_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& minimum, int& size ); +void atlas__NodesFunctionSpace__min_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& minimum, + int& size ); +void atlas__NodesFunctionSpace__min_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& minimum, + int& size ); +void atlas__NodesFunctionSpace__min_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& minimum, + int& size ); + +void atlas__NodesFunctionSpace__max_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& maximum, int& size ); +void atlas__NodesFunctionSpace__max_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& maximum, + int& size ); +void atlas__NodesFunctionSpace__max_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& maximum, + int& size ); +void atlas__NodesFunctionSpace__max_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& maximum, + int& size ); + +void atlas__NodesFunctionSpace__minloc_double( const NodeColumns* This, const field::FieldImpl* field, double& minimum, + long& glb_idx ); +void atlas__NodesFunctionSpace__minloc_float( const NodeColumns* This, const field::FieldImpl* field, float& minimum, + long& glb_idx ); +void atlas__NodesFunctionSpace__minloc_int( const NodeColumns* This, const field::FieldImpl* field, int& minimum, + long& glb_idx ); +void atlas__NodesFunctionSpace__minloc_long( const NodeColumns* This, const field::FieldImpl* field, long& minimum, + long& glb_idx ); + +void atlas__NodesFunctionSpace__maxloc_double( const NodeColumns* This, const field::FieldImpl* field, double& maximum, + long& glb_idx ); +void atlas__NodesFunctionSpace__maxloc_float( const NodeColumns* This, const field::FieldImpl* field, float& maximum, + long& glb_idx ); +void atlas__NodesFunctionSpace__maxloc_int( const NodeColumns* This, const field::FieldImpl* field, int& maximum, + long& glb_idx ); +void atlas__NodesFunctionSpace__maxloc_long( const NodeColumns* This, const field::FieldImpl* field, long& maximum, + long& glb_idx ); + +void atlas__NodesFunctionSpace__minloc_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& minimum, long*& glb_idx, int& size ); +void atlas__NodesFunctionSpace__minloc_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& minimum, long*& glb_idx, int& size ); +void atlas__NodesFunctionSpace__minloc_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& minimum, + long*& glb_idx, int& size ); +void atlas__NodesFunctionSpace__minloc_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& minimum, + long*& glb_idx, int& size ); + +void atlas__NodesFunctionSpace__maxloc_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& maximum, long*& glb_idx, int& size ); +void atlas__NodesFunctionSpace__maxloc_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& maximum, long*& glb_idx, int& size ); +void atlas__NodesFunctionSpace__maxloc_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& maximum, + long*& glb_idx, int& size ); +void atlas__NodesFunctionSpace__maxloc_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& maximum, + long*& glb_idx, int& size ); + +void atlas__NodesFunctionSpace__mean_double( const NodeColumns* This, const field::FieldImpl* field, double& mean, + int& N ); +void atlas__NodesFunctionSpace__mean_float( const NodeColumns* This, const field::FieldImpl* field, float& mean, + int& N ); +void atlas__NodesFunctionSpace__mean_int( const NodeColumns* This, const field::FieldImpl* field, int& mean, int& N ); +void atlas__NodesFunctionSpace__mean_long( const NodeColumns* This, const field::FieldImpl* field, long& mean, int& N ); +void atlas__NodesFunctionSpace__mean_arr_double( const NodeColumns* This, const field::FieldImpl* field, double*& mean, + int& size, int& N ); +void atlas__NodesFunctionSpace__mean_arr_float( const NodeColumns* This, const field::FieldImpl* field, float*& mean, + int& size, int& N ); +void atlas__NodesFunctionSpace__mean_arr_int( const NodeColumns* This, const field::FieldImpl* field, int*& mean, + int& size, int& N ); +void atlas__NodesFunctionSpace__mean_arr_long( const NodeColumns* This, const field::FieldImpl* field, long*& mean, + int& size, int& N ); + +void atlas__NodesFunctionSpace__mean_and_stddev_double( const NodeColumns* This, const field::FieldImpl* field, + double& mean, double& stddev, int& N ); +void atlas__NodesFunctionSpace__mean_and_stddev_float( const NodeColumns* This, const field::FieldImpl* field, + float& mean, float& stddev, int& N ); +void atlas__NodesFunctionSpace__mean_and_stddev_int( const NodeColumns* This, const field::FieldImpl* field, int& mean, + int& stddev, int& N ); +void atlas__NodesFunctionSpace__mean_and_stddev_long( const NodeColumns* This, const field::FieldImpl* field, + long& mean, long& stddev, int& N ); +void atlas__NodesFunctionSpace__mean_and_stddev_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& mean, double*& stddev, int& size, int& N ); +void atlas__NodesFunctionSpace__mean_and_stddev_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& mean, float*& stddev, int& size, int& N ); +void atlas__NodesFunctionSpace__mean_and_stddev_arr_int( const NodeColumns* This, const field::FieldImpl* field, + int*& mean, int*& stddev, int& size, int& N ); +void atlas__NodesFunctionSpace__mean_and_stddev_arr_long( const NodeColumns* This, const field::FieldImpl* field, + long*& mean, long*& stddev, int& size, int& N ); + +void atlas__NodesFunctionSpace__minloclev_double( const NodeColumns* This, const field::FieldImpl* field, + double& minimum, long& glb_idx, int& level ); +void atlas__NodesFunctionSpace__minloclev_float( const NodeColumns* This, const field::FieldImpl* field, float& minimum, + long& glb_idx, int& level ); +void atlas__NodesFunctionSpace__minloclev_int( const NodeColumns* This, const field::FieldImpl* field, int& minimum, + long& glb_idx, int& level ); +void atlas__NodesFunctionSpace__minloclev_long( const NodeColumns* This, const field::FieldImpl* field, long& minimum, + long& glb_idx, int& level ); + +void atlas__NodesFunctionSpace__maxloclev_double( const NodeColumns* This, const field::FieldImpl* field, + double& maximum, long& glb_idx, int& level ); +void atlas__NodesFunctionSpace__maxloclev_float( const NodeColumns* This, const field::FieldImpl* field, float& maximum, + long& glb_idx, int& level ); +void atlas__NodesFunctionSpace__maxloclev_int( const NodeColumns* This, const field::FieldImpl* field, int& maximum, + long& glb_idx, int& level ); +void atlas__NodesFunctionSpace__maxloclev_long( const NodeColumns* This, const field::FieldImpl* field, long& maximum, + long& glb_idx, int& level ); + +void atlas__NodesFunctionSpace__minloclev_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& minimum, long*& glb_idx, int*& level, int& size ); +void atlas__NodesFunctionSpace__minloclev_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& minimum, long*& glb_idx, int*& level, int& size ); +void atlas__NodesFunctionSpace__minloclev_arr_int( const NodeColumns* This, const field::FieldImpl* field, + int*& minimum, long*& glb_idx, int*& level, int& size ); +void atlas__NodesFunctionSpace__minloclev_arr_long( const NodeColumns* This, const field::FieldImpl* field, + long*& minimum, long*& glb_idx, int*& level, int& size ); + +void atlas__NodesFunctionSpace__maxloclev_arr_double( const NodeColumns* This, const field::FieldImpl* field, + double*& maximum, long*& glb_idx, int*& level, int& size ); +void atlas__NodesFunctionSpace__maxloclev_arr_float( const NodeColumns* This, const field::FieldImpl* field, + float*& maximum, long*& glb_idx, int*& level, int& size ); +void atlas__NodesFunctionSpace__maxloclev_arr_int( const NodeColumns* This, const field::FieldImpl* field, + int*& maximum, long*& glb_idx, int*& level, int& size ); +void atlas__NodesFunctionSpace__maxloclev_arr_long( const NodeColumns* This, const field::FieldImpl* field, + long*& maximum, long*& glb_idx, int*& level, int& size ); + +void atlas__NodesFunctionSpace__sum_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* sum, int& N ); +void atlas__NodesFunctionSpace__oisum_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* sum, int& N ); +void atlas__NodesFunctionSpace__min_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* min ); +void atlas__NodesFunctionSpace__max_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* max ); +void atlas__NodesFunctionSpace__minloc_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* min, field::FieldImpl* glb_idx ); +void atlas__NodesFunctionSpace__maxloc_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* max, field::FieldImpl* glb_idx ); +void atlas__NodesFunctionSpace__mean_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* mean, int& N ); +void atlas__NodesFunctionSpace__mean_and_stddev_per_level( const NodeColumns* This, const field::FieldImpl* field, + field::FieldImpl* mean, field::FieldImpl* stddev, int& N ); } -} // namespace detail -} // namespace functionspace -} // namespace atlas +} // namespace detail +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/PointCloud.cc b/src/atlas/functionspace/PointCloud.cc index 2e34badc3..a2c28e2a6 100644 --- a/src/atlas/functionspace/PointCloud.cc +++ b/src/atlas/functionspace/PointCloud.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,68 +17,53 @@ namespace functionspace { namespace detail { -PointCloud::PointCloud(const std::vector& points) { - lonlat_ = Field("lonlat", array::make_datatype(), array::make_shape(points.size(),2)); - auto lonlat = array::make_view(lonlat_); - for( size_t j=0; j& points ) { + lonlat_ = Field( "lonlat", array::make_datatype(), array::make_shape( points.size(), 2 ) ); + auto lonlat = array::make_view( lonlat_ ); + for ( size_t j = 0; j < points.size(); ++j ) { + lonlat( j, 0 ) = points[j].x(); + lonlat( j, 1 ) = points[j].y(); + } } -PointCloud::PointCloud(const Field& lonlat) : - lonlat_(lonlat) { -} +PointCloud::PointCloud( const Field& lonlat ) : lonlat_( lonlat ) {} -PointCloud::PointCloud(const Field& lonlat, const Field& ghost) : - lonlat_(lonlat), - ghost_(ghost) { -} +PointCloud::PointCloud( const Field& lonlat, const Field& ghost ) : lonlat_( lonlat ), ghost_( ghost ) {} const Field& PointCloud::ghost() const { - if (not ghost_) { - ghost_ = Field( "ghost", array::make_datatype(), array::make_shape(size()) ); - array::make_view(ghost_).assign(0); - } - return ghost_; + if ( not ghost_ ) { + ghost_ = Field( "ghost", array::make_datatype(), array::make_shape( size() ) ); + array::make_view( ghost_ ).assign( 0 ); + } + return ghost_; } - -Field PointCloud::createField(const eckit::Configuration& options) const { - NOTIMP; - return Field(); +Field PointCloud::createField( const eckit::Configuration& options ) const { + NOTIMP; + return Field(); } -Field PointCloud::createField( - const Field& other, - const eckit::Configuration& config ) const -{ - return createField( - option::datatype ( other.datatype() ) | - config ); +Field PointCloud::createField( const Field& other, const eckit::Configuration& config ) const { + return createField( option::datatype( other.datatype() ) | config ); } std::string PointCloud::distribution() const { - return std::string("serial"); + return std::string( "serial" ); } -} +} // namespace detail PointCloud::PointCloud( const FunctionSpace& functionspace ) : - FunctionSpace(functionspace), - functionspace_( dynamic_cast< const detail::PointCloud* >( get() ) ) { -} + FunctionSpace( functionspace ), + functionspace_( dynamic_cast( get() ) ) {} PointCloud::PointCloud( const Field& points ) : - FunctionSpace( new detail::PointCloud(points) ), - functionspace_( dynamic_cast< const detail::PointCloud* >( get() ) ) { -} + FunctionSpace( new detail::PointCloud( points ) ), + functionspace_( dynamic_cast( get() ) ) {} PointCloud::PointCloud( const std::vector& points ) : - FunctionSpace( new detail::PointCloud(points) ), - functionspace_( dynamic_cast< const detail::PointCloud* >( get() ) ) { -} - + FunctionSpace( new detail::PointCloud( points ) ), + functionspace_( dynamic_cast( get() ) ) {} -} -} +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/PointCloud.h b/src/atlas/functionspace/PointCloud.h index 993061133..680a3f799 100644 --- a/src/atlas/functionspace/PointCloud.h +++ b/src/atlas/functionspace/PointCloud.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -21,54 +22,50 @@ namespace functionspace { namespace detail { -class PointCloud : public FunctionSpaceImpl -{ +class PointCloud : public FunctionSpaceImpl { public: - PointCloud(const std::vector&); - PointCloud(const Field& lonlat); - PointCloud(const Field& lonlat, const Field& ghost); + PointCloud( const std::vector& ); + PointCloud( const Field& lonlat ); + PointCloud( const Field& lonlat, const Field& ghost ); virtual ~PointCloud() {} virtual std::string type() const { return "PointCloud"; } virtual operator bool() const { return true; } - virtual size_t footprint() const { return sizeof(*this); } + virtual size_t footprint() const { return sizeof( *this ); } virtual std::string distribution() const; const Field& lonlat() const { return lonlat_; } const Field& ghost() const; - size_t size() const { return lonlat_.shape(0); } + size_t size() const { return lonlat_.shape( 0 ); } /// @brief Create a spectral field using FunctionSpaceImpl::createField; virtual Field createField( const eckit::Configuration& ) const; virtual Field createField( const Field&, const eckit::Configuration& ) const; - private: - +private: Field lonlat_; mutable Field ghost_; }; -} // namespace datail +} // namespace detail //------------------------------------------------------------------------------------------------------ class PointCloud : public FunctionSpace { public: + PointCloud( const FunctionSpace& ); + PointCloud( const Field& points ); + PointCloud( const std::vector& ); - PointCloud( const FunctionSpace& ); - PointCloud( const Field& points ); - PointCloud( const std::vector& ); + operator bool() const { return valid(); } + bool valid() const { return functionspace_; } - operator bool() const { return valid(); } - bool valid() const { return functionspace_; } - - const Field& lonlat() const { return functionspace_->lonlat(); } - const Field& ghost() const { return functionspace_->ghost(); } - size_t size() const { return functionspace_->size(); } + const Field& lonlat() const { return functionspace_->lonlat(); } + const Field& ghost() const { return functionspace_->ghost(); } + size_t size() const { return functionspace_->size(); } private: - - const detail::PointCloud* functionspace_; + const detail::PointCloud* functionspace_; }; -} // namespace functionspace -} // namespace atlas +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index 77a74f21a..b85879674 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -4,37 +4,38 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "eckit/utils/MD5.h" -#include "eckit/os/BackTrace.h" #include "atlas/parallel/mpi/mpi.h" +#include "eckit/os/BackTrace.h" +#include "eckit/utils/MD5.h" -#include "atlas/mesh/Mesh.h" +#include "atlas/array/MakeView.h" #include "atlas/field/FieldSet.h" #include "atlas/field/detail/FieldImpl.h" #include "atlas/functionspace/Spectral.h" +#include "atlas/mesh/Mesh.h" #include "atlas/option.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "atlas/array/MakeView.h" #include "atlas/trans/Trans.h" #ifdef ATLAS_HAVE_TRANS #include "atlas/trans/ifs/TransIFS.h" namespace { -void trans_check(const int code, const char* msg, const eckit::CodeLocation& location) { - if(code != TRANS_SUCCESS) { - std::stringstream errmsg; - errmsg << "atlas::trans ERROR: " << msg << " failed: \n"; - errmsg << ::trans_error_msg(code); - throw eckit::Exception(errmsg.str(),location); - } -} -#define TRANS_CHECK( CALL ) trans_check(CALL, #CALL, Here() ) +void trans_check( const int code, const char* msg, const eckit::CodeLocation& location ) { + if ( code != TRANS_SUCCESS ) { + std::stringstream errmsg; + errmsg << "atlas::trans ERROR: " << msg << " failed: \n"; + errmsg << ::trans_error_msg( code ); + throw eckit::Exception( errmsg.str(), location ); + } } +#define TRANS_CHECK( CALL ) trans_check( CALL, #CALL, Here() ) +} // namespace #endif namespace atlas { @@ -44,510 +45,428 @@ namespace detail { #ifdef ATLAS_HAVE_TRANS class Spectral::Parallelisation { public: + 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 ) ); + 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() ) ); + } + + int nb_spectral_coefficients_global() const { return trans_->nspec2g; } + int nb_spectral_coefficients() const { return trans_->nspec2; } - 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)); - 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())); - } - - int nb_spectral_coefficients_global() const { return trans_->nspec2g; } - int nb_spectral_coefficients() const { return trans_->nspec2; } - - std::string distribution() const { return "trans"; } - operator ::Trans_t*() const { return trans_.get(); } - std::shared_ptr<::Trans_t> trans_; + std::string distribution() const { return "trans"; } + operator ::Trans_t*() const { return trans_.get(); } + std::shared_ptr<::Trans_t> trans_; }; #else class Spectral::Parallelisation { public: - Parallelisation(int truncation) : truncation_(truncation) {} - int nb_spectral_coefficients_global() const { return (truncation_+1)*(truncation_+2); } - int nb_spectral_coefficients() const { return nb_spectral_coefficients_global(); } - int truncation_; - std::string distribution() const { return "serial"; } + Parallelisation( int truncation ) : truncation_( truncation ) {} + int nb_spectral_coefficients_global() const { return ( truncation_ + 1 ) * ( truncation_ + 2 ); } + int nb_spectral_coefficients() const { return nb_spectral_coefficients_global(); } + int truncation_; + std::string distribution() const { return "serial"; } }; #endif -void Spectral::set_field_metadata(const eckit::Configuration& config, Field& field) const -{ - field.set_functionspace(this); - - bool global(false); - if( config.get("global",global) ) - { - if( global ) - { - size_t owner(0); - config.get("owner",owner); - field.metadata().set("owner",owner); +void Spectral::set_field_metadata( const eckit::Configuration& config, Field& field ) const { + field.set_functionspace( this ); + + bool global( false ); + if ( config.get( "global", global ) ) { + if ( global ) { + size_t owner( 0 ); + config.get( "owner", owner ); + field.metadata().set( "owner", owner ); + } } - } - field.metadata().set("global",global); + field.metadata().set( "global", global ); - field.set_levels( config_levels(config) ); - field.set_variables(0); + field.set_levels( config_levels( config ) ); + field.set_variables( 0 ); } - -size_t Spectral::config_size(const eckit::Configuration& config) const -{ - size_t size = nb_spectral_coefficients(); - bool global(false); - if( config.get("global",global) ) - { - if( global ) - { - size_t owner(0); - config.get("owner",owner); - size = (mpi::comm().rank() == owner ? nb_spectral_coefficients_global() : 0); +size_t Spectral::config_size( const eckit::Configuration& config ) const { + size_t size = nb_spectral_coefficients(); + bool global( false ); + if ( config.get( "global", global ) ) { + if ( global ) { + size_t owner( 0 ); + config.get( "owner", owner ); + size = ( mpi::comm().rank() == owner ? nb_spectral_coefficients_global() : 0 ); + } } - } - return size; + return size; } // ---------------------------------------------------------------------- Spectral::Spectral( const eckit::Configuration& config ) : - Spectral::Spectral( config.getUnsigned("truncation"), config ) -{ -} + Spectral::Spectral( config.getUnsigned( "truncation" ), config ) {} // ---------------------------------------------------------------------- Spectral::Spectral( const int truncation, const eckit::Configuration& config ) : - truncation_(truncation), - parallelisation_( new Parallelisation(truncation_) ), - nb_levels_(0) -{ - config.get("levels",nb_levels_); + truncation_( truncation ), + parallelisation_( new Parallelisation( truncation_ ) ), + nb_levels_( 0 ) { + config.get( "levels", nb_levels_ ); } Spectral::Spectral( const trans::Trans& trans, const eckit::Configuration& config ) : - truncation_(trans.truncation()), + truncation_( trans.truncation() ), #ifdef ATLAS_HAVE_TRANS - parallelisation_( new Parallelisation( dynamic_cast(*trans.get()).trans_) ), + parallelisation_( new Parallelisation( dynamic_cast( *trans.get() ).trans_ ) ), #else - parallelisation_( new Parallelisation(truncation_) ), + parallelisation_( new Parallelisation( truncation_ ) ), #endif - nb_levels_(0) -{ - config.get("levels",nb_levels_); + nb_levels_( 0 ) { + config.get( "levels", nb_levels_ ); } -Spectral::~Spectral() -{ -} +Spectral::~Spectral() {} std::string Spectral::distribution() const { - return parallelisation_->distribution(); + return parallelisation_->distribution(); } size_t Spectral::footprint() const { - size_t size = sizeof(*this); - // TODO - return size; + size_t size = sizeof( *this ); + // TODO + return size; } size_t Spectral::nb_spectral_coefficients() const { - return parallelisation_->nb_spectral_coefficients(); + return parallelisation_->nb_spectral_coefficients(); } size_t Spectral::nb_spectral_coefficients_global() const { - return parallelisation_->nb_spectral_coefficients_global(); + return parallelisation_->nb_spectral_coefficients_global(); } - -array::DataType Spectral::config_datatype(const eckit::Configuration& config) const -{ - array::DataType::kind_t kind; - if( ! config.get("datatype",kind) ) throw eckit::AssertionFailed("datatype missing",Here()); - return array::DataType(kind); +array::DataType Spectral::config_datatype( const eckit::Configuration& config ) const { + array::DataType::kind_t kind; + if ( !config.get( "datatype", kind ) ) throw eckit::AssertionFailed( "datatype missing", Here() ); + return array::DataType( kind ); } -std::string Spectral::config_name(const eckit::Configuration& config) const -{ - std::string name; - config.get("name",name); - return name; +std::string Spectral::config_name( const eckit::Configuration& config ) const { + std::string name; + config.get( "name", name ); + return name; } -size_t Spectral::config_levels(const eckit::Configuration& config) const -{ - size_t levels(nb_levels_); - config.get("levels",levels); - return levels; +size_t Spectral::config_levels( const eckit::Configuration& config ) const { + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + return levels; } -Field Spectral::createField(const eckit::Configuration& options) const { - array::ArrayShape array_shape; +Field Spectral::createField( const eckit::Configuration& options ) const { + array::ArrayShape array_shape; - size_t nb_spec_coeffs = config_size(options); - array_shape.push_back(nb_spec_coeffs); + size_t nb_spec_coeffs = config_size( options ); + array_shape.push_back( nb_spec_coeffs ); - size_t levels = config_levels(options); - if( levels ) array_shape.push_back(levels); + size_t levels = config_levels( options ); + if ( levels ) array_shape.push_back( levels ); - Field field = Field(config_name(options), config_datatype(options), array_shape ); + Field field = Field( config_name( options ), config_datatype( options ), array_shape ); - set_field_metadata(options,field); - return field; + set_field_metadata( options, field ); + return field; } -Field Spectral::createField( - const Field& other, - const eckit::Configuration& config ) const -{ - return createField( - option::datatype ( other.datatype() ) | - option::levels ( other.levels() ) | - config ); +Field Spectral::createField( const Field& other, const eckit::Configuration& config ) const { + return createField( option::datatype( other.datatype() ) | option::levels( other.levels() ) | config ); } +void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset ) const { + ASSERT( local_fieldset.size() == global_fieldset.size() ); -void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset ) const -{ - ASSERT(local_fieldset.size() == global_fieldset.size()); - - for( size_t f=0; f() ) - { - std::stringstream err; - err << "Cannot gather spectral field " << loc.name() << " of datatype " << loc.datatype().str() << "."; - err << "Only " << array::DataType::str() << " supported."; - throw eckit::BadValue(err.str()); - } + for ( size_t f = 0; f < local_fieldset.size(); ++f ) { + const Field& loc = local_fieldset[f]; + if ( loc.datatype() != array::DataType::str() ) { + std::stringstream err; + err << "Cannot gather spectral field " << loc.name() << " of datatype " << loc.datatype().str() << "."; + err << "Only " << array::DataType::str() << " supported."; + throw eckit::BadValue( err.str() ); + } #ifdef ATLAS_HAVE_TRANS - Field& glb = global_fieldset[f]; - size_t root=0; - glb.metadata().get("owner",root); - ASSERT( loc.shape(0) == nb_spectral_coefficients() ); - if( mpi::comm().rank() == root ) - ASSERT( glb.shape(0) == nb_spectral_coefficients_global() ); - std::vector nto(1,root+1); - if( loc.rank() > 1 ) { - nto.resize(loc.stride(0)); - for( size_t i=0; i(); - args.nto = nto.data(); - args.rspec = loc.data(); - TRANS_CHECK( ::trans_gathspec(&args) ); + Field& glb = global_fieldset[f]; + size_t root = 0; + glb.metadata().get( "owner", root ); + ASSERT( loc.shape( 0 ) == nb_spectral_coefficients() ); + if ( mpi::comm().rank() == root ) ASSERT( glb.shape( 0 ) == nb_spectral_coefficients_global() ); + std::vector nto( 1, root + 1 ); + if ( loc.rank() > 1 ) { + nto.resize( loc.stride( 0 ) ); + for ( size_t i = 0; i < nto.size(); ++i ) + nto[i] = root + 1; + } + + struct ::GathSpec_t args = new_gathspec( *parallelisation_ ); + args.nfld = nto.size(); + args.rspecg = glb.data(); + args.nto = nto.data(); + args.rspec = loc.data(); + TRANS_CHECK(::trans_gathspec( &args ) ); #else - throw eckit::Exception("Cannot gather spectral fields because Atlas has not been compiled with TRANS support."); + throw eckit::Exception( + "Cannot gather spectral fields because Atlas has " + "not been compiled with TRANS support." ); #endif - } -} -void Spectral::gather( const Field& local, Field& global ) const -{ - FieldSet local_fields; - FieldSet global_fields; - local_fields.add(local); - global_fields.add(global); - gather(local_fields,global_fields); -} - -void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldset ) const -{ - ASSERT(local_fieldset.size() == global_fieldset.size()); - - for( size_t f=0; f() ) - { - std::stringstream err; - err << "Cannot scatter spectral field " << glb.name() << " of datatype " << glb.datatype().str() << "."; - err << "Only " << array::DataType::str() << " supported."; - throw eckit::BadValue(err.str()); - } - -#ifdef ATLAS_HAVE_TRANS - size_t root=0; - glb.metadata().get("owner",root); - ASSERT( loc.shape(0) == nb_spectral_coefficients() ); - if( mpi::comm().rank() == root ) - ASSERT( glb.shape(0) == nb_spectral_coefficients_global() ); - std::vector nfrom(1,root+1); - if( loc.rank() > 1 ) { - nfrom.resize(loc.stride(0)); - for( size_t i=0; i(); - args.nfrom = nfrom.data(); - args.rspec = loc.data(); - TRANS_CHECK( ::trans_distspec(&args) ); +void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldset ) const { + ASSERT( local_fieldset.size() == global_fieldset.size() ); + + for ( size_t f = 0; f < local_fieldset.size(); ++f ) { + const Field& glb = global_fieldset[f]; + Field& loc = local_fieldset[f]; + if ( loc.datatype() != array::DataType::str() ) { + std::stringstream err; + err << "Cannot scatter spectral field " << glb.name() << " of datatype " << glb.datatype().str() << "."; + err << "Only " << array::DataType::str() << " supported."; + throw eckit::BadValue( err.str() ); + } - glb.metadata().broadcast(loc.metadata(),root); - loc.metadata().set("global",false); +#ifdef ATLAS_HAVE_TRANS + size_t root = 0; + glb.metadata().get( "owner", root ); + ASSERT( loc.shape( 0 ) == nb_spectral_coefficients() ); + if ( mpi::comm().rank() == root ) ASSERT( glb.shape( 0 ) == nb_spectral_coefficients_global() ); + std::vector nfrom( 1, root + 1 ); + if ( loc.rank() > 1 ) { + nfrom.resize( loc.stride( 0 ) ); + for ( size_t i = 0; i < nfrom.size(); ++i ) + nfrom[i] = root + 1; + } + + struct ::DistSpec_t args = new_distspec( *parallelisation_ ); + args.nfld = nfrom.size(); + args.rspecg = glb.data(); + args.nfrom = nfrom.data(); + args.rspec = loc.data(); + TRANS_CHECK(::trans_distspec( &args ) ); + + glb.metadata().broadcast( loc.metadata(), root ); + loc.metadata().set( "global", false ); #else - throw eckit::Exception("Cannot scatter spectral fields because Atlas has not been compiled with TRANS support."); + throw eckit::Exception( + "Cannot scatter spectral fields because Atlas has " + "not been compiled with TRANS support." ); #endif - - } + } } -void Spectral::scatter( const Field& global, Field& local ) const -{ - FieldSet global_fields; - FieldSet local_fields; - global_fields.add(global); - local_fields.add(local); - scatter(global_fields,local_fields); +void Spectral::scatter( const Field& global, Field& local ) const { + FieldSet global_fields; + FieldSet local_fields; + global_fields.add( global ); + local_fields.add( local ); + scatter( global_fields, local_fields ); } std::string Spectral::checksum( const FieldSet& fieldset ) const { - eckit::MD5 md5; - NOTIMP; - return md5; + eckit::MD5 md5; + NOTIMP; + return md5; } std::string Spectral::checksum( const Field& field ) const { - FieldSet fieldset; - fieldset.add(field); - return checksum(fieldset); + FieldSet fieldset; + fieldset.add( field ); + return checksum( fieldset ); } void Spectral::norm( const Field& field, double& norm, int rank ) const { #ifdef ATLAS_HAVE_TRANS - ASSERT( std::max(1,field.levels()) == 1 ); - struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); - args.nfld = 1; - args.rspec = field.data(); - args.rnorm = &norm; - args.nmaster = rank+1; - TRANS_CHECK( ::trans_specnorm(&args) ); + ASSERT( std::max( 1, field.levels() ) == 1 ); + struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); + args.nfld = 1; + args.rspec = field.data(); + args.rnorm = &norm; + args.nmaster = rank + 1; + TRANS_CHECK(::trans_specnorm( &args ) ); #else - throw eckit::Exception("Cannot compute spectral norms because Atlas has not been compiled with TRANS support."); + throw eckit::Exception( + "Cannot compute spectral norms because Atlas has not " + "been compiled with TRANS support." ); #endif } void Spectral::norm( const Field& field, double norm_per_level[], int rank ) const { #ifdef ATLAS_HAVE_TRANS - ASSERT( std::max(1,field.levels()) == 1 ); - struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); - args.nfld = std::max(1,field.levels()); - args.rspec = field.data(); - args.rnorm = norm_per_level; - args.nmaster = rank+1; - TRANS_CHECK( ::trans_specnorm(&args) ); + ASSERT( std::max( 1, field.levels() ) == 1 ); + struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); + args.nfld = std::max( 1, field.levels() ); + args.rspec = field.data(); + args.rnorm = norm_per_level; + args.nmaster = rank + 1; + TRANS_CHECK(::trans_specnorm( &args ) ); #else - throw eckit::Exception("Cannot compute spectral norms because Atlas has not been compiled with TRANS support."); + throw eckit::Exception( + "Cannot compute spectral norms because Atlas has not " + "been compiled with TRANS support." ); #endif } void Spectral::norm( const Field& field, std::vector& norm_per_level, int rank ) const { #ifdef ATLAS_HAVE_TRANS - norm_per_level.resize( std::max(1,field.levels()) ); - struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); - args.nfld = norm_per_level.size(); - args.rspec = field.data(); - args.rnorm = norm_per_level.data(); - args.nmaster = rank+1; - TRANS_CHECK( ::trans_specnorm(&args) ); + norm_per_level.resize( std::max( 1, field.levels() ) ); + struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); + args.nfld = norm_per_level.size(); + args.rspec = field.data(); + args.rnorm = norm_per_level.data(); + args.nmaster = rank + 1; + TRANS_CHECK(::trans_specnorm( &args ) ); #else - throw eckit::Exception("Cannot compute spectral norms because Atlas has not been compiled with TRANS support."); + throw eckit::Exception( + "Cannot compute spectral norms because Atlas has not " + "been compiled with TRANS support." ); #endif } -} // namespace detail +} // namespace detail // ---------------------------------------------------------------------- Spectral::Spectral( const FunctionSpace& functionspace ) : - FunctionSpace(functionspace), - functionspace_( dynamic_cast< const detail::Spectral* >( get() ) ) { -} + FunctionSpace( functionspace ), + functionspace_( dynamic_cast( get() ) ) {} Spectral::Spectral( const eckit::Configuration& config ) : - FunctionSpace( new detail::Spectral(config) ), - functionspace_( dynamic_cast< const detail::Spectral* >( get() ) ) { -} + FunctionSpace( new detail::Spectral( config ) ), + functionspace_( dynamic_cast( get() ) ) {} Spectral::Spectral( const size_t truncation, const eckit::Configuration& config ) : - FunctionSpace( new detail::Spectral(truncation,config) ), - functionspace_( dynamic_cast< const detail::Spectral* >( get() ) ) { -} + FunctionSpace( new detail::Spectral( truncation, config ) ), + functionspace_( dynamic_cast( get() ) ) {} Spectral::Spectral( const trans::Trans& trans, const eckit::Configuration& config ) : - FunctionSpace( new detail::Spectral(trans,config) ), - functionspace_( dynamic_cast< const detail::Spectral* >( get() ) ) { -} + FunctionSpace( new detail::Spectral( trans, config ) ), + functionspace_( dynamic_cast( get() ) ) {} size_t Spectral::nb_spectral_coefficients() const { - return functionspace_->nb_spectral_coefficients(); + return functionspace_->nb_spectral_coefficients(); } size_t Spectral::nb_spectral_coefficients_global() const { - return functionspace_->nb_spectral_coefficients_global(); + return functionspace_->nb_spectral_coefficients_global(); } int Spectral::truncation() const { - return functionspace_->truncation(); + return functionspace_->truncation(); } void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset ) const { - functionspace_->gather(local_fieldset,global_fieldset); + functionspace_->gather( local_fieldset, global_fieldset ); } void Spectral::gather( const Field& local, Field& global ) const { - functionspace_->gather(local,global); + functionspace_->gather( local, global ); } void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldset ) const { - functionspace_->scatter(global_fieldset,local_fieldset); + functionspace_->scatter( global_fieldset, local_fieldset ); } void Spectral::scatter( const Field& global, Field& local ) const { - functionspace_->scatter(global,local); + functionspace_->scatter( global, local ); } std::string Spectral::checksum( const FieldSet& fieldset ) const { - return functionspace_->checksum(fieldset); + return functionspace_->checksum( fieldset ); } std::string Spectral::checksum( const Field& field ) const { - return functionspace_->checksum(field); + return functionspace_->checksum( field ); } void Spectral::norm( const Field& field, double& norm, int rank ) const { - functionspace_->norm(field,norm,rank); + functionspace_->norm( field, norm, rank ); } void Spectral::norm( const Field& field, double norm_per_level[], int rank ) const { - functionspace_->norm(field,norm_per_level,rank); + functionspace_->norm( field, norm_per_level, rank ); } void Spectral::norm( const Field& field, std::vector& norm_per_level, int rank ) const { - functionspace_->norm(field,norm_per_level,rank); + functionspace_->norm( field, norm_per_level, rank ); } - // ---------------------------------------------------------------------- - -extern "C" -{ -const detail::Spectral* atlas__SpectralFunctionSpace__new__config ( const eckit::Configuration* config ) - { - ATLAS_ERROR_HANDLING( - return new detail::Spectral(*config); - ); +extern "C" { +const detail::Spectral* atlas__SpectralFunctionSpace__new__config( const eckit::Configuration* config ) { + ATLAS_ERROR_HANDLING( return new detail::Spectral( *config ); ); return 0; - } - -const detail::Spectral* atlas__SpectralFunctionSpace__new__trans (trans::TransImpl* trans, const eckit::Configuration* config ) -{ - ATLAS_ERROR_HANDLING( - return new detail::Spectral(trans::Trans(trans),*config); - ); - return 0; -} - -void atlas__SpectralFunctionSpace__delete ( detail::Spectral* This ) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - delete This; - ); -} - -field::FieldImpl* atlas__fs__Spectral__create_field (const detail::Spectral* This, const eckit::Configuration* options) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(options); - field::FieldImpl* field; - { - Field f = This->createField( *options ); - field = f.get(); - field->attach(); - } - field->detach(); - return field; - ); - return 0; } - -void atlas__SpectralFunctionSpace__gather (const detail::Spectral* This, const field::FieldImpl* local, field::FieldImpl* global) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(global); - ASSERT(local); - const Field l(local); - Field g(global); - This->gather(l,g); - ); +const detail::Spectral* atlas__SpectralFunctionSpace__new__trans( trans::TransImpl* trans, + const eckit::Configuration* config ) { + ATLAS_ERROR_HANDLING( return new detail::Spectral( trans::Trans( trans ), *config ); ); + return 0; } -void atlas__SpectralFunctionSpace__scatter (const detail::Spectral* This, const field::FieldImpl* global, field::FieldImpl* local) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(global); - ASSERT(local); - const Field g(global); - Field l(local); - This->scatter(g,l); - ); +void atlas__SpectralFunctionSpace__delete( detail::Spectral* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); delete This; ); } -void atlas__SpectralFunctionSpace__gather_fieldset (const detail::Spectral* This, const field::FieldSetImpl* local, field::FieldSetImpl* global) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(global); - ASSERT(local); - const FieldSet l(local); - FieldSet g(global); - This->gather(l,g); - ); +field::FieldImpl* atlas__fs__Spectral__create_field( const detail::Spectral* This, + const eckit::Configuration* options ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( options ); field::FieldImpl * field; { + Field f = This->createField( *options ); + field = f.get(); + field->attach(); + } field->detach(); + return field; ); + return 0; } -void atlas__SpectralFunctionSpace__scatter_fieldset (const detail::Spectral* This, const field::FieldSetImpl* global, field::FieldSetImpl* local) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(global); - ASSERT(local); - const FieldSet g(global); - FieldSet l(local); - This->scatter(g,l); - ); +void atlas__SpectralFunctionSpace__gather( const detail::Spectral* This, const field::FieldImpl* local, + field::FieldImpl* global ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( global ); ASSERT( local ); const Field l( local ); Field g( global ); + This->gather( l, g ); ); } -void atlas__SpectralFunctionSpace__norm(const detail::Spectral* This, const field::FieldImpl* field, double norm[], int rank) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(field); - ASSERT(norm); - This->norm(field,norm,rank); - ); +void atlas__SpectralFunctionSpace__scatter( const detail::Spectral* This, const field::FieldImpl* global, + field::FieldImpl* local ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( global ); ASSERT( local ); const Field g( global ); Field l( local ); + This->scatter( g, l ); ); } +void atlas__SpectralFunctionSpace__gather_fieldset( const detail::Spectral* This, const field::FieldSetImpl* local, + field::FieldSetImpl* global ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( global ); ASSERT( local ); const FieldSet l( local ); + FieldSet g( global ); This->gather( l, g ); ); +} - +void atlas__SpectralFunctionSpace__scatter_fieldset( const detail::Spectral* This, const field::FieldSetImpl* global, + field::FieldSetImpl* local ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( global ); ASSERT( local ); const FieldSet g( global ); + FieldSet l( local ); This->scatter( g, l ); ); } -} // namespace functionspace -} // namespace atlas +void atlas__SpectralFunctionSpace__norm( const detail::Spectral* This, const field::FieldImpl* field, double norm[], + int rank ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( field ); ASSERT( norm ); This->norm( field, norm, rank ); ); +} +} +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/Spectral.h b/src/atlas/functionspace/Spectral.h index b6353493a..99c4c9aa5 100644 --- a/src/atlas/functionspace/Spectral.h +++ b/src/atlas/functionspace/Spectral.h @@ -4,27 +4,28 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "atlas/library/config.h" +#include "atlas/field/Field.h" #include "atlas/functionspace/FunctionSpace.h" +#include "atlas/library/config.h" #include "atlas/util/Config.h" -#include "atlas/field/Field.h" namespace atlas { - class Field; - class FieldSet; -} +class Field; +class FieldSet; +} // namespace atlas namespace atlas { namespace trans { - class Trans; -} +class Trans; } +} // namespace atlas namespace atlas { namespace functionspace { @@ -32,125 +33,128 @@ namespace detail { // ------------------------------------------------------------------- -class Spectral : public FunctionSpaceImpl -{ +class Spectral : public FunctionSpaceImpl { public: + Spectral( const eckit::Configuration& ); - Spectral( const eckit::Configuration& ); - - Spectral( const int truncation, const eckit::Configuration& = util::NoConfig() ); - - Spectral( const trans::Trans&, const eckit::Configuration& = util::NoConfig() ); + Spectral( const int truncation, const eckit::Configuration& = util::NoConfig() ); - virtual ~Spectral(); + Spectral( const trans::Trans&, const eckit::Configuration& = util::NoConfig() ); - virtual std::string type() const { return "Spectral"; } + virtual ~Spectral(); - virtual std::string distribution() const; + virtual std::string type() const { return "Spectral"; } - /// @brief Create a spectral field - using FunctionSpaceImpl::createField; - virtual Field createField( const eckit::Configuration& ) const; - virtual Field createField( const Field&, const eckit::Configuration& ) const; + virtual std::string distribution() const; - void gather( const FieldSet&, FieldSet& ) const; - void gather( const Field&, Field& ) const; + /// @brief Create a spectral field + using FunctionSpaceImpl::createField; + virtual Field createField( const eckit::Configuration& ) const; + virtual Field createField( const Field&, const eckit::Configuration& ) const; - void scatter( const FieldSet&, FieldSet& ) const; - void scatter( const Field&, Field& ) const; + void gather( const FieldSet&, FieldSet& ) const; + void gather( const Field&, Field& ) const; - std::string checksum( const FieldSet& ) const; - std::string checksum( const Field& ) const; + void scatter( const FieldSet&, FieldSet& ) const; + void scatter( const Field&, Field& ) const; - void norm( const Field&, double& norm, int rank=0 ) const; - void norm( const Field&, double norm_per_level[], int rank=0 ) const; - void norm( const Field&, std::vector& norm_per_level, int rank=0 ) const; + std::string checksum( const FieldSet& ) const; + std::string checksum( const Field& ) const; -public: // methods + void norm( const Field&, double& norm, int rank = 0 ) const; + void norm( const Field&, double norm_per_level[], int rank = 0 ) const; + void norm( const Field&, std::vector& norm_per_level, int rank = 0 ) const; - size_t nb_spectral_coefficients() const; - size_t nb_spectral_coefficients_global() const; - int truncation() const { return truncation_; } +public: // methods + size_t nb_spectral_coefficients() const; + size_t nb_spectral_coefficients_global() const; + int truncation() const { return truncation_; } -private: // methods +private: // methods + array::DataType config_datatype( const eckit::Configuration& ) const; + std::string config_name( const eckit::Configuration& ) const; + size_t config_size( const eckit::Configuration& ) const; + size_t config_levels( const eckit::Configuration& ) const; + void set_field_metadata( const eckit::Configuration&, Field& ) const; + size_t footprint() const; - array::DataType config_datatype( const eckit::Configuration& ) const; - std::string config_name( const eckit::Configuration& ) const; - size_t config_size( const eckit::Configuration& ) const; - size_t config_levels( const eckit::Configuration& ) const; - void set_field_metadata(const eckit::Configuration&, Field& ) const; - size_t footprint() const; +private: // data + size_t nb_levels_; -private: // data - - size_t nb_levels_; - - int truncation_; - - class Parallelisation; - std::unique_ptr parallelisation_; + int truncation_; + class Parallelisation; + std::unique_ptr parallelisation_; }; -} // detail +} // namespace detail // ------------------------------------------------------------------- class Spectral : public FunctionSpace { public: + Spectral( const FunctionSpace& ); + Spectral( const eckit::Configuration& ); + Spectral( const size_t truncation, const eckit::Configuration& = util::NoConfig() ); + Spectral( const trans::Trans&, const eckit::Configuration& = util::NoConfig() ); - Spectral( const FunctionSpace& ); - Spectral( const eckit::Configuration& ); - Spectral( const size_t truncation, const eckit::Configuration& = util::NoConfig() ); - Spectral( const trans::Trans&, const eckit::Configuration& = util::NoConfig() ); - - operator bool() const { return valid(); } - bool valid() const { return functionspace_; } + operator bool() const { return valid(); } + bool valid() const { return functionspace_; } - void gather( const FieldSet&, FieldSet& ) const; - void gather( const Field&, Field& ) const; + void gather( const FieldSet&, FieldSet& ) const; + void gather( const Field&, Field& ) const; - void scatter( const FieldSet&, FieldSet& ) const; - void scatter( const Field&, Field& ) const; + void scatter( const FieldSet&, FieldSet& ) const; + void scatter( const Field&, Field& ) const; - std::string checksum( const FieldSet& ) const; - std::string checksum( const Field& ) const; + std::string checksum( const FieldSet& ) const; + std::string checksum( const Field& ) const; - void norm( const Field&, double& norm, int rank=0 ) const; - void norm( const Field&, double norm_per_level[], int rank=0 ) const; - void norm( const Field&, std::vector& norm_per_level, int rank=0 ) const; + void norm( const Field&, double& norm, int rank = 0 ) const; + void norm( const Field&, double norm_per_level[], int rank = 0 ) const; + void norm( const Field&, std::vector& norm_per_level, int rank = 0 ) const; - size_t nb_spectral_coefficients() const; - size_t nb_spectral_coefficients_global() const; - int truncation() const; + size_t nb_spectral_coefficients() const; + size_t nb_spectral_coefficients_global() const; + int truncation() const; private: - - const detail::Spectral* functionspace_; + const detail::Spectral* functionspace_; }; -} // namespace functionspace -} // namespace atlas +} // namespace functionspace +} // namespace atlas // ------------------------------------------------------------------- // C wrapper interfaces to C++ routines namespace atlas { -namespace field { class FieldSetImpl; class FieldImpl; } -namespace trans { class TransImpl; } +namespace field { +class FieldSetImpl; +class FieldImpl; +} // namespace field +namespace trans { +class TransImpl; +} namespace functionspace { -extern "C" -{ - const detail::Spectral* atlas__SpectralFunctionSpace__new__config ( const eckit::Configuration* config ); - const detail::Spectral* atlas__SpectralFunctionSpace__new__trans (trans::TransImpl* trans, const eckit::Configuration* config ); - void atlas__SpectralFunctionSpace__delete (detail::Spectral* This); - field::FieldImpl* atlas__fs__Spectral__create_field(const detail::Spectral* This, const eckit::Configuration* options); - void atlas__SpectralFunctionSpace__gather(const detail::Spectral* This, const field::FieldImpl* local, field::FieldImpl* global); - void atlas__SpectralFunctionSpace__gather_fieldset(const detail::Spectral* This, const field::FieldSetImpl* local, field::FieldSetImpl* global); - void atlas__SpectralFunctionSpace__scatter(const detail::Spectral* This, const field::FieldImpl* global, field::FieldImpl* local); - void atlas__SpectralFunctionSpace__scatter_fieldset(const detail::Spectral* This, const field::FieldSetImpl* global, field::FieldSetImpl* local); - void atlas__SpectralFunctionSpace__norm(const detail::Spectral* This, const field::FieldImpl* field, double norm[], int rank); +extern "C" { +const detail::Spectral* atlas__SpectralFunctionSpace__new__config( const eckit::Configuration* config ); +const detail::Spectral* atlas__SpectralFunctionSpace__new__trans( trans::TransImpl* trans, + const eckit::Configuration* config ); +void atlas__SpectralFunctionSpace__delete( detail::Spectral* This ); +field::FieldImpl* atlas__fs__Spectral__create_field( const detail::Spectral* This, + const eckit::Configuration* options ); +void atlas__SpectralFunctionSpace__gather( const detail::Spectral* This, const field::FieldImpl* local, + field::FieldImpl* global ); +void atlas__SpectralFunctionSpace__gather_fieldset( const detail::Spectral* This, const field::FieldSetImpl* local, + field::FieldSetImpl* global ); +void atlas__SpectralFunctionSpace__scatter( const detail::Spectral* This, const field::FieldImpl* global, + field::FieldImpl* local ); +void atlas__SpectralFunctionSpace__scatter_fieldset( const detail::Spectral* This, const field::FieldSetImpl* global, + field::FieldSetImpl* local ); +void atlas__SpectralFunctionSpace__norm( const detail::Spectral* This, const field::FieldImpl* field, double norm[], + int rank ); } -} // namespace functionspace -} // namespace atlas +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index f5c3422ff..65b98dd7d 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -4,34 +4,35 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include +#include #include "atlas/functionspace/StructuredColumns.h" #include "eckit/utils/MD5.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/field/detail/FieldImpl.h" +#include "atlas/array/MakeView.h" #include "atlas/field/FieldSet.h" -#include "atlas/util/Checksum.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/runtime/ErrorHandling.h" -#include "atlas/runtime/Trace.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/parallel/GatherScatter.h" +#include "atlas/field/detail/FieldImpl.h" +#include "atlas/mesh/Mesh.h" #include "atlas/parallel/Checksum.h" +#include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/HaloExchange.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/omp/omp.h" -#include "atlas/array/MakeView.h" +#include "atlas/runtime/ErrorHandling.h" +#include "atlas/runtime/Trace.h" +#include "atlas/util/Checksum.h" +#include "atlas/util/CoordinateEnums.h" #include "atlas/mesh/Mesh.h" -#define IDX(i,j) "("< -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() ); - } else { - return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); +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() ); } + else { + return make_view( field ).slice( Range::all(), Range::all(), Range::dummy() ); + } } - } - else { - if( field.variables() ) { - return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); - } else { - return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + else { + if ( field.variables() ) { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::all() ); + } + else { + return make_view( field ).slice( Range::all(), Range::dummy(), Range::dummy() ); + } } - } } template -std::string checksum_3d_field(const parallel::Checksum& checksum, const Field& field ) -{ - array::LocalView values = make_leveled_view(field); - array::ArrayT surface_field( values.shape(0), values.shape(2) ); - array::ArrayView surface = array::make_view(surface_field); - const size_t npts = values.shape(0); - atlas_omp_for( size_t n=0; n values = make_leveled_view( field ); + array::ArrayT surface_field( values.shape( 0 ), values.shape( 2 ) ); + array::ArrayView surface = array::make_view( surface_field ); + const size_t npts = values.shape( 0 ); + atlas_omp_for( size_t n = 0; n < npts; ++n ) { + for ( size_t j = 0; j < surface.shape( 1 ); ++j ) { + surface( n, j ) = 0.; + for ( size_t l = 0; l < values.shape( 1 ); ++l ) + surface( n, j ) += values( n, l, j ); + } } - } - return checksum.execute( surface.data(), surface_field.stride(0) ); + return checksum.execute( surface.data(), surface_field.stride( 0 ) ); } -struct GridPoint -{ +struct GridPoint { public: - idx_t i,j; - idx_t r; - - GridPoint() {} - GridPoint(idx_t _i, idx_t _j) : - i(_i), - j(_j) { - } - - bool operator < (const GridPoint& other) const - { - if( j < other.j ) return true; - if( j == other.j ) return i < other.i; - return false; - } - - bool operator == (const GridPoint& other) const - { - return ( j==other.j && i==other.i ); - } + idx_t i, j; + idx_t r; + + GridPoint() {} + GridPoint( idx_t _i, idx_t _j ) : i( _i ), j( _j ) {} + + bool operator<( const GridPoint& other ) const { + if ( j < other.j ) return true; + if ( j == other.j ) return i < other.i; + return false; + } + + bool operator==( const GridPoint& other ) const { return ( j == other.j && i == other.i ); } }; -struct GridPointSet -{ +struct GridPointSet { public: - //idx_t r{0}; - std::set set; - bool insert(idx_t i, idx_t j) { - auto inserted = set.insert(GridPoint(i,j)); - if( inserted.second ) { - const_cast(*inserted.first).r = set.size()-1; + // idx_t r{0}; + std::set set; + bool insert( idx_t i, idx_t j ) { + auto inserted = set.insert( GridPoint( i, j ) ); + if ( inserted.second ) { const_cast( *inserted.first ).r = set.size() - 1; } + return inserted.second; } - return inserted.second; - } - size_t size() const { return set.size(); } + size_t size() const { return set.size(); } - using const_iterator = std::set::const_iterator; + using const_iterator = std::set::const_iterator; - const_iterator begin() const { return set.begin(); } - const_iterator end() const { return set.end(); } + const_iterator begin() const { return set.begin(); } + const_iterator end() const { return set.end(); } }; +} // namespace -} +void StructuredColumns::set_field_metadata( const eckit::Configuration& config, Field& field ) const { + field.set_functionspace( this ); -void StructuredColumns::set_field_metadata(const eckit::Configuration& config, Field& field) const -{ - field.set_functionspace(this); - - bool global(false); - if( config.get("global",global) ) - { - if( global ) - { - size_t owner(0); - config.get("owner",owner); - field.metadata().set("owner",owner); + bool global( false ); + if ( config.get( "global", global ) ) { + if ( global ) { + size_t owner( 0 ); + config.get( "owner", owner ); + field.metadata().set( "owner", owner ); + } } - } - field.metadata().set("global",global); + field.metadata().set( "global", global ); - size_t levels(nb_levels_); - config.get("levels",levels); - field.set_levels(levels); + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + field.set_levels( levels ); - size_t variables(0); - config.get("variables",variables); - field.set_variables(variables); + size_t variables( 0 ); + config.get( "variables", variables ); + field.set_variables( variables ); } -array::DataType StructuredColumns::config_datatype(const eckit::Configuration& config) const -{ - array::DataType::kind_t kind; - if( ! config.get("datatype",kind) ) throw eckit::AssertionFailed("datatype missing",Here()); - return array::DataType(kind); +array::DataType StructuredColumns::config_datatype( const eckit::Configuration& config ) const { + array::DataType::kind_t kind; + if ( !config.get( "datatype", kind ) ) throw eckit::AssertionFailed( "datatype missing", Here() ); + return array::DataType( kind ); } -std::string StructuredColumns::config_name(const eckit::Configuration& config) const -{ - std::string name; - config.get("name",name); - return name; +std::string StructuredColumns::config_name( const eckit::Configuration& config ) const { + std::string name; + config.get( "name", name ); + return name; } -size_t StructuredColumns::config_levels(const eckit::Configuration& config) const -{ - size_t levels(nb_levels_); - config.get("levels",levels); - return levels; +size_t StructuredColumns::config_levels( const eckit::Configuration& config ) const { + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + return levels; } -array::ArrayShape StructuredColumns::config_shape(const eckit::Configuration& config) const { - array::ArrayShape shape; +array::ArrayShape StructuredColumns::config_shape( const eckit::Configuration& config ) const { + array::ArrayShape shape; - shape.push_back(config_size(config)); + shape.push_back( config_size( config ) ); - size_t levels(nb_levels_); - config.get("levels",levels); - if( levels > 0 ) shape.push_back(levels); + size_t levels( nb_levels_ ); + config.get( "levels", levels ); + if ( levels > 0 ) shape.push_back( levels ); - size_t variables(0); - config.get("variables",variables); - if( variables > 0 ) shape.push_back(variables); + size_t variables( 0 ); + config.get( "variables", variables ); + if ( variables > 0 ) shape.push_back( variables ); - return shape; + return shape; } -void StructuredColumns::Map2to1::print(std::ostream& out) const { - for( idx_t j=j_min_; j<=j_max_; ++j ) { - out << std::setw(4) << j << " : "; - for( idx_t i=i_min_; i<=i_max_; ++i ) { - idx_t v = operator()(i,j); - if( v == missing() ) - out << std::setw(4) << "X"; - else - out << std::setw(4) << v; +void StructuredColumns::Map2to1::print( std::ostream& out ) const { + for ( idx_t j = j_min_; j <= j_max_; ++j ) { + out << std::setw( 4 ) << j << " : "; + for ( idx_t i = i_min_; i <= i_max_; ++i ) { + idx_t v = operator()( i, j ); + if ( v == missing() ) + out << std::setw( 4 ) << "X"; + else + out << std::setw( 4 ) << v; + } + out << '\n'; } - out << '\n'; - } } -void StructuredColumns::IndexRange::print(std::ostream& out) const { - for( idx_t i=min_; i<=max_; ++i ) { - idx_t v = operator()(i); - if( v == missing() ) - out << std::setw(4) << "X"; - else - out << std::setw(4) << v; - } - out << '\n'; +void StructuredColumns::IndexRange::print( std::ostream& out ) const { + for ( idx_t i = min_; i <= max_; ++i ) { + idx_t v = operator()( i ); + if ( v == missing() ) + out << std::setw( 4 ) << "X"; + else + out << std::setw( 4 ) << v; + } + out << '\n'; } - -size_t StructuredColumns::config_size(const eckit::Configuration& config) const -{ - size_t size = size_halo_; - bool global(false); - if( config.get("global",global) ) - { - if( global ) - { - size_t owner(0); - config.get("owner",owner); - size = (mpi::comm().rank() == owner ? grid_.size() : 0); +size_t StructuredColumns::config_size( const eckit::Configuration& config ) const { + size_t size = size_halo_; + bool global( false ); + if ( config.get( "global", global ) ) { + if ( global ) { + size_t owner( 0 ); + config.get( "owner", owner ); + size = ( mpi::comm().rank() == owner ? grid_.size() : 0 ); + } } - } - return size; + return size; } std::string StructuredColumns::distribution() const { - return distribution_; + return distribution_; } // ---------------------------------------------------------------------------- // Constructor // ---------------------------------------------------------------------------- -StructuredColumns::StructuredColumns(const Grid& grid, const eckit::Configuration& config) : - StructuredColumns::StructuredColumns(grid, grid::Partitioner(), config ) { -} +StructuredColumns::StructuredColumns( const Grid& grid, const eckit::Configuration& config ) : + StructuredColumns::StructuredColumns( grid, grid::Partitioner(), config ) {} -StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& p, const eckit::Configuration& config ) : - grid_(grid), - nb_levels_(0) -{ +StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& p, + const eckit::Configuration& config ) : + grid_( grid ), + nb_levels_( 0 ) { ATLAS_TRACE( "Generating StructuredColumns..." ); - nb_levels_ = config_levels(config); - if ( not grid_ ) - { - throw eckit::BadCast("Grid is not a grid::Structured type", Here()); - } + nb_levels_ = config_levels( config ); + if ( not grid_ ) { throw eckit::BadCast( "Grid is not a grid::Structured type", Here() ); } const eckit::mpi::Comm& comm = mpi::comm(); - grid::Partitioner partitioner( p ); - if( not partitioner ) { - if( grid_.domain().global() ) { - if( grid::Partitioner::exists("trans") ) - partitioner = grid::Partitioner("trans"); - else - partitioner = grid::Partitioner("equal_regions"); - } else { - partitioner = grid::Partitioner("checkerboard"); - } + if ( not partitioner ) { + if ( grid_.domain().global() ) { + if ( grid::Partitioner::exists( "trans" ) ) + partitioner = grid::Partitioner( "trans" ); + else + partitioner = grid::Partitioner( "equal_regions" ); + } + else { + partitioner = grid::Partitioner( "checkerboard" ); + } } grid::Distribution distribution; - ATLAS_TRACE_SCOPE( "Partitioning grid ..." ) { - distribution = grid::Distribution(grid,partitioner); - } + ATLAS_TRACE_SCOPE( "Partitioning grid ..." ) { distribution = grid::Distribution( grid, partitioner ); } distribution_ = distribution.type(); int mpi_rank = mpi::comm().rank(); @@ -277,29 +247,28 @@ StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& j_begin_ = std::numeric_limits::max(); j_end_ = std::numeric_limits::min(); i_begin_.resize( grid_.ny(), std::numeric_limits::max() ); - i_end_ .resize( grid_.ny(), std::numeric_limits::min() ); + i_end_.resize( grid_.ny(), std::numeric_limits::min() ); size_t c( 0 ); - size_t owned(0); - for( size_t j=0; j( j_begin_, j ); - j_end_ = std::max( j_end_, j+1 ); - i_begin_[j] = std::min( i_begin_[j], i ); - i_end_ [j] = std::max( i_end_ [j], i+1 ); - ++owned; - } - } + size_t owned( 0 ); + for ( size_t j = 0; j < grid_.ny(); ++j ) { + for ( size_t i = 0; i < grid_.nx( j ); ++i, ++c ) { + if ( distribution.partition( c ) == mpi_rank ) { + j_begin_ = std::min( j_begin_, j ); + j_end_ = std::max( j_end_, j + 1 ); + i_begin_[j] = std::min( i_begin_[j], i ); + i_end_[j] = std::max( i_end_[j], i + 1 ); + ++owned; + } + } } - int halo = config.getInt("halo", 0); - + int halo = config.getInt( "halo", 0 ); GridPointSet gridpoints; - for( idx_t j=j_begin_; j idx_t { - const idx_t nx = grid_.nx(j); - while( i >= nx) { - i -= nx; - } - while( i < 0 ) { - i += nx; - } - return i; + j_end_halo_ = j_end_ + halo; + i_begin_halo_.resize( -halo, grid_.ny() - 1 + halo ); + i_end_halo_.resize( -halo, grid_.ny() - 1 + halo ); + + auto compute_i = [this]( idx_t i, idx_t j ) -> idx_t { + const idx_t nx = grid_.nx( j ); + while ( i >= nx ) { + i -= nx; + } + while ( i < 0 ) { + i += nx; + } + return i; }; - 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; - } 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); - } - return j; + 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; } + 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 ); } + return j; }; - auto compute_x = [this, &compute_i, &compute_j](idx_t i, idx_t j) -> double { - idx_t ii,jj; double x; - jj = compute_j(j); - ii = compute_i(i,jj); // guaranteed between 0 and nx(jj) - const idx_t nx = grid_.nx(jj); - const double a = (ii-i)/nx; - x = grid_.x(ii,jj) - a*grid_.x(nx,jj); - return x; + auto compute_x = [this, &compute_i, &compute_j]( idx_t i, idx_t j ) -> double { + idx_t ii, jj; + double x; + jj = compute_j( j ); + ii = compute_i( i, jj ); // guaranteed between 0 and nx(jj) + const idx_t nx = grid_.nx( jj ); + const double a = ( ii - i ) / nx; + x = grid_.x( ii, jj ) - a * grid_.x( nx, jj ); + return x; }; - auto compute_y = [this, &compute_j](idx_t j) -> double { - idx_t jj; double y; - jj = compute_j(j); - const idx_t ny = grid_.ny(); - y = ( j < 0 ) ? 90. + ( 90.-grid_.y(jj)) - : ( j >= grid_.ny() ) ? -90. + (-90.-grid_.y(jj)) - : grid_.y(jj); - return y; + auto compute_y = [this, &compute_j]( idx_t j ) -> double { + idx_t jj; + double y; + jj = compute_j( j ); + const idx_t ny = grid_.ny(); + y = ( j < 0 ) ? 90. + ( 90. - grid_.y( jj ) ) + : ( j >= grid_.ny() ) ? -90. + ( -90. - grid_.y( jj ) ) : grid_.y( jj ); + return y; }; - std::vector global_offsets(grid_.ny()); - size_t grid_idx=0; - for( size_t j=0; j global_offsets( grid_.ny() ); + size_t grid_idx = 0; + for ( size_t j = 0; j < grid_.ny(); ++j ) { + global_offsets[j] = grid_idx; + grid_idx += grid_.nx( j ); } - auto compute_g = [this,&global_offsets, &compute_i, &compute_j](idx_t i, idx_t j) -> gidx_t { - idx_t ii,jj; gidx_t g; - jj = compute_j(j); - ii = compute_i(i,jj); - if( jj != j ) { - ASSERT( grid_.nx(jj)%2 == 0 ); // assert even number of points - ii = ( ii < grid_.nx(jj)/2 ) ? ii + grid_.nx(jj)/2 - : ( ii >= grid_.nx(jj)/2 ) ? ii - grid_.nx(jj)/2 - : ii; - } - g = global_offsets[jj]+ii+1; - return g; + auto compute_g = [this, &global_offsets, &compute_i, &compute_j]( idx_t i, idx_t j ) -> gidx_t { + idx_t ii, jj; + gidx_t g; + jj = compute_j( j ); + ii = compute_i( i, jj ); + if ( jj != j ) { + ASSERT( grid_.nx( jj ) % 2 == 0 ); // assert even number of points + ii = ( ii < grid_.nx( jj ) / 2 ) ? ii + grid_.nx( jj ) / 2 + : ( ii >= grid_.nx( jj ) / 2 ) ? ii - grid_.nx( jj ) / 2 : ii; + } + g = global_offsets[jj] + ii + 1; + return g; }; - auto compute_p = [this,&global_offsets,&distribution,&compute_i,&compute_j](idx_t i, idx_t j) -> int { - idx_t ii,jj; int p; - jj = compute_j(j); - ii = compute_i(i,jj); - if( jj != j ) { - ASSERT( grid_.nx(jj)%2 == 0 ); // assert even number of points - ii = ( ii < grid_.nx(jj)/2 ) ? ii + grid_.nx(jj)/2 - : ( ii >= grid_.nx(jj)/2 ) ? ii - grid_.nx(jj)/2 - : ii; - } - p = distribution.partition(global_offsets[jj]+ii); - return p; + auto compute_p = [this, &global_offsets, &distribution, &compute_i, &compute_j]( idx_t i, idx_t j ) -> int { + idx_t ii, jj; + int p; + jj = compute_j( j ); + ii = compute_i( i, jj ); + if ( jj != j ) { + ASSERT( grid_.nx( jj ) % 2 == 0 ); // assert even number of points + ii = ( ii < grid_.nx( jj ) / 2 ) ? ii + grid_.nx( jj ) / 2 + : ( ii >= grid_.nx( jj ) / 2 ) ? ii - grid_.nx( jj ) / 2 : ii; + } + p = distribution.partition( global_offsets[jj] + ii ); + return p; }; - if( atlas::Library::instance().debug() ) { - ATLAS_TRACE_SCOPE("Load imbalance") { - comm.barrier(); - } + if ( atlas::Library::instance().debug() ) { + ATLAS_TRACE_SCOPE( "Load imbalance" ) { comm.barrier(); } } - ATLAS_TRACE_SCOPE( "Compute mapping ..." ) - { - idx_t imin = std::numeric_limits::max(); - idx_t imax = -std::numeric_limits::max(); - idx_t jmin = std::numeric_limits::max(); - idx_t jmax = -std::numeric_limits::max(); - for( idx_t j=j_begin_halo_; j compute_x(ii,jj) ) ? ii+halo : ii+std::max(0,halo-1); - imin = std::min(imin,i_minus_halo); - imax = std::max(imax,i_plus_halo); - i_begin_halo_(jj) = std::min(i_begin_halo_(jj),i_minus_halo); - i_end_halo_(jj) = std::max(i_end_halo_(jj),i_plus_halo+1); - } + ATLAS_TRACE_SCOPE( "Compute mapping ..." ) { + idx_t imin = std::numeric_limits::max(); + idx_t imax = -std::numeric_limits::max(); + idx_t jmin = std::numeric_limits::max(); + idx_t jmax = -std::numeric_limits::max(); + for ( idx_t j = j_begin_halo_; j < j_end_halo_; ++j ) { + i_begin_halo_( j ) = imin; + i_end_halo_( j ) = imax; } - } - for( idx_t j=j_begin_halo_; j compute_x( ii, jj ) ) ? ii + halo : ii + std::max( 0, halo - 1 ); + imin = std::min( imin, i_minus_halo ); + imax = std::max( imax, i_plus_halo ); + i_begin_halo_( jj ) = std::min( i_begin_halo_( jj ), i_minus_halo ); + i_end_halo_( jj ) = std::max( i_end_halo_( jj ), i_plus_halo + 1 ); + } + } + } + for ( idx_t j = j_begin_halo_; j < j_end_halo_; ++j ) { + for ( idx_t i = i_begin_halo_( j ); i < i_end_halo_( j ); ++i ) { + gridpoints.insert( i, j ); + } } - } - ij2gp_.resize( {imin,imax}, {jmin,jmax} ); + ij2gp_.resize( {imin, imax}, {jmin, jmax} ); - field_xy_ = Field("xy",array::make_datatype(),array::make_shape(gridpoints.size(),2)); - auto xy = array::make_view(field_xy_); - for( const GridPoint& gp : gridpoints ) { - ij2gp_.set(gp.i,gp.j, gp.r); - 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); - } - else { - xy(gp.r,YY) = compute_y(gp.j); + field_xy_ = Field( "xy", array::make_datatype(), array::make_shape( gridpoints.size(), 2 ) ); + auto xy = array::make_view( field_xy_ ); + for ( const GridPoint& gp : gridpoints ) { + ij2gp_.set( gp.i, gp.j, gp.r ); + 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 ); } + else { + xy( gp.r, YY ) = compute_y( gp.j ); + } } - } } size_halo_ = gridpoints.size(); - field_partition_ = Field("partition", array::make_datatype(),array::make_shape(size_halo_)); - field_global_index_ = Field("glb_idx", array::make_datatype(),array::make_shape(size_halo_)); - field_remote_index_ = Field("remote_idx", array::make_datatype(),array::make_shape(size_halo_)); - - auto part = array::make_view(field_partition_); - auto global_idx = array::make_view(field_global_index_); - auto remote_idx = array::make_view(field_remote_index_); - - - for( const GridPoint& gp : gridpoints ) { - bool in_domain(false); - if( gp.j>=0 && gp.j=0 && gp.i(), array::make_shape( size_halo_ ) ); + field_global_index_ = Field( "glb_idx", array::make_datatype(), array::make_shape( size_halo_ ) ); + field_remote_index_ = Field( "remote_idx", array::make_datatype(), array::make_shape( size_halo_ ) ); + + auto part = array::make_view( field_partition_ ); + auto global_idx = array::make_view( field_global_index_ ); + auto remote_idx = array::make_view( field_remote_index_ ); + + for ( const GridPoint& gp : gridpoints ) { + bool in_domain( false ); + if ( gp.j >= 0 && gp.j < grid_.ny() ) { + if ( gp.i >= 0 && gp.i < grid_.nx( gp.j ) ) { + in_domain = true; + size_t k = global_offsets[gp.j] + gp.i; + part( gp.r ) = distribution.partition( k ); + global_idx( gp.r ) = k + 1; + remote_idx( gp.r ) = gp.r; + } + } + if ( not in_domain ) { + global_idx( gp.r ) = compute_g( gp.i, gp.j ); + part( gp.r ) = compute_p( gp.i, gp.j ); } - } - if( not in_domain ) { - global_idx(gp.r) = compute_g(gp.i,gp.j); - part(gp.r) = compute_p(gp.i,gp.j); - } } - ATLAS_TRACE_SCOPE("Parallelisation ...") - { + ATLAS_TRACE_SCOPE( "Parallelisation ..." ) { + auto build_partition_graph = [this]() -> std::unique_ptr { - auto build_partition_graph = [this]() -> std::unique_ptr { + const eckit::mpi::Comm& comm = mpi::comm(); + const int mpi_size = int( comm.size() ); + const int mpi_rank = int( comm.rank() ); - const eckit::mpi::Comm& comm = mpi::comm(); - const int mpi_size = int(comm.size()); - const int mpi_rank = int(comm.rank()); + auto p = array::make_view( this->partition() ); - auto p = array::make_view< int, 1 >( this->partition() ); + std::set others_set; + others_set.insert( mpi_rank ); + for ( size_t i = size_owned_; i < size_halo_; ++i ) { + others_set.insert( p( i ) ); + } + std::vector others( others_set.begin(), others_set.end() ); - std::set others_set; - others_set.insert(mpi_rank); - for( size_t i=size_owned_; i others(others_set.begin(),others_set.end()); - - eckit::mpi::Buffer recv_others(mpi_size); - - comm.allGatherv(others.begin(),others.end(),recv_others); - - std::vector counts(recv_others.counts.begin(),recv_others.counts.end()); - std::vector displs(recv_others.displs.begin(),recv_others.displs.end()); - std::vector values(recv_others.buffer.begin(),recv_others.buffer.end()); - return std::unique_ptr( new Mesh::PartitionGraph( values.data(), mpi_size, displs.data(), counts.data() ) ); - }; - - std::unique_ptr graph_ptr; - ATLAS_TRACE_SCOPE( "Building partition graph..." ) { - graph_ptr = build_partition_graph(); - } - const Mesh::PartitionGraph& graph = *graph_ptr; - - ATLAS_TRACE_SCOPE( "Setup parallel fields..." ) - { - auto p = array::make_view< int, 1 >( partition() ); - auto g = array::make_view< gidx_t, 1 >( global_index() ); - - const eckit::mpi::Comm& comm = mpi::comm(); - const int mpi_size = int(comm.size()); - const int mpi_rank = int(comm.rank()); - - auto neighbours = graph.nearestNeighbours(mpi_rank); - std::map part_to_neighbour; - for( size_t j=0; j halo_per_neighbour(neighbours.size(),0); - for( size_t i=size_owned_; i > g_per_neighbour(neighbours.size()); - for( size_t j=0; j > r_per_neighbour(neighbours.size()); - for( size_t j=0; j send_requests(neighbours.size()); - std::vector recv_requests(neighbours.size()); - - std::vector recv_size(neighbours.size()); - int tag = 0; - for( size_t j=0; j > recv_g_per_neighbour(neighbours.size()); - for( size_t j=0; j > send_r_per_neighbour(neighbours.size()); - std::map g_to_r; - for( size_t j=0; j recv_others( mpi_size ); + + comm.allGatherv( others.begin(), others.end(), recv_others ); + + std::vector counts( recv_others.counts.begin(), recv_others.counts.end() ); + std::vector displs( recv_others.displs.begin(), recv_others.displs.end() ); + std::vector values( recv_others.buffer.begin(), recv_others.buffer.end() ); + return std::unique_ptr( + new Mesh::PartitionGraph( values.data(), mpi_size, displs.data(), counts.data() ) ); + }; + + std::unique_ptr graph_ptr; + ATLAS_TRACE_SCOPE( "Building partition graph..." ) { graph_ptr = build_partition_graph(); } + const Mesh::PartitionGraph& graph = *graph_ptr; + + ATLAS_TRACE_SCOPE( "Setup parallel fields..." ) { + auto p = array::make_view( partition() ); + auto g = array::make_view( global_index() ); + + const eckit::mpi::Comm& comm = mpi::comm(); + const int mpi_size = int( comm.size() ); + const int mpi_rank = int( comm.rank() ); + + auto neighbours = graph.nearestNeighbours( mpi_rank ); + std::map part_to_neighbour; + for ( size_t j = 0; j < neighbours.size(); ++j ) { + part_to_neighbour[neighbours[j]] = j; + } + std::vector halo_per_neighbour( neighbours.size(), 0 ); + for ( size_t i = size_owned_; i < size_halo_; ++i ) { + halo_per_neighbour[part_to_neighbour[p( i )]]++; } - } - - for( size_t j=0; j counters(neighbours.size(),0); - for( size_t j=size_owned_; jsetup(part.data(), remote_idx.data(), 0, global_idx.data(), size_owned_ ); - } - - ATLAS_TRACE_SCOPE( "Setup checksum..." ) - { - checksum_ = new parallel::Checksum(); - checksum_->setup(part.data(), remote_idx.data(), 0, global_idx.data(), size_owned_ ); - } - - ATLAS_TRACE_SCOPE( "Setup halo exchange..." ) - { - halo_exchange_ = new parallel::HaloExchange(); - halo_exchange_->setup(part.data(),remote_idx.data(),0,size_halo_); - } - } + std::vector> g_per_neighbour( neighbours.size() ); + for ( size_t j = 0; j < neighbours.size(); ++j ) { + g_per_neighbour[j].reserve( halo_per_neighbour[j] ); + } + for ( size_t j = size_owned_; j < size_halo_; ++j ) { + g_per_neighbour[part_to_neighbour[p( j )]].push_back( g( j ) ); + } + std::vector> r_per_neighbour( neighbours.size() ); + for ( size_t j = 0; j < neighbours.size(); ++j ) { + r_per_neighbour[j].resize( halo_per_neighbour[j] ); + } + + std::vector send_requests( neighbours.size() ); + std::vector recv_requests( neighbours.size() ); + + std::vector recv_size( neighbours.size() ); + int tag = 0; + for ( size_t j = 0; j < neighbours.size(); ++j ) { + size_t g_per_neighbour_size = 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 ); + } + + for ( size_t j = 0; j < neighbours.size(); ++j ) { + comm.wait( send_requests[j] ); + } + + for ( size_t j = 0; j < neighbours.size(); ++j ) { + comm.wait( recv_requests[j] ); + } + + std::vector> recv_g_per_neighbour( neighbours.size() ); + for ( size_t j = 0; j < neighbours.size(); ++j ) { + recv_g_per_neighbour[j].resize( recv_size[j] ); + send_requests[j] = + comm.iSend( g_per_neighbour[j].data(), g_per_neighbour[j].size(), neighbours[j], tag ); + recv_requests[j] = + comm.iReceive( recv_g_per_neighbour[j].data(), recv_g_per_neighbour[j].size(), neighbours[j], tag ); + } + + std::vector> send_r_per_neighbour( neighbours.size() ); + std::map g_to_r; + for ( size_t j = 0; j < size_owned_; ++j ) { + g_to_r[g( j )] = j; + } + for ( size_t j = 0; j < neighbours.size(); ++j ) { + send_r_per_neighbour[j].reserve( recv_size[j] ); + + comm.wait( recv_requests[j] ); // wait for recv_g_per_neighbour[j] + for ( gidx_t gidx : recv_g_per_neighbour[j] ) { + send_r_per_neighbour[j].push_back( g_to_r[gidx] ); + } + } + + for ( size_t j = 0; j < neighbours.size(); ++j ) { + comm.wait( send_requests[j] ); + send_requests[j] = + comm.iSend( send_r_per_neighbour[j].data(), send_r_per_neighbour[j].size(), neighbours[j], tag ); + recv_requests[j] = + comm.iReceive( r_per_neighbour[j].data(), r_per_neighbour[j].size(), neighbours[j], tag ); + } + + for ( size_t j = 0; j < neighbours.size(); ++j ) { + comm.wait( recv_requests[j] ); + } + + std::vector counters( neighbours.size(), 0 ); + for ( size_t j = size_owned_; j < size_halo_; ++j ) { + size_t neighbour = part_to_neighbour[p( j )]; + remote_idx( j ) = r_per_neighbour[neighbour][counters[neighbour]++]; + } + + for ( size_t j = 0; j < neighbours.size(); ++j ) { + comm.wait( send_requests[j] ); + } + } + + ATLAS_TRACE_SCOPE( "Setup gather_scatter..." ) { + gather_scatter_ = new parallel::GatherScatter(); + gather_scatter_->setup( part.data(), remote_idx.data(), 0, global_idx.data(), size_owned_ ); + } + + ATLAS_TRACE_SCOPE( "Setup checksum..." ) { + checksum_ = new parallel::Checksum(); + checksum_->setup( part.data(), remote_idx.data(), 0, global_idx.data(), size_owned_ ); + } + + ATLAS_TRACE_SCOPE( "Setup halo exchange..." ) { + halo_exchange_ = new parallel::HaloExchange(); + halo_exchange_->setup( part.data(), remote_idx.data(), 0, size_halo_ ); + } + } } // ---------------------------------------------------------------------------- - // ---------------------------------------------------------------------------- // Destructor // ---------------------------------------------------------------------------- -StructuredColumns::~StructuredColumns() -{ -} +StructuredColumns::~StructuredColumns() {} // ---------------------------------------------------------------------------- - size_t StructuredColumns::footprint() const { - size_t size = sizeof(*this); - // TODO - return size; + size_t size = sizeof( *this ); + // TODO + return size; } // ---------------------------------------------------------------------------- // Create Field // ---------------------------------------------------------------------------- -Field StructuredColumns::createField( const eckit::Configuration& options ) const -{ - size_t npts = config_size(options); - Field field( config_name(options) , config_datatype(options), config_shape(options) ); - set_field_metadata(options,field); +Field StructuredColumns::createField( const eckit::Configuration& options ) const { + size_t npts = config_size( options ); + Field field( config_name( options ), config_datatype( options ), config_shape( options ) ); + set_field_metadata( options, field ); return field; } -Field StructuredColumns::createField( - const Field& other, - const eckit::Configuration& config ) const -{ - return createField( - option::datatype ( other.datatype() ) | - option::levels ( other.levels() ) | - option::variables( other.variables() ) | - config ); +Field StructuredColumns::createField( const Field& other, const eckit::Configuration& config ) const { + return createField( option::datatype( other.datatype() ) | option::levels( other.levels() ) | + option::variables( other.variables() ) | config ); } // ---------------------------------------------------------------------------- - // ---------------------------------------------------------------------------- // Gather FieldSet // ---------------------------------------------------------------------------- -void StructuredColumns::gather( - const FieldSet& local_fieldset, - FieldSet& global_fieldset ) const -{ - ASSERT(local_fieldset.size() == global_fieldset.size()); - - for( size_t f=0; f() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field loc_field( make_leveled_view( loc ) ); - parallel::Field glb_field( make_leveled_view( glb ) ); - gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); - } - else throw eckit::Exception("datatype not supported",Here()); +void StructuredColumns::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset ) const { + ASSERT( local_fieldset.size() == global_fieldset.size() ); + + for ( size_t f = 0; f < local_fieldset.size(); ++f ) { + const Field& loc = local_fieldset[f]; + Field& glb = global_fieldset[f]; + const size_t nb_fields = 1; + size_t root( 0 ); + glb.metadata().get( "owner", root ); + + if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field loc_field( make_leveled_view( loc ) ); + parallel::Field glb_field( make_leveled_view( glb ) ); + gather_scatter_->gather( &loc_field, &glb_field, nb_fields, root ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); } } // ---------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------- // Gather Field // ---------------------------------------------------------------------------- -void StructuredColumns::gather( - const Field& local, - Field& global) const -{ +void StructuredColumns::gather( const Field& local, Field& global ) const { FieldSet local_fields; FieldSet global_fields; - local_fields.add(local); - global_fields.add(global); - gather(local_fields,global_fields); + local_fields.add( local ); + global_fields.add( global ); + gather( local_fields, global_fields ); } // ---------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------- // Scatter FieldSet // ---------------------------------------------------------------------------- -void StructuredColumns::scatter( - const FieldSet& global_fieldset, - FieldSet& local_fieldset) const -{ - ASSERT(local_fieldset.size() == global_fieldset.size()); - - for( size_t f=0; f() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); - } - else if( loc.datatype() == array::DataType::kind() ) { - parallel::Field glb_field( make_leveled_view( glb ) ); - parallel::Field loc_field( make_leveled_view( loc ) ); - gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); - } - else throw eckit::Exception("datatype not supported",Here()); +void StructuredColumns::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldset ) const { + ASSERT( local_fieldset.size() == global_fieldset.size() ); + + for ( size_t f = 0; f < local_fieldset.size(); ++f ) { + const Field& glb = global_fieldset[f]; + Field& loc = local_fieldset[f]; + const size_t nb_fields = 1; + size_t root( 0 ); + glb.metadata().get( "owner", root ); + + if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); + } + else if ( loc.datatype() == array::DataType::kind() ) { + parallel::Field glb_field( make_leveled_view( glb ) ); + parallel::Field loc_field( make_leveled_view( loc ) ); + gather_scatter_->scatter( &glb_field, &loc_field, nb_fields, root ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); - glb.metadata().broadcast(loc.metadata(),root); - loc.metadata().set("global",false); - } + glb.metadata().broadcast( loc.metadata(), root ); + loc.metadata().set( "global", false ); + } } // ---------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------- // Scatter Field // ---------------------------------------------------------------------------- -void StructuredColumns::scatter( - const Field& global, - Field& local) const -{ +void StructuredColumns::scatter( const Field& global, Field& local ) const { FieldSet global_fields; FieldSet local_fields; - global_fields.add(global); - local_fields.add(local); - scatter(global_fields, local_fields); + global_fields.add( global ); + local_fields.add( local ); + scatter( global_fields, local_fields ); } // ---------------------------------------------------------------------------- - std::string StructuredColumns::checksum( const FieldSet& fieldset ) const { - eckit::MD5 md5; - for( size_t f=0; f() ) - md5 << checksum_3d_field(*checksum_,field); - else if( field.datatype() == array::DataType::kind() ) - md5 << checksum_3d_field(*checksum_,field); - else if( field.datatype() == array::DataType::kind() ) - md5 << checksum_3d_field(*checksum_,field); - else if( field.datatype() == array::DataType::kind() ) - md5 << checksum_3d_field(*checksum_,field); - else throw eckit::Exception("datatype not supported",Here()); - } - return md5; + eckit::MD5 md5; + for ( size_t f = 0; f < fieldset.size(); ++f ) { + const Field& field = fieldset[f]; + if ( field.datatype() == array::DataType::kind() ) + md5 << checksum_3d_field( *checksum_, field ); + else if ( field.datatype() == array::DataType::kind() ) + md5 << checksum_3d_field( *checksum_, field ); + else if ( field.datatype() == array::DataType::kind() ) + md5 << checksum_3d_field( *checksum_, field ); + else if ( field.datatype() == array::DataType::kind() ) + md5 << checksum_3d_field( *checksum_, field ); + else + throw eckit::Exception( "datatype not supported", Here() ); + } + return md5; } std::string StructuredColumns::checksum( const Field& field ) const { - FieldSet fieldset; - fieldset.add(field); - return checksum(fieldset); + FieldSet fieldset; + fieldset.add( field ); + return checksum( fieldset ); } - - - namespace { -template -void dispatch_haloExchange( Field& field, const parallel::HaloExchange& halo_exchange ) -{ - if ( field.datatype() == array::DataType::kind() ) { - halo_exchange.template execute( field.array(), false); - } - else if( field.datatype() == array::DataType::kind() ) { - halo_exchange.template execute( field.array(), false ); - } - else if( field.datatype() == array::DataType::kind() ) { - halo_exchange.template execute( field.array(), false ); - } - else if( field.datatype() == array::DataType::kind() ) { - halo_exchange.template execute( field.array(), false ); - } - else throw eckit::Exception("datatype not supported",Here()); -} -} - -void StructuredColumns::haloExchange( FieldSet& fieldset ) const -{ - for( size_t f=0; f(field,*halo_exchange_); - break; - case 2: - dispatch_haloExchange<2>(field,*halo_exchange_); - break; - case 3: - dispatch_haloExchange<3>(field,*halo_exchange_); - break; - case 4: - dispatch_haloExchange<4>(field,*halo_exchange_); - break; - default: - throw eckit::Exception("Rank not supported", Here()); - break; +template +void dispatch_haloExchange( Field& field, const parallel::HaloExchange& halo_exchange ) { + if ( field.datatype() == array::DataType::kind() ) { + halo_exchange.template execute( field.array(), false ); + } + else if ( field.datatype() == array::DataType::kind() ) { + halo_exchange.template execute( field.array(), false ); + } + else if ( field.datatype() == array::DataType::kind() ) { + halo_exchange.template execute( field.array(), false ); + } + else if ( field.datatype() == array::DataType::kind() ) { + halo_exchange.template execute( field.array(), false ); + } + else + throw eckit::Exception( "datatype not supported", Here() ); +} +} // namespace + +void StructuredColumns::haloExchange( FieldSet& fieldset ) const { + for ( size_t f = 0; f < fieldset.size(); ++f ) { + Field& field = fieldset[f]; + switch ( field.rank() ) { + case 1: + dispatch_haloExchange<1>( field, *halo_exchange_ ); + break; + case 2: + dispatch_haloExchange<2>( field, *halo_exchange_ ); + break; + case 3: + dispatch_haloExchange<3>( field, *halo_exchange_ ); + break; + case 4: + dispatch_haloExchange<4>( field, *halo_exchange_ ); + break; + default: + throw eckit::Exception( "Rank not supported", Here() ); + break; + } } - } } -void StructuredColumns::haloExchange( Field& field ) const -{ - FieldSet fieldset; - fieldset.add(field); - haloExchange(fieldset); +void StructuredColumns::haloExchange( Field& field ) const { + FieldSet fieldset; + fieldset.add( field ); + haloExchange( fieldset ); } - - - -} // namespace detail +} // namespace detail // ---------------------------------------------------------------------------- -StructuredColumns::StructuredColumns() : - FunctionSpace(), - functionspace_(nullptr) { -} +StructuredColumns::StructuredColumns() : FunctionSpace(), functionspace_( nullptr ) {} StructuredColumns::StructuredColumns( const FunctionSpace& functionspace ) : - FunctionSpace( functionspace ), - functionspace_( dynamic_cast( get() ) ) { -} + FunctionSpace( functionspace ), + functionspace_( dynamic_cast( get() ) ) {} StructuredColumns::StructuredColumns( const Grid& grid, const eckit::Configuration& config ) : - FunctionSpace( new detail::StructuredColumns(grid,config) ), - functionspace_( dynamic_cast( get() ) ) { -} + FunctionSpace( new detail::StructuredColumns( grid, config ) ), + functionspace_( dynamic_cast( get() ) ) {} -StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& partitioner, const eckit::Configuration& config ) : - FunctionSpace( new detail::StructuredColumns(grid,partitioner,config) ), - functionspace_( dynamic_cast( get() ) ) { -} +StructuredColumns::StructuredColumns( const Grid& grid, const grid::Partitioner& partitioner, + const eckit::Configuration& config ) : + FunctionSpace( new detail::StructuredColumns( grid, partitioner, config ) ), + functionspace_( dynamic_cast( get() ) ) {} void StructuredColumns::gather( const FieldSet& local, FieldSet& global ) const { - functionspace_->gather(local,global); + functionspace_->gather( local, global ); } void StructuredColumns::gather( const Field& local, Field& global ) const { - functionspace_->gather(local,global); + functionspace_->gather( local, global ); } void StructuredColumns::scatter( const FieldSet& global, FieldSet& local ) const { - functionspace_->scatter(global,local); + functionspace_->scatter( global, local ); } void StructuredColumns::scatter( const Field& global, Field& local ) const { - functionspace_->scatter(global,local); + functionspace_->scatter( global, local ); } void StructuredColumns::haloExchange( FieldSet& fields ) const { - functionspace_->haloExchange( fields ); + functionspace_->haloExchange( fields ); } void StructuredColumns::haloExchange( Field& field ) const { - functionspace_->haloExchange( field ); + functionspace_->haloExchange( field ); } std::string StructuredColumns::checksum( const FieldSet& fieldset ) const { - return functionspace_->checksum(fieldset); + return functionspace_->checksum( fieldset ); } -std::string StructuredColumns::checksum( const Field& field) const { - return functionspace_->checksum(field); +std::string StructuredColumns::checksum( const Field& field ) const { + return functionspace_->checksum( field ); } - // ---------------------------------------------------------------------------- // Fortran interfaces // ---------------------------------------------------------------------------- -extern "C" -{ - -const detail::StructuredColumns* atlas__functionspace__StructuredColumns__new__grid (const Grid::Implementation* grid, const eckit::Configuration* config) -{ - ATLAS_ERROR_HANDLING( - return new detail::StructuredColumns( Grid(grid), grid::Partitioner(), *config ); - ); - return 0; -} +extern "C" { -void atlas__functionspace__StructuredColumns__delete (detail::StructuredColumns* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - delete This; - ); +const detail::StructuredColumns* atlas__functionspace__StructuredColumns__new__grid( + const Grid::Implementation* grid, const eckit::Configuration* config ) { + ATLAS_ERROR_HANDLING( return new detail::StructuredColumns( Grid( grid ), grid::Partitioner(), *config ); ); + return 0; } -field::FieldImpl* atlas__fs__StructuredColumns__create_field (const detail::StructuredColumns* This, const eckit::Configuration* options) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - field::FieldImpl* field; - { - Field f = This->createField(*options); - field = f.get(); - field->attach(); - } - field->detach(); - return field; - ); - return 0; +void atlas__functionspace__StructuredColumns__delete( detail::StructuredColumns* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); delete This; ); } -void atlas__functionspace__StructuredColumns__gather (const detail::StructuredColumns* This, const field::FieldImpl* local, field::FieldImpl* global) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(global); - ASSERT(local); - const Field l(local); - Field g(global); - This->gather(l,g); - ); +field::FieldImpl* atlas__fs__StructuredColumns__create_field( const detail::StructuredColumns* This, + const eckit::Configuration* options ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); field::FieldImpl * field; { + Field f = This->createField( *options ); + field = f.get(); + field->attach(); + } field->detach(); + return field; ); + return 0; } -void atlas__functionspace__StructuredColumns__scatter (const detail::StructuredColumns* This, const field::FieldImpl* global, field::FieldImpl* local) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(global); - ASSERT(local); - const Field g(global); - Field l(local); - This->scatter(g,l); - ); +void atlas__functionspace__StructuredColumns__gather( const detail::StructuredColumns* This, + const field::FieldImpl* local, field::FieldImpl* global ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( global ); ASSERT( local ); const Field l( local ); Field g( global ); + This->gather( l, g ); ); } -void atlas__fs__StructuredColumns__halo_exchange_field (const detail::StructuredColumns* This, const field::FieldImpl* field) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(field); - Field f(field); - This->haloExchange( f ); - ); +void atlas__functionspace__StructuredColumns__scatter( const detail::StructuredColumns* This, + const field::FieldImpl* global, field::FieldImpl* local ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( global ); ASSERT( local ); const Field g( global ); Field l( local ); + This->scatter( g, l ); ); } -void atlas__fs__StructuredColumns__halo_exchange_fieldset (const detail::StructuredColumns* This, const field::FieldSetImpl* fieldset) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(fieldset); - FieldSet f(fieldset); - This->haloExchange( f ); - ); +void atlas__fs__StructuredColumns__halo_exchange_field( const detail::StructuredColumns* This, + const field::FieldImpl* field ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( field ); Field f( field ); This->haloExchange( f ); ); } +void atlas__fs__StructuredColumns__halo_exchange_fieldset( const detail::StructuredColumns* This, + const field::FieldSetImpl* fieldset ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( fieldset ); FieldSet f( fieldset ); This->haloExchange( f ); ); +} - -void atlas__fs__StructuredColumns__checksum_fieldset(const detail::StructuredColumns* This, const field::FieldSetImpl* fieldset, char* &checksum, int &size, int &allocated) -{ - ASSERT(This); - ASSERT(fieldset); - ATLAS_ERROR_HANDLING( - std::string checksum_str (This->checksum(fieldset)); - size = checksum_str.size(); - checksum = new char[size+1]; allocated = true; - strcpy(checksum,checksum_str.c_str()); - ); +void atlas__fs__StructuredColumns__checksum_fieldset( const detail::StructuredColumns* This, + const field::FieldSetImpl* fieldset, char*& checksum, int& size, + int& allocated ) { + ASSERT( This ); + ASSERT( fieldset ); + ATLAS_ERROR_HANDLING( std::string checksum_str( This->checksum( fieldset ) ); size = checksum_str.size(); + checksum = new char[size + 1]; allocated = true; strcpy( checksum, checksum_str.c_str() ); ); } -void atlas__fs__StructuredColumns__checksum_field(const detail::StructuredColumns* This, const field::FieldImpl* field, char* &checksum, int &size, int &allocated) -{ - ASSERT(This); - ASSERT(field); - ATLAS_ERROR_HANDLING( - std::string checksum_str (This->checksum(field)); - size = checksum_str.size(); - checksum = new char[size+1]; allocated = true; - strcpy(checksum,checksum_str.c_str()); - ); +void atlas__fs__StructuredColumns__checksum_field( const detail::StructuredColumns* This, const field::FieldImpl* field, + char*& checksum, int& size, int& allocated ) { + ASSERT( This ); + ASSERT( field ); + ATLAS_ERROR_HANDLING( std::string checksum_str( This->checksum( field ) ); size = checksum_str.size(); + checksum = new char[size + 1]; allocated = true; strcpy( checksum, checksum_str.c_str() ); ); } -void atlas__fs__StructuredColumns__index_host (const detail::StructuredColumns* This, int* &data, int &i_min, int &i_max, int &j_min, int &j_max) -{ - ASSERT(This); - ATLAS_ERROR_HANDLING( - data = const_cast(This)->ij2gp_.data_.data(); - i_min = This->ij2gp_.i_min_+1; - i_max = This->ij2gp_.i_max_+1; - j_min = This->ij2gp_.j_min_+1; - j_max = This->ij2gp_.j_max_+1; - ); +void atlas__fs__StructuredColumns__index_host( const detail::StructuredColumns* This, int*& data, int& i_min, + int& i_max, int& j_min, int& j_max ) { + ASSERT( This ); + ATLAS_ERROR_HANDLING( data = const_cast( This )->ij2gp_.data_.data(); + i_min = This->ij2gp_.i_min_ + 1; i_max = This->ij2gp_.i_max_ + 1; + j_min = This->ij2gp_.j_min_ + 1; j_max = This->ij2gp_.j_max_ + 1; ); } -int atlas__fs__StructuredColumns__j_begin (const detail::StructuredColumns* This) { return This->j_begin()+1; } -int atlas__fs__StructuredColumns__j_end (const detail::StructuredColumns* This) { return This->j_end(); } -int atlas__fs__StructuredColumns__i_begin (const detail::StructuredColumns* This, int j) { return This->i_begin(j-1)+1; } -int atlas__fs__StructuredColumns__i_end (const detail::StructuredColumns* This, int j) { return This->i_end(j-1); } -int atlas__fs__StructuredColumns__j_begin_halo (const detail::StructuredColumns* This) { return This->j_begin_halo()+1; } -int atlas__fs__StructuredColumns__j_end_halo (const detail::StructuredColumns* This) { return This->j_end_halo(); } -int atlas__fs__StructuredColumns__i_begin_halo (const detail::StructuredColumns* This, int j) { return This->i_begin_halo(j-1)+1; } -int atlas__fs__StructuredColumns__i_end_halo (const detail::StructuredColumns* This, int j) { return This->i_end_halo(j-1); } - -field::FieldImpl* atlas__fs__StructuredColumns__xy (const detail::StructuredColumns* This) { - return This->xy().get(); +int atlas__fs__StructuredColumns__j_begin( const detail::StructuredColumns* This ) { + return This->j_begin() + 1; +} +int atlas__fs__StructuredColumns__j_end( const detail::StructuredColumns* This ) { + return This->j_end(); +} +int atlas__fs__StructuredColumns__i_begin( const detail::StructuredColumns* This, int j ) { + return This->i_begin( j - 1 ) + 1; +} +int atlas__fs__StructuredColumns__i_end( const detail::StructuredColumns* This, int j ) { + return This->i_end( j - 1 ); +} +int atlas__fs__StructuredColumns__j_begin_halo( const detail::StructuredColumns* This ) { + return This->j_begin_halo() + 1; +} +int atlas__fs__StructuredColumns__j_end_halo( const detail::StructuredColumns* This ) { + return This->j_end_halo(); +} +int atlas__fs__StructuredColumns__i_begin_halo( const detail::StructuredColumns* This, int j ) { + return This->i_begin_halo( j - 1 ) + 1; +} +int atlas__fs__StructuredColumns__i_end_halo( const detail::StructuredColumns* This, int j ) { + return This->i_end_halo( j - 1 ); } -field::FieldImpl* atlas__fs__StructuredColumns__partition (const detail::StructuredColumns* This) { - return This->partition().get(); +field::FieldImpl* atlas__fs__StructuredColumns__xy( const detail::StructuredColumns* This ) { + return This->xy().get(); } -field::FieldImpl* atlas__fs__StructuredColumns__global_index (const detail::StructuredColumns* This) { - return This->global_index().get(); +field::FieldImpl* atlas__fs__StructuredColumns__partition( const detail::StructuredColumns* This ) { + return This->partition().get(); } +field::FieldImpl* atlas__fs__StructuredColumns__global_index( const detail::StructuredColumns* This ) { + return This->global_index().get(); +} } // ---------------------------------------------------------------------------- -} // namespace functionspace -} // namespace atlas - +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/functionspace/StructuredColumns.h b/src/atlas/functionspace/StructuredColumns.h index 9cda8f4b4..87cd11a80 100644 --- a/src/atlas/functionspace/StructuredColumns.h +++ b/src/atlas/functionspace/StructuredColumns.h @@ -4,36 +4,37 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include "atlas/library/config.h" +#include "atlas/array/DataType.h" +#include "atlas/field/Field.h" #include "atlas/functionspace/FunctionSpace.h" -#include "atlas/util/Config.h" #include "atlas/grid/Grid.h" #include "atlas/grid/Partitioner.h" -#include "atlas/array/DataType.h" -#include "atlas/field/Field.h" +#include "atlas/library/config.h" #include "atlas/option.h" +#include "atlas/util/Config.h" namespace atlas { namespace parallel { - class GatherScatter; - class HaloExchange; - class Checksum; -} -} +class GatherScatter; +class HaloExchange; +class Checksum; +} // namespace parallel +} // namespace atlas namespace atlas { - class FieldSet; +class FieldSet; namespace field { - class FieldSetImpl; -} +class FieldSetImpl; } +} // namespace atlas namespace atlas { namespace functionspace { @@ -42,294 +43,267 @@ namespace functionspace { namespace detail { class StructuredColumns : public FunctionSpaceImpl { - public: + StructuredColumns( const Grid&, const eckit::Configuration& = util::NoConfig() ); - StructuredColumns( const Grid&, const eckit::Configuration& = util::NoConfig() ); - - StructuredColumns( const Grid&, const grid::Partitioner&, const eckit::Configuration& = util::NoConfig() ); + StructuredColumns( const Grid&, const grid::Partitioner&, const eckit::Configuration& = util::NoConfig() ); - virtual ~StructuredColumns(); + virtual ~StructuredColumns(); - static std::string static_type() { return "StructuredColumns"; } - virtual std::string type() const { return static_type(); } - virtual std::string distribution() const; + static std::string static_type() { return "StructuredColumns"; } + virtual std::string type() const { return static_type(); } + virtual std::string distribution() const; - /// @brief Create a Structured field - virtual Field createField( const eckit::Configuration&) const; + /// @brief Create a Structured field + virtual Field createField( const eckit::Configuration& ) const; - virtual Field createField(const Field&, const eckit::Configuration& ) const; + virtual Field createField( const Field&, const eckit::Configuration& ) const; - void gather( const FieldSet&, FieldSet& ) const; - void gather( const Field&, Field& ) const; + void gather( const FieldSet&, FieldSet& ) const; + void gather( const Field&, Field& ) const; - void scatter( const FieldSet&, FieldSet& ) const; - void scatter( const Field&, Field& ) const; + void scatter( const FieldSet&, FieldSet& ) const; + void scatter( const Field&, Field& ) const; - void haloExchange( FieldSet& ) const; - void haloExchange( Field& ) const; + void haloExchange( FieldSet& ) const; + void haloExchange( Field& ) const; + size_t sizeOwned() const { return size_owned_; } + size_t sizeHalo() const { return size_halo_; } + size_t size() const { return size_halo_; } - size_t sizeOwned() const { return size_owned_; } - size_t sizeHalo() const { return size_halo_; } - size_t size() const { return size_halo_; } + std::string checksum( const FieldSet& ) const; + std::string checksum( const Field& ) const; - std::string checksum( const FieldSet& ) const; - std::string checksum( const Field& ) const; + const grid::StructuredGrid& grid() const { return grid_; } - const grid::StructuredGrid& grid() const { return grid_; } + idx_t i_begin( idx_t j ) const { return i_begin_[j]; } + idx_t i_end( idx_t j ) const { return i_end_[j]; } - idx_t i_begin( idx_t j ) const { return i_begin_[j]; } - idx_t i_end ( idx_t j ) const { return i_end_[j]; } + idx_t i_begin_halo( idx_t j ) const { return i_begin_halo_[j]; } + idx_t i_end_halo( idx_t j ) const { return i_end_halo_[j]; } - idx_t i_begin_halo( idx_t j ) const { return i_begin_halo_[j]; } - idx_t i_end_halo ( idx_t j ) const { return i_end_halo_[j]; } + idx_t j_begin() const { return j_begin_; } + idx_t j_end() const { return j_end_; } - idx_t j_begin() const { return j_begin_; } - idx_t j_end() const { return j_end_; } + idx_t j_begin_halo() const { return j_begin_halo_; } + idx_t j_end_halo() const { return j_end_halo_; } - idx_t j_begin_halo() const { return j_begin_halo_; } - idx_t j_end_halo() const { return j_end_halo_; } + idx_t index( idx_t i, idx_t j ) const { return ij2gp_( i, j ); } - idx_t index( idx_t i, idx_t j ) const { - return ij2gp_(i,j); - } + Field xy() const { return field_xy_; } + Field partition() const { return field_partition_; } + Field global_index() const { return field_global_index_; } + Field remote_index() const { return field_remote_index_; } - Field xy() const { return field_xy_; } - Field partition() const { return field_partition_; } - Field global_index() const { return field_global_index_; } - Field remote_index() const { return field_remote_index_; } +private: // methods + size_t config_size( const eckit::Configuration& config ) const; + array::DataType config_datatype( const eckit::Configuration& ) const; + std::string config_name( const eckit::Configuration& ) const; + size_t config_levels( const eckit::Configuration& ) const; + array::ArrayShape config_shape( const eckit::Configuration& ) const; + void set_field_metadata( const eckit::Configuration&, Field& ) const; + size_t footprint() const; -private: // methods +private: // data + std::string distribution_; - size_t config_size(const eckit::Configuration& config) const; - array::DataType config_datatype(const eckit::Configuration&) const; - std::string config_name(const eckit::Configuration&) const; - size_t config_levels(const eckit::Configuration&) const; - array::ArrayShape config_shape(const eckit::Configuration&) const; - void set_field_metadata(const eckit::Configuration&, Field& ) const; - size_t footprint() const; + size_t size_owned_; + size_t size_halo_; + size_t nb_levels_; -private: // data + const grid::StructuredGrid grid_; + parallel::GatherScatter* gather_scatter_; + parallel::HaloExchange* halo_exchange_; + parallel::Checksum* checksum_; - std::string distribution_; + Field field_xy_; + Field field_partition_; + Field field_global_index_; + Field field_remote_index_; - size_t size_owned_; - size_t size_halo_; - size_t nb_levels_; + class Map2to1 { + public: + Map2to1() { resize( {1, 0}, {1, 0} ); } - const grid::StructuredGrid grid_; - parallel::GatherScatter* gather_scatter_; - parallel::HaloExchange* halo_exchange_; - parallel::Checksum* checksum_; + Map2to1( std::array i_range, std::array j_range ) { resize( i_range, j_range ); } - Field field_xy_; - Field field_partition_; - Field field_global_index_; - Field field_remote_index_; + void resize( std::array i_range, std::array j_range ) { + i_min_ = i_range[0]; + i_max_ = i_range[1]; + j_min_ = j_range[0]; + j_max_ = j_range[1]; + j_stride_ = ( i_max_ - i_min_ + 1 ); + data_.resize( ( i_max_ - i_min_ + 1 ) * ( j_max_ - j_min_ + 1 ), missing() + 1 ); + } - class Map2to1 { - public: + std::vector data_; + idx_t i_min_; + idx_t i_max_; + idx_t j_min_; + idx_t j_max_; + idx_t j_stride_; - Map2to1() { - resize( {1,0}, {1,0} ); - } + idx_t operator()( idx_t i, idx_t j ) const { return data_[( i - i_min_ ) + ( j - j_min_ ) * j_stride_] - 1; } - Map2to1( std::array i_range, std::array j_range ) { - resize(i_range,j_range); - } + void set( idx_t i, idx_t j, idx_t n ) { data_[( i - i_min_ ) + ( j - j_min_ ) * j_stride_] = n + 1; } - void resize( std::array i_range, std::array j_range ) { - i_min_ = i_range[0]; - i_max_ = i_range[1]; - j_min_ = j_range[0]; - j_max_ = j_range[1]; - j_stride_ = (i_max_-i_min_+1); - data_.resize( (i_max_-i_min_+1)*(j_max_-j_min_+1), missing()+1 ); - } + idx_t missing() const { return std::numeric_limits::max() - 1; } - std::vector data_; - idx_t i_min_; - idx_t i_max_; - idx_t j_min_; - idx_t j_max_; - idx_t j_stride_; + private: + void print( std::ostream& ) const; - idx_t operator()( idx_t i, idx_t j ) const { - return data_[ (i-i_min_) + (j-j_min_)*j_stride_ ] - 1; - } + friend std::ostream& operator<<( std::ostream& s, const Map2to1& p ) { + p.print( s ); + return s; + } + }; - void set( idx_t i, idx_t j, idx_t n ) { - data_[ (i-i_min_) + (j-j_min_)*j_stride_ ] = n+1; - } + class IndexRange { + public: + IndexRange() { resize( 1, 0 ); } - idx_t missing() const { return std::numeric_limits::max()-1; } + IndexRange( idx_t min, idx_t max ) { resize( min, max ); } - private: + std::vector data_; + idx_t min_; + idx_t max_; - void print(std::ostream&) const; + idx_t operator()( idx_t i ) const { return data_[i - min_]; } - friend std::ostream& operator<<(std::ostream& s, const Map2to1& p) { - p.print(s); - return s; - } - }; + idx_t& operator()( idx_t i ) { return data_[i - min_]; } - class IndexRange { - public: + idx_t operator[]( idx_t i ) const { return data_[i - min_]; } - IndexRange() { - resize(1,0); - } + idx_t& operator[]( idx_t i ) { return data_[i - min_]; } - IndexRange( idx_t min, idx_t max ) { - resize(min,max); - } + idx_t missing() const { return std::numeric_limits::max() - 1; } - std::vector data_; - idx_t min_; - idx_t max_; + size_t size() const { return data_.size(); } - idx_t operator()( idx_t i ) const { - return data_[ i-min_ ]; - } + void resize( idx_t min, idx_t max ) { + min_ = min; + max_ = max; + data_.resize( max_ - min_ + 1, missing() + 1 ); + } - idx_t& operator()( idx_t i ) { - return data_[ i-min_ ]; - } + private: + void print( std::ostream& ) const; - idx_t operator[]( idx_t i ) const { - return data_[ i-min_ ]; - } + friend std::ostream& operator<<( std::ostream& s, const IndexRange& p ) { + p.print( s ); + return s; + } + }; - idx_t& operator[]( idx_t i ) { - return data_[ i-min_ ]; - } - - idx_t missing() const { return std::numeric_limits::max()-1; } - - size_t size() const { return data_.size(); } - - void resize( idx_t min, idx_t max ) { - min_ = min; - max_ = max; - data_.resize( max_-min_+1, missing()+1 ); - } - - private: - - void print(std::ostream&) const; - - friend std::ostream& operator<<(std::ostream& s, const IndexRange& p) { - p.print(s); - return s; - } - - }; - - idx_t j_begin_; - idx_t j_end_; - std::vector i_begin_; - std::vector i_end_; - idx_t j_begin_halo_; - idx_t j_end_halo_; - IndexRange i_begin_halo_; - IndexRange i_end_halo_; + idx_t j_begin_; + idx_t j_end_; + std::vector i_begin_; + std::vector i_end_; + idx_t j_begin_halo_; + idx_t j_end_halo_; + IndexRange i_begin_halo_; + IndexRange i_end_halo_; public: - Map2to1 ij2gp_; + Map2to1 ij2gp_; }; // ------------------------------------------------------------------- -} // namespace detail +} // namespace detail // ------------------------------------------------------------------- -class StructuredColumns: public FunctionSpace { - +class StructuredColumns : public FunctionSpace { public: + StructuredColumns(); + StructuredColumns( const FunctionSpace& ); + StructuredColumns( const Grid&, const eckit::Configuration& = util::NoConfig() ); + StructuredColumns( const Grid&, const grid::Partitioner&, const eckit::Configuration& = util::NoConfig() ); - StructuredColumns(); - StructuredColumns( const FunctionSpace& ); - StructuredColumns( const Grid&, const eckit::Configuration& = util::NoConfig() ); - StructuredColumns( const Grid&, const grid::Partitioner&, const eckit::Configuration& = util::NoConfig() ); + static std::string type() { return detail::StructuredColumns::static_type(); } - static std::string type() { return detail::StructuredColumns::static_type(); } + operator bool() const { return valid(); } + bool valid() const { return functionspace_; } - operator bool() const { return valid(); } - bool valid() const { return functionspace_; } + size_t size() const { return functionspace_->size(); } + size_t sizeOwned() const { return functionspace_->sizeOwned(); } + size_t sizeHalo() const { return functionspace_->sizeHalo(); } - size_t size() const { return functionspace_->size(); } - size_t sizeOwned() const { return functionspace_->sizeOwned(); } - size_t sizeHalo() const { return functionspace_->sizeHalo(); } + const grid::StructuredGrid& grid() const { return functionspace_->grid(); } - const grid::StructuredGrid& grid() const { return functionspace_->grid(); } + void gather( const FieldSet&, FieldSet& ) const; + void gather( const Field&, Field& ) const; - void gather( const FieldSet&, FieldSet& ) const; - void gather( const Field&, Field& ) const; + void scatter( const FieldSet&, FieldSet& ) const; + void scatter( const Field&, Field& ) const; - void scatter( const FieldSet&, FieldSet& ) const; - void scatter( const Field&, Field& ) const; + void haloExchange( FieldSet& ) const; + void haloExchange( Field& ) const; - void haloExchange( FieldSet& ) const; - void haloExchange( Field& ) const; + std::string checksum( const FieldSet& ) const; + std::string checksum( const Field& ) const; - std::string checksum( const FieldSet& ) const; - std::string checksum( const Field& ) const; + idx_t index( idx_t i, idx_t j ) const { return functionspace_->index( i, j ); } - idx_t index( idx_t i, idx_t j ) const { return functionspace_->index(i,j); } + idx_t i_begin( idx_t j ) const { return functionspace_->i_begin( j ); } + idx_t i_end( idx_t j ) const { return functionspace_->i_end( j ); } - idx_t i_begin( idx_t j ) const { return functionspace_->i_begin(j); } - idx_t i_end ( idx_t j ) const { return functionspace_->i_end(j); } + idx_t i_begin_halo( idx_t j ) const { return functionspace_->i_begin_halo( j ); } + idx_t i_end_halo( idx_t j ) const { return functionspace_->i_end_halo( j ); } - idx_t i_begin_halo( idx_t j ) const { return functionspace_->i_begin_halo(j); } - idx_t i_end_halo ( idx_t j ) const { return functionspace_->i_end_halo(j); } + idx_t j_begin() const { return functionspace_->j_begin(); } + idx_t j_end() const { return functionspace_->j_end(); } - idx_t j_begin() const { return functionspace_->j_begin(); } - idx_t j_end() const { return functionspace_->j_end(); } + idx_t j_begin_halo() const { return functionspace_->j_begin_halo(); } + idx_t j_end_halo() const { return functionspace_->j_end_halo(); } - idx_t j_begin_halo() const { return functionspace_->j_begin_halo(); } - idx_t j_end_halo() const { return functionspace_->j_end_halo(); } - - Field xy() const { return functionspace_->xy(); } - Field partition() const { return functionspace_->partition(); } - Field global_index() const { return functionspace_->global_index(); } - Field remote_index() const { return functionspace_->remote_index(); } + Field xy() const { return functionspace_->xy(); } + Field partition() const { return functionspace_->partition(); } + Field global_index() const { return functionspace_->global_index(); } + Field remote_index() const { return functionspace_->remote_index(); } private: - - const detail::StructuredColumns* functionspace_; + const detail::StructuredColumns* functionspace_; }; // ------------------------------------------------------------------- // C wrapper interfaces to C++ routines -extern "C" -{ - const detail::StructuredColumns* atlas__functionspace__StructuredColumns__new__grid (const Grid::Implementation* grid, const eckit::Configuration* config ); - void atlas__functionspace__StructuredColumns__delete (detail::StructuredColumns* This); - field::FieldImpl* atlas__fs__StructuredColumns__create_field (const detail::StructuredColumns* This, const eckit::Configuration* options); - void atlas__functionspace__StructuredColumns__gather (const detail::StructuredColumns* This, const field::FieldImpl* local, field::FieldImpl* global); - void atlas__functionspace__StructuredColumns__scatter (const detail::StructuredColumns* This, const field::FieldImpl* global, field::FieldImpl* local); - void atlas__fs__StructuredColumns__checksum_fieldset(const detail::StructuredColumns* This, const field::FieldSetImpl* fieldset, char* &checksum, int &size, int &allocated); - void atlas__fs__StructuredColumns__checksum_field(const detail::StructuredColumns* This, const field::FieldImpl* field, char* &checksum, int &size, int &allocated); - void atlas__fs__StructuredColumns__halo_exchange_field (const detail::StructuredColumns* This, const field::FieldImpl* field); - void atlas__fs__StructuredColumns__halo_exchange_fieldset (const detail::StructuredColumns* This, const field::FieldSetImpl* fieldset); - void atlas__fs__StructuredColumns__index_host (const detail::StructuredColumns* This, int* &data, int &i_min, int &i_max, int &j_min, int &j_max); - int atlas__fs__StructuredColumns__j_begin (const detail::StructuredColumns* This); - int atlas__fs__StructuredColumns__j_end (const detail::StructuredColumns* This); - int atlas__fs__StructuredColumns__i_begin (const detail::StructuredColumns* This, int j); - int atlas__fs__StructuredColumns__i_end (const detail::StructuredColumns* This, int j); - int atlas__fs__StructuredColumns__j_begin_halo (const detail::StructuredColumns* This); - int atlas__fs__StructuredColumns__j_end_halo (const detail::StructuredColumns* This); - int atlas__fs__StructuredColumns__i_begin_halo (const detail::StructuredColumns* This, int j); - int atlas__fs__StructuredColumns__i_end_halo (const detail::StructuredColumns* This, int j); - - field::FieldImpl* atlas__fs__StructuredColumns__xy (const detail::StructuredColumns* This); - field::FieldImpl* atlas__fs__StructuredColumns__partition (const detail::StructuredColumns* This); - field::FieldImpl* atlas__fs__StructuredColumns__global_index (const detail::StructuredColumns* This); - +extern "C" { +const detail::StructuredColumns* atlas__functionspace__StructuredColumns__new__grid( + const Grid::Implementation* grid, const eckit::Configuration* config ); +void atlas__functionspace__StructuredColumns__delete( detail::StructuredColumns* This ); +field::FieldImpl* atlas__fs__StructuredColumns__create_field( const detail::StructuredColumns* This, + const eckit::Configuration* options ); +void atlas__functionspace__StructuredColumns__gather( const detail::StructuredColumns* This, + const field::FieldImpl* local, field::FieldImpl* global ); +void atlas__functionspace__StructuredColumns__scatter( const detail::StructuredColumns* This, + const field::FieldImpl* global, field::FieldImpl* local ); +void atlas__fs__StructuredColumns__checksum_fieldset( const detail::StructuredColumns* This, + const field::FieldSetImpl* fieldset, char*& checksum, int& size, + int& allocated ); +void atlas__fs__StructuredColumns__checksum_field( const detail::StructuredColumns* This, const field::FieldImpl* field, + char*& checksum, int& size, int& allocated ); +void atlas__fs__StructuredColumns__halo_exchange_field( const detail::StructuredColumns* This, + const field::FieldImpl* field ); +void atlas__fs__StructuredColumns__halo_exchange_fieldset( const detail::StructuredColumns* This, + const field::FieldSetImpl* fieldset ); +void atlas__fs__StructuredColumns__index_host( const detail::StructuredColumns* This, int*& data, int& i_min, + int& i_max, int& j_min, int& j_max ); +int atlas__fs__StructuredColumns__j_begin( const detail::StructuredColumns* This ); +int atlas__fs__StructuredColumns__j_end( const detail::StructuredColumns* This ); +int atlas__fs__StructuredColumns__i_begin( const detail::StructuredColumns* This, int j ); +int atlas__fs__StructuredColumns__i_end( const detail::StructuredColumns* This, int j ); +int atlas__fs__StructuredColumns__j_begin_halo( const detail::StructuredColumns* This ); +int atlas__fs__StructuredColumns__j_end_halo( const detail::StructuredColumns* This ); +int atlas__fs__StructuredColumns__i_begin_halo( const detail::StructuredColumns* This, int j ); +int atlas__fs__StructuredColumns__i_end_halo( const detail::StructuredColumns* This, int j ); + +field::FieldImpl* atlas__fs__StructuredColumns__xy( const detail::StructuredColumns* This ); +field::FieldImpl* atlas__fs__StructuredColumns__partition( const detail::StructuredColumns* This ); +field::FieldImpl* atlas__fs__StructuredColumns__global_index( const detail::StructuredColumns* This ); } -} // namespace functionspace -} // namespace atlas +} // namespace functionspace +} // namespace atlas diff --git a/src/atlas/grid.h b/src/atlas/grid.h index 35ff84067..c916132cf 100644 --- a/src/atlas/grid.h +++ b/src/atlas/grid.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,7 +13,7 @@ #pragma once +#include "atlas/grid/Distribution.h" #include "atlas/grid/Grid.h" #include "atlas/grid/Iterator.h" #include "atlas/grid/Partitioner.h" -#include "atlas/grid/Distribution.h" diff --git a/src/atlas/grid/Distribution.cc b/src/atlas/grid/Distribution.cc index 8a6a6b1b1..8c7be780e 100644 --- a/src/atlas/grid/Distribution.cc +++ b/src/atlas/grid/Distribution.cc @@ -4,13 +4,14 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/grid/Distribution.h" #include #include "atlas/grid/Grid.h" -#include "atlas/grid/Distribution.h" #include "atlas/grid/Partitioner.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" @@ -20,101 +21,76 @@ namespace grid { namespace { std::string distribution_type( int N, const Partitioner& p = Partitioner() ) { - if( N == 1 ) { - return "serial"; - } - if( not p ) { - return "custom"; - } - return p.type(); -} + if ( N == 1 ) { return "serial"; } + if ( not p ) { return "custom"; } + return p.type(); } +} // namespace Distribution::impl_t::impl_t( const Grid& grid ) : - nb_partitions_(1), - part_(grid.size(),0), - nb_pts_(nb_partitions_,grid.size()), - max_pts_(grid.size()), - min_pts_(grid.size()), - type_( distribution_type(nb_partitions_) ) { -} + nb_partitions_( 1 ), + part_( grid.size(), 0 ), + nb_pts_( nb_partitions_, grid.size() ), + max_pts_( grid.size() ), + min_pts_( grid.size() ), + type_( distribution_type( nb_partitions_ ) ) {} Distribution::impl_t::impl_t( const Grid& grid, const Partitioner& partitioner ) { - part_.resize(grid.size()); - partitioner.partition(grid,part_.data()); + part_.resize( grid.size() ); + partitioner.partition( grid, part_.data() ); nb_partitions_ = partitioner.nb_partitions(); - nb_pts_.resize(nb_partitions_,0); - for(size_t j = 0; j < part_.size(); ++j) + nb_pts_.resize( nb_partitions_, 0 ); + for ( size_t j = 0; j < part_.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); + 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 ); } Distribution::impl_t::impl_t( size_t npts, int part[], int part0 ) { - part_.assign(part,part+npts); - std::set partset(part_.begin(),part_.end()); + part_.assign( part, part + npts ); + std::set partset( part_.begin(), part_.end() ); nb_partitions_ = partset.size(); - nb_pts_.resize(nb_partitions_,0); - for(size_t j = 0; j < part_.size(); ++j) { + nb_pts_.resize( nb_partitions_, 0 ); + for ( size_t j = 0; j < part_.size(); ++j ) { part_[j] -= part0; ++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_); + 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_ ); } - void Distribution::impl_t::print( std::ostream& s ) const { - s << "Distribution( " - << "type: " << type_ - <<", nbPoints: " << part_.size() - <<", nbPartitions: " < +#include "atlas/library/config.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" -#include "atlas/library/config.h" namespace atlas { - class Grid; +class Grid; namespace grid { class Partitioner; } -} +} // namespace atlas namespace atlas { namespace grid { class Distribution { - - friend class Partitioner; + friend class Partitioner; public: + class impl_t : public eckit::Owned { + public: + impl_t( const Grid& ); - class impl_t: public eckit::Owned { + impl_t( const Grid&, const Partitioner& ); - public: + impl_t( size_t npts, int partition[], int part0 = 0 ); - impl_t( const Grid& ); + virtual ~impl_t() {} - impl_t( const Grid&, const Partitioner& ); + int partition( const gidx_t gidx ) const { return part_[gidx]; } - impl_t( size_t npts, int partition[], int part0 = 0 ); + const std::vector& partition() const { return part_; } - virtual ~impl_t() {} + size_t nb_partitions() const { return nb_partitions_; } - int partition( const gidx_t gidx ) const { - return part_[gidx]; - } + operator const std::vector&() const { return part_; } - const std::vector& partition() const { - return part_; - } + const int* data() const { return part_.data(); } - size_t nb_partitions() const { - return nb_partitions_; - } + const std::vector& nb_pts() const { return nb_pts_; } - operator const std::vector&() const { - return part_; - } - - const int* data() const { - return part_.data(); - } + size_t max_pts() const { return max_pts_; } + size_t min_pts() const { return min_pts_; } - const std::vector& nb_pts() const { - return nb_pts_; - } - - size_t max_pts() const { - return max_pts_; - } - size_t min_pts() const { - return min_pts_; - } + const std::string& type() const { return type_; } - const std::string& type() const { return type_; } + void print( std::ostream& ) const; - void print( std::ostream& ) const; - - private: - - size_t nb_partitions_; - std::vector part_; - std::vector nb_pts_; - size_t max_pts_; - size_t min_pts_; - std::string type_; - - }; + private: + size_t nb_partitions_; + std::vector part_; + std::vector nb_pts_; + size_t max_pts_; + size_t min_pts_; + std::string type_; + }; public: - Distribution(); Distribution( const impl_t* ); Distribution( const Distribution& ); @@ -104,57 +81,38 @@ class Distribution { ~Distribution() {} - int partition(const gidx_t gidx) const { - return impl_->partition(gidx); - } + int partition( const gidx_t gidx ) const { return impl_->partition( gidx ); } - const std::vector& partition() const { - return impl_->partition(); - } + const std::vector& partition() const { return impl_->partition(); } - size_t nb_partitions() const { - return impl_->nb_partitions(); - } + size_t nb_partitions() const { return impl_->nb_partitions(); } - operator const std::vector&() const { - return *impl_; - } + operator const std::vector&() const { return *impl_; } - const int* data() const { - return impl_->data(); - } + const int* data() const { return impl_->data(); } - const std::vector& nb_pts() const { - return impl_->nb_pts(); - } + const std::vector& nb_pts() const { return impl_->nb_pts(); } - size_t max_pts() const { - return impl_->max_pts(); - } - size_t min_pts() const { - return impl_->min_pts(); - } + size_t max_pts() const { return impl_->max_pts(); } + size_t min_pts() const { return impl_->min_pts(); } - const std::string& type() const { - return impl_->type(); - } + const std::string& type() const { return impl_->type(); } - friend std::ostream& operator<<(std::ostream& os, const Distribution& distribution ) { - distribution.impl_->print(os); - return os; + friend std::ostream& operator<<( std::ostream& os, const Distribution& distribution ) { + distribution.impl_->print( os ); + return os; } const impl_t* get() const { return impl_.get(); } private: - eckit::SharedPtr impl_; }; extern "C" { - Distribution::impl_t* atlas__GridDistribution__new(int npts, int part[], int part0); - void atlas__GridDistribution__delete(Distribution::impl_t* This); +Distribution::impl_t* atlas__GridDistribution__new( int npts, int part[], int part0 ); +void atlas__GridDistribution__delete( Distribution::impl_t* This ); } -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/Grid.cc b/src/atlas/grid/Grid.cc index 99bf61f9a..ea9b5cfc1 100644 --- a/src/atlas/grid/Grid.cc +++ b/src/atlas/grid/Grid.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,128 +16,84 @@ #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" +#include "atlas/domain/Domain.h" #include "atlas/grid/Grid.h" #include "atlas/grid/Spacing.h" -#include "atlas/domain/Domain.h" -#include "atlas/projection/Projection.h" -#include "atlas/util/Config.h" #include "atlas/grid/detail/grid/Gaussian.h" #include "atlas/grid/detail/grid/Structured.h" +#include "atlas/projection/Projection.h" +#include "atlas/util/Config.h" namespace atlas { -Grid::Grid(): - grid_( nullptr ) { -} +Grid::Grid() : grid_( nullptr ) {} -Grid::Grid(const Grid& grid): - grid_( grid.grid_ ) { -} +Grid::Grid( const Grid& grid ) : grid_( grid.grid_ ) {} -Grid::Grid( const Grid::Implementation *grid ): - grid_( grid ) { -} +Grid::Grid( const Grid::Implementation* grid ) : grid_( grid ) {} Grid::Grid( const std::string& shortname, const Domain& domain ) { - grid_ = Grid::Implementation::create( - shortname, - Config("domain", domain.spec()) - ); + grid_ = Grid::Implementation::create( shortname, Config( "domain", domain.spec() ) ); } Grid::Grid( const Config& p ) { - grid_ = Grid::Implementation::create(p); + grid_ = Grid::Implementation::create( p ); } namespace grid { -inline const UnstructuredGrid::grid_t* unstructured_grid( const Grid::Implementation *grid ) { - return dynamic_cast(grid); +inline const UnstructuredGrid::grid_t* unstructured_grid( const Grid::Implementation* grid ) { + return dynamic_cast( grid ); } -UnstructuredGrid::UnstructuredGrid(): - Grid(), - grid_( nullptr ) { -} +UnstructuredGrid::UnstructuredGrid() : Grid(), grid_( nullptr ) {} -UnstructuredGrid::UnstructuredGrid( const Grid& grid ): - Grid( grid ), - grid_( unstructured_grid(get()) ) { -} +UnstructuredGrid::UnstructuredGrid( const Grid& grid ) : Grid( grid ), grid_( unstructured_grid( get() ) ) {} -UnstructuredGrid::UnstructuredGrid( const Grid::Implementation* grid ): +UnstructuredGrid::UnstructuredGrid( const Grid::Implementation* grid ) : Grid( grid ), - grid_( unstructured_grid(get()) ) { -} + grid_( unstructured_grid( get() ) ) {} -UnstructuredGrid::UnstructuredGrid( const Config& grid ): - Grid( grid ), - grid_( unstructured_grid(get()) ) { -} +UnstructuredGrid::UnstructuredGrid( const Config& grid ) : Grid( grid ), grid_( unstructured_grid( get() ) ) {} -UnstructuredGrid::UnstructuredGrid( std::vector* xy ): - Grid( new UnstructuredGrid::grid_t(xy) ), - grid_( unstructured_grid(get()) ) { -} +UnstructuredGrid::UnstructuredGrid( std::vector* xy ) : + Grid( new UnstructuredGrid::grid_t( xy ) ), + grid_( unstructured_grid( get() ) ) {} -UnstructuredGrid::UnstructuredGrid( std::vector&& xy ): - Grid( new UnstructuredGrid::grid_t( std::forward< std::vector >(xy) ) ), - grid_( unstructured_grid(get()) ) { -} +UnstructuredGrid::UnstructuredGrid( std::vector&& xy ) : + Grid( new UnstructuredGrid::grid_t( std::forward>( xy ) ) ), + grid_( unstructured_grid( get() ) ) {} -UnstructuredGrid::UnstructuredGrid( std::initializer_list xy ): +UnstructuredGrid::UnstructuredGrid( std::initializer_list xy ) : Grid( new UnstructuredGrid::grid_t( xy ) ), - grid_( unstructured_grid(get()) ) { -} + grid_( unstructured_grid( get() ) ) {} -inline const StructuredGrid::grid_t* structured_grid( const Grid::Implementation *grid ) { - return dynamic_cast(grid); +inline const StructuredGrid::grid_t* structured_grid( const Grid::Implementation* grid ) { + return dynamic_cast( grid ); } -StructuredGrid::StructuredGrid(): - Grid(), - grid_( nullptr ) { -} +StructuredGrid::StructuredGrid() : Grid(), grid_( nullptr ) {} -StructuredGrid::StructuredGrid( const Grid& grid ): - Grid( grid ), - grid_( structured_grid(get()) ) { -} +StructuredGrid::StructuredGrid( const Grid& grid ) : Grid( grid ), grid_( structured_grid( get() ) ) {} -StructuredGrid::StructuredGrid( const Grid::Implementation* grid ): - Grid( grid ), - grid_( structured_grid(get()) ) { -} +StructuredGrid::StructuredGrid( const Grid::Implementation* grid ) : Grid( grid ), grid_( structured_grid( get() ) ) {} -StructuredGrid::StructuredGrid( const std::string& grid, const Domain& domain ): +StructuredGrid::StructuredGrid( const std::string& grid, const Domain& domain ) : Grid( grid, domain ), - grid_( structured_grid(get()) ) { -} + grid_( structured_grid( get() ) ) {} -StructuredGrid::StructuredGrid( const Config& grid ): - Grid( grid ), - grid_( structured_grid(get()) ) { -} +StructuredGrid::StructuredGrid( const Config& grid ) : Grid( grid ), grid_( structured_grid( get() ) ) {} -StructuredGrid::StructuredGrid( - const XSpace& xspace, - const YSpace& yspace, - const Projection& projection, - const Domain& domain -) : +StructuredGrid::StructuredGrid( const XSpace& xspace, const YSpace& yspace, const Projection& projection, + const Domain& domain ) : Grid( new detail::grid::Structured( xspace, yspace, projection, domain ) ), - grid_( structured_grid(get()) ) { -} + grid_( structured_grid( get() ) ) {} +ReducedGaussianGrid::ReducedGaussianGrid( const std::vector& nx, const Domain& domain ) : + ReducedGaussianGrid::grid_t( detail::grid::reduced_gaussian( nx, domain ) ) {} -ReducedGaussianGrid::ReducedGaussianGrid( const std::vector& nx, const Domain& domain ): - ReducedGaussianGrid::grid_t( detail::grid::reduced_gaussian(nx,domain) ) { -} - -ReducedGaussianGrid::ReducedGaussianGrid( const std::initializer_list& nx ): - ReducedGaussianGrid( std::vector(nx) ) { -} - +ReducedGaussianGrid::ReducedGaussianGrid( const std::initializer_list& nx ) : + ReducedGaussianGrid( std::vector( nx ) ) {} -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/Grid.h b/src/atlas/grid/Grid.h index e639a5376..494e4c633 100644 --- a/src/atlas/grid/Grid.h +++ b/src/atlas/grid/Grid.h @@ -4,23 +4,24 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include "eckit/memory/SharedPtr.h" +#include "atlas/domain/Domain.h" +#include "atlas/grid/Iterator.h" #include "atlas/grid/detail/grid/Grid.h" -#include "atlas/grid/detail/grid/Unstructured.h" #include "atlas/grid/detail/grid/Structured.h" +#include "atlas/grid/detail/grid/Unstructured.h" #include "atlas/projection/Projection.h" -#include "atlas/domain/Domain.h" -#include "atlas/grid/Iterator.h" +#include "eckit/memory/SharedPtr.h" namespace eckit { - class Hash; +class Hash; } namespace atlas { @@ -28,51 +29,51 @@ namespace atlas { //--------------------------------------------------------------------------------------------------------------------- class Grid { - public: - using Implementation = grid::detail::grid::Grid; using Config = Implementation::Config; using Spec = Implementation::Spec; using Domain = atlas::Domain; using Projection = atlas::Projection; - using PointXY = atlas::PointXY; // must be sizeof(double)*2 - using PointLonLat = atlas::PointLonLat; // must be sizeof(double)*2 - + using PointXY = atlas::PointXY; // must be sizeof(double)*2 + using PointLonLat = atlas::PointLonLat; // must be sizeof(double)*2 class IterateXY { public: - using iterator = grid::IteratorXY; - using const_iterator = iterator; - using Predicate = std::function< bool(long) >; + using iterator = grid::IteratorXY; + using const_iterator = iterator; + using Predicate = std::function; + public: - IterateXY(const Implementation& grid, Predicate p) : grid_(grid), p_(p), use_p_(true) {} - IterateXY(const Implementation& grid) : grid_(grid) {} - iterator begin() const { return use_p_ ? grid_.xy_begin(p_) : grid_.xy_begin(); } - iterator end() const { return use_p_ ? grid_.xy_end(p_) : grid_.xy_end(); } + IterateXY( const Implementation& grid, Predicate p ) : grid_( grid ), p_( p ), use_p_( true ) {} + IterateXY( const Implementation& grid ) : grid_( grid ) {} + iterator begin() const { return use_p_ ? grid_.xy_begin( p_ ) : grid_.xy_begin(); } + iterator end() const { return use_p_ ? grid_.xy_end( p_ ) : grid_.xy_end(); } + private: - const Implementation& grid_; - Predicate p_; - bool use_p_{false}; + const Implementation& grid_; + Predicate p_; + bool use_p_{false}; }; class IterateLonLat { public: - using iterator = grid::IteratorLonLat; - using const_iterator = iterator; + using iterator = grid::IteratorLonLat; + using const_iterator = iterator; + public: - IterateLonLat(const Implementation& grid) : grid_(grid) {} - iterator begin() const { return grid_.lonlat_begin(); } - iterator end() const { return grid_.lonlat_end(); } + IterateLonLat( const Implementation& grid ) : grid_( grid ) {} + iterator begin() const { return grid_.lonlat_begin(); } + iterator end() const { return grid_.lonlat_end(); } + private: - const Implementation& grid_; + const Implementation& grid_; }; public: - - IterateXY xy( IterateXY::Predicate p ) const { return IterateXY(*grid_,p); } - IterateXY xy() const { return IterateXY(*grid_); } - IterateLonLat lonlat() const { return IterateLonLat(*grid_); } + IterateXY xy( IterateXY::Predicate p ) const { return IterateXY( *grid_, p ); } + IterateXY xy() const { return IterateXY( *grid_ ); } + IterateLonLat lonlat() const { return IterateLonLat( *grid_ ); } Grid(); Grid( const Grid& ); @@ -93,16 +94,14 @@ class Grid { std::string uid() const { return grid_->uid(); } /// Adds to the hash the information that makes this Grid unique - void hash(eckit::Hash& h) const { return grid_->hash(h); } + void hash( eckit::Hash& h ) const { return grid_->hash( h ); } Spec spec() const { return grid_->spec(); } const Implementation* get() const { return grid_.get(); } private: - eckit::SharedPtr grid_; - }; namespace grid { @@ -137,368 +136,228 @@ class ShiftedLonLatGrid; //--------------------------------------------------------------------------------------------------------------------- - //--------------------------------------------------------------------------------------------------------------------- -class UnstructuredGrid: public Grid { - +class UnstructuredGrid : public Grid { public: - - using grid_t = detail::grid::Unstructured; + using grid_t = detail::grid::Unstructured; public: - UnstructuredGrid(); UnstructuredGrid( const Grid& ); UnstructuredGrid( const Config& ); UnstructuredGrid( const Grid::Implementation* ); - UnstructuredGrid( std::vector* ); // takes ownership - UnstructuredGrid( std::vector&& ); // move constructor + UnstructuredGrid( std::vector* ); // takes ownership + UnstructuredGrid( std::vector&& ); // move constructor UnstructuredGrid( std::initializer_list ); - operator bool() const { - return valid(); - } + operator bool() const { return valid(); } - bool valid() const { - return grid_; - } + bool valid() const { return grid_; } using Grid::xy; void xy( size_t n, double xy[] ) const { - PointXY _xy = grid_->xy(n); - xy[0] = _xy.x(); - xy[1] = _xy.y(); + PointXY _xy = grid_->xy( n ); + xy[0] = _xy.x(); + xy[1] = _xy.y(); } - PointXY xy( size_t n ) const { - return grid_->xy(n); - } - - PointLonLat lonlat( size_t n ) const { - return grid_->lonlat(n); - } + PointXY xy( size_t n ) const { return grid_->xy( n ); } + PointLonLat lonlat( size_t n ) const { return grid_->lonlat( n ); } private: - const grid_t* grid_; }; //--------------------------------------------------------------------------------------------------------------------- -class StructuredGrid: public Grid { - +class StructuredGrid : public Grid { public: - - using grid_t = detail::grid::Structured; - using XSpace = grid_t::XSpace; - using YSpace = grid_t::YSpace; + using grid_t = detail::grid::Structured; + using XSpace = grid_t::XSpace; + using YSpace = grid_t::YSpace; public: - StructuredGrid(); StructuredGrid( const Grid& ); StructuredGrid( const Grid::Implementation* ); StructuredGrid( const std::string& name, const Domain& = Domain() ); StructuredGrid( const Config& ); - StructuredGrid( - const XSpace&, - const YSpace&, - const Projection& = Projection(), - const Domain& = Domain() - ); - - operator bool() const { - return valid(); - } + StructuredGrid( const XSpace&, const YSpace&, const Projection& = Projection(), const Domain& = Domain() ); - bool valid() const { - return grid_; - } + operator bool() const { return valid(); } - inline size_t ny() const { - return grid_->ny(); - } + bool valid() const { return grid_; } - inline size_t nx( size_t j ) const { - return grid_->nx(j); - } + inline size_t ny() const { return grid_->ny(); } - inline const std::vector& nx() const { - return grid_->nx(); - } + inline size_t nx( size_t j ) const { return grid_->nx( j ); } - inline size_t nxmax() const { - return grid_->nxmax(); - } + inline const std::vector& nx() const { return grid_->nx(); } - inline const std::vector& y() const { - return grid_->y(); - } + inline size_t nxmax() const { return grid_->nxmax(); } - inline double x( size_t i, size_t j ) const { - return grid_->x(i,j); - } + inline const std::vector& y() const { return grid_->y(); } - inline double y( size_t j ) const { - return grid_->y(j); - } + inline double x( size_t i, size_t j ) const { return grid_->x( i, j ); } + + inline double y( size_t j ) const { return grid_->y( j ); } using Grid::xy; - void xy( size_t i, size_t j, double xy[] ) const { - grid_->xy(i,j,xy); - } + void xy( size_t i, size_t j, double xy[] ) const { grid_->xy( i, j, xy ); } - void lonlat( size_t i, size_t j, double lonlat[] ) const { - grid_->lonlat(i,j,lonlat); - } + void lonlat( size_t i, size_t j, double lonlat[] ) const { grid_->lonlat( i, j, lonlat ); } - PointXY xy( size_t i, size_t j ) const { - return PointXY( x(i,j), y(j) ); - } + PointXY xy( size_t i, size_t j ) const { return PointXY( x( i, j ), y( j ) ); } - PointLonLat lonlat( size_t i, size_t j ) const { - return grid_->lonlat(i,j); - } + PointLonLat lonlat( size_t i, size_t j ) const { return grid_->lonlat( i, j ); } - inline bool reduced() const { - return grid_->reduced(); - } + inline bool reduced() const { return grid_->reduced(); } - inline bool regular() const { - return not reduced(); - } + inline bool regular() const { return not reduced(); } - bool periodic() const { - return grid_->periodic(); - } + bool periodic() const { return grid_->periodic(); } - const YSpace& yspace() const { - return grid_->yspace(); - } + const YSpace& yspace() const { return grid_->yspace(); } private: - const grid_t* grid_; }; //--------------------------------------------------------------------------------------------------------------------- -class ReducedGrid: public StructuredGrid { - +class ReducedGrid : public StructuredGrid { public: - using StructuredGrid::StructuredGrid; - operator bool() const { - return valid(); - } - - bool valid() const { - return StructuredGrid::valid() && reduced(); - } + operator bool() const { return valid(); } + bool valid() const { return StructuredGrid::valid() && reduced(); } }; //--------------------------------------------------------------------------------------------------------------------- -class RegularGrid: public StructuredGrid { - +class RegularGrid : public StructuredGrid { public: - using StructuredGrid::StructuredGrid; using StructuredGrid::x; using StructuredGrid::xy; - operator bool() const { - return valid(); - } + operator bool() const { return valid(); } - bool valid() const { - return StructuredGrid::valid() && regular(); - } + bool valid() const { return StructuredGrid::valid() && regular(); } - size_t nx() const { - return nxmax(); - } + size_t nx() const { return nxmax(); } - inline double x( size_t i ) const { - return x(i,0); - } + inline double x( size_t i ) const { return x( i, 0 ); } - PointXY xy( size_t i, size_t j ) const { - return PointXY( x(i), y(j ) ); - } + PointXY xy( size_t i, size_t j ) const { return PointXY( x( i ), y( j ) ); } }; //--------------------------------------------------------------------------------------------------------------------- -template< class Grid > +template class Gaussian : public Grid { - public: - using Grid::Grid; - long N() const { return Grid::ny()/2; } + long N() const { return Grid::ny() / 2; } - inline double lon( size_t i, size_t j ) const { - return Grid::x(i,j); - } + inline double lon( size_t i, size_t j ) const { return Grid::x( i, j ); } - inline double lat( size_t j ) const { - return Grid::y(j); - } + inline double lat( size_t j ) const { return Grid::y( j ); } - PointLonLat lonlat( size_t i, size_t j ) const { - return Grid::xy(i,j); - } + PointLonLat lonlat( size_t i, size_t j ) const { return Grid::xy( i, j ); } protected: - bool gaussian() const { - return Grid::domain().global() - && not Grid::projection() - && Grid::yspace().type() == "gaussian"; + return Grid::domain().global() && not Grid::projection() && Grid::yspace().type() == "gaussian"; } }; //--------------------------------------------------------------------------------------------------------------------- class GaussianGrid : public Gaussian { - using grid_t = Gaussian; public: - using grid_t::grid_t; - operator bool() const { - return valid(); - } + operator bool() const { return valid(); } - bool valid() const { - return StructuredGrid::valid() && gaussian(); - } + bool valid() const { return StructuredGrid::valid() && gaussian(); } }; //--------------------------------------------------------------------------------------------------------------------- class ReducedGaussianGrid : public Gaussian { - using grid_t = Gaussian; public: - using grid_t::grid_t; ReducedGaussianGrid( const std::initializer_list& pl ); ReducedGaussianGrid( const std::vector& pl, const Domain& domain = Domain() ); - operator bool() const { - return valid(); - } + operator bool() const { return valid(); } - bool valid() const { - return ReducedGrid::valid() && gaussian(); - } + bool valid() const { return ReducedGrid::valid() && gaussian(); } }; //--------------------------------------------------------------------------------------------------------------------- class RegularGaussianGrid : public Gaussian { - using grid_t = Gaussian; public: - using grid_t::grid_t; - inline double lon( size_t i ) const { - return x(i); - } - - inline double lat( size_t j ) const { - return y(j); - } + inline double lon( size_t i ) const { return x( i ); } - PointLonLat lonlat( size_t i, size_t j ) const { - return xy(i,j); - } + inline double lat( size_t j ) const { return y( j ); } - operator bool() const { - return valid(); - } + PointLonLat lonlat( size_t i, size_t j ) const { return xy( i, j ); } - bool valid() const { - return RegularGrid::valid() && gaussian(); - } + operator bool() const { return valid(); } + bool valid() const { return RegularGrid::valid() && gaussian(); } }; //--------------------------------------------------------------------------------------------------------------------- class RegularLonLatGrid : public RegularGrid { - public: - using RegularGrid::RegularGrid; public: + operator bool() const { return valid(); } - operator bool() const { - return valid(); - } - - bool valid() const { - return RegularGrid::valid() && global_lonlat(); - } + bool valid() const { return RegularGrid::valid() && global_lonlat(); } - inline double lon( size_t i ) const { - return x(i); - } + inline double lon( size_t i ) const { return x( i ); } - inline double lat( size_t j ) const { - return y(j); - } + inline double lat( size_t j ) const { return y( j ); } - PointLonLat lonlat( size_t i, size_t j ) const { - return xy(i,j); - } + PointLonLat lonlat( size_t i, size_t j ) const { return xy( i, j ); } - bool standard() const { return standard_lon() && standard_lat(); } - bool shifted() const { return shifted_lon() && shifted_lat(); } - bool shiftedLon() const { return shifted_lon() && standard_lat(); } - bool shiftedLat() const { return standard_lon() && shifted_lat(); } + bool standard() const { return standard_lon() && standard_lat(); } + bool shifted() const { return shifted_lon() && shifted_lat(); } + bool shiftedLon() const { return shifted_lon() && standard_lat(); } + bool shiftedLat() const { return standard_lon() && shifted_lat(); } protected: + bool global_lonlat() const { return domain().global() && not projection() && yspace().type() == "linear"; } - bool global_lonlat() const { - return domain().global() - && not projection() - && yspace().type() == "linear"; - } - - bool standard_lon() const { - return x(0) == 0.; - } + bool standard_lon() const { return x( 0 ) == 0.; } - bool standard_lat() const { - return y(0) == 90. - && ny()%2 == 1; - } + bool standard_lat() const { return y( 0 ) == 90. && ny() % 2 == 1; } - bool shifted_lon() const { - return x(0) == 0.5*360./nx(); - } + bool shifted_lon() const { return x( 0 ) == 0.5 * 360. / nx(); } - bool shifted_lat() const { - return y(0) == 90.-0.5*180./ny() - && ny()%2 == 0; - } + bool shifted_lat() const { return y( 0 ) == 90. - 0.5 * 180. / ny() && ny() % 2 == 0; } }; //--------------------------------------------------------------------------------------------------------------------- -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/Iterator.h b/src/atlas/grid/Iterator.h index 10138a44c..872571f38 100644 --- a/src/atlas/grid/Iterator.h +++ b/src/atlas/grid/Iterator.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -20,76 +21,50 @@ namespace grid { //--------------------------------------------------------------------------------------------------------------------- class IteratorXY { - public: + IteratorXY( detail::grid::Grid::IteratorXY* iterator ) : iterator_( iterator ) {} - IteratorXY( detail::grid::Grid::IteratorXY* iterator ): - iterator_(iterator) { - } - - bool next( PointXY& xy ) { - return iterator_->next(xy); - } + bool next( PointXY& xy ) { return iterator_->next( xy ); } - PointXY operator *() const { - return iterator_->operator *(); - } + PointXY operator*() const { return iterator_->operator*(); } - const IteratorXY& operator ++() { - iterator_->operator ++(); + const IteratorXY& operator++() { + iterator_->operator++(); return *this; } - bool operator ==(const IteratorXY &other) const { - return iterator_->operator ==(*other.iterator_); - } + bool operator==( const IteratorXY& other ) const { return iterator_->operator==( *other.iterator_ ); } - bool operator !=(const IteratorXY &other) const { - return iterator_->operator !=(*other.iterator_); - } + bool operator!=( const IteratorXY& other ) const { return iterator_->operator!=( *other.iterator_ ); } private: - std::unique_ptr iterator_; }; //--------------------------------------------------------------------------------------------------------------------- class IteratorLonLat { - public: + IteratorLonLat( detail::grid::Grid::IteratorLonLat* iterator ) : iterator_( iterator ) {} - IteratorLonLat( detail::grid::Grid::IteratorLonLat* iterator ): - iterator_(iterator) { - } - - bool next( PointLonLat& lonlat ) { - return iterator_->next(lonlat); - } + bool next( PointLonLat& lonlat ) { return iterator_->next( lonlat ); } - PointLonLat operator *() const { - return iterator_->operator *(); - } + PointLonLat operator*() const { return iterator_->operator*(); } - const IteratorLonLat& operator ++() { - iterator_->operator ++(); + const IteratorLonLat& operator++() { + iterator_->operator++(); return *this; } - bool operator ==(const IteratorLonLat &other) const { - return iterator_->operator ==(*other.iterator_); - } + bool operator==( const IteratorLonLat& other ) const { return iterator_->operator==( *other.iterator_ ); } - bool operator !=(const IteratorLonLat &other) const { - return iterator_->operator !=(*other.iterator_); - } + bool operator!=( const IteratorLonLat& other ) const { return iterator_->operator!=( *other.iterator_ ); } private: - std::unique_ptr iterator_; }; //--------------------------------------------------------------------------------------------------------------------- -} -} +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/Partitioner.cc b/src/atlas/grid/Partitioner.cc index 7ebfaf2e0..b2aece935 100644 --- a/src/atlas/grid/Partitioner.cc +++ b/src/atlas/grid/Partitioner.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -19,99 +20,88 @@ namespace grid { using Factory = detail::partitioner::PartitionerFactory; bool Partitioner::exists( const std::string& type ) { - return Factory::has(type); + return Factory::has( type ); } -Partitioner::Partitioner( const detail::partitioner::Partitioner* partitioner ): - partitioner_( partitioner ) { -} +Partitioner::Partitioner( const detail::partitioner::Partitioner* partitioner ) : partitioner_( partitioner ) {} -Partitioner::Partitioner( const std::string& type ): - partitioner_( Factory::build(type) ) { -} +Partitioner::Partitioner( const std::string& type ) : partitioner_( Factory::build( type ) ) {} -Partitioner::Partitioner( const std::string& type, const size_t nb_partitions): - partitioner_( Factory::build(type,nb_partitions) ) { -} +Partitioner::Partitioner( const std::string& type, const size_t nb_partitions ) : + partitioner_( Factory::build( type, nb_partitions ) ) {} 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 eckit::BadParameter("'type' missing in configuration for Partitioner",Here()); - config.get("partitions",partitions); - return Factory::build(type,partitions); -} + if ( not config.get( "type", type ) ) + throw eckit::BadParameter( "'type' missing in configuration for Partitioner", Here() ); + config.get( "partitions", partitions ); + return Factory::build( type, partitions ); } +} // namespace -Partitioner::Partitioner( const Config& config ): - partitioner_( partitioner_from_config(config) ) { -} +Partitioner::Partitioner( const Config& config ) : partitioner_( partitioner_from_config( config ) ) {} -void Partitioner::partition(const Grid &grid, int part[]) const { - ATLAS_TRACE(); - partitioner_->partition(grid,part); +void Partitioner::partition( const Grid& grid, int part[] ) const { + ATLAS_TRACE(); + partitioner_->partition( grid, part ); } -MatchingMeshPartitioner::MatchingMeshPartitioner() : - Partitioner() { -} +MatchingMeshPartitioner::MatchingMeshPartitioner() : Partitioner() {} -grid::detail::partitioner::Partitioner* matching_mesh_partititioner( const Mesh& mesh, const Partitioner::Config& config ) { - std::string type ("lonlat-polygon"); - config.get("type",type); - return MatchedPartitionerFactory::build(type,mesh); +grid::detail::partitioner::Partitioner* matching_mesh_partititioner( const Mesh& mesh, + const Partitioner::Config& config ) { + std::string type( "lonlat-polygon" ); + config.get( "type", type ); + return MatchedPartitionerFactory::build( type, mesh ); } MatchingMeshPartitioner::MatchingMeshPartitioner( const Mesh& mesh, const Config& config ) : - Partitioner( matching_mesh_partititioner(mesh,config) ) { -} + Partitioner( matching_mesh_partititioner( mesh, config ) ) {} extern "C" { -detail::partitioner::Partitioner* atlas__grid__Partitioner__new( const Partitioner::Config* config) -{ +detail::partitioner::Partitioner* atlas__grid__Partitioner__new( const Partitioner::Config* config ) { detail::partitioner::Partitioner* p; { - Partitioner partitioner(*config); - p = const_cast(partitioner.get()); - p->attach(); + Partitioner partitioner( *config ); + p = const_cast( partitioner.get() ); + p->attach(); } p->detach(); return p; } -detail::partitioner::Partitioner* atlas__grid__MatchingMeshPartitioner__new( const Mesh::Implementation* mesh, const Partitioner::Config* config ) -{ +detail::partitioner::Partitioner* atlas__grid__MatchingMeshPartitioner__new( const Mesh::Implementation* mesh, + const Partitioner::Config* config ) { detail::partitioner::Partitioner* p; { - MatchingMeshPartitioner partitioner( Mesh(mesh), *config ); - p = const_cast(partitioner.get()); - p->attach(); + MatchingMeshPartitioner partitioner( Mesh( mesh ), *config ); + p = const_cast( partitioner.get() ); + p->attach(); } p->detach(); return p; } -Distribution::impl_t* atlas__grid__Partitioner__partition( const Partitioner::Implementation* This, const Grid::Implementation* grid ) -{ - Distribution::impl_t* d; - { - Distribution distribution = This->partition( Grid(grid) ); - d = const_cast(distribution.get()); - d->attach(); - } - d->detach(); - return d; +Distribution::impl_t* atlas__grid__Partitioner__partition( const Partitioner::Implementation* This, + const Grid::Implementation* grid ) { + Distribution::impl_t* d; + { + Distribution distribution = This->partition( Grid( grid ) ); + d = const_cast( distribution.get() ); + d->attach(); + } + d->detach(); + return d; } -void atlas__grid__Partitioner__delete(detail::partitioner::Partitioner* This) -{ +void atlas__grid__Partitioner__delete( detail::partitioner::Partitioner* This ) { delete This; } -} // extern "C" +} // extern "C" -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/Partitioner.h b/src/atlas/grid/Partitioner.h index 0b2171246..4efedf377 100644 --- a/src/atlas/grid/Partitioner.h +++ b/src/atlas/grid/Partitioner.h @@ -4,18 +4,17 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #pragma once -#include "eckit/memory/SharedPtr.h" -#include "atlas/grid/detail/partitioner/Partitioner.h" #include "atlas/grid/Distribution.h" #include "atlas/grid/Grid.h" - +#include "atlas/grid/detail/partitioner/Partitioner.h" +#include "eckit/memory/SharedPtr.h" namespace atlas { namespace grid { @@ -23,18 +22,14 @@ namespace grid { // ------------------------------------------------------------------ class Partitioner { - public: - - using Config = eckit::Parametrisation; - using Implementation = detail::partitioner::Partitioner; + using Config = eckit::Parametrisation; + using Implementation = detail::partitioner::Partitioner; public: - - static bool exists(const std::string& type); + static bool exists( const std::string& type ); public: - Partitioner() {} Partitioner( const Implementation* ); Partitioner( const std::string& type ); @@ -45,7 +40,7 @@ class Partitioner { void partition( const Grid& grid, int part[] ) const; - Distribution partition( const Grid& grid ) const { return Distribution(grid,*this); } + Distribution partition( const Grid& grid ) const { return Distribution( grid, *this ); } size_t nb_partitions() const { return partitioner_->nb_partitions(); } @@ -54,38 +49,33 @@ class Partitioner { Implementation const* get() const { return partitioner_.get(); } private: - eckit::SharedPtr partitioner_; }; // ------------------------------------------------------------------ -class MatchingMeshPartitioner: public Partitioner { - +class MatchingMeshPartitioner : public Partitioner { public: - - using Config = eckit::Parametrisation; + using Config = eckit::Parametrisation; public: - - static bool exists(const std::string& type); + static bool exists( const std::string& type ); public: - MatchingMeshPartitioner(); MatchingMeshPartitioner( const Mesh& mesh, const Config& config ); }; // ------------------------------------------------------------------ - extern "C" { - Partitioner::Implementation* atlas__grid__Partitioner__new( const Partitioner::Config* config ); - Partitioner::Implementation* atlas__grid__MatchingMeshPartitioner__new( const Mesh::Implementation* mesh, const Partitioner::Config* config ); - void atlas__grid__Partitioner__delete(Partitioner::Implementation* This); - Distribution::impl_t* atlas__grid__Partitioner__partition( const Partitioner::Implementation* This, const Grid::Implementation* grid ); +Partitioner::Implementation* atlas__grid__Partitioner__new( const Partitioner::Config* config ); +Partitioner::Implementation* atlas__grid__MatchingMeshPartitioner__new( const Mesh::Implementation* mesh, + const Partitioner::Config* config ); +void atlas__grid__Partitioner__delete( Partitioner::Implementation* This ); +Distribution::impl_t* atlas__grid__Partitioner__partition( const Partitioner::Implementation* This, + const Grid::Implementation* grid ); } - -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/Spacing.cc b/src/atlas/grid/Spacing.cc index 0d2c2a8bc..6c6859ec7 100644 --- a/src/atlas/grid/Spacing.cc +++ b/src/atlas/grid/Spacing.cc @@ -1,38 +1,25 @@ #include "atlas/grid/Spacing.h" -#include "atlas/grid/detail/spacing/LinearSpacing.h" #include "atlas/grid/detail/spacing/GaussianSpacing.h" +#include "atlas/grid/detail/spacing/LinearSpacing.h" namespace atlas { namespace grid { -Spacing::Spacing(): - spacing_( nullptr ){ -} +Spacing::Spacing() : spacing_( nullptr ) {} -Spacing::Spacing( const Spacing& other ): - spacing_( other.spacing_ ) { -} +Spacing::Spacing( const Spacing& other ) : spacing_( other.spacing_ ) {} -Spacing::Spacing( const spacing::Spacing *spacing ): - spacing_( spacing ) { -} +Spacing::Spacing( const spacing::Spacing* spacing ) : spacing_( spacing ) {} -Spacing::Spacing( const eckit::Parametrisation& p ): - spacing_( atlas::grid::spacing::Spacing::create(p) ) { -} +Spacing::Spacing( const eckit::Parametrisation& p ) : spacing_( atlas::grid::spacing::Spacing::create( p ) ) {} LinearSpacing::LinearSpacing( double start, double stop, long N, bool endpoint ) : - Spacing( new atlas::grid::spacing::LinearSpacing(start,stop,N,endpoint) ) { -} + Spacing( new atlas::grid::spacing::LinearSpacing( start, stop, N, endpoint ) ) {} LinearSpacing::LinearSpacing( const Interval& interval, long N, bool endpoint ) : - Spacing( new atlas::grid::spacing::LinearSpacing(interval,N,endpoint) ) { -} - -GaussianSpacing::GaussianSpacing( long N ) : - Spacing( new atlas::grid::spacing::GaussianSpacing(N) ) { -} + Spacing( new atlas::grid::spacing::LinearSpacing( interval, N, endpoint ) ) {} +GaussianSpacing::GaussianSpacing( long N ) : Spacing( new atlas::grid::spacing::GaussianSpacing( N ) ) {} -} // namespace Grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/Spacing.h b/src/atlas/grid/Spacing.h index e3e4d3e54..248def6ef 100644 --- a/src/atlas/grid/Spacing.h +++ b/src/atlas/grid/Spacing.h @@ -1,8 +1,8 @@ #pragma once -#include "eckit/memory/SharedPtr.h" #include "atlas/grid/detail/spacing/Spacing.h" #include "atlas/util/Config.h" +#include "eckit/memory/SharedPtr.h" //--------------------------------------------------------------------------------------------------------------------- @@ -19,75 +19,66 @@ namespace grid { //--------------------------------------------------------------------------------------------------------------------- class Spacing { - public: - - using Implementation = atlas::grid::spacing::Spacing; - using const_iterator = Implementation::const_iterator; - using Interval = Implementation::Interval; - using Spec = Implementation::Spec; + using Implementation = atlas::grid::spacing::Spacing; + using const_iterator = Implementation::const_iterator; + using Interval = Implementation::Interval; + using Spec = Implementation::Spec; public: + Spacing(); + Spacing( const Spacing& ); + Spacing( const atlas::grid::spacing::Spacing* ); + Spacing( const eckit::Parametrisation& ); - Spacing(); - Spacing( const Spacing& ); - Spacing( const atlas::grid::spacing::Spacing* ); - Spacing( const eckit::Parametrisation& ); + operator bool() const { return spacing_; } - operator bool() const { return spacing_; } + operator const atlas::grid::spacing::Spacing*() { return spacing_.get(); } - operator const atlas::grid::spacing::Spacing*() { return spacing_.get(); } + size_t size() const { return spacing_.get()->size(); } - size_t size() const { return spacing_.get()->size(); } + double operator[]( size_t i ) const { return spacing_.get()->operator[]( i ); } - double operator[](size_t i) const { return spacing_.get()->operator[](i); } + const_iterator begin() const { return spacing_.get()->begin(); } + const_iterator end() const { return spacing_.get()->end(); } - const_iterator begin() const { return spacing_.get()->begin(); } - const_iterator end() const { return spacing_.get()->end(); } + double front() const { return spacing_.get()->front(); } + double back() const { return spacing_.get()->back(); } - double front() const { return spacing_.get()->front(); } - double back() const { return spacing_.get()->back(); } + Interval interval() const { return spacing_.get()->interval(); } - Interval interval() const { return spacing_.get()->interval(); } + double min() const { return spacing_.get()->min(); } + double max() const { return spacing_.get()->max(); } - double min() const { return spacing_.get()->min(); } - double max() const { return spacing_.get()->max(); } + std::string type() const { return spacing_.get()->type(); } - std::string type() const { return spacing_.get()->type(); } + Spec spec() const { return spacing_.get()->spec(); } - Spec spec() const { return spacing_.get()->spec(); } - - const atlas::grid::spacing::Spacing* get() const { return spacing_.get(); } + const atlas::grid::spacing::Spacing* get() const { return spacing_.get(); } private: - - eckit::SharedPtr spacing_; + eckit::SharedPtr spacing_; }; //--------------------------------------------------------------------------------------------------------------------- class LinearSpacing : public Spacing { - public: - - using Interval = std::array; - + using Interval = std::array; + public: - - LinearSpacing( double start, double stop, long N, bool endpoint = true ); - LinearSpacing( const Interval&, long N, bool endpoint = true ); + LinearSpacing( double start, double stop, long N, bool endpoint = true ); + LinearSpacing( const Interval&, long N, bool endpoint = true ); }; //--------------------------------------------------------------------------------------------------------------------- class GaussianSpacing : public Spacing { - public: - - GaussianSpacing( long N ); + GaussianSpacing( long N ); }; //--------------------------------------------------------------------------------------------------------------------- -} -} +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/grid/Gaussian.cc b/src/atlas/grid/detail/grid/Gaussian.cc index 08062bb47..2452f4c93 100644 --- a/src/atlas/grid/detail/grid/Gaussian.cc +++ b/src/atlas/grid/detail/grid/Gaussian.cc @@ -5,242 +5,229 @@ #include "eckit/utils/Translator.h" -#include "atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h" #include "atlas/grid/detail/grid/GridBuilder.h" +#include "atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h" namespace atlas { namespace grid { -namespace { // anonymous +namespace { // anonymous -static eckit::Translator to_int; +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(); } static Spacing yspace( const Grid::Config& grid ) { - long N; - grid.get("N",N); + grid.get( "N", N ); Grid::Config config; - config.set("type","gaussian"); - config.set("start", 90.0); - config.set("end", -90.0); - config.set("N",2*N); - return Spacing(config); - + config.set( "type", "gaussian" ); + config.set( "start", 90.0 ); + config.set( "end", -90.0 ); + config.set( "N", 2 * N ); + return Spacing( config ); } static StructuredGrid::XSpace xspace( const std::vector& nx ) { - return StructuredGrid::XSpace({0.,360.},nx,false); - // XSpace( const std::array& interval, const std::vector& N, bool endpoint=true ); - // - // _xspace->nx = nx; - // _xspace->nxmax = 0; - // _xspace->nxmin = std::numeric_limits::max(); - // for( size_t j=0; j<_xspace->ny; ++j ) { - // _xspace->xmin.push_back( 0. ); - // _xspace->xmax.push_back( 360. ); - // _xspace->dx.push_back( 360./_xspace->nx[j] ); - // _xspace->nxmin = std::min( _xspace->nxmin, size_t(_xspace->nx[j]) ); - // _xspace->nxmax = std::max( _xspace->nxmax, size_t(_xspace->nx[j]) ); - // } - // return _xspace; + return StructuredGrid::XSpace( {0., 360.}, nx, false ); + // XSpace( const std::array& interval, const std::vector& N, + // bool endpoint=true ); + // + // _xspace->nx = nx; + // _xspace->nxmax = 0; + // _xspace->nxmin = std::numeric_limits::max(); + // for( size_t j=0; j<_xspace->ny; ++j ) { + // _xspace->xmin.push_back( 0. ); + // _xspace->xmax.push_back( 360. ); + // _xspace->dx.push_back( 360./_xspace->nx[j] ); + // _xspace->nxmin = std::min( _xspace->nxmin, size_t(_xspace->nx[j]) ); + // _xspace->nxmax = std::max( _xspace->nxmax, size_t(_xspace->nx[j]) ); + // } + // return _xspace; } //--------------------------------------------------------------------------------------------------------------------- static class classic_gaussian : public GridBuilder { - public: + classic_gaussian() : GridBuilder( "classic_gaussian", {"^[Nn]([0-9]+)$"} ) {} - classic_gaussian() : GridBuilder("classic_gaussian",{"^[Nn]([0-9]+)$"}) {} - - virtual void print(std::ostream& os) const { - os << std::left << std::setw(20) << "N" << "Classic Gaussian grid"; - } - - virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { - int id; - std::vector matches; - if( match( name, matches, id ) ) { - util::Config grid(config); - int N = to_int(matches[0]); - grid.set("type", type() ); - grid.set("N",N); - return create( grid ); + virtual void print( std::ostream& os ) const { + os << std::left << std::setw( 20 ) << "N" + << "Classic Gaussian grid"; } - return nullptr; - } - virtual const Grid::Implementation* create( const Grid::Config& config ) const { - long N; - config.get("N",N); - std::vector nx(2*N); - detail::pl::classic_gaussian::points_per_latitude_npole_spole( N, nx.data() ); - return new StructuredGrid::grid_t( "N"+std::to_string(N), xspace(nx) , yspace(config), projection(config), domain(config) ); - } + virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { + int id; + std::vector matches; + if ( match( name, matches, id ) ) { + util::Config grid( config ); + int N = to_int( matches[0] ); + grid.set( "type", type() ); + grid.set( "N", N ); + return create( grid ); + } + return nullptr; + } + + virtual const Grid::Implementation* create( const Grid::Config& config ) const { + long N; + config.get( "N", N ); + std::vector nx( 2 * N ); + detail::pl::classic_gaussian::points_per_latitude_npole_spole( N, nx.data() ); + return new StructuredGrid::grid_t( "N" + std::to_string( N ), xspace( nx ), yspace( config ), + projection( config ), domain( config ) ); + } - void force_link() {} + void force_link() {} } classic_gaussian_; //--------------------------------------------------------------------------------------------------------------------- static class octahedral_gaussian : GridBuilder { - public: + octahedral_gaussian() : GridBuilder( "octahedral_gaussian", {"^[Oo]([0-9]+)$"} ) {} - octahedral_gaussian(): GridBuilder("octahedral_gaussian",{"^[Oo]([0-9]+)$"}) {} - - virtual void print(std::ostream& os) const { - os << std::left << std::setw(20) << "O" << "Octahedral Gaussian grid"; - } - - virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { - int id; - std::vector matches; - if( match( name, matches, id ) ) { - util::Config grid(config); - int N = to_int(matches[0]); - grid.set("type", type()); - grid.set("N",N); - return create( grid ); + virtual void print( std::ostream& os ) const { + os << std::left << std::setw( 20 ) << "O" + << "Octahedral Gaussian grid"; } - return nullptr; - } - virtual const Grid::Implementation* create( const Grid::Config& config ) const { - - long N; - config.get("N",N); + virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { + int id; + std::vector matches; + if ( match( name, matches, id ) ) { + util::Config grid( config ); + int N = to_int( matches[0] ); + grid.set( "type", type() ); + grid.set( "N", N ); + return create( grid ); + } + return nullptr; + } - long start = 20; - config.get("nx[0]",start); + virtual const Grid::Implementation* create( const Grid::Config& config ) const { + long N; + config.get( "N", N ); - std::vector nx(2*N); - for(long j=0; j nx( 2 * N ); + for ( long j = 0; j < N; ++j ) { + nx[j] = start + 4 * j; + nx[2 * N - 1 - j] = nx[j]; + } + return new StructuredGrid::grid_t( "O" + std::to_string( N ), xspace( nx ), yspace( config ), + projection( config ), domain( config ) ); } - return new StructuredGrid::grid_t( "O"+std::to_string(N), xspace(nx) , yspace(config), projection(config), domain(config) ); - } - void force_link() {} + void force_link() {} } octahedral_gaussian_; //--------------------------------------------------------------------------------------------------------------------- static class regular_gaussian : GridBuilder { - public: + regular_gaussian() : GridBuilder( "regular_gaussian", {"^[Ff]([0-9]+)$"} ) {} - regular_gaussian(): GridBuilder("regular_gaussian",{"^[Ff]([0-9]+)$"}) {} - - virtual void print(std::ostream& os) const { - os << std::left << std::setw(20) << "F" << "Regular Gaussian grid"; - } - - virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { - int id; - std::vector matches; - if( match( name, matches, id ) ) { - util::Config grid(config); - int N = to_int(matches[0]); - grid.set("type", type()); - grid.set("N",N); - return create( grid ); + virtual void print( std::ostream& os ) const { + os << std::left << std::setw( 20 ) << "F" + << "Regular Gaussian grid"; } - return nullptr; - } - virtual const Grid::Implementation* create( const Grid::Config& config) const { - long N; - config.get("N",N); - std::vector nx(2*N,4*N); - return new StructuredGrid::grid_t( "F"+std::to_string(N), xspace(nx) , yspace(config), projection(config), domain(config) ); - } + virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { + int id; + std::vector matches; + if ( match( name, matches, id ) ) { + util::Config grid( config ); + int N = to_int( matches[0] ); + grid.set( "type", type() ); + grid.set( "N", N ); + return create( grid ); + } + return nullptr; + } - void force_link() {} + virtual const Grid::Implementation* create( const Grid::Config& config ) const { + long N; + config.get( "N", N ); + std::vector nx( 2 * N, 4 * N ); + return new StructuredGrid::grid_t( "F" + std::to_string( N ), xspace( nx ), yspace( config ), + projection( config ), domain( config ) ); + } + + void force_link() {} } regular_gaussian_; //--------------------------------------------------------------------------------------------------------------------- -} // anonymous namespace +} // anonymous namespace namespace detail { namespace grid { void force_link_Gaussian() { - regular_gaussian_.force_link(); - classic_gaussian_.force_link(); - octahedral_gaussian_.force_link(); + regular_gaussian_.force_link(); + classic_gaussian_.force_link(); + octahedral_gaussian_.force_link(); } StructuredGrid::grid_t* reduced_gaussian( const std::vector& nx ) { + Grid::Config yspace; + yspace.set( "type", "gaussian" ); + yspace.set( "start", 90.0 ); + yspace.set( "end", -90.0 ); + yspace.set( "N", nx.size() ); - Grid::Config yspace; - yspace.set("type","gaussian"); - yspace.set("start", 90.0); - yspace.set("end", -90.0); - yspace.set("N",nx.size()); - - return new StructuredGrid::grid_t( xspace(nx) , Spacing(yspace), Projection(), Domain() ); + return new StructuredGrid::grid_t( xspace( nx ), Spacing( yspace ), Projection(), Domain() ); } StructuredGrid::grid_t* reduced_gaussian( const std::vector& nx, const Domain& domain ) { + Grid::Config yspace; + yspace.set( "type", "gaussian" ); + yspace.set( "start", 90.0 ); + yspace.set( "end", -90.0 ); + yspace.set( "N", nx.size() ); - Grid::Config yspace; - yspace.set("type","gaussian"); - yspace.set("start", 90.0); - yspace.set("end", -90.0); - yspace.set("N",nx.size()); - - return new StructuredGrid::grid_t( xspace(nx) , Spacing(yspace), Projection(), domain ); + return new StructuredGrid::grid_t( xspace( nx ), Spacing( yspace ), Projection(), domain ); } template -inline std::vector long_vector(Int nx, long ny) { - std::vector _nx(ny); - for( long j=0; j long_vector( Int nx, long ny ) { + std::vector _nx( ny ); + for ( long j = 0; j < ny; ++j ) { + _nx[j] = nx[j]; + } + return _nx; } extern "C" { - - StructuredGrid::grid_t* atlas__grid__reduced__ReducedGaussian_int(int nx[], long ny) { - return reduced_gaussian( long_vector(nx,ny) ); - } - - StructuredGrid::grid_t* atlas__grid__reduced__ReducedGaussian_long(long nx[], long ny) { - return reduced_gaussian( long_vector(nx,ny) ); - } - +StructuredGrid::grid_t* atlas__grid__reduced__ReducedGaussian_int( int nx[], long ny ) { + return reduced_gaussian( long_vector( nx, ny ) ); } +StructuredGrid::grid_t* atlas__grid__reduced__ReducedGaussian_long( long nx[], long ny ) { + return reduced_gaussian( long_vector( nx, ny ) ); +} +} -} // namespace grid -} // namespace detail +} // namespace grid +} // namespace detail -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/grid/Gaussian.h b/src/atlas/grid/detail/grid/Gaussian.h index 42b34ede9..309af4ea6 100644 --- a/src/atlas/grid/detail/grid/Gaussian.h +++ b/src/atlas/grid/detail/grid/Gaussian.h @@ -10,7 +10,7 @@ namespace grid { StructuredGrid::grid_t* reduced_gaussian( const std::vector& nx ); StructuredGrid::grid_t* reduced_gaussian( const std::vector& nx, const Domain& domain ); -} -} -} -} +} // namespace grid +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/grid/Grid.cc b/src/atlas/grid/detail/grid/Grid.cc index c3c312e4f..18ff4f15e 100644 --- a/src/atlas/grid/detail/grid/Grid.cc +++ b/src/atlas/grid/detail/grid/Grid.cc @@ -4,11 +4,11 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "Grid.h" #include @@ -17,105 +17,81 @@ #include "eckit/utils/MD5.h" #include "atlas/grid.h" +#include "atlas/grid/detail/grid/GridBuilder.h" #include "atlas/mesh/Mesh.h" #include "atlas/runtime/Log.h" -#include "atlas/grid/detail/grid/GridBuilder.h" - namespace atlas { namespace grid { namespace detail { namespace grid { - static void checkSizeOfPoint() { // compile time check support C++11 - static_assert( sizeof(PointXY)==2*sizeof(double), "Grid requires size of Point to be 2*double" ); + static_assert( sizeof( PointXY ) == 2 * sizeof( double ), "Grid requires size of Point to be 2*double" ); // runtime check - ASSERT( sizeof(PointXY) == 2*sizeof(double) ); + ASSERT( sizeof( PointXY ) == 2 * sizeof( double ) ); } - std::string Grid::className() { return "atlas.Grid"; } - -const Grid* Grid::create(const Config& config) { - - +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) ) { + if ( config.get( "type", type ) ) { const GridBuilder::Registry& registry = GridBuilder::typeRegistry(); - if( registry.find(type) != registry.end() ) { - const GridBuilder& gc = *registry.at(type); + if ( registry.find( type ) != registry.end() ) { + const GridBuilder& gc = *registry.at( type ); return gc.create( 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 eckit::BadParameter("no name or type in configuration",Here()); - } else { - throw eckit::BadParameter("name or type in configuration don't exist",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 eckit::BadParameter( "no name or type in configuration", Here() ); } + else { + throw eckit::BadParameter( "name or type in configuration don't exist", Here() ); } } - 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; } + } - 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; - } - } - - // Throw exception - std::ostringstream log; - log << "Could not construct Grid from the name \""<< name<< "\"\n"; - log << "Accepted names are: \n"; - for( GridBuilder::Registry::const_iterator it = registry.begin(); it!=registry.end(); ++it ) { + // Throw exception + std::ostringstream log; + log << "Could not construct Grid from the name \"" << name << "\"\n"; + log << "Accepted names are: \n"; + for ( GridBuilder::Registry::const_iterator it = registry.begin(); it != registry.end(); ++it ) { log << " - " << *it->second << "\n"; - } - throw eckit::BadParameter(log.str()); -// return GridBuilder::createNamed(name); + } + throw eckit::BadParameter( log.str() ); + // return GridBuilder::createNamed(name); } - -Grid::Grid() -{ +Grid::Grid() { checkSizeOfPoint(); } -Grid::~Grid() { -} - +Grid::~Grid() {} Grid::uid_t Grid::uid() const { - if (uid_.empty()) { - uid_ = hash(); - } + if ( uid_.empty() ) { uid_ = hash(); } return uid_; } - std::string Grid::hash() const { - if (hash_.empty()) { + if ( hash_.empty() ) { eckit::MD5 md5; - hash(md5); + hash( md5 ); hash_ = md5.digest(); } return hash_; diff --git a/src/atlas/grid/detail/grid/Grid.h b/src/atlas/grid/detail/grid/Grid.h index 565b0b05b..80a2e8b25 100644 --- a/src/atlas/grid/detail/grid/Grid.h +++ b/src/atlas/grid/detail/grid/Grid.h @@ -4,32 +4,32 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include #include -#include "eckit/memory/Builder.h" -#include "eckit/memory/Owned.h" +#include #include "atlas/domain/Domain.h" #include "atlas/projection/Projection.h" #include "atlas/util/Config.h" #include "atlas/util/Point.h" +#include "eckit/memory/Builder.h" +#include "eckit/memory/Owned.h" -namespace eckit { class Hash; } +namespace eckit { +class Hash; +} namespace atlas { namespace grid { namespace detail { namespace grid { - class Grid : public eckit::Owned { - public: // types - using Projection = atlas::Projection; using Domain = atlas::Domain; using Config = atlas::util::Config; @@ -39,29 +39,26 @@ class Grid : public eckit::Owned { using uid_t = std::string; using hash_t = std::string; - class IteratorXY { public: - using Predicate = std::function; - virtual bool next(PointXY&) =0; - virtual const PointXY operator *() const =0; - virtual const IteratorXY& operator ++() =0; - virtual bool operator ==(const IteratorXY &other) const =0; - virtual bool operator !=(const IteratorXY &other) const =0; + using Predicate = std::function; + virtual bool next( PointXY& ) = 0; + virtual const PointXY operator*() const = 0; + virtual const IteratorXY& operator++() = 0; + virtual bool operator==( const IteratorXY& other ) const = 0; + virtual bool operator!=( const IteratorXY& other ) const = 0; }; class IteratorLonLat { public: - virtual bool next(PointLonLat&) =0; - virtual const PointLonLat operator *() const =0; - virtual const IteratorLonLat& operator ++() =0; - virtual bool operator ==(const IteratorLonLat &other) const =0; - virtual bool operator !=(const IteratorLonLat &other) const =0; + virtual bool next( PointLonLat& ) = 0; + virtual const PointLonLat operator*() const = 0; + virtual const IteratorLonLat& operator++() = 0; + virtual bool operator==( const IteratorLonLat& other ) const = 0; + virtual bool operator!=( const IteratorLonLat& other ) const = 0; }; - public: // methods - static std::string className(); static const Grid* create( const Config& ); @@ -76,14 +73,14 @@ class Grid : public eckit::Owned { /// Human readable name (may not be unique) virtual std::string name() const = 0; - virtual std::string type() const=0; + virtual std::string type() const = 0; /// Unique grid id /// Computed from the hash. Can be used to compare 2 grids. uid_t uid() const; /// Adds to the hash the information that makes this Grid unique - virtual void hash(eckit::Hash&) const = 0; + virtual void hash( eckit::Hash& ) const = 0; /// @returns the hash of the information that makes this Grid unique std::string hash() const; @@ -91,7 +88,8 @@ class Grid : public eckit::Owned { /// @return area represented by the grid const Domain& domain() const { return domain_; } - /// @return projection (mapping between geographic coordinates and grid coordinates) + /// @return projection (mapping between geographic coordinates and grid + /// coordinates) const Projection& projection() const { return projection_; } /// @return number of grid points @@ -101,37 +99,33 @@ class Grid : public eckit::Owned { virtual Spec spec() const = 0; - virtual IteratorXY* xy_begin() const=0; - virtual IteratorXY* xy_end() const=0; - virtual IteratorXY* xy_begin(IteratorXY::Predicate p) const=0; - virtual IteratorXY* xy_end(IteratorXY::Predicate p) const=0; - virtual IteratorLonLat* lonlat_begin() const=0; - virtual IteratorLonLat* lonlat_end() const=0; + virtual IteratorXY* xy_begin() const = 0; + virtual IteratorXY* xy_end() const = 0; + virtual IteratorXY* xy_begin( IteratorXY::Predicate p ) const = 0; + virtual IteratorXY* xy_end( IteratorXY::Predicate p ) const = 0; + virtual IteratorLonLat* lonlat_begin() const = 0; + virtual IteratorLonLat* lonlat_end() const = 0; protected: // methods - /// Fill provided me - virtual void print(std::ostream&) const = 0; + virtual void print( std::ostream& ) const = 0; private: // methods - - friend std::ostream& operator<<(std::ostream& s, const Grid& p) { - p.print(s); + friend std::ostream& operator<<( std::ostream& s, const Grid& p ) { + p.print( s ); return s; } private: // members - /// Cache the unique ID mutable uid_t uid_; /// Cache the hash mutable hash_t hash_; -protected: // members - +protected: // members Projection projection_; - Domain domain_; + Domain domain_; }; } // namespace grid diff --git a/src/atlas/grid/detail/grid/GridBuilder.cc b/src/atlas/grid/detail/grid/GridBuilder.cc index 1a49b89cf..ece5447b4 100644 --- a/src/atlas/grid/detail/grid/GridBuilder.cc +++ b/src/atlas/grid/detail/grid/GridBuilder.cc @@ -4,11 +4,11 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "GridBuilder.h" #include @@ -25,79 +25,69 @@ namespace grid { namespace { -size_t regex_count_parens(const std::string& string) { - size_t out = 0; +size_t regex_count_parens( const std::string& string ) { + size_t out = 0; bool last_was_backslash = 0; - for(const char *step=string.c_str(); *step !='\0'; step++) { - if (*step == '\\' && !last_was_backslash) { + for ( const char* step = string.c_str(); *step != '\0'; step++ ) { + if ( *step == '\\' && !last_was_backslash ) { last_was_backslash = true; continue; } - if (*step == ')' && !last_was_backslash) - out++; + if ( *step == ')' && !last_was_backslash ) out++; last_was_backslash = false; } return out; } -int regex_match_impl( const std::string& string, - const std::string& regex, - std::vector& substr, - bool use_substr, - bool use_case) { +int regex_match_impl( const std::string& string, const std::string& regex, std::vector& substr, + bool use_substr, bool use_case ) { regex_t re; size_t matchcount = 0; - 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; - - ASSERT(compiled_ok); - - int found = !regexec(&re, string.c_str(), matchcount+1, result, 0); - if (found && use_substr) { - substr.resize(matchcount); - //match zero is the whole string; ignore it. - for (size_t i=0; i< matchcount; i++) { - if (result[i+1].rm_eo > 0) { - //GNU peculiarity: match-to-empty marked with -1. - size_t length_of_match = result[i+1].rm_eo - result[i+1].rm_so; - substr[i] = std::string(&string[result[i+1].rm_so],length_of_match); + 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; + + ASSERT( compiled_ok ); + + int found = !regexec( &re, string.c_str(), matchcount + 1, result, 0 ); + if ( found && use_substr ) { + substr.resize( matchcount ); + // match zero is the whole string; ignore it. + for ( size_t i = 0; i < matchcount; i++ ) { + if ( result[i + 1].rm_eo > 0 ) { + // GNU peculiarity: match-to-empty marked with -1. + size_t length_of_match = result[i + 1].rm_eo - result[i + 1].rm_so; + substr[i] = std::string( &string[result[i + 1].rm_so], length_of_match ); } } } - regfree(&re); + regfree( &re ); return found; } class Regex { - public: - Regex(const std::string& regex, bool use_case=true) : - regex_(regex), - use_case_(use_case) { - } - bool match(const std::string& string) const { +public: + Regex( const std::string& regex, bool use_case = true ) : regex_( regex ), use_case_( use_case ) {} + bool match( const std::string& string ) const { std::vector substr; - return regex_match_impl(string,regex_,substr,false,use_case_); + return regex_match_impl( string, regex_, substr, false, use_case_ ); } - bool match(const std::string& string, std::vector& substr) const { - return regex_match_impl(string,regex_,substr,true,use_case_); + bool match( const std::string& string, std::vector& substr ) const { + return regex_match_impl( string, regex_, substr, true, use_case_ ); } operator std::string() const { return regex_; } - private: + +private: std::string regex_; bool use_case_; }; -static eckit::Mutex *local_mutex = 0; -static GridBuilder::Registry *named_grids = 0; -static GridBuilder::Registry *typed_grids = 0; - +static eckit::Mutex* local_mutex = 0; +static GridBuilder::Registry* named_grids = 0; +static GridBuilder::Registry* typed_grids = 0; static pthread_once_t once = PTHREAD_ONCE_INIT; @@ -116,121 +106,107 @@ namespace grid { void force_link_Gaussian(); void force_link_LonLat(); void force_link_Regional(); -} -} +} // namespace grid +} // namespace detail const GridBuilder::Registry& GridBuilder::nameRegistry() { - detail::grid::force_link_Gaussian(); - detail::grid::force_link_LonLat(); - detail::grid::force_link_Regional(); - return *named_grids; + detail::grid::force_link_Gaussian(); + detail::grid::force_link_LonLat(); + detail::grid::force_link_Regional(); + return *named_grids; } const GridBuilder::Registry& GridBuilder::typeRegistry() { - return *typed_grids; + return *typed_grids; } +GridBuilder::GridBuilder( const std::string& type ) : names_(), type_( type ) { + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); -GridBuilder::GridBuilder( const std::string& type ) : - names_(), - type_(type) { - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); - - ASSERT(typed_grids->find(type_) == typed_grids->end()); - (*typed_grids)[type] = this; + ASSERT( typed_grids->find( type_ ) == typed_grids->end() ); + ( *typed_grids )[type] = this; } - -GridBuilder::GridBuilder( const std::vector& names ) : - names_(names), - type_() { - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); - for( const std::string& name : names_ ) { - ASSERT(named_grids->find(name) == named_grids->end()); - (*named_grids)[name] = this; - } +GridBuilder::GridBuilder( const std::vector& names ) : names_( names ), type_() { + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); + for ( const std::string& name : names_ ) { + ASSERT( named_grids->find( name ) == named_grids->end() ); + ( *named_grids )[name] = this; + } } GridBuilder::GridBuilder( const std::string& type, const std::vector& names ) : - names_(names), - type_(type) { - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); - - for( const std::string& name : names_ ) { - ASSERT(named_grids->find(name) == named_grids->end()); - (*named_grids)[name] = this; - } - - ASSERT(typed_grids->find(type_) == typed_grids->end()); - (*typed_grids)[type] = this; + names_( names ), + type_( type ) { + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); + + for ( const std::string& name : names_ ) { + ASSERT( named_grids->find( name ) == named_grids->end() ); + ( *named_grids )[name] = this; + } + + ASSERT( typed_grids->find( type_ ) == typed_grids->end() ); + ( *typed_grids )[type] = this; } GridBuilder::~GridBuilder() { - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); - for( const std::string& name : names_ ) { - ASSERT(named_grids->find(name) != named_grids->end()); - (*named_grids).erase(name); + for ( const std::string& name : names_ ) { + ASSERT( named_grids->find( name ) != named_grids->end() ); + ( *named_grids ).erase( name ); } - if( not type_.empty() ) { - ASSERT(typed_grids->find(type_) != typed_grids->end()); - (*typed_grids).erase(type_); + if ( not type_.empty() ) { + ASSERT( typed_grids->find( type_ ) != typed_grids->end() ); + ( *typed_grids ).erase( type_ ); } } const Grid::Implementation* GridBuilder::create( const Grid::Config& config ) const { + eckit::Factory& fact = eckit::Factory::instance(); - eckit::Factory& fact = eckit::Factory::instance(); - - std::string name; - if (config.get("name",name)) { // ignore any further configuration - return create(name); - } - - std::string type; - if (config.get("type",type) && fact.exists(type)) { - return fact.get(type).create(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 eckit::BadParameter("no name or type in configuration",Here()); - } else { - throw eckit::BadParameter("name or type in configuration don't exist",Here()); - } - - return nullptr; -} + std::string name; + if ( config.get( "name", name ) ) { // ignore any further configuration + return create( name ); + } + std::string type; + if ( config.get( "type", type ) && fact.exists( type ) ) { return fact.get( type ).create( 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 eckit::BadParameter( "no name or type in configuration", Here() ); } + else { + throw eckit::BadParameter( "name or type in configuration don't exist", Here() ); + } -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; - ++id; - } - return false; + return nullptr; } -std::string GridBuilder::type() const { return type_; } +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; + ++id; + } + return false; +} + +std::string GridBuilder::type() const { + return type_; +} std::ostream& operator<<( std::ostream& os, const GridBuilder& g ) { - g.print(os); - return os; + g.print( os ); + return os; } //--------------------------------------------------------------------------------------------------------------------- -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/grid/GridBuilder.h b/src/atlas/grid/detail/grid/GridBuilder.h index 8b309a2ed..48d979042 100644 --- a/src/atlas/grid/detail/grid/GridBuilder.h +++ b/src/atlas/grid/detail/grid/GridBuilder.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -22,40 +23,34 @@ namespace atlas { namespace grid { class GridBuilder { - public: - - using Registry = std::map< std::string, GridBuilder*>; - static const Registry& nameRegistry(); - static const Registry& typeRegistry(); + using Registry = std::map; + static const Registry& nameRegistry(); + static const Registry& typeRegistry(); public: + GridBuilder( const std::string& names ); + GridBuilder( const std::vector& names ); + GridBuilder( const std::string& type, const std::vector& names ); - GridBuilder( const std::string& names ); - GridBuilder( const std::vector& names ); - GridBuilder( const std::string& type, const std::vector& names ); - - virtual ~GridBuilder(); + virtual ~GridBuilder(); - virtual const Grid::Implementation* create( const Grid::Config& ) const; + virtual const Grid::Implementation* create( const Grid::Config& ) const; - virtual const Grid::Implementation* create( const std::string&, const Grid::Config& = Grid::Config() ) const =0; + virtual const Grid::Implementation* create( const std::string&, const Grid::Config& = Grid::Config() ) const = 0; - std::string type() const; + std::string type() const; protected: - - bool match( const std::string& string, std::vector& matches, int &id ) const; + bool match( const std::string& string, std::vector& matches, int& id ) const; private: + friend std::ostream& operator<<( std::ostream& os, const GridBuilder& g ); - friend std::ostream& operator<<( std::ostream& os, const GridBuilder& g ); - - virtual void print(std::ostream& os) const =0; - - std::vector names_; - std::string type_; + virtual void print( std::ostream& os ) const = 0; + std::vector names_; + std::string type_; }; } // namespace grid diff --git a/src/atlas/grid/detail/grid/LonLat.cc b/src/atlas/grid/detail/grid/LonLat.cc index 3b561717f..4616aa24d 100644 --- a/src/atlas/grid/detail/grid/LonLat.cc +++ b/src/atlas/grid/detail/grid/LonLat.cc @@ -6,284 +6,254 @@ namespace atlas { namespace grid { -namespace { // anonymous +namespace { // anonymous -static eckit::Translator to_int; +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(); } struct Shift { - - enum Bits { + enum Bits + { NONE = 0, - LAT = (1<<1), - LON = (1<<2) + LAT = ( 1 << 1 ), + LON = ( 1 << 2 ) }; - Shift(int bits=NONE) : bits_(bits) { - } + Shift( int bits = NONE ) : bits_( bits ) {} - Shift(bool shift_lon, bool shift_lat) : bits_((shift_lon? LON:NONE) | (shift_lat? LAT:NONE)) { - } + Shift( bool shift_lon, bool shift_lat ) : bits_( ( shift_lon ? LON : NONE ) | ( shift_lat ? LAT : NONE ) ) {} - bool operator()(int bits) const { - return (bits_ & bits) == bits; - } + bool operator()( int bits ) const { return ( bits_ & bits ) == bits; } const int bits_; - }; using XSpace = StructuredGrid::XSpace; -StructuredGrid::grid_t* create_lonlat(long nlon, long nlat, Shift shift, const Grid::Config& config = Grid::Config() ) { +StructuredGrid::grid_t* create_lonlat( long nlon, long nlat, Shift shift, + const Grid::Config& config = Grid::Config() ) { + bool shifted_x = shift( Shift::LON ); + bool shifted_y = shift( Shift::LAT ); - bool shifted_x = shift(Shift::LON); - bool shifted_y = shift(Shift::LAT); - - double start_x = (shifted_x ? 0.5 : 0.0)*360.0/double(nlon); - std::array interval_x = { start_x, start_x+360. }; - bool no_endpoint = false; - XSpace xspace( interval_x, std::vector(nlat,nlon), no_endpoint ); + double start_x = ( shifted_x ? 0.5 : 0.0 ) * 360.0 / double( nlon ); + std::array interval_x = {start_x, start_x + 360.}; + bool no_endpoint = false; + XSpace xspace( interval_x, std::vector( nlat, nlon ), no_endpoint ); // spacing is uniform in y // If shifted_y, the whole interval is shifted by -dy/2, and last latitude // would be -90-dy/2 (below -90!!!), if endpoint=true. // Instead, we set endpoint=false so that last latitude is -90+dy/2 instead. Grid::Config config_spacing; - config_spacing.set("type","linear"); - config_spacing.set("start", 90.0 -(shifted_y ? 90.0/double(nlat) : 0.0) ); - config_spacing.set("end", -90.0 -(shifted_y ? 90.0/double(nlat) : 0.0) ); - config_spacing.set("endpoint", shifted_y ? false : true); - config_spacing.set("N",nlat); - Spacing yspace(config_spacing); + config_spacing.set( "type", "linear" ); + config_spacing.set( "start", 90.0 - ( shifted_y ? 90.0 / double( nlat ) : 0.0 ) ); + config_spacing.set( "end", -90.0 - ( shifted_y ? 90.0 / double( nlat ) : 0.0 ) ); + config_spacing.set( "endpoint", shifted_y ? false : true ); + config_spacing.set( "N", nlat ); + Spacing yspace( config_spacing ); 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; - if( shifted_x and shifted_y ) - name = "S"; - else if( shifted_x and not shifted_y ) - name = "Slon"; - else if( not shifted_x and shifted_y ) - name = "Slat"; + if ( shifted_x and shifted_y ) + name = "S"; + else if ( shifted_x and not shifted_y ) + name = "Slon"; + else if ( not shifted_x and shifted_y ) + name = "Slat"; else - name = "L"; + name = "L"; - name += std::to_string(nlon)+"x"+std::to_string(nlat); + name += std::to_string( nlon ) + "x" + std::to_string( nlat ); - return new StructuredGrid::grid_t( name, xspace, yspace, projection, domain(config) ); + return new StructuredGrid::grid_t( name, xspace, yspace, projection, domain( config ) ); } StructuredGrid::grid_t* create_lonlat( const Grid::Config& config, Shift shift ) { + bool shifted_y = shift( Shift::LAT ); - bool shifted_y = shift(Shift::LAT); - - long N, nx, ny; - // dimensions - if ( config.get("N",N) ) { - nx = 4*N; - ny = shifted_y ? 2*N : 2*N+1; - } else if( config.get("nx",nx) - && config.get("ny",ny) ) { - } else { - throw eckit::BadParameter("Configuration requires either N, or (nx,ny)",Here()); - } - - return create_lonlat(nx,ny,shift,config); + long N, nx, ny; + // dimensions + if ( config.get( "N", N ) ) { + nx = 4 * N; + ny = shifted_y ? 2 * N : 2 * N + 1; + } + else if ( config.get( "nx", nx ) && config.get( "ny", ny ) ) { + } + else { + throw eckit::BadParameter( "Configuration requires either N, or (nx,ny)", Here() ); + } + return create_lonlat( nx, ny, shift, config ); } //--------------------------------------------------------------------------------------------------------------------- static class regular_lonlat : public GridBuilder { - public: + regular_lonlat() : GridBuilder( "regular_lonlat", {"^[Ll]([0-9]+)x([0-9]+)$", "^[Ll]([0-9]+)$"} ) {} - regular_lonlat(): GridBuilder( "regular_lonlat", { - "^[Ll]([0-9]+)x([0-9]+)$", - "^[Ll]([0-9]+)$" } ){} - - virtual void print(std::ostream& os) const { - os << std::left << std::setw(20) << "Lx / L" << "Regular longitude-latitude grid"; - } - - virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { - int id; - std::vector matches; - if( match( name, matches, id ) ) { - - util::Config grid(config); - grid.set("type", type()); - - if( id == 0 ) { - grid.set( "nx", to_int(matches[0]) ); - grid.set( "ny", to_int(matches[1]) ); - return create( grid ); - } - - if( id == 1 ) { - grid.set( "N", to_int(matches[0]) ); - return create( grid ); - } + virtual void print( std::ostream& os ) const { + os << std::left << std::setw( 20 ) << "Lx / L" + << "Regular longitude-latitude grid"; + } + virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { + int id; + std::vector matches; + if ( match( name, matches, id ) ) { + util::Config grid( config ); + grid.set( "type", type() ); + + if ( id == 0 ) { + grid.set( "nx", to_int( matches[0] ) ); + grid.set( "ny", to_int( matches[1] ) ); + return create( grid ); + } + + if ( id == 1 ) { + grid.set( "N", to_int( matches[0] ) ); + return create( grid ); + } + } + return nullptr; } - return nullptr; - } - virtual const Grid::Implementation* create( const Grid::Config& config ) const { - return create_lonlat( config, Shift(false,false) ); - } + virtual const Grid::Implementation* create( const Grid::Config& config ) const { + return create_lonlat( config, Shift( false, false ) ); + } - void force_link() {} + void force_link() {} } regular_lonlat_; //--------------------------------------------------------------------------------------------------------------------- static class shifted_lonlat : public GridBuilder { - public: + shifted_lonlat() : GridBuilder( "shifted_lonlat", {"^[Ss]([0-9]+)x([0-9]+)$", "^[Ss]([0-9]+)$"} ) {} - shifted_lonlat(): GridBuilder( "shifted_lonlat", { - "^[Ss]([0-9]+)x([0-9]+)$", - "^[Ss]([0-9]+)$" } ){} - - virtual void print(std::ostream& os) const { - os << std::left << std::setw(20) << "Sx / S" << "Shifted longitude-latitude grid"; - } - - virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { - int id; - std::vector matches; - if( match( name, matches, id ) ) { - - util::Config grid(config); - grid.set("type", type()); - - if( id == 0 ) { - grid.set( "nx", to_int(matches[0]) ); - grid.set( "ny", to_int(matches[1]) ); - return create( grid ); - } - - if( id == 1 ) { - grid.set( "N", to_int(matches[0]) ); - return create( grid ); - } + virtual void print( std::ostream& os ) const { + os << std::left << std::setw( 20 ) << "Sx / S" + << "Shifted longitude-latitude grid"; + } + virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { + int id; + std::vector matches; + if ( match( name, matches, id ) ) { + util::Config grid( config ); + grid.set( "type", type() ); + + if ( id == 0 ) { + grid.set( "nx", to_int( matches[0] ) ); + grid.set( "ny", to_int( matches[1] ) ); + return create( grid ); + } + + if ( id == 1 ) { + grid.set( "N", to_int( matches[0] ) ); + return create( grid ); + } + } + return nullptr; } - return nullptr; - } - virtual const Grid::Implementation* create( const Grid::Config& config ) const { - return create_lonlat( config, Shift(true,true) ); - } + virtual const Grid::Implementation* create( const Grid::Config& config ) const { + return create_lonlat( config, Shift( true, true ) ); + } - void force_link() {} + void force_link() {} } shifted_lonlat_; //--------------------------------------------------------------------------------------------------------------------- static class shifted_lon : public GridBuilder { - public: + shifted_lon() : + GridBuilder( "shifted_lon", {"^[Ss][Ll][Oo][Nn]([0-9]+)x([0-9]+)$", "^[Ss][Ll][Oo][Nn]([0-9]+)$"} ) {} - shifted_lon(): GridBuilder( "shifted_lon", { - "^[Ss][Ll][Oo][Nn]([0-9]+)x([0-9]+)$", - "^[Ss][Ll][Oo][Nn]([0-9]+)$" } ){} - - virtual void print(std::ostream& os) const { - os << std::left << std::setw(20) << "Slonx / Slon" << "Shifted longitude grid"; - } - - virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { - int id; - std::vector matches; - if( match( name, matches, id ) ) { - - util::Config grid(config); - grid.set("type", type()); - - if( id == 0 ) { - grid.set( "nx", to_int(matches[0]) ); - grid.set( "ny", to_int(matches[1]) ); - return create( grid ); - } - - if( id == 1 ) { - grid.set( "N", to_int(matches[0]) ); - return create( grid ); - } + virtual void print( std::ostream& os ) const { + os << std::left << std::setw( 20 ) << "Slonx / Slon" + << "Shifted longitude grid"; + } + virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { + int id; + std::vector matches; + if ( match( name, matches, id ) ) { + util::Config grid( config ); + grid.set( "type", type() ); + + if ( id == 0 ) { + grid.set( "nx", to_int( matches[0] ) ); + grid.set( "ny", to_int( matches[1] ) ); + return create( grid ); + } + + if ( id == 1 ) { + grid.set( "N", to_int( matches[0] ) ); + return create( grid ); + } + } + return nullptr; } - return nullptr; - } - virtual const Grid::Implementation* create( const Grid::Config& config ) const { - return create_lonlat( config, Shift(true,false) ); - } + virtual const Grid::Implementation* create( const Grid::Config& config ) const { + return create_lonlat( config, Shift( true, false ) ); + } - void force_link() {} + void force_link() {} } shifted_lon_; - //--------------------------------------------------------------------------------------------------------------------- static class shifted_lat : public GridBuilder { - public: + shifted_lat() : + GridBuilder( "shifted_lat", {"^[Ss][Ll][Aa][Tt]([0-9]+)x([0-9]+)$", "^[Ss][Ll][Aa][Tt]([0-9]+)$"} ) {} - shifted_lat(): GridBuilder( "shifted_lat", { - "^[Ss][Ll][Aa][Tt]([0-9]+)x([0-9]+)$", - "^[Ss][Ll][Aa][Tt]([0-9]+)$" } ){} - - virtual void print(std::ostream& os) const { - os << std::left << std::setw(20) << "Slatx / Slat" << "Shifted latitude grid"; - } - - virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { - int id; - std::vector matches; - if( match( name, matches, id ) ) { - - util::Config grid(config); - grid.set("type", type()); - - if( id == 0 ) { - grid.set( "nx", to_int(matches[0]) ); - grid.set( "ny", to_int(matches[1]) ); - return create( grid ); - } - - if( id == 1 ) { - grid.set( "N", to_int(matches[0]) ); - return create( grid ); - } + virtual void print( std::ostream& os ) const { + os << std::left << std::setw( 20 ) << "Slatx / Slat" + << "Shifted latitude grid"; + } + virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { + int id; + std::vector matches; + if ( match( name, matches, id ) ) { + util::Config grid( config ); + grid.set( "type", type() ); + + if ( id == 0 ) { + grid.set( "nx", to_int( matches[0] ) ); + grid.set( "ny", to_int( matches[1] ) ); + return create( grid ); + } + + if ( id == 1 ) { + grid.set( "N", to_int( matches[0] ) ); + return create( grid ); + } + } + return nullptr; } - return nullptr; - } - virtual const Grid::Implementation* create( const Grid::Config& config ) const { - return create_lonlat( config, Shift(false,true) ); - } + virtual const Grid::Implementation* create( const Grid::Config& config ) const { + return create_lonlat( config, Shift( false, true ) ); + } - void force_link() {} + void force_link() {} } shifted_lat_; @@ -295,14 +265,14 @@ namespace detail { namespace grid { void force_link_LonLat() { - regular_lonlat_.force_link(); - shifted_lonlat_.force_link(); - shifted_lon_.force_link(); - shifted_lat_.force_link(); + regular_lonlat_.force_link(); + shifted_lonlat_.force_link(); + shifted_lon_.force_link(); + shifted_lat_.force_link(); } -} -} +} // namespace grid +} // namespace detail } // namespace grid } // namespace atlas diff --git a/src/atlas/grid/detail/grid/Regional.cc b/src/atlas/grid/detail/grid/Regional.cc index 7d109d95c..888fb1088 100644 --- a/src/atlas/grid/detail/grid/Regional.cc +++ b/src/atlas/grid/detail/grid/Regional.cc @@ -9,306 +9,274 @@ using YSpace = atlas::grid::StructuredGrid::YSpace; namespace atlas { namespace grid { -namespace { // anonymous +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(); } struct ConfigParser { + struct Parsed { + Parsed() {} + Parsed( std::initializer_list interval ) : min( *interval.begin() ), max( *( interval.begin() + 1 ) ) {} + double min; + double max; + long N; + double step; + bool endpoint = {true}; + }; + bool valid = {false}; + Parsed x; + Parsed y; + + double step( double min, double max, long N, bool endpoint = true ) { + double l = max - min; + if ( endpoint && N > 1 ) + return l / double( N - 1 ); + else + return l / double( N ); + } - struct Parsed { - Parsed() {} - Parsed( std::initializer_list interval ) : min(*interval.begin()), max(*(interval.begin()+1)) {} - double min; - double max; - long N; - double step; - bool endpoint = {true}; - }; - bool valid = {false}; - Parsed x; - Parsed y; - - double step(double min,double max, long N, bool endpoint=true) { - double l = max-min; - if( endpoint && N>1 ) - return l/double(N-1); - else - return l/double(N); - } - - static bool parse( const Projection&, const Grid::Config&, Parsed& x, Parsed& y ); - - template - static bool parse( const Projection&, const Grid::Config&, Parsed& x, Parsed& y ); + static bool parse( const Projection&, const Grid::Config&, Parsed& x, Parsed& y ); + template + static bool parse( const Projection&, const Grid::Config&, Parsed& x, Parsed& y ); }; struct Parse_llc_step : ConfigParser { - Parse_llc_step( const Projection& p, const Grid::Config& config ) { - std::vector centre_lonlat; + Parse_llc_step( const Projection& p, const Grid::Config& config ) { + std::vector centre_lonlat; - 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); + 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); - ATLAS_DEBUG_VAR( PointXY(centre) ); + double centre[] = {centre_lonlat[0], centre_lonlat[1]}; + p.lonlat2xy( centre ); + ATLAS_DEBUG_VAR( PointXY( centre ) ); - double lx = x.step * double(x.N-1); - double ly = y.step * double(y.N-1); + double lx = x.step * double( x.N - 1 ); + double ly = y.step * double( y.N - 1 ); - x.min = centre[0] - 0.5 * lx; - x.max = centre[0] + 0.5 * lx; - y.min = centre[1] - 0.5 * ly; - y.max = centre[1] + 0.5 * ly; - - } + x.min = centre[0] - 0.5 * lx; + x.max = centre[0] + 0.5 * lx; + y.min = centre[1] - 0.5 * ly; + y.max = centre[1] + 0.5 * ly; + } }; struct Parse_bounds_xy : ConfigParser { - Parse_bounds_xy( const Projection& p, const Grid::Config& config ) { - 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; - - x.step = step(x.min,x.max,x.N); - y.step = step(y.min,y.max,y.N); - } + Parse_bounds_xy( const Projection& p, const Grid::Config& config ) { + 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; + + x.step = step( x.min, x.max, x.N ); + y.step = step( y.min, y.max, y.N ); + } }; struct Parse_bounds_lonlat : ConfigParser { - Parse_bounds_lonlat( const Projection& p, const Grid::Config& config ) { - valid = config.get("nx",x.N) - && config.get("ny",y.N) - && config.get("north",y.max) // unrotated! - && config.get("south",y.min) // unrotated! - && config.get("east", x.max) // unrotated! - && config.get("west", x.min); // unrotated! - - // This version only works with a "lonlat" or "rotated_lonlat" projection!!! - if( valid ) { - bool valid_projection = not p or p.type() == "rotated_lonlat"; - if( not valid_projection ) { - std::stringstream errmsg; - errmsg << "This configuration requires that the projection is \"lonlat\" or \"rotated_lonlat\". Received: " << p.type(); - errmsg << "\n" "p.bool() = " << bool(p); - throw eckit::BadParameter(errmsg.str(),Here()); - } + Parse_bounds_lonlat( const Projection& p, const Grid::Config& config ) { + valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && config.get( "north", y.max ) // unrotated! + && config.get( "south", y.min ) // unrotated! + && config.get( "east", x.max ) // unrotated! + && config.get( "west", x.min ); // unrotated! + + // This version only works with a "lonlat" or "rotated_lonlat" projection!!! + if ( valid ) { + bool valid_projection = not p or p.type() == "rotated_lonlat"; + if ( not valid_projection ) { + std::stringstream errmsg; + errmsg << "This configuration requires that the projection is " + "\"lonlat\" or \"rotated_lonlat\". Received: " + << p.type(); + errmsg << "\n" + "p.bool() = " + << bool( p ); + throw eckit::BadParameter( errmsg.str(), Here() ); + } + } + + if ( not valid ) return; + + x.step = step( x.min, x.max, x.N ); + y.step = step( y.min, y.max, y.N ); } - - if( not valid ) return; - - x.step = step(x.min,x.max,x.N); - y.step = step(y.min,y.max,y.N); - } }; struct Parse_ll00_ll11 : ConfigParser { - Parse_ll00_ll11( const Projection& p, const Grid::Config& config ) { - std::vector sw; - std::vector ne; - valid = config.get("nx",x.N) - && config.get("ny",y.N) - && config.get("lonlat(xmin,ymin)",sw) // includes rotation - && config.get("lonlat(xmax,ymax)",ne); // includes rotation - - if( not valid ) return; - - p.lonlat2xy(sw.data()); - p.lonlat2xy(ne.data()); - x.min = sw[0]; x.max = ne[0]; - y.min = sw[1]; y.max = ne[1]; - - x.step = step(x.min,x.max,x.N); - y.step = step(y.min,y.max,y.N); - } + Parse_ll00_ll11( const Projection& p, const Grid::Config& config ) { + std::vector sw; + std::vector ne; + valid = config.get( "nx", x.N ) && config.get( "ny", y.N ) && + config.get( "lonlat(xmin,ymin)", sw ) // includes rotation + && config.get( "lonlat(xmax,ymax)", ne ); // includes rotation + + if ( not valid ) return; + + p.lonlat2xy( sw.data() ); + p.lonlat2xy( ne.data() ); + x.min = sw[0]; + x.max = ne[0]; + y.min = sw[1]; + y.max = ne[1]; + + x.step = step( x.min, x.max, x.N ); + y.step = step( y.min, y.max, y.N ); + } }; struct Parse_ll00_step : ConfigParser { - Parse_ll00_step( const Projection& p, const Grid::Config& config ) { - std::vector sw; - 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; - - p.lonlat2xy(sw.data()); - x.min = sw[0]; - y.min = sw[1]; - - x.max = x.min + x.step * (x.N-1); - y.max = y.min + y.step * (y.N-1); - } -}; + Parse_ll00_step( const Projection& p, const Grid::Config& config ) { + std::vector sw; + 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; + + p.lonlat2xy( sw.data() ); + x.min = sw[0]; + y.min = sw[1]; + x.max = x.min + x.step * ( x.N - 1 ); + y.max = y.min + y.step * ( y.N - 1 ); + } +}; template bool ConfigParser::parse( const Projection& projection, const Grid::Config& config, Parsed& x, Parsed& y ) { - Parser p(projection,config); - if( p.valid ) { - x = p.x; - y = p.y; - return true; // success - } - return false; // failure + Parser p( projection, config ); + if ( p.valid ) { + x = p.x; + y = p.y; + return true; // success + } + return false; // failure } 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; - // bounding box using 4 variables (any projection allowed) - if( ConfigParser::parse< Parse_bounds_xy >( projection, config, x, y) ) return true; - - // centre of domain and increments (any projection allowed) - if( ConfigParser::parse< Parse_llc_step >( projection, config, x, y) ) return true; + // centre of domain and increments (any projection allowed) + if ( ConfigParser::parse( projection, config, x, y ) ) return true; - // bottom-left of domain and increments (any projection allowed) - if( ConfigParser::parse< Parse_ll00_step >( projection, config, x, y) ) return true; + // bottom-left of domain and increments (any projection allowed) + if ( ConfigParser::parse( projection, config, x, y ) ) return true; - // bounding box using two points defined in lonlat (any projection allowed) - if( ConfigParser::parse< Parse_ll00_ll11 >( 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 here on, projection must be (rotated) lonlat + // From here on, projection must be (rotated) lonlat - // bounding box using 4 variables (south west north east) - if( ConfigParser::parse< Parse_bounds_lonlat >( projection, config, x, y) ) return true; + // bounding box using 4 variables (south west north east) + if ( ConfigParser::parse( projection, config, x, y ) ) return true; - return false; + return false; } - static class regional : public GridBuilder { - public: + regional() : GridBuilder( "regional" ) {} - regional() : GridBuilder("regional") {} - - virtual void print(std::ostream& os) const { - //os << std::left << std::setw(20) << "O" << "Octahedral Gaussian grid"; - } - - virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { - eckit::NotImplemented( "There are no named regional grids implemented.", Here() ); - return nullptr; - } - - virtual const Grid::Implementation* create( const Grid::Config& config ) const { - - - // read projection subconfiguration - Projection projection; - { - util::Config config_proj; - if ( config.get("projection",config_proj) ) { - projection = Projection( config_proj ); - } + virtual void print( std::ostream& os ) const { + // os << std::left << std::setw(20) << "O" << "Octahedral Gaussian + // grid"; } - // Read grid configuration - ConfigParser::Parsed x,y; - if( not ConfigParser::parse(projection,config,x,y) ) { - throw eckit::BadParameter("Could not parse configuration for RegularRegional grid", Here()); + virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { + eckit::NotImplemented( "There are no named regional grids implemented.", Here() ); + return nullptr; } - YSpace yspace( 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); + virtual const Grid::Implementation* create( const Grid::Config& config ) const { + // read projection subconfiguration + Projection projection; + { + util::Config config_proj; + if ( config.get( "projection", config_proj ) ) { projection = Projection( config_proj ); } + } - return new StructuredGrid::grid_t( xspace, yspace, projection, domain(config) ); + // Read grid configuration + ConfigParser::Parsed x, y; + if ( not ConfigParser::parse( projection, config, x, y ) ) { + throw eckit::BadParameter( "Could not parse configuration for RegularRegional grid", Here() ); + } - } + YSpace yspace( LinearSpacing( y.min, y.max, y.N, y.endpoint ) ); - void force_link() {} - -} regional_; + 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 ) ); + } + void force_link() {} +} regional_; static class zonal_band : public GridBuilder { - public: + zonal_band() : GridBuilder( "zonal_band" ) {} - zonal_band() : GridBuilder("zonal_band") {} - - virtual void print(std::ostream& os) const { - //os << std::left << std::setw(20) << "O" << "Octahedral Gaussian grid"; - } - - virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { - eckit::NotImplemented( "There are no named zonal_band grids implemented.", Here() ); - return nullptr; - } - - virtual const Grid::Implementation* create( const Grid::Config& config ) const { - + virtual void print( std::ostream& os ) const { + // os << std::left << std::setw(20) << "O" << "Octahedral Gaussian + // grid"; + } - // read projection subconfiguration - Projection projection; - { - util::Config config_proj; - if ( config.get("projection",config_proj) ) { - projection = Projection( config_proj ); - } + virtual const Grid::Implementation* create( const std::string& name, const Grid::Config& config ) const { + eckit::NotImplemented( "There are no named zonal_band grids implemented.", Here() ); + return nullptr; } - ASSERT( projection.units() == "degrees" ); + virtual const Grid::Implementation* create( const Grid::Config& config ) const { + // read projection subconfiguration + Projection projection; + { + util::Config config_proj; + if ( config.get( "projection", config_proj ) ) { projection = Projection( config_proj ); } + } - // Read grid configuration - ConfigParser::Parsed y; - long nx; - if( not config.get("nx",nx ) ) throw eckit::BadParameter("Parameter 'nx' missing in configuration", Here()); - if( not config.get("ny",y.N) ) throw eckit::BadParameter("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.; + ASSERT( projection.units() == "degrees" ); - YSpace yspace( LinearSpacing(y.min,y.max,y.N,true) ); + // Read grid configuration + ConfigParser::Parsed y; + long nx; + if ( not config.get( "nx", nx ) ) + throw eckit::BadParameter( "Parameter 'nx' missing in configuration", Here() ); + if ( not config.get( "ny", y.N ) ) + throw eckit::BadParameter( "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.; - XSpace xspace( {0.,360.}, std::vector(y.N,nx), false ); + YSpace yspace( LinearSpacing( y.min, y.max, y.N, true ) ); - return new StructuredGrid::grid_t( xspace, yspace, projection, domain(config) ); + XSpace xspace( {0., 360.}, std::vector( y.N, nx ), false ); - } + return new StructuredGrid::grid_t( xspace, yspace, projection, domain( config ) ); + } - void force_link() {} + void force_link() {} } zonal_band_; - - - -} // anonymous +} // namespace namespace detail { namespace grid { void force_link_Regional() { - regional_.force_link(); - zonal_band_.force_link(); + regional_.force_link(); + zonal_band_.force_link(); } -} -} +} // namespace grid +} // namespace detail -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index b35d560f7..bc7084017 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -4,414 +4,383 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "Structured.h" #include #include -#include "eckit/types/FloatCompare.h" -#include "atlas/runtime/ErrorHandling.h" #include "atlas/domain/Domain.h" #include "atlas/grid/Grid.h" #include "atlas/grid/detail/grid/GridBuilder.h" #include "atlas/grid/detail/spacing/CustomSpacing.h" #include "atlas/grid/detail/spacing/LinearSpacing.h" +#include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" #include "atlas/util/Earth.h" #include "atlas/util/Point.h" +#include "eckit/types/FloatCompare.h" namespace atlas { namespace grid { namespace detail { namespace grid { - std::string Structured::static_type() { return "structured"; } std::string Structured::name() const { - return name_; -} - -Structured::Structured( XSpace xspace, YSpace yspace, Projection p, Domain domain ): - Structured( Structured::static_type(), xspace, yspace, p, domain ) { + return name_; } -Structured::Structured( const std::string& name, XSpace xspace, YSpace yspace, Projection projection, Domain domain): - Grid(), - name_(name), - xspace_(xspace), - yspace_(yspace) { - // Copry members - if( projection ) - projection_ = projection; - else - projection_ = Projection(); - - y_.assign(yspace_.begin(),yspace_.end()); - size_t ny = y_.size(); - - if( xspace_.ny() == 1 && yspace_.size() > 1 ) { - nx_ .resize( ny, xspace_.nx()[0] ); - dx_ .resize( ny, xspace_.dx()[0] ); - xmin_ .resize( ny, xspace_.xmin()[0] ); - xmax_ .resize( ny, xspace_.xmax()[0] ); - } else { - nx_ = xspace_.nx(); - dx_ = xspace_.dx(); - xmin_ = xspace_.xmin(); - xmax_ = xspace_.xmax(); - } - - ASSERT( nx_.size() == ny ); +Structured::Structured( XSpace xspace, YSpace yspace, Projection p, Domain domain ) : + Structured( Structured::static_type(), xspace, yspace, p, domain ) {} + +Structured::Structured( const std::string& name, XSpace xspace, YSpace yspace, Projection projection, Domain domain ) : + Grid(), + name_( name ), + xspace_( xspace ), + yspace_( yspace ) { + // Copry members + if ( projection ) + projection_ = projection; + else + projection_ = Projection(); + + y_.assign( yspace_.begin(), yspace_.end() ); + size_t ny = y_.size(); + + if ( xspace_.ny() == 1 && yspace_.size() > 1 ) { + nx_.resize( ny, xspace_.nx()[0] ); + dx_.resize( ny, xspace_.dx()[0] ); + xmin_.resize( ny, xspace_.xmin()[0] ); + xmax_.resize( ny, xspace_.xmax()[0] ); + } + else { + nx_ = xspace_.nx(); + dx_ = xspace_.dx(); + xmin_ = xspace_.xmin(); + xmax_ = xspace_.xmax(); + } - // Further setup - nxmin_ = nxmax_ = static_cast(nx_.front()); - for (size_t j=1; j(nx_[j]),nxmin_); - nxmax_ = std::max(static_cast(nx_[j]),nxmax_); - } - npts_ = size_t(std::accumulate(nx_.begin(), nx_.end(), 0)); + ASSERT( nx_.size() == ny ); + // Further setup + nxmin_ = nxmax_ = static_cast( nx_.front() ); + for ( size_t j = 1; j < ny; ++j ) { + nxmin_ = std::min( static_cast( nx_[j] ), nxmin_ ); + nxmax_ = std::max( static_cast( nx_[j] ), nxmax_ ); + } + npts_ = size_t( std::accumulate( nx_.begin(), nx_.end(), 0 ) ); - if( not domain.empty() ) { - crop( domain ); - } + if ( not domain.empty() ) { crop( domain ); } - computeTruePeriodicity(); + computeTruePeriodicity(); - if( domain.global() ) - domain_ = Domain( Grid::Config("type","global") ); - else - computeDomain(); + if ( domain.global() ) + domain_ = Domain( Grid::Config( "type", "global" ) ); + else + computeDomain(); } void Structured::computeDomain() { - if( periodic() ) { - if( yspace().max() - yspace().min() == 180. ) { - domain_ = Domain( Grid::Config("type","global") ); + if ( periodic() ) { + if ( yspace().max() - yspace().min() == 180. ) { domain_ = Domain( Grid::Config( "type", "global" ) ); } + else { + Grid::Config config; + config.set( "type", "zonal_band" ); + config.set( "ymin", yspace().min() ); + config.set( "ymax", yspace().max() ); + domain_ = Domain( config ); + } } - else { - Grid::Config config; - config.set("type","zonal_band"); - config.set("ymin",yspace().min()); - config.set("ymax",yspace().max()); - domain_ = Domain(config); + else if ( domain_.empty() ) { + Grid::Config config; + config.set( "type", "rectangular" ); + config.set( "xmin", xmin_[0] ); + config.set( "xmax", xmax_[0] ); + config.set( "ymin", yspace().min() ); + config.set( "ymax", yspace().max() ); + config.set( "units", projection_.units() ); + domain_ = Domain( config ); } - } else if( domain_.empty() ) { - Grid::Config config; - config.set("type","rectangular"); - config.set("xmin",xmin_[0]); - config.set("xmax",xmax_[0]); - config.set("ymin",yspace().min()); - config.set("ymax",yspace().max()); - config.set("units",projection_.units()); - domain_ = Domain(config); - } } -Structured::~Structured() { -} +Structured::~Structured() {} -Structured::XSpace::XSpace() : - impl_( nullptr ){ -} +Structured::XSpace::XSpace() : impl_( nullptr ) {} -Structured::XSpace::XSpace( const XSpace& xspace ) : - impl_( xspace.impl_ ){ -} +Structured::XSpace::XSpace( const XSpace& xspace ) : impl_( xspace.impl_ ) {} -Structured::XSpace::XSpace( const std::array& interval, const std::vector& N, bool endpoint ) : - impl_( new Implementation(interval,N,endpoint) ) { -} +Structured::XSpace::XSpace( const std::array& interval, const std::vector& N, bool endpoint ) : + impl_( new Implementation( interval, N, endpoint ) ) {} -Structured::XSpace::XSpace( const Spacing& spacing ) : - impl_( new Implementation(spacing) ) { -} +Structured::XSpace::XSpace( const Spacing& spacing ) : impl_( new Implementation( spacing ) ) {} -Structured::XSpace::XSpace( const Config& config ) : - impl_( new Implementation(config) ) { -} +Structured::XSpace::XSpace( const Config& config ) : impl_( new Implementation( config ) ) {} -Structured::XSpace::XSpace( const std::vector& config ) : - impl_( new Implementation(config) ) { -} +Structured::XSpace::XSpace( const std::vector& config ) : impl_( new Implementation( config ) ) {} Structured::XSpace::Implementation::Implementation( const Config& config ) { + Config config_xspace( config ); + + std::string xspace_type; + config_xspace.get( "type", xspace_type ); + ASSERT( xspace_type == "linear" ); + + std::vector v_N; + std::vector v_start; + std::vector v_end; + std::vector v_length; + config_xspace.get( "N[]", v_N ); + config_xspace.get( "start[]", v_start ); + config_xspace.get( "end[]", v_end ); + config_xspace.get( "length[]", v_length ); + + size_t ny = + 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() ) ASSERT( v_N.size() == ny ); + if ( not v_start.empty() ) ASSERT( v_start.size() == ny ); + if ( not v_end.empty() ) ASSERT( v_end.size() == ny ); + if ( not v_length.empty() ) ASSERT( v_length.size() == ny ); + + nxmin_ = std::numeric_limits::max(); + nxmax_ = 0; - Config config_xspace(config); - - std::string xspace_type; - config_xspace.get("type",xspace_type); - ASSERT( xspace_type == "linear" ); - - std::vector v_N; - std::vector v_start; - std::vector v_end; - std::vector v_length; - config_xspace.get("N[]", v_N ); - config_xspace.get("start[]", v_start ); - config_xspace.get("end[]", v_end ); - config_xspace.get("length[]", v_length); - - size_t ny = 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() ) ASSERT(v_N. size() == ny); - if( not v_start. empty() ) ASSERT(v_start. size() == ny); - if( not v_end. empty() ) ASSERT(v_end. size() == ny); - if( not v_length.empty() ) ASSERT(v_length.size() == ny); - - nxmin_ = std::numeric_limits::max(); - nxmax_ = 0; - - for( size_t j=0; j& config_list ) { - reserve( config_list.size() ); nxmin_ = std::numeric_limits::max(); nxmax_ = 0; std::string xspace_type; - for( size_t j=0; j& interval, const std::vector& N, bool endpoint ) : - ny_(N.size()), - nx_(N), - xmin_(ny_,interval[0]), - xmax_(ny_,interval[1]), - dx_(ny_) { - nxmin_ = std::numeric_limits::max(); - nxmax_ = 0; - double length = interval[1] - interval[0]; - for( size_t j=0; j(*spacing.get()); - dx_[0] = linspace.step(); - nxmax_ = nx_[0]; - nxmin_ = nx_[0]; +Structured::XSpace::Implementation::Implementation( const std::array& interval, const std::vector& N, + bool endpoint ) : + ny_( N.size() ), + nx_( N ), + xmin_( ny_, interval[0] ), + xmax_( ny_, interval[1] ), + dx_( ny_ ) { + nxmin_ = std::numeric_limits::max(); + nxmax_ = 0; + double length = interval[1] - interval[0]; + for ( size_t j = 0; j < ny_; ++j ) { + nxmin_ = std::min( nxmin_, size_t( nx_[j] ) ); + nxmax_ = std::max( nxmax_, size_t( nx_[j] ) ); + dx_[j] = endpoint ? length / double( nx_[j] - 1 ) : length / double( nx_[j] ); + } } +Structured::XSpace::Implementation::Implementation( const Spacing& spacing ) : + ny_( 1 ), + nx_( ny_, spacing.size() ), + xmin_( ny_, spacing.min() ), + xmax_( ny_, spacing.max() ), + dx_( ny_ ) { + const spacing::LinearSpacing& linspace = dynamic_cast( *spacing.get() ); + dx_[0] = linspace.step(); + nxmax_ = nx_[0]; + nxmin_ = nx_[0]; +} Grid::Spec Structured::XSpace::Implementation::spec() const { - Grid::Spec spec; - - bool same_xmin = true; - bool same_xmax = true; - bool same_nx = true; - - double xmin = xmin_[0]; - double xmax = xmax_[0]; - long nx = nx_ [0]; - double dx = dx_ [0]; - - ASSERT(xmin_.size() == ny_); - ASSERT(xmax_.size() == ny_); - ASSERT(nx_ .size() == ny_); - - for( size_t j=1; j(xmin_, x, eps_)) { - x += 360.; - } - while (eckit::types::is_strictly_greater(x, xmax_, eps_)) { - x -= 360.; + bool endpoint = std::abs( ( xmax - xmin ) - ( nx - 1 ) * dx ) < 1.e-10; + + spec.set( "type", "linear" ); + if ( same_xmin ) { spec.set( "start", xmin ); } + else { + spec.set( "start[]", xmin_ ); + } + if ( same_xmax ) { spec.set( "end", xmax ); } + else { + spec.set( "end[]", xmax_ ); + } + if ( same_nx ) { spec.set( "N", nx ); } + else { + spec.set( "N[]", nx_ ); + } + spec.set( "endpoint", endpoint ); + + return spec; +} + +namespace { +class Normalise { +public: + Normalise( const RectangularDomain& domain ) : + degrees_( domain.units() == "degrees" ), + xmin_( domain.xmin() ), + xmax_( domain.xmax() ), + eps_( 1e-11 ) {} + + double operator()( double x ) const { + if ( degrees_ ) { + while ( eckit::types::is_strictly_greater( xmin_, x, eps_ ) ) { + x += 360.; + } + while ( eckit::types::is_strictly_greater( x, xmax_, eps_ ) ) { + x -= 360.; + } } - } - return x; + return x; } - private: +private: const bool degrees_; const double xmin_; const double xmax_; const double eps_; - }; -} +}; +} // namespace void Structured::crop( const Domain& dom ) { - - if( dom.global() ) - return; + if ( dom.global() ) return; ASSERT( dom.units() == projection().units() ); - auto zonal_domain = ZonalBandDomain(dom); - auto rect_domain = RectangularDomain(dom); - - if( zonal_domain ) { - - const double cropped_ymin = zonal_domain.ymin(); - const double cropped_ymax = zonal_domain.ymax(); - - size_t jmin = ny(); - size_t jmax = 0; - for( size_t j=0; j cropped_y ( y_ .begin()+jmin, y_ .begin()+jmin+cropped_ny ); - std::vector cropped_xmin( xmin_.begin()+jmin, xmin_.begin()+jmin+cropped_ny ); - std::vector cropped_xmax( xmax_.begin()+jmin, xmax_.begin()+jmin+cropped_ny ); - std::vector cropped_dx ( dx_ .begin()+jmin, dx_ .begin()+jmin+cropped_ny ); - std::vector cropped_nx ( nx_ .begin()+jmin, nx_ .begin()+jmin+cropped_ny ); - ASSERT( cropped_nx.size() == cropped_ny ); - - size_t cropped_nxmin, cropped_nxmax; - cropped_nxmin = cropped_nxmax = static_cast(cropped_nx.front()); - for (size_t j=1; j(cropped_nx[j]),cropped_nxmin); - cropped_nxmax = std::max(static_cast(cropped_nx[j]),cropped_nxmax); - } - size_t cropped_npts = size_t(std::accumulate(cropped_nx.begin(), cropped_nx.end(), 0)); - - Spacing cropped_yspace( new spacing::CustomSpacing(cropped_ny, cropped_y.data(), {cropped_ymin, cropped_ymax}) ); - - // Modify grid - { - domain_ = dom; - yspace_ = cropped_yspace; - xmin_ = cropped_xmin; - xmax_ = cropped_xmax; - dx_ = cropped_dx; - nx_ = cropped_nx; - nxmin_ = cropped_nxmin; - nxmax_ = cropped_nxmax; - npts_ = cropped_npts; - y_ = cropped_y; - } - - } else if ( rect_domain ) { + auto zonal_domain = ZonalBandDomain( dom ); + auto rect_domain = RectangularDomain( dom ); + if ( zonal_domain ) { + const double cropped_ymin = zonal_domain.ymin(); + const double cropped_ymax = zonal_domain.ymax(); + + size_t jmin = ny(); + size_t jmax = 0; + for ( size_t j = 0; j < ny(); ++j ) { + if ( zonal_domain.contains_y( y( j ) ) ) { + jmin = std::min( j, jmin ); + jmax = std::max( j, jmax ); + } + } + size_t cropped_ny = jmax - jmin + 1; + std::vector cropped_y( y_.begin() + jmin, y_.begin() + jmin + cropped_ny ); + std::vector cropped_xmin( xmin_.begin() + jmin, xmin_.begin() + jmin + cropped_ny ); + std::vector cropped_xmax( xmax_.begin() + jmin, xmax_.begin() + jmin + cropped_ny ); + std::vector cropped_dx( dx_.begin() + jmin, dx_.begin() + jmin + cropped_ny ); + std::vector cropped_nx( nx_.begin() + jmin, nx_.begin() + jmin + cropped_ny ); + ASSERT( cropped_nx.size() == cropped_ny ); + + size_t cropped_nxmin, cropped_nxmax; + cropped_nxmin = cropped_nxmax = static_cast( cropped_nx.front() ); + for ( size_t j = 1; j < cropped_ny; ++j ) { + cropped_nxmin = std::min( static_cast( cropped_nx[j] ), cropped_nxmin ); + cropped_nxmax = std::max( static_cast( cropped_nx[j] ), cropped_nxmax ); + } + size_t cropped_npts = size_t( std::accumulate( cropped_nx.begin(), cropped_nx.end(), 0 ) ); + + Spacing cropped_yspace( + new spacing::CustomSpacing( cropped_ny, cropped_y.data(), {cropped_ymin, cropped_ymax} ) ); + + // Modify grid + { + domain_ = dom; + yspace_ = cropped_yspace; + xmin_ = cropped_xmin; + xmax_ = cropped_xmax; + dx_ = cropped_dx; + nx_ = cropped_nx; + nxmin_ = cropped_nxmin; + nxmax_ = cropped_nxmax; + npts_ = cropped_npts; + y_ = cropped_y; + } + } + else if ( rect_domain ) { const double cropped_ymin = rect_domain.ymin(); const double cropped_ymax = rect_domain.ymax(); // Cropping in Y size_t jmin = ny(); size_t jmax = 0; - for( size_t j=0; j cropped_y ( y_ .begin()+jmin, y_ .begin()+jmin+cropped_ny ); - std::vector cropped_dx ( dx_.begin()+jmin, dx_.begin()+jmin+cropped_ny ); + size_t cropped_ny = jmax - jmin + 1; + std::vector cropped_y( y_.begin() + jmin, y_.begin() + jmin + cropped_ny ); + std::vector cropped_dx( dx_.begin() + jmin, dx_.begin() + jmin + cropped_ny ); - std::vector cropped_xmin( cropped_ny, std::numeric_limits::max() ); + std::vector cropped_xmin( cropped_ny, std::numeric_limits::max() ); std::vector cropped_xmax( cropped_ny, -std::numeric_limits::max() ); - std::vector cropped_nx ( cropped_ny ); + std::vector cropped_nx( cropped_ny ); // Cropping in X - Normalise normalise(rect_domain); - for( size_t j=jmin, jcropped=0; j<=jmax; ++j, ++jcropped ) { - size_t n=0; - for( size_t i=0; i(cropped_nx.front()); + cropped_nxmin = cropped_nxmax = static_cast( cropped_nx.front() ); - for (size_t j=1; j(cropped_nx[j]),cropped_nxmin); - cropped_nxmax = std::max(static_cast(cropped_nx[j]),cropped_nxmax); + for ( size_t j = 1; j < cropped_ny; ++j ) { + cropped_nxmin = std::min( static_cast( cropped_nx[j] ), cropped_nxmin ); + cropped_nxmax = std::max( static_cast( cropped_nx[j] ), cropped_nxmax ); } - size_t cropped_npts = size_t(std::accumulate(cropped_nx.begin(), cropped_nx.end(), 0)); + size_t cropped_npts = size_t( std::accumulate( cropped_nx.begin(), cropped_nx.end(), 0 ) ); - Spacing cropped_yspace( new spacing::CustomSpacing(cropped_ny, cropped_y.data(), {cropped_ymin, cropped_ymax}) ); + Spacing cropped_yspace( + new spacing::CustomSpacing( cropped_ny, cropped_y.data(), {cropped_ymin, cropped_ymax} ) ); // Modify grid { - domain_ = dom; - yspace_ = cropped_yspace; - xmin_ = cropped_xmin; - xmax_ = cropped_xmax; - dx_ = cropped_dx; - nx_ = cropped_nx; - nxmin_ = cropped_nxmin; - nxmax_ = cropped_nxmax; - npts_ = cropped_npts; - y_ = cropped_y; + domain_ = dom; + yspace_ = cropped_yspace; + xmin_ = cropped_xmin; + xmax_ = cropped_xmax; + dx_ = cropped_dx; + nx_ = cropped_nx; + nxmin_ = cropped_nxmin; + nxmax_ = cropped_nxmax; + npts_ = cropped_npts; + y_ = cropped_y; } } else { - std::stringstream errmsg; - errmsg << "Cannot crop the grid with domain " << dom; - eckit::BadParameter(errmsg.str(), Here()); + std::stringstream errmsg; + errmsg << "Cannot crop the grid with domain " << dom; + eckit::BadParameter( errmsg.str(), Here() ); } } void Structured::computeTruePeriodicity() { + if ( projection_.strictlyRegional() ) { periodic_x_ = false; } + else if ( domain_.global() ) { + periodic_x_ = true; + } + else { + // domain could be zonal band - if( projection_.strictlyRegional() ) { - periodic_x_ = false; - - } else if( domain_.global() ) { - periodic_x_ = true; - - } else { - // domain could be zonal band - - size_t j = ny()/2; - if( xmin_[j] + (nx_[j]-1) * dx_[j] == xmax_[j] ) { - periodic_x_ = false; // This would lead to duplicated points - } else { - - // High chance to be periodic. Check anyway. - const PointLonLat Pllmin = projection().lonlat(PointXY(xmin_[j], y_[j])); - const PointLonLat Pllmax = projection().lonlat(PointXY(xmax_[j], y_[j])); + size_t j = ny() / 2; + if ( xmin_[j] + ( nx_[j] - 1 ) * dx_[j] == xmax_[j] ) { + periodic_x_ = false; // This would lead to duplicated points + } + else { + // High chance to be periodic. Check anyway. + const PointLonLat Pllmin = projection().lonlat( PointXY( xmin_[j], y_[j] ) ); + const PointLonLat Pllmax = projection().lonlat( PointXY( xmax_[j], y_[j] ) ); - Point3 Pxmin = util::Earth::convertGeodeticToGeocentric(Pllmin, 1.); - Point3 Pxmax = util::Earth::convertGeodeticToGeocentric(Pllmax, 1.); + Point3 Pxmin = util::Earth::convertGeodeticToGeocentric( Pllmin, 1. ); + Point3 Pxmax = util::Earth::convertGeodeticToGeocentric( Pllmax, 1. ); - periodic_x_ = points_equal( Pxmin, Pxmax ); + periodic_x_ = points_equal( Pxmin, Pxmax ); + } } - - } } -void Structured::print(std::ostream& os) const { +void Structured::print( std::ostream& os ) const { os << "Structured(Name:" << name() << ")"; } std::string Structured::type() const { - return static_type(); + return static_type(); } -void Structured::hash(eckit::Hash& h) const { - - h.add(y().data(), sizeof(double)*y().size()); - h.add(nx().data(), sizeof(long)*ny()); +void Structured::hash( eckit::Hash& h ) const { + h.add( y().data(), sizeof( double ) * y().size() ); + h.add( nx().data(), sizeof( long ) * ny() ); // also add lonmin and lonmax - h.add(xmin_.data(), sizeof(double)*xmin_.size()); - h.add(dx_.data(), sizeof(double)*dx_.size()); + h.add( xmin_.data(), sizeof( double ) * xmin_.size() ); + h.add( dx_.data(), sizeof( double ) * dx_.size() ); // also add projection information - projection().hash(h); + projection().hash( h ); // also add domain information, even though already encoded in grid. - domain().hash(h); + domain().hash( h ); } Grid::Spec Structured::spec() const { Grid::Spec grid_spec; - if( name() == "structured" ) { - grid_spec.set("type", type()); - grid_spec.set("xspace",xspace().spec()); - grid_spec.set("yspace",yspace().spec()); + if ( name() == "structured" ) { + grid_spec.set( "type", type() ); + grid_spec.set( "xspace", xspace().spec() ); + grid_spec.set( "yspace", yspace().spec() ); } else { - grid_spec.set("name",name()); + grid_spec.set( "name", name() ); } - grid_spec.set("domain",domain().spec()); - grid_spec.set("projection",projection().spec()); + grid_spec.set( "domain", domain().spec() ); + grid_spec.set( "projection", projection().spec() ); return grid_spec; } - // -------------------------------------------------------------------- -namespace { // anonymous +namespace { // anonymous static class structured : public GridBuilder { - - using Implementation = atlas::Grid::Implementation; - using Config = Grid::Config; - using XSpace = StructuredGrid::XSpace; + using Implementation = atlas::Grid::Implementation; + using Config = Grid::Config; + using XSpace = StructuredGrid::XSpace; public: + structured() : GridBuilder( "structured" ) {} - structured(): GridBuilder( "structured" ){} - - virtual void print(std::ostream& os) const { - os << std::left << std::setw(20) << " " << "Structured grid"; + virtual void print( std::ostream& os ) const { + os << std::left << std::setw( 20 ) << " " + << "Structured grid"; } virtual const Implementation* create( const std::string& name, const Config& config ) const { @@ -543,220 +506,142 @@ static class structured : public GridBuilder { } virtual const Implementation* create( const Config& config ) const { - Projection projection; - Spacing yspace; - Domain domain; + Spacing yspace; + 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 eckit::BadParameter("yspace missing in configuration"); - yspace = Spacing(config_yspace); + if ( not config.get( "yspace", config_yspace ) ) throw eckit::BadParameter( "yspace missing in configuration" ); + yspace = Spacing( config_yspace ); XSpace xspace; Config config_xspace; std::vector config_xspace_list; - if( config.get("xspace[]",config_xspace_list) ) { - xspace = XSpace( config_xspace_list ); - } else if( config.get("xspace",config_xspace) ) { + if ( config.get( "xspace[]", config_xspace_list ) ) { xspace = XSpace( config_xspace_list ); } + else if ( config.get( "xspace", config_xspace ) ) { xspace = XSpace( config_xspace ); - } else { - throw eckit::BadParameter("xspace missing in configuration"); + } + else { + throw eckit::BadParameter( "xspace missing in configuration" ); } - return new StructuredGrid::grid_t(xspace, yspace, projection, domain ); + return new StructuredGrid::grid_t( xspace, yspace, projection, domain ); } } structured_; -} // anonymous namespace - +} // anonymous namespace // -------------------------------------------------------------------- - extern "C" { +long atlas__grid__Structured__ny( Structured* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->ny(); ); + return 0; +} - long atlas__grid__Structured__ny(Structured* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->ny(); - ); - return 0; - } - - - long atlas__grid__Structured__nx(Structured* This, long jlat) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->nx(jlat); - ); - return 0; - } - - - void atlas__grid__Structured__nx_array(Structured* This, const long* &nx_array, size_t &size) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - nx_array = This->nx().data(); - size = This->nx().size(); - ); - } - - - long atlas__grid__Structured__nxmax(Structured* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->nxmax(); - ); - return 0; - } - - - long atlas__grid__Structured__nxmin(Structured* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->nxmin(); - ); - return 0; - } - - - long atlas__grid__Structured__size(Structured* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->size(); - ); - return 0; - } - - - double atlas__grid__Structured__y(Structured* This, long j) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->y(j); - ); - return 0.; - } - - - double atlas__grid__Structured__x( Structured* This, long i, long j ) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->x(i,j); - ); - return 0.; - } - - - void atlas__grid__Structured__xy( Structured* This, long i, long j, double crd[] ) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - This->xy(i,j, crd); - ); - } - - void atlas__grid__Structured__lonlat( Structured* This, long i, long j, double crd[] ) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - This->lonlat(i,j, crd); - ); - } - - - void atlas__grid__Structured__y_array( Structured* This, const double* &y_array, size_t &size) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - y_array = This->y().data(); - size = This->y().size(); - ); - } +long atlas__grid__Structured__nx( Structured* This, long jlat ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->nx( jlat ); ); + return 0; +} +void atlas__grid__Structured__nx_array( Structured* This, const long*& nx_array, size_t& size ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); nx_array = This->nx().data(); size = This->nx().size(); ); +} - int atlas__grid__Structured__reduced(Structured* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->reduced(); - ); - return 1; - } +long atlas__grid__Structured__nxmax( Structured* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->nxmax(); ); + return 0; +} +long atlas__grid__Structured__nxmin( Structured* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->nxmin(); ); + return 0; +} - const Structured* atlas__grid__Structured(char* identifier) { - ATLAS_ERROR_HANDLING( - ASSERT( identifier ); - const Structured* grid = dynamic_cast( Grid::create( std::string(identifier) ) ); - ASSERT( grid ); - return grid; - ); - return 0; - } +long atlas__grid__Structured__size( Structured* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->size(); ); + return 0; +} +double atlas__grid__Structured__y( Structured* This, long j ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->y( j ); ); + return 0.; +} - const Structured* atlas__grid__Structured__config(util::Config* conf) { - ATLAS_ERROR_HANDLING( - ASSERT( conf ); - const Structured* grid = dynamic_cast( Grid::create( *conf ) ); - ASSERT( grid ); - return grid; - ); - return 0; - } +double atlas__grid__Structured__x( Structured* This, long i, long j ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->x( i, j ); ); + return 0.; +} +void atlas__grid__Structured__xy( Structured* This, long i, long j, double crd[] ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); This->xy( i, j, crd ); ); +} - void atlas__grid__Structured__delete(Structured* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ); - delete This; - } +void atlas__grid__Structured__lonlat( Structured* This, long i, long j, double crd[] ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); This->lonlat( i, j, crd ); ); +} +void atlas__grid__Structured__y_array( Structured* This, const double*& y_array, size_t& size ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); y_array = This->y().data(); size = This->y().size(); ); +} - Structured* atlas__grid__regular__RegularGaussian(long N) { - NOTIMP; - } - Structured* atlas__grid__regular__RegularLonLat(long nlon, long nlat) { - NOTIMP; - } - Structured* atlas__grid__regular__ShiftedLonLat(long nlon, long nlat) { - NOTIMP; - } - Structured* atlas__grid__regular__ShiftedLon(long nlon, long nlat) { - NOTIMP; - } - Structured* atlas__grid__regular__ShiftedLat(long nlon, long nlat) { - NOTIMP; - } +int atlas__grid__Structured__reduced( Structured* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->reduced(); ); + return 1; +} +const Structured* atlas__grid__Structured( char* identifier ) { + ATLAS_ERROR_HANDLING( ASSERT( identifier ); const Structured* grid = dynamic_cast( + Grid::create( std::string( identifier ) ) ); + ASSERT( grid ); return grid; ); + return 0; +} - long atlas__grid__Gaussian__N(Structured* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - GaussianGrid gaussian(This); - ASSERT( gaussian ); - return gaussian.N(); - ); - return 0; - } +const Structured* atlas__grid__Structured__config( util::Config* conf ) { + ATLAS_ERROR_HANDLING( ASSERT( conf ); + const Structured* grid = dynamic_cast( Grid::create( *conf ) ); + ASSERT( grid ); return grid; ); + return 0; +} +void atlas__grid__Structured__delete( Structured* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ); + delete This; +} +Structured* atlas__grid__regular__RegularGaussian( long N ) { + NOTIMP; +} +Structured* atlas__grid__regular__RegularLonLat( long nlon, long nlat ) { + NOTIMP; +} +Structured* atlas__grid__regular__ShiftedLonLat( long nlon, long nlat ) { + NOTIMP; +} +Structured* atlas__grid__regular__ShiftedLon( long nlon, long nlat ) { + NOTIMP; +} +Structured* atlas__grid__regular__ShiftedLat( long nlon, long nlat ) { + NOTIMP; } +long atlas__grid__Gaussian__N( Structured* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); GaussianGrid gaussian( This ); ASSERT( gaussian ); return gaussian.N(); ); + return 0; +} +} } // namespace grid } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index 4c6fb67fd..e4578c336 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -4,24 +4,23 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #pragma once -#include #include +#include -#include "eckit/memory/Builder.h" -#include "eckit/utils/Hash.h" #include "atlas/grid/detail/grid/Grid.h" #include "atlas/util/Config.h" +#include "eckit/memory/Builder.h" +#include "eckit/utils/Hash.h" #include "atlas/grid/Spacing.h" - namespace atlas { namespace grid { namespace detail { @@ -37,200 +36,171 @@ namespace grid { * such distribution can be represented with this class */ class Structured : public Grid { - public: + class IteratorXY : public Grid::IteratorXY { + public: + IteratorXY( const Structured& grid, bool begin = true ) : grid_( grid ), i_( 0 ), j_( begin ? 0 : grid.ny() ) {} - class IteratorXY: public Grid::IteratorXY { - public: - IteratorXY(const Structured& grid, bool begin = true): - grid_(grid), - i_(0), - j_( begin ? 0 : grid.ny() ) { - } + virtual bool next( PointXY& xy ) { + if ( j_ < grid_.ny() && i_ < grid_.nx( j_ ) ) { + xy = grid_.xy( i_++, j_ ); - virtual bool next(PointXY& xy) { + if ( i_ == grid_.nx( j_ ) ) { + j_++; + i_ = 0; + } + return true; + } + return false; + } - if( j_( other ).j_ && i_ == static_cast( other ).i_; + } + virtual bool operator!=( const Grid::IteratorXY& other ) const { + return i_ != static_cast( other ).i_ || j_ != static_cast( other ).j_; + } - virtual const PointXY operator *() const { - return grid_.xy(i_,j_); - } + private: + const Structured& grid_; + size_t i_; + size_t j_; + }; - virtual const Grid::IteratorXY& operator ++() { - ++i_; - if( i_ == grid_.nx(j_) ) { - ++j_; - i_=0; + class IteratorXYPredicated : public Grid::IteratorXY { + public: + IteratorXYPredicated( const Structured& grid, Grid::IteratorXY::Predicate p, bool begin = true ) : + grid_( grid ), + p_( p ), + i_( 0 ), + j_( begin ? 0 : grid.ny() ), + n_( 0 ), + size_( grid.size() ) { + if ( begin ) { + while ( not p_( n_ ) && n_ < size_ ) { + ++i_; + if ( i_ == grid_.nx( j_ ) ) { + ++j_; + i_ = 0; + } + ++n_; + } + } } - return *this; - } - virtual bool operator ==(const Grid::IteratorXY &other) const { - return j_ == static_cast(other).j_ && i_ == static_cast(other).i_; - } + virtual bool next( PointXY& xy ) { + NOTIMP; - virtual bool operator !=(const Grid::IteratorXY &other) const { - return i_ != static_cast(other).i_ || j_ != static_cast(other).j_; - } + if ( j_ < grid_.ny() && i_ < grid_.nx( j_ ) ) { + xy = grid_.xy( i_++, j_ ); + if ( i_ == grid_.nx( j_ ) ) { + j_++; + i_ = 0; + } + return true; + } + return false; + } - private: - const Structured& grid_; - size_t i_; - size_t j_; - }; - - - class IteratorXYPredicated: public Grid::IteratorXY { - public: - IteratorXYPredicated(const Structured& grid, Grid::IteratorXY::Predicate p, bool begin = true): - grid_(grid), - p_(p), - i_(0), - j_( begin ? 0 : grid.ny() ), - n_(0), - size_(grid.size()) { - if( begin ) { - while( not p_(n_) && n_(other).j_ && i_ == static_cast(other).i_; - } - - virtual bool operator !=(const Grid::IteratorXY &other) const { - return i_ != static_cast(other).i_ || j_ != static_cast(other).j_; - } - - - private: - Grid::IteratorXY::Predicate p_; - const Structured& grid_; - size_t i_; - size_t j_; - size_t n_; - size_t size_; - }; - - + virtual bool operator==( const Grid::IteratorXY& other ) const { + return j_ == static_cast( other ).j_ && + i_ == static_cast( other ).i_; + } - class IteratorLonLat: public Grid::IteratorLonLat { - public: - IteratorLonLat(const Structured& grid, bool begin = true): - grid_(grid), - i_(0), - j_( begin ? 0 : grid.ny() ) { - } - - virtual bool next(PointLonLat& lonlat) { - - if( j_( other ).i_ || + j_ != static_cast( other ).j_; + } - if( i_==grid_.nx(j_) ) { - j_++; - i_=0; - } - return true; - } - return false; - } + private: + Grid::IteratorXY::Predicate p_; + const Structured& grid_; + size_t i_; + size_t j_; + size_t n_; + size_t size_; + }; + class IteratorLonLat : public Grid::IteratorLonLat { + public: + IteratorLonLat( const Structured& grid, bool begin = true ) : + grid_( grid ), + i_( 0 ), + j_( begin ? 0 : grid.ny() ) {} + + virtual bool next( PointLonLat& lonlat ) { + if ( j_ < grid_.ny() && i_ < grid_.nx( j_ ) ) { + lonlat = grid_.lonlat( i_++, j_ ); + + if ( i_ == grid_.nx( j_ ) ) { + j_++; + i_ = 0; + } + return true; + } + return false; + } - virtual const PointLonLat operator *() const { - return grid_.lonlat(i_,j_); - } + virtual const PointLonLat operator*() const { return grid_.lonlat( i_, j_ ); } - virtual const Grid::IteratorLonLat& operator ++() { - ++i_; - if( i_ == grid_.nx(j_) ) { - ++j_; - i_=0; + virtual const Grid::IteratorLonLat& operator++() { + ++i_; + if ( i_ == grid_.nx( j_ ) ) { + ++j_; + i_ = 0; + } + return *this; } - return *this; - } - - virtual bool operator ==(const Grid::IteratorLonLat &other) const { - return j_ == static_cast(other).j_ && i_ == static_cast(other).i_; - } - virtual bool operator !=(const Grid::IteratorLonLat &other) const { - return i_ != static_cast(other).i_ || j_ != static_cast(other).j_; - } + virtual bool operator==( const Grid::IteratorLonLat& other ) const { + return j_ == static_cast( other ).j_ && + i_ == static_cast( other ).i_; + } + virtual bool operator!=( const Grid::IteratorLonLat& other ) const { + return i_ != static_cast( other ).i_ || + j_ != static_cast( other ).j_; + } - private: - const Structured& grid_; - size_t i_; - size_t j_; - }; + private: + const Structured& grid_; + size_t i_; + size_t j_; + }; public: - class XSpace { - class Implementation : public eckit::Owned { - public: - - Implementation( const std::array& interval, const std::vector& N, bool endpoint=true ); + Implementation( const std::array& interval, const std::vector& N, bool endpoint = true ); Implementation( const Spacing& ); @@ -261,11 +231,9 @@ class Structured : public Grid { Spec spec() const; private: - void reserve( long ny ); private: - size_t ny_; size_t nxmin_; size_t nxmax_; @@ -276,14 +244,13 @@ class Structured : public Grid { }; public: - XSpace(); XSpace( const XSpace& ); XSpace( const Spacing& ); - XSpace( const std::array& interval, const std::vector& N, bool endpoint=true ); + XSpace( const std::array& interval, const std::vector& N, bool endpoint = true ); XSpace( const Config& ); @@ -312,110 +279,86 @@ class Structured : public Grid { Spec spec() const { return impl_->spec(); } private: - eckit::SharedPtr impl_; }; using YSpace = Spacing; public: - static std::string static_type(); public: - Structured( const std::string&, XSpace, YSpace, Projection, Domain ); Structured( XSpace, YSpace, Projection, Domain ); virtual ~Structured(); - virtual size_t size() const { - return npts_; - } + virtual size_t size() const { return npts_; } virtual Spec spec() const; /** - * Human readable name - * Either the name is the one given at construction as a canonical named grid, or the name "structured" - */ + * Human readable name + * Either the name is the one given at construction as a canonical named grid, + * or the name "structured" + */ virtual std::string name() const; virtual std::string type() const; - inline size_t ny() const { - return y_.size(); - } + inline size_t ny() const { return y_.size(); } - inline size_t nx( size_t j ) const { - return static_cast(nx_[j]); - } + inline size_t nx( size_t j ) const { return static_cast( nx_[j] ); } - inline size_t nxmax() const { - return nxmax_; - } + inline size_t nxmax() const { return nxmax_; } - inline size_t nxmin() const { - return nxmin_; - } + inline size_t nxmin() const { return nxmin_; } - inline const std::vector& nx() const { - return nx_; - } + inline const std::vector& nx() const { return nx_; } - inline const std::vector& y() const { - return y_; - } + inline const std::vector& y() const { return y_; } - inline double x( size_t i, size_t j ) const { - return xmin_[j] + static_cast(i) * dx_[j]; - } + inline double x( size_t i, size_t j ) const { return xmin_[j] + static_cast( i ) * dx_[j]; } - inline double y( size_t j ) const { - return y_[j]; - } + inline double y( size_t j ) const { return y_[j]; } inline void xy( size_t i, size_t j, double crd[] ) const { - crd[0] = x(i,j); - crd[1] = y(j); + crd[0] = x( i, j ); + crd[1] = y( j ); } - PointXY xy( size_t i, size_t j ) const { - return PointXY( x(i,j), y(j) ); - } + PointXY xy( size_t i, size_t j ) const { return PointXY( x( i, j ), y( j ) ); } - PointLonLat lonlat( size_t i, size_t j ) const { - return projection_.lonlat( xy(i,j) ); - } + PointLonLat lonlat( size_t i, size_t j ) const { return projection_.lonlat( xy( i, j ) ); } - void lonlat(size_t i, size_t j, double crd[]) const { - xy(i,j,crd); - projection_.xy2lonlat(crd); + void lonlat( size_t i, size_t j, double crd[] ) const { + xy( i, j, crd ); + projection_.xy2lonlat( crd ); } - inline bool reduced() const { - return nxmax() != nxmin(); - } + inline bool reduced() const { return nxmax() != nxmin(); } bool periodic() const { return periodic_x_; } const XSpace& xspace() const { return xspace_; } const YSpace& yspace() const { return yspace_; } - 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 { return new IteratorXYPredicated(*this,p); } - virtual IteratorXYPredicated* xy_end(IteratorXY::Predicate p) const { return new IteratorXYPredicated(*this,p,false); } - + 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 ); } -protected: // methods + virtual IteratorXYPredicated* xy_begin( IteratorXY::Predicate p ) const { + return new IteratorXYPredicated( *this, p ); + } + virtual IteratorXYPredicated* xy_end( IteratorXY::Predicate p ) const { + return new IteratorXYPredicated( *this, p, false ); + } - virtual void print(std::ostream&) const; +protected: // methods + virtual void print( std::ostream& ) const; - virtual void hash(eckit::Hash&) const; + virtual void hash( eckit::Hash& ) const; void computeTruePeriodicity(); @@ -424,7 +367,6 @@ class Structured : public Grid { void crop( const Domain& ); protected: - // Minimum number of points across parallels (constant y) size_t nxmin_; @@ -459,38 +401,34 @@ class Structured : public Grid { mutable std::string type_; }; - -extern "C" -{ - void atlas__grid__Structured__delete(Structured* This); - const Structured *atlas__grid__Structured(char* identifier); - const Structured* atlas__grid__Structured__config(util::Config* conf); - Structured* atlas__grid__regular__RegularGaussian(long N); - Structured* atlas__grid__reduced__ReducedGaussian_int(int nx[], long ny); - Structured* atlas__grid__reduced__ReducedGaussian_long(long nx[], long ny); - Structured* atlas__grid__regular__RegularLonLat(long nx, long ny); - Structured* atlas__grid__regular__ShiftedLonLat(long nx, long ny); - Structured* atlas__grid__regular__ShiftedLon(long nx, long ny); - Structured* atlas__grid__regular__ShiftedLat(long nx, long ny); - - void atlas__grid__Structured__nx_array (Structured* This, const long* &nx, size_t &size); - long atlas__grid__Structured__nx (Structured* This, long j); - long atlas__grid__Structured__ny (Structured* This); - long atlas__grid__Structured__nxmin (Structured* This); - long atlas__grid__Structured__nxmax (Structured* This); - long atlas__grid__Structured__size (Structured* This); - double atlas__grid__Structured__y (Structured* This, long j); - double atlas__grid__Structured__x (Structured* This, long i, long j); - void atlas__grid__Structured__xy (Structured* This, long i, long j, double crd[]); - void atlas__grid__Structured__lonlat (Structured* This, long i, long j, double crd[]); - void atlas__grid__Structured__y_array (Structured* This, const double* &lats, size_t &size); - int atlas__grid__Structured__reduced (Structured* This); - - long atlas__grid__Gaussian__N (Structured* This); - +extern "C" { +void atlas__grid__Structured__delete( Structured* This ); +const Structured* atlas__grid__Structured( char* identifier ); +const Structured* atlas__grid__Structured__config( util::Config* conf ); +Structured* atlas__grid__regular__RegularGaussian( long N ); +Structured* atlas__grid__reduced__ReducedGaussian_int( int nx[], long ny ); +Structured* atlas__grid__reduced__ReducedGaussian_long( long nx[], long ny ); +Structured* atlas__grid__regular__RegularLonLat( long nx, long ny ); +Structured* atlas__grid__regular__ShiftedLonLat( long nx, long ny ); +Structured* atlas__grid__regular__ShiftedLon( long nx, long ny ); +Structured* atlas__grid__regular__ShiftedLat( long nx, long ny ); + +void atlas__grid__Structured__nx_array( Structured* This, const long*& nx, size_t& size ); +long atlas__grid__Structured__nx( Structured* This, long j ); +long atlas__grid__Structured__ny( Structured* This ); +long atlas__grid__Structured__nxmin( Structured* This ); +long atlas__grid__Structured__nxmax( Structured* This ); +long atlas__grid__Structured__size( Structured* This ); +double atlas__grid__Structured__y( Structured* This, long j ); +double atlas__grid__Structured__x( Structured* This, long i, long j ); +void atlas__grid__Structured__xy( Structured* This, long i, long j, double crd[] ); +void atlas__grid__Structured__lonlat( Structured* This, long i, long j, double crd[] ); +void atlas__grid__Structured__y_array( Structured* This, const double*& lats, size_t& size ); +int atlas__grid__Structured__reduced( Structured* This ); + +long atlas__grid__Gaussian__N( Structured* This ); } - } // namespace grid } // namespace detail } // namespace grid diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index b9c7e7073..33dd368b6 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -4,136 +4,119 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "atlas/grid/detail/grid/Unstructured.h" #include -#include "eckit/memory/Builder.h" #include "atlas/array/ArrayView.h" #include "atlas/field/Field.h" -#include "atlas/util/CoordinateEnums.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/runtime/Log.h" - +#include "atlas/util/CoordinateEnums.h" +#include "eckit/memory/Builder.h" namespace atlas { namespace grid { namespace detail { namespace grid { +eckit::ConcreteBuilderT1 builder_Unstructured( Unstructured::static_type() ); -eckit::ConcreteBuilderT1 builder_Unstructured(Unstructured::static_type()); - -Unstructured::Unstructured(const Mesh& m) : - Grid(), - points_ ( new std::vector< PointXY > (m.nodes().size() ) ) { - +Unstructured::Unstructured( const Mesh& m ) : Grid(), points_( new std::vector( m.nodes().size() ) ) { util::Config config_domain; - config_domain.set("type","global"); - domain_ = Domain(config_domain); + config_domain.set( "type", "global" ); + domain_ = Domain( config_domain ); - auto xy = array::make_view(m.nodes().xy()); - std::vector &p = *points_; - const size_t npts = p.size(); + auto xy = array::make_view( m.nodes().xy() ); + std::vector& p = *points_; + const size_t npts = p.size(); - for( size_t n=0; n* pts) : - Grid(), - points_(pts) { +Unstructured::Unstructured( std::vector* pts ) : Grid(), points_( pts ) { util::Config config_domain; - config_domain.set("type","global"); - domain_ = Domain(config_domain); + config_domain.set( "type", "global" ); + domain_ = Domain( config_domain ); } -Unstructured::Unstructured(std::vector&& pts) : +Unstructured::Unstructured( std::vector&& pts ) : Grid(), - points_( new std::vector( std::move(pts) ) ) { + points_( new std::vector( std::move( pts ) ) ) { util::Config config_domain; - config_domain.set("type","global"); - domain_ = Domain(config_domain); + config_domain.set( "type", "global" ); + domain_ = Domain( config_domain ); } -Unstructured::Unstructured( std::initializer_list< PointXY > initializer_list ) : +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); -} - - -Unstructured::~Unstructured() { + config_domain.set( "type", "global" ); + domain_ = Domain( config_domain ); } +Unstructured::~Unstructured() {} Grid::uid_t Unstructured::name() const { - if (shortName_.empty()) { + if ( shortName_.empty() ) { std::ostringstream s; - s << "unstructured." << Grid::hash().substr(0, 7); + s << "unstructured." << Grid::hash().substr( 0, 7 ); shortName_ = s.str(); } return shortName_; } +void Unstructured::hash( eckit::Hash& h ) const { + ASSERT( points_ ); -void Unstructured::hash(eckit::Hash &h) const { - ASSERT(points_); - - const std::vector< PointXY > &pts = *points_; - h.add(&pts[0], sizeof(PointXY)*pts.size()); + const std::vector& pts = *points_; + h.add( &pts[0], sizeof( PointXY ) * pts.size() ); - for (size_t i = 0; i < pts.size(); i++) { - const PointXY &p = pts[i]; + for ( size_t i = 0; i < pts.size(); i++ ) { + const PointXY& p = pts[i]; h << p.x() << p.y(); } - projection().hash(h); + projection().hash( h ); } - size_t Unstructured::size() const { - ASSERT(points_); + ASSERT( points_ ); return points_->size(); } - Grid::Spec Unstructured::spec() const { - if (cached_spec_) - return *cached_spec_; + if ( cached_spec_ ) return *cached_spec_; cached_spec_.reset( new Grid::Spec ); - cached_spec_->set("type", static_type()); + cached_spec_->set( "type", static_type() ); - cached_spec_->set("domain",domain().spec()); - cached_spec_->set("projection",projection().spec()); + cached_spec_->set( "domain", domain().spec() ); + cached_spec_->set( "projection", projection().spec() ); std::unique_ptr it( xy_begin() ); - std::vector coords(2*size()); - size_t c(0); + std::vector coords( 2 * size() ); + size_t c( 0 ); PointXY xy; - while( it->next(xy) ) { - coords[c++] = xy.x(); - coords[c++] = xy.y(); + while ( it->next( xy ) ) { + coords[c++] = xy.x(); + coords[c++] = xy.y(); } cached_spec_->set( "xy", coords ); @@ -141,14 +124,11 @@ Grid::Spec Unstructured::spec() const { return *cached_spec_; } - -void Unstructured::print(std::ostream& os) const { +void Unstructured::print( std::ostream& os ) const { os << "Unstructured(Npts:" << size() << ")"; } - } // namespace grid } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index 80b701dab..3e464122f 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,17 +14,16 @@ /// @author Pedro Maciel /// @date January 2015 - #pragma once #include -#include #include -#include "eckit/utils/Hash.h" +#include #include "atlas/grid/detail/grid/Grid.h" +#include "eckit/utils/Hash.h" namespace atlas { - class Mesh; +class Mesh; } namespace atlas { @@ -31,142 +31,127 @@ namespace grid { namespace detail { namespace grid { - class Unstructured : public Grid { - public: - - class IteratorXY: public Grid::IteratorXY { - public: - IteratorXY(const Unstructured& grid, bool begin=true): - grid_(grid), - n_( begin ? 0 : grid_.points_->size() ) { - } - - virtual bool next(PointXY& xy) { - if( n_ != grid_.points_->size() ) { - xy = grid_.xy(n_++); - return true; - } else { - return false; - } - } - - virtual const PointXY operator *() const { - return grid_.xy(n_); - } - - virtual const Grid::IteratorXY& operator ++() { - ++n_; - return *this; - } - - virtual bool operator ==(const Grid::IteratorXY &other) const { - return n_ == static_cast(other).n_; - } - - virtual bool operator !=(const Grid::IteratorXY &other) const { - return n_ != static_cast(other).n_; - } - - private: - const Unstructured& grid_; - size_t n_; - }; - - class IteratorXYPredicated: public Grid::IteratorXY { - public: - IteratorXYPredicated(const Unstructured& grid, Grid::IteratorXY::Predicate p, bool begin=true): - grid_(grid), - p_(p), - size_(grid_.points_->size()), - n_( begin ? 0 : grid_.points_->size() ) { - - if( begin) { - + class IteratorXY : public Grid::IteratorXY { + public: + IteratorXY( const Unstructured& grid, bool begin = true ) : + grid_( grid ), + n_( begin ? 0 : grid_.points_->size() ) {} + + virtual bool next( PointXY& xy ) { + if ( n_ != grid_.points_->size() ) { + xy = grid_.xy( n_++ ); + return true; + } + else { + return false; + } } - } - virtual bool next(PointXY& xy) { - NOTIMP; - if( n_ != grid_.points_->size() ) { - xy = grid_.xy(n_++); - return true; - } else { - return false; - } - } + virtual const PointXY operator*() const { return grid_.xy( n_ ); } - virtual const PointXY operator *() const { - return grid_.xy(n_); - } - - virtual const Grid::IteratorXY& operator ++() { - do { - ++n_; - if( n_ == size_ ) return *this; - } while( not p_(n_) ); - return *this; - } + virtual const Grid::IteratorXY& operator++() { + ++n_; + return *this; + } - virtual bool operator ==(const Grid::IteratorXY &other) const { - return n_ == static_cast(other).n_; - } + virtual bool operator==( const Grid::IteratorXY& other ) const { + return n_ == static_cast( other ).n_; + } - virtual bool operator !=(const Grid::IteratorXY &other) const { - return n_ != static_cast(other).n_; - } + virtual bool operator!=( const Grid::IteratorXY& other ) const { + return n_ != static_cast( other ).n_; + } - private: - const Unstructured& grid_; - Grid::IteratorXY::Predicate p_; - size_t n_; - size_t size_; - }; + private: + const Unstructured& grid_; + size_t n_; + }; + + class IteratorXYPredicated : public Grid::IteratorXY { + public: + IteratorXYPredicated( const Unstructured& grid, Grid::IteratorXY::Predicate p, bool begin = true ) : + grid_( grid ), + p_( p ), + size_( grid_.points_->size() ), + n_( begin ? 0 : grid_.points_->size() ) { + if ( begin ) {} + } + virtual bool next( PointXY& xy ) { + NOTIMP; + if ( n_ != grid_.points_->size() ) { + xy = grid_.xy( n_++ ); + return true; + } + else { + return false; + } + } + virtual const PointXY operator*() const { return grid_.xy( n_ ); } + virtual const Grid::IteratorXY& operator++() { + do { + ++n_; + if ( n_ == size_ ) return *this; + } while ( not p_( n_ ) ); + return *this; + } - class IteratorLonLat: public Grid::IteratorLonLat { - public: - IteratorLonLat(const Unstructured& grid, bool begin=true): - grid_(grid), - n_( begin ? 0 : grid_.points_->size() ) { - } + virtual bool operator==( const Grid::IteratorXY& other ) const { + return n_ == static_cast( other ).n_; + } - virtual bool next(PointLonLat& lonlat) { - if( n_ != grid_.points_->size() ) { - lonlat = grid_.lonlat(n_++); - return true; - } else { - return false; - } - } + virtual bool operator!=( const Grid::IteratorXY& other ) const { + return n_ != static_cast( other ).n_; + } - virtual const PointLonLat operator *() const { - return grid_.lonlat(n_); - } + private: + const Unstructured& grid_; + Grid::IteratorXY::Predicate p_; + size_t n_; + size_t size_; + }; + + class IteratorLonLat : public Grid::IteratorLonLat { + public: + IteratorLonLat( const Unstructured& grid, bool begin = true ) : + grid_( grid ), + n_( begin ? 0 : grid_.points_->size() ) {} + + virtual bool next( PointLonLat& lonlat ) { + if ( n_ != grid_.points_->size() ) { + lonlat = grid_.lonlat( n_++ ); + return true; + } + else { + return false; + } + } - virtual const Grid::IteratorLonLat& operator ++() { - ++n_; - return *this; - } + virtual const PointLonLat operator*() const { return grid_.lonlat( n_ ); } - virtual bool operator ==(const Grid::IteratorLonLat &other) const { - return n_ == static_cast(other).n_; - } + virtual const Grid::IteratorLonLat& operator++() { + ++n_; + return *this; + } - virtual bool operator !=(const Grid::IteratorLonLat &other) const { - return n_ != static_cast(other).n_; - } + virtual bool operator==( const Grid::IteratorLonLat& other ) const { + return n_ == static_cast( other ).n_; + } - private: - const Unstructured& grid_; - size_t n_; - }; + virtual bool operator!=( const Grid::IteratorLonLat& other ) const { + return n_ != static_cast( other ).n_; + } -public: // methods + private: + const Unstructured& grid_; + size_t n_; + }; +public: // methods static std::string static_type() { return "unstructured"; } virtual std::string name() const; virtual std::string type() const { return static_type(); } @@ -175,16 +160,16 @@ class Unstructured : public Grid { Unstructured( const Config& ); /// Constructor taking a list of points (takes ownership) - Unstructured( std::vector< PointXY >* pts ); + Unstructured( std::vector* pts ); /// Constructor taking a list of points (takes ownership) - Unstructured( std::vector< PointXY >&& pts ); + Unstructured( std::vector&& pts ); /// Constructor taking a mesh Unstructured( const Mesh& m ); /// Constructor from initializer list - Unstructured( std::initializer_list< PointXY > ); + Unstructured( std::initializer_list ); virtual ~Unstructured(); @@ -192,39 +177,38 @@ class Unstructured : public Grid { virtual Spec spec() const; + PointXY xy( size_t n ) const { return ( *points_ )[n]; } - PointXY xy(size_t n) const { return (*points_)[n]; } - - PointLonLat lonlat(size_t n) const { return projection_.lonlat((*points_)[n]); } + PointLonLat lonlat( size_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 { return new IteratorXYPredicated(*this,p); } - virtual IteratorXYPredicated* xy_end(IteratorXY::Predicate p) const { return new IteratorXYPredicated(*this,p,false); } - -private: // methods + 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 { + return new IteratorXYPredicated( *this, p ); + } + virtual IteratorXYPredicated* xy_end( IteratorXY::Predicate p ) const { + return new IteratorXYPredicated( *this, p, false ); + } - virtual void print(std::ostream&) const; +private: // methods + virtual void print( std::ostream& ) const; /// Hash of the lonlat array + BoundingBox - virtual void hash(eckit::Hash&) const; + virtual void hash( eckit::Hash& ) const; protected: - /// Storage of coordinate points - std::unique_ptr< std::vector< PointXY > > points_; + std::unique_ptr> points_; /// Cache for the shortName mutable std::string shortName_; /// Cache for the spec since may be quite heavy to compute mutable std::unique_ptr cached_spec_; - }; - } // namespace grid } // namespace detail } // namespace grid diff --git a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc index 61487378a..b6b8e4d4f 100644 --- a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc @@ -1,13 +1,13 @@ +#include "atlas/grid/detail/partitioner/CheckerboardPartitioner.h" +#include #include #include -#include -#include #include -#include -#include "atlas/grid/detail/partitioner/CheckerboardPartitioner.h" -#include "atlas/util/MicroDeg.h" -#include "atlas/runtime/Log.h" +#include +#include #include "atlas/grid/Grid.h" +#include "atlas/runtime/Log.h" +#include "atlas/util/MicroDeg.h" using atlas::util::microdeg; @@ -16,223 +16,206 @@ namespace grid { namespace detail { namespace partitioner { -CheckerboardPartitioner::CheckerboardPartitioner() : - Partitioner() { - nbands_ = 0; // to be computed later - checkerboard_ = true; // default +CheckerboardPartitioner::CheckerboardPartitioner() : Partitioner() { + nbands_ = 0; // to be computed later + checkerboard_ = true; // default } -CheckerboardPartitioner::CheckerboardPartitioner(int N) : - Partitioner(N) { - nbands_ = 0; // to be computed later - checkerboard_ = true; // default +CheckerboardPartitioner::CheckerboardPartitioner( int N ) : Partitioner( N ) { + nbands_ = 0; // to be computed later + checkerboard_ = true; // default } -CheckerboardPartitioner::CheckerboardPartitioner(int N, int nbands) : - Partitioner(N) { - nbands_ = nbands; - checkerboard_ = true; // default +CheckerboardPartitioner::CheckerboardPartitioner( int N, int nbands ) : Partitioner( N ) { + nbands_ = nbands; + checkerboard_ = true; // default } -CheckerboardPartitioner::CheckerboardPartitioner(int N, int nbands, bool checkerboard) : - Partitioner(N) { - nbands_ = nbands; - checkerboard_ = checkerboard; +CheckerboardPartitioner::CheckerboardPartitioner( int N, int nbands, bool checkerboard ) : Partitioner( N ) { + nbands_ = nbands; + checkerboard_ = checkerboard; } -CheckerboardPartitioner::Checkerboard CheckerboardPartitioner::checkerboard(const Grid& grid) const { - - // grid dimensions - const RegularGrid rg(grid); - if ( !rg ) - throw eckit::BadValue("Checkerboard Partitioner only works for Regular grids.",Here()); - - Checkerboard cb; - - cb.nx=rg.nx(); - cb.ny=rg.ny(); - size_t nparts = nb_partitions(); - - 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=(int) 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 - - // true checkerboard means nbands must divide nparts - if (checkerboard_) { - while ( nparts % cb.nbands !=0 ) cb.nbands--; +CheckerboardPartitioner::Checkerboard CheckerboardPartitioner::checkerboard( const Grid& grid ) const { + // grid dimensions + const RegularGrid rg( grid ); + if ( !rg ) throw eckit::BadValue( "Checkerboard Partitioner only works for Regular grids.", Here() ); + + Checkerboard cb; + + cb.nx = rg.nx(); + cb.ny = rg.ny(); + size_t nparts = nb_partitions(); + + 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 = (int)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 + + // true checkerboard means nbands must divide nparts + if ( checkerboard_ ) { + while ( nparts % cb.nbands != 0 ) + cb.nbands--; + } } - } - if (checkerboard_ && nparts%cb.nbands!=0) - throw eckit::BadValue("number of bands doesn't divide number of partitions",Here()); + if ( checkerboard_ && nparts % cb.nbands != 0 ) + throw eckit::BadValue( "number of bands doesn't divide number of partitions", Here() ); - return cb; + return cb; } -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); - return false; +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 ); + 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); - 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 ); + return false; } -void CheckerboardPartitioner::partition( const Checkerboard& cb, int nb_nodes, NodeInt nodes[], int part[]) const -{ - size_t nparts = nb_partitions(); - size_t nbands = cb.nbands; - size_t nx = cb.nx; - size_t ny = cb.ny; - size_t remainder; - - /* - Sort nodes from south to north (increasing y), and west to east (increasing x). Now we can easily split - the points in bands. Note this may not be necessary, as it could be - already by construction in this order, but then sorting is really fast - */ - - /* - Number of procs per band - */ - std::vector< size_t > npartsb(nbands,0); // number of procs per band - remainder=nparts; - for (size_t iband=0;iband ngpb(nbands,0); - // split latitudes? - if (true) - { - remainder=nb_nodes; - for (size_t iband=0;iband ngpp(npartsb[iband],0); - remainder=ngpb[iband]; - //std::cout << "remainder = " << remainder << std::endl; - for (size_t ipart=0;ipart ngpb( nbands, 0 ); + // split latitudes? + if ( true ) { + remainder = nb_nodes; + for ( size_t iband = 0; iband < nbands; iband++ ) { + ngpb[iband] = ( nb_nodes * npartsb[iband] ) / nparts; + remainder -= ngpb[iband]; + } + // distribute remaining gridpoints over first bands + for ( size_t iband = 0; iband < remainder; iband++ ) + ++ngpb[iband]; + } + else { + remainder = ny; + for ( size_t iband = 0; iband < nbands; iband++ ) { + ngpb[iband] = nx * ( ( ny * npartsb[iband] ) / nparts ); + remainder -= ngpb[iband] / nx; + } + // distribute remaining rows over first bands + for ( size_t iband = 0; iband < remainder; iband++ ) + ngpb[iband] += nx; } - } + // for (int iband=0;iband ngpp( npartsb[iband], 0 ); + remainder = ngpb[iband]; + // std::cout << "remainder = " << remainder << std::endl; + for ( size_t ipart = 0; ipart < npartsb[iband]; ipart++ ) { + ngpp[ipart] = ngpb[iband] / npartsb[iband]; + remainder -= ngpp[ipart]; + // std::cout << "remainder = " << remainder << std::endl; + } + // distribute remaining gridpoints over first parts + for ( size_t ipart = 0; ipart < remainder; ipart++ ) + ++ngpp[ipart]; + + /* +std::cout << "ngpb = " << ngpb[iband] << "\n"; +for (int ipart=0;ipart nodes(grid.size()); - int n(0); - - for(size_t iy = 0; iy < cb.ny; ++iy) +void CheckerboardPartitioner::partition( const Grid& grid, int part[] ) const { + if ( nb_partitions() == 1 ) // trivial solution, so much faster { - for(size_t ix = 0; ix < cb.nx; ++ix) - { - nodes[n].x = ix; - nodes[n].y = iy; - nodes[n].n = n; - ++n; - } + for ( size_t j = 0; j < grid.size(); ++j ) + part[j] = 0; + } + else { + auto cb = checkerboard( grid ); + + std::vector nodes( grid.size() ); + int n( 0 ); + + for ( size_t iy = 0; iy < cb.ny; ++iy ) { + for ( size_t ix = 0; ix < cb.nx; ++ix ) { + nodes[n].x = ix; + nodes[n].y = iy; + nodes[n].n = n; + ++n; + } + } + + partition( cb, grid.size(), nodes.data(), part ); } - - partition( cb, grid.size(), nodes.data(), part); - } } -} // namespace partitioner -} // namespace detail -} // namespace grid -} // namespace atlas +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas namespace { - atlas::grid::detail::partitioner::PartitionerBuilder __CheckerBoard("checkerboard"); +atlas::grid::detail::partitioner::PartitionerBuilder + __CheckerBoard( "checkerboard" ); } - - - diff --git a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.h b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.h index 63751fbd0..c50ad9dc9 100644 --- a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.h +++ b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.h @@ -8,54 +8,48 @@ namespace grid { namespace detail { namespace partitioner { -class CheckerboardPartitioner: public Partitioner { - +class CheckerboardPartitioner : public Partitioner { public: - CheckerboardPartitioner(); - CheckerboardPartitioner(int N); // N is the number of parts (aka MPI tasks) - - CheckerboardPartitioner(int N, int nbands); - CheckerboardPartitioner(int N, int nbands, bool checkerboard); + CheckerboardPartitioner( int N ); // N is the number of parts (aka MPI tasks) + CheckerboardPartitioner( int N, int nbands ); + CheckerboardPartitioner( int N, int nbands, bool checkerboard ); - // Node struct that holds the x and y indices (for global, it's longitude and latitude in millidegrees (integers)) + // Node struct that holds the x and y indices (for global, it's longitude and + // latitude in millidegrees (integers)) // This structure is used in sorting algorithms, and uses less memory than // if x and y were in double precision. - struct NodeInt - { - int x, y; - int n; + struct NodeInt { + int x, y; + int n; }; virtual std::string type() const { return "checkerboard"; } private: - struct Checkerboard { - size_t nbands; // number of bands - size_t nx, ny; // grid dimensions + size_t nbands; // number of bands + size_t nx, ny; // grid dimensions }; - Checkerboard checkerboard(const Grid&) const; + Checkerboard checkerboard( const Grid& ) const; // Doesn't matter if nodes[] is in degrees or radians, as a sorting // algorithm is used internally - void partition( const Checkerboard& cb, int nb_nodes, NodeInt nodes[], int part[]) const; + void partition( const Checkerboard& cb, int nb_nodes, NodeInt nodes[], int part[] ) const; virtual void partition( const Grid&, int part[] ) const; void check() const; private: - size_t nbands_; // number of bands from configuration bool checkerboard_; // exact (true) or approximate (false) checkerboard - }; -} // namespace partitioner -} // namespace detail -} // namespace grid -} // namespace atlas +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index b91ff4397..8e9fc55d2 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -4,23 +4,24 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" +#include #include #include -#include -#include #include -#include +#include +#include #include "atlas/grid/Grid.h" -#include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" -#include "atlas/util/MicroDeg.h" -#include "atlas/runtime/Trace.h" -#include "atlas/runtime/Log.h" -#include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/mpi/Buffer.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Log.h" +#include "atlas/runtime/Trace.h" +#include "atlas/util/MicroDeg.h" using atlas::util::microdeg; @@ -29,106 +30,120 @@ namespace grid { namespace detail { namespace partitioner { -double gamma(const double& x) { +double gamma( const double& x ) { double p[14]; double w, y; int k, n; - p[0 ] = 0.999999999999999990e+00; - p[1 ] = -0.422784335098466784e+00; - p[2 ] = -0.233093736421782878e+00; - p[3 ] = 0.191091101387638410e+00; - p[4 ] = -0.024552490005641278e+00; - p[5 ] = -0.017645244547851414e+00; - p[6 ] = 0.008023273027855346e+00; - p[7 ] = -0.000804329819255744e+00; - p[8 ] = -0.000360837876648255e+00; - p[9 ] = 0.000145596568617526e+00; + p[0] = 0.999999999999999990e+00; + p[1] = -0.422784335098466784e+00; + p[2] = -0.233093736421782878e+00; + p[3] = 0.191091101387638410e+00; + p[4] = -0.024552490005641278e+00; + p[5] = -0.017645244547851414e+00; + p[6] = 0.008023273027855346e+00; + p[7] = -0.000804329819255744e+00; + p[8] = -0.000360837876648255e+00; + p[9] = 0.000145596568617526e+00; p[10] = -0.000017545539395205e+00; p[11] = -0.000002591225267689e+00; - p[12] = 0.000001337767384067e+00; + p[12] = 0.000001337767384067e+00; p[13] = -0.000000199542863674e+00; - n = round(x - 2); - w = x - (n + 2); - y = ((((((((((((p[13] * w + p[12]) * w + p[11]) * w + p[10]) * - w + p[9]) * w + p[8]) * w + p[7]) * w + p[6]) * w + p[5]) * - w + p[4]) * w + p[3]) * w + p[2]) * w + p[1]) * w + p[0]; - if (n > 0) { + n = round( x - 2 ); + w = x - ( n + 2 ); + y = ( ( ( ( ( ( ( ( ( ( ( ( p[13] * w + p[12] ) * w + p[11] ) * w + p[10] ) * w + p[9] ) * w + p[8] ) * w + p[7] ) * + w + + p[6] ) * + w + + p[5] ) * + w + + p[4] ) * + w + + p[3] ) * + w + + p[2] ) * + w + + p[1] ) * + w + + p[0]; + if ( n > 0 ) { w = x - 1; - for( k = 2; k<= n; ++k ) - w = w * (x - k); - } else { + for ( k = 2; k <= n; ++k ) + w = w * ( x - k ); + } + else { w = 1; - for( k = 0; k<= -n - 1; ++k) - y = y * (x + k); + for ( k = 0; k <= -n - 1; ++k ) + y = y * ( x + k ); } - return w/y; + return w / y; } - -double area_of_cap(const double& s_cap) { +double area_of_cap( const double& s_cap ) { // // AREA_OF_CAP Area of spherical cap // // AREA_OF_CAP(S_CAP) sets AREA to be the area of an S^2 spherical // cap of spherical radius S_CAP. // - return 4.0*M_PI * std::pow( std::sin(0.5*s_cap), 2 ); + return 4.0 * M_PI * std::pow( std::sin( 0.5 * s_cap ), 2 ); } -double area_of_collar(const double& a_top, const double& a_bot) { +double area_of_collar( const double& a_top, const double& a_bot ) { // AREA_OF_COLLAR Area of spherical collar // // AREA_OF_COLLAR(A_TOP, A_BOT) sets AREA to be the area of an S^2 spherical - // collar specified by A_TOP, A_BOT, where A_TOP is top (smaller) spherical radius, + // collar specified by A_TOP, A_BOT, where A_TOP is top (smaller) spherical + // radius, // A_BOT is bottom (larger) spherical radius. // - return area_of_cap(a_bot) - area_of_cap(a_top); + return area_of_cap( a_bot ) - area_of_cap( a_top ); } -double sradius_of_cap(const double& area) { +double sradius_of_cap( const double& area ) { // SRADIUS_OF_CAP(AREA) returns the spherical radius of // an S^2 spherical cap of area AREA. // - return 2.*std::asin(0.5*std::sqrt(area/M_PI)); + return 2. * std::asin( 0.5 * std::sqrt( area / M_PI ) ); } -double area_of_ideal_region(int N) { +double area_of_ideal_region( int N ) { // // AREA_OF_IDEAL_REGION(N) sets AREA to be the area of one of N equal // area regions on S^2, that is 1/N times AREA_OF_SPHERE. // - double area_of_sphere = 2.*std::pow(M_PI,1.5)/gamma(1.5); - return area_of_sphere/static_cast(N); + double area_of_sphere = 2. * std::pow( M_PI, 1.5 ) / gamma( 1.5 ); + return area_of_sphere / static_cast( N ); } -double polar_colat(int N) { +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) ); + 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 ) ); return polar_c; } -double ideal_collar_angle(int N) { +double ideal_collar_angle( int N ) { // // IDEAL_COLLAR_ANGLE The ideal angle for spherical collars of an EQ partition // // IDEAL_COLLAR_ANGLE(N) sets ANGLE to the ideal angle for the // spherical collars of an EQ partition of the unit sphere S^2 into N regions. // - return std::sqrt( area_of_ideal_region(N) ); + return std::sqrt( area_of_ideal_region( N ) ); } -void ideal_region_list(int N, const double& c_polar, int n_collars, double r_regions[]) { +void ideal_region_list( int N, const double& c_polar, int n_collars, double r_regions[] ) { // // IDEAL_REGION_LIST The ideal real number of regions in each zone // // List the ideal real number of regions in each collar, plus the polar caps. // - // Given N, c_polar and n_collars, determine r_regions, a list of the ideal real + // Given N, c_polar and n_collars, determine r_regions, a list of the ideal + // real // number of regions in each collar, plus the polar caps. // The number of elements is n_collars+2. // r_regions[1] is 1. @@ -136,38 +151,39 @@ void ideal_region_list(int N, const double& c_polar, int n_collars, double r_reg // The sum of r_regions is N. // // real(wp),intent(out) :: r_regions(n_collars+2) - double ideal_region_area,ideal_collar_area; + double ideal_region_area, ideal_collar_area; r_regions[0] = 1.; - if( n_collars > 0 ) { + if ( n_collars > 0 ) { // // Based on n_collars and c_polar, determine a_fitting, // the collar angle such that n_collars collars fit between the polar caps. // - double a_fitting = (M_PI-2.*c_polar)/static_cast(n_collars); - ideal_region_area = area_of_ideal_region(N); - for(int collar_n=0; collar_n < n_collars; ++collar_n) { - ideal_collar_area = area_of_collar(c_polar+collar_n*a_fitting, c_polar+(collar_n+1)*a_fitting); - r_regions[1+collar_n] = ideal_collar_area / ideal_region_area; + double a_fitting = ( M_PI - 2. * c_polar ) / static_cast( n_collars ); + ideal_region_area = area_of_ideal_region( N ); + for ( int collar_n = 0; collar_n < n_collars; ++collar_n ) { + ideal_collar_area = + area_of_collar( c_polar + collar_n * a_fitting, c_polar + ( collar_n + 1 ) * a_fitting ); + r_regions[1 + collar_n] = ideal_collar_area / ideal_region_area; } } - r_regions[2+n_collars-1] = 1.; + r_regions[2 + n_collars - 1] = 1.; } -int num_collars(int N, const double& c_polar, const double& a_ideal) { +int num_collars( int N, const double& c_polar, const double& a_ideal ) { // // NUM_COLLARS The number of collars between the polar caps // // Given N, an ideal angle, and c_polar, // determine n_collars, the number of collars between the polar caps. // - bool enough = (N > 2) && (a_ideal > 0); - if( enough ) - return std::max(1, static_cast(round((M_PI-2.*c_polar)/a_ideal))); + bool enough = ( N > 2 ) && ( a_ideal > 0 ); + if ( enough ) + return std::max( 1, static_cast( round( ( M_PI - 2. * c_polar ) / a_ideal ) ) ); else return 0; } -void round_to_naturals(int N, int ncollars, double r_regions[], int n_regions[]) { +void round_to_naturals( int N, int ncollars, double r_regions[], int n_regions[] ) { // ROUND_TO_NATURALS Round off a given list of numbers of regions // // Given N and r_regions, determine n_regions, @@ -179,17 +195,19 @@ void round_to_naturals(int N, int ncollars, double r_regions[], int n_regions[]) // The sum of n_regions is N. // double discrepancy = 0.; - for( int zone_n=0; zone_n& n_regions, std::vector& s_cap) { +void eq_caps( int N, std::vector& n_regions, std::vector& s_cap ) { // - // eq_regions uses the zonal equal area sphere partitioning algorithm to partition + // eq_regions uses the zonal equal area sphere partitioning algorithm to + // partition // the surface of a sphere into N regions of equal area and small diameter. // - if( N == 1 ) { + if ( N == 1 ) { // // We have only one region, which must be the whole sphere. // - n_regions.resize(1); - s_cap.resize(1); - n_regions[0]=1; - s_cap[0] = M_PI; + n_regions.resize( 1 ); + s_cap.resize( 1 ); + n_regions[0] = 1; + s_cap[0] = M_PI; // int n_regions_ns=1; - } else { + } + else { // // Given N, determine c_polar // the colatitude of the North polar spherical cap. // - double c_polar = polar_colat(N); + double c_polar = polar_colat( N ); // // Given N, determine the ideal angle for spherical collars. // Based on N, this ideal angle, and c_polar, // determine n_collars, the number of collars between the polar caps. // - int n_collars = num_collars(N,c_polar,ideal_collar_angle(N)); + int n_collars = num_collars( N, c_polar, ideal_collar_angle( N ) ); // int n_regions_ns=n_collars+2; // @@ -246,8 +266,8 @@ void eq_caps(int N, std::vector& n_regions, std::vector& s_cap) { // r_regions[0] is 1. // r_regions[2+n_collars-1] is 1. // The sum of r_regions is N. - std::vector r_regions(n_collars+2); - ideal_region_list(N,c_polar,n_collars,r_regions.data()); + std::vector r_regions( n_collars + 2 ); + ideal_region_list( N, c_polar, n_collars, r_regions.data() ); // // Given N and r_regions, determine n_regions, a list of the natural number // of regions in each collar and the polar caps. @@ -257,25 +277,25 @@ void eq_caps(int N, std::vector& n_regions, std::vector& s_cap) { // n_regions[2+n_collars-1] is 1. // The sum of n_regions is N. // - n_regions.resize(n_collars+2); - round_to_naturals(N,n_collars,r_regions.data(),n_regions.data()); + n_regions.resize( n_collars + 2 ); + round_to_naturals( N, n_collars, r_regions.data(), n_regions.data() ); // // Given dim, N, c_polar and n_regions, determine s_cap, - // an increasing list of colatitudes of spherical caps which enclose the same area + // an increasing list of colatitudes of spherical caps which enclose the + // same area // as that given by the cumulative sum of regions. // The number of elements is n_collars+2. // s_cap[0] is c_polar. // s_cap[n_collars] is Pi-c_polar. // s_cap[n_collars+1] is Pi. // - s_cap.resize(n_collars+2); - cap_colats(N,n_collars,c_polar,n_regions.data(),s_cap.data()); + s_cap.resize( n_collars + 2 ); + cap_colats( N, n_collars, c_polar, n_regions.data(), s_cap.data() ); } // int n_regions_ew=maxval(n_regions(:)); } - -void eq_regions(int N, double xmin[], double xmax[], double ymin[], double ymax[]) { +void eq_regions( int N, double xmin[], double xmax[], double ymin[], double ymax[] ) { // EQ_REGIONS Recursive zonal equal area (EQ) partition of sphere // // Syntax @@ -289,37 +309,42 @@ void eq_regions(int N, double xmin[], double xmax[], double ymin[], double ymax[ // The arguments dim and N must be positive integers. // // The result REGIONS is a (dim by 2 by N) array, representing the regions - // of S^dim. Each element represents a pair of vertex points in spherical polar + // of S^dim. Each element represents a pair of vertex points in spherical + // polar // coordinates. // // Each region is defined as a product of intervals in spherical polar - // coordinates. The pair of vertex points regions(:,1,n) and regions(:,2,n) give + // coordinates. The pair of vertex points regions(:,1,n) and regions(:,2,n) + // give // the lower and upper limits of each interval. // // REGIONS = EQ_REGIONS(dim,N,'offset','extra') uses experimental extra - // offsets for S^2 and S^3 to try to minimize energy. If dim > 3, extra offsets + // offsets for S^2 and S^3 to try to minimize energy. If dim > 3, extra + // offsets // are not used. // // REGIONS = EQ_REGIONS(dim,N,extra_offset) uses experimental extra offsets // if extra_offset is true or non-zero. // // [REGIONS,DIM_1_ROT] = EQ_REGIONS(dim,N) also returns DIM_1_ROT, a cell - // array containing N rotation matrices, one per region, each of size dim by dim. + // array containing N rotation matrices, one per region, each of size dim by + // dim. // These describe the R^dim rotation needed to place the region in its final // position. // // [REGIONS,DIM_1_ROT] = EQ_REGIONS(dim,N,'offset','extra') partitions S^dim - // into N regions, using extra offsets, and also returning DIM_1_ROT, as above. + // into N regions, using extra offsets, and also returning DIM_1_ROT, as + // above. // - if (N == 1) { + if ( N == 1 ) { // // We have only one region, which must be the whole sphere. // - xmin[0]=0.; - ymin[0]=-0.5*M_PI; - xmax[0]=2.*M_PI; - ymax[0]=0.5*M_PI; + xmin[0] = 0.; + ymin[0] = -0.5 * M_PI; + xmax[0] = 2. * M_PI; + ymax[0] = 0.5 * M_PI; return; } // @@ -328,7 +353,7 @@ void eq_regions(int N, double xmin[], double xmax[], double ymin[], double ymax[ // std::vector n_regions; std::vector s_cap; - eq_caps(N,n_regions,s_cap); + eq_caps( N, n_regions, s_cap ); // // s_cap is an increasing list of colatitudes of the caps. // @@ -336,81 +361,79 @@ void eq_regions(int N, double xmin[], double xmax[], double ymin[], double ymax[ // We have a number of zones: two polar caps and a number of collars. // n_regions is the list of the number of regions in each zone. // - int n_collars = n_regions.size()-2; + int n_collars = n_regions.size() - 2; // // Start with the top cap. // - xmin[0]=0.; - ymin[0]=0.5*M_PI-s_cap[0]; - xmax[0]=2.*M_PI; - ymax[0]=0.5*M_PI; + xmin[0] = 0.; + ymin[0] = 0.5 * M_PI - s_cap[0]; + xmax[0] = 2. * M_PI; + ymax[0] = 0.5 * M_PI; int region_n = 1; - for( int collar_n=0; collar_n(n_regions[collar_n+1]))*region_ew; - ymin[region_n]=0.5*M_PI-s_cap[collar_n+1]; - xmax[region_n]=2.*M_PI/(static_cast(n_regions[collar_n+1]))*(region_ew+1.); - ymax[region_n]=0.5*M_PI-s_cap[collar_n]; + for ( int collar_n = 0; collar_n < n_collars; ++collar_n ) { + for ( int region_ew = 0; region_ew < n_regions[collar_n + 1]; ++region_ew ) { + xmin[region_n] = 2. * M_PI / ( static_cast( n_regions[collar_n + 1] ) ) * region_ew; + ymin[region_n] = 0.5 * M_PI - s_cap[collar_n + 1]; + xmax[region_n] = 2. * M_PI / ( static_cast( n_regions[collar_n + 1] ) ) * ( region_ew + 1. ); + ymax[region_n] = 0.5 * M_PI - s_cap[collar_n]; ++region_n; } } // // End with the bottom cap. // - xmin[N-1]=0.; - ymin[N-1]=-0.5*M_PI; - xmax[N-1]=2.*M_PI; - ymax[N-1]=0.5*M_PI-s_cap[s_cap.size()-2]; + xmin[N - 1] = 0.; + ymin[N - 1] = -0.5 * M_PI; + xmax[N - 1] = 2. * M_PI; + ymax[N - 1] = 0.5 * M_PI - s_cap[s_cap.size() - 2]; } -EqualRegionsPartitioner::EqualRegionsPartitioner() : - Partitioner(), - N_(nb_partitions()) { +EqualRegionsPartitioner::EqualRegionsPartitioner() : Partitioner(), N_( nb_partitions() ) { std::vector s_cap; - eq_caps(N_, sectors_, s_cap); - bands_.resize(s_cap.size()); - for (size_t n = 0; n < s_cap.size(); ++n) { - bands_[n] = 0.5*M_PI-s_cap[n]; + eq_caps( N_, sectors_, s_cap ); + bands_.resize( s_cap.size() ); + for ( size_t n = 0; n < s_cap.size(); ++n ) { + bands_[n] = 0.5 * M_PI - s_cap[n]; } } -EqualRegionsPartitioner::EqualRegionsPartitioner(int N) : - Partitioner(N), - N_(N) { +EqualRegionsPartitioner::EqualRegionsPartitioner( int N ) : Partitioner( N ), N_( N ) { std::vector s_cap; - eq_caps(N_, sectors_, s_cap); - bands_.resize(s_cap.size()); - for (size_t n = 0; n < s_cap.size(); ++n) { - bands_[n] = 0.5*M_PI-s_cap[n]; + eq_caps( N_, sectors_, s_cap ); + bands_.resize( s_cap.size() ); + for ( size_t n = 0; n < s_cap.size(); ++n ) { + bands_[n] = 0.5 * M_PI - s_cap[n]; } } -int EqualRegionsPartitioner::partition(const double& x, const double& y) const { - int b = band(y); +int EqualRegionsPartitioner::partition( const double& x, const double& y ) const { + int b = band( y ); int p = 0; - for(int n=0; n() ) ); +int EqualRegionsPartitioner::band( const double& y ) const { + return std::distance( bands_.begin(), std::lower_bound( bands_.begin(), bands_.end(), y, std::greater() ) ); } -int EqualRegionsPartitioner::sector(int band, const double& x) const { +int EqualRegionsPartitioner::sector( int band, const double& x ) const { double xreg = x; - if(x<0.) xreg += 2.*M_PI; - else if(x>2.*M_PI) xreg -= 2.*M_PI; - return std::floor(xreg*sectors_[band]/(2.*M_PI+1e-8)); + if ( x < 0. ) + xreg += 2. * M_PI; + else if ( x > 2. * M_PI ) + xreg -= 2. * M_PI; + return std::floor( xreg * sectors_[band] / ( 2. * M_PI + 1e-8 ) ); } -void EqualRegionsPartitioner::where(int partition, int& band, int& sector) const { - int p=0; - for(size_t b = 0; b < bands_.size(); ++b) { - for( int s=0; s node2.y ) return true; - if( node1.y == node2.y ) return (node1.x < node2.x); +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 ); 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); +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 ); return false; } void EqualRegionsPartitioner::partition( int nb_nodes, NodeInt nodes[], int part[] ) const { - ATLAS_TRACE( "EqualRegionsPartitioner::partition" ); - // std::clock_t init, final; // init=std::clock(); // std::cout << "partition start (" << nb_nodes << " points)" << std::endl; @@ -447,48 +468,50 @@ void EqualRegionsPartitioner::partition( int nb_nodes, NodeInt nodes[], int part int band; /* - Sort nodes from north to south, and west to east. Now we can easily split - the points in bands. Note, for RGG, this should not be necessary, as it is - already by construction in this order, but then sorting is really fast - */ + Sort nodes from north to south, and west to east. Now we can easily split + the points in bands. Note, for RGG, this should not be necessary, as it is + already by construction in this order, but then sorting is really fast + */ -// std::sort( nodes, nodes+nb_nodes, compare_NS_WE); + // std::sort( nodes, nodes+nb_nodes, compare_NS_WE); /* - For every band, now sort from west to east, and north to south. Inside every band - we can now easily split nodes in sectors. - */ - int chunk_size = nb_nodes/nb_parts; - int chunk_remainder = nb_nodes - chunk_size*nb_parts; - int remainder = chunk_remainder; + For every band, now sort from west to east, and north to south. Inside every + band + we can now easily split nodes in sectors. + */ + int chunk_size = nb_nodes / nb_parts; + int chunk_remainder = nb_nodes - chunk_size * nb_parts; + int remainder = chunk_remainder; std::vector count; - count.reserve(nb_parts); - end=0; - for( band=0; band0?1:0) ); + for ( p = 0; p < nb_regions( band ); ++p ) { + count.push_back( chunk_size + ( remainder-- > 0 ? 1 : 0 ) ); end += count.back(); } - std::sort( nodes+begin, nodes+end, compare_WE_NS ); + std::sort( nodes + begin, nodes + end, compare_WE_NS ); } /* - Create list that tells in original node numbering which part the node belongs to - */ + Create list that tells in original node numbering which part the node belongs + to + */ remainder = chunk_remainder; - end = 0; - for( p=0; p nodes(grid.size()); - int* nodes_buffer = reinterpret_cast(nodes.data()); - long nb_workers = comm.size(); + std::vector nodes( grid.size() ); + int* nodes_buffer = reinterpret_cast( nodes.data() ); + long nb_workers = comm.size(); /* - Sort nodes from north to south, and west to east. Now we can easily split - the points in bands. Note, for StructuredGrid, this should not be necessary, as it is - already by construction in this order, but then sorting is really fast - */ + Sort nodes from north to south, and west to east. Now we can easily split + the points in bands. Note, for StructuredGrid, this should not be necessary, + as it is + already by construction in this order, but then sorting is really fast + */ - if( StructuredGrid(grid) ) { - // The grid comes sorted from north to south and west to east by construction + if ( StructuredGrid( grid ) ) { + // The grid comes sorted from north to south and west to east by + // construction // Assert to make sure. - StructuredGrid structured_grid(grid); - ASSERT( structured_grid.y(1) < structured_grid.y(0) ); - ASSERT( structured_grid.x(1,0) > structured_grid.x(0,0) ); - - ATLAS_TRACE("Take shortcut"); - int n(0); - for( size_t j=0; j structured_grid.x( 0, 0 ) ); + + ATLAS_TRACE( "Take shortcut" ); + int n( 0 ); + for ( size_t j = 0; j < structured_grid.ny(); ++j ) { + double y = microdeg( structured_grid.y( j ) ); + for ( size_t i = 0; i < structured_grid.nx( j ); ++i, ++n ) { + nodes[n].x = microdeg( structured_grid.x( i, j ) ); nodes[n].y = y; nodes[n].n = n; } } - } else { - ATLAS_TRACE("sort all"); + } + else { + ATLAS_TRACE( "sort all" ); std::vector requests; - for( int w=0; w w_nodes(w_size); - int* w_nodes_buffer = reinterpret_cast(w_nodes.data()); + if ( mpi_rank == work_rank ) { + std::vector w_nodes( w_size ); + int* w_nodes_buffer = reinterpret_cast( w_nodes.data() ); - ATLAS_TRACE_SCOPE("create one bit") { - if( true ) // optimized experimental when true (still need to benchmark) + ATLAS_TRACE_SCOPE( "create one bit" ) { + if ( true ) // optimized experimental when true (still need to + // benchmark) { - auto filter = [w_begin,w_end](long n) { - return (n>=w_begin && n= w_begin && n < w_end ); }; + int i = w_begin; + int j( 0 ); + for ( PointXY point : grid.xy( filter ) ) { + w_nodes[j].x = microdeg( point.x() ); + w_nodes[j].y = microdeg( point.y() ); w_nodes[j].n = i++; ++j; } } - else - { - int i(0); - int j(0); - for( PointXY point : grid.xy() ) { - if( i >= w_begin && i < w_end ) { - w_nodes[j].x = microdeg(point.x()); - w_nodes[j].y = microdeg(point.y()); - w_nodes[j].n = i; - ++j; + else { + int i( 0 ); + int j( 0 ); + for ( PointXY point : grid.xy() ) { + if ( i >= w_begin && i < w_end ) { + w_nodes[j].x = microdeg( point.x() ); + w_nodes[j].y = microdeg( point.y() ); + w_nodes[j].n = i; + ++j; } ++i; } } } - ATLAS_TRACE_SCOPE("sort one bit") { - std::sort(w_nodes.begin(),w_nodes.end(), compare_NS_WE ); - } - ATLAS_TRACE_SCOPE("send to rank0") { - comm.send( w_nodes_buffer, 3*w_size, /* dest= */ 0, /* tag= */ 0 ); + ATLAS_TRACE_SCOPE( "sort one bit" ) { std::sort( w_nodes.begin(), w_nodes.end(), compare_NS_WE ); } + ATLAS_TRACE_SCOPE( "send to rank0" ) { + comm.send( w_nodes_buffer, 3 * w_size, /* dest= */ 0, /* tag= */ 0 ); } } } ATLAS_TRACE_MPI( WAIT ) { - for( auto request : requests ) { + for ( auto request : requests ) { comm.wait( request ); } } - ATLAS_TRACE_SCOPE("merge sorted") { - for( int w=0; w requests; - int nb_parts = N_; - int nb_nodes = grid.size(); - int chunk_size = nb_nodes/nb_parts; - int chunk_remainder = nb_nodes - chunk_size*nb_parts; - int remainder = chunk_remainder; - std::vector count; count.reserve(nb_parts); - std::vector displs; displs.reserve(nb_parts); - std::vector b_count; b_count.reserve(nb_bands()); - std::vector b_displs; b_displs.reserve(nb_bands()); + int nb_parts = N_; + int nb_nodes = grid.size(); + int chunk_size = nb_nodes / nb_parts; + int chunk_remainder = nb_nodes - chunk_size * nb_parts; + int remainder = chunk_remainder; + std::vector count; + count.reserve( nb_parts ); + std::vector displs; + displs.reserve( nb_parts ); + std::vector b_count; + b_count.reserve( nb_bands() ); + std::vector b_displs; + b_displs.reserve( nb_bands() ); { int end = 0; - for( int band=0; band0?1:0); - displs.push_back(end); - count.push_back(w_size); + for ( int band = 0; band < nb_bands(); ++band ) { + b_displs.push_back( end ); + int b_size( 0 ); + for ( int p = 0; p < nb_regions( band ); ++p ) { + int w_size = chunk_size + ( remainder-- > 0 ? 1 : 0 ); + displs.push_back( end ); + count.push_back( w_size ); end += w_size; b_size += w_size; } - b_count.push_back(b_size); + b_count.push_back( b_size ); } } - int w(0); - for( int band=0; band -__EqualRegions ("equal_regions"); +atlas::grid::detail::partitioner::PartitionerBuilder + __EqualRegions( "equal_regions" ); } - - - - - - - diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h index e7040c301..ccb42bca1 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h @@ -4,12 +4,11 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - - // Purpose. // -------- // eq_regions provides the code to perform a high level @@ -20,40 +19,46 @@ // ----------- // This C++ implementation is ported from the MATLAB // "Recursive Zonal Equal Area (EQ) Sphere Partitioning Toolbox" of the -// same name developed by Paul Leopardi at the University of New South Wales. +// same name developed by Paul Leopardi at the University of New South +// Wales. // This version has been coded specifically for the case of partitioning the -// surface of a sphere or S^dim (where dim=2) as denoted in the original code. -// Only a subset of the original eq_regions package has been coded to determin +// surface of a sphere or S^dim (where dim=2) as denoted in the original +// code. +// Only a subset of the original eq_regions package has been coded to +// determin // the high level distribution of regions on a sphere, as the detailed // distribution of grid points to each region is left to implentatios. // -// The following copyright notice for the eq_regions package is included from +// The following copyright notice for the eq_regions package is included +// from // the original MatLab release. // // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -// + Release 1.10 2005-06-26 + -// + + -// + Copyright (c) 2004, 2005, University of New South Wales + -// + + -// + Permission is hereby granted, free of charge, to any person obtaining + -// + a copy of this software and associated documentation files (the + -// + "Software"), to deal in the Software without restriction, including + -// + without limitation the rights to use, copy, modify, merge, publish, + -// + distribute, sublicense, and/or sell copies of the Software, and to + -// + permit persons to whom the Software is furnished to do so, subject to + -// + the following conditions: + -// + + -// + The above copyright notice and this permission notice shall be included + -// + in all copies or substantial portions of the Software. + -// + + -// + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + -// + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + -// + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + -// + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + -// + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + -// + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + -// + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + -// + + +// + Release 1.10 2005-06-26 + +// + + +// + Copyright (c) 2004, 2005, University of New South Wales + +// + + +// + Permission is hereby granted, free of charge, to any person obtaining + +// + a copy of this software and associated documentation files (the + +// + "Software"), to deal in the Software without restriction, including + +// + without limitation the rights to use, copy, modify, merge, publish, + +// + distribute, sublicense, and/or sell copies of the Software, and to + +// + permit persons to whom the Software is furnished to do so, subject to + +// + the following conditions: + +// + + +// + The above copyright notice and this permission notice shall be included +// + +// + in all copies or substantial portions of the Software. + +// + + +// + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + +// + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + +// + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// + +// + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + +// + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + +// + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + +// + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// + + // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // @@ -62,38 +67,31 @@ #include #include "atlas/grid/detail/partitioner/Partitioner.h" - namespace atlas { namespace grid { namespace detail { namespace partitioner { -void eq_caps(int N, std::vector& n_regions, std::vector& s_cap); -void eq_regions(int N, double xmin[], double xmax[], double ymin[], double ymax[]); - -class EqualRegionsPartitioner: public Partitioner { +void eq_caps( int N, std::vector& n_regions, std::vector& s_cap ); +void eq_regions( int N, double xmin[], double xmax[], double ymin[], double ymax[] ); +class EqualRegionsPartitioner : public Partitioner { public: - EqualRegionsPartitioner(); - EqualRegionsPartitioner(int N); + EqualRegionsPartitioner( int N ); - void where(int partition, int& band, int& sector) const; - int nb_bands() const { - return bands_.size(); - } - int nb_regions(int band) const { - return sectors_[band]; - } + void where( int partition, int& band, int& sector ) const; + int nb_bands() const { return bands_.size(); } + int nb_regions( int band ) const { return sectors_[band]; } virtual void partition( const Grid&, int part[] ) const; virtual std::string type() const { return "equal_regions"; } public: - - // Node struct that holds the longitude and latitude in millidegrees (integers) + // Node struct that holds the longitude and latitude in millidegrees + // (integers) // This structure is used in sorting algorithms, and uses less memory than // if x and y were in double precision. struct NodeInt { @@ -102,28 +100,26 @@ class EqualRegionsPartitioner: public Partitioner { }; private: - // Doesn't matter if nodes[] is in degrees or radians, as a sorting // algorithm is used internally - void partition(int nb_nodes, NodeInt nodes[], int part[]) const; + void partition( int nb_nodes, NodeInt nodes[], int part[] ) const; // x and y in radians - int partition(const double& x, const double& y) const; + int partition( const double& x, const double& y ) const; // y in radians - int band(const double& y) const; + int band( const double& y ) const; // x in radians - int sector(int band, const double& x) const; + int sector( int band, const double& x ) const; private: - int N_; std::vector bands_; std::vector sectors_; }; -} // namespace partitioner -} // namespace detail -} // namespace grid -} // namespace atlas +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h index 4239c9c5b..08cc5027d 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h @@ -4,50 +4,37 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include "eckit/exception/Exceptions.h" #include "atlas/grid/detail/partitioner/Partitioner.h" +#include "eckit/exception/Exceptions.h" namespace atlas { namespace grid { namespace detail { namespace partitioner { - class MatchingMeshPartitioner : public Partitioner { public: + MatchingMeshPartitioner() : Partitioner() { NOTIMP; } - MatchingMeshPartitioner() : - Partitioner() { - NOTIMP; - } - - MatchingMeshPartitioner(const size_t nb_partitions) : - Partitioner(nb_partitions) { - NOTIMP; - } + MatchingMeshPartitioner( const size_t nb_partitions ) : Partitioner( nb_partitions ) { NOTIMP; } - MatchingMeshPartitioner(const Mesh& mesh) : - Partitioner(mesh.nb_partitions()), - prePartitionedMesh_(mesh) { - } + MatchingMeshPartitioner( const Mesh& mesh ) : Partitioner( mesh.nb_partitions() ), prePartitionedMesh_( mesh ) {} virtual ~MatchingMeshPartitioner() {} protected: - const Mesh prePartitionedMesh_; - }; - -} // partitioners -} // detail -} // grid -} // atlas +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc index 4db2aa981..16e1c2456 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc @@ -4,17 +4,14 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h" #include -#include "eckit/geometry/Point2.h" -#include "eckit/mpi/Comm.h" -#include "eckit/log/ProgressTimer.h" #include "atlas/array/ArrayView.h" #include "atlas/field/Field.h" #include "atlas/grid/Grid.h" @@ -23,161 +20,142 @@ #include "atlas/mesh/Nodes.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" +#include "eckit/geometry/Point2.h" +#include "eckit/log/ProgressTimer.h" +#include "eckit/mpi/Comm.h" namespace atlas { namespace grid { namespace detail { namespace partitioner { - namespace { +PartitionerBuilder __builder( "brute-force" ); -PartitionerBuilder __builder("brute-force"); - - -double dot_sign( - const double& Ax, const double& Ay, - const double& Bx, const double& By, - const double& Cx, const double& Cy ) { - return (Ax - Cx) * (By - Cy) - - (Bx - Cx) * (Ay - Cy); +double dot_sign( const double& Ax, const double& Ay, const double& Bx, const double& By, const double& Cx, + const double& Cy ) { + return ( Ax - Cx ) * ( By - Cy ) - ( Bx - Cx ) * ( Ay - Cy ); } - /// Point-in-triangle test /// @note "dot product" test, equivalent to half-plane check -/// @see http://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle -bool point_in_triangle( - const PointLonLat& P, - const PointLonLat& A, const PointLonLat& B, const PointLonLat& C ) { - +/// @see +/// http://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle +bool point_in_triangle( const PointLonLat& P, const PointLonLat& A, const PointLonLat& B, const PointLonLat& C ) { // Compute signs of dot products - const bool - b1 = dot_sign(P.lon(), P.lat(), A.lon(), A.lat(), B.lon(), B.lat()) < 0, - b2 = dot_sign(P.lon(), P.lat(), B.lon(), B.lat(), C.lon(), C.lat()) < 0, - b3 = dot_sign(P.lon(), P.lat(), C.lon(), C.lat(), A.lon(), A.lat()) < 0; + const bool b1 = dot_sign( P.lon(), P.lat(), A.lon(), A.lat(), B.lon(), B.lat() ) < 0, + b2 = dot_sign( P.lon(), P.lat(), B.lon(), B.lat(), C.lon(), C.lat() ) < 0, + b3 = dot_sign( P.lon(), P.lat(), C.lon(), C.lat(), A.lon(), A.lat() ) < 0; // Check if point is in triangle - // - check for b1 && b2 && b3 only works for triangles ordered counter-clockwise - // - check for b1==b2 && b2==b3 works for both, equivalent to "all points on the same side" - return (b1 == b2) && (b2 == b3); + // - check for b1 && b2 && b3 only works for triangles ordered + // counter-clockwise + // - check for b1==b2 && b2==b3 works for both, equivalent to "all points on + // the same side" + return ( b1 == b2 ) && ( b2 == b3 ); } - /// Point-in-quadrilateral test -/// @note limited to convex quadrilaterals, @see https://en.wikipedia.org/wiki/Convex_polygon -bool point_in_quadrilateral ( - const PointLonLat& P, - const PointLonLat& A, const PointLonLat& B, const PointLonLat& C, const PointLonLat& D ) { - const bool - b1 = dot_sign(P.lon(), P.lat(), A.lon(), A.lat(), B.lon(), B.lat()) < 0, - b2 = dot_sign(P.lon(), P.lat(), B.lon(), B.lat(), C.lon(), C.lat()) < 0, - b3 = dot_sign(P.lon(), P.lat(), C.lon(), C.lat(), D.lon(), D.lat()) < 0, - b4 = dot_sign(P.lon(), P.lat(), D.lon(), D.lat(), A.lon(), A.lat()) < 0; - return (b1 == b2) && (b2 == b3) && (b3 == b4); +/// @note limited to convex quadrilaterals, @see +/// https://en.wikipedia.org/wiki/Convex_polygon +bool point_in_quadrilateral( const PointLonLat& P, const PointLonLat& A, const PointLonLat& B, const PointLonLat& C, + const PointLonLat& D ) { + const bool b1 = dot_sign( P.lon(), P.lat(), A.lon(), A.lat(), B.lon(), B.lat() ) < 0, + b2 = dot_sign( P.lon(), P.lat(), B.lon(), B.lat(), C.lon(), C.lat() ) < 0, + b3 = dot_sign( P.lon(), P.lat(), C.lon(), C.lat(), D.lon(), D.lat() ) < 0, + b4 = dot_sign( P.lon(), P.lat(), D.lon(), D.lat(), A.lon(), A.lat() ) < 0; + return ( b1 == b2 ) && ( b2 == b3 ) && ( b3 == b4 ); } - -} // (anonymous namespace) - - -void MatchingMeshPartitionerBruteForce::partition(const Grid& grid, int partitioning[]) const { - eckit::mpi::Comm& comm = eckit::mpi::comm(); - const int mpi_rank = int(comm.rank()); - - // Point coordinates - // - use a bounding box to quickly discard points, - // - except when that is above/below bounding box but poles should be included - // FIXME: THIS IS A HACK! the coordinates include North/South Pole (first/last partitions only) - - ASSERT( grid.domain().global() ); - bool includesNorthPole = (mpi_rank == 0); - bool includesSouthPole = (mpi_rank == (int(comm.size()) - 1 )); - - ASSERT(prePartitionedMesh_.nodes().size()); - auto lonlat_src = array::make_view< double, 2 >(prePartitionedMesh_.nodes().lonlat()); - - std::vector< PointLonLat > coordinates; - PointLonLat coordinatesMin = PointLonLat(lonlat_src(0, LON), lonlat_src(0, LAT)); - PointLonLat coordinatesMax = coordinatesMin; - - for (size_t i = 0; i < lonlat_src.size(); ++i) { - PointLonLat A(lonlat_src(i, LON), lonlat_src(i, LAT)); - coordinatesMin = PointLonLat::componentsMin(coordinatesMin, A); - coordinatesMax = PointLonLat::componentsMax(coordinatesMax, A); - coordinates.push_back(A); - } - - { - eckit::ProgressTimer timer("Partitioning target", grid.size(), "point", - double(10), atlas::Log::info()); - for (size_t i=0; i( conn(j,0) ); - idx[1] = static_cast( conn(j,1) ); - idx[2] = static_cast( conn(j,2) ); - idx[3] = nb_nodes > 3? static_cast( conn(j,3) ) : 0; - - if ((elements.name() == "Triangle" && point_in_triangle(P, - coordinates[idx[0]], - coordinates[idx[1]], - coordinates[idx[2]] )) - || (elements.name() == "Quadrilateral" && point_in_quadrilateral(P, - coordinates[idx[0]], - coordinates[idx[1]], - coordinates[idx[2]], - coordinates[idx[3]] )) ) { - - partitioning[i] = mpi_rank; - found = true; - - } - } - - } - } else if ((includesNorthPole && P[LAT] > coordinatesMax[LAT]) - || (includesSouthPole && P[LAT] < coordinatesMin[LAT])) { - - partitioning[i] = mpi_rank; - - } - } - } - - - // Synchronize the partitioning and return a grid partitioner - comm.allReduceInPlace(partitioning, grid.size(), eckit::mpi::Operation::MAX); - const int min = *std::min_element(partitioning, partitioning+grid.size()); - if (min<0) { - throw eckit::SeriousBug("Could not find partition for target node (source mesh does not contain all target grid points)", Here()); - } - +} // namespace + +void MatchingMeshPartitionerBruteForce::partition( const Grid& grid, int partitioning[] ) const { + eckit::mpi::Comm& comm = eckit::mpi::comm(); + const int mpi_rank = int( comm.rank() ); + + // Point coordinates + // - use a bounding box to quickly discard points, + // - except when that is above/below bounding box but poles should be included + // FIXME: THIS IS A HACK! the coordinates include North/South Pole + // (first/last partitions only) + + ASSERT( grid.domain().global() ); + bool includesNorthPole = ( mpi_rank == 0 ); + bool includesSouthPole = ( mpi_rank == ( int( comm.size() ) - 1 ) ); + + ASSERT( prePartitionedMesh_.nodes().size() ); + auto lonlat_src = array::make_view( prePartitionedMesh_.nodes().lonlat() ); + + std::vector coordinates; + PointLonLat coordinatesMin = PointLonLat( lonlat_src( 0, LON ), lonlat_src( 0, LAT ) ); + PointLonLat coordinatesMax = coordinatesMin; + + for ( size_t i = 0; i < lonlat_src.size(); ++i ) { + PointLonLat A( lonlat_src( i, LON ), lonlat_src( i, LAT ) ); + coordinatesMin = PointLonLat::componentsMin( coordinatesMin, A ); + coordinatesMax = PointLonLat::componentsMax( coordinatesMax, A ); + coordinates.push_back( A ); + } + + { + eckit::ProgressTimer timer( "Partitioning target", grid.size(), "point", double( 10 ), atlas::Log::info() ); + for ( size_t i = 0; i < grid.size(); ++i, ++timer ) { + partitioning[i] = -1; + const PointLonLat& P( coordinates[i] ); + + if ( coordinatesMin[LON] <= P[LON] && P[LON] <= coordinatesMax[LON] && coordinatesMin[LAT] <= P[LAT] && + P[LAT] <= coordinatesMax[LAT] ) { + const mesh::Cells& elements_src = prePartitionedMesh_.cells(); + const size_t nb_types = elements_src.nb_types(); + bool found = false; + + for ( size_t t = 0; t < nb_types && !found; ++t ) { + size_t idx[4]; + const mesh::Elements& elements = elements_src.elements( t ); + const mesh::BlockConnectivity& conn = elements.node_connectivity(); + + const size_t nb_nodes = elements.nb_nodes(); + ASSERT( ( nb_nodes == 3 && elements.name() == "Triangle" ) || + ( nb_nodes == 4 && elements.name() == "Quadrilateral" ) ); + + for ( size_t j = 0; j < elements.size() && !found; ++j ) { + idx[0] = static_cast( conn( j, 0 ) ); + idx[1] = static_cast( conn( j, 1 ) ); + idx[2] = static_cast( conn( j, 2 ) ); + idx[3] = nb_nodes > 3 ? static_cast( conn( j, 3 ) ) : 0; + + if ( ( elements.name() == "Triangle" && + point_in_triangle( P, coordinates[idx[0]], coordinates[idx[1]], + coordinates[idx[2]] ) ) || + ( elements.name() == "Quadrilateral" && + point_in_quadrilateral( P, coordinates[idx[0]], coordinates[idx[1]], coordinates[idx[2]], + coordinates[idx[3]] ) ) ) { + partitioning[i] = mpi_rank; + found = true; + } + } + } + } + else if ( ( includesNorthPole && P[LAT] > coordinatesMax[LAT] ) || + ( includesSouthPole && P[LAT] < coordinatesMin[LAT] ) ) { + partitioning[i] = mpi_rank; + } + } + } + + // Synchronize the partitioning and return a grid partitioner + comm.allReduceInPlace( partitioning, grid.size(), eckit::mpi::Operation::MAX ); + const int min = *std::min_element( partitioning, partitioning + grid.size() ); + if ( min < 0 ) { + throw eckit::SeriousBug( + "Could not find partition for target node (source " + "mesh does not contain all target grid points)", + Here() ); + } } - -} // partitioner -} // detail -} // grid -} // atlas - +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h index 15a3aedd7..0e7b3b40a 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -17,27 +18,21 @@ namespace grid { namespace detail { namespace partitioner { - class MatchingMeshPartitionerBruteForce : public MatchingMeshPartitioner { - public: - - static std::string static_type() {return "brute-force";} + static std::string static_type() { return "brute-force"; } public: - MatchingMeshPartitionerBruteForce() : MatchingMeshPartitioner() {} - MatchingMeshPartitionerBruteForce(const size_t nb_partitions) : MatchingMeshPartitioner(nb_partitions) {} - MatchingMeshPartitionerBruteForce(const Mesh& mesh) : MatchingMeshPartitioner(mesh) {} + MatchingMeshPartitionerBruteForce( const size_t nb_partitions ) : MatchingMeshPartitioner( nb_partitions ) {} + MatchingMeshPartitionerBruteForce( const Mesh& mesh ) : MatchingMeshPartitioner( mesh ) {} - virtual void partition(const Grid& grid, int partitioning[]) const; - - virtual std::string type() const { return static_type(); } + virtual void partition( const Grid& grid, int partitioning[] ) const; + virtual std::string type() const { return static_type(); } }; - -} // partitioner -} // detail -} // grid -} // atlas +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc index e4759383f..1207f4b4b 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc @@ -4,77 +4,73 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h" #include -#include "eckit/config/Resource.h" -#include "eckit/log/ProgressTimer.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Nodes.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/util/LonLatPolygon.h" +#include "eckit/config/Resource.h" +#include "eckit/log/ProgressTimer.h" namespace atlas { namespace grid { namespace detail { namespace partitioner { - namespace { -PartitionerBuilder __builder("lonlat-polygon"); +PartitionerBuilder __builder( "lonlat-polygon" ); } - void MatchingMeshPartitionerLonLatPolygon::partition( const Grid& grid, int partitioning[] ) const { const eckit::mpi::Comm& comm = atlas::mpi::comm(); - const int mpi_rank = int(comm.rank()); - const int mpi_size = int(comm.size()); + const int mpi_rank = int( comm.rank() ); + const int mpi_size = int( comm.size() ); ASSERT( grid.domain().global() ); Log::debug() << "MatchingMeshPartitionerLonLatPolygon::partition" << std::endl; - // FIXME: THIS IS A HACK! the coordinates include North/South Pole (first/last partitions only) - bool includesNorthPole = (mpi_rank == 0); - bool includesSouthPole = (mpi_rank == mpi_size - 1); + // FIXME: THIS IS A HACK! the coordinates include North/South Pole (first/last + // partitions only) + bool includesNorthPole = ( mpi_rank == 0 ); + bool includesSouthPole = ( mpi_rank == mpi_size - 1 ); - const util::LonLatPolygon poly( - prePartitionedMesh_.polygon(0), - prePartitionedMesh_.nodes().lonlat() ); + const util::LonLatPolygon poly( prePartitionedMesh_.polygon( 0 ), prePartitionedMesh_.nodes().lonlat() ); { - eckit::ProgressTimer timer("Partitioning", grid.size(), "point", - double(10), atlas::Log::info()); + eckit::ProgressTimer timer( "Partitioning", grid.size(), "point", double( 10 ), atlas::Log::info() ); size_t i = 0; - for (const PointXY Pxy : grid.xy()) { + for ( const PointXY Pxy : grid.xy() ) { ++timer; - const PointLonLat P = grid.projection().lonlat(Pxy); - const bool atThePole = - (includesNorthPole && P.lat() >= poly.coordinatesMax().lat()) || - (includesSouthPole && P.lat() < poly.coordinatesMin().lat()); + const PointLonLat P = grid.projection().lonlat( Pxy ); + const bool atThePole = ( includesNorthPole && P.lat() >= poly.coordinatesMax().lat() ) || + ( includesSouthPole && P.lat() < poly.coordinatesMin().lat() ); - partitioning[i++] = atThePole || poly.contains(P) ? mpi_rank : -1; + partitioning[i++] = atThePole || poly.contains( P ) ? mpi_rank : -1; } } // Synchronize partitioning, do a sanity check - comm.allReduceInPlace(partitioning, grid.size(), eckit::mpi::Operation::MAX); - const int min = *std::min_element(partitioning, partitioning+grid.size()); - if (min<0) { - throw eckit::SeriousBug("Could not find partition for target node (source mesh does not contain all target grid points)", Here()); + comm.allReduceInPlace( partitioning, grid.size(), eckit::mpi::Operation::MAX ); + const int min = *std::min_element( partitioning, partitioning + grid.size() ); + if ( min < 0 ) { + throw eckit::SeriousBug( + "Could not find partition for target node (source " + "mesh does not contain all target grid points)", + Here() ); } } - -} // partitioner -} // detail -} // grid -} // atlas - +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h index 8d668282d..4fa24dcba 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h @@ -4,11 +4,11 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #pragma once #include "atlas/grid/detail/partitioner/MatchingMeshPartitioner.h" @@ -18,33 +18,29 @@ namespace grid { namespace detail { namespace partitioner { - class MatchingMeshPartitionerLonLatPolygon : public MatchingMeshPartitioner { - public: - - static std::string static_type() {return "lonlat-polygon";} + static std::string static_type() { return "lonlat-polygon"; } public: - MatchingMeshPartitionerLonLatPolygon() : MatchingMeshPartitioner() {} - MatchingMeshPartitionerLonLatPolygon(const size_t nb_partitions) : MatchingMeshPartitioner(nb_partitions) {} - MatchingMeshPartitionerLonLatPolygon(const Mesh& mesh) : MatchingMeshPartitioner(mesh) {} + MatchingMeshPartitionerLonLatPolygon( const size_t nb_partitions ) : MatchingMeshPartitioner( nb_partitions ) {} + MatchingMeshPartitionerLonLatPolygon( const Mesh& mesh ) : MatchingMeshPartitioner( mesh ) {} /** - * @brief Partition a grid, using the same partitions from a pre-partitioned mesh. - * The method constructs a partition edges polygon to test every target grid node with. - * @param[in] grid grid to be partitioned - * @param[out] partitioning partitioning result - */ - void partition(const Grid& grid, int partitioning[]) const; + * @brief Partition a grid, using the same partitions from a pre-partitioned + * mesh. + * The method constructs a partition edges polygon to test every target grid + * node with. + * @param[in] grid grid to be partitioned + * @param[out] partitioning partitioning result + */ + void partition( const Grid& grid, int partitioning[] ) const; virtual std::string type() const { return static_type(); } - }; - -} // partitioner -} // detail -} // grid -} // atlas +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc index 6a26e3123..6d2a7ba2e 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc @@ -4,76 +4,72 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h" #include -#include "eckit/log/ProgressTimer.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Nodes.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/util/SphericalPolygon.h" +#include "eckit/log/ProgressTimer.h" namespace atlas { namespace grid { namespace detail { namespace partitioner { - namespace { -PartitionerBuilder __builder("spherical-polygon"); +PartitionerBuilder __builder( "spherical-polygon" ); } - void MatchingMeshPartitionerSphericalPolygon::partition( const Grid& grid, int partitioning[] ) const { const eckit::mpi::Comm& comm = atlas::mpi::comm(); - const int mpi_rank = int(comm.rank()); - const int mpi_size = int(comm.size()); + const int mpi_rank = int( comm.rank() ); + const int mpi_size = int( comm.size() ); ASSERT( grid.domain().global() ); Log::debug() << "MatchingMeshPartitionerSphericalPolygon::partition" << std::endl; - // FIXME: THIS IS A HACK! the coordinates include North/South Pole (first/last partitions only) - bool includesNorthPole = (mpi_rank == 0); - bool includesSouthPole = (mpi_rank == mpi_size - 1); + // FIXME: THIS IS A HACK! the coordinates include North/South Pole (first/last + // partitions only) + bool includesNorthPole = ( mpi_rank == 0 ); + bool includesSouthPole = ( mpi_rank == mpi_size - 1 ); - const util::SphericalPolygon poly( - prePartitionedMesh_.polygon(0), - prePartitionedMesh_.nodes().lonlat() ); + const util::SphericalPolygon poly( prePartitionedMesh_.polygon( 0 ), prePartitionedMesh_.nodes().lonlat() ); { - eckit::ProgressTimer timer("Partitioning", grid.size(), "point", - double(10), atlas::Log::info()); + eckit::ProgressTimer timer( "Partitioning", grid.size(), "point", double( 10 ), atlas::Log::info() ); size_t i = 0; - for (const PointXY Pxy : grid.xy()) { + for ( const PointXY Pxy : grid.xy() ) { ++timer; - const PointLonLat P = grid.projection().lonlat(Pxy); - const bool atThePole = - (includesNorthPole && P.lat() >= poly.coordinatesMax().lat()) || - (includesSouthPole && P.lat() < poly.coordinatesMin().lat()); + const PointLonLat P = grid.projection().lonlat( Pxy ); + const bool atThePole = ( includesNorthPole && P.lat() >= poly.coordinatesMax().lat() ) || + ( includesSouthPole && P.lat() < poly.coordinatesMin().lat() ); - partitioning[i++] = atThePole || poly.contains(P) ? mpi_rank : -1; + partitioning[i++] = atThePole || poly.contains( P ) ? mpi_rank : -1; } } // Synchronize partitioning, do a sanity check - comm.allReduceInPlace(partitioning, grid.size(), eckit::mpi::Operation::MAX); - const int min = *std::min_element(partitioning, partitioning+grid.size()); - if (min<0) { - throw eckit::SeriousBug("Could not find partition for target node (source mesh does not contain all target grid points)", Here()); + comm.allReduceInPlace( partitioning, grid.size(), eckit::mpi::Operation::MAX ); + const int min = *std::min_element( partitioning, partitioning + grid.size() ); + if ( min < 0 ) { + throw eckit::SeriousBug( + "Could not find partition for target node (source " + "mesh does not contain all target grid points)", + Here() ); } } - -} // partitioner -} // detail -} // grid -} // atlas - +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h index a997ea0cd..cbfc9edde 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h @@ -4,11 +4,11 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #pragma once #include "atlas/grid/detail/partitioner/MatchingMeshPartitioner.h" @@ -18,33 +18,29 @@ namespace grid { namespace detail { namespace partitioner { - class MatchingMeshPartitionerSphericalPolygon : public MatchingMeshPartitioner { - public: - - static std::string static_type() {return "spherical-polygon";} + static std::string static_type() { return "spherical-polygon"; } public: - MatchingMeshPartitionerSphericalPolygon() : MatchingMeshPartitioner() {} - MatchingMeshPartitionerSphericalPolygon(const size_t nb_partitions) : MatchingMeshPartitioner(nb_partitions) {} - MatchingMeshPartitionerSphericalPolygon(const Mesh& mesh) : MatchingMeshPartitioner(mesh) {} + MatchingMeshPartitionerSphericalPolygon( const size_t nb_partitions ) : MatchingMeshPartitioner( nb_partitions ) {} + MatchingMeshPartitionerSphericalPolygon( const Mesh& mesh ) : MatchingMeshPartitioner( mesh ) {} /** - * @brief Partition a grid, using the same partitions from a pre-partitioned mesh. - * The method constructs a partition edges polygon to test every target grid node with. - * @param[in] grid grid to be partitioned - * @param[out] partitioning partitioning result - */ - void partition(const Grid& grid, int partitioning[]) const; + * @brief Partition a grid, using the same partitions from a pre-partitioned + * mesh. + * The method constructs a partition edges polygon to test every target grid + * node with. + * @param[in] grid grid to be partitioned + * @param[out] partitioning partitioning result + */ + void partition( const Grid& grid, int partitioning[] ) const; virtual std::string type() const { return static_type(); } - }; - -} // partitioner -} // detail -} // grid -} // atlas +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/Partitioner.cc b/src/atlas/grid/detail/partitioner/Partitioner.cc index 5b0f9bfb8..682bc603d 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.cc +++ b/src/atlas/grid/detail/partitioner/Partitioner.cc @@ -4,197 +4,181 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - +#include "atlas/grid/detail/partitioner/Partitioner.h" #include #include -#include "eckit/thread/AutoLock.h" -#include "eckit/thread/Mutex.h" -#include "atlas/grid/detail/partitioner/Partitioner.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" -#include "atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitioner.h" -#include "atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h" +#include "atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h" +#include "atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h" +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" #ifdef ATLAS_HAVE_TRANS #include "atlas/grid/detail/partitioner/TransPartitioner.h" #endif #include "atlas/grid/Distribution.h" #include "atlas/grid/Partitioner.h" #include "atlas/library/config.h" -#include "atlas/library/config.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" - namespace { -static eckit::Mutex *local_mutex = 0; -static std::map *m = 0; -static pthread_once_t once = PTHREAD_ONCE_INIT; +static eckit::Mutex* local_mutex = 0; +static std::map* m = 0; +static pthread_once_t once = PTHREAD_ONCE_INIT; static void init() { local_mutex = new eckit::Mutex(); - m = new std::map(); -} + m = new std::map(); } +} // namespace namespace atlas { namespace grid { namespace detail { namespace partitioner { -Partitioner::Partitioner(): nb_partitions_(mpi::comm().size()) { -} +Partitioner::Partitioner() : nb_partitions_( mpi::comm().size() ) {} -Partitioner::Partitioner(const size_t nb_partitions): nb_partitions_(nb_partitions) { -} +Partitioner::Partitioner( const size_t nb_partitions ) : nb_partitions_( nb_partitions ) {} -Partitioner::~Partitioner() { -} +Partitioner::~Partitioner() {} size_t Partitioner::nb_partitions() const { return nb_partitions_; } -Distribution Partitioner::partition(const Grid& grid) const { - return Distribution( grid, atlas::grid::Partitioner(this) ); +Distribution Partitioner::partition( const Grid& grid ) const { + return Distribution( grid, atlas::grid::Partitioner( this ) ); } - namespace { -template void load_builder() { - PartitionerBuilder("tmp"); +template +void load_builder() { + PartitionerBuilder( "tmp" ); } struct force_link { force_link() { - load_builder< EqualRegionsPartitioner >(); + load_builder(); #ifdef ATLAS_HAVE_TRANS - load_builder< TransPartitioner >(); + load_builder(); #endif } }; -} - +} // namespace +PartitionerFactory::PartitionerFactory( const std::string& name ) : name_( name ) { + pthread_once( &once, init ); -PartitionerFactory::PartitionerFactory(const std::string &name): - name_(name) { + eckit::AutoLock lock( local_mutex ); - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); - - ASSERT(m->find(name) == m->end()); - (*m)[name] = this; + ASSERT( m->find( name ) == m->end() ); + ( *m )[name] = this; } - PartitionerFactory::~PartitionerFactory() { - eckit::AutoLock lock(local_mutex); - m->erase(name_); + eckit::AutoLock lock( local_mutex ); + m->erase( name_ ); } +void PartitionerFactory::list( std::ostream& out ) { + pthread_once( &once, init ); -void PartitionerFactory::list(std::ostream& out) { - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; const char* sep = ""; - for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { - out << sep << (*j).first; + for ( std::map::const_iterator j = m->begin(); j != m->end(); ++j ) { + out << sep << ( *j ).first; sep = ", "; } } -bool PartitionerFactory::has(const std::string& name) { - pthread_once(&once, init); +bool PartitionerFactory::has( const std::string& name ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - return ( m->find(name) != m->end() ); + return ( m->find( name ) != m->end() ); } +Partitioner* PartitionerFactory::build( const std::string& name ) { + pthread_once( &once, init ); - -Partitioner* PartitionerFactory::build(const std::string& name) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::map::const_iterator j = m->find(name); + std::map::const_iterator j = m->find( name ); Log::debug() << "Looking for PartitionerFactory [" << name << "]" << '\n'; - if (j == m->end()) { + if ( j == m->end() ) { Log::error() << "No PartitionerFactory for [" << name << "]" << '\n'; Log::error() << "PartitionerFactories are:" << '\n'; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << '\n'; - throw eckit::SeriousBug(std::string("No PartitionerFactory called ") + name); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << '\n'; + throw eckit::SeriousBug( std::string( "No PartitionerFactory called " ) + name ); } - return (*j).second->make(); + return ( *j ).second->make(); } -Partitioner* PartitionerFactory::build(const std::string& name, const size_t nb_partitions ) { - - pthread_once(&once, init); +Partitioner* PartitionerFactory::build( const std::string& name, const size_t nb_partitions ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::map::const_iterator j = m->find(name); + std::map::const_iterator j = m->find( name ); Log::debug() << "Looking for PartitionerFactory [" << name << "]" << '\n'; - if (j == m->end()) { + if ( j == m->end() ) { Log::error() << "No PartitionerFactory for [" << name << "]" << '\n'; Log::error() << "PartitionerFactories are:" << '\n'; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << '\n'; - throw eckit::SeriousBug(std::string("No PartitionerFactory called ") + name); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << '\n'; + throw eckit::SeriousBug( std::string( "No PartitionerFactory called " ) + name ); } - return (*j).second->make(nb_partitions); + return ( *j ).second->make( nb_partitions ); } -} // namespace partitioner -} // namespace detail +} // namespace partitioner +} // namespace detail -grid::detail::partitioner::Partitioner* MatchedPartitionerFactory::build( - const std::string& type, - const Mesh& partitioned ) { +grid::detail::partitioner::Partitioner* MatchedPartitionerFactory::build( const std::string& type, + const Mesh& partitioned ) { using namespace grid::detail::partitioner; - if( type == MatchingMeshPartitionerSphericalPolygon::static_type() ) { - return new MatchingMeshPartitionerSphericalPolygon(partitioned); - } else if( type == MatchingMeshPartitionerLonLatPolygon::static_type() ) { - return new MatchingMeshPartitionerLonLatPolygon(partitioned); - } else if ( type == MatchingMeshPartitionerBruteForce::static_type() ) { - return new MatchingMeshPartitionerBruteForce(partitioned); - } else { + if ( type == MatchingMeshPartitionerSphericalPolygon::static_type() ) { + return new MatchingMeshPartitionerSphericalPolygon( partitioned ); + } + else if ( type == MatchingMeshPartitionerLonLatPolygon::static_type() ) { + return new MatchingMeshPartitionerLonLatPolygon( partitioned ); + } + else if ( type == MatchingMeshPartitionerBruteForce::static_type() ) { + return new MatchingMeshPartitionerBruteForce( partitioned ); + } + else { NOTIMP; } } - -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/Partitioner.h b/src/atlas/grid/detail/partitioner/Partitioner.h index 9837d07a2..f088c3d06 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.h +++ b/src/atlas/grid/detail/partitioner/Partitioner.h @@ -4,17 +4,17 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #pragma once -#include "eckit/memory/Owned.h" #include "atlas/grid/Distribution.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" +#include "eckit/memory/Owned.h" namespace atlas { namespace grid { @@ -22,98 +22,79 @@ namespace detail { namespace partitioner { class Partitioner : public eckit::Owned { - public: - - using Grid = atlas::Grid; + using Grid = atlas::Grid; public: - Partitioner(); - Partitioner(const size_t nb_partitions); + Partitioner( const size_t nb_partitions ); virtual ~Partitioner(); - virtual void partition(const Grid& grid, int part[] ) const = 0; + virtual void partition( const Grid& grid, int part[] ) const = 0; - Distribution partition(const Grid& grid) const; + Distribution partition( const Grid& grid ) const; size_t nb_partitions() const; - + virtual std::string type() const = 0; private: - size_t nb_partitions_; }; - // ------------------------------------------------------------------ class PartitionerFactory { - public: - - using Grid = Partitioner::Grid; + using Grid = Partitioner::Grid; public: - /*! - * \brief build Partitioner with factory key, constructor arguments - * \return Partitioner - */ - static Partitioner* build(const std::string&); - static Partitioner* build(const std::string&, const size_t nb_partitions); + * \brief build Partitioner with factory key, constructor arguments + * \return Partitioner + */ + static Partitioner* build( const std::string& ); + static Partitioner* build( const std::string&, const size_t nb_partitions ); /*! - * \brief list all registered partioner builders - */ - static void list(std::ostream &); - static bool has(const std::string& name); + * \brief list all registered partioner builders + */ + static void list( std::ostream& ); + static bool has( const std::string& name ); private: - std::string name_; - virtual Partitioner* make() = 0 ; - virtual Partitioner* make(const size_t nb_partitions) = 0 ; + virtual Partitioner* make() = 0; + virtual Partitioner* make( const size_t nb_partitions ) = 0; protected: - - PartitionerFactory(const std::string&); + PartitionerFactory( const std::string& ); virtual ~PartitionerFactory(); }; // ------------------------------------------------------------------ -template +template class PartitionerBuilder : public PartitionerFactory { + virtual Partitioner* make() { return new T(); } - virtual Partitioner* make() { - return new T(); - } - - virtual Partitioner* make(const size_t nb_partitions) { - return new T(nb_partitions); - } + virtual Partitioner* make( const size_t nb_partitions ) { return new T( nb_partitions ); } public: - - PartitionerBuilder(const std::string& name) : PartitionerFactory(name) {} + PartitionerBuilder( const std::string& name ) : PartitionerFactory( name ) {} }; // ------------------------------------------------------------------ -} // namespace partitioner -} // namespace detail +} // namespace partitioner +} // namespace detail class MatchedPartitionerFactory { public: - - static grid::detail::partitioner::Partitioner* build( - const std::string& type, - const Mesh& partitioned ); + static grid::detail::partitioner::Partitioner* build( const std::string& type, const Mesh& partitioned ); }; // ------------------------------------------------------------------ -} // namespace grid -} // namespace atlas +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index 1960dd9c4..41606ae35 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -8,91 +8,88 @@ * nor does it submit to any jurisdiction. */ -#include "eckit/exception/Exceptions.h" -#include "atlas/grid/Grid.h" #include "atlas/grid/detail/partitioner/TransPartitioner.h" +#include "atlas/array.h" +#include "atlas/grid/Grid.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" -#include "atlas/trans/ifs/TransIFS.h" #include "atlas/parallel/mpi/mpi.h" -#include "atlas/array.h" #include "atlas/runtime/Trace.h" +#include "atlas/trans/ifs/TransIFS.h" +#include "eckit/exception/Exceptions.h" namespace atlas { namespace grid { namespace detail { namespace partitioner { -TransPartitioner::TransPartitioner() : - Partitioner() { - EqualRegionsPartitioner eqreg(nb_partitions()); +TransPartitioner::TransPartitioner() : Partitioner() { + EqualRegionsPartitioner eqreg( nb_partitions() ); nbands_ = eqreg.nb_bands(); - nregions_.resize(nbands_); - for( size_t b=0; b nloen = t.nloen(); - array::LocalView n_regions = t.n_regions(); - array::LocalView nfrstlat = t.nfrstlat(); - array::LocalView nlstlat = t.nlstlat(); - array::LocalView nptrfrstlat = t.nptrfrstlat(); - array::LocalView nsta = t.nsta(); - array::LocalView nonl = t.nonl(); - + array::LocalView nloen = t.nloen(); + array::LocalView n_regions = t.n_regions(); + array::LocalView nfrstlat = t.nfrstlat(); + array::LocalView nlstlat = t.nlstlat(); + array::LocalView nptrfrstlat = t.nptrfrstlat(); + array::LocalView nsta = t.nsta(); + array::LocalView nonl = t.nonl(); - int i(0); - int maxind(0); - std::vector iglobal(t.ndgl()*nlonmax,-1); + int i( 0 ); + int maxind( 0 ); + std::vector iglobal( t.ndgl() * nlonmax, -1 ); - for( int jgl=0; jgl= grid.size() ) throw eckit::OutOfRange(ind,grid.size(),Here()); + int iproc( 0 ); + for ( int ja = 0; ja < t.n_regions_NS(); ++ja ) { + for ( int jb = 0; jb < n_regions( ja ); ++jb ) { + for ( int jgl = nfrstlat( ja ) - 1; jgl < nlstlat( ja ); ++jgl ) { + int igl = nptrfrstlat( ja ) + jgl - nfrstlat( ja ); + for ( int jl = nsta( jb, igl ) - 1; jl < nsta( jb, igl ) + nonl( jb, igl ) - 1; ++jl ) { + size_t ind = iglobal[jgl * nlonmax + jl] - 1; + if ( ind >= grid.size() ) throw eckit::OutOfRange( ind, grid.size(), Here() ); part[ind] = iproc; } } @@ -105,17 +102,16 @@ int TransPartitioner::nb_bands() const { return nbands_; } -int TransPartitioner::nb_regions(int b) const { +int TransPartitioner::nb_regions( int b ) const { return nregions_[b]; } -} // namespace partitioner -} // namespace detail -} // namespace grid -} // namespace atlas +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas namespace { -atlas::grid::detail::partitioner::PartitionerBuilder< -atlas::grid::detail::partitioner::TransPartitioner> __Trans("trans"); +atlas::grid::detail::partitioner::PartitionerBuilder __Trans( + "trans" ); } - diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.h b/src/atlas/grid/detail/partitioner/TransPartitioner.h index f91c65c89..7a6e547b8 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.h +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -18,40 +19,39 @@ namespace detail { namespace partitioner { /// @class TransPartitioner -/// @brief Equal regions partitioning algorithm computed by the IFS trans library +/// @brief Equal regions partitioning algorithm computed by the IFS trans +/// library /// /// The user is advised to use the "EqualRegionsPartitioner" class instead. This /// implementation is only here to to guarantee the exact same distribution /// as IFS is using. The difference with "EqualRegionsPartitioner" is minimal. /// (a few points may be assigned to different partitions). -class TransPartitioner: public Partitioner { - +class TransPartitioner : public Partitioner { public: - /// @brief Constructor TransPartitioner(); - TransPartitioner(const size_t nb_partitions ); + TransPartitioner( const size_t nb_partitions ); virtual ~TransPartitioner(); - /// Warning: this function temporariliy allocates a new Trans, but without the computations + /// Warning: this function temporariliy allocates a new Trans, but without the + /// computations /// of the spectral coefficients (LDGRIDONLY=TRUE) - virtual void partition(const Grid&, int part[]) const; + virtual void partition( const Grid&, int part[] ) const; int nb_bands() const; - int nb_regions(int b) const; - + int nb_regions( int b ) const; + virtual std::string type() const { return "trans"; } private: - size_t nbands_; std::vector nregions_; }; -} // namespace partitioner -} // namespace detail -} // namespace grid -} // namespace atlas +} // namespace partitioner +} // namespace detail +} // namespace grid +} // namespace atlas diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N.cc b/src/atlas/grid/detail/pl/classic_gaussian/N.cc index 05525c01c..70f986504 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N.cc @@ -4,47 +4,41 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @author Willem Deconinck /// @date Mar 2016 - #include "N.h" - namespace atlas { namespace grid { namespace detail { namespace pl { namespace classic_gaussian { - std::string PointsPerLatitude::className() { return "atlas.grid.reduced.pl.classic_gaussian.PointsPerLatitude"; } - -void PointsPerLatitude::assign(long nlon[], const size_t size) const { +void PointsPerLatitude::assign( long nlon[], const size_t size ) const { 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 { +void PointsPerLatitude::assign( std::vector& nlon ) const { nlon = nlon_; } - -template +template void load() { - eckit::ConcreteBuilderT0 builder("tmp"); + eckit::ConcreteBuilderT0 builder( "tmp" ); } - void regist() { load(); load(); @@ -71,10 +65,8 @@ void regist() { load(); } - } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N.h b/src/atlas/grid/detail/pl/classic_gaussian/N.h index 0cfbd4996..b0fd0d676 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N.h +++ b/src/atlas/grid/detail/pl/classic_gaussian/N.h @@ -4,94 +4,86 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @author Willem Deconinck /// @date Mar 2016 - #pragma once #include "eckit/memory/Builder.h" #include "eckit/memory/Owned.h" - namespace atlas { namespace grid { namespace detail { namespace pl { namespace classic_gaussian { - class PointsPerLatitude : public eckit::Owned { - - public: - +public: typedef eckit::BuilderT0 builder_t; static std::string className(); /// @pre nlats has enough allocated memory to store the latitudes /// @param size of lats vector - void assign(long nlon[], const size_t size) const; + void assign( long nlon[], const size_t size ) const; /// @post resizes the vector to the number of latitutes - void assign(std::vector& nlon) const; - - size_t N() const { - return nlon_.size(); - } + void assign( std::vector& nlon ) const; - protected: + size_t N() const { return nlon_.size(); } +protected: std::vector nlon_; - }; +#define DECLARE_POINTS_PER_LATITUDE( NUMBER ) \ + class N##NUMBER : public PointsPerLatitude { \ + public: \ + N##NUMBER(); \ + }; + +#define LIST( ... ) __VA_ARGS__ +#define DEFINE_POINTS_PER_LATITUDE( NUMBER, NLON ) \ + eckit::ConcreteBuilderT0 builder_N##NUMBER( #NUMBER ); \ + \ + N##NUMBER::N##NUMBER() { \ + size_t N = NUMBER; \ + long nlon[] = {NLON}; \ + nlon_.assign( nlon, nlon + N ); \ + } -#define DECLARE_POINTS_PER_LATITUDE(NUMBER) \ - class N##NUMBER : public PointsPerLatitude { public: N##NUMBER(); }; - -#define LIST(...) __VA_ARGS__ -#define DEFINE_POINTS_PER_LATITUDE(NUMBER,NLON) \ - eckit::ConcreteBuilderT0 builder_N##NUMBER(#NUMBER); \ - \ - N##NUMBER::N##NUMBER()\ - {\ - size_t N = NUMBER;\ - long nlon[] = {NLON} ;\ - nlon_.assign(nlon,nlon+N);\ - } - -DECLARE_POINTS_PER_LATITUDE(16); -DECLARE_POINTS_PER_LATITUDE(24); -DECLARE_POINTS_PER_LATITUDE(32); -DECLARE_POINTS_PER_LATITUDE(48); -DECLARE_POINTS_PER_LATITUDE(64); -DECLARE_POINTS_PER_LATITUDE(80); -DECLARE_POINTS_PER_LATITUDE(96); -DECLARE_POINTS_PER_LATITUDE(128); -DECLARE_POINTS_PER_LATITUDE(160); -DECLARE_POINTS_PER_LATITUDE(200); -DECLARE_POINTS_PER_LATITUDE(256); -DECLARE_POINTS_PER_LATITUDE(320); -DECLARE_POINTS_PER_LATITUDE(400); -DECLARE_POINTS_PER_LATITUDE(512); -DECLARE_POINTS_PER_LATITUDE(576); -DECLARE_POINTS_PER_LATITUDE(640); -DECLARE_POINTS_PER_LATITUDE(800); -DECLARE_POINTS_PER_LATITUDE(1024); -DECLARE_POINTS_PER_LATITUDE(1280); -DECLARE_POINTS_PER_LATITUDE(1600); -DECLARE_POINTS_PER_LATITUDE(2000); -DECLARE_POINTS_PER_LATITUDE(4000); -DECLARE_POINTS_PER_LATITUDE(8000); +DECLARE_POINTS_PER_LATITUDE( 16 ); +DECLARE_POINTS_PER_LATITUDE( 24 ); +DECLARE_POINTS_PER_LATITUDE( 32 ); +DECLARE_POINTS_PER_LATITUDE( 48 ); +DECLARE_POINTS_PER_LATITUDE( 64 ); +DECLARE_POINTS_PER_LATITUDE( 80 ); +DECLARE_POINTS_PER_LATITUDE( 96 ); +DECLARE_POINTS_PER_LATITUDE( 128 ); +DECLARE_POINTS_PER_LATITUDE( 160 ); +DECLARE_POINTS_PER_LATITUDE( 200 ); +DECLARE_POINTS_PER_LATITUDE( 256 ); +DECLARE_POINTS_PER_LATITUDE( 320 ); +DECLARE_POINTS_PER_LATITUDE( 400 ); +DECLARE_POINTS_PER_LATITUDE( 512 ); +DECLARE_POINTS_PER_LATITUDE( 576 ); +DECLARE_POINTS_PER_LATITUDE( 640 ); +DECLARE_POINTS_PER_LATITUDE( 800 ); +DECLARE_POINTS_PER_LATITUDE( 1024 ); +DECLARE_POINTS_PER_LATITUDE( 1280 ); +DECLARE_POINTS_PER_LATITUDE( 1600 ); +DECLARE_POINTS_PER_LATITUDE( 2000 ); +DECLARE_POINTS_PER_LATITUDE( 4000 ); +DECLARE_POINTS_PER_LATITUDE( 8000 ); #undef DECLARE_POINTS_PER_LATITUDE - } // namespace classic_gaussian } // namespace pl } // namespace detail diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N1024.cc b/src/atlas/grid/detail/pl/classic_gaussian/N1024.cc index 014dc60c0..b825c9e60 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N1024.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N1024.cc @@ -8,1036 +8,69 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(1024, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 60, - 64, - 72, - 72, - 75, - 81, - 90, - 96, - 96, - 108, - 108, - 120, - 120, - 125, - 125, - 135, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 216, - 216, - 225, - 225, - 240, - 240, - 243, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 384, - 384, - 400, - 400, - 405, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 625, - 625, - 625, - 625, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 750, - 750, - 750, - 750, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 800, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1215, - 1250, - 1250, - 1250, - 1250, - 1250, - 1250, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1620, - 1620, - 1620, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1944, - 1944, - 1944, - 1944, - 1944, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2025, - 2025, - 2025, - 2025, - 2048, - 2048, - 2048, - 2048, - 2048, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2187, - 2187, - 2187, - 2187, - 2187, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2430, - 2430, - 2430, - 2430, - 2430, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2592, - 2592, - 2592, - 2592, - 2592, - 2592, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096 -)) +DEFINE_POINTS_PER_LATITUDE( + 1024, LIST( 18, 25, 32, 40, 45, 50, 60, 64, 72, 72, 75, 81, 90, 96, 96, 108, 108, 120, 120, 125, 125, 135, 144, 150, + 160, 160, 180, 180, 180, 192, 192, 200, 216, 216, 225, 225, 240, 240, 243, 250, 256, 270, 270, 288, 288, + 288, 300, 300, 320, 320, 320, 360, 360, 360, 360, 360, 360, 375, 375, 384, 384, 400, 400, 405, 432, 432, + 432, 432, 450, 450, 450, 480, 480, 480, 480, 480, 486, 500, 500, 512, 512, 540, 540, 540, 540, 576, 576, + 576, 576, 576, 576, 600, 600, 600, 600, 625, 625, 625, 625, 640, 640, 648, 675, 675, 675, 675, 675, 720, + 720, 720, 720, 720, 720, 720, 729, 750, 750, 750, 750, 768, 768, 800, 800, 800, 800, 800, 800, 810, 864, + 864, 864, 864, 864, 864, 864, 864, 864, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, + 960, 960, 972, 972, 1000, 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1080, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1152, 1200, + 1200, 1200, 1200, 1200, 1200, 1200, 1215, 1215, 1215, 1250, 1250, 1250, 1250, 1250, 1250, 1280, 1280, + 1280, 1280, 1280, 1296, 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1500, 1500, + 1500, 1500, 1500, 1500, 1500, 1500, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1620, 1620, 1620, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1800, 1800, 1800, 1800, 1800, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1944, 1944, 1944, 1944, 1944, 2000, 2000, + 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2025, 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2048, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2187, 2187, 2187, 2187, 2187, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, + 2250, 2250, 2250, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2400, 2400, 2400, 2400, + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2430, 2430, + 2430, 2430, 2430, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + 2500, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2592, 2592, 2592, 2592, + 2592, 2592, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, + 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2916, 2916, 2916, 2916, 2916, + 2916, 2916, 2916, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, + 3000, 3000, 3000, 3000, 3000, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, + 3072, 3072, 3072, 3072, 3072, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, + 3125, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3200, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3375, 3375, 3375, 3375, 3375, + 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, + 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3456, 3456, 3456, + 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, + 3456, 3456, 3456, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, + 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, + 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3645, 3645, 3645, 3645, + 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3750, 3750, 3750, 3750, 3750, 3750, + 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, + 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, + 3888, 3888, 3888, 3888, 3888, 3888, 3888, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, + 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, + 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, + 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, + 4000, 4000, 4000, 4000, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, + 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, + 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N128.cc b/src/atlas/grid/detail/pl/classic_gaussian/N128.cc index aaee51f68..247e52dde 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N128.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N128.cc @@ -8,140 +8,17 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(128, LIST( - 18, - 25, - 36, - 40, - 45, - 50, - 60, - 64, - 72, - 72, - 80, - 90, - 90, - 100, - 108, - 120, - 120, - 125, - 128, - 144, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 216, - 216, - 216, - 225, - 240, - 240, - 240, - 250, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 320, - 324, - 360, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 375, - 375, - 384, - 384, - 400, - 400, - 400, - 400, - 405, - 432, - 432, - 432, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 480, - 480, - 480, - 480, - 480, - 486, - 486, - 486, - 500, - 500, - 500, - 500, - 500, - 500, - 500, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512, - 512 -)) +DEFINE_POINTS_PER_LATITUDE( 128, LIST( 18, 25, 36, 40, 45, 50, 60, 64, 72, 72, 80, 90, 90, 100, 108, 120, 120, 125, 128, + 144, 144, 150, 160, 160, 180, 180, 180, 192, 192, 200, 216, 216, 216, 225, 240, + 240, 240, 250, 250, 256, 270, 270, 288, 288, 288, 300, 300, 320, 320, 320, 320, + 324, 360, 360, 360, 360, 360, 360, 360, 375, 375, 375, 375, 384, 384, 400, 400, + 400, 400, 405, 432, 432, 432, 432, 432, 432, 432, 450, 450, 450, 450, 450, 480, + 480, 480, 480, 480, 480, 480, 480, 480, 480, 486, 486, 486, 500, 500, 500, 500, + 500, 500, 500, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, 512 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N1280.cc b/src/atlas/grid/detail/pl/classic_gaussian/N1280.cc index 6012ef333..7d2280053 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N1280.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N1280.cc @@ -8,1292 +8,84 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(1280, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 60, - 64, - 72, - 72, - 75, - 81, - 90, - 96, - 96, - 108, - 108, - 120, - 120, - 120, - 125, - 135, - 135, - 144, - 144, - 160, - 160, - 180, - 180, - 180, - 192, - 200, - 200, - 216, - 216, - 225, - 240, - 240, - 240, - 250, - 250, - 256, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 324, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 375, - 384, - 400, - 400, - 400, - 432, - 432, - 432, - 432, - 432, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 625, - 625, - 625, - 625, - 640, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 729, - 750, - 750, - 750, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1250, - 1250, - 1250, - 1250, - 1250, - 1250, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1620, - 1620, - 1620, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1944, - 1944, - 1944, - 1944, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2025, - 2025, - 2025, - 2025, - 2048, - 2048, - 2048, - 2048, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2187, - 2187, - 2187, - 2187, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2430, - 2430, - 2430, - 2430, - 2430, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2592, - 2592, - 2592, - 2592, - 2592, - 2592, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120 -)) +DEFINE_POINTS_PER_LATITUDE( + 1280, LIST( 18, 25, 32, 40, 45, 50, 60, 64, 72, 72, 75, 81, 90, 96, 96, 108, 108, 120, 120, 120, 125, 135, 135, 144, + 144, 160, 160, 180, 180, 180, 192, 200, 200, 216, 216, 225, 240, 240, 240, 250, 250, 256, 270, 288, 288, + 288, 300, 300, 320, 320, 320, 324, 360, 360, 360, 360, 360, 375, 375, 375, 384, 400, 400, 400, 432, 432, + 432, 432, 432, 450, 450, 480, 480, 480, 480, 480, 486, 500, 500, 512, 512, 540, 540, 540, 540, 540, 576, + 576, 576, 576, 576, 600, 600, 600, 600, 625, 625, 625, 625, 640, 640, 640, 648, 675, 675, 675, 675, 720, + 720, 720, 720, 720, 720, 720, 729, 729, 750, 750, 750, 768, 768, 768, 800, 800, 800, 800, 800, 810, 864, + 864, 864, 864, 864, 864, 864, 864, 864, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, + 960, 960, 972, 972, 1000, 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1080, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1200, 1200, + 1200, 1200, 1200, 1200, 1200, 1200, 1215, 1215, 1250, 1250, 1250, 1250, 1250, 1250, 1280, 1280, 1280, + 1280, 1280, 1296, 1296, 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1500, 1500, 1500, + 1500, 1500, 1500, 1500, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1620, 1620, 1620, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1800, 1800, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2025, 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2160, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2187, 2187, 2187, + 2187, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2304, 2304, 2304, 2304, 2304, + 2304, 2304, 2304, 2304, 2304, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, + 2400, 2400, 2400, 2400, 2400, 2430, 2430, 2430, 2430, 2430, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + 2500, 2500, 2500, 2500, 2500, 2500, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, + 2592, 2592, 2592, 2592, 2592, 2592, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, + 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2916, 2916, 2916, 2916, 2916, 2916, 3000, 3000, + 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3072, 3072, + 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3125, 3125, 3125, 3125, 3125, + 3125, 3125, 3125, 3125, 3125, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3200, 3200, 3200, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3375, 3375, 3375, 3375, 3375, 3375, + 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, + 3375, 3375, 3375, 3375, 3375, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, + 3456, 3456, 3456, 3456, 3456, 3456, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, + 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, + 3600, 3600, 3600, 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3750, 3750, 3750, 3750, + 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, + 3750, 3750, 3750, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, + 3888, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, + 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4050, 4050, 4050, 4050, + 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4374, 4374, 4374, + 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, + 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, + 4608, 4608, 4608, 4608, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4860, 4860, 4860, 4860, + 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, + 4860, 4860, 4860, 4860, 4860, 4860, 4860, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N16.cc b/src/atlas/grid/detail/pl/classic_gaussian/N16.cc index 4320f6aa6..c3435033f 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N16.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N16.cc @@ -8,28 +8,10 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(16, LIST( - 20, - 27, - 32, - 40, - 45, - 48, - 60, - 60, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64 -)) +DEFINE_POINTS_PER_LATITUDE( 16, LIST( 20, 27, 32, 40, 45, 48, 60, 60, 64, 64, 64, 64, 64, 64, 64, 64 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N160.cc b/src/atlas/grid/detail/pl/classic_gaussian/N160.cc index bc091063e..1be4c0472 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N160.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N160.cc @@ -8,172 +8,19 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(160, LIST( - 18, - 25, - 36, - 40, - 45, - 50, - 60, - 64, - 72, - 72, - 80, - 90, - 90, - 96, - 108, - 120, - 120, - 125, - 128, - 135, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 216, - 216, - 225, - 225, - 240, - 240, - 243, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 320, - 324, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 375, - 384, - 384, - 400, - 400, - 400, - 405, - 432, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 480, - 480, - 500, - 500, - 500, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 600, - 600, - 600, - 600, - 600, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640 -)) +DEFINE_POINTS_PER_LATITUDE( 160, LIST( 18, 25, 36, 40, 45, 50, 60, 64, 72, 72, 80, 90, 90, 96, 108, 120, 120, 125, 128, + 135, 144, 150, 160, 160, 180, 180, 180, 192, 192, 200, 216, 216, 225, 225, 240, + 240, 243, 250, 256, 270, 270, 288, 288, 288, 300, 300, 320, 320, 320, 320, 324, + 360, 360, 360, 360, 360, 360, 375, 375, 375, 384, 384, 400, 400, 400, 405, 432, + 432, 432, 432, 432, 450, 450, 450, 450, 480, 480, 480, 480, 480, 480, 480, 500, + 500, 500, 500, 500, 512, 512, 540, 540, 540, 540, 540, 540, 540, 540, 576, 576, + 576, 576, 576, 576, 576, 576, 576, 576, 600, 600, 600, 600, 600, 600, 600, 600, + 600, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N1600.cc b/src/atlas/grid/detail/pl/classic_gaussian/N1600.cc index 8da0d5a4e..b993438c2 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N1600.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N1600.cc @@ -8,1612 +8,103 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(1600, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 54, - 60, - 72, - 72, - 75, - 80, - 90, - 90, - 96, - 100, - 108, - 120, - 120, - 120, - 125, - 128, - 135, - 144, - 144, - 150, - 160, - 160, - 162, - 180, - 180, - 180, - 192, - 192, - 216, - 216, - 225, - 240, - 240, - 243, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 384, - 384, - 400, - 400, - 405, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 625, - 625, - 625, - 625, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 729, - 750, - 750, - 750, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 810, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1250, - 1250, - 1250, - 1250, - 1250, - 1250, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1620, - 1620, - 1620, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1944, - 1944, - 1944, - 1944, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2025, - 2025, - 2025, - 2025, - 2048, - 2048, - 2048, - 2048, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2187, - 2187, - 2187, - 2187, - 2187, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2430, - 2430, - 2430, - 2430, - 2430, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2592, - 2592, - 2592, - 2592, - 2592, - 2592, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400 -)) +DEFINE_POINTS_PER_LATITUDE( + 1600, LIST( 18, 25, 32, 40, 45, 50, 54, 60, 72, 72, 75, 80, 90, 90, 96, 100, 108, 120, 120, 120, 125, 128, 135, 144, + 144, 150, 160, 160, 162, 180, 180, 180, 192, 192, 216, 216, 225, 240, 240, 243, 250, 256, 270, 270, 288, + 288, 288, 300, 300, 320, 320, 320, 360, 360, 360, 360, 360, 360, 375, 375, 384, 384, 400, 400, 405, 432, + 432, 432, 432, 450, 450, 450, 480, 480, 480, 480, 480, 486, 500, 500, 512, 512, 540, 540, 540, 540, 576, + 576, 576, 576, 576, 576, 600, 600, 600, 600, 625, 625, 625, 625, 640, 640, 648, 675, 675, 675, 675, 720, + 720, 720, 720, 720, 720, 720, 729, 729, 750, 750, 750, 768, 768, 768, 800, 800, 800, 800, 800, 810, 810, + 864, 864, 864, 864, 864, 864, 864, 864, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, + 960, 960, 960, 972, 1000, 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1080, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1200, 1200, + 1200, 1200, 1200, 1200, 1200, 1200, 1215, 1215, 1250, 1250, 1250, 1250, 1250, 1250, 1280, 1280, 1280, + 1280, 1280, 1296, 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1500, 1500, 1500, + 1500, 1500, 1500, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1620, 1620, 1620, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2025, 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2187, 2187, 2187, 2187, 2187, 2250, 2250, + 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, + 2430, 2430, 2430, 2430, 2430, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2592, 2592, 2592, 2592, 2592, 2592, 2700, + 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2916, 2916, + 2916, 2916, 2916, 2916, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, + 3000, 3000, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3125, 3125, + 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3200, 3200, 3200, 3200, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3375, 3375, 3375, 3375, 3375, + 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, + 3375, 3375, 3375, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, + 3456, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, + 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3645, 3645, 3645, 3645, 3645, 3645, + 3645, 3645, 3645, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, + 3750, 3750, 3750, 3750, 3750, 3750, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 4000, + 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, + 4000, 4000, 4000, 4000, 4000, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4096, 4096, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, + 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, + 4860, 4860, 4860, 4860, 4860, 4860, 4860, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, + 5184, 5184, 5184, 5184, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, + 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, + 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, + 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5625, 5625, 5625, + 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, + 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, + 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, + 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5760, + 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, + 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, + 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5832, 5832, 5832, 5832, 5832, 5832, + 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, + 5832, 5832, 5832, 5832, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, + 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, + 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, + 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, + 6000, 6000, 6000, 6000, 6000, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, + 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, + 6075, 6075, 6075, 6075, 6075, 6075, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, + 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, + 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, + 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, + 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, + 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, + 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N200.cc b/src/atlas/grid/detail/pl/classic_gaussian/N200.cc index 9ac98d572..124b2c7ea 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N200.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N200.cc @@ -8,212 +8,20 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(200, LIST( - 18, - 25, - 36, - 40, - 45, - 50, - 60, - 64, - 72, - 72, - 75, - 81, - 90, - 96, - 100, - 108, - 120, - 125, - 128, - 135, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 216, - 216, - 225, - 225, - 240, - 240, - 243, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 320, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 375, - 384, - 400, - 400, - 400, - 400, - 432, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 500, - 512, - 512, - 512, - 540, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 600, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 648, - 648, - 675, - 675, - 675, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 729, - 729, - 750, - 750, - 750, - 750, - 750, - 750, - 750, - 750, - 768, - 768, - 768, - 768, - 768, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800 -)) +DEFINE_POINTS_PER_LATITUDE( + 200, + LIST( 18, 25, 36, 40, 45, 50, 60, 64, 72, 72, 75, 81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 160, 180, + 180, 180, 192, 192, 200, 216, 216, 225, 225, 240, 240, 243, 250, 256, 270, 270, 288, 288, 288, 300, 300, 320, + 320, 320, 320, 360, 360, 360, 360, 360, 360, 375, 375, 375, 384, 400, 400, 400, 400, 432, 432, 432, 432, 432, + 450, 450, 450, 480, 480, 480, 480, 480, 480, 486, 500, 500, 500, 512, 512, 512, 540, 540, 540, 540, 540, 576, + 576, 576, 576, 576, 576, 576, 576, 600, 600, 600, 600, 600, 640, 640, 640, 640, 640, 640, 640, 640, 640, 640, + 648, 648, 675, 675, 675, 675, 675, 675, 675, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, + 720, 729, 729, 729, 750, 750, 750, 750, 750, 750, 750, 750, 768, 768, 768, 768, 768, 768, 768, 768, 800, 800, + 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, + 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800, 800 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N2000.cc b/src/atlas/grid/detail/pl/classic_gaussian/N2000.cc index 81a010a0d..b16b0aafa 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N2000.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N2000.cc @@ -8,2012 +8,126 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(2000, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 60, - 60, - 72, - 72, - 75, - 81, - 90, - 96, - 96, - 108, - 108, - 120, - 120, - 120, - 125, - 135, - 135, - 144, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 180, - 192, - 192, - 192, - 200, - 216, - 216, - 216, - 225, - 240, - 240, - 243, - 250, - 256, - 270, - 270, - 288, - 300, - 300, - 320, - 320, - 320, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 384, - 400, - 400, - 400, - 405, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 625, - 625, - 625, - 625, - 640, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 750, - 750, - 750, - 750, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1215, - 1250, - 1250, - 1250, - 1250, - 1250, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1620, - 1620, - 1620, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1944, - 1944, - 1944, - 1944, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2025, - 2025, - 2025, - 2025, - 2048, - 2048, - 2048, - 2048, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2187, - 2187, - 2187, - 2187, - 2187, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2430, - 2430, - 2430, - 2430, - 2430, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2592, - 2592, - 2592, - 2592, - 2592, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3240, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000 -)) +DEFINE_POINTS_PER_LATITUDE( + 2000, LIST( 18, 25, 32, 40, 45, 50, 60, 60, 72, 72, 75, 81, 90, 96, 96, 108, 108, 120, 120, 120, 125, 135, 135, 144, + 144, 150, 160, 160, 180, 180, 180, 180, 192, 192, 192, 200, 216, 216, 216, 225, 240, 240, 243, 250, 256, + 270, 270, 288, 300, 300, 320, 320, 320, 360, 360, 360, 360, 360, 360, 375, 375, 384, 400, 400, 400, 405, + 432, 432, 432, 432, 450, 450, 450, 480, 480, 480, 480, 486, 500, 500, 500, 512, 512, 540, 540, 540, 540, + 576, 576, 576, 576, 576, 600, 600, 600, 600, 625, 625, 625, 625, 640, 640, 640, 648, 675, 675, 675, 675, + 720, 720, 720, 720, 720, 720, 720, 729, 750, 750, 750, 750, 768, 768, 768, 800, 800, 800, 800, 800, 810, + 864, 864, 864, 864, 864, 864, 864, 864, 864, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, + 960, 960, 960, 972, 972, 1000, 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1080, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1152, 1200, + 1200, 1200, 1200, 1200, 1200, 1200, 1215, 1215, 1215, 1250, 1250, 1250, 1250, 1250, 1280, 1280, 1280, + 1280, 1280, 1296, 1296, 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1500, 1500, 1500, 1500, + 1500, 1500, 1500, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1620, 1620, 1620, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2025, + 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2187, 2187, 2187, 2187, 2187, 2250, 2250, 2250, 2250, + 2250, 2250, 2250, 2250, 2250, 2250, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2400, 2400, + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2430, 2430, 2430, + 2430, 2430, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2560, 2560, 2560, + 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2592, 2592, 2592, 2592, 2592, 2700, 2700, 2700, 2700, 2700, + 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2916, 2916, 2916, 2916, 2916, 2916, 3000, 3000, + 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3072, 3072, 3072, 3072, + 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3240, 3240, 3240, 3240, + 3240, 3240, 3240, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, + 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, + 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, + 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3645, 3645, + 3645, 3645, 3645, 3645, 3645, 3645, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, + 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 4000, + 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, + 4000, 4000, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4096, 4096, 4096, 4096, 4096, 4096, + 4096, 4096, 4096, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4374, 4374, 4374, 4374, 4374, 4374, 4374, + 4374, 4374, 4374, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4608, 4608, 4608, 4608, 4608, 4608, 4608, + 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 4860, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5184, 5184, 5184, + 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5400, 5400, 5400, 5400, 5400, 5400, 5400, + 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, + 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, + 5400, 5400, 5400, 5400, 5400, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, + 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, + 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, + 5625, 5625, 5625, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, + 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, + 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 6000, + 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, + 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, + 6000, 6000, 6000, 6000, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, + 6075, 6075, 6075, 6075, 6075, 6075, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, + 6144, 6144, 6144, 6144, 6144, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, + 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, + 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, + 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6750, 6750, 6750, 6750, 6750, + 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, + 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, + 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6912, 6912, + 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, + 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, + 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, + 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, + 7290, 7290, 7290, 7290, 7290, 7290, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, + 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, + 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, + 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, + 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, + 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, + 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, + 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, + 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, + 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, + 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7776, 7776, 7776, 7776, 7776, + 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, + 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, + 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, + 7776, 7776, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N24.cc b/src/atlas/grid/detail/pl/classic_gaussian/N24.cc index 93df036d9..7d31437e9 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N24.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N24.cc @@ -8,36 +8,11 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(24, LIST( - 20, - 25, - 36, - 40, - 45, - 48, - 54, - 60, - 64, - 72, - 80, - 80, - 90, - 90, - 96, - 96, - 96, - 96, - 96, - 96, - 96, - 96, - 96, - 96 -)) +DEFINE_POINTS_PER_LATITUDE( 24, LIST( 20, 25, 36, 40, 45, 48, 54, 60, 64, 72, 80, 80, 90, 90, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N256.cc b/src/atlas/grid/detail/pl/classic_gaussian/N256.cc index ea90d2a29..20b6fadb5 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N256.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N256.cc @@ -8,264 +8,20 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(256, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 60, - 64, - 72, - 72, - 75, - 81, - 90, - 96, - 100, - 108, - 120, - 120, - 125, - 135, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 216, - 216, - 216, - 225, - 240, - 240, - 243, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 324, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 384, - 384, - 400, - 400, - 400, - 432, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 600, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 729, - 750, - 750, - 750, - 750, - 750, - 768, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 810, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 972, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024 -)) +DEFINE_POINTS_PER_LATITUDE( + 256, LIST( 18, 25, 32, 40, 45, 50, 60, 64, 72, 72, 75, 81, 90, 96, 100, 108, 120, 120, 125, 135, 144, 150, 160, 160, + 180, 180, 180, 192, 192, 200, 216, 216, 216, 225, 240, 240, 243, 250, 256, 270, 270, 288, 288, 288, 300, + 300, 320, 320, 320, 324, 360, 360, 360, 360, 360, 360, 375, 375, 384, 384, 400, 400, 400, 432, 432, 432, + 432, 432, 450, 450, 450, 480, 480, 480, 480, 480, 486, 500, 500, 500, 512, 512, 540, 540, 540, 540, 540, + 576, 576, 576, 576, 576, 576, 600, 600, 600, 600, 600, 640, 640, 640, 640, 640, 640, 640, 640, 648, 675, + 675, 675, 675, 675, 675, 720, 720, 720, 720, 720, 720, 720, 720, 720, 729, 729, 750, 750, 750, 750, 750, + 768, 768, 768, 768, 800, 800, 800, 800, 800, 800, 800, 800, 810, 810, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 960, 960, 960, + 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 972, 972, + 972, 972, 972, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, + 1000, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, + 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 ) ) } // namespace classic_gaussian } // namespace pl diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N32.cc b/src/atlas/grid/detail/pl/classic_gaussian/N32.cc index 70b1243a5..76f872d5d 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N32.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N32.cc @@ -8,44 +8,11 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(32, LIST( - 20, - 27, - 36, - 40, - 45, - 50, - 60, - 64, - 72, - 75, - 80, - 90, - 90, - 96, - 100, - 108, - 108, - 120, - 120, - 120, - 128, - 128, - 128, - 128, - 128, - 128, - 128, - 128, - 128, - 128, - 128, - 128 -)) +DEFINE_POINTS_PER_LATITUDE( 32, LIST( 20, 27, 36, 40, 45, 50, 60, 64, 72, 75, 80, 90, 90, 96, 100, 108, 108, 120, 120, + 120, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N320.cc b/src/atlas/grid/detail/pl/classic_gaussian/N320.cc index a4329bf68..3494bbd64 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N320.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N320.cc @@ -8,332 +8,27 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(320, LIST( - 18, - 25, - 36, - 40, - 45, - 50, - 60, - 64, - 72, - 72, - 75, - 81, - 90, - 96, - 100, - 108, - 120, - 120, - 125, - 135, - 144, - 144, - 150, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 216, - 216, - 216, - 225, - 240, - 240, - 240, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 324, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 384, - 384, - 400, - 400, - 405, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 648, - 648, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 750, - 750, - 750, - 750, - 768, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 800, - 810, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1152, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1215, - 1215, - 1215, - 1215, - 1215, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280 -)) +DEFINE_POINTS_PER_LATITUDE( + 320, + LIST( 18, 25, 36, 40, 45, 50, 60, 64, 72, 72, 75, 81, 90, 96, 100, 108, 120, 120, 125, 135, 144, 144, 150, 160, 180, + 180, 180, 192, 192, 200, 216, 216, 216, 225, 240, 240, 240, 250, 256, 270, 270, 288, 288, 288, 300, 300, 320, + 320, 320, 324, 360, 360, 360, 360, 360, 360, 375, 375, 384, 384, 400, 400, 405, 432, 432, 432, 432, 450, 450, + 450, 480, 480, 480, 480, 480, 486, 500, 500, 500, 512, 512, 540, 540, 540, 540, 540, 576, 576, 576, 576, 576, + 576, 600, 600, 600, 600, 640, 640, 640, 640, 640, 640, 640, 648, 648, 675, 675, 675, 675, 720, 720, 720, 720, + 720, 720, 720, 720, 720, 729, 750, 750, 750, 750, 768, 768, 768, 768, 800, 800, 800, 800, 800, 800, 810, 810, + 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 900, 900, 900, 900, 900, 900, 900, 900, 960, 960, 960, + 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 972, 972, 1000, 1000, 1000, 1000, 1000, 1000, 1000, + 1000, 1024, 1024, 1024, 1024, 1024, 1024, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1152, + 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, + 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1215, 1215, 1215, 1215, 1215, 1215, 1215, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N400.cc b/src/atlas/grid/detail/pl/classic_gaussian/N400.cc index 0534a53d3..334e7d49f 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N400.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N400.cc @@ -8,412 +8,32 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(400, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 60, - 60, - 72, - 72, - 75, - 81, - 90, - 96, - 100, - 108, - 120, - 120, - 125, - 128, - 144, - 144, - 150, - 160, - 160, - 180, - 180, - 192, - 192, - 200, - 200, - 216, - 216, - 225, - 240, - 240, - 240, - 250, - 250, - 256, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 324, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 384, - 400, - 400, - 400, - 405, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 729, - 750, - 750, - 750, - 750, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 800, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1215, - 1215, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1458, - 1458, - 1458, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600 -)) +DEFINE_POINTS_PER_LATITUDE( + 400, + LIST( 18, 25, 32, 40, 45, 50, 60, 60, 72, 72, 75, 81, 90, 96, 100, 108, 120, 120, 125, 128, 144, 144, 150, 160, 160, + 180, 180, 192, 192, 200, 200, 216, 216, 225, 240, 240, 240, 250, 250, 256, 270, 288, 288, 288, 300, 300, 320, + 320, 320, 324, 360, 360, 360, 360, 360, 360, 375, 375, 384, 400, 400, 400, 405, 432, 432, 432, 432, 450, 450, + 450, 480, 480, 480, 480, 480, 486, 500, 500, 512, 512, 540, 540, 540, 540, 540, 576, 576, 576, 576, 576, 576, + 600, 600, 600, 600, 640, 640, 640, 640, 640, 640, 640, 648, 675, 675, 675, 675, 675, 720, 720, 720, 720, 720, + 720, 720, 729, 729, 750, 750, 750, 750, 768, 768, 768, 800, 800, 800, 800, 800, 800, 810, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 900, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, 960, 960, + 960, 960, 960, 972, 972, 1000, 1000, 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1024, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1152, + 1152, 1152, 1152, 1152, 1152, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1215, 1215, + 1215, 1215, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1296, 1296, 1296, 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, + 1350, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1458, 1458, 1458, 1458, + 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N4000.cc b/src/atlas/grid/detail/pl/classic_gaussian/N4000.cc index 601537f5c..8d5269344 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N4000.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N4000.cc @@ -8,4012 +8,261 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(4000, LIST( - 18, - 24, - 32, - 40, - 45, - 48, - 54, - 60, - 64, - 72, - 75, - 80, - 90, - 90, - 96, - 100, - 108, - 108, - 120, - 120, - 125, - 128, - 135, - 135, - 144, - 150, - 150, - 160, - 160, - 180, - 180, - 180, - 180, - 192, - 192, - 192, - 200, - 216, - 216, - 216, - 216, - 225, - 225, - 240, - 240, - 240, - 243, - 250, - 256, - 256, - 270, - 270, - 270, - 288, - 288, - 288, - 288, - 300, - 300, - 300, - 320, - 320, - 320, - 320, - 324, - 360, - 360, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 375, - 375, - 384, - 384, - 400, - 400, - 400, - 405, - 405, - 432, - 432, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 480, - 486, - 486, - 500, - 500, - 500, - 512, - 512, - 512, - 540, - 540, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 600, - 600, - 625, - 625, - 625, - 625, - 625, - 625, - 640, - 640, - 640, - 648, - 648, - 675, - 675, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 729, - 750, - 750, - 750, - 750, - 750, - 768, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 800, - 800, - 810, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1215, - 1215, - 1250, - 1250, - 1250, - 1250, - 1250, - 1250, - 1250, - 1250, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1620, - 1620, - 1620, - 1620, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1944, - 1944, - 1944, - 1944, - 1944, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2048, - 2048, - 2048, - 2048, - 2048, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2430, - 2430, - 2430, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2592, - 2592, - 2592, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2916, - 2916, - 2916, - 2916, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3240, - 3240, - 3240, - 3240, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3375, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3456, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3600, - 3645, - 3645, - 3645, - 3645, - 3645, - 3645, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3750, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3840, - 3888, - 3888, - 3888, - 3888, - 3888, - 3888, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4000, - 4050, - 4050, - 4050, - 4050, - 4050, - 4050, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4096, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4320, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4374, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4500, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4608, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4800, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 4860, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5000, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5120, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5184, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5400, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5625, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5760, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 5832, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6000, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6075, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6144, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6250, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6400, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6480, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6561, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6750, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 6912, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7200, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7290, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7500, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7680, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 7776, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8000, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8100, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8192, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8640, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 8748, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9000, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9216, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9375, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9600, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 9720, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10000, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10125, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10240, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10368, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10800, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 10935, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11250, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11520, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 11664, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12000, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12150, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12288, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12500, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12800, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 12960, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13122, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13500, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 13824, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14400, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 14580, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15000, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15360, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15552, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 15625, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000, - 16000 -)) +DEFINE_POINTS_PER_LATITUDE( + 4000, LIST( 18, 24, 32, 40, 45, 48, 54, 60, 64, 72, 75, 80, 90, 90, 96, 100, 108, 108, 120, 120, 125, 128, 135, 135, + 144, 150, 150, 160, 160, 180, 180, 180, 180, 192, 192, 192, 200, 216, 216, 216, 216, 225, 225, 240, 240, + 240, 243, 250, 256, 256, 270, 270, 270, 288, 288, 288, 288, 300, 300, 300, 320, 320, 320, 320, 324, 360, + 360, 360, 360, 360, 360, 360, 360, 375, 375, 375, 375, 384, 384, 400, 400, 400, 405, 405, 432, 432, 432, + 432, 432, 432, 450, 450, 450, 450, 480, 480, 480, 480, 480, 480, 486, 486, 500, 500, 500, 512, 512, 512, + 540, 540, 540, 540, 540, 540, 576, 576, 576, 576, 576, 576, 576, 576, 600, 600, 600, 600, 600, 600, 625, + 625, 625, 625, 625, 625, 640, 640, 640, 648, 648, 675, 675, 675, 675, 675, 675, 720, 720, 720, 720, 720, + 720, 720, 720, 720, 720, 720, 729, 729, 750, 750, 750, 750, 750, 768, 768, 768, 768, 800, 800, 800, 800, + 800, 800, 800, 810, 810, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 900, 900, 900, + 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 972, 972, + 972, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1024, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1152, 1152, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, + 1200, 1200, 1200, 1215, 1215, 1215, 1215, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1296, 1296, 1296, 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, + 1350, 1350, 1350, 1350, 1350, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1458, 1500, 1500, 1500, 1500, + 1500, 1500, 1500, 1500, 1500, 1500, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1620, 1620, 1620, 1620, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1944, 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2000, 2000, 2000, 2025, 2025, 2025, 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2048, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2187, 2187, 2187, 2187, 2187, 2187, 2187, + 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2304, 2304, + 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2400, 2400, 2400, 2400, 2400, 2400, + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2430, + 2430, 2430, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2560, 2560, 2560, 2560, 2560, 2560, 2560, + 2592, 2592, 2592, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2916, 2916, 2916, 2916, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, + 3000, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3125, 3125, 3125, 3125, 3125, 3125, 3125, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3240, 3240, 3240, 3240, 3375, 3375, 3375, + 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3456, 3456, + 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, + 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3645, 3645, 3645, 3645, 3645, 3645, 3750, + 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3888, 3888, 3888, 3888, 3888, 3888, 4000, + 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4050, 4050, + 4050, 4050, 4050, 4050, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4860, 4860, 4860, 4860, 4860, 4860, 4860, + 4860, 4860, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5400, + 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, + 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5625, 5625, + 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, + 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5760, + 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, + 5760, 5760, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 6000, 6000, 6000, + 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, + 6000, 6000, 6000, 6000, 6000, 6000, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, 6075, + 6075, 6075, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6250, 6250, 6250, 6250, 6250, + 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6561, 6561, + 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6750, 6750, 6750, 6750, 6750, + 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, + 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, + 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, + 6912, 6912, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7290, 7290, + 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7500, 7500, 7500, + 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, + 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7680, 7680, + 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, + 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7776, 7776, 7776, 7776, + 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, + 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, + 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, + 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, + 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, + 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, + 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8748, 8748, 8748, 8748, 8748, + 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 9000, 9000, + 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, + 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, + 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, + 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, + 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9375, + 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, + 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9600, 9600, 9600, 9600, 9600, + 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, + 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, + 9600, 9600, 9600, 9600, 9600, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, + 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, + 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10240, + 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, + 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10368, 10368, 10368, 10368, 10368, 10368, 10368, + 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, + 10368, 10368, 10368, 10368, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, + 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 11250, + 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, + 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, + 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, + 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, + 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11520, 11520, 11520, 11520, 11520, 11520, 11520, + 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, + 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, + 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, + 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11664, 11664, 11664, 11664, 11664, 11664, + 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, + 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 12000, 12000, 12000, + 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, + 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, + 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, + 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, + 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12150, 12150, 12150, 12150, + 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, + 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, + 12150, 12150, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, + 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, + 12288, 12288, 12288, 12288, 12288, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, + 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, + 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, + 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12800, 12800, + 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, + 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, + 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, + 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, + 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, + 12800, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, + 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, + 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 13122, 13122, + 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, + 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, + 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, + 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, + 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, + 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, + 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, + 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, + 13824, 13824, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14580, + 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, + 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, + 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, + 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, + 14580, 14580, 14580, 14580, 14580, 14580, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, + 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, + 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, + 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, + 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, + 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, + 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, + 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15625, 15625, 15625, + 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, + 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, + 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, + 15625, 15625, 15625, 15625, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N48.cc b/src/atlas/grid/detail/pl/classic_gaussian/N48.cc index 7949e0dd1..7e0e6ea59 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N48.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N48.cc @@ -8,60 +8,12 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(48, LIST( - 20, - 25, - 36, - 40, - 45, - 50, - 60, - 60, - 72, - 75, - 80, - 90, - 96, - 100, - 108, - 120, - 120, - 120, - 128, - 135, - 144, - 144, - 160, - 160, - 160, - 160, - 160, - 180, - 180, - 180, - 180, - 180, - 192, - 192, - 192, - 192, - 192, - 192, - 192, - 192, - 192, - 192, - 192, - 192, - 192, - 192, - 192, - 192 -)) +DEFINE_POINTS_PER_LATITUDE( 48, LIST( 20, 25, 36, 40, 45, 50, 60, 60, 72, 75, 80, 90, 96, 100, 108, 120, 120, 120, 128, + 135, 144, 144, 160, 160, 160, 160, 160, 180, 180, 180, 180, 180, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N512.cc b/src/atlas/grid/detail/pl/classic_gaussian/N512.cc index 3dba44f6c..ba7cd62a6 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N512.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N512.cc @@ -8,524 +8,38 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(512, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 60, - 60, - 72, - 72, - 75, - 81, - 90, - 96, - 96, - 100, - 108, - 120, - 125, - 128, - 135, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 216, - 216, - 225, - 225, - 240, - 240, - 243, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 320, - 320, - 320, - 320, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 384, - 384, - 400, - 400, - 400, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 729, - 750, - 750, - 750, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 800, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1215, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1620, - 1620, - 1620, - 1620, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1944, - 1944, - 1944, - 1944, - 1944, - 1944, - 1944, - 1944, - 1944, - 1944, - 1944, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048 -)) +DEFINE_POINTS_PER_LATITUDE( + 512, + LIST( 18, 25, 32, 40, 45, 50, 60, 60, 72, 72, 75, 81, 90, 96, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160, 160, + 180, 180, 180, 192, 192, 200, 216, 216, 225, 225, 240, 240, 243, 250, 256, 270, 270, 288, 288, 288, 300, 320, + 320, 320, 320, 360, 360, 360, 360, 360, 360, 375, 375, 384, 384, 400, 400, 400, 432, 432, 432, 432, 450, 450, + 450, 480, 480, 480, 480, 480, 486, 500, 500, 512, 512, 540, 540, 540, 540, 540, 576, 576, 576, 576, 576, 576, + 600, 600, 600, 640, 640, 640, 640, 640, 640, 640, 648, 675, 675, 675, 675, 675, 720, 720, 720, 720, 720, 720, + 720, 729, 729, 750, 750, 750, 768, 768, 768, 800, 800, 800, 800, 800, 800, 810, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, + 972, 972, 1000, 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1080, 1080, 1080, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1152, 1200, + 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1215, 1215, 1215, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1296, 1296, 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, + 1350, 1350, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1458, 1458, 1458, 1458, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1536, + 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1620, 1620, 1620, 1620, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1944, 1944, 1944, + 1944, 1944, 1944, 1944, 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2000, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, + 2025, 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2048 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N576.cc b/src/atlas/grid/detail/pl/classic_gaussian/N576.cc index 482d7285d..05d473d0e 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N576.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N576.cc @@ -8,588 +8,42 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(576, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 60, - 60, - 72, - 72, - 75, - 81, - 90, - 96, - 96, - 100, - 108, - 120, - 120, - 125, - 135, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 216, - 216, - 225, - 225, - 240, - 240, - 243, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 384, - 384, - 400, - 400, - 400, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 540, +DEFINE_POINTS_PER_LATITUDE( 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, - 640, - 640, - 640, - 640, - 640, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 750, - 750, - 750, - 750, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 810, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1215, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1620, - 1620, - 1620, - 1620, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1944, - 1944, - 1944, - 1944, - 1944, - 1944, - 1944, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304 -)) + LIST( 18, 25, 32, 40, 45, 50, 60, 60, 72, 72, 75, 81, 90, 96, 96, 100, 108, 120, 120, 125, 135, 144, 150, 160, 160, + 180, 180, 180, 192, 192, 200, 216, 216, 225, 225, 240, 240, 243, 250, 256, 270, 270, 288, 288, 288, 300, 300, + 320, 320, 320, 360, 360, 360, 360, 360, 360, 375, 375, 384, 384, 400, 400, 400, 432, 432, 432, 432, 450, 450, + 450, 480, 480, 480, 480, 480, 486, 500, 500, 512, 512, 540, 540, 540, 540, 540, 576, 576, 576, 576, 576, 600, + 600, 600, 600, 640, 640, 640, 640, 640, 640, 640, 648, 675, 675, 675, 675, 675, 720, 720, 720, 720, 720, 720, + 720, 729, 750, 750, 750, 750, 768, 768, 768, 800, 800, 800, 800, 800, 810, 810, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 972, 972, 972, + 1000, 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1152, 1200, 1200, 1200, 1200, 1200, + 1200, 1200, 1200, 1200, 1215, 1215, 1215, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, + 1280, 1296, 1296, 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1458, + 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1620, 1620, 1620, 1620, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1800, 1800, 1800, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1944, 1944, 1944, 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2000, 2000, 2000, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2025, 2048, 2048, 2048, 2048, + 2048, 2048, 2048, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2187, 2187, 2187, 2187, 2187, 2187, 2187, 2187, + 2187, 2187, 2187, 2187, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, + 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, + 2250, 2250, 2250, 2250, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, + 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, + 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, + 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, + 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, + 2304, 2304, 2304, 2304, 2304 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N64.cc b/src/atlas/grid/detail/pl/classic_gaussian/N64.cc index 5fc2b1c3e..71bab123a 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N64.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N64.cc @@ -8,76 +8,13 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(64, LIST( - 20, - 25, - 36, - 40, - 45, - 54, - 60, - 64, - 72, - 75, - 80, - 90, - 96, - 100, - 108, - 120, - 120, - 125, - 135, - 135, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 180, - 192, - 192, - 200, - 200, - 216, - 216, - 216, - 216, - 225, - 225, - 225, - 240, - 240, - 240, - 240, - 243, - 250, - 250, - 250, - 250, - 256, - 256, - 256, - 256, - 256, - 256, - 256, - 256, - 256, - 256, - 256, - 256, - 256, - 256, - 256, - 256 -)) +DEFINE_POINTS_PER_LATITUDE( 64, LIST( 20, 25, 36, 40, 45, 54, 60, 64, 72, 75, 80, 90, 96, 100, 108, 120, 120, 125, 135, + 135, 144, 150, 160, 160, 180, 180, 180, 180, 192, 192, 200, 200, 216, 216, 216, + 216, 225, 225, 225, 240, 240, 240, 240, 243, 250, 250, 250, 250, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N640.cc b/src/atlas/grid/detail/pl/classic_gaussian/N640.cc index 4dfd903b0..96634d2f6 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N640.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N640.cc @@ -8,652 +8,45 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(640, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 60, - 60, - 72, - 72, - 75, - 81, - 90, - 90, - 96, - 100, - 108, - 120, - 120, - 125, - 135, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 216, - 216, - 216, - 225, - 240, - 240, - 243, - 250, - 256, - 270, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 384, - 384, - 400, - 400, - 400, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 600, +DEFINE_POINTS_PER_LATITUDE( 640, - 640, - 640, - 640, - 640, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 750, - 750, - 750, - 750, - 768, - 768, - 768, - 800, - 800, - 800, - 800, - 800, - 810, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1215, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1620, - 1620, - 1620, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1944, - 1944, - 1944, - 1944, - 1944, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2025, - 2025, - 2025, - 2025, - 2025, - 2025, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2048, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560 -)) + LIST( 18, 25, 32, 40, 45, 50, 60, 60, 72, 72, 75, 81, 90, 90, 96, 100, 108, 120, 120, 125, 135, 144, 150, 160, 160, + 180, 180, 180, 192, 192, 200, 216, 216, 216, 225, 240, 240, 243, 250, 256, 270, 270, 288, 288, 288, 300, 300, + 320, 320, 320, 360, 360, 360, 360, 360, 360, 375, 375, 384, 384, 400, 400, 400, 432, 432, 432, 432, 450, 450, + 450, 480, 480, 480, 480, 480, 486, 500, 500, 512, 512, 540, 540, 540, 540, 540, 576, 576, 576, 576, 576, 600, + 600, 600, 600, 640, 640, 640, 640, 640, 640, 640, 648, 675, 675, 675, 675, 720, 720, 720, 720, 720, 720, 720, + 720, 729, 750, 750, 750, 750, 768, 768, 768, 800, 800, 800, 800, 800, 810, 810, 864, 864, 864, 864, 864, 864, + 864, 864, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 972, 972, 1000, + 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1125, + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1152, 1200, 1200, 1200, 1200, 1200, 1200, + 1200, 1200, 1215, 1215, 1215, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1296, + 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1458, 1500, 1500, 1500, 1500, + 1500, 1500, 1500, 1500, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, 1600, 1600, 1600, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1620, 1620, 1620, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1800, 1800, 1800, 1800, + 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1944, 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2000, 2025, 2025, 2025, 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2048, 2048, 2048, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2187, 2187, 2187, 2187, 2187, 2187, 2187, + 2187, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, + 2250, 2250, 2250, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, + 2304, 2304, 2304, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, + 2400, 2400, 2400, 2400, 2430, 2430, 2430, 2430, 2430, 2430, 2430, 2430, 2430, 2430, 2430, 2430, 2430, 2430, + 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + 2500, 2500, 2500, 2500, 2500, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, + 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, + 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, + 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, + 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, + 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N80.cc b/src/atlas/grid/detail/pl/classic_gaussian/N80.cc index d1f6a68df..1137f61f7 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N80.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N80.cc @@ -8,92 +8,14 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(80, LIST( - 18, - 25, - 36, - 40, - 45, - 54, - 60, - 64, - 72, - 72, - 80, - 90, - 96, - 100, - 108, - 120, - 120, - 128, - 135, - 144, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 200, - 216, - 216, - 216, - 225, - 225, - 240, - 240, - 240, - 256, - 256, - 256, - 256, - 288, - 288, - 288, - 288, - 288, - 288, - 288, - 288, - 288, - 300, - 300, - 300, - 300, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320, - 320 -)) +DEFINE_POINTS_PER_LATITUDE( 80, LIST( 18, 25, 36, 40, 45, 54, 60, 64, 72, 72, 80, 90, 96, 100, 108, 120, 120, 128, 135, + 144, 144, 150, 160, 160, 180, 180, 180, 192, 192, 200, 200, 216, 216, 216, 225, + 225, 240, 240, 240, 256, 256, 256, 256, 288, 288, 288, 288, 288, 288, 288, 288, + 288, 300, 300, 300, 300, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320, 320 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N800.cc b/src/atlas/grid/detail/pl/classic_gaussian/N800.cc index a3be5d7ee..580681bcf 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N800.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N800.cc @@ -8,812 +8,54 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(800, LIST( - 18, - 25, - 32, - 40, - 45, - 50, - 60, - 60, - 72, - 72, - 75, - 80, - 90, - 90, - 96, - 100, - 108, - 120, - 120, - 125, - 128, - 135, - 144, - 150, - 160, - 160, - 180, - 180, - 192, - 192, - 200, - 200, - 216, - 216, - 225, - 240, - 240, - 240, - 250, - 250, - 256, - 270, - 288, - 288, - 288, - 300, - 300, - 320, - 320, - 320, - 324, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 375, - 384, - 400, - 400, - 400, - 405, - 432, - 432, - 432, - 432, - 450, - 450, - 450, - 480, - 480, - 480, - 480, - 486, - 500, - 500, - 500, - 512, - 512, - 540, - 540, - 540, - 540, - 576, - 576, - 576, - 576, - 576, - 576, - 600, - 600, - 600, - 625, - 625, - 625, - 625, - 625, - 640, - 640, - 648, - 675, - 675, - 675, - 675, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 720, - 729, - 750, - 750, - 750, - 768, - 768, - 768, +DEFINE_POINTS_PER_LATITUDE( 800, - 800, - 800, - 800, - 800, - 800, - 810, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 864, - 900, - 900, - 900, - 900, - 900, - 900, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 960, - 972, - 972, - 1000, - 1000, - 1000, - 1000, - 1000, - 1024, - 1024, - 1024, - 1024, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1080, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1125, - 1152, - 1152, - 1152, - 1152, - 1152, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1200, - 1215, - 1215, - 1250, - 1250, - 1250, - 1250, - 1250, - 1250, - 1280, - 1280, - 1280, - 1280, - 1280, - 1280, - 1296, - 1296, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1350, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1440, - 1458, - 1458, - 1458, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1500, - 1536, - 1536, - 1536, - 1536, - 1536, - 1536, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1600, - 1620, - 1620, - 1620, - 1620, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1728, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1800, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1875, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1920, - 1944, - 1944, - 1944, - 1944, - 1944, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2000, - 2025, - 2025, - 2025, - 2025, - 2025, - 2048, - 2048, - 2048, - 2048, - 2048, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2160, - 2187, - 2187, - 2187, - 2187, - 2187, - 2187, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2250, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2304, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2400, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2430, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2500, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2560, - 2592, - 2592, - 2592, - 2592, - 2592, - 2592, - 2592, - 2592, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2700, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2880, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 2916, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3000, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3072, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3125, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200, - 3200 -)) + LIST( 18, 25, 32, 40, 45, 50, 60, 60, 72, 72, 75, 80, 90, 90, 96, 100, 108, 120, 120, 125, 128, 135, 144, 150, 160, + 160, 180, 180, 192, 192, 200, 200, 216, 216, 225, 240, 240, 240, 250, 250, 256, 270, 288, 288, 288, 300, 300, + 320, 320, 320, 324, 360, 360, 360, 360, 360, 375, 375, 375, 384, 400, 400, 400, 405, 432, 432, 432, 432, 450, + 450, 450, 480, 480, 480, 480, 486, 500, 500, 500, 512, 512, 540, 540, 540, 540, 576, 576, 576, 576, 576, 576, + 600, 600, 600, 625, 625, 625, 625, 625, 640, 640, 648, 675, 675, 675, 675, 720, 720, 720, 720, 720, 720, 720, + 720, 729, 750, 750, 750, 768, 768, 768, 800, 800, 800, 800, 800, 800, 810, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 972, 972, 1000, + 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1125, + 1125, 1125, 1125, 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1152, 1200, 1200, 1200, 1200, 1200, 1200, 1200, + 1200, 1215, 1215, 1250, 1250, 1250, 1250, 1250, 1250, 1280, 1280, 1280, 1280, 1280, 1280, 1296, 1296, 1350, + 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1536, + 1536, 1536, 1536, 1536, 1536, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1620, + 1620, 1620, 1620, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1920, 1920, 1944, 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2025, 2025, 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2048, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, + 2187, 2187, 2187, 2187, 2187, 2187, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, + 2250, 2250, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2400, 2400, 2400, 2400, + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, + 2430, 2430, 2430, 2430, 2430, 2430, 2430, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, + 2560, 2560, 2560, 2560, 2592, 2592, 2592, 2592, 2592, 2592, 2592, 2592, 2700, 2700, 2700, 2700, 2700, 2700, + 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, + 2700, 2700, 2700, 2700, 2700, 2700, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2916, 2916, 2916, 2916, 2916, 2916, 2916, 2916, + 2916, 2916, 2916, 2916, 2916, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, + 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, + 3000, 3000, 3000, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, + 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, + 3072, 3072, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, + 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3200, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N8000.cc b/src/atlas/grid/detail/pl/classic_gaussian/N8000.cc index c8b6607e9..062f413f6 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N8000.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N8000.cc @@ -8,812 +8,528 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(8000, LIST( - 16, 24, 30, 36, 40, 45, 54, 60, 64, 72, - 72, 75, 81, 90, 90, 96, 100, 108, 120, 120, - 120, 125, 128, 135, 144, 144, 150, 160, 160, 160, - 180, 180, 180, 180, 192, 192, 192, 200, 216, 216, - 216, 216, 225, 225, 240, 240, 240, 243, 250, 250, - 256, 270, 270, 270, 288, 288, 288, 288, 300, 300, - 300, 320, 320, 320, 320, 324, 360, 360, 360, 360, - 360, 360, 360, 360, 375, 375, 375, 375, 384, 384, - 400, 400, 400, 405, 405, 432, 432, 432, 432, 432, - 432, 450, 450, 450, 450, 480, 480, 480, 480, 480, - 480, 480, 486, 500, 500, 500, 512, 512, 512, 540, - 540, 540, 540, 540, 540, 540, 576, 576, 576, 576, - 576, 576, 576, 576, 600, 600, 600, 600, 600, 625, - 625, 625, 625, 625, 625, 640, 640, 640, 640, 648, - 675, 675, 675, 675, 675, 675, 675, 720, 720, 720, - 720, 720, 720, 720, 720, 720, 720, 729, 729, 750, - 750, 750, 750, 750, 768, 768, 768, 768, 800, 800, - 800, 800, 800, 800, 800, 800, 810, 810, 864, 864, - 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, - 864, 900, 900, 900, 900, 900, 900, 900, 900, 960, - 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, - 960, 960, 960, 972, 972, 972, 1000, 1000, 1000, 1000, - 1000, 1000, 1024, 1024, 1024, 1024, 1024, 1024, 1080, 1080, - 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, - 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, - 1125, 1125, 1152, 1152, 1152, 1152, 1152, 1152, 1200, 1200, - 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1215, - 1215, 1215, 1215, 1250, 1250, 1250, 1250, 1250, 1250, 1250, - 1250, 1280, 1280, 1280, 1280, 1280, 1280, 1280, 1296, 1296, - 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, - 1350, 1350, 1350, 1350, 1440, 1440, 1440, 1440, 1440, 1440, - 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, - 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1458, 1500, - 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1500, 1536, - 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, - 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, - 1600, 1600, 1600, 1620, 1620, 1620, 1620, 1728, 1728, 1728, - 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, - 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, - 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, 1800, - 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, - 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, - 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1920, 1920, - 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1920, 1944, 1944, - 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, - 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2025, 2025, 2025, - 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2048, 2160, 2160, - 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, - 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, - 2160, 2160, 2160, 2160, 2160, 2187, 2187, 2187, 2187, 2187, - 2187, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, - 2250, 2250, 2250, 2250, 2250, 2250, 2304, 2304, 2304, 2304, - 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2400, - 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, - 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, - 2400, 2400, 2430, 2430, 2430, 2430, 2430, 2430, 2430, 2500, - 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, - 2500, 2500, 2500, 2500, 2500, 2560, 2560, 2560, 2560, 2560, - 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2592, - 2592, 2592, 2592, 2592, 2592, 2592, 2592, 2700, 2700, 2700, - 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, - 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, - 2700, 2700, 2700, 2880, 2880, 2880, 2880, 2880, 2880, 2880, - 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, - 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, - 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, - 2880, 2880, 2880, 2880, 2880, 2880, 2916, 2916, 2916, 2916, - 2916, 2916, 2916, 2916, 3000, 3000, 3000, 3000, 3000, 3000, - 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, - 3000, 3000, 3000, 3000, 3072, 3072, 3072, 3072, 3072, 3072, - 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, - 3072, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, - 3125, 3125, 3125, 3125, 3200, 3200, 3200, 3200, 3200, 3200, - 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, - 3200, 3200, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, - 3240, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, - 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, - 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, - 3375, 3375, 3375, 3375, 3456, 3456, 3456, 3456, 3456, 3456, - 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, - 3456, 3456, 3456, 3600, 3600, 3600, 3600, 3600, 3600, 3600, - 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, - 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, - 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3645, 3645, 3645, - 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3645, 3750, 3750, - 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, - 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, - 3750, 3750, 3750, 3840, 3840, 3840, 3840, 3840, 3840, 3840, - 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, - 3840, 3840, 3840, 3840, 3840, 3888, 3888, 3888, 3888, 3888, - 3888, 3888, 3888, 3888, 3888, 3888, 3888, 4000, 4000, 4000, - 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, - 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, - 4000, 4000, 4000, 4050, 4050, 4050, 4050, 4050, 4050, 4050, - 4050, 4050, 4050, 4050, 4050, 4096, 4096, 4096, 4096, 4096, - 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4320, 4320, 4320, - 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, - 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, - 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, - 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, - 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, - 4320, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, - 4374, 4374, 4374, 4374, 4500, 4500, 4500, 4500, 4500, 4500, - 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, - 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, - 4500, 4500, 4500, 4500, 4608, 4608, 4608, 4608, 4608, 4608, - 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, - 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, - 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, - 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, - 4800, 4800, 4800, 4800, 4800, 4860, 4860, 4860, 4860, 4860, - 4860, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, - 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5120, 5120, - 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, - 5120, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5400, 5400, - 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, - 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, - 5400, 5400, 5400, 5625, 5625, 5625, 5625, 5625, 5625, 5625, - 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, - 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, - 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, - 5760, 5760, 5760, 5760, 5760, 5760, 5832, 5832, 5832, 5832, - 5832, 5832, 5832, 5832, 5832, 6000, 6000, 6000, 6000, 6000, - 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, - 6000, 6000, 6000, 6000, 6000, 6000, 6075, 6075, 6075, 6075, - 6075, 6075, 6075, 6075, 6075, 6144, 6144, 6144, 6144, 6144, - 6144, 6144, 6144, 6250, 6250, 6250, 6250, 6250, 6250, 6250, - 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6400, 6400, 6400, - 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, - 6400, 6400, 6400, 6400, 6400, 6400, 6480, 6480, 6480, 6480, - 6480, 6480, 6480, 6480, 6480, 6480, 6480, 6561, 6561, 6561, - 6561, 6561, 6561, 6561, 6561, 6561, 6750, 6750, 6750, 6750, - 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, - 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, - 6750, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, - 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, - 6912, 6912, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, - 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, - 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, - 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, - 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, - 7290, 7290, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, - 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, - 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, - 7500, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, - 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, - 7680, 7680, 7680, 7680, 7680, 7680, 7776, 7776, 7776, 7776, - 7776, 7776, 7776, 7776, 7776, 7776, 7776, 7776, 8000, 8000, - 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, - 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, - 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, - 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, - 8100, 8100, 8100, 8100, 8192, 8192, 8192, 8192, 8192, 8192, - 8192, 8192, 8192, 8192, 8192, 8192, 8640, 8640, 8640, 8640, - 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, - 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, - 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, - 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, - 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, - 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, - 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, - 8748, 8748, 8748, 8748, 8748, 8748, 9000, 9000, 9000, 9000, - 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, - 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, - 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, - 9000, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, - 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, - 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, - 9216, 9216, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, - 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, - 9375, 9375, 9375, 9375, 9375, 9375, 9600, 9600, 9600, 9600, - 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, - 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, - 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9720, 9720, - 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, - 9720, 9720, 9720, 9720, 9720, 9720, 10000, 10000, 10000, 10000, - 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, - 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, - 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, - 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10125, 10125, - 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, - 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10240, 10240, 10240, - 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, - 10240, 10240, 10240, 10240, 10240, 10368, 10368, 10368, 10368, 10368, - 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, - 10368, 10368, 10368, 10368, 10800, 10800, 10800, 10800, 10800, 10800, - 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, - 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, - 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, - 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, - 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, - 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10935, - 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, - 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, - 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, - 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, - 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, - 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, - 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11520, - 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, - 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, - 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, - 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, - 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, - 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, - 11664, 11664, 11664, 11664, 12000, 12000, 12000, 12000, 12000, 12000, - 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, - 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, - 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, - 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, - 12000, 12000, 12000, 12000, 12000, 12000, 12150, 12150, 12150, 12150, - 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, - 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, - 12150, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, - 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, - 12288, 12288, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, - 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, - 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, - 12500, 12500, 12500, 12500, 12500, 12500, 12800, 12800, 12800, 12800, - 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, - 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, - 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, - 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, - 12800, 12800, 12800, 12800, 12960, 12960, 12960, 12960, 12960, 12960, - 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, - 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 13122, - 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, - 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, - 13122, 13122, 13122, 13122, 13122, 13122, 13500, 13500, 13500, 13500, - 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, - 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, - 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, - 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, - 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, - 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13824, - 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, - 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, - 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, - 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, - 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, - 13824, 13824, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, - 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, - 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, - 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, - 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, - 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, - 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, - 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, - 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, - 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14580, 14580, - 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, - 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, - 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 15000, - 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, - 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, - 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, - 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, - 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, - 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, - 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15360, - 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, - 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, - 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, - 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, - 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, - 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, - 15360, 15360, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, - 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, - 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, - 15552, 15552, 15552, 15552, 15625, 15625, 15625, 15625, 15625, 15625, - 15625, 15625, 15625, 15625, 15625, 15625, 15625, 16000, 16000, 16000, - 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, - 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, - 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, - 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, - 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, - 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, - 16000, 16000, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, - 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, - 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, - 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, - 16384, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, - 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, - 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, - 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, - 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, - 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, - 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, - 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, - 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 17280, 17280, - 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, - 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, - 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, - 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, - 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, - 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, - 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, - 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, - 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, - 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, - 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, - 17496, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, - 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, - 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, - 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, - 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, - 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, - 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, - 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, - 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, - 18000, 18000, 18000, 18225, 18225, 18225, 18225, 18225, 18225, 18225, - 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, - 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, - 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, - 18225, 18225, 18225, 18225, 18225, 18432, 18432, 18432, 18432, 18432, - 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, - 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, - 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, - 18432, 18432, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, - 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, - 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, - 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, - 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, - 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, - 18750, 18750, 18750, 19200, 19200, 19200, 19200, 19200, 19200, 19200, - 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, - 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, - 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, - 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, - 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, - 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, - 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, - 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19440, 19440, - 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, - 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, - 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, - 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, - 19440, 19440, 19440, 19440, 19440, 19683, 19683, 19683, 19683, 19683, - 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, - 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, - 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, - 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, - 19683, 19683, 19683, 20000, 20000, 20000, 20000, 20000, 20000, 20000, - 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, - 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, - 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, - 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, - 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, - 20000, 20000, 20000, 20000, 20250, 20250, 20250, 20250, 20250, 20250, - 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, - 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, - 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, - 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, - 20250, 20250, 20250, 20250, 20480, 20480, 20480, 20480, 20480, 20480, - 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, - 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, - 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, - 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, - 20480, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, - 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, - 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, - 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, - 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, - 20736, 20736, 20736, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, - 21600, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, - 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, - 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, - 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, - 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, - 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, - 22500, 22500, 22500, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, - 23040, 23040, 23040, 23040, 23328, 23328, 23328, 23328, 23328, 23328, - 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, - 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, - 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, - 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, - 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, - 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, - 24000, 24000, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, - 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, - 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, - 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, - 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, - 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, - 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, - 24300, 24300, 24300, 24300, 24300, 24576, 24576, 24576, 24576, 24576, - 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, - 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, - 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, - 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, - 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, - 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, - 24576, 24576, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, - 25000, 25000, 25000, 25000, 25000, 25000, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, - 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25920, 25920, - 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, - 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, - 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, - 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, - 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, - 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, - 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, - 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, - 25920, 25920, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, - 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, - 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, - 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, - 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, - 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, - 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, - 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, - 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, - 26244, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, - 27000, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, - 27648, 27648, 27648, 27648, 27648, 27648, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, - 28800, 28800, 28800, 28800, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, - 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, - 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, - 30375, 30375, 30375, 30375, 30375, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, - 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, - 31104, 31104, 31104, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, - 31250, 31250, 31250, 31250, 31250, 31250, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, - 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000 -)) +DEFINE_POINTS_PER_LATITUDE( + 8000, LIST( 16, 24, 30, 36, 40, 45, 54, 60, 64, 72, 72, 75, 81, 90, 90, 96, 100, 108, 120, 120, 120, 125, 128, 135, + 144, 144, 150, 160, 160, 160, 180, 180, 180, 180, 192, 192, 192, 200, 216, 216, 216, 216, 225, 225, 240, + 240, 240, 243, 250, 250, 256, 270, 270, 270, 288, 288, 288, 288, 300, 300, 300, 320, 320, 320, 320, 324, + 360, 360, 360, 360, 360, 360, 360, 360, 375, 375, 375, 375, 384, 384, 400, 400, 400, 405, 405, 432, 432, + 432, 432, 432, 432, 450, 450, 450, 450, 480, 480, 480, 480, 480, 480, 480, 486, 500, 500, 500, 512, 512, + 512, 540, 540, 540, 540, 540, 540, 540, 576, 576, 576, 576, 576, 576, 576, 576, 600, 600, 600, 600, 600, + 625, 625, 625, 625, 625, 625, 640, 640, 640, 640, 648, 675, 675, 675, 675, 675, 675, 675, 720, 720, 720, + 720, 720, 720, 720, 720, 720, 720, 729, 729, 750, 750, 750, 750, 750, 768, 768, 768, 768, 800, 800, 800, + 800, 800, 800, 800, 800, 810, 810, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, 900, + 900, 900, 900, 900, 900, 900, 900, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, + 972, 972, 972, 1000, 1000, 1000, 1000, 1000, 1000, 1024, 1024, 1024, 1024, 1024, 1024, 1080, 1080, 1080, + 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1080, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, 1152, 1152, 1152, 1152, 1152, 1152, 1200, 1200, 1200, 1200, 1200, 1200, 1200, + 1200, 1200, 1200, 1200, 1215, 1215, 1215, 1215, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1250, 1280, + 1280, 1280, 1280, 1280, 1280, 1280, 1296, 1296, 1296, 1350, 1350, 1350, 1350, 1350, 1350, 1350, 1350, + 1350, 1350, 1350, 1350, 1350, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, + 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1440, 1458, 1458, 1458, 1458, 1500, 1500, 1500, 1500, + 1500, 1500, 1500, 1500, 1500, 1500, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1536, 1600, 1600, + 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1600, 1620, 1620, 1620, 1620, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, + 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1728, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, + 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1800, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, + 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1875, 1920, 1920, 1920, 1920, 1920, 1920, 1920, + 1920, 1920, 1920, 1944, 1944, 1944, 1944, 1944, 1944, 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2000, 2000, 2025, 2025, 2025, 2025, 2025, 2025, 2048, 2048, 2048, 2048, 2048, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, + 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2160, 2187, 2187, 2187, 2187, 2187, 2187, 2250, 2250, + 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2250, 2304, 2304, 2304, 2304, + 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2304, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, + 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2400, 2430, 2430, + 2430, 2430, 2430, 2430, 2430, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, 2500, + 2500, 2500, 2500, 2500, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, 2560, + 2560, 2592, 2592, 2592, 2592, 2592, 2592, 2592, 2592, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, + 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, 2700, + 2700, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, + 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2880, 2916, 2916, 2916, 2916, 2916, 2916, 2916, + 2916, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, + 3000, 3000, 3000, 3000, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, 3072, + 3072, 3072, 3072, 3072, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, 3125, + 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, 3200, + 3200, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3240, 3375, 3375, 3375, 3375, 3375, 3375, 3375, + 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, + 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3375, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, + 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3456, 3600, 3600, 3600, 3600, 3600, 3600, + 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, + 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3600, 3645, 3645, 3645, 3645, 3645, 3645, + 3645, 3645, 3645, 3645, 3645, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, + 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3750, 3840, 3840, 3840, 3840, + 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, 3840, + 3840, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 3888, 4000, 4000, 4000, 4000, + 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, + 4000, 4000, 4000, 4000, 4000, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, + 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, + 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4320, 4374, 4374, + 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4374, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4500, + 4500, 4500, 4500, 4500, 4500, 4500, 4500, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, + 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4608, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4860, 4860, 4860, 4860, 4860, 4860, 5000, 5000, 5000, 5000, + 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5000, 5120, 5120, 5120, 5120, + 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5120, 5184, 5184, 5184, 5184, 5184, 5184, 5184, 5400, + 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5400, + 5400, 5400, 5400, 5400, 5400, 5400, 5400, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, + 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, 5625, + 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5760, 5832, + 5832, 5832, 5832, 5832, 5832, 5832, 5832, 5832, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, + 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6075, 6075, 6075, 6075, 6075, + 6075, 6075, 6075, 6075, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6144, 6250, 6250, 6250, 6250, 6250, + 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6250, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, + 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6400, 6480, 6480, 6480, 6480, 6480, 6480, + 6480, 6480, 6480, 6480, 6480, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6561, 6750, 6750, 6750, + 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, 6750, + 6750, 6750, 6750, 6750, 6750, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, + 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 6912, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, + 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7200, 7290, 7290, 7290, 7290, + 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7290, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, + 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, 7500, + 7500, 7500, 7500, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, + 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7680, 7776, 7776, 7776, 7776, 7776, 7776, + 7776, 7776, 7776, 7776, 7776, 7776, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, 8000, + 8000, 8000, 8000, 8000, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, 8100, + 8100, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8640, 8640, 8640, 8640, + 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, + 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, + 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, + 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8640, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, + 8748, 8748, 8748, 8748, 8748, 8748, 8748, 8748, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, + 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, + 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9000, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, + 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, 9216, + 9216, 9216, 9216, 9216, 9216, 9216, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, + 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9375, 9600, 9600, 9600, 9600, + 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, + 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9600, 9720, 9720, 9720, 9720, 9720, 9720, + 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 9720, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, + 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10000, 10125, 10125, 10125, 10125, 10125, 10125, 10125, + 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10125, 10240, 10240, 10240, + 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, 10240, + 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, 10368, + 10368, 10368, 10368, 10368, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, + 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10800, 10935, 10935, 10935, 10935, 10935, 10935, + 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, 10935, + 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, + 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, + 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, 11250, + 11250, 11250, 11250, 11250, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, + 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, + 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, 11520, + 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, + 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 11664, 12000, 12000, 12000, 12000, 12000, 12000, + 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, + 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, + 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, 12000, + 12000, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, + 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12150, 12288, 12288, 12288, 12288, + 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, + 12288, 12288, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, + 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, 12500, + 12500, 12500, 12500, 12500, 12500, 12500, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, + 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, + 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, + 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12800, 12960, 12960, 12960, 12960, 12960, 12960, + 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, 12960, + 12960, 12960, 12960, 12960, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, + 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, 13122, + 13122, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, 13500, + 13500, 13500, 13500, 13500, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, + 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, + 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, + 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 13824, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, 14400, + 14400, 14400, 14400, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, + 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, 14580, + 14580, 14580, 14580, 14580, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, + 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15000, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, 15360, + 15360, 15360, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, + 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, 15552, + 15552, 15552, 15552, 15552, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, 15625, + 15625, 15625, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16000, + 16000, 16000, 16000, 16000, 16000, 16000, 16000, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, + 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, + 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16200, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, 16384, + 16384, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, + 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, + 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, + 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, + 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, + 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 16875, 17280, 17280, + 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, + 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, + 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, + 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, + 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17280, 17496, 17496, 17496, 17496, 17496, + 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, + 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, 17496, + 17496, 17496, 17496, 17496, 17496, 17496, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, + 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, + 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, + 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, + 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, + 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, + 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18000, 18225, 18225, 18225, 18225, 18225, 18225, 18225, + 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, + 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, 18225, + 18225, 18225, 18225, 18225, 18225, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, + 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, + 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18750, 18750, 18750, + 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, + 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, + 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, + 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 18750, 19200, 19200, + 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, + 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, + 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, + 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, + 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, + 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19200, 19440, 19440, 19440, 19440, 19440, 19440, 19440, + 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, + 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, + 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19440, 19683, 19683, 19683, 19683, 19683, + 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, + 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, + 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 19683, 20000, 20000, + 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, + 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, + 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, + 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20000, 20250, + 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, + 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, + 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, 20250, + 20250, 20250, 20250, 20250, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, + 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, + 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480, + 20480, 20480, 20480, 20480, 20480, 20480, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, + 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, + 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, + 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 20736, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, + 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21600, 21870, 21870, 21870, 21870, + 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, + 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, + 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, + 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 21870, 22500, 22500, 22500, 22500, 22500, 22500, + 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, + 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, + 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, + 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, + 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, + 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, + 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, + 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, + 22500, 22500, 22500, 22500, 22500, 22500, 22500, 22500, 23040, 23040, 23040, 23040, 23040, 23040, 23040, + 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, + 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, + 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, + 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, + 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, + 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, + 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, + 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23040, 23328, 23328, 23328, 23328, 23328, 23328, + 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, + 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, + 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, + 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 23328, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, 24000, + 24000, 24000, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, + 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, + 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, + 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, + 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, 24300, + 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, + 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, + 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, + 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, 24576, + 24576, 24576, 24576, 24576, 24576, 24576, 24576, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, + 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, + 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, + 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, + 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, + 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, + 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, 25000, + 25000, 25000, 25000, 25000, 25000, 25000, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, + 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25600, 25920, 25920, 25920, 25920, 25920, 25920, 25920, + 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, + 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, + 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, + 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, + 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, 25920, + 25920, 25920, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, + 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, + 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, + 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, + 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, + 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, 26244, + 26244, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, 27000, + 27000, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, 27648, + 27648, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, 28125, + 28125, 28125, 28125, 28125, 28125, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, + 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 28800, 29160, + 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, + 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, + 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, + 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, + 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, + 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, + 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, + 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, + 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 29160, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30000, + 30000, 30000, 30000, 30000, 30000, 30000, 30000, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, 30375, + 30375, 30375, 30375, 30375, 30375, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, + 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, 31104, + 31104, 31104, 31104, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, + 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, + 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, + 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, + 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, + 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, + 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, 31250, + 31250, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, 32000, + 32000 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N96.cc b/src/atlas/grid/detail/pl/classic_gaussian/N96.cc index ad4af3608..6f8a5aa4f 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N96.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N96.cc @@ -8,108 +8,15 @@ namespace detail { namespace pl { namespace classic_gaussian { -DEFINE_POINTS_PER_LATITUDE(96, LIST( - 18, - 25, - 36, - 40, - 45, - 50, - 60, - 64, - 72, - 72, - 80, - 90, - 96, - 100, - 108, - 120, - 120, - 125, - 135, - 144, - 144, - 150, - 160, - 160, - 180, - 180, - 180, - 192, - 192, - 200, - 200, - 216, - 216, - 225, - 225, - 240, - 240, - 240, - 250, - 250, - 256, - 270, - 270, - 270, - 288, - 288, - 288, - 288, - 300, - 300, - 300, - 320, - 320, - 320, - 320, - 320, - 324, - 360, - 360, - 360, - 360, - 360, - 360, - 360, - 360, - 360, - 360, - 360, - 375, - 375, - 375, - 375, - 375, - 375, - 375, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384, - 384 -)) +DEFINE_POINTS_PER_LATITUDE( 96, LIST( 18, 25, 36, 40, 45, 50, 60, 64, 72, 72, 80, 90, 96, 100, 108, 120, 120, 125, 135, + 144, 144, 150, 160, 160, 180, 180, 180, 192, 192, 200, 200, 216, 216, 225, 225, + 240, 240, 240, 250, 250, 256, 270, 270, 270, 288, 288, 288, 288, 300, 300, 300, + 320, 320, 320, 320, 320, 324, 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, + 360, 375, 375, 375, 375, 375, 375, 375, 384, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384 ) ) } // namespace classic_gaussian } // namespace pl } // namespace detail } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc index 02726e550..271b3d20b 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -28,27 +29,25 @@ namespace classic_gaussian { //----------------------------------------------------------------------------- -void points_per_latitude_npole_equator (const size_t N, long nlon[]) { +void points_per_latitude_npole_equator( const size_t N, long nlon[] ) { std::stringstream Nstream; Nstream << N; std::string Nstr = Nstream.str(); - if( Factory::instance().exists(Nstr) ) { - ScopedPtr pl ( - Factory::instance().get(Nstr).create() ); - pl->assign(nlon,N); - } else { - throw eckit::BadParameter( - "gaussian::classic::PointsPerLatitude not available for N"+Nstr, - Here()); + if ( Factory::instance().exists( Nstr ) ) { + ScopedPtr pl( Factory::instance().get( Nstr ).create() ); + pl->assign( nlon, N ); + } + else { + throw eckit::BadParameter( "gaussian::classic::PointsPerLatitude not available for N" + Nstr, Here() ); } } //----------------------------------------------------------------------------- -void points_per_latitude_npole_spole (const size_t N, long nlon[]) { - points_per_latitude_npole_equator(N,nlon); - size_t end = 2*N-1; - for(size_t jlat=0; jlat - namespace atlas { namespace grid { namespace detail { namespace pl { namespace classic_gaussian { - /** * @brief Compute points per latitude between North pole and equator - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @param N [in] Number of latitudes between pole and equator (Gaussian N + * number) * @param nlon [out] points per latitude */ -void points_per_latitude_npole_equator (const size_t N, long nlon[]); - +void points_per_latitude_npole_equator( const size_t N, long nlon[] ); /** * @brief Compute points per latitude between North pole and South pole - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @param N [in] Number of latitudes between pole and equator (Gaussian N + * number) * @param nlon [out] points per latitude (size 2*N) */ -void points_per_latitude_npole_spole (const size_t N, long nlon[]); - +void points_per_latitude_npole_spole( const size_t N, long nlon[] ); } // namespace classic_gaussian } // namespace pl diff --git a/src/atlas/grid/detail/spacing/CustomSpacing.cc b/src/atlas/grid/detail/spacing/CustomSpacing.cc index 28fd46f56..4b8f189f8 100644 --- a/src/atlas/grid/detail/spacing/CustomSpacing.cc +++ b/src/atlas/grid/detail/spacing/CustomSpacing.cc @@ -1,5 +1,5 @@ -#include #include "atlas/grid/detail/spacing/CustomSpacing.h" +#include #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" @@ -7,51 +7,44 @@ namespace atlas { namespace grid { namespace spacing { -CustomSpacing::CustomSpacing(long N, const double values[], const Interval& interval) { - - x_.assign(values,values+N); - min_ = std::min(interval[0],interval[1]); - max_ = std::max(interval[0],interval[1]); +CustomSpacing::CustomSpacing( long N, const double values[], const Interval& interval ) { + x_.assign( values, values + N ); + min_ = std::min( interval[0], interval[1] ); + max_ = std::max( interval[0], interval[1] ); } -CustomSpacing::CustomSpacing(const eckit::Parametrisation& params) { - - params.get("values",x_); - - size_t N; - if( params.get("N",N) ) { - ASSERT( x_.size() == N ); - } - N = x_.size(); +CustomSpacing::CustomSpacing( const eckit::Parametrisation& params ) { + params.get( "values", x_ ); - std::vector interval; - if( params.get("interval",interval) ) { + size_t N; + if ( params.get( "N", N ) ) { ASSERT( x_.size() == N ); } + N = x_.size(); - min_ = std::min(interval[0],interval[1]); - max_ = std::max(interval[0],interval[1]); - - } else { - - min_ = x_.front(); - max_ = x_.front(); - for( size_t j=1; j interval; + if ( params.get( "interval", interval ) ) { + min_ = std::min( interval[0], interval[1] ); + max_ = std::max( interval[0], interval[1] ); + } + else { + min_ = x_.front(); + max_ = x_.front(); + for ( size_t j = 1; j < N; ++j ) { + min_ = std::min( min_, x_[j] ); + max_ = std::max( max_, x_[j] ); + } } - } } CustomSpacing::Spec CustomSpacing::spec() const { - Spec spacing_specs; - spacing_specs.set("type",static_type()); - spacing_specs.set("values",x_); - spacing_specs.set("interval", std::vector{min(),max()}); - return spacing_specs; + Spec spacing_specs; + spacing_specs.set( "type", static_type() ); + spacing_specs.set( "values", x_ ); + spacing_specs.set( "interval", std::vector{min(), max()} ); + return spacing_specs; } -register_BuilderT1(Spacing,CustomSpacing,CustomSpacing::static_type()); +register_BuilderT1( Spacing, CustomSpacing, CustomSpacing::static_type() ); } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/CustomSpacing.h b/src/atlas/grid/detail/spacing/CustomSpacing.h index 2ed791049..0919d8d5b 100644 --- a/src/atlas/grid/detail/spacing/CustomSpacing.h +++ b/src/atlas/grid/detail/spacing/CustomSpacing.h @@ -13,36 +13,41 @@ namespace spacing { /// /// Using the constructor CustomSpacing( N, x[], {min,max} ) we can create /// -/// CustomSpacing( 4, {75,25,-25,-75} ) --> { 75 , 25 , -25 , -75 } -/// CustomSpacing( 4, {75,25,-25,-75}, {-90,90} ) --> { 75 , 25 , -25 , -75 } +/// CustomSpacing( 4, {75,25,-25,-75} ) --> { 75 , 25 , -25 +/// , -75 } +/// CustomSpacing( 4, {75,25,-25,-75}, {-90,90} ) --> { 75 , 25 , -25 +/// , -75 } /// -/// The optional argument {min,max} serves as purpose to indicate that the points -/// lie in the open interval (min,max). If not specified, the default values are taken +/// The optional argument {min,max} serves as purpose to indicate that the +/// points +/// lie in the open interval (min,max). If not specified, the default values are +/// taken /// to be the North and South pole's latitudes. /// /// Configuration parameters can be passed as well with following keys: /// -/// {"N":4, "values":[75,25,-25,75] } --> { 75 , 25 , -25 , -75 } -/// {"N":4, "values":[75,25,-25,75], "interval":[-90,90] } --> { 75 , 25 , -25 , -75 } +/// {"N":4, "values":[75,25,-25,75] } --> { 75 , 25 , +/// -25 , -75 } +/// {"N":4, "values":[75,25,-25,75], "interval":[-90,90] } --> { 75 , 25 , +/// -25 , -75 } -class CustomSpacing: public Spacing { +class CustomSpacing : public Spacing { private: - using Interval = std::array; - static constexpr double North() { return 90.; } + using Interval = std::array; + static constexpr double North() { return 90.; } static constexpr double South() { return -90.; } -public: +public: // constructor - CustomSpacing(const eckit::Parametrisation& p); + CustomSpacing( const eckit::Parametrisation& p ); - CustomSpacing(long N, const double x[], const Interval& = {North(),South()} ); + CustomSpacing( long N, const double x[], const Interval& = {North(), South()} ); // class name - static std::string static_type() {return "custom";} - virtual std::string type() const {return static_type();} - - virtual Spec spec() const; + static std::string static_type() { return "custom"; } + virtual std::string type() const { return static_type(); } + virtual Spec spec() const; }; } // namespace spacing diff --git a/src/atlas/grid/detail/spacing/FocusSpacing.cc b/src/atlas/grid/detail/spacing/FocusSpacing.cc index 032859371..a2906230d 100644 --- a/src/atlas/grid/detail/spacing/FocusSpacing.cc +++ b/src/atlas/grid/detail/spacing/FocusSpacing.cc @@ -1,5 +1,5 @@ -#include #include "atlas/grid/detail/spacing/FocusSpacing.h" +#include #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" @@ -7,57 +7,53 @@ namespace atlas { namespace grid { namespace spacing { -FocusSpacing::FocusSpacing(const eckit::Parametrisation& params) { - - double xmin; - double xmax; - long N; - - // retrieve xmin, xmax and N from params - if ( !params.get("start",xmin) ) throw eckit::BadParameter("start missing in Params",Here()); - if ( !params.get("end",xmax) ) throw eckit::BadParameter("end missing in Params",Here()); - if ( !params.get("N", N ) ) throw eckit::BadParameter("N missing in Params", Here()); - - // additional parameters for focus spacing - if( ! params.get("focus_factor",focus_factor_) ) - throw eckit::BadParameter("focus_factor missing in Params",Here()); - - x_.resize(N); - if (N==1) { - x_[0] = 0.5*(xmin+xmax); - } else { - const double midpoint = 0.5*(xmin+xmax); - const double d2 = 2./double(N-1); - const double c1 = (xmax-xmin)*M_1_PI; - const double c2 = 1./focus_factor_; - x_[0] = xmin; - x_[N-1] = xmax; - for( long i=1; i interval; - if( params.get("interval",interval) ) { - start = interval[0]; - end = interval[1]; - } - if( start!=90. && end!=-90. ) { - NOTIMP; - } - - min_ = std::min(start,end); - max_ = std::max(start,end); - +GaussianSpacing::GaussianSpacing( const eckit::Parametrisation& params ) { + // retrieve N from params + long N; + if ( !params.get( "N", N ) ) throw eckit::BadParameter( "N missing in Params", Here() ); + + // perform checks + ASSERT( N % 2 == 0 ); + + // initialize latitudes during setup, to avoid repeating it. + x_.resize( N ); + gaussian::gaussian_latitudes_npole_spole( N / 2, x_.data() ); + + // Not yet implemented: specify different bounds or direction (e.g from south + // to north pole) + double start = 90.; + double end = -90.; + params.get( "start", start ); + params.get( "end", end ); + + std::vector interval; + if ( params.get( "interval", interval ) ) { + start = interval[0]; + end = interval[1]; + } + if ( start != 90. && end != -90. ) { NOTIMP; } + + min_ = std::min( start, end ); + max_ = std::max( start, end ); } GaussianSpacing::Spec GaussianSpacing::spec() const { - Spec spacing_specs; - spacing_specs.set("type",static_type()); - spacing_specs.set("N",size()); - return spacing_specs; + Spec spacing_specs; + spacing_specs.set( "type", static_type() ); + spacing_specs.set( "N", size() ); + return spacing_specs; } -register_BuilderT1(Spacing,GaussianSpacing,GaussianSpacing::static_type()); +register_BuilderT1( Spacing, GaussianSpacing, GaussianSpacing::static_type() ); } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/GaussianSpacing.h b/src/atlas/grid/detail/spacing/GaussianSpacing.h index 4568c55cc..303c87b8c 100644 --- a/src/atlas/grid/detail/spacing/GaussianSpacing.h +++ b/src/atlas/grid/detail/spacing/GaussianSpacing.h @@ -7,44 +7,43 @@ namespace atlas { namespace grid { namespace spacing { - /// @brief Gaussian spacing in interval /// /// There are N Gaussian spaced points in the open interval (90, -90) /// /// Using the constructor GaussianSpacing( N ) we can create /// -/// Gaussian( 4 ) --> { 59.44... , 19.87... , -19.87... , -59.44... } +/// Gaussian( 4 ) --> { 59.44... , 19.87... , +/// -19.87... , -59.44... } /// /// Configuration parameters can be passed as well with following keys: /// -/// {"N":4 } --> { 59.44... , 19.87... , -19.87... , -59.44... } +/// {"N":4 } --> { 59.44... , 19.87... , +/// -19.87... , -59.44... } /// -/// To reverse the orientation of points to go from negative to positive instead, pass also +/// To reverse the orientation of points to go from negative to positive +/// instead, pass also /// the start and end keys: /// -/// {"N":4, "start":-90, "end":90 } --> { -59.44... , -19.87... , 19.87... , 59.44... } - -class GaussianSpacing: public Spacing { +/// {"N":4, "start":-90, "end":90 } --> { -59.44... , -19.87... , +/// 19.87... , 59.44... } +class GaussianSpacing : public Spacing { public: - // constructor - GaussianSpacing(const eckit::Parametrisation& p); + GaussianSpacing( const eckit::Parametrisation& p ); - GaussianSpacing(long N); + GaussianSpacing( long N ); // class name - static std::string static_type() {return "gaussian";} - virtual std::string type() const {return static_type();} - - virtual Spec spec() const; + static std::string static_type() { return "gaussian"; } + virtual std::string type() const { return static_type(); } + virtual Spec spec() const; }; } // namespace spacing } // namespace grid } // namespace atlas - #endif diff --git a/src/atlas/grid/detail/spacing/LinearSpacing.cc b/src/atlas/grid/detail/spacing/LinearSpacing.cc index 7f15f4afc..45fc50b5b 100644 --- a/src/atlas/grid/detail/spacing/LinearSpacing.cc +++ b/src/atlas/grid/detail/spacing/LinearSpacing.cc @@ -1,5 +1,5 @@ -#include #include "atlas/grid/detail/spacing/LinearSpacing.h" +#include #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" @@ -7,58 +7,59 @@ namespace atlas { namespace grid { namespace spacing { - -LinearSpacing::Params::Params(const eckit::Parametrisation& params) { - endpoint = true; - params.get("endpoint", endpoint ); - std::vector interval; - // if( params.get("step",step) ) { - // - // // Several combinations possible: - // if( params.get("start",start) && params.get("end",end) ) { - // N = long( (end-start)/step ) + (endpoint ? 1 : 0 ); - // } else if( params.get("centre",centre) && params.get("N",N) ) { - // start = endpoint ? centre - step * 0.5*double(N-1) - // : centre - step * 0.5*double(N); - // end = endpoint ? start + step * double(N-1) : - // start + step * double(N); - // } else { - // throw eckit::BadParameter("Invalid combination of parameters",Here()); - // } - // } - // else - if( params.get("N",N) ) { - // Only one remaining combinations possible: - if( params.get("start",start) && params.get("end",end) ) { - // OK - } else if( params.get("interval",interval) ) { - start = interval[0]; - end = interval[1]; +LinearSpacing::Params::Params( const eckit::Parametrisation& params ) { + endpoint = true; + params.get( "endpoint", endpoint ); + std::vector interval; + // if( params.get("step",step) ) { + // + // // Several combinations possible: + // if( params.get("start",start) && params.get("end",end) ) { + // N = long( (end-start)/step ) + (endpoint ? 1 : 0 ); + // } else if( params.get("centre",centre) && params.get("N",N) ) { + // start = endpoint ? centre - step * 0.5*double(N-1) + // : centre - step * 0.5*double(N); + // end = endpoint ? start + step * double(N-1) : + // start + step * double(N); + // } else { + // throw eckit::BadParameter("Invalid combination of parameters",Here()); + // } + // } + // else + if ( params.get( "N", N ) ) { + // Only one remaining combinations possible: + if ( params.get( "start", start ) && params.get( "end", end ) ) { + // OK + } + else if ( params.get( "interval", interval ) ) { + start = interval[0]; + end = interval[1]; + } + else if ( params.get( "start", start ) && params.get( "length", length ) ) { + end = start + length; + } + else { + throw eckit::BadParameter( "Invalid combination of parameters", Here() ); + } } - else if( params.get("start",start) && params.get("length",length) ) { - end = start + length; - } else { - throw eckit::BadParameter("Invalid combination of parameters",Here()); + else { + throw eckit::BadParameter( "Invalid combination of parameters", Here() ); } - } - else { - throw eckit::BadParameter("Invalid combination of parameters",Here()); - } - length = end - start; - - if( endpoint && N>1 ) - step = length/double(N-1); - else - step = length/double(N); -} + length = end - start; + if ( endpoint && N > 1 ) + step = length / double( N - 1 ); + else + step = length / double( N ); +} -LinearSpacing::LinearSpacing(const eckit::Parametrisation& params) { - Params p(params); - setup(p.start,p.end,p.N,p.endpoint); +LinearSpacing::LinearSpacing( const eckit::Parametrisation& params ) { + Params p( params ); + setup( p.start, p.end, p.N, p.endpoint ); } -// LinearSpacing::LinearSpacing( double centre, double step, long N, bool endpoint ) { +// LinearSpacing::LinearSpacing( double centre, double step, long N, bool +// endpoint ) { // double start = endpoint ? centre - step * double(N-1)/2. : // centre - step * double(N)/2.; // double end = endpoint ? start + step * double(N-1) : @@ -67,62 +68,58 @@ LinearSpacing::LinearSpacing(const eckit::Parametrisation& params) { // } LinearSpacing::LinearSpacing( double start, double end, long N, bool endpoint ) { - setup(start,end,N,endpoint); + setup( start, end, N, endpoint ); } LinearSpacing::LinearSpacing( const Interval& interval, long N, bool endpoint ) { - setup(interval[0],interval[1],N,endpoint); + setup( interval[0], interval[1], N, endpoint ); } +void LinearSpacing::setup( double start, double end, long N, bool endpoint ) { + x_.resize( N ); -void LinearSpacing::setup(double start, double end, long N, bool endpoint) { + double step; + if ( endpoint && N > 1 ) + step = ( end - start ) / double( N - 1 ); + else + step = ( end - start ) / double( N ); - x_.resize(N); - - double step; - if( endpoint && N>1 ) - step = (end-start)/double(N-1); - else - step = (end-start)/double(N); - - for( long i=0; i1 ) - return x_[1]-x_[0]; - else - return 0.; + if ( size() > 1 ) + return x_[1] - x_[0]; + else + return 0.; } bool LinearSpacing::endpoint() const { - return std::abs(x_.back()-max_)<1.e-12; + return std::abs( x_.back() - max_ ) < 1.e-12; } LinearSpacing::Spec LinearSpacing::spec() const { - Spec spacing_specs; - spacing_specs.set("type",static_type()); - spacing_specs.set("start",start_); - spacing_specs.set("end",end_); - spacing_specs.set("N",N_); - spacing_specs.set("endpoint",endpoint_); - return spacing_specs; + Spec spacing_specs; + spacing_specs.set( "type", static_type() ); + spacing_specs.set( "start", start_ ); + spacing_specs.set( "end", end_ ); + spacing_specs.set( "N", N_ ); + spacing_specs.set( "endpoint", endpoint_ ); + return spacing_specs; } - -register_BuilderT1(Spacing,LinearSpacing,LinearSpacing::static_type()); +register_BuilderT1( Spacing, LinearSpacing, LinearSpacing::static_type() ); } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/LinearSpacing.h b/src/atlas/grid/detail/spacing/LinearSpacing.h index 290feb46b..d622e7b4d 100644 --- a/src/atlas/grid/detail/spacing/LinearSpacing.h +++ b/src/atlas/grid/detail/spacing/LinearSpacing.h @@ -9,43 +9,48 @@ namespace spacing { /// @brief Linear spacing in interval /// -/// There are N equally spaced points in the closed interval [start, stop] or the -/// half-open interval [start, stop) (depending on whether endpoint is True or False) +/// There are N equally spaced points in the closed interval [start, stop] or +/// the +/// half-open interval [start, stop) (depending on whether endpoint is True or +/// False) /// /// Using the constructor LinearSpacing( start, end, N, endpoint ) we can create /// -/// LinearSpacing( 2, 3, 5, true ) --> { 2.0 , 2.25 , 2.5 , 2.75 , 3.0 } -/// LinearSpacing( 2, 3, 5, false ) --> { 2.0 , 2.2 , 2.4 , 2.6 , 2.8 } +/// LinearSpacing( 2, 3, 5, true ) --> { 2.0 , 2.25 , +/// 2.5 , 2.75 , 3.0 } +/// LinearSpacing( 2, 3, 5, false ) --> { 2.0 , 2.2 , +/// 2.4 , 2.6 , 2.8 } /// /// Configuration parameters can be passed as well with following keys: /// -/// {"start":2 , "end":3, "N":5, "endpoint":true } --> { 2.0 , 2.25 , 2.5 , 2.75 , 3.0 } -/// {"start":2 , "end":3, "N":5, "endpoint":false} --> { 2.0 , 2.2 , 2.4 , 2.6 , 2.8 } +/// {"start":2 , "end":3, "N":5, "endpoint":true } --> { 2.0 , 2.25 , 2.5 +/// , 2.75 , 3.0 } +/// {"start":2 , "end":3, "N":5, "endpoint":false} --> { 2.0 , 2.2 , 2.4 +/// , 2.6 , 2.8 } /// -/// Instead of the "end" key, you can provide the "length" key, to achieve the same results: +/// Instead of the "end" key, you can provide the "length" key, to achieve the +/// same results: /// -/// {"start":2 , "length":1, "N":5, "endpoint":true } --> { 2.0 , 2.25 , 2.5 , 2.75 , 3.0 } -/// {"start":2 , "length":1, "N":5, "endpoint":false} --> { 2.0 , 2.2 , 2.4 , 2.6 , 2.8 } - - -class LinearSpacing: public Spacing { - -public: - - using Interval = std::array; +/// {"start":2 , "length":1, "N":5, "endpoint":true } --> { 2.0 , 2.25 , 2.5 +/// , 2.75 , 3.0 } +/// {"start":2 , "length":1, "N":5, "endpoint":false} --> { 2.0 , 2.2 , 2.4 +/// , 2.6 , 2.8 } +class LinearSpacing : public Spacing { public: + using Interval = std::array; +public: /// constructor LinearSpacing( const eckit::Parametrisation& p ); - LinearSpacing( double start, double end, long N, bool endpoint=true ); - LinearSpacing( const Interval&, long N, bool endpoint=true ); + LinearSpacing( double start, double end, long N, bool endpoint = true ); + LinearSpacing( const Interval&, long N, bool endpoint = true ); // LinearSpacing( double centre, double step, long N, bool endpoint=true ); // class name - static std::string static_type() {return "linear";} - virtual std::string type() const {return static_type();} + static std::string static_type() { return "linear"; } + virtual std::string type() const { return static_type(); } double step() const; @@ -54,22 +59,20 @@ class LinearSpacing: public Spacing { virtual Spec spec() const; public: - struct Params { - double start; - double end; - long N; - double length; - bool endpoint; - double step; - Params(const eckit::Parametrisation& p); + double start; + double end; + long N; + double length; + bool endpoint; + double step; + Params( const eckit::Parametrisation& p ); }; protected: - // points are equally spaced between xmin and xmax // Depending on value of endpoint, the spacing will be different - void setup(double start, double end, long N, bool endpoint); + void setup( double start, double end, long N, bool endpoint ); double start_; double end_; diff --git a/src/atlas/grid/detail/spacing/Spacing.cc b/src/atlas/grid/detail/spacing/Spacing.cc index ea645edf7..28ce69f68 100644 --- a/src/atlas/grid/detail/spacing/Spacing.cc +++ b/src/atlas/grid/detail/spacing/Spacing.cc @@ -7,12 +7,12 @@ namespace atlas { namespace grid { namespace spacing { -Spacing* Spacing::create(const eckit::Parametrisation& params) { - std::string spacingType; - if (not params.get("type",spacingType) ) { - throw eckit::BadParameter("type missing in configuration",Here()); - } - return eckit::Factory::instance().get(spacingType).create(params); +Spacing* Spacing::create( const eckit::Parametrisation& params ) { + std::string spacingType; + if ( not params.get( "type", spacingType ) ) { + throw eckit::BadParameter( "type missing in configuration", Here() ); + } + return eckit::Factory::instance().get( spacingType ).create( params ); } } // namespace spacing diff --git a/src/atlas/grid/detail/spacing/Spacing.h b/src/atlas/grid/detail/spacing/Spacing.h index 29d21ecb8..51187caa4 100644 --- a/src/atlas/grid/detail/spacing/Spacing.h +++ b/src/atlas/grid/detail/spacing/Spacing.h @@ -1,13 +1,13 @@ #pragma once -#include #include +#include +#include "atlas/util/Config.h" #include "eckit/memory/Builder.h" #include "eckit/memory/Owned.h" -#include "atlas/util/Config.h" namespace eckit { - class Parametrisation; +class Parametrisation; } namespace atlas { @@ -15,48 +15,43 @@ namespace grid { namespace spacing { class Spacing : public eckit::Owned { - public: - using const_iterator = std::vector::const_iterator; - using Interval = std::array; - using Spec = atlas::util::Config; + using Interval = std::array; + using Spec = atlas::util::Config; using ARG1 = const eckit::Parametrisation&; using builder_t = eckit::BuilderT1; - static std::string className() {return "atlas.Spacing";} + static std::string className() { return "atlas.Spacing"; } public: + static Spacing* create( const eckit::Parametrisation& params ); - static Spacing* create(const eckit::Parametrisation& params); - - virtual std::string type() const =0; + virtual std::string type() const = 0; - double operator[](size_t i) const { return x_[i]; } + double operator[]( size_t i ) const { return x_[i]; } size_t size() const { return x_.size(); } const double* data() const { return x_.data(); } const_iterator begin() const { return x_.begin(); } - const_iterator end() const { return x_.end(); } + const_iterator end() const { return x_.end(); } double front() const { return x_.front(); } - double back() const { return x_.back(); } + double back() const { return x_.back(); } - Interval interval() const { return {{min_,max_}}; } + Interval interval() const { return {{min_, max_}}; } double min() const { return min_; } double max() const { return max_; } - - virtual Spec spec() const =0; -protected: + virtual Spec spec() const = 0; +protected: std::vector x_; double min_; double max_; - }; } // namespace spacing diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc index 1205b3f43..e1b6ae54d 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,15 +14,15 @@ #include -#include "eckit/memory/ScopedPtr.h" -#include "atlas/library/config.h" +#include "atlas/array.h" +#include "atlas/array/MakeView.h" #include "atlas/grid/detail/spacing/gaussian/Latitudes.h" #include "atlas/grid/detail/spacing/gaussian/N.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/util/Constants.h" +#include "atlas/library/config.h" #include "atlas/runtime/Log.h" -#include "atlas/array.h" -#include "atlas/array/MakeView.h" +#include "atlas/util/Constants.h" +#include "atlas/util/CoordinateEnums.h" +#include "eckit/memory/ScopedPtr.h" using eckit::ConcreteBuilderT0; using eckit::Factory; @@ -38,65 +39,60 @@ namespace gaussian { //----------------------------------------------------------------------------- -void compute_gaussian_quadrature_npole_equator(const size_t N, double lat[], double weights[]); +void compute_gaussian_quadrature_npole_equator( const size_t N, double lat[], double weights[] ); //----------------------------------------------------------------------------- -void gaussian_latitudes_npole_equator(const size_t N, double lats[]) { +void gaussian_latitudes_npole_equator( const size_t N, double lats[] ) { std::stringstream Nstream; Nstream << N; std::string Nstr = Nstream.str(); - if( Factory::instance().exists(Nstr) ) { - ScopedPtr gl ( - Factory::instance().get(Nstr).create() ); - gl->assign(lats,N); - } else { - std::vector weights(N); - compute_gaussian_quadrature_npole_equator(N,lats,weights.data()); + if ( Factory::instance().exists( Nstr ) ) { + ScopedPtr gl( Factory::instance().get( Nstr ).create() ); + gl->assign( lats, N ); + } + else { + std::vector weights( N ); + compute_gaussian_quadrature_npole_equator( N, lats, weights.data() ); } } //----------------------------------------------------------------------------- -void gaussian_latitudes_npole_spole(const size_t N, double lats[]) { - gaussian_latitudes_npole_equator(N,lats); - size_t end = 2*N-1; - for(size_t jlat=0; jlat(jn)*zdlx ); + zdlk += pfn[ik] * std::cos( static_cast( jn ) * zdlx ); // normalised derivative == d/d\theta(\overbar{P_n}^0) - zdlldn -= pfn[ik]*static_cast(jn)*std::sin( static_cast(jn)*zdlx ); + zdlldn -= pfn[ik] * static_cast( jn ) * std::sin( static_cast( jn ) * zdlx ); ++ik; } // Newton method - zdlmod = -zdlk/zdlldn; - zdlxn = zdlx+zdlmod; - pxn = zdlxn; - pxmod = zdlmod; + zdlmod = -zdlk / zdlldn; + zdlxn = zdlx + zdlmod; + pxn = zdlxn; + pxmod = zdlmod; } -void legpol_weight( - const int kn, - const double pfn[], - const double px, - double &pw ) { - //Routine to compute the quadrature weight of the legendre polynomial +void legpol_weight( const int kn, const double pfn[], const double px, double& pw ) { + // Routine to compute the quadrature weight of the legendre polynomial // Explicit arguments : // -------------------- @@ -158,29 +150,22 @@ void legpol_weight( int ik; int kodd = kn % 2; - zdlx = px; + zdlx = px; zdlldn = 0.; - ik=1; + ik = 1; // Compute weights // --------------- - for( int jn=2-kodd; jn<=kn; jn+=2 ) { - zdlldn -= pfn[ik]*static_cast(jn)*std::sin( static_cast(jn)*zdlx ); + for ( int jn = 2 - kodd; jn <= kn; jn += 2 ) { + zdlldn -= pfn[ik] * static_cast( jn ) * std::sin( static_cast( jn ) * zdlx ); ++ik; } - pw = static_cast (2*kn+1)/(zdlldn*zdlldn); + pw = static_cast( 2 * kn + 1 ) / ( zdlldn * zdlldn ); } - //----------------------------------------------------------------------------- -void legpol_quadrature( - const int kn, - const double pfn[], - double &pl, - double &pw, - int& kiter, - double &pmod ) { +void legpol_quadrature( const int kn, const double pfn[], double& pl, double& pw, int& kiter, double& pmod ) { //**** *GAWL * - Routine to perform the Newton loop // Purpose. @@ -210,31 +195,30 @@ void legpol_quadrature( // --------------- itemax = 20; - zx = pl; - iflag = 0; - pw = 0.; + zx = pl; + iflag = 0; + pw = 0.; //* 2. Newton iteration. // ----------------- const double zeps = std::numeric_limits::epsilon(); - for( int jter=1; jter<=itemax+1; ++jter) { + for ( int jter = 1; jter <= itemax + 1; ++jter ) { kiter = jter; - legpol_newton_iteration(kn,pfn,zx,zxn,pmod); + legpol_newton_iteration( kn, pfn, zx, zxn, pmod ); zx = zxn; - if( iflag == 1 ) { - legpol_weight(kn,pfn,zx,zw); + if ( iflag == 1 ) { + 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 ) { + if ( iflag != 1 ) { std::stringstream s; - s << "Could not converge gaussian latitude to accuracy ["< zfn_( kdgl + 1, kdgl + 1 ); + ArrayView zfn = make_view( zfn_ ); - int kdgl = 2*N; - array::ArrayT zfn_(kdgl+1,kdgl+1); - ArrayView zfn = make_view(zfn_); - int iodd; // Belousov, Swarztrauber use zfn(0,0)=std::sqrt(2.) // IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 - zfn(0,0) = 2.; - for( int jn=1; jn<=kdgl; ++jn ) { - double zfnn = zfn(0,0); - for( int jgl=1; jgl<=jn; ++jgl) { - zfnn *= std::sqrt(1.-0.25/(static_cast(jgl*jgl))); + zfn( 0, 0 ) = 2.; + for ( int jn = 1; jn <= kdgl; ++jn ) { + double zfnn = zfn( 0, 0 ); + for ( int jgl = 1; jgl <= jn; ++jgl ) { + zfnn *= std::sqrt( 1. - 0.25 / ( static_cast( jgl * jgl ) ) ); } - iodd = jn % 2; - zfn(jn,jn)=zfnn; - for( int jgl=2; jgl<=jn-iodd; jgl+=2 ) { - zfn(jn,jn-jgl) = zfn(jn,jn-jgl+2) * - static_cast ((jgl-1)*(2*jn-jgl+2)) / - static_cast (jgl*(2*jn-jgl+1)); + iodd = jn % 2; + zfn( jn, jn ) = zfnn; + for ( int jgl = 2; jgl <= jn - iodd; jgl += 2 ) { + zfn( jn, jn - jgl ) = zfn( jn, jn - jgl + 2 ) * static_cast( ( jgl - 1 ) * ( 2 * jn - jgl + 2 ) ) / + static_cast( jgl * ( 2 * jn - jgl + 1 ) ); } } - iodd = kdgl % 2; + iodd = kdgl % 2; int ik = iodd; - std::vector zzfn(N+1); - std::vector zmod(kdgl); - std::vector iter(kdgl); + std::vector zzfn( N + 1 ); + std::vector zmod( kdgl ); + std::vector iter( kdgl ); - for( int jgl=iodd; jgl<=kdgl; jgl+=2 ) { - zzfn[ik] = zfn(kdgl,jgl); + for ( int jgl = iodd; jgl <= kdgl; jgl += 2 ) { + zzfn[ik] = zfn( kdgl, jgl ); ++ik; } const double pole = 90.; - for( size_t jgl=0; jgl - namespace atlas { namespace grid { namespace spacing { namespace gaussian { - /** * @brief Compute gaussian latitudes between North pole and equator - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @param N [in] Number of latitudes between pole and equator (Gaussian + * N number) * @param latitudes [out] latitudes in degrees */ -void gaussian_latitudes_npole_equator(const size_t N, double latitudes[]); - +void gaussian_latitudes_npole_equator( const size_t N, double latitudes[] ); /** - * @brief Compute gaussian latitudes and quadrature weights between North pole and equator - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @brief Compute gaussian latitudes and quadrature weights between North pole + * and equator + * @param N [in] Number of latitudes between pole and equator (Gaussian + * N number) * @param latitudes [out] latitudes in degrees * @param weights [out] quadrature weights */ -void gaussian_quadrature_npole_equator(const size_t N, double latitudes[], double weights[]); - +void gaussian_quadrature_npole_equator( const size_t N, double latitudes[], double weights[] ); /** * @brief Compute gaussian latitudes between North pole and South pole - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @param N [in] Number of latitudes between pole and equator (Gaussian + * N number) * @param latitudes [out] latitudes in degrees (size 2*N) */ -void gaussian_latitudes_npole_spole(const size_t N, double latitudes[]); - +void gaussian_latitudes_npole_spole( const size_t N, double latitudes[] ); /** - * @brief Compute gaussian latitudes and quadrature weights between North pole and South pole - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @brief Compute gaussian latitudes and quadrature weights between North pole + * and South pole + * @param N [in] Number of latitudes between pole and equator (Gaussian + * N number) * @param latitudes [out] latitudes in degrees (size 2*N) * @param weights [out] quadrature weights (size 2*N) */ -void gaussian_quadrature_npole_spole (const size_t N, double latitudes[], double weights[]); - +void gaussian_quadrature_npole_spole( const size_t N, double latitudes[], double weights[] ); } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - #endif - diff --git a/src/atlas/grid/detail/spacing/gaussian/N.cc b/src/atlas/grid/detail/spacing/gaussian/N.cc index 362de91d4..e4e116f94 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N.cc @@ -4,46 +4,40 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @author Willem Deconinck /// @date Jan 2015 - #include "atlas/grid/detail/spacing/gaussian/N.h" - namespace atlas { namespace grid { namespace spacing { namespace gaussian { - std::string GaussianLatitudes::className() { return "GaussianLatitudes"; } - -void GaussianLatitudes::assign(double lats[], const size_t size) const { +void GaussianLatitudes::assign( double lats[], const size_t size ) const { 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 { +void GaussianLatitudes::assign( std::vector& lats ) const { lats = lats_; } - -template +template void load() { - eckit::ConcreteBuilderT0 builder("tmp"); + eckit::ConcreteBuilderT0 builder( "tmp" ); } - void regist() { load(); load(); @@ -70,9 +64,7 @@ void regist() { load(); } - } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N.h b/src/atlas/grid/detail/spacing/gaussian/N.h index 8070fcdd4..9c5a4766d 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N.h +++ b/src/atlas/grid/detail/spacing/gaussian/N.h @@ -4,99 +4,89 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @author Willem Deconinck /// @date Nov 2014 - #ifndef atlas_grid_spacing_gaussian_N_h #define atlas_grid_spacing_gaussian_N_h #include "eckit/memory/Builder.h" #include "eckit/memory/Owned.h" - namespace atlas { namespace grid { namespace spacing { namespace gaussian { - class GaussianLatitudes : public eckit::Owned { - - public: - +public: typedef eckit::BuilderT0 builder_t; static std::string className(); /// @pre nlats has enough allocated memory to store the latitudes /// @param size of lats vector - void assign(double lats[], const size_t size) const; + void assign( double lats[], const size_t size ) const; /// @post resizes the vector to the number of latitutes - void assign(std::vector& lats) const; - - size_t N() const { - return lats_.size(); - } + void assign( std::vector& lats ) const; - protected: + size_t N() const { return lats_.size(); } +protected: std::vector lats_; - }; +#define DECLARE_GAUSSIAN_LATITUDES( NUMBER ) \ + class N##NUMBER : public GaussianLatitudes { \ + public: \ + N##NUMBER(); \ + }; + +#define LIST( ... ) __VA_ARGS__ +#define DEFINE_GAUSSIAN_LATITUDES( NUMBER, LATS ) \ + eckit::ConcreteBuilderT0 builder_N##NUMBER( #NUMBER ); \ + \ + N##NUMBER::N##NUMBER() { \ + size_t N = NUMBER; \ + double lat[] = {LATS}; \ + lats_.assign( lat, lat + N ); \ + } -#define DECLARE_GAUSSIAN_LATITUDES(NUMBER) \ - class N##NUMBER : public GaussianLatitudes { public: N##NUMBER(); }; - -#define LIST(...) __VA_ARGS__ -#define DEFINE_GAUSSIAN_LATITUDES(NUMBER,LATS) \ - eckit::ConcreteBuilderT0 builder_N##NUMBER(#NUMBER); \ - \ - N##NUMBER::N##NUMBER()\ - {\ - size_t N = NUMBER;\ - double lat[] = {LATS} ;\ - lats_.assign(lat,lat+N);\ - }\ - -DECLARE_GAUSSIAN_LATITUDES(16); -DECLARE_GAUSSIAN_LATITUDES(24); -DECLARE_GAUSSIAN_LATITUDES(32); -DECLARE_GAUSSIAN_LATITUDES(48); -DECLARE_GAUSSIAN_LATITUDES(64); -DECLARE_GAUSSIAN_LATITUDES(80); -DECLARE_GAUSSIAN_LATITUDES(96); -DECLARE_GAUSSIAN_LATITUDES(128); -DECLARE_GAUSSIAN_LATITUDES(160); -DECLARE_GAUSSIAN_LATITUDES(200); -DECLARE_GAUSSIAN_LATITUDES(256); -DECLARE_GAUSSIAN_LATITUDES(320); -DECLARE_GAUSSIAN_LATITUDES(400); -DECLARE_GAUSSIAN_LATITUDES(512); -DECLARE_GAUSSIAN_LATITUDES(576); -DECLARE_GAUSSIAN_LATITUDES(640); -DECLARE_GAUSSIAN_LATITUDES(800); -DECLARE_GAUSSIAN_LATITUDES(1024); -DECLARE_GAUSSIAN_LATITUDES(1280); -DECLARE_GAUSSIAN_LATITUDES(1600); -DECLARE_GAUSSIAN_LATITUDES(2000); -DECLARE_GAUSSIAN_LATITUDES(4000); -DECLARE_GAUSSIAN_LATITUDES(8000); - +DECLARE_GAUSSIAN_LATITUDES( 16 ); +DECLARE_GAUSSIAN_LATITUDES( 24 ); +DECLARE_GAUSSIAN_LATITUDES( 32 ); +DECLARE_GAUSSIAN_LATITUDES( 48 ); +DECLARE_GAUSSIAN_LATITUDES( 64 ); +DECLARE_GAUSSIAN_LATITUDES( 80 ); +DECLARE_GAUSSIAN_LATITUDES( 96 ); +DECLARE_GAUSSIAN_LATITUDES( 128 ); +DECLARE_GAUSSIAN_LATITUDES( 160 ); +DECLARE_GAUSSIAN_LATITUDES( 200 ); +DECLARE_GAUSSIAN_LATITUDES( 256 ); +DECLARE_GAUSSIAN_LATITUDES( 320 ); +DECLARE_GAUSSIAN_LATITUDES( 400 ); +DECLARE_GAUSSIAN_LATITUDES( 512 ); +DECLARE_GAUSSIAN_LATITUDES( 576 ); +DECLARE_GAUSSIAN_LATITUDES( 640 ); +DECLARE_GAUSSIAN_LATITUDES( 800 ); +DECLARE_GAUSSIAN_LATITUDES( 1024 ); +DECLARE_GAUSSIAN_LATITUDES( 1280 ); +DECLARE_GAUSSIAN_LATITUDES( 1600 ); +DECLARE_GAUSSIAN_LATITUDES( 2000 ); +DECLARE_GAUSSIAN_LATITUDES( 4000 ); +DECLARE_GAUSSIAN_LATITUDES( 8000 ); #undef DECLARE_GAUSSIAN_LATITUDES - } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - #endif diff --git a/src/atlas/grid/detail/spacing/gaussian/N1024.cc b/src/atlas/grid/detail/spacing/gaussian/N1024.cc index d209597d5..bc2ba3366 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N1024.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N1024.cc @@ -7,216 +7,180 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(1024, LIST( - 89.932737928460, 89.845605479540, 89.757958466419, 89.670195191296, 89.582387815250, - 89.494559098662, 89.406718455753, 89.318870478120, 89.231017670122, 89.143161513177, - 89.055302939412, 88.967442564544, 88.879580811588, 88.791717980751, 88.703854290968, - 88.615989905657, 88.528124949263, 88.440259518219, 88.352393688409, 88.264527520359, - 88.176661062939, 88.088794356040, 88.000927432542, 87.913060319791, 87.825193040716, - 87.737325614688, 87.649458058179, 87.561590385292, 87.473722608166, 87.385854737308, - 87.297986781862, 87.210118749818, 87.122250648189, 87.034382483161, 86.946514260205, - 86.858645984181, 86.770777659421, 86.682909289796, 86.595040878780, 86.507172429496, - 86.419303944761, 86.331435427121, 86.243566878886, 86.155698302153, 86.067829698833, - 85.979961070667, 85.892092419252, 85.804223746047, 85.716355052393, 85.628486339523, - 85.540617608572, 85.452748860590, 85.364880096544, 85.277011317330, 85.189142523781, - 85.101273716667, 85.013404896705, 84.925536064563, 84.837667220863, 84.749798366184, - 84.661929501069, 84.574060626026, 84.486191741528, 84.398322848020, 84.310453945921, - 84.222585035621, 84.134716117490, 84.046847191874, 83.958978259099, 83.871109319475, - 83.783240373290, 83.695371420820, 83.607502462324, 83.519633498046, 83.431764528220, - 83.343895553063, 83.256026572786, 83.168157587584, 83.080288597647, 82.992419603152, - 82.904550604269, 82.816681601158, 82.728812593972, 82.640943582859, 82.553074567956, - 82.465205549396, 82.377336527307, 82.289467501807, 82.201598473014, 82.113729441036, - 82.025860405980, 81.937991367945, 81.850122327028, 81.762253283322, 81.674384236914, - 81.586515187890, 81.498646136330, 81.410777082312, 81.322908025911, 81.235038967199, - 81.147169906244, 81.059300843113, 80.971431777869, 80.883562710572, 80.795693641283, - 80.707824570058, 80.619955496950, 80.532086422013, 80.444217345296, 80.356348266849, - 80.268479186718, 80.180610104949, 80.092741021585, 80.004871936668, 79.917002850239, - 79.829133762336, 79.741264672999, 79.653395582263, 79.565526490164, 79.477657396735, - 79.389788302011, 79.301919206022, 79.214050108800, 79.126181010375, 79.038311910775, - 78.950442810029, 78.862573708164, 78.774704605205, 78.686835501180, 78.598966396111, - 78.511097290023, 78.423228182940, 78.335359074884, 78.247489965876, 78.159620855938, - 78.071751745091, 77.983882633354, 77.896013520746, 77.808144407288, 77.720275292996, - 77.632406177888, 77.544537061983, 77.456667945296, 77.368798827844, 77.280929709643, - 77.193060590708, 77.105191471054, 77.017322350696, 76.929453229649, 76.841584107925, - 76.753714985538, 76.665845862502, 76.577976738829, 76.490107614531, 76.402238489621, - 76.314369364111, 76.226500238012, 76.138631111335, 76.050761984091, 75.962892856291, - 75.875023727945, 75.787154599064, 75.699285469656, 75.611416339733, 75.523547209302, - 75.435678078374, 75.347808946958, 75.259939815061, 75.172070682693, 75.084201549862, - 74.996332416576, 74.908463282843, 74.820594148671, 74.732725014067, 74.644855879040, - 74.556986743595, 74.469117607740, 74.381248471483, 74.293379334829, 74.205510197785, - 74.117641060359, 74.029771922556, 73.941902784382, 73.854033645844, 73.766164506947, - 73.678295367697, 73.590426228100, 73.502557088162, 73.414687947887, 73.326818807282, - 73.238949666350, 73.151080525099, 73.063211383532, 72.975342241654, 72.887473099470, - 72.799603956985, 72.711734814204, 72.623865671130, 72.535996527769, 72.448127384125, - 72.360258240201, 72.272389096003, 72.184519951533, 72.096650806797, 72.008781661798, - 71.920912516539, 71.833043371026, 71.745174225260, 71.657305079247, 71.569435932989, - 71.481566786490, 71.393697639753, 71.305828492782, 71.217959345580, 71.130090198151, - 71.042221050496, 70.954351902621, 70.866482754527, 70.778613606218, 70.690744457696, - 70.602875308964, 70.515006160026, 70.427137010884, 70.339267861541, 70.251398711999, - 70.163529562262, 70.075660412331, 69.987791262209, 69.899922111899, 69.812052961404, - 69.724183810725, 69.636314659865, 69.548445508827, 69.460576357612, 69.372707206223, - 69.284838054662, 69.196968902932, 69.109099751034, 69.021230598970, 68.933361446744, - 68.845492294356, 68.757623141808, 68.669753989104, 68.581884836244, 68.494015683230, - 68.406146530065, 68.318277376750, 68.230408223287, 68.142539069678, 68.054669915925, - 67.966800762029, 67.878931607992, 67.791062453816, 67.703193299502, 67.615324145052, - 67.527454990468, 67.439585835750, 67.351716680902, 67.263847525924, 67.175978370817, - 67.088109215584, 67.000240060226, 66.912370904743, 66.824501749138, 66.736632593412, - 66.648763437566, 66.560894281602, 66.473025125521, 66.385155969324, 66.297286813013, - 66.209417656589, 66.121548500052, 66.033679343405, 65.945810186649, 65.857941029784, - 65.770071872812, 65.682202715735, 65.594333558552, 65.506464401266, 65.418595243877, - 65.330726086387, 65.242856928797, 65.154987771107, 65.067118613319, 64.979249455434, - 64.891380297453, 64.803511139377, 64.715641981206, 64.627772822942, 64.539903664587, - 64.452034506139, 64.364165347602, 64.276296188975, 64.188427030260, 64.100557871457, - 64.012688712568, 63.924819553592, 63.836950394532, 63.749081235388, 63.661212076161, - 63.573342916851, 63.485473757459, 63.397604597987, 63.309735438435, 63.221866278804, - 63.133997119094, 63.046127959307, 62.958258799443, 62.870389639503, 62.782520479487, - 62.694651319397, 62.606782159233, 62.518912998996, 62.431043838687, 62.343174678305, - 62.255305517853, 62.167436357330, 62.079567196737, 61.991698036075, 61.903828875345, - 61.815959714547, 61.728090553681, 61.640221392750, 61.552352231752, 61.464483070689, - 61.376613909561, 61.288744748369, 61.200875587114, 61.113006425796, 61.025137264415, - 60.937268102973, 60.849398941469, 60.761529779905, 60.673660618281, 60.585791456597, - 60.497922294854, 60.410053133052, 60.322183971193, 60.234314809276, 60.146445647302, - 60.058576485271, 59.970707323185, 59.882838161043, 59.794968998847, 59.707099836595, - 59.619230674290, 59.531361511931, 59.443492349520, 59.355623187055, 59.267754024539, - 59.179884861970, 59.092015699351, 59.004146536680, 58.916277373959, 58.828408211189, - 58.740539048368, 58.652669885499, 58.564800722581, 58.476931559614, 58.389062396600, - 58.301193233538, 58.213324070430, 58.125454907274, 58.037585744072, 57.949716580824, - 57.861847417531, 57.773978254193, 57.686109090809, 57.598239927382, 57.510370763910, - 57.422501600395, 57.334632436836, 57.246763273234, 57.158894109590, 57.071024945903, - 56.983155782175, 56.895286618404, 56.807417454593, 56.719548290741, 56.631679126848, - 56.543809962914, 56.455940798941, 56.368071634928, 56.280202470876, 56.192333306784, - 56.104464142654, 56.016594978486, 55.928725814279, 55.840856650035, 55.752987485753, - 55.665118321433, 55.577249157077, 55.489379992684, 55.401510828255, 55.313641663790, - 55.225772499289, 55.137903334752, 55.050034170180, 54.962165005573, 54.874295840932, - 54.786426676256, 54.698557511545, 54.610688346801, 54.522819182023, 54.434950017212, - 54.347080852367, 54.259211687489, 54.171342522579, 54.083473357636, 53.995604192661, - 53.907735027655, 53.819865862616, 53.731996697546, 53.644127532444, 53.556258367312, - 53.468389202149, 53.380520036955, 53.292650871731, 53.204781706476, 53.116912541192, - 53.029043375878, 52.941174210535, 52.853305045162, 52.765435879760, 52.677566714330, - 52.589697548871, 52.501828383383, 52.413959217867, 52.326090052323, 52.238220886751, - 52.150351721152, 52.062482555525, 51.974613389871, 51.886744224189, 51.798875058481, - 51.711005892747, 51.623136726985, 51.535267561198, 51.447398395384, 51.359529229545, - 51.271660063679, 51.183790897788, 51.095921731872, 51.008052565931, 50.920183399964, - 50.832314233973, 50.744445067957, 50.656575901916, 50.568706735851, 50.480837569762, - 50.392968403648, 50.305099237511, 50.217230071350, 50.129360905166, 50.041491738958, - 49.953622572727, 49.865753406473, 49.777884240196, 49.690015073896, 49.602145907574, - 49.514276741229, 49.426407574862, 49.338538408472, 49.250669242061, 49.162800075628, - 49.074930909173, 48.987061742696, 48.899192576198, 48.811323409679, 48.723454243139, - 48.635585076577, 48.547715909995, 48.459846743392, 48.371977576768, 48.284108410124, - 48.196239243460, 48.108370076775, 48.020500910070, 47.932631743346, 47.844762576601, - 47.756893409837, 47.669024243053, 47.581155076250, 47.493285909427, 47.405416742586, - 47.317547575725, 47.229678408845, 47.141809241947, 47.053940075030, 46.966070908094, - 46.878201741140, 46.790332574167, 46.702463407176, 46.614594240167, 46.526725073140, - 46.438855906096, 46.350986739033, 46.263117571953, 46.175248404855, 46.087379237740, - 45.999510070607, 45.911640903457, 45.823771736290, 45.735902569106, 45.648033401905, - 45.560164234688, 45.472295067453, 45.384425900202, 45.296556732935, 45.208687565651, - 45.120818398351, 45.032949231035, 44.945080063702, 44.857210896354, 44.769341728989, - 44.681472561609, 44.593603394213, 44.505734226802, 44.417865059375, 44.329995891933, - 44.242126724475, 44.154257557002, 44.066388389514, 43.978519222011, 43.890650054493, - 43.802780886960, 43.714911719412, 43.627042551849, 43.539173384272, 43.451304216681, - 43.363435049075, 43.275565881454, 43.187696713820, 43.099827546171, 43.011958378508, - 42.924089210831, 42.836220043140, 42.748350875436, 42.660481707717, 42.572612539985, - 42.484743372240, 42.396874204480, 42.309005036708, 42.221135868922, 42.133266701123, - 42.045397533310, 41.957528365484, 41.869659197646, 41.781790029794, 41.693920861930, - 41.606051694052, 41.518182526162, 41.430313358259, 41.342444190344, 41.254575022416, - 41.166705854475, 41.078836686523, 40.990967518558, 40.903098350580, 40.815229182591, - 40.727360014589, 40.639490846575, 40.551621678550, 40.463752510512, 40.375883342463, - 40.288014174402, 40.200145006329, 40.112275838244, 40.024406670148, 39.936537502041, - 39.848668333922, 39.760799165792, 39.672929997650, 39.585060829497, 39.497191661333, - 39.409322493158, 39.321453324972, 39.233584156775, 39.145714988566, 39.057845820347, - 38.969976652118, 38.882107483877, 38.794238315626, 38.706369147364, 38.618499979092, - 38.530630810809, 38.442761642515, 38.354892474212, 38.267023305898, 38.179154137573, - 38.091284969239, 38.003415800894, 37.915546632539, 37.827677464174, 37.739808295800, - 37.651939127415, 37.564069959020, 37.476200790616, 37.388331622201, 37.300462453777, - 37.212593285344, 37.124724116900, 37.036854948448, 36.948985779985, 36.861116611513, - 36.773247443032, 36.685378274542, 36.597509106042, 36.509639937533, 36.421770769014, - 36.333901600487, 36.246032431950, 36.158163263405, 36.070294094850, 35.982424926287, - 35.894555757714, 35.806686589133, 35.718817420543, 35.630948251944, 35.543079083336, - 35.455209914720, 35.367340746095, 35.279471577462, 35.191602408820, 35.103733240170, - 35.015864071511, 34.927994902843, 34.840125734168, 34.752256565484, 34.664387396792, - 34.576518228092, 34.488649059383, 34.400779890666, 34.312910721942, 34.225041553209, - 34.137172384468, 34.049303215720, 33.961434046963, 33.873564878199, 33.785695709426, - 33.697826540646, 33.609957371859, 33.522088203063, 33.434219034260, 33.346349865450, - 33.258480696631, 33.170611527805, 33.082742358972, 32.994873190131, 32.907004021283, - 32.819134852428, 32.731265683565, 32.643396514695, 32.555527345817, 32.467658176933, - 32.379789008041, 32.291919839142, 32.204050670236, 32.116181501323, 32.028312332403, - 31.940443163476, 31.852573994542, 31.764704825601, 31.676835656653, 31.588966487698, - 31.501097318737, 31.413228149768, 31.325358980793, 31.237489811812, 31.149620642823, - 31.061751473829, 30.973882304827, 30.886013135819, 30.798143966804, 30.710274797783, - 30.622405628756, 30.534536459722, 30.446667290681, 30.358798121634, 30.270928952581, - 30.183059783522, 30.095190614457, 30.007321445385, 29.919452276307, 29.831583107223, - 29.743713938132, 29.655844769036, 29.567975599934, 29.480106430825, 29.392237261711, - 29.304368092591, 29.216498923464, 29.128629754332, 29.040760585194, 28.952891416050, - 28.865022246901, 28.777153077745, 28.689283908584, 28.601414739417, 28.513545570245, - 28.425676401067, 28.337807231883, 28.249938062693, 28.162068893498, 28.074199724298, - 27.986330555092, 27.898461385880, 27.810592216664, 27.722723047441, 27.634853878214, - 27.546984708981, 27.459115539742, 27.371246370498, 27.283377201249, 27.195508031995, - 27.107638862736, 27.019769693471, 26.931900524202, 26.844031354927, 26.756162185647, - 26.668293016362, 26.580423847071, 26.492554677776, 26.404685508476, 26.316816339171, - 26.228947169861, 26.141078000546, 26.053208831226, 25.965339661902, 25.877470492572, - 25.789601323238, 25.701732153899, 25.613862984555, 25.525993815206, 25.438124645853, - 25.350255476495, 25.262386307132, 25.174517137765, 25.086647968393, 24.998778799016, - 24.910909629635, 24.823040460250, 24.735171290859, 24.647302121465, 24.559432952066, - 24.471563782662, 24.383694613254, 24.295825443842, 24.207956274425, 24.120087105005, - 24.032217935579, 23.944348766150, 23.856479596716, 23.768610427278, 23.680741257835, - 23.592872088389, 23.505002918938, 23.417133749483, 23.329264580024, 23.241395410561, - 23.153526241094, 23.065657071623, 22.977787902148, 22.889918732668, 22.802049563185, - 22.714180393698, 22.626311224207, 22.538442054711, 22.450572885212, 22.362703715710, - 22.274834546203, 22.186965376692, 22.099096207178, 22.011227037659, 21.923357868137, - 21.835488698612, 21.747619529082, 21.659750359549, 21.571881190012, 21.484012020472, - 21.396142850927, 21.308273681379, 21.220404511828, 21.132535342273, 21.044666172714, - 20.956797003152, 20.868927833587, 20.781058664017, 20.693189494445, 20.605320324869, - 20.517451155289, 20.429581985706, 20.341712816120, 20.253843646530, 20.165974476937, - 20.078105307340, 19.990236137740, 19.902366968137, 19.814497798531, 19.726628628921, - 19.638759459308, 19.550890289692, 19.463021120072, 19.375151950450, 19.287282780824, - 19.199413611195, 19.111544441563, 19.023675271928, 18.935806102290, 18.847936932648, - 18.760067763004, 18.672198593357, 18.584329423706, 18.496460254053, 18.408591084396, - 18.320721914737, 18.232852745075, 18.144983575409, 18.057114405741, 17.969245236070, - 17.881376066396, 17.793506896719, 17.705637727039, 17.617768557357, 17.529899387672, - 17.442030217984, 17.354161048293, 17.266291878599, 17.178422708903, 17.090553539204, - 17.002684369502, 16.914815199797, 16.826946030090, 16.739076860380, 16.651207690668, - 16.563338520953, 16.475469351235, 16.387600181515, 16.299731011792, 16.211861842067, - 16.123992672339, 16.036123502609, 15.948254332876, 15.860385163141, 15.772515993403, - 15.684646823662, 15.596777653920, 15.508908484175, 15.421039314427, 15.333170144677, - 15.245300974925, 15.157431805170, 15.069562635413, 14.981693465654, 14.893824295893, - 14.805955126129, 14.718085956363, 14.630216786594, 14.542347616824, 14.454478447051, - 14.366609277276, 14.278740107498, 14.190870937719, 14.103001767937, 14.015132598154, - 13.927263428368, 13.839394258580, 13.751525088790, 13.663655918998, 13.575786749203, - 13.487917579407, 13.400048409609, 13.312179239809, 13.224310070006, 13.136440900202, - 13.048571730396, 12.960702560587, 12.872833390777, 12.784964220965, 12.697095051151, - 12.609225881335, 12.521356711517, 12.433487541698, 12.345618371876, 12.257749202053, - 12.169880032227, 12.082010862400, 11.994141692572, 11.906272522741, 11.818403352909, - 11.730534183074, 11.642665013239, 11.554795843401, 11.466926673562, 11.379057503721, - 11.291188333878, 11.203319164034, 11.115449994188, 11.027580824340, 10.939711654491, - 10.851842484640, 10.763973314787, 10.676104144933, 10.588234975078, 10.500365805220, - 10.412496635362, 10.324627465501, 10.236758295640, 10.148889125776, 10.061019955912, - 9.973150786046, 9.885281616178, 9.797412446309, 9.709543276438, 9.621674106566, - 9.533804936693, 9.445935766818, 9.358066596942, 9.270197427065, 9.182328257186, - 9.094459087306, 9.006589917424, 8.918720747542, 8.830851577657, 8.742982407772, - 8.655113237886, 8.567244067998, 8.479374898109, 8.391505728218, 8.303636558327, - 8.215767388434, 8.127898218540, 8.040029048645, 7.952159878749, 7.864290708852, - 7.776421538953, 7.688552369054, 7.600683199153, 7.512814029251, 7.424944859348, - 7.337075689444, 7.249206519539, 7.161337349633, 7.073468179726, 6.985599009818, - 6.897729839909, 6.809860669999, 6.721991500088, 6.634122330176, 6.546253160263, - 6.458383990349, 6.370514820434, 6.282645650519, 6.194776480602, 6.106907310685, - 6.019038140766, 5.931168970847, 5.843299800927, 5.755430631006, 5.667561461084, - 5.579692291162, 5.491823121239, 5.403953951315, 5.316084781390, 5.228215611464, - 5.140346441538, 5.052477271611, 4.964608101683, 4.876738931755, 4.788869761826, - 4.701000591896, 4.613131421965, 4.525262252034, 4.437393082102, 4.349523912170, - 4.261654742237, 4.173785572303, 4.085916402369, 3.998047232434, 3.910178062499, - 3.822308892563, 3.734439722626, 3.646570552689, 3.558701382752, 3.470832212814, - 3.382963042876, 3.295093872937, 3.207224702997, 3.119355533057, 3.031486363117, - 2.943617193176, 2.855748023235, 2.767878853294, 2.680009683352, 2.592140513409, - 2.504271343467, 2.416402173524, 2.328533003580, 2.240663833637, 2.152794663692, - 2.064925493748, 1.977056323804, 1.889187153859, 1.801317983914, 1.713448813968, - 1.625579644023, 1.537710474077, 1.449841304131, 1.361972134184, 1.274102964238, - 1.186233794291, 1.098364624344, 1.010495454397, 0.922626284450, 0.834757114503, - 0.746887944556, 0.659018774608, 0.571149604661, 0.483280434713, 0.395411264765, - 0.307542094817, 0.219672924870, 0.131803754922, 0.043934584974 - )) +DEFINE_GAUSSIAN_LATITUDES( + 1024, LIST( 89.932737928460, 89.845605479540, 89.757958466419, 89.670195191296, 89.582387815250, 89.494559098662, + 89.406718455753, 89.318870478120, 89.231017670122, 89.143161513177, 89.055302939412, 88.967442564544, + 88.879580811588, 88.791717980751, 88.703854290968, 88.615989905657, 88.528124949263, 88.440259518219, + 88.352393688409, 88.264527520359, 88.176661062939, 88.088794356040, 88.000927432542, 87.913060319791, + 87.825193040716, 87.737325614688, 87.649458058179, 87.561590385292, 87.473722608166, 87.385854737308, + 87.297986781862, 87.210118749818, 87.122250648189, 87.034382483161, 86.946514260205, 86.858645984181, + 86.770777659421, 86.682909289796, 86.595040878780, 86.507172429496, 86.419303944761, 86.331435427121, + 86.243566878886, 86.155698302153, 86.067829698833, 85.979961070667, 85.892092419252, 85.804223746047, + 85.716355052393, 85.628486339523, 85.540617608572, 85.452748860590, 85.364880096544, 85.277011317330, + 85.189142523781, 85.101273716667, 85.013404896705, 84.925536064563, 84.837667220863, 84.749798366184, + 84.661929501069, 84.574060626026, 84.486191741528, 84.398322848020, 84.310453945921, 84.222585035621, + 84.134716117490, 84.046847191874, 83.958978259099, 83.871109319475, 83.783240373290, 83.695371420820, + 83.607502462324, 83.519633498046, 83.431764528220, 83.343895553063, 83.256026572786, 83.168157587584, + 83.080288597647, 82.992419603152, 82.904550604269, 82.816681601158, 82.728812593972, 82.640943582859, + 82.553074567956, 82.465205549396, 82.377336527307, 82.289467501807, 82.201598473014, 82.113729441036, + 82.025860405980, 81.937991367945, 81.850122327028, 81.762253283322, 81.674384236914, 81.586515187890, + 81.498646136330, 81.410777082312, 81.322908025911, 81.235038967199, 81.147169906244, 81.059300843113, + 80.971431777869, 80.883562710572, 80.795693641283, 80.707824570058, 80.619955496950, 80.532086422013, + 80.444217345296, 80.356348266849, 80.268479186718, 80.180610104949, 80.092741021585, 80.004871936668, + 79.917002850239, 79.829133762336, 79.741264672999, 79.653395582263, 79.565526490164, 79.477657396735, + 79.389788302011, 79.301919206022, 79.214050108800, 79.126181010375, 79.038311910775, 78.950442810029, + 78.862573708164, 78.774704605205, 78.686835501180, 78.598966396111, 78.511097290023, 78.423228182940, + 78.335359074884, 78.247489965876, 78.159620855938, 78.071751745091, 77.983882633354, 77.896013520746, + 77.808144407288, 77.720275292996, 77.632406177888, 77.544537061983, 77.456667945296, 77.368798827844, + 77.280929709643, 77.193060590708, 77.105191471054, 77.017322350696, 76.929453229649, 76.841584107925, + 76.753714985538, 76.665845862502, 76.577976738829, 76.490107614531, 76.402238489621, 76.314369364111, + 76.226500238012, 76.138631111335, 76.050761984091, 75.962892856291, 75.875023727945, 75.787154599064, + 75.699285469656, 75.611416339733, 75.523547209302, 75.435678078374, 75.347808946958, 75.259939815061, + 75.172070682693, 75.084201549862, 74.996332416576, 74.908463282843, 74.820594148671, 74.732725014067, + 74.644855879040, 74.556986743595, 74.469117607740, 74.381248471483, 74.293379334829, 74.205510197785, + 74.117641060359, 74.029771922556, 73.941902784382, 73.854033645844, 73.766164506947, 73.678295367697, + 73.590426228100, 73.502557088162, 73.414687947887, 73.326818807282, 73.238949666350, 73.151080525099, + 73.063211383532, 72.975342241654, 72.887473099470, 72.799603956985, 72.711734814204, 72.623865671130, + 72.535996527769, 72.448127384125, 72.360258240201, 72.272389096003, 72.184519951533, 72.096650806797, + 72.008781661798, 71.920912516539, 71.833043371026, 71.745174225260, 71.657305079247, 71.569435932989, + 71.481566786490, 71.393697639753, 71.305828492782, 71.217959345580, 71.130090198151, 71.042221050496, + 70.954351902621, 70.866482754527, 70.778613606218, 70.690744457696, 70.602875308964, 70.515006160026, + 70.427137010884, 70.339267861541, 70.251398711999, 70.163529562262, 70.075660412331, 69.987791262209, + 69.899922111899, 69.812052961404, 69.724183810725, 69.636314659865, 69.548445508827, 69.460576357612, + 69.372707206223, 69.284838054662, 69.196968902932, 69.109099751034, 69.021230598970, 68.933361446744, + 68.845492294356, 68.757623141808, 68.669753989104, 68.581884836244, 68.494015683230, 68.406146530065, + 68.318277376750, 68.230408223287, 68.142539069678, 68.054669915925, 67.966800762029, 67.878931607992, + 67.791062453816, 67.703193299502, 67.615324145052, 67.527454990468, 67.439585835750, 67.351716680902, + 67.263847525924, 67.175978370817, 67.088109215584, 67.000240060226, 66.912370904743, 66.824501749138, + 66.736632593412, 66.648763437566, 66.560894281602, 66.473025125521, 66.385155969324, 66.297286813013, + 66.209417656589, 66.121548500052, 66.033679343405, 65.945810186649, 65.857941029784, 65.770071872812, + 65.682202715735, 65.594333558552, 65.506464401266, 65.418595243877, 65.330726086387, 65.242856928797, + 65.154987771107, 65.067118613319, 64.979249455434, 64.891380297453, 64.803511139377, 64.715641981206, + 64.627772822942, 64.539903664587, 64.452034506139, 64.364165347602, 64.276296188975, 64.188427030260, + 64.100557871457, 64.012688712568, 63.924819553592, 63.836950394532, 63.749081235388, 63.661212076161, + 63.573342916851, 63.485473757459, 63.397604597987, 63.309735438435, 63.221866278804, 63.133997119094, + 63.046127959307, 62.958258799443, 62.870389639503, 62.782520479487, 62.694651319397, 62.606782159233, + 62.518912998996, 62.431043838687, 62.343174678305, 62.255305517853, 62.167436357330, 62.079567196737, + 61.991698036075, 61.903828875345, 61.815959714547, 61.728090553681, 61.640221392750, 61.552352231752, + 61.464483070689, 61.376613909561, 61.288744748369, 61.200875587114, 61.113006425796, 61.025137264415, + 60.937268102973, 60.849398941469, 60.761529779905, 60.673660618281, 60.585791456597, 60.497922294854, + 60.410053133052, 60.322183971193, 60.234314809276, 60.146445647302, 60.058576485271, 59.970707323185, + 59.882838161043, 59.794968998847, 59.707099836595, 59.619230674290, 59.531361511931, 59.443492349520, + 59.355623187055, 59.267754024539, 59.179884861970, 59.092015699351, 59.004146536680, 58.916277373959, + 58.828408211189, 58.740539048368, 58.652669885499, 58.564800722581, 58.476931559614, 58.389062396600, + 58.301193233538, 58.213324070430, 58.125454907274, 58.037585744072, 57.949716580824, 57.861847417531, + 57.773978254193, 57.686109090809, 57.598239927382, 57.510370763910, 57.422501600395, 57.334632436836, + 57.246763273234, 57.158894109590, 57.071024945903, 56.983155782175, 56.895286618404, 56.807417454593, + 56.719548290741, 56.631679126848, 56.543809962914, 56.455940798941, 56.368071634928, 56.280202470876, + 56.192333306784, 56.104464142654, 56.016594978486, 55.928725814279, 55.840856650035, 55.752987485753, + 55.665118321433, 55.577249157077, 55.489379992684, 55.401510828255, 55.313641663790, 55.225772499289, + 55.137903334752, 55.050034170180, 54.962165005573, 54.874295840932, 54.786426676256, 54.698557511545, + 54.610688346801, 54.522819182023, 54.434950017212, 54.347080852367, 54.259211687489, 54.171342522579, + 54.083473357636, 53.995604192661, 53.907735027655, 53.819865862616, 53.731996697546, 53.644127532444, + 53.556258367312, 53.468389202149, 53.380520036955, 53.292650871731, 53.204781706476, 53.116912541192, + 53.029043375878, 52.941174210535, 52.853305045162, 52.765435879760, 52.677566714330, 52.589697548871, + 52.501828383383, 52.413959217867, 52.326090052323, 52.238220886751, 52.150351721152, 52.062482555525, + 51.974613389871, 51.886744224189, 51.798875058481, 51.711005892747, 51.623136726985, 51.535267561198, + 51.447398395384, 51.359529229545, 51.271660063679, 51.183790897788, 51.095921731872, 51.008052565931, + 50.920183399964, 50.832314233973, 50.744445067957, 50.656575901916, 50.568706735851, 50.480837569762, + 50.392968403648, 50.305099237511, 50.217230071350, 50.129360905166, 50.041491738958, 49.953622572727, + 49.865753406473, 49.777884240196, 49.690015073896, 49.602145907574, 49.514276741229, 49.426407574862, + 49.338538408472, 49.250669242061, 49.162800075628, 49.074930909173, 48.987061742696, 48.899192576198, + 48.811323409679, 48.723454243139, 48.635585076577, 48.547715909995, 48.459846743392, 48.371977576768, + 48.284108410124, 48.196239243460, 48.108370076775, 48.020500910070, 47.932631743346, 47.844762576601, + 47.756893409837, 47.669024243053, 47.581155076250, 47.493285909427, 47.405416742586, 47.317547575725, + 47.229678408845, 47.141809241947, 47.053940075030, 46.966070908094, 46.878201741140, 46.790332574167, + 46.702463407176, 46.614594240167, 46.526725073140, 46.438855906096, 46.350986739033, 46.263117571953, + 46.175248404855, 46.087379237740, 45.999510070607, 45.911640903457, 45.823771736290, 45.735902569106, + 45.648033401905, 45.560164234688, 45.472295067453, 45.384425900202, 45.296556732935, 45.208687565651, + 45.120818398351, 45.032949231035, 44.945080063702, 44.857210896354, 44.769341728989, 44.681472561609, + 44.593603394213, 44.505734226802, 44.417865059375, 44.329995891933, 44.242126724475, 44.154257557002, + 44.066388389514, 43.978519222011, 43.890650054493, 43.802780886960, 43.714911719412, 43.627042551849, + 43.539173384272, 43.451304216681, 43.363435049075, 43.275565881454, 43.187696713820, 43.099827546171, + 43.011958378508, 42.924089210831, 42.836220043140, 42.748350875436, 42.660481707717, 42.572612539985, + 42.484743372240, 42.396874204480, 42.309005036708, 42.221135868922, 42.133266701123, 42.045397533310, + 41.957528365484, 41.869659197646, 41.781790029794, 41.693920861930, 41.606051694052, 41.518182526162, + 41.430313358259, 41.342444190344, 41.254575022416, 41.166705854475, 41.078836686523, 40.990967518558, + 40.903098350580, 40.815229182591, 40.727360014589, 40.639490846575, 40.551621678550, 40.463752510512, + 40.375883342463, 40.288014174402, 40.200145006329, 40.112275838244, 40.024406670148, 39.936537502041, + 39.848668333922, 39.760799165792, 39.672929997650, 39.585060829497, 39.497191661333, 39.409322493158, + 39.321453324972, 39.233584156775, 39.145714988566, 39.057845820347, 38.969976652118, 38.882107483877, + 38.794238315626, 38.706369147364, 38.618499979092, 38.530630810809, 38.442761642515, 38.354892474212, + 38.267023305898, 38.179154137573, 38.091284969239, 38.003415800894, 37.915546632539, 37.827677464174, + 37.739808295800, 37.651939127415, 37.564069959020, 37.476200790616, 37.388331622201, 37.300462453777, + 37.212593285344, 37.124724116900, 37.036854948448, 36.948985779985, 36.861116611513, 36.773247443032, + 36.685378274542, 36.597509106042, 36.509639937533, 36.421770769014, 36.333901600487, 36.246032431950, + 36.158163263405, 36.070294094850, 35.982424926287, 35.894555757714, 35.806686589133, 35.718817420543, + 35.630948251944, 35.543079083336, 35.455209914720, 35.367340746095, 35.279471577462, 35.191602408820, + 35.103733240170, 35.015864071511, 34.927994902843, 34.840125734168, 34.752256565484, 34.664387396792, + 34.576518228092, 34.488649059383, 34.400779890666, 34.312910721942, 34.225041553209, 34.137172384468, + 34.049303215720, 33.961434046963, 33.873564878199, 33.785695709426, 33.697826540646, 33.609957371859, + 33.522088203063, 33.434219034260, 33.346349865450, 33.258480696631, 33.170611527805, 33.082742358972, + 32.994873190131, 32.907004021283, 32.819134852428, 32.731265683565, 32.643396514695, 32.555527345817, + 32.467658176933, 32.379789008041, 32.291919839142, 32.204050670236, 32.116181501323, 32.028312332403, + 31.940443163476, 31.852573994542, 31.764704825601, 31.676835656653, 31.588966487698, 31.501097318737, + 31.413228149768, 31.325358980793, 31.237489811812, 31.149620642823, 31.061751473829, 30.973882304827, + 30.886013135819, 30.798143966804, 30.710274797783, 30.622405628756, 30.534536459722, 30.446667290681, + 30.358798121634, 30.270928952581, 30.183059783522, 30.095190614457, 30.007321445385, 29.919452276307, + 29.831583107223, 29.743713938132, 29.655844769036, 29.567975599934, 29.480106430825, 29.392237261711, + 29.304368092591, 29.216498923464, 29.128629754332, 29.040760585194, 28.952891416050, 28.865022246901, + 28.777153077745, 28.689283908584, 28.601414739417, 28.513545570245, 28.425676401067, 28.337807231883, + 28.249938062693, 28.162068893498, 28.074199724298, 27.986330555092, 27.898461385880, 27.810592216664, + 27.722723047441, 27.634853878214, 27.546984708981, 27.459115539742, 27.371246370498, 27.283377201249, + 27.195508031995, 27.107638862736, 27.019769693471, 26.931900524202, 26.844031354927, 26.756162185647, + 26.668293016362, 26.580423847071, 26.492554677776, 26.404685508476, 26.316816339171, 26.228947169861, + 26.141078000546, 26.053208831226, 25.965339661902, 25.877470492572, 25.789601323238, 25.701732153899, + 25.613862984555, 25.525993815206, 25.438124645853, 25.350255476495, 25.262386307132, 25.174517137765, + 25.086647968393, 24.998778799016, 24.910909629635, 24.823040460250, 24.735171290859, 24.647302121465, + 24.559432952066, 24.471563782662, 24.383694613254, 24.295825443842, 24.207956274425, 24.120087105005, + 24.032217935579, 23.944348766150, 23.856479596716, 23.768610427278, 23.680741257835, 23.592872088389, + 23.505002918938, 23.417133749483, 23.329264580024, 23.241395410561, 23.153526241094, 23.065657071623, + 22.977787902148, 22.889918732668, 22.802049563185, 22.714180393698, 22.626311224207, 22.538442054711, + 22.450572885212, 22.362703715710, 22.274834546203, 22.186965376692, 22.099096207178, 22.011227037659, + 21.923357868137, 21.835488698612, 21.747619529082, 21.659750359549, 21.571881190012, 21.484012020472, + 21.396142850927, 21.308273681379, 21.220404511828, 21.132535342273, 21.044666172714, 20.956797003152, + 20.868927833587, 20.781058664017, 20.693189494445, 20.605320324869, 20.517451155289, 20.429581985706, + 20.341712816120, 20.253843646530, 20.165974476937, 20.078105307340, 19.990236137740, 19.902366968137, + 19.814497798531, 19.726628628921, 19.638759459308, 19.550890289692, 19.463021120072, 19.375151950450, + 19.287282780824, 19.199413611195, 19.111544441563, 19.023675271928, 18.935806102290, 18.847936932648, + 18.760067763004, 18.672198593357, 18.584329423706, 18.496460254053, 18.408591084396, 18.320721914737, + 18.232852745075, 18.144983575409, 18.057114405741, 17.969245236070, 17.881376066396, 17.793506896719, + 17.705637727039, 17.617768557357, 17.529899387672, 17.442030217984, 17.354161048293, 17.266291878599, + 17.178422708903, 17.090553539204, 17.002684369502, 16.914815199797, 16.826946030090, 16.739076860380, + 16.651207690668, 16.563338520953, 16.475469351235, 16.387600181515, 16.299731011792, 16.211861842067, + 16.123992672339, 16.036123502609, 15.948254332876, 15.860385163141, 15.772515993403, 15.684646823662, + 15.596777653920, 15.508908484175, 15.421039314427, 15.333170144677, 15.245300974925, 15.157431805170, + 15.069562635413, 14.981693465654, 14.893824295893, 14.805955126129, 14.718085956363, 14.630216786594, + 14.542347616824, 14.454478447051, 14.366609277276, 14.278740107498, 14.190870937719, 14.103001767937, + 14.015132598154, 13.927263428368, 13.839394258580, 13.751525088790, 13.663655918998, 13.575786749203, + 13.487917579407, 13.400048409609, 13.312179239809, 13.224310070006, 13.136440900202, 13.048571730396, + 12.960702560587, 12.872833390777, 12.784964220965, 12.697095051151, 12.609225881335, 12.521356711517, + 12.433487541698, 12.345618371876, 12.257749202053, 12.169880032227, 12.082010862400, 11.994141692572, + 11.906272522741, 11.818403352909, 11.730534183074, 11.642665013239, 11.554795843401, 11.466926673562, + 11.379057503721, 11.291188333878, 11.203319164034, 11.115449994188, 11.027580824340, 10.939711654491, + 10.851842484640, 10.763973314787, 10.676104144933, 10.588234975078, 10.500365805220, 10.412496635362, + 10.324627465501, 10.236758295640, 10.148889125776, 10.061019955912, 9.973150786046, 9.885281616178, + 9.797412446309, 9.709543276438, 9.621674106566, 9.533804936693, 9.445935766818, 9.358066596942, + 9.270197427065, 9.182328257186, 9.094459087306, 9.006589917424, 8.918720747542, 8.830851577657, + 8.742982407772, 8.655113237886, 8.567244067998, 8.479374898109, 8.391505728218, 8.303636558327, + 8.215767388434, 8.127898218540, 8.040029048645, 7.952159878749, 7.864290708852, 7.776421538953, + 7.688552369054, 7.600683199153, 7.512814029251, 7.424944859348, 7.337075689444, 7.249206519539, + 7.161337349633, 7.073468179726, 6.985599009818, 6.897729839909, 6.809860669999, 6.721991500088, + 6.634122330176, 6.546253160263, 6.458383990349, 6.370514820434, 6.282645650519, 6.194776480602, + 6.106907310685, 6.019038140766, 5.931168970847, 5.843299800927, 5.755430631006, 5.667561461084, + 5.579692291162, 5.491823121239, 5.403953951315, 5.316084781390, 5.228215611464, 5.140346441538, + 5.052477271611, 4.964608101683, 4.876738931755, 4.788869761826, 4.701000591896, 4.613131421965, + 4.525262252034, 4.437393082102, 4.349523912170, 4.261654742237, 4.173785572303, 4.085916402369, + 3.998047232434, 3.910178062499, 3.822308892563, 3.734439722626, 3.646570552689, 3.558701382752, + 3.470832212814, 3.382963042876, 3.295093872937, 3.207224702997, 3.119355533057, 3.031486363117, + 2.943617193176, 2.855748023235, 2.767878853294, 2.680009683352, 2.592140513409, 2.504271343467, + 2.416402173524, 2.328533003580, 2.240663833637, 2.152794663692, 2.064925493748, 1.977056323804, + 1.889187153859, 1.801317983914, 1.713448813968, 1.625579644023, 1.537710474077, 1.449841304131, + 1.361972134184, 1.274102964238, 1.186233794291, 1.098364624344, 1.010495454397, 0.922626284450, + 0.834757114503, 0.746887944556, 0.659018774608, 0.571149604661, 0.483280434713, 0.395411264765, + 0.307542094817, 0.219672924870, 0.131803754922, 0.043934584974 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N128.cc b/src/atlas/grid/detail/spacing/gaussian/N128.cc index 1a1d7fff4..eaf60c8e7 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N128.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N128.cc @@ -7,37 +7,31 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(128,LIST( - 89.462821568577, 88.766951352842, 88.066971647431, 87.366063433082, 86.664803013441, - 85.963372160880, 85.261846060713, 84.560261383053, 83.858638128608, 83.156988128542, - 82.455318827164, 81.753635141838, 81.051940450936, 80.350237152036, 79.648526993666, - 78.946811280967, 78.245091007821, 77.543366944409, 76.841639696782, 76.139909748368, - 75.438177489488, 74.736443238739, 74.034707258747, 73.332969767937, 72.631230949459, - 71.929490958033, 71.227749925260, 70.526007963782, 69.824265170583, 69.122521629614, - 68.420777413915, 67.719032587332, 67.017287205917, 66.315541319089, 65.613794970579, - 64.912048199233, 64.210301039674, 63.508553522860, 62.806805676556, 62.105057525741, - 61.403309092943, 60.701560398538, 59.999811460996, 59.298062297105, 58.596312922156, - 57.894563350105, 57.192813593719, 56.491063664698, 55.789313573786, 55.087563330867, - 54.385812945049, 53.684062424740, 52.982311777713, 52.280561011166, 51.578810131776, - 50.877059145743, 50.175308058833, 49.473556876418, 48.771805603506, 48.070054244773, - 47.368302804592, 46.666551287055, 45.964799695997, 45.263048035017, 44.561296307493, - 43.859544516602, 43.157792665336, 42.456040756510, 41.754288792783, 41.052536776662, - 40.350784710518, 39.649032596592, 38.947280437007, 38.245528233774, 37.543775988799, - 36.842023703894, 36.140271380778, 35.438519021086, 34.736766626375, 34.035014198127, - 33.333261737756, 32.631509246608, 31.929756725971, 31.228004177076, 30.526251601098, - 29.824498999163, 29.122746372350, 28.420993721692, 27.719241048181, 27.017488352770, - 26.315735636373, 25.613982899871, 24.912230144110, 24.210477369908, 23.508724578050, - 22.806971769296, 22.105218944378, 21.403466104006, 20.701713248864, 19.999960379617, - 19.298207496906, 18.596454601357, 17.894701693573, 17.192948774143, 16.491195843640, - 15.789442902620, 15.087689951625, 14.385936991186, 13.684184021817, 12.982431044024, - 12.280678058301, 11.578925065131, 10.877172064989, 10.175419058338, 9.473666045636, - 8.771913027332, 8.070160003868, 7.368406975680, 6.666653943198, 5.964900906845, - 5.263147867043, 4.561394824207, 3.859641778748, 3.157888731076, 2.456135681596, - 1.754382630712, 1.052629578828, 0.350876526343 - )) +DEFINE_GAUSSIAN_LATITUDES( + 128, LIST( 89.462821568577, 88.766951352842, 88.066971647431, 87.366063433082, 86.664803013441, 85.963372160880, + 85.261846060713, 84.560261383053, 83.858638128608, 83.156988128542, 82.455318827164, 81.753635141838, + 81.051940450936, 80.350237152036, 79.648526993666, 78.946811280967, 78.245091007821, 77.543366944409, + 76.841639696782, 76.139909748368, 75.438177489488, 74.736443238739, 74.034707258747, 73.332969767937, + 72.631230949459, 71.929490958033, 71.227749925260, 70.526007963782, 69.824265170583, 69.122521629614, + 68.420777413915, 67.719032587332, 67.017287205917, 66.315541319089, 65.613794970579, 64.912048199233, + 64.210301039674, 63.508553522860, 62.806805676556, 62.105057525741, 61.403309092943, 60.701560398538, + 59.999811460996, 59.298062297105, 58.596312922156, 57.894563350105, 57.192813593719, 56.491063664698, + 55.789313573786, 55.087563330867, 54.385812945049, 53.684062424740, 52.982311777713, 52.280561011166, + 51.578810131776, 50.877059145743, 50.175308058833, 49.473556876418, 48.771805603506, 48.070054244773, + 47.368302804592, 46.666551287055, 45.964799695997, 45.263048035017, 44.561296307493, 43.859544516602, + 43.157792665336, 42.456040756510, 41.754288792783, 41.052536776662, 40.350784710518, 39.649032596592, + 38.947280437007, 38.245528233774, 37.543775988799, 36.842023703894, 36.140271380778, 35.438519021086, + 34.736766626375, 34.035014198127, 33.333261737756, 32.631509246608, 31.929756725971, 31.228004177076, + 30.526251601098, 29.824498999163, 29.122746372350, 28.420993721692, 27.719241048181, 27.017488352770, + 26.315735636373, 25.613982899871, 24.912230144110, 24.210477369908, 23.508724578050, 22.806971769296, + 22.105218944378, 21.403466104006, 20.701713248864, 19.999960379617, 19.298207496906, 18.596454601357, + 17.894701693573, 17.192948774143, 16.491195843640, 15.789442902620, 15.087689951625, 14.385936991186, + 13.684184021817, 12.982431044024, 12.280678058301, 11.578925065131, 10.877172064989, 10.175419058338, + 9.473666045636, 8.771913027332, 8.070160003868, 7.368406975680, 6.666653943198, 5.964900906845, + 5.263147867043, 4.561394824207, 3.859641778748, 3.157888731076, 2.456135681596, 1.754382630712, + 1.052629578828, 0.350876526343 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N1280.cc b/src/atlas/grid/detail/spacing/gaussian/N1280.cc index 95ab7804c..72fac78bd 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N1280.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N1280.cc @@ -7,267 +7,223 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(1280,LIST( - 89.946187715666, 89.876478353332, 89.806357319542, 89.736143271610, 89.665893941216, - 89.595627537554, 89.525351592371, 89.455069779123, 89.384784101392, 89.314495744374, - 89.244205453805, 89.173913722284, 89.103620888239, 89.033327191846, 88.963032808263, - 88.892737868231, 88.822442471310, 88.752146694651, 88.681850598962, 88.611554232668, - 88.541257634869, 88.470960837475, 88.400663866794, 88.330366744703, 88.260069489546, - 88.189772116821, 88.119474639706, 88.049177069484, 87.978879415867, 87.908581687262, - 87.838283890982, 87.767986033420, 87.697688120188, 87.627390156234, 87.557092145936, - 87.486794093181, 87.416496001435, 87.346197873796, 87.275899713042, 87.205601521672, - 87.135303301940, 87.065005055883, 86.994706785348, 86.924408492014, 86.854110177409, - 86.783811842927, 86.713513489844, 86.643215119329, 86.572916732453, 86.502618330204, - 86.432319913490, 86.362021483149, 86.291723039957, 86.221424584631, 86.151126117835, - 86.080827640187, 86.010529152260, 85.940230654589, 85.869932147670, 85.799633631968, - 85.729335107917, 85.659036575923, 85.588738036364, 85.518439489598, 85.448140935957, - 85.377842375757, 85.307543809290, 85.237245236836, 85.166946658654, 85.096648074992, - 85.026349486082, 84.956050892143, 84.885752293383, 84.815453689997, 84.745155082172, - 84.674856470083, 84.604557853897, 84.534259233771, 84.463960609857, 84.393661982296, - 84.323363351224, 84.253064716770, 84.182766079057, 84.112467438200, 84.042168794312, - 83.971870147499, 83.901571497861, 83.831272845495, 83.760974190494, 83.690675532945, - 83.620376872933, 83.550078210538, 83.479779545838, 83.409480878906, 83.339182209812, - 83.268883538625, 83.198584865410, 83.128286190228, 83.057987513139, 82.987688834201, - 82.917390153469, 82.847091470996, 82.776792786832, 82.706494101027, 82.636195413627, - 82.565896724678, 82.495598034223, 82.425299342304, 82.355000648962, 82.284701954235, - 82.214403258161, 82.144104560776, 82.073805862115, 82.003507162212, 81.933208461099, - 81.862909758807, 81.792611055367, 81.722312350809, 81.652013645159, 81.581714938446, - 81.511416230696, 81.441117521935, 81.370818812187, 81.300520101476, 81.230221389825, - 81.159922677258, 81.089623963795, 81.019325249457, 80.949026534265, 80.878727818239, - 80.808429101398, 80.738130383760, 80.667831665344, 80.597532946166, 80.527234226244, - 80.456935505594, 80.386636784233, 80.316338062175, 80.246039339436, 80.175740616030, - 80.105441891972, 80.035143167276, 79.964844441954, 79.894545716020, 79.824246989487, - 79.753948262366, 79.683649534670, 79.613350806411, 79.543052077600, 79.472753348248, - 79.402454618366, 79.332155887964, 79.261857157052, 79.191558425641, 79.121259693740, - 79.050960961358, 78.980662228505, 78.910363495190, 78.840064761421, 78.769766027208, - 78.699467292557, 78.629168557478, 78.558869821978, 78.488571086065, 78.418272349746, - 78.347973613030, 78.277674875922, 78.207376138430, 78.137077400561, 78.066778662322, - 77.996479923719, 77.926181184758, 77.855882445445, 77.785583705787, 77.715284965790, - 77.644986225459, 77.574687484800, 77.504388743819, 77.434090002520, 77.363791260910, - 77.293492518993, 77.223193776775, 77.152895034260, 77.082596291454, 77.012297548360, - 76.941998804985, 76.871700061331, 76.801401317404, 76.731102573208, 76.660803828747, - 76.590505084026, 76.520206339048, 76.449907593818, 76.379608848339, 76.309310102615, - 76.239011356650, 76.168712610448, 76.098413864012, 76.028115117346, 75.957816370454, - 75.887517623337, 75.817218876001, 75.746920128448, 75.676621380681, 75.606322632704, - 75.536023884520, 75.465725136131, 75.395426387540, 75.325127638752, 75.254828889767, - 75.184530140590, 75.114231391222, 75.043932641667, 74.973633891927, 74.903335142004, - 74.833036391902, 74.762737641623, 74.692438891169, 74.622140140542, 74.551841389746, - 74.481542638781, 74.411243887652, 74.340945136359, 74.270646384904, 74.200347633291, - 74.130048881522, 74.059750129597, 73.989451377520, 73.919152625292, 73.848853872916, - 73.778555120392, 73.708256367724, 73.637957614913, 73.567658861960, 73.497360108869, - 73.427061355639, 73.356762602274, 73.286463848775, 73.216165095143, 73.145866341381, - 73.075567587489, 73.005268833470, 72.934970079325, 72.864671325055, 72.794372570663, - 72.724073816149, 72.653775061515, 72.583476306763, 72.513177551893, 72.442878796909, - 72.372580041809, 72.302281286597, 72.231982531274, 72.161683775840, 72.091385020297, - 72.021086264647, 71.950787508890, 71.880488753029, 71.810189997063, 71.739891240994, - 71.669592484824, 71.599293728554, 71.528994972184, 71.458696215717, 71.388397459152, - 71.318098702491, 71.247799945736, 71.177501188887, 71.107202431945, 71.036903674912, - 70.966604917788, 70.896306160574, 70.826007403271, 70.755708645881, 70.685409888405, - 70.615111130842, 70.544812373195, 70.474513615463, 70.404214857649, 70.333916099752, - 70.263617341774, 70.193318583716, 70.123019825578, 70.052721067362, 69.982422309068, - 69.912123550696, 69.841824792249, 69.771526033726, 69.701227275128, 69.630928516457, - 69.560629757712, 69.490330998895, 69.420032240006, 69.349733481047, 69.279434722017, - 69.209135962918, 69.138837203750, 69.068538444514, 68.998239685210, 68.927940925840, - 68.857642166404, 68.787343406903, 68.717044647337, 68.646745887706, 68.576447128012, - 68.506148368256, 68.435849608437, 68.365550848557, 68.295252088615, 68.224953328613, - 68.154654568552, 68.084355808431, 68.014057048251, 67.943758288014, 67.873459527718, - 67.803160767366, 67.732862006957, 67.662563246492, 67.592264485972, 67.521965725397, - 67.451666964768, 67.381368204085, 67.311069443348, 67.240770682558, 67.170471921717, - 67.100173160823, 67.029874399877, 66.959575638881, 66.889276877835, 66.818978116738, - 66.748679355592, 66.678380594396, 66.608081833152, 66.537783071860, 66.467484310520, - 66.397185549132, 66.326886787698, 66.256588026217, 66.186289264690, 66.115990503117, - 66.045691741499, 65.975392979836, 65.905094218128, 65.834795456377, 65.764496694581, - 65.694197932743, 65.623899170861, 65.553600408936, 65.483301646970, 65.413002884961, - 65.342704122911, 65.272405360820, 65.202106598688, 65.131807836516, 65.061509074303, - 64.991210312051, 64.920911549759, 64.850612787428, 64.780314025058, 64.710015262650, - 64.639716500204, 64.569417737720, 64.499118975198, 64.428820212639, 64.358521450043, - 64.288222687411, 64.217923924742, 64.147625162038, 64.077326399297, 64.007027636522, - 63.936728873711, 63.866430110865, 63.796131347985, 63.725832585070, 63.655533822122, - 63.585235059139, 63.514936296124, 63.444637533075, 63.374338769993, 63.304040006879, - 63.233741243732, 63.163442480553, 63.093143717342, 63.022844954099, 62.952546190825, - 62.882247427520, 62.811948664184, 62.741649900817, 62.671351137420, 62.601052373993, - 62.530753610535, 62.460454847048, 62.390156083532, 62.319857319986, 62.249558556411, - 62.179259792807, 62.108961029175, 62.038662265514, 61.968363501825, 61.898064738108, - 61.827765974364, 61.757467210592, 61.687168446792, 61.616869682965, 61.546570919112, - 61.476272155231, 61.405973391324, 61.335674627391, 61.265375863432, 61.195077099446, - 61.124778335435, 61.054479571399, 60.984180807337, 60.913882043249, 60.843583279137, - 60.773284515000, 60.702985750838, 60.632686986652, 60.562388222441, 60.492089458207, - 60.421790693948, 60.351491929665, 60.281193165359, 60.210894401030, 60.140595636677, - 60.070296872301, 59.999998107902, 59.929699343481, 59.859400579037, 59.789101814570, - 59.718803050081, 59.648504285570, 59.578205521036, 59.507906756481, 59.437607991905, - 59.367309227306, 59.297010462687, 59.226711698046, 59.156412933384, 59.086114168701, - 59.015815403997, 58.945516639273, 58.875217874528, 58.804919109762, 58.734620344977, - 58.664321580171, 58.594022815345, 58.523724050500, 58.453425285635, 58.383126520750, - 58.312827755846, 58.242528990922, 58.172230225979, 58.101931461018, 58.031632696037, - 57.961333931038, 57.891035166019, 57.820736400983, 57.750437635927, 57.680138870854, - 57.609840105762, 57.539541340653, 57.469242575525, 57.398943810380, 57.328645045216, - 57.258346280036, 57.188047514837, 57.117748749622, 57.047449984389, 56.977151219139, - 56.906852453871, 56.836553688587, 56.766254923287, 56.695956157969, 56.625657392635, - 56.555358627284, 56.485059861917, 56.414761096534, 56.344462331134, 56.274163565718, - 56.203864800287, 56.133566034839, 56.063267269376, 55.992968503897, 55.922669738403, - 55.852370972893, 55.782072207367, 55.711773441826, 55.641474676271, 55.571175910699, - 55.500877145113, 55.430578379513, 55.360279613897, 55.289980848266, 55.219682082621, - 55.149383316961, 55.079084551287, 55.008785785599, 54.938487019896, 54.868188254179, - 54.797889488448, 54.727590722702, 54.657291956943, 54.586993191170, 54.516694425384, - 54.446395659583, 54.376096893769, 54.305798127941, 54.235499362100, 54.165200596246, - 54.094901830378, 54.024603064497, 53.954304298603, 53.884005532696, 53.813706766776, - 53.743408000843, 53.673109234897, 53.602810468939, 53.532511702968, 53.462212936984, - 53.391914170988, 53.321615404979, 53.251316638958, 53.181017872924, 53.110719106879, - 53.040420340821, 52.970121574751, 52.899822808669, 52.829524042575, 52.759225276469, - 52.688926510352, 52.618627744222, 52.548328978081, 52.478030211928, 52.407731445764, - 52.337432679589, 52.267133913402, 52.196835147203, 52.126536380993, 52.056237614772, - 51.985938848540, 51.915640082297, 51.845341316043, 51.775042549778, 51.704743783502, - 51.634445017215, 51.564146250917, 51.493847484609, 51.423548718289, 51.353249951960, - 51.282951185619, 51.212652419269, 51.142353652907, 51.072054886536, 51.001756120154, - 50.931457353762, 50.861158587360, 50.790859820947, 50.720561054525, 50.650262288092, - 50.579963521649, 50.509664755197, 50.439365988735, 50.369067222262, 50.298768455780, - 50.228469689289, 50.158170922787, 50.087872156277, 50.017573389756, 49.947274623226, - 49.876975856687, 49.806677090138, 49.736378323580, 49.666079557012, 49.595780790436, - 49.525482023850, 49.455183257255, 49.384884490651, 49.314585724037, 49.244286957415, - 49.173988190784, 49.103689424144, 49.033390657495, 48.963091890837, 48.892793124171, - 48.822494357496, 48.752195590812, 48.681896824119, 48.611598057418, 48.541299290709, - 48.471000523990, 48.400701757264, 48.330402990529, 48.260104223786, 48.189805457034, - 48.119506690274, 48.049207923506, 47.978909156730, 47.908610389945, 47.838311623152, - 47.768012856352, 47.697714089543, 47.627415322726, 47.557116555902, 47.486817789069, - 47.416519022229, 47.346220255381, 47.275921488525, 47.205622721661, 47.135323954790, - 47.065025187911, 46.994726421024, 46.924427654130, 46.854128887228, 46.783830120319, - 46.713531353402, 46.643232586478, 46.572933819546, 46.502635052608, 46.432336285661, - 46.362037518708, 46.291738751747, 46.221439984779, 46.151141217804, 46.080842450822, - 46.010543683832, 45.940244916836, 45.869946149832, 45.799647382822, 45.729348615805, - 45.659049848780, 45.588751081749, 45.518452314711, 45.448153547666, 45.377854780614, - 45.307556013556, 45.237257246491, 45.166958479419, 45.096659712340, 45.026360945255, - 44.956062178164, 44.885763411065, 44.815464643961, 44.745165876849, 44.674867109732, - 44.604568342607, 44.534269575477, 44.463970808340, 44.393672041197, 44.323373274047, - 44.253074506891, 44.182775739729, 44.112476972561, 44.042178205386, 43.971879438205, - 43.901580671019, 43.831281903826, 43.760983136627, 43.690684369422, 43.620385602211, - 43.550086834994, 43.479788067771, 43.409489300542, 43.339190533307, 43.268891766067, - 43.198592998820, 43.128294231568, 43.057995464310, 42.987696697046, 42.917397929776, - 42.847099162501, 42.776800395220, 42.706501627934, 42.636202860641, 42.565904093344, - 42.495605326040, 42.425306558731, 42.355007791417, 42.284709024097, 42.214410256772, - 42.144111489441, 42.073812722104, 42.003513954763, 41.933215187416, 41.862916420064, - 41.792617652706, 41.722318885343, 41.652020117975, 41.581721350601, 41.511422583223, - 41.441123815839, 41.370825048450, 41.300526281056, 41.230227513656, 41.159928746252, - 41.089629978843, 41.019331211428, 40.949032444009, 40.878733676584, 40.808434909155, - 40.738136141720, 40.667837374281, 40.597538606836, 40.527239839387, 40.456941071933, - 40.386642304474, 40.316343537011, 40.246044769542, 40.175746002069, 40.105447234591, - 40.035148467108, 39.964849699620, 39.894550932128, 39.824252164631, 39.753953397130, - 39.683654629624, 39.613355862113, 39.543057094598, 39.472758327078, 39.402459559553, - 39.332160792024, 39.261862024491, 39.191563256953, 39.121264489410, 39.050965721863, - 38.980666954312, 38.910368186756, 38.840069419196, 38.769770651632, 38.699471884063, - 38.629173116490, 38.558874348913, 38.488575581331, 38.418276813745, 38.347978046155, - 38.277679278560, 38.207380510961, 38.137081743359, 38.066782975752, 37.996484208140, - 37.926185440525, 37.855886672906, 37.785587905282, 37.715289137654, 37.644990370023, - 37.574691602387, 37.504392834747, 37.434094067103, 37.363795299455, 37.293496531804, - 37.223197764148, 37.152898996488, 37.082600228825, 37.012301461157, 36.942002693486, - 36.871703925811, 36.801405158132, 36.731106390449, 36.660807622762, 36.590508855071, - 36.520210087377, 36.449911319679, 36.379612551977, 36.309313784271, 36.239015016562, - 36.168716248849, 36.098417481132, 36.028118713412, 35.957819945688, 35.887521177960, - 35.817222410229, 35.746923642494, 35.676624874755, 35.606326107013, 35.536027339267, - 35.465728571518, 35.395429803765, 35.325131036009, 35.254832268249, 35.184533500486, - 35.114234732719, 35.043935964949, 34.973637197175, 34.903338429398, 34.833039661618, - 34.762740893834, 34.692442126047, 34.622143358256, 34.551844590462, 34.481545822665, - 34.411247054864, 34.340948287060, 34.270649519253, 34.200350751443, 34.130051983629, - 34.059753215812, 33.989454447991, 33.919155680168, 33.848856912341, 33.778558144511, - 33.708259376678, 33.637960608842, 33.567661841002, 33.497363073160, 33.427064305314, - 33.356765537465, 33.286466769613, 33.216168001758, 33.145869233900, 33.075570466039, - 33.005271698175, 32.934972930308, 32.864674162437, 32.794375394564, 32.724076626688, - 32.653777858809, 32.583479090926, 32.513180323041, 32.442881555153, 32.372582787262, - 32.302284019368, 32.231985251471, 32.161686483571, 32.091387715668, 32.021088947763, - 31.950790179854, 31.880491411943, 31.810192644029, 31.739893876112, 31.669595108192, - 31.599296340270, 31.528997572344, 31.458698804416, 31.388400036485, 31.318101268552, - 31.247802500615, 31.177503732676, 31.107204964734, 31.036906196790, 30.966607428843, - 30.896308660893, 30.826009892940, 30.755711124985, 30.685412357027, 30.615113589066, - 30.544814821103, 30.474516053137, 30.404217285169, 30.333918517198, 30.263619749224, - 30.193320981248, 30.123022213270, 30.052723445288, 29.982424677304, 29.912125909318, - 29.841827141329, 29.771528373338, 29.701229605344, 29.630930837348, 29.560632069349, - 29.490333301348, 29.420034533344, 29.349735765338, 29.279436997329, 29.209138229318, - 29.138839461305, 29.068540693289, 28.998241925270, 28.927943157250, 28.857644389227, - 28.787345621201, 28.717046853174, 28.646748085144, 28.576449317111, 28.506150549077, - 28.435851781039, 28.365553013000, 28.295254244959, 28.224955476915, 28.154656708868, - 28.084357940820, 28.014059172769, 27.943760404716, 27.873461636661, 27.803162868604, - 27.732864100544, 27.662565332482, 27.592266564418, 27.521967796352, 27.451669028284, - 27.381370260213, 27.311071492140, 27.240772724065, 27.170473955988, 27.100175187909, - 27.029876419828, 26.959577651744, 26.889278883659, 26.818980115571, 26.748681347482, - 26.678382579390, 26.608083811296, 26.537785043200, 26.467486275102, 26.397187507002, - 26.326888738900, 26.256589970796, 26.186291202690, 26.115992434582, 26.045693666472, - 25.975394898360, 25.905096130246, 25.834797362130, 25.764498594012, 25.694199825892, - 25.623901057770, 25.553602289646, 25.483303521520, 25.413004753393, 25.342705985263, - 25.272407217131, 25.202108448998, 25.131809680863, 25.061510912726, 24.991212144586, - 24.920913376446, 24.850614608303, 24.780315840158, 24.710017072012, 24.639718303863, - 24.569419535713, 24.499120767561, 24.428821999407, 24.358523231252, 24.288224463094, - 24.217925694935, 24.147626926774, 24.077328158612, 24.007029390447, 23.936730622281, - 23.866431854113, 23.796133085943, 23.725834317772, 23.655535549599, 23.585236781424, - 23.514938013247, 23.444639245069, 23.374340476889, 23.304041708707, 23.233742940524, - 23.163444172339, 23.093145404152, 23.022846635964, 22.952547867774, 22.882249099582, - 22.811950331389, 22.741651563194, 22.671352794997, 22.601054026799, 22.530755258600, - 22.460456490398, 22.390157722195, 22.319858953991, 22.249560185785, 22.179261417577, - 22.108962649368, 22.038663881157, 21.968365112945, 21.898066344731, 21.827767576515, - 21.757468808298, 21.687170040080, 21.616871271860, 21.546572503638, 21.476273735415, - 21.405974967191, 21.335676198965, 21.265377430738, 21.195078662509, 21.124779894278, - 21.054481126046, 20.984182357813, 20.913883589578, 20.843584821342, 20.773286053104, - 20.702987284865, 20.632688516625, 20.562389748383, 20.492090980140, 20.421792211895, - 20.351493443649, 20.281194675401, 20.210895907153, 20.140597138902, 20.070298370651, - 19.999999602398, 19.929700834143, 19.859402065888, 19.789103297631, 19.718804529372, - 19.648505761113, 19.578206992852, 19.507908224589, 19.437609456326, 19.367310688061, - 19.297011919794, 19.226713151527, 19.156414383258, 19.086115614988, 19.015816846717, - 18.945518078444, 18.875219310170, 18.804920541895, 18.734621773618, 18.664323005341, - 18.594024237062, 18.523725468782, 18.453426700500, 18.383127932218, 18.312829163934, - 18.242530395649, 18.172231627363, 18.101932859075, 18.031634090787, 17.961335322497, - 17.891036554206, 17.820737785914, 17.750439017621, 17.680140249326, 17.609841481031, - 17.539542712734, 17.469243944436, 17.398945176137, 17.328646407837, 17.258347639536, - 17.188048871233, 17.117750102930, 17.047451334625, 16.977152566319, 16.906853798012, - 16.836555029705, 16.766256261396, 16.695957493085, 16.625658724774, 16.555359956462, - 16.485061188149, 16.414762419834, 16.344463651519, 16.274164883202, 16.203866114885, - 16.133567346566, 16.063268578247, 15.992969809926, 15.922671041605, 15.852372273282, - 15.782073504958, 15.711774736634, 15.641475968308, 15.571177199981, 15.500878431654, - 15.430579663325, 15.360280894996, 15.289982126665, 15.219683358334, 15.149384590001, - 15.079085821668, 15.008787053333, 14.938488284998, 14.868189516662, 14.797890748324, - 14.727591979986, 14.657293211647, 14.586994443307, 14.516695674966, 14.446396906625, - 14.376098138282, 14.305799369938, 14.235500601594, 14.165201833248, 14.094903064902, - 14.024604296555, 13.954305528207, 13.884006759858, 13.813707991508, 13.743409223158, - 13.673110454806, 13.602811686454, 13.532512918101, 13.462214149747, 13.391915381392, - 13.321616613036, 13.251317844680, 13.181019076323, 13.110720307964, 13.040421539606, - 12.970122771246, 12.899824002885, 12.829525234524, 12.759226466162, 12.688927697799, - 12.618628929435, 12.548330161071, 12.478031392706, 12.407732624340, 12.337433855973, - 12.267135087606, 12.196836319237, 12.126537550868, 12.056238782499, 11.985940014128, - 11.915641245757, 11.845342477385, 11.775043709013, 11.704744940639, 11.634446172265, - 11.564147403891, 11.493848635515, 11.423549867139, 11.353251098762, 11.282952330385, - 11.212653562006, 11.142354793628, 11.072056025248, 11.001757256868, 10.931458488487, - 10.861159720105, 10.790860951723, 10.720562183340, 10.650263414957, 10.579964646573, - 10.509665878188, 10.439367109803, 10.369068341417, 10.298769573030, 10.228470804643, - 10.158172036255, 10.087873267866, 10.017574499477, 9.947275731087, 9.876976962697, - 9.806678194306, 9.736379425915, 9.666080657523, 9.595781889130, 9.525483120737, - 9.455184352343, 9.384885583949, 9.314586815554, 9.244288047159, 9.173989278763, - 9.103690510366, 9.033391741969, 8.963092973571, 8.892794205173, 8.822495436775, - 8.752196668376, 8.681897899976, 8.611599131576, 8.541300363175, 8.471001594774, - 8.400702826372, 8.330404057970, 8.260105289567, 8.189806521164, 8.119507752760, - 8.049208984356, 7.978910215951, 7.908611447546, 7.838312679141, 7.768013910735, - 7.697715142328, 7.627416373921, 7.557117605514, 7.486818837106, 7.416520068698, - 7.346221300289, 7.275922531880, 7.205623763470, 7.135324995060, 7.065026226650, - 6.994727458239, 6.924428689828, 6.854129921416, 6.783831153004, 6.713532384592, - 6.643233616179, 6.572934847765, 6.502636079352, 6.432337310938, 6.362038542524, - 6.291739774109, 6.221441005694, 6.151142237278, 6.080843468862, 6.010544700446, - 5.940245932030, 5.869947163613, 5.799648395196, 5.729349626778, 5.659050858360, - 5.588752089942, 5.518453321523, 5.448154553105, 5.377855784685, 5.307557016266, - 5.237258247846, 5.166959479426, 5.096660711006, 5.026361942585, 4.956063174164, - 4.885764405743, 4.815465637321, 4.745166868899, 4.674868100477, 4.604569332055, - 4.534270563632, 4.463971795209, 4.393673026786, 4.323374258363, 4.253075489939, - 4.182776721515, 4.112477953091, 4.042179184666, 3.971880416242, 3.901581647817, - 3.831282879392, 3.760984110967, 3.690685342541, 3.620386574115, 3.550087805689, - 3.479789037263, 3.409490268837, 3.339191500410, 3.268892731984, 3.198593963557, - 3.128295195130, 3.057996426702, 2.987697658275, 2.917398889847, 2.847100121419, - 2.776801352991, 2.706502584563, 2.636203816135, 2.565905047706, 2.495606279278, - 2.425307510849, 2.355008742420, 2.284709973991, 2.214411205562, 2.144112437133, - 2.073813668703, 2.003514900274, 1.933216131844, 1.862917363415, 1.792618594985, - 1.722319826555, 1.652021058125, 1.581722289695, 1.511423521264, 1.441124752834, - 1.370825984404, 1.300527215973, 1.230228447543, 1.159929679112, 1.089630910681, - 1.019332142250, 0.949033373820, 0.878734605389, 0.808435836958, 0.738137068527, - 0.667838300096, 0.597539531665, 0.527240763234, 0.456941994803, 0.386643226372, - 0.316344457940, 0.246045689509, 0.175746921078, 0.105448152647, 0.035149384216 - )) +DEFINE_GAUSSIAN_LATITUDES( + 1280, LIST( 89.946187715666, 89.876478353332, 89.806357319542, 89.736143271610, 89.665893941216, 89.595627537554, + 89.525351592371, 89.455069779123, 89.384784101392, 89.314495744374, 89.244205453805, 89.173913722284, + 89.103620888239, 89.033327191846, 88.963032808263, 88.892737868231, 88.822442471310, 88.752146694651, + 88.681850598962, 88.611554232668, 88.541257634869, 88.470960837475, 88.400663866794, 88.330366744703, + 88.260069489546, 88.189772116821, 88.119474639706, 88.049177069484, 87.978879415867, 87.908581687262, + 87.838283890982, 87.767986033420, 87.697688120188, 87.627390156234, 87.557092145936, 87.486794093181, + 87.416496001435, 87.346197873796, 87.275899713042, 87.205601521672, 87.135303301940, 87.065005055883, + 86.994706785348, 86.924408492014, 86.854110177409, 86.783811842927, 86.713513489844, 86.643215119329, + 86.572916732453, 86.502618330204, 86.432319913490, 86.362021483149, 86.291723039957, 86.221424584631, + 86.151126117835, 86.080827640187, 86.010529152260, 85.940230654589, 85.869932147670, 85.799633631968, + 85.729335107917, 85.659036575923, 85.588738036364, 85.518439489598, 85.448140935957, 85.377842375757, + 85.307543809290, 85.237245236836, 85.166946658654, 85.096648074992, 85.026349486082, 84.956050892143, + 84.885752293383, 84.815453689997, 84.745155082172, 84.674856470083, 84.604557853897, 84.534259233771, + 84.463960609857, 84.393661982296, 84.323363351224, 84.253064716770, 84.182766079057, 84.112467438200, + 84.042168794312, 83.971870147499, 83.901571497861, 83.831272845495, 83.760974190494, 83.690675532945, + 83.620376872933, 83.550078210538, 83.479779545838, 83.409480878906, 83.339182209812, 83.268883538625, + 83.198584865410, 83.128286190228, 83.057987513139, 82.987688834201, 82.917390153469, 82.847091470996, + 82.776792786832, 82.706494101027, 82.636195413627, 82.565896724678, 82.495598034223, 82.425299342304, + 82.355000648962, 82.284701954235, 82.214403258161, 82.144104560776, 82.073805862115, 82.003507162212, + 81.933208461099, 81.862909758807, 81.792611055367, 81.722312350809, 81.652013645159, 81.581714938446, + 81.511416230696, 81.441117521935, 81.370818812187, 81.300520101476, 81.230221389825, 81.159922677258, + 81.089623963795, 81.019325249457, 80.949026534265, 80.878727818239, 80.808429101398, 80.738130383760, + 80.667831665344, 80.597532946166, 80.527234226244, 80.456935505594, 80.386636784233, 80.316338062175, + 80.246039339436, 80.175740616030, 80.105441891972, 80.035143167276, 79.964844441954, 79.894545716020, + 79.824246989487, 79.753948262366, 79.683649534670, 79.613350806411, 79.543052077600, 79.472753348248, + 79.402454618366, 79.332155887964, 79.261857157052, 79.191558425641, 79.121259693740, 79.050960961358, + 78.980662228505, 78.910363495190, 78.840064761421, 78.769766027208, 78.699467292557, 78.629168557478, + 78.558869821978, 78.488571086065, 78.418272349746, 78.347973613030, 78.277674875922, 78.207376138430, + 78.137077400561, 78.066778662322, 77.996479923719, 77.926181184758, 77.855882445445, 77.785583705787, + 77.715284965790, 77.644986225459, 77.574687484800, 77.504388743819, 77.434090002520, 77.363791260910, + 77.293492518993, 77.223193776775, 77.152895034260, 77.082596291454, 77.012297548360, 76.941998804985, + 76.871700061331, 76.801401317404, 76.731102573208, 76.660803828747, 76.590505084026, 76.520206339048, + 76.449907593818, 76.379608848339, 76.309310102615, 76.239011356650, 76.168712610448, 76.098413864012, + 76.028115117346, 75.957816370454, 75.887517623337, 75.817218876001, 75.746920128448, 75.676621380681, + 75.606322632704, 75.536023884520, 75.465725136131, 75.395426387540, 75.325127638752, 75.254828889767, + 75.184530140590, 75.114231391222, 75.043932641667, 74.973633891927, 74.903335142004, 74.833036391902, + 74.762737641623, 74.692438891169, 74.622140140542, 74.551841389746, 74.481542638781, 74.411243887652, + 74.340945136359, 74.270646384904, 74.200347633291, 74.130048881522, 74.059750129597, 73.989451377520, + 73.919152625292, 73.848853872916, 73.778555120392, 73.708256367724, 73.637957614913, 73.567658861960, + 73.497360108869, 73.427061355639, 73.356762602274, 73.286463848775, 73.216165095143, 73.145866341381, + 73.075567587489, 73.005268833470, 72.934970079325, 72.864671325055, 72.794372570663, 72.724073816149, + 72.653775061515, 72.583476306763, 72.513177551893, 72.442878796909, 72.372580041809, 72.302281286597, + 72.231982531274, 72.161683775840, 72.091385020297, 72.021086264647, 71.950787508890, 71.880488753029, + 71.810189997063, 71.739891240994, 71.669592484824, 71.599293728554, 71.528994972184, 71.458696215717, + 71.388397459152, 71.318098702491, 71.247799945736, 71.177501188887, 71.107202431945, 71.036903674912, + 70.966604917788, 70.896306160574, 70.826007403271, 70.755708645881, 70.685409888405, 70.615111130842, + 70.544812373195, 70.474513615463, 70.404214857649, 70.333916099752, 70.263617341774, 70.193318583716, + 70.123019825578, 70.052721067362, 69.982422309068, 69.912123550696, 69.841824792249, 69.771526033726, + 69.701227275128, 69.630928516457, 69.560629757712, 69.490330998895, 69.420032240006, 69.349733481047, + 69.279434722017, 69.209135962918, 69.138837203750, 69.068538444514, 68.998239685210, 68.927940925840, + 68.857642166404, 68.787343406903, 68.717044647337, 68.646745887706, 68.576447128012, 68.506148368256, + 68.435849608437, 68.365550848557, 68.295252088615, 68.224953328613, 68.154654568552, 68.084355808431, + 68.014057048251, 67.943758288014, 67.873459527718, 67.803160767366, 67.732862006957, 67.662563246492, + 67.592264485972, 67.521965725397, 67.451666964768, 67.381368204085, 67.311069443348, 67.240770682558, + 67.170471921717, 67.100173160823, 67.029874399877, 66.959575638881, 66.889276877835, 66.818978116738, + 66.748679355592, 66.678380594396, 66.608081833152, 66.537783071860, 66.467484310520, 66.397185549132, + 66.326886787698, 66.256588026217, 66.186289264690, 66.115990503117, 66.045691741499, 65.975392979836, + 65.905094218128, 65.834795456377, 65.764496694581, 65.694197932743, 65.623899170861, 65.553600408936, + 65.483301646970, 65.413002884961, 65.342704122911, 65.272405360820, 65.202106598688, 65.131807836516, + 65.061509074303, 64.991210312051, 64.920911549759, 64.850612787428, 64.780314025058, 64.710015262650, + 64.639716500204, 64.569417737720, 64.499118975198, 64.428820212639, 64.358521450043, 64.288222687411, + 64.217923924742, 64.147625162038, 64.077326399297, 64.007027636522, 63.936728873711, 63.866430110865, + 63.796131347985, 63.725832585070, 63.655533822122, 63.585235059139, 63.514936296124, 63.444637533075, + 63.374338769993, 63.304040006879, 63.233741243732, 63.163442480553, 63.093143717342, 63.022844954099, + 62.952546190825, 62.882247427520, 62.811948664184, 62.741649900817, 62.671351137420, 62.601052373993, + 62.530753610535, 62.460454847048, 62.390156083532, 62.319857319986, 62.249558556411, 62.179259792807, + 62.108961029175, 62.038662265514, 61.968363501825, 61.898064738108, 61.827765974364, 61.757467210592, + 61.687168446792, 61.616869682965, 61.546570919112, 61.476272155231, 61.405973391324, 61.335674627391, + 61.265375863432, 61.195077099446, 61.124778335435, 61.054479571399, 60.984180807337, 60.913882043249, + 60.843583279137, 60.773284515000, 60.702985750838, 60.632686986652, 60.562388222441, 60.492089458207, + 60.421790693948, 60.351491929665, 60.281193165359, 60.210894401030, 60.140595636677, 60.070296872301, + 59.999998107902, 59.929699343481, 59.859400579037, 59.789101814570, 59.718803050081, 59.648504285570, + 59.578205521036, 59.507906756481, 59.437607991905, 59.367309227306, 59.297010462687, 59.226711698046, + 59.156412933384, 59.086114168701, 59.015815403997, 58.945516639273, 58.875217874528, 58.804919109762, + 58.734620344977, 58.664321580171, 58.594022815345, 58.523724050500, 58.453425285635, 58.383126520750, + 58.312827755846, 58.242528990922, 58.172230225979, 58.101931461018, 58.031632696037, 57.961333931038, + 57.891035166019, 57.820736400983, 57.750437635927, 57.680138870854, 57.609840105762, 57.539541340653, + 57.469242575525, 57.398943810380, 57.328645045216, 57.258346280036, 57.188047514837, 57.117748749622, + 57.047449984389, 56.977151219139, 56.906852453871, 56.836553688587, 56.766254923287, 56.695956157969, + 56.625657392635, 56.555358627284, 56.485059861917, 56.414761096534, 56.344462331134, 56.274163565718, + 56.203864800287, 56.133566034839, 56.063267269376, 55.992968503897, 55.922669738403, 55.852370972893, + 55.782072207367, 55.711773441826, 55.641474676271, 55.571175910699, 55.500877145113, 55.430578379513, + 55.360279613897, 55.289980848266, 55.219682082621, 55.149383316961, 55.079084551287, 55.008785785599, + 54.938487019896, 54.868188254179, 54.797889488448, 54.727590722702, 54.657291956943, 54.586993191170, + 54.516694425384, 54.446395659583, 54.376096893769, 54.305798127941, 54.235499362100, 54.165200596246, + 54.094901830378, 54.024603064497, 53.954304298603, 53.884005532696, 53.813706766776, 53.743408000843, + 53.673109234897, 53.602810468939, 53.532511702968, 53.462212936984, 53.391914170988, 53.321615404979, + 53.251316638958, 53.181017872924, 53.110719106879, 53.040420340821, 52.970121574751, 52.899822808669, + 52.829524042575, 52.759225276469, 52.688926510352, 52.618627744222, 52.548328978081, 52.478030211928, + 52.407731445764, 52.337432679589, 52.267133913402, 52.196835147203, 52.126536380993, 52.056237614772, + 51.985938848540, 51.915640082297, 51.845341316043, 51.775042549778, 51.704743783502, 51.634445017215, + 51.564146250917, 51.493847484609, 51.423548718289, 51.353249951960, 51.282951185619, 51.212652419269, + 51.142353652907, 51.072054886536, 51.001756120154, 50.931457353762, 50.861158587360, 50.790859820947, + 50.720561054525, 50.650262288092, 50.579963521649, 50.509664755197, 50.439365988735, 50.369067222262, + 50.298768455780, 50.228469689289, 50.158170922787, 50.087872156277, 50.017573389756, 49.947274623226, + 49.876975856687, 49.806677090138, 49.736378323580, 49.666079557012, 49.595780790436, 49.525482023850, + 49.455183257255, 49.384884490651, 49.314585724037, 49.244286957415, 49.173988190784, 49.103689424144, + 49.033390657495, 48.963091890837, 48.892793124171, 48.822494357496, 48.752195590812, 48.681896824119, + 48.611598057418, 48.541299290709, 48.471000523990, 48.400701757264, 48.330402990529, 48.260104223786, + 48.189805457034, 48.119506690274, 48.049207923506, 47.978909156730, 47.908610389945, 47.838311623152, + 47.768012856352, 47.697714089543, 47.627415322726, 47.557116555902, 47.486817789069, 47.416519022229, + 47.346220255381, 47.275921488525, 47.205622721661, 47.135323954790, 47.065025187911, 46.994726421024, + 46.924427654130, 46.854128887228, 46.783830120319, 46.713531353402, 46.643232586478, 46.572933819546, + 46.502635052608, 46.432336285661, 46.362037518708, 46.291738751747, 46.221439984779, 46.151141217804, + 46.080842450822, 46.010543683832, 45.940244916836, 45.869946149832, 45.799647382822, 45.729348615805, + 45.659049848780, 45.588751081749, 45.518452314711, 45.448153547666, 45.377854780614, 45.307556013556, + 45.237257246491, 45.166958479419, 45.096659712340, 45.026360945255, 44.956062178164, 44.885763411065, + 44.815464643961, 44.745165876849, 44.674867109732, 44.604568342607, 44.534269575477, 44.463970808340, + 44.393672041197, 44.323373274047, 44.253074506891, 44.182775739729, 44.112476972561, 44.042178205386, + 43.971879438205, 43.901580671019, 43.831281903826, 43.760983136627, 43.690684369422, 43.620385602211, + 43.550086834994, 43.479788067771, 43.409489300542, 43.339190533307, 43.268891766067, 43.198592998820, + 43.128294231568, 43.057995464310, 42.987696697046, 42.917397929776, 42.847099162501, 42.776800395220, + 42.706501627934, 42.636202860641, 42.565904093344, 42.495605326040, 42.425306558731, 42.355007791417, + 42.284709024097, 42.214410256772, 42.144111489441, 42.073812722104, 42.003513954763, 41.933215187416, + 41.862916420064, 41.792617652706, 41.722318885343, 41.652020117975, 41.581721350601, 41.511422583223, + 41.441123815839, 41.370825048450, 41.300526281056, 41.230227513656, 41.159928746252, 41.089629978843, + 41.019331211428, 40.949032444009, 40.878733676584, 40.808434909155, 40.738136141720, 40.667837374281, + 40.597538606836, 40.527239839387, 40.456941071933, 40.386642304474, 40.316343537011, 40.246044769542, + 40.175746002069, 40.105447234591, 40.035148467108, 39.964849699620, 39.894550932128, 39.824252164631, + 39.753953397130, 39.683654629624, 39.613355862113, 39.543057094598, 39.472758327078, 39.402459559553, + 39.332160792024, 39.261862024491, 39.191563256953, 39.121264489410, 39.050965721863, 38.980666954312, + 38.910368186756, 38.840069419196, 38.769770651632, 38.699471884063, 38.629173116490, 38.558874348913, + 38.488575581331, 38.418276813745, 38.347978046155, 38.277679278560, 38.207380510961, 38.137081743359, + 38.066782975752, 37.996484208140, 37.926185440525, 37.855886672906, 37.785587905282, 37.715289137654, + 37.644990370023, 37.574691602387, 37.504392834747, 37.434094067103, 37.363795299455, 37.293496531804, + 37.223197764148, 37.152898996488, 37.082600228825, 37.012301461157, 36.942002693486, 36.871703925811, + 36.801405158132, 36.731106390449, 36.660807622762, 36.590508855071, 36.520210087377, 36.449911319679, + 36.379612551977, 36.309313784271, 36.239015016562, 36.168716248849, 36.098417481132, 36.028118713412, + 35.957819945688, 35.887521177960, 35.817222410229, 35.746923642494, 35.676624874755, 35.606326107013, + 35.536027339267, 35.465728571518, 35.395429803765, 35.325131036009, 35.254832268249, 35.184533500486, + 35.114234732719, 35.043935964949, 34.973637197175, 34.903338429398, 34.833039661618, 34.762740893834, + 34.692442126047, 34.622143358256, 34.551844590462, 34.481545822665, 34.411247054864, 34.340948287060, + 34.270649519253, 34.200350751443, 34.130051983629, 34.059753215812, 33.989454447991, 33.919155680168, + 33.848856912341, 33.778558144511, 33.708259376678, 33.637960608842, 33.567661841002, 33.497363073160, + 33.427064305314, 33.356765537465, 33.286466769613, 33.216168001758, 33.145869233900, 33.075570466039, + 33.005271698175, 32.934972930308, 32.864674162437, 32.794375394564, 32.724076626688, 32.653777858809, + 32.583479090926, 32.513180323041, 32.442881555153, 32.372582787262, 32.302284019368, 32.231985251471, + 32.161686483571, 32.091387715668, 32.021088947763, 31.950790179854, 31.880491411943, 31.810192644029, + 31.739893876112, 31.669595108192, 31.599296340270, 31.528997572344, 31.458698804416, 31.388400036485, + 31.318101268552, 31.247802500615, 31.177503732676, 31.107204964734, 31.036906196790, 30.966607428843, + 30.896308660893, 30.826009892940, 30.755711124985, 30.685412357027, 30.615113589066, 30.544814821103, + 30.474516053137, 30.404217285169, 30.333918517198, 30.263619749224, 30.193320981248, 30.123022213270, + 30.052723445288, 29.982424677304, 29.912125909318, 29.841827141329, 29.771528373338, 29.701229605344, + 29.630930837348, 29.560632069349, 29.490333301348, 29.420034533344, 29.349735765338, 29.279436997329, + 29.209138229318, 29.138839461305, 29.068540693289, 28.998241925270, 28.927943157250, 28.857644389227, + 28.787345621201, 28.717046853174, 28.646748085144, 28.576449317111, 28.506150549077, 28.435851781039, + 28.365553013000, 28.295254244959, 28.224955476915, 28.154656708868, 28.084357940820, 28.014059172769, + 27.943760404716, 27.873461636661, 27.803162868604, 27.732864100544, 27.662565332482, 27.592266564418, + 27.521967796352, 27.451669028284, 27.381370260213, 27.311071492140, 27.240772724065, 27.170473955988, + 27.100175187909, 27.029876419828, 26.959577651744, 26.889278883659, 26.818980115571, 26.748681347482, + 26.678382579390, 26.608083811296, 26.537785043200, 26.467486275102, 26.397187507002, 26.326888738900, + 26.256589970796, 26.186291202690, 26.115992434582, 26.045693666472, 25.975394898360, 25.905096130246, + 25.834797362130, 25.764498594012, 25.694199825892, 25.623901057770, 25.553602289646, 25.483303521520, + 25.413004753393, 25.342705985263, 25.272407217131, 25.202108448998, 25.131809680863, 25.061510912726, + 24.991212144586, 24.920913376446, 24.850614608303, 24.780315840158, 24.710017072012, 24.639718303863, + 24.569419535713, 24.499120767561, 24.428821999407, 24.358523231252, 24.288224463094, 24.217925694935, + 24.147626926774, 24.077328158612, 24.007029390447, 23.936730622281, 23.866431854113, 23.796133085943, + 23.725834317772, 23.655535549599, 23.585236781424, 23.514938013247, 23.444639245069, 23.374340476889, + 23.304041708707, 23.233742940524, 23.163444172339, 23.093145404152, 23.022846635964, 22.952547867774, + 22.882249099582, 22.811950331389, 22.741651563194, 22.671352794997, 22.601054026799, 22.530755258600, + 22.460456490398, 22.390157722195, 22.319858953991, 22.249560185785, 22.179261417577, 22.108962649368, + 22.038663881157, 21.968365112945, 21.898066344731, 21.827767576515, 21.757468808298, 21.687170040080, + 21.616871271860, 21.546572503638, 21.476273735415, 21.405974967191, 21.335676198965, 21.265377430738, + 21.195078662509, 21.124779894278, 21.054481126046, 20.984182357813, 20.913883589578, 20.843584821342, + 20.773286053104, 20.702987284865, 20.632688516625, 20.562389748383, 20.492090980140, 20.421792211895, + 20.351493443649, 20.281194675401, 20.210895907153, 20.140597138902, 20.070298370651, 19.999999602398, + 19.929700834143, 19.859402065888, 19.789103297631, 19.718804529372, 19.648505761113, 19.578206992852, + 19.507908224589, 19.437609456326, 19.367310688061, 19.297011919794, 19.226713151527, 19.156414383258, + 19.086115614988, 19.015816846717, 18.945518078444, 18.875219310170, 18.804920541895, 18.734621773618, + 18.664323005341, 18.594024237062, 18.523725468782, 18.453426700500, 18.383127932218, 18.312829163934, + 18.242530395649, 18.172231627363, 18.101932859075, 18.031634090787, 17.961335322497, 17.891036554206, + 17.820737785914, 17.750439017621, 17.680140249326, 17.609841481031, 17.539542712734, 17.469243944436, + 17.398945176137, 17.328646407837, 17.258347639536, 17.188048871233, 17.117750102930, 17.047451334625, + 16.977152566319, 16.906853798012, 16.836555029705, 16.766256261396, 16.695957493085, 16.625658724774, + 16.555359956462, 16.485061188149, 16.414762419834, 16.344463651519, 16.274164883202, 16.203866114885, + 16.133567346566, 16.063268578247, 15.992969809926, 15.922671041605, 15.852372273282, 15.782073504958, + 15.711774736634, 15.641475968308, 15.571177199981, 15.500878431654, 15.430579663325, 15.360280894996, + 15.289982126665, 15.219683358334, 15.149384590001, 15.079085821668, 15.008787053333, 14.938488284998, + 14.868189516662, 14.797890748324, 14.727591979986, 14.657293211647, 14.586994443307, 14.516695674966, + 14.446396906625, 14.376098138282, 14.305799369938, 14.235500601594, 14.165201833248, 14.094903064902, + 14.024604296555, 13.954305528207, 13.884006759858, 13.813707991508, 13.743409223158, 13.673110454806, + 13.602811686454, 13.532512918101, 13.462214149747, 13.391915381392, 13.321616613036, 13.251317844680, + 13.181019076323, 13.110720307964, 13.040421539606, 12.970122771246, 12.899824002885, 12.829525234524, + 12.759226466162, 12.688927697799, 12.618628929435, 12.548330161071, 12.478031392706, 12.407732624340, + 12.337433855973, 12.267135087606, 12.196836319237, 12.126537550868, 12.056238782499, 11.985940014128, + 11.915641245757, 11.845342477385, 11.775043709013, 11.704744940639, 11.634446172265, 11.564147403891, + 11.493848635515, 11.423549867139, 11.353251098762, 11.282952330385, 11.212653562006, 11.142354793628, + 11.072056025248, 11.001757256868, 10.931458488487, 10.861159720105, 10.790860951723, 10.720562183340, + 10.650263414957, 10.579964646573, 10.509665878188, 10.439367109803, 10.369068341417, 10.298769573030, + 10.228470804643, 10.158172036255, 10.087873267866, 10.017574499477, 9.947275731087, 9.876976962697, + 9.806678194306, 9.736379425915, 9.666080657523, 9.595781889130, 9.525483120737, 9.455184352343, + 9.384885583949, 9.314586815554, 9.244288047159, 9.173989278763, 9.103690510366, 9.033391741969, + 8.963092973571, 8.892794205173, 8.822495436775, 8.752196668376, 8.681897899976, 8.611599131576, + 8.541300363175, 8.471001594774, 8.400702826372, 8.330404057970, 8.260105289567, 8.189806521164, + 8.119507752760, 8.049208984356, 7.978910215951, 7.908611447546, 7.838312679141, 7.768013910735, + 7.697715142328, 7.627416373921, 7.557117605514, 7.486818837106, 7.416520068698, 7.346221300289, + 7.275922531880, 7.205623763470, 7.135324995060, 7.065026226650, 6.994727458239, 6.924428689828, + 6.854129921416, 6.783831153004, 6.713532384592, 6.643233616179, 6.572934847765, 6.502636079352, + 6.432337310938, 6.362038542524, 6.291739774109, 6.221441005694, 6.151142237278, 6.080843468862, + 6.010544700446, 5.940245932030, 5.869947163613, 5.799648395196, 5.729349626778, 5.659050858360, + 5.588752089942, 5.518453321523, 5.448154553105, 5.377855784685, 5.307557016266, 5.237258247846, + 5.166959479426, 5.096660711006, 5.026361942585, 4.956063174164, 4.885764405743, 4.815465637321, + 4.745166868899, 4.674868100477, 4.604569332055, 4.534270563632, 4.463971795209, 4.393673026786, + 4.323374258363, 4.253075489939, 4.182776721515, 4.112477953091, 4.042179184666, 3.971880416242, + 3.901581647817, 3.831282879392, 3.760984110967, 3.690685342541, 3.620386574115, 3.550087805689, + 3.479789037263, 3.409490268837, 3.339191500410, 3.268892731984, 3.198593963557, 3.128295195130, + 3.057996426702, 2.987697658275, 2.917398889847, 2.847100121419, 2.776801352991, 2.706502584563, + 2.636203816135, 2.565905047706, 2.495606279278, 2.425307510849, 2.355008742420, 2.284709973991, + 2.214411205562, 2.144112437133, 2.073813668703, 2.003514900274, 1.933216131844, 1.862917363415, + 1.792618594985, 1.722319826555, 1.652021058125, 1.581722289695, 1.511423521264, 1.441124752834, + 1.370825984404, 1.300527215973, 1.230228447543, 1.159929679112, 1.089630910681, 1.019332142250, + 0.949033373820, 0.878734605389, 0.808435836958, 0.738137068527, 0.667838300096, 0.597539531665, + 0.527240763234, 0.456941994803, 0.386643226372, 0.316344457940, 0.246045689509, 0.175746921078, + 0.105448152647, 0.035149384216 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N16.cc b/src/atlas/grid/detail/spacing/gaussian/N16.cc index 22fee0626..5bb5fdaa0 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N16.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N16.cc @@ -7,27 +7,13 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(16, LIST( - 85.7605871204438159, - 80.2687790722500125, - 74.7445403686357679, - 69.2129761693708616, - 63.6786355610968613, - 58.1429540492032828, - 52.6065260343452650, - 47.0696420596876806, - 41.5324612466560765, - 35.9950784112715994, - 30.4575539611520938, - 24.9199286299486111, - 19.3822313464343878, - 13.8444837343848572, - 8.3067028565188039, - 2.7689030077360099 - )) +DEFINE_GAUSSIAN_LATITUDES( 16, + LIST( 85.7605871204438159, 80.2687790722500125, 74.7445403686357679, 69.2129761693708616, + 63.6786355610968613, 58.1429540492032828, 52.6065260343452650, 47.0696420596876806, + 41.5324612466560765, 35.9950784112715994, 30.4575539611520938, 24.9199286299486111, + 19.3822313464343878, 13.8444837343848572, 8.3067028565188039, 2.7689030077360099 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N160.cc b/src/atlas/grid/detail/spacing/gaussian/N160.cc index 5939d8375..ce185f4d9 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N160.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N160.cc @@ -7,43 +7,36 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(160,LIST( - 89.570089550607, 89.013176131022, 88.452973836713, 87.892028445344, 87.330801179738, - 86.769437514528, 86.207997621423, 85.646510847953, 85.084993200912, 84.523454148914, - 83.961899649718, 83.400333638737, 82.838758819710, 82.277177111434, 81.715589913266, - 81.153998269713, 80.592402976178, 80.030804649031, 79.469203773292, 78.907600735838, - 78.345995849036, 77.784389367849, 77.222781502445, 76.661172427620, 76.099562289938, - 75.537951213208, 74.976339302737, 74.414726648662, 73.853113328584, 73.291499409676, - 72.729884950380, 72.168270001775, 71.606654608708, 71.045038810711, 70.483422642771, - 69.921806135960, 69.360189317972, 68.798572213565, 68.236954844948, 67.675337232092, - 67.113719393011, 66.552101343996, 65.990483099813, 65.428864673879, 64.867246078414, - 64.305627324571, 63.744008422549, 63.182389381694, 62.620770210586, 62.059150917117, - 61.497531508556, 60.935911991615, 60.374292372493, 59.812672656933, 59.251052850257, - 58.689432957406, 58.127812982976, 57.566192931243, 57.004572806194, 56.442952611549, - 55.881332350787, 55.319712027158, 54.758091643709, 54.196471203297, 53.634850708600, - 53.073230162138, 52.511609566278, 51.949988923250, 51.388368235154, 50.826747503971, - 50.265126731571, 49.703505919720, 49.141885070089, 48.580264184257, 48.018643263723, - 47.457022309904, 46.895401324147, 46.333780307729, 45.772159261862, 45.210538187702, - 44.648917086344, 44.087295958835, 43.525674806167, 42.964053629291, 42.402432429111, - 41.840811206489, 41.279189962251, 40.717568697184, 40.155947412042, 39.594326107546, - 39.032704784385, 38.471083443221, 37.909462084686, 37.347840709389, 36.786219317912, - 36.224597910814, 35.662976488634, 35.101355051887, 34.539733601070, 33.978112136661, - 33.416490659120, 32.854869168890, 32.293247666397, 31.731626152053, 31.170004626255, - 30.608383089386, 30.046761541816, 29.485139983902, 28.923518415990, 28.361896838413, - 27.800275251495, 27.238653655548, 26.677032050875, 26.115410437771, 25.553788816520, - 24.992167187398, 24.430545550672, 23.868923906604, 23.307302255447, 22.745680597445, - 22.184058932838, 21.622437261859, 21.060815584735, 20.499193901686, 19.937572212927, - 19.375950518668, 18.814328819115, 18.252707114466, 17.691085404918, 17.129463690661, - 16.567841971882, 16.006220248764, 15.444598521486, 14.882976790224, 14.321355055149, - 13.759733316430, 13.198111574234, 12.636489828723, 12.074868080057, 11.513246328393, - 10.951624573887, 10.390002816691, 9.828381056956, 9.266759294829, 8.705137530459, - 8.143515763989, 7.581893995562, 7.020272225320, 6.458650453403, 5.897028679950, - 5.335406905098, 4.773785128984, 4.212163351743, 3.650541573510, 3.088919794419, - 2.527298014602, 1.965676234193, 1.404054453324, 0.842432672126, 0.280810890730 - )) +DEFINE_GAUSSIAN_LATITUDES( + 160, LIST( 89.570089550607, 89.013176131022, 88.452973836713, 87.892028445344, 87.330801179738, 86.769437514528, + 86.207997621423, 85.646510847953, 85.084993200912, 84.523454148914, 83.961899649718, 83.400333638737, + 82.838758819710, 82.277177111434, 81.715589913266, 81.153998269713, 80.592402976178, 80.030804649031, + 79.469203773292, 78.907600735838, 78.345995849036, 77.784389367849, 77.222781502445, 76.661172427620, + 76.099562289938, 75.537951213208, 74.976339302737, 74.414726648662, 73.853113328584, 73.291499409676, + 72.729884950380, 72.168270001775, 71.606654608708, 71.045038810711, 70.483422642771, 69.921806135960, + 69.360189317972, 68.798572213565, 68.236954844948, 67.675337232092, 67.113719393011, 66.552101343996, + 65.990483099813, 65.428864673879, 64.867246078414, 64.305627324571, 63.744008422549, 63.182389381694, + 62.620770210586, 62.059150917117, 61.497531508556, 60.935911991615, 60.374292372493, 59.812672656933, + 59.251052850257, 58.689432957406, 58.127812982976, 57.566192931243, 57.004572806194, 56.442952611549, + 55.881332350787, 55.319712027158, 54.758091643709, 54.196471203297, 53.634850708600, 53.073230162138, + 52.511609566278, 51.949988923250, 51.388368235154, 50.826747503971, 50.265126731571, 49.703505919720, + 49.141885070089, 48.580264184257, 48.018643263723, 47.457022309904, 46.895401324147, 46.333780307729, + 45.772159261862, 45.210538187702, 44.648917086344, 44.087295958835, 43.525674806167, 42.964053629291, + 42.402432429111, 41.840811206489, 41.279189962251, 40.717568697184, 40.155947412042, 39.594326107546, + 39.032704784385, 38.471083443221, 37.909462084686, 37.347840709389, 36.786219317912, 36.224597910814, + 35.662976488634, 35.101355051887, 34.539733601070, 33.978112136661, 33.416490659120, 32.854869168890, + 32.293247666397, 31.731626152053, 31.170004626255, 30.608383089386, 30.046761541816, 29.485139983902, + 28.923518415990, 28.361896838413, 27.800275251495, 27.238653655548, 26.677032050875, 26.115410437771, + 25.553788816520, 24.992167187398, 24.430545550672, 23.868923906604, 23.307302255447, 22.745680597445, + 22.184058932838, 21.622437261859, 21.060815584735, 20.499193901686, 19.937572212927, 19.375950518668, + 18.814328819115, 18.252707114466, 17.691085404918, 17.129463690661, 16.567841971882, 16.006220248764, + 15.444598521486, 14.882976790224, 14.321355055149, 13.759733316430, 13.198111574234, 12.636489828723, + 12.074868080057, 11.513246328393, 10.951624573887, 10.390002816691, 9.828381056956, 9.266759294829, + 8.705137530459, 8.143515763989, 7.581893995562, 7.020272225320, 6.458650453403, 5.897028679950, + 5.335406905098, 4.773785128984, 4.212163351743, 3.650541573510, 3.088919794419, 2.527298014602, + 1.965676234193, 1.404054453324, 0.842432672126, 0.280810890730 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N1600.cc b/src/atlas/grid/detail/spacing/gaussian/N1600.cc index 3f9e23b2a..8ace5abcc 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N1600.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N1600.cc @@ -7,331 +7,274 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(1600,LIST( - 89.956948491058, 89.901178822991, 89.845079804890, 89.788906372571, 89.732704713178, - 89.676489394638, 89.620266442582, 89.564038795892, 89.507808057494, 89.451575175583, - 89.395340746771, 89.339105165153, 89.282868701480, 89.226631547902, 89.170393844551, - 89.114155696023, 89.057917181969, 89.001678364113, 88.945439291023, 88.889200001442, - 88.832960526648, 88.776720892172, 88.720481119062, 88.664241224818, 88.608001224118, - 88.551761129360, 88.495520951086, 88.439280698324, 88.383040378843, 88.326799999369, - 88.270559565753, 88.214319083110, 88.158078555930, 88.101837988170, 88.045597383333, - 87.989356744529, 87.933116074532, 87.876875375818, 87.820634650612, 87.764393900912, - 87.708153128521, 87.651912335070, 87.595671522036, 87.539430690761, 87.483189842469, - 87.426948978275, 87.370708099200, 87.314467206178, 87.258226300067, 87.201985381657, - 87.145744451675, 87.089503510791, 87.033262559625, 86.977021598752, 86.920780628702, - 86.864539649971, 86.808298663016, 86.752057668265, 86.695816666116, 86.639575656940, - 86.583334641085, 86.527093618874, 86.470852590613, 86.414611556584, 86.358370517056, - 86.302129472280, 86.245888422491, 86.189647367911, 86.133406308749, 86.077165245203, - 86.020924177459, 85.964683105691, 85.908442030065, 85.852200950740, 85.795959867862, - 85.739718781574, 85.683477692007, 85.627236599289, 85.570995503540, 85.514754404873, - 85.458513303398, 85.402272199216, 85.346031092427, 85.289789983123, 85.233548871394, - 85.177307757325, 85.121066640996, 85.064825522485, 85.008584401865, 84.952343279207, - 84.896102154578, 84.839861028043, 84.783619899663, 84.727378769498, 84.671137637604, - 84.614896504035, 84.558655368843, 84.502414232077, 84.446173093787, 84.389931954017, - 84.333690812811, 84.277449670213, 84.221208526262, 84.164967380998, 84.108726234457, - 84.052485086678, 83.996243937694, 83.940002787538, 83.883761636244, 83.827520483842, - 83.771279330362, 83.715038175834, 83.658797020285, 83.602555863742, 83.546314706230, - 83.490073547776, 83.433832388404, 83.377591228136, 83.321350066995, 83.265108905004, - 83.208867742183, 83.152626578553, 83.096385414133, 83.040144248943, 82.983903083002, - 82.927661916327, 82.871420748935, 82.815179580843, 82.758938412069, 82.702697242626, - 82.646456072532, 82.590214901800, 82.533973730445, 82.477732558482, 82.421491385923, - 82.365250212781, 82.309009039070, 82.252767864802, 82.196526689989, 82.140285514643, - 82.084044338775, 82.027803162396, 81.971561985516, 81.915320808147, 81.859079630299, - 81.802838451980, 81.746597273202, 81.690356093972, 81.634114914301, 81.577873734197, - 81.521632553669, 81.465391372725, 81.409150191374, 81.352909009622, 81.296667827479, - 81.240426644952, 81.184185462047, 81.127944278772, 81.071703095135, 81.015461911141, - 80.959220726798, 80.902979542112, 80.846738357090, 80.790497171737, 80.734255986059, - 80.678014800063, 80.621773613754, 80.565532427138, 80.509291240220, 80.453050053006, - 80.396808865500, 80.340567677708, 80.284326489635, 80.228085301286, 80.171844112665, - 80.115602923777, 80.059361734627, 80.003120545219, 79.946879355557, 79.890638165646, - 79.834396975489, 79.778155785091, 79.721914594456, 79.665673403587, 79.609432212489, - 79.553191021165, 79.496949829619, 79.440708637854, 79.384467445874, 79.328226253682, - 79.271985061281, 79.215743868675, 79.159502675867, 79.103261482861, 79.047020289658, - 78.990779096262, 78.934537902677, 78.878296708904, 78.822055514948, 78.765814320810, - 78.709573126493, 78.653331932000, 78.597090737333, 78.540849542496, 78.484608347490, - 78.428367152319, 78.372125956984, 78.315884761487, 78.259643565832, 78.203402370020, - 78.147161174054, 78.090919977936, 78.034678781667, 77.978437585251, 77.922196388689, - 77.865955191983, 77.809713995135, 77.753472798147, 77.697231601021, 77.640990403760, - 77.584749206363, 77.528508008835, 77.472266811176, 77.416025613388, 77.359784415473, - 77.303543217432, 77.247302019268, 77.191060820981, 77.134819622574, 77.078578424048, - 77.022337225405, 76.966096026645, 76.909854827771, 76.853613628784, 76.797372429686, - 76.741131230477, 76.684890031160, 76.628648831736, 76.572407632205, 76.516166432570, - 76.459925232831, 76.403684032991, 76.347442833049, 76.291201633008, 76.234960432869, - 76.178719232632, 76.122478032300, 76.066236831873, 76.009995631352, 75.953754430738, - 75.897513230033, 75.841272029238, 75.785030828353, 75.728789627381, 75.672548426321, - 75.616307225175, 75.560066023944, 75.503824822628, 75.447583621230, 75.391342419749, - 75.335101218187, 75.278860016545, 75.222618814823, 75.166377613023, 75.110136411145, - 75.053895209190, 74.997654007160, 74.941412805054, 74.885171602875, 74.828930400621, - 74.772689198296, 74.716447995898, 74.660206793430, 74.603965590891, 74.547724388284, - 74.491483185607, 74.435241982862, 74.379000780051, 74.322759577172, 74.266518374228, - 74.210277171219, 74.154035968146, 74.097794765009, 74.041553561809, 73.985312358547, - 73.929071155223, 73.872829951838, 73.816588748392, 73.760347544887, 73.704106341323, - 73.647865137700, 73.591623934019, 73.535382730281, 73.479141526486, 73.422900322635, - 73.366659118728, 73.310417914766, 73.254176710750, 73.197935506680, 73.141694302556, - 73.085453098380, 73.029211894151, 72.972970689870, 72.916729485538, 72.860488281156, - 72.804247076723, 72.748005872240, 72.691764667707, 72.635523463126, 72.579282258497, - 72.523041053820, 72.466799849095, 72.410558644323, 72.354317439505, 72.298076234640, - 72.241835029730, 72.185593824775, 72.129352619775, 72.073111414731, 72.016870209642, - 71.960629004510, 71.904387799335, 71.848146594117, 71.791905388857, 71.735664183555, - 71.679422978211, 71.623181772826, 71.566940567400, 71.510699361934, 71.454458156428, - 71.398216950882, 71.341975745297, 71.285734539673, 71.229493334010, 71.173252128309, - 71.117010922570, 71.060769716793, 71.004528510979, 70.948287305128, 70.892046099240, - 70.835804893316, 70.779563687357, 70.723322481361, 70.667081275330, 70.610840069264, - 70.554598863164, 70.498357657029, 70.442116450859, 70.385875244656, 70.329634038420, - 70.273392832150, 70.217151625847, 70.160910419512, 70.104669213144, 70.048428006743, - 69.992186800311, 69.935945593848, 69.879704387353, 69.823463180827, 69.767221974270, - 69.710980767683, 69.654739561065, 69.598498354417, 69.542257147739, 69.486015941032, - 69.429774734296, 69.373533527530, 69.317292320736, 69.261051113913, 69.204809907061, - 69.148568700182, 69.092327493274, 69.036086286339, 68.979845079376, 68.923603872387, - 68.867362665370, 68.811121458326, 68.754880251256, 68.698639044159, 68.642397837036, - 68.586156629887, 68.529915422712, 68.473674215512, 68.417433008286, 68.361191801036, - 68.304950593760, 68.248709386459, 68.192468179134, 68.136226971784, 68.079985764411, - 68.023744557013, 67.967503349591, 67.911262142146, 67.855020934677, 67.798779727185, - 67.742538519670, 67.686297312132, 67.630056104571, 67.573814896987, 67.517573689381, - 67.461332481753, 67.405091274103, 67.348850066431, 67.292608858736, 67.236367651021, - 67.180126443284, 67.123885235525, 67.067644027746, 67.011402819945, 66.955161612124, - 66.898920404282, 66.842679196420, 66.786437988537, 66.730196780634, 66.673955572711, - 66.617714364767, 66.561473156805, 66.505231948822, 66.448990740820, 66.392749532799, - 66.336508324758, 66.280267116698, 66.224025908620, 66.167784700522, 66.111543492406, - 66.055302284271, 65.999061076118, 65.942819867947, 65.886578659757, 65.830337451550, - 65.774096243324, 65.717855035081, 65.661613826820, 65.605372618542, 65.549131410246, - 65.492890201932, 65.436648993602, 65.380407785255, 65.324166576890, 65.267925368509, - 65.211684160111, 65.155442951697, 65.099201743266, 65.042960534818, 64.986719326355, - 64.930478117875, 64.874236909379, 64.817995700867, 64.761754492340, 64.705513283796, - 64.649272075237, 64.593030866663, 64.536789658073, 64.480548449468, 64.424307240847, - 64.368066032212, 64.311824823562, 64.255583614896, 64.199342406216, 64.143101197521, - 64.086859988811, 64.030618780087, 63.974377571349, 63.918136362596, 63.861895153829, - 63.805653945048, 63.749412736253, 63.693171527443, 63.636930318620, 63.580689109783, - 63.524447900933, 63.468206692069, 63.411965483191, 63.355724274300, 63.299483065395, - 63.243241856477, 63.187000647546, 63.130759438602, 63.074518229645, 63.018277020675, - 62.962035811692, 62.905794602697, 62.849553393688, 62.793312184667, 62.737070975634, - 62.680829766588, 62.624588557529, 62.568347348459, 62.512106139376, 62.455864930281, - 62.399623721174, 62.343382512055, 62.287141302924, 62.230900093781, 62.174658884626, - 62.118417675459, 62.062176466281, 62.005935257092, 61.949694047891, 61.893452838678, - 61.837211629454, 61.780970420219, 61.724729210972, 61.668488001715, 61.612246792446, - 61.556005583166, 61.499764373875, 61.443523164574, 61.387281955261, 61.331040745938, - 61.274799536604, 61.218558327259, 61.162317117904, 61.106075908538, 61.049834699162, - 60.993593489776, 60.937352280379, 60.881111070972, 60.824869861554, 60.768628652127, - 60.712387442689, 60.656146233241, 60.599905023784, 60.543663814316, 60.487422604839, - 60.431181395352, 60.374940185855, 60.318698976348, 60.262457766832, 60.206216557306, - 60.149975347770, 60.093734138225, 60.037492928671, 59.981251719107, 59.925010509534, - 59.868769299952, 59.812528090360, 59.756286880760, 59.700045671150, 59.643804461531, - 59.587563251903, 59.531322042266, 59.475080832621, 59.418839622966, 59.362598413303, - 59.306357203630, 59.250115993950, 59.193874784260, 59.137633574562, 59.081392364855, - 59.025151155140, 58.968909945416, 58.912668735684, 58.856427525944, 58.800186316195, - 58.743945106438, 58.687703896672, 58.631462686899, 58.575221477117, 58.518980267327, - 58.462739057529, 58.406497847723, 58.350256637909, 58.294015428087, 58.237774218258, - 58.181533008420, 58.125291798575, 58.069050588721, 58.012809378861, 57.956568168992, - 57.900326959116, 57.844085749232, 57.787844539340, 57.731603329441, 57.675362119535, - 57.619120909621, 57.562879699700, 57.506638489771, 57.450397279835, 57.394156069892, - 57.337914859941, 57.281673649983, 57.225432440018, 57.169191230046, 57.112950020067, - 57.056708810081, 57.000467600088, 56.944226390087, 56.887985180080, 56.831743970066, - 56.775502760045, 56.719261550017, 56.663020339982, 56.606779129941, 56.550537919892, - 56.494296709838, 56.438055499776, 56.381814289708, 56.325573079633, 56.269331869551, - 56.213090659463, 56.156849449369, 56.100608239268, 56.044367029160, 55.988125819046, - 55.931884608926, 55.875643398799, 55.819402188666, 55.763160978527, 55.706919768382, - 55.650678558230, 55.594437348072, 55.538196137908, 55.481954927738, 55.425713717562, - 55.369472507379, 55.313231297191, 55.256990086997, 55.200748876796, 55.144507666590, - 55.088266456378, 55.032025246159, 54.975784035935, 54.919542825706, 54.863301615470, - 54.807060405229, 54.750819194981, 54.694577984728, 54.638336774470, 54.582095564206, - 54.525854353936, 54.469613143660, 54.413371933379, 54.357130723092, 54.300889512800, - 54.244648302502, 54.188407092199, 54.132165881890, 54.075924671576, 54.019683461257, - 53.963442250932, 53.907201040602, 53.850959830266, 53.794718619925, 53.738477409579, - 53.682236199228, 53.625994988871, 53.569753778510, 53.513512568143, 53.457271357770, - 53.401030147393, 53.344788937011, 53.288547726623, 53.232306516231, 53.176065305833, - 53.119824095431, 53.063582885023, 53.007341674611, 52.951100464193, 52.894859253771, - 52.838618043344, 52.782376832912, 52.726135622475, 52.669894412033, 52.613653201586, - 52.557411991135, 52.501170780679, 52.444929570218, 52.388688359752, 52.332447149282, - 52.276205938807, 52.219964728328, 52.163723517843, 52.107482307354, 52.051241096861, - 51.994999886363, 51.938758675860, 51.882517465353, 51.826276254842, 51.770035044326, - 51.713793833805, 51.657552623280, 51.601311412751, 51.545070202217, 51.488828991679, - 51.432587781136, 51.376346570589, 51.320105360038, 51.263864149482, 51.207622938923, - 51.151381728358, 51.095140517790, 51.038899307217, 50.982658096641, 50.926416886060, - 50.870175675474, 50.813934464885, 50.757693254292, 50.701452043694, 50.645210833092, - 50.588969622486, 50.532728411876, 50.476487201263, 50.420245990645, 50.364004780023, - 50.307763569397, 50.251522358767, 50.195281148133, 50.139039937495, 50.082798726853, - 50.026557516207, 49.970316305558, 49.914075094904, 49.857833884247, 49.801592673586, - 49.745351462921, 49.689110252252, 49.632869041579, 49.576627830903, 49.520386620223, - 49.464145409539, 49.407904198851, 49.351662988160, 49.295421777465, 49.239180566766, - 49.182939356064, 49.126698145358, 49.070456934648, 49.014215723935, 48.957974513218, - 48.901733302498, 48.845492091774, 48.789250881046, 48.733009670315, 48.676768459580, - 48.620527248842, 48.564286038100, 48.508044827355, 48.451803616606, 48.395562405854, - 48.339321195099, 48.283079984340, 48.226838773577, 48.170597562811, 48.114356352042, - 48.058115141270, 48.001873930494, 47.945632719714, 47.889391508932, 47.833150298146, - 47.776909087357, 47.720667876564, 47.664426665768, 47.608185454969, 47.551944244167, - 47.495703033362, 47.439461822553, 47.383220611741, 47.326979400926, 47.270738190108, - 47.214496979286, 47.158255768461, 47.102014557634, 47.045773346803, 46.989532135969, - 46.933290925132, 46.877049714291, 46.820808503448, 46.764567292602, 46.708326081752, - 46.652084870900, 46.595843660044, 46.539602449186, 46.483361238324, 46.427120027460, - 46.370878816592, 46.314637605722, 46.258396394849, 46.202155183972, 46.145913973093, - 46.089672762211, 46.033431551326, 45.977190340438, 45.920949129547, 45.864707918653, - 45.808466707756, 45.752225496857, 45.695984285954, 45.639743075049, 45.583501864141, - 45.527260653230, 45.471019442317, 45.414778231400, 45.358537020481, 45.302295809559, - 45.246054598635, 45.189813387707, 45.133572176777, 45.077330965844, 45.021089754909, - 44.964848543971, 44.908607333030, 44.852366122086, 44.796124911140, 44.739883700191, - 44.683642489239, 44.627401278285, 44.571160067328, 44.514918856368, 44.458677645406, - 44.402436434442, 44.346195223474, 44.289954012505, 44.233712801532, 44.177471590557, - 44.121230379580, 44.064989168600, 44.008747957617, 43.952506746632, 43.896265535644, - 43.840024324654, 43.783783113662, 43.727541902667, 43.671300691669, 43.615059480669, - 43.558818269667, 43.502577058662, 43.446335847655, 43.390094636645, 43.333853425633, - 43.277612214618, 43.221371003601, 43.165129792582, 43.108888581560, 43.052647370536, - 42.996406159510, 42.940164948481, 42.883923737450, 42.827682526417, 42.771441315381, - 42.715200104343, 42.658958893302, 42.602717682260, 42.546476471215, 42.490235260168, - 42.433994049118, 42.377752838066, 42.321511627012, 42.265270415956, 42.209029204898, - 42.152787993837, 42.096546782774, 42.040305571709, 41.984064360641, 41.927823149572, - 41.871581938500, 41.815340727426, 41.759099516350, 41.702858305272, 41.646617094191, - 41.590375883109, 41.534134672024, 41.477893460937, 41.421652249848, 41.365411038757, - 41.309169827664, 41.252928616569, 41.196687405472, 41.140446194372, 41.084204983271, - 41.027963772167, 40.971722561062, 40.915481349954, 40.859240138844, 40.802998927732, - 40.746757716619, 40.690516505503, 40.634275294385, 40.578034083265, 40.521792872143, - 40.465551661019, 40.409310449894, 40.353069238766, 40.296828027636, 40.240586816504, - 40.184345605371, 40.128104394235, 40.071863183097, 40.015621971958, 39.959380760816, - 39.903139549673, 39.846898338528, 39.790657127381, 39.734415916231, 39.678174705080, - 39.621933493928, 39.565692282773, 39.509451071616, 39.453209860458, 39.396968649297, - 39.340727438135, 39.284486226971, 39.228245015805, 39.172003804637, 39.115762593468, - 39.059521382297, 39.003280171123, 38.947038959948, 38.890797748772, 38.834556537593, - 38.778315326413, 38.722074115230, 38.665832904047, 38.609591692861, 38.553350481673, - 38.497109270484, 38.440868059293, 38.384626848100, 38.328385636906, 38.272144425710, - 38.215903214512, 38.159662003312, 38.103420792111, 38.047179580908, 37.990938369703, - 37.934697158497, 37.878455947289, 37.822214736079, 37.765973524867, 37.709732313654, - 37.653491102439, 37.597249891223, 37.541008680005, 37.484767468785, 37.428526257564, - 37.372285046341, 37.316043835116, 37.259802623890, 37.203561412662, 37.147320201432, - 37.091078990201, 37.034837778968, 36.978596567734, 36.922355356498, 36.866114145260, - 36.809872934021, 36.753631722781, 36.697390511538, 36.641149300295, 36.584908089049, - 36.528666877802, 36.472425666554, 36.416184455304, 36.359943244052, 36.303702032799, - 36.247460821545, 36.191219610289, 36.134978399031, 36.078737187772, 36.022495976511, - 35.966254765249, 35.910013553986, 35.853772342721, 35.797531131454, 35.741289920186, - 35.685048708916, 35.628807497645, 35.572566286373, 35.516325075099, 35.460083863824, - 35.403842652547, 35.347601441269, 35.291360229989, 35.235119018708, 35.178877807425, - 35.122636596141, 35.066395384856, 35.010154173569, 34.953912962281, 34.897671750991, - 34.841430539700, 34.785189328408, 34.728948117114, 34.672706905819, 34.616465694522, - 34.560224483224, 34.503983271925, 34.447742060625, 34.391500849323, 34.335259638019, - 34.279018426714, 34.222777215408, 34.166536004101, 34.110294792792, 34.054053581482, - 33.997812370171, 33.941571158858, 33.885329947544, 33.829088736229, 33.772847524912, - 33.716606313594, 33.660365102275, 33.604123890954, 33.547882679632, 33.491641468309, - 33.435400256985, 33.379159045659, 33.322917834332, 33.266676623004, 33.210435411675, - 33.154194200344, 33.097952989012, 33.041711777679, 32.985470566344, 32.929229355008, - 32.872988143671, 32.816746932333, 32.760505720994, 32.704264509653, 32.648023298311, - 32.591782086968, 32.535540875624, 32.479299664278, 32.423058452931, 32.366817241583, - 32.310576030234, 32.254334818884, 32.198093607532, 32.141852396180, 32.085611184826, - 32.029369973471, 31.973128762114, 31.916887550757, 31.860646339398, 31.804405128039, - 31.748163916678, 31.691922705316, 31.635681493953, 31.579440282588, 31.523199071223, - 31.466957859856, 31.410716648488, 31.354475437119, 31.298234225749, 31.241993014378, - 31.185751803006, 31.129510591633, 31.073269380258, 31.017028168883, 30.960786957506, - 30.904545746128, 30.848304534749, 30.792063323369, 30.735822111988, 30.679580900606, - 30.623339689223, 30.567098477839, 30.510857266453, 30.454616055067, 30.398374843679, - 30.342133632291, 30.285892420901, 30.229651209510, 30.173409998119, 30.117168786726, - 30.060927575332, 30.004686363937, 29.948445152541, 29.892203941144, 29.835962729746, - 29.779721518347, 29.723480306947, 29.667239095546, 29.610997884144, 29.554756672741, - 29.498515461337, 29.442274249932, 29.386033038526, 29.329791827119, 29.273550615711, - 29.217309404302, 29.161068192891, 29.104826981480, 29.048585770068, 28.992344558655, - 28.936103347241, 28.879862135826, 28.823620924410, 28.767379712994, 28.711138501576, - 28.654897290157, 28.598656078737, 28.542414867316, 28.486173655895, 28.429932444472, - 28.373691233049, 28.317450021624, 28.261208810199, 28.204967598772, 28.148726387345, - 28.092485175917, 28.036243964487, 27.980002753057, 27.923761541626, 27.867520330194, - 27.811279118762, 27.755037907328, 27.698796695893, 27.642555484458, 27.586314273021, - 27.530073061584, 27.473831850146, 27.417590638707, 27.361349427267, 27.305108215826, - 27.248867004384, 27.192625792941, 27.136384581498, 27.080143370053, 27.023902158608, - 26.967660947162, 26.911419735715, 26.855178524267, 26.798937312818, 26.742696101369, - 26.686454889918, 26.630213678467, 26.573972467015, 26.517731255562, 26.461490044108, - 26.405248832653, 26.349007621198, 26.292766409742, 26.236525198285, 26.180283986827, - 26.124042775368, 26.067801563908, 26.011560352448, 25.955319140987, 25.899077929525, - 25.842836718062, 25.786595506598, 25.730354295134, 25.674113083668, 25.617871872202, - 25.561630660735, 25.505389449268, 25.449148237799, 25.392907026330, 25.336665814860, - 25.280424603389, 25.224183391918, 25.167942180446, 25.111700968972, 25.055459757499, - 24.999218546024, 24.942977334548, 24.886736123072, 24.830494911595, 24.774253700118, - 24.718012488639, 24.661771277160, 24.605530065680, 24.549288854199, 24.493047642718, - 24.436806431236, 24.380565219753, 24.324324008269, 24.268082796785, 24.211841585300, - 24.155600373814, 24.099359162327, 24.043117950840, 23.986876739352, 23.930635527863, - 23.874394316374, 23.818153104884, 23.761911893393, 23.705670681901, 23.649429470409, - 23.593188258916, 23.536947047422, 23.480705835928, 23.424464624433, 23.368223412937, - 23.311982201441, 23.255740989943, 23.199499778446, 23.143258566947, 23.087017355448, - 23.030776143948, 22.974534932447, 22.918293720946, 22.862052509444, 22.805811297942, - 22.749570086438, 22.693328874935, 22.637087663430, 22.580846451925, 22.524605240419, - 22.468364028912, 22.412122817405, 22.355881605897, 22.299640394389, 22.243399182880, - 22.187157971370, 22.130916759859, 22.074675548348, 22.018434336837, 21.962193125324, - 21.905951913811, 21.849710702298, 21.793469490784, 21.737228279269, 21.680987067753, - 21.624745856237, 21.568504644721, 21.512263433203, 21.456022221685, 21.399781010167, - 21.343539798648, 21.287298587128, 21.231057375607, 21.174816164087, 21.118574952565, - 21.062333741043, 21.006092529520, 20.949851317997, 20.893610106473, 20.837368894948, - 20.781127683423, 20.724886471897, 20.668645260371, 20.612404048844, 20.556162837317, - 20.499921625789, 20.443680414260, 20.387439202731, 20.331197991201, 20.274956779671, - 20.218715568140, 20.162474356609, 20.106233145077, 20.049991933544, 19.993750722011, - 19.937509510477, 19.881268298943, 19.825027087408, 19.768785875873, 19.712544664337, - 19.656303452801, 19.600062241264, 19.543821029726, 19.487579818188, 19.431338606650, - 19.375097395110, 19.318856183571, 19.262614972031, 19.206373760490, 19.150132548949, - 19.093891337407, 19.037650125865, 18.981408914322, 18.925167702779, 18.868926491235, - 18.812685279690, 18.756444068146, 18.700202856600, 18.643961645054, 18.587720433508, - 18.531479221961, 18.475238010414, 18.418996798866, 18.362755587317, 18.306514375769, - 18.250273164219, 18.194031952669, 18.137790741119, 18.081549529568, 18.025308318017, - 17.969067106465, 17.912825894913, 17.856584683360, 17.800343471807, 17.744102260253, - 17.687861048699, 17.631619837144, 17.575378625589, 17.519137414033, 17.462896202477, - 17.406654990920, 17.350413779363, 17.294172567806, 17.237931356248, 17.181690144690, - 17.125448933131, 17.069207721571, 17.012966510012, 16.956725298451, 16.900484086891, - 16.844242875330, 16.788001663768, 16.731760452206, 16.675519240644, 16.619278029081, - 16.563036817517, 16.506795605954, 16.450554394389, 16.394313182825, 16.338071971260, - 16.281830759694, 16.225589548128, 16.169348336562, 16.113107124995, 16.056865913428, - 16.000624701860, 15.944383490292, 15.888142278724, 15.831901067155, 15.775659855586, - 15.719418644016, 15.663177432446, 15.606936220876, 15.550695009305, 15.494453797733, - 15.438212586162, 15.381971374590, 15.325730163017, 15.269488951444, 15.213247739871, - 15.157006528297, 15.100765316723, 15.044524105149, 14.988282893574, 14.932041681998, - 14.875800470423, 14.819559258847, 14.763318047270, 14.707076835694, 14.650835624116, - 14.594594412539, 14.538353200961, 14.482111989383, 14.425870777804, 14.369629566225, - 14.313388354646, 14.257147143066, 14.200905931486, 14.144664719905, 14.088423508324, - 14.032182296743, 13.975941085162, 13.919699873580, 13.863458661998, 13.807217450415, - 13.750976238832, 13.694735027249, 13.638493815665, 13.582252604081, 13.526011392497, - 13.469770180912, 13.413528969327, 13.357287757741, 13.301046546156, 13.244805334570, - 13.188564122983, 13.132322911396, 13.076081699809, 13.019840488222, 12.963599276634, - 12.907358065046, 12.851116853458, 12.794875641869, 12.738634430280, 12.682393218691, - 12.626152007101, 12.569910795511, 12.513669583921, 12.457428372330, 12.401187160739, - 12.344945949148, 12.288704737557, 12.232463525965, 12.176222314373, 12.119981102780, - 12.063739891187, 12.007498679594, 11.951257468001, 11.895016256407, 11.838775044813, - 11.782533833219, 11.726292621625, 11.670051410030, 11.613810198435, 11.557568986839, - 11.501327775244, 11.445086563648, 11.388845352051, 11.332604140455, 11.276362928858, - 11.220121717261, 11.163880505664, 11.107639294066, 11.051398082468, 10.995156870870, - 10.938915659271, 10.882674447672, 10.826433236073, 10.770192024474, 10.713950812875, - 10.657709601275, 10.601468389675, 10.545227178074, 10.488985966474, 10.432744754873, - 10.376503543272, 10.320262331670, 10.264021120069, 10.207779908467, 10.151538696865, - 10.095297485262, 10.039056273660, 9.982815062057, 9.926573850454, 9.870332638851, - 9.814091427247, 9.757850215643, 9.701609004039, 9.645367792435, 9.589126580830, - 9.532885369225, 9.476644157620, 9.420402946015, 9.364161734410, 9.307920522804, - 9.251679311198, 9.195438099592, 9.139196887985, 9.082955676379, 9.026714464772, - 8.970473253165, 8.914232041558, 8.857990829950, 8.801749618343, 8.745508406735, - 8.689267195127, 8.633025983518, 8.576784771910, 8.520543560301, 8.464302348692, - 8.408061137083, 8.351819925473, 8.295578713864, 8.239337502254, 8.183096290644, - 8.126855079034, 8.070613867424, 8.014372655813, 7.958131444202, 7.901890232591, - 7.845649020980, 7.789407809369, 7.733166597758, 7.676925386146, 7.620684174534, - 7.564442962922, 7.508201751310, 7.451960539697, 7.395719328085, 7.339478116472, - 7.283236904859, 7.226995693246, 7.170754481632, 7.114513270019, 7.058272058405, - 7.002030846792, 6.945789635178, 6.889548423563, 6.833307211949, 6.777066000335, - 6.720824788720, 6.664583577105, 6.608342365490, 6.552101153875, 6.495859942260, - 6.439618730644, 6.383377519029, 6.327136307413, 6.270895095797, 6.214653884181, - 6.158412672565, 6.102171460949, 6.045930249332, 5.989689037715, 5.933447826099, - 5.877206614482, 5.820965402865, 5.764724191248, 5.708482979630, 5.652241768013, - 5.596000556395, 5.539759344777, 5.483518133160, 5.427276921542, 5.371035709923, - 5.314794498305, 5.258553286687, 5.202312075068, 5.146070863450, 5.089829651831, - 5.033588440212, 4.977347228593, 4.921106016974, 4.864864805355, 4.808623593735, - 4.752382382116, 4.696141170496, 4.639899958877, 4.583658747257, 4.527417535637, - 4.471176324017, 4.414935112397, 4.358693900777, 4.302452689156, 4.246211477536, - 4.189970265915, 4.133729054295, 4.077487842674, 4.021246631053, 3.965005419432, - 3.908764207811, 3.852522996190, 3.796281784569, 3.740040572948, 3.683799361327, - 3.627558149705, 3.571316938084, 3.515075726462, 3.458834514840, 3.402593303218, - 3.346352091597, 3.290110879975, 3.233869668353, 3.177628456730, 3.121387245108, - 3.065146033486, 3.008904821864, 2.952663610241, 2.896422398619, 2.840181186996, - 2.783939975374, 2.727698763751, 2.671457552128, 2.615216340506, 2.558975128883, - 2.502733917260, 2.446492705637, 2.390251494014, 2.334010282391, 2.277769070768, - 2.221527859144, 2.165286647521, 2.109045435898, 2.052804224275, 1.996563012651, - 1.940321801028, 1.884080589404, 1.827839377781, 1.771598166157, 1.715356954533, - 1.659115742910, 1.602874531286, 1.546633319662, 1.490392108039, 1.434150896415, - 1.377909684791, 1.321668473167, 1.265427261543, 1.209186049919, 1.152944838295, - 1.096703626671, 1.040462415047, 0.984221203423, 0.927979991799, 0.871738780175, - 0.815497568551, 0.759256356927, 0.703015145303, 0.646773933679, 0.590532722054, - 0.534291510430, 0.478050298806, 0.421809087182, 0.365567875558, 0.309326663933, - 0.253085452309, 0.196844240685, 0.140603029061, 0.084361817436, 0.028120605812 - )) +DEFINE_GAUSSIAN_LATITUDES( + 1600, + LIST( + 89.956948491058, 89.901178822991, 89.845079804890, 89.788906372571, 89.732704713178, 89.676489394638, + 89.620266442582, 89.564038795892, 89.507808057494, 89.451575175583, 89.395340746771, 89.339105165153, + 89.282868701480, 89.226631547902, 89.170393844551, 89.114155696023, 89.057917181969, 89.001678364113, + 88.945439291023, 88.889200001442, 88.832960526648, 88.776720892172, 88.720481119062, 88.664241224818, + 88.608001224118, 88.551761129360, 88.495520951086, 88.439280698324, 88.383040378843, 88.326799999369, + 88.270559565753, 88.214319083110, 88.158078555930, 88.101837988170, 88.045597383333, 87.989356744529, + 87.933116074532, 87.876875375818, 87.820634650612, 87.764393900912, 87.708153128521, 87.651912335070, + 87.595671522036, 87.539430690761, 87.483189842469, 87.426948978275, 87.370708099200, 87.314467206178, + 87.258226300067, 87.201985381657, 87.145744451675, 87.089503510791, 87.033262559625, 86.977021598752, + 86.920780628702, 86.864539649971, 86.808298663016, 86.752057668265, 86.695816666116, 86.639575656940, + 86.583334641085, 86.527093618874, 86.470852590613, 86.414611556584, 86.358370517056, 86.302129472280, + 86.245888422491, 86.189647367911, 86.133406308749, 86.077165245203, 86.020924177459, 85.964683105691, + 85.908442030065, 85.852200950740, 85.795959867862, 85.739718781574, 85.683477692007, 85.627236599289, + 85.570995503540, 85.514754404873, 85.458513303398, 85.402272199216, 85.346031092427, 85.289789983123, + 85.233548871394, 85.177307757325, 85.121066640996, 85.064825522485, 85.008584401865, 84.952343279207, + 84.896102154578, 84.839861028043, 84.783619899663, 84.727378769498, 84.671137637604, 84.614896504035, + 84.558655368843, 84.502414232077, 84.446173093787, 84.389931954017, 84.333690812811, 84.277449670213, + 84.221208526262, 84.164967380998, 84.108726234457, 84.052485086678, 83.996243937694, 83.940002787538, + 83.883761636244, 83.827520483842, 83.771279330362, 83.715038175834, 83.658797020285, 83.602555863742, + 83.546314706230, 83.490073547776, 83.433832388404, 83.377591228136, 83.321350066995, 83.265108905004, + 83.208867742183, 83.152626578553, 83.096385414133, 83.040144248943, 82.983903083002, 82.927661916327, + 82.871420748935, 82.815179580843, 82.758938412069, 82.702697242626, 82.646456072532, 82.590214901800, + 82.533973730445, 82.477732558482, 82.421491385923, 82.365250212781, 82.309009039070, 82.252767864802, + 82.196526689989, 82.140285514643, 82.084044338775, 82.027803162396, 81.971561985516, 81.915320808147, + 81.859079630299, 81.802838451980, 81.746597273202, 81.690356093972, 81.634114914301, 81.577873734197, + 81.521632553669, 81.465391372725, 81.409150191374, 81.352909009622, 81.296667827479, 81.240426644952, + 81.184185462047, 81.127944278772, 81.071703095135, 81.015461911141, 80.959220726798, 80.902979542112, + 80.846738357090, 80.790497171737, 80.734255986059, 80.678014800063, 80.621773613754, 80.565532427138, + 80.509291240220, 80.453050053006, 80.396808865500, 80.340567677708, 80.284326489635, 80.228085301286, + 80.171844112665, 80.115602923777, 80.059361734627, 80.003120545219, 79.946879355557, 79.890638165646, + 79.834396975489, 79.778155785091, 79.721914594456, 79.665673403587, 79.609432212489, 79.553191021165, + 79.496949829619, 79.440708637854, 79.384467445874, 79.328226253682, 79.271985061281, 79.215743868675, + 79.159502675867, 79.103261482861, 79.047020289658, 78.990779096262, 78.934537902677, 78.878296708904, + 78.822055514948, 78.765814320810, 78.709573126493, 78.653331932000, 78.597090737333, 78.540849542496, + 78.484608347490, 78.428367152319, 78.372125956984, 78.315884761487, 78.259643565832, 78.203402370020, + 78.147161174054, 78.090919977936, 78.034678781667, 77.978437585251, 77.922196388689, 77.865955191983, + 77.809713995135, 77.753472798147, 77.697231601021, 77.640990403760, 77.584749206363, 77.528508008835, + 77.472266811176, 77.416025613388, 77.359784415473, 77.303543217432, 77.247302019268, 77.191060820981, + 77.134819622574, 77.078578424048, 77.022337225405, 76.966096026645, 76.909854827771, 76.853613628784, + 76.797372429686, 76.741131230477, 76.684890031160, 76.628648831736, 76.572407632205, 76.516166432570, + 76.459925232831, 76.403684032991, 76.347442833049, 76.291201633008, 76.234960432869, 76.178719232632, + 76.122478032300, 76.066236831873, 76.009995631352, 75.953754430738, 75.897513230033, 75.841272029238, + 75.785030828353, 75.728789627381, 75.672548426321, 75.616307225175, 75.560066023944, 75.503824822628, + 75.447583621230, 75.391342419749, 75.335101218187, 75.278860016545, 75.222618814823, 75.166377613023, + 75.110136411145, 75.053895209190, 74.997654007160, 74.941412805054, 74.885171602875, 74.828930400621, + 74.772689198296, 74.716447995898, 74.660206793430, 74.603965590891, 74.547724388284, 74.491483185607, + 74.435241982862, 74.379000780051, 74.322759577172, 74.266518374228, 74.210277171219, 74.154035968146, + 74.097794765009, 74.041553561809, 73.985312358547, 73.929071155223, 73.872829951838, 73.816588748392, + 73.760347544887, 73.704106341323, 73.647865137700, 73.591623934019, 73.535382730281, 73.479141526486, + 73.422900322635, 73.366659118728, 73.310417914766, 73.254176710750, 73.197935506680, 73.141694302556, + 73.085453098380, 73.029211894151, 72.972970689870, 72.916729485538, 72.860488281156, 72.804247076723, + 72.748005872240, 72.691764667707, 72.635523463126, 72.579282258497, 72.523041053820, 72.466799849095, + 72.410558644323, 72.354317439505, 72.298076234640, 72.241835029730, 72.185593824775, 72.129352619775, + 72.073111414731, 72.016870209642, 71.960629004510, 71.904387799335, 71.848146594117, 71.791905388857, + 71.735664183555, 71.679422978211, 71.623181772826, 71.566940567400, 71.510699361934, 71.454458156428, + 71.398216950882, 71.341975745297, 71.285734539673, 71.229493334010, 71.173252128309, 71.117010922570, + 71.060769716793, 71.004528510979, 70.948287305128, 70.892046099240, 70.835804893316, 70.779563687357, + 70.723322481361, 70.667081275330, 70.610840069264, 70.554598863164, 70.498357657029, 70.442116450859, + 70.385875244656, 70.329634038420, 70.273392832150, 70.217151625847, 70.160910419512, 70.104669213144, + 70.048428006743, 69.992186800311, 69.935945593848, 69.879704387353, 69.823463180827, 69.767221974270, + 69.710980767683, 69.654739561065, 69.598498354417, 69.542257147739, 69.486015941032, 69.429774734296, + 69.373533527530, 69.317292320736, 69.261051113913, 69.204809907061, 69.148568700182, 69.092327493274, + 69.036086286339, 68.979845079376, 68.923603872387, 68.867362665370, 68.811121458326, 68.754880251256, + 68.698639044159, 68.642397837036, 68.586156629887, 68.529915422712, 68.473674215512, 68.417433008286, + 68.361191801036, 68.304950593760, 68.248709386459, 68.192468179134, 68.136226971784, 68.079985764411, + 68.023744557013, 67.967503349591, 67.911262142146, 67.855020934677, 67.798779727185, 67.742538519670, + 67.686297312132, 67.630056104571, 67.573814896987, 67.517573689381, 67.461332481753, 67.405091274103, + 67.348850066431, 67.292608858736, 67.236367651021, 67.180126443284, 67.123885235525, 67.067644027746, + 67.011402819945, 66.955161612124, 66.898920404282, 66.842679196420, 66.786437988537, 66.730196780634, + 66.673955572711, 66.617714364767, 66.561473156805, 66.505231948822, 66.448990740820, 66.392749532799, + 66.336508324758, 66.280267116698, 66.224025908620, 66.167784700522, 66.111543492406, 66.055302284271, + 65.999061076118, 65.942819867947, 65.886578659757, 65.830337451550, 65.774096243324, 65.717855035081, + 65.661613826820, 65.605372618542, 65.549131410246, 65.492890201932, 65.436648993602, 65.380407785255, + 65.324166576890, 65.267925368509, 65.211684160111, 65.155442951697, 65.099201743266, 65.042960534818, + 64.986719326355, 64.930478117875, 64.874236909379, 64.817995700867, 64.761754492340, 64.705513283796, + 64.649272075237, 64.593030866663, 64.536789658073, 64.480548449468, 64.424307240847, 64.368066032212, + 64.311824823562, 64.255583614896, 64.199342406216, 64.143101197521, 64.086859988811, 64.030618780087, + 63.974377571349, 63.918136362596, 63.861895153829, 63.805653945048, 63.749412736253, 63.693171527443, + 63.636930318620, 63.580689109783, 63.524447900933, 63.468206692069, 63.411965483191, 63.355724274300, + 63.299483065395, 63.243241856477, 63.187000647546, 63.130759438602, 63.074518229645, 63.018277020675, + 62.962035811692, 62.905794602697, 62.849553393688, 62.793312184667, 62.737070975634, 62.680829766588, + 62.624588557529, 62.568347348459, 62.512106139376, 62.455864930281, 62.399623721174, 62.343382512055, + 62.287141302924, 62.230900093781, 62.174658884626, 62.118417675459, 62.062176466281, 62.005935257092, + 61.949694047891, 61.893452838678, 61.837211629454, 61.780970420219, 61.724729210972, 61.668488001715, + 61.612246792446, 61.556005583166, 61.499764373875, 61.443523164574, 61.387281955261, 61.331040745938, + 61.274799536604, 61.218558327259, 61.162317117904, 61.106075908538, 61.049834699162, 60.993593489776, + 60.937352280379, 60.881111070972, 60.824869861554, 60.768628652127, 60.712387442689, 60.656146233241, + 60.599905023784, 60.543663814316, 60.487422604839, 60.431181395352, 60.374940185855, 60.318698976348, + 60.262457766832, 60.206216557306, 60.149975347770, 60.093734138225, 60.037492928671, 59.981251719107, + 59.925010509534, 59.868769299952, 59.812528090360, 59.756286880760, 59.700045671150, 59.643804461531, + 59.587563251903, 59.531322042266, 59.475080832621, 59.418839622966, 59.362598413303, 59.306357203630, + 59.250115993950, 59.193874784260, 59.137633574562, 59.081392364855, 59.025151155140, 58.968909945416, + 58.912668735684, 58.856427525944, 58.800186316195, 58.743945106438, 58.687703896672, 58.631462686899, + 58.575221477117, 58.518980267327, 58.462739057529, 58.406497847723, 58.350256637909, 58.294015428087, + 58.237774218258, 58.181533008420, 58.125291798575, 58.069050588721, 58.012809378861, 57.956568168992, + 57.900326959116, 57.844085749232, 57.787844539340, 57.731603329441, 57.675362119535, 57.619120909621, + 57.562879699700, 57.506638489771, 57.450397279835, 57.394156069892, 57.337914859941, 57.281673649983, + 57.225432440018, 57.169191230046, 57.112950020067, 57.056708810081, 57.000467600088, 56.944226390087, + 56.887985180080, 56.831743970066, 56.775502760045, 56.719261550017, 56.663020339982, 56.606779129941, + 56.550537919892, 56.494296709838, 56.438055499776, 56.381814289708, 56.325573079633, 56.269331869551, + 56.213090659463, 56.156849449369, 56.100608239268, 56.044367029160, 55.988125819046, 55.931884608926, + 55.875643398799, 55.819402188666, 55.763160978527, 55.706919768382, 55.650678558230, 55.594437348072, + 55.538196137908, 55.481954927738, 55.425713717562, 55.369472507379, 55.313231297191, 55.256990086997, + 55.200748876796, 55.144507666590, 55.088266456378, 55.032025246159, 54.975784035935, 54.919542825706, + 54.863301615470, 54.807060405229, 54.750819194981, 54.694577984728, 54.638336774470, 54.582095564206, + 54.525854353936, 54.469613143660, 54.413371933379, 54.357130723092, 54.300889512800, 54.244648302502, + 54.188407092199, 54.132165881890, 54.075924671576, 54.019683461257, 53.963442250932, 53.907201040602, + 53.850959830266, 53.794718619925, 53.738477409579, 53.682236199228, 53.625994988871, 53.569753778510, + 53.513512568143, 53.457271357770, 53.401030147393, 53.344788937011, 53.288547726623, 53.232306516231, + 53.176065305833, 53.119824095431, 53.063582885023, 53.007341674611, 52.951100464193, 52.894859253771, + 52.838618043344, 52.782376832912, 52.726135622475, 52.669894412033, 52.613653201586, 52.557411991135, + 52.501170780679, 52.444929570218, 52.388688359752, 52.332447149282, 52.276205938807, 52.219964728328, + 52.163723517843, 52.107482307354, 52.051241096861, 51.994999886363, 51.938758675860, 51.882517465353, + 51.826276254842, 51.770035044326, 51.713793833805, 51.657552623280, 51.601311412751, 51.545070202217, + 51.488828991679, 51.432587781136, 51.376346570589, 51.320105360038, 51.263864149482, 51.207622938923, + 51.151381728358, 51.095140517790, 51.038899307217, 50.982658096641, 50.926416886060, 50.870175675474, + 50.813934464885, 50.757693254292, 50.701452043694, 50.645210833092, 50.588969622486, 50.532728411876, + 50.476487201263, 50.420245990645, 50.364004780023, 50.307763569397, 50.251522358767, 50.195281148133, + 50.139039937495, 50.082798726853, 50.026557516207, 49.970316305558, 49.914075094904, 49.857833884247, + 49.801592673586, 49.745351462921, 49.689110252252, 49.632869041579, 49.576627830903, 49.520386620223, + 49.464145409539, 49.407904198851, 49.351662988160, 49.295421777465, 49.239180566766, 49.182939356064, + 49.126698145358, 49.070456934648, 49.014215723935, 48.957974513218, 48.901733302498, 48.845492091774, + 48.789250881046, 48.733009670315, 48.676768459580, 48.620527248842, 48.564286038100, 48.508044827355, + 48.451803616606, 48.395562405854, 48.339321195099, 48.283079984340, 48.226838773577, 48.170597562811, + 48.114356352042, 48.058115141270, 48.001873930494, 47.945632719714, 47.889391508932, 47.833150298146, + 47.776909087357, 47.720667876564, 47.664426665768, 47.608185454969, 47.551944244167, 47.495703033362, + 47.439461822553, 47.383220611741, 47.326979400926, 47.270738190108, 47.214496979286, 47.158255768461, + 47.102014557634, 47.045773346803, 46.989532135969, 46.933290925132, 46.877049714291, 46.820808503448, + 46.764567292602, 46.708326081752, 46.652084870900, 46.595843660044, 46.539602449186, 46.483361238324, + 46.427120027460, 46.370878816592, 46.314637605722, 46.258396394849, 46.202155183972, 46.145913973093, + 46.089672762211, 46.033431551326, 45.977190340438, 45.920949129547, 45.864707918653, 45.808466707756, + 45.752225496857, 45.695984285954, 45.639743075049, 45.583501864141, 45.527260653230, 45.471019442317, + 45.414778231400, 45.358537020481, 45.302295809559, 45.246054598635, 45.189813387707, 45.133572176777, + 45.077330965844, 45.021089754909, 44.964848543971, 44.908607333030, 44.852366122086, 44.796124911140, + 44.739883700191, 44.683642489239, 44.627401278285, 44.571160067328, 44.514918856368, 44.458677645406, + 44.402436434442, 44.346195223474, 44.289954012505, 44.233712801532, 44.177471590557, 44.121230379580, + 44.064989168600, 44.008747957617, 43.952506746632, 43.896265535644, 43.840024324654, 43.783783113662, + 43.727541902667, 43.671300691669, 43.615059480669, 43.558818269667, 43.502577058662, 43.446335847655, + 43.390094636645, 43.333853425633, 43.277612214618, 43.221371003601, 43.165129792582, 43.108888581560, + 43.052647370536, 42.996406159510, 42.940164948481, 42.883923737450, 42.827682526417, 42.771441315381, + 42.715200104343, 42.658958893302, 42.602717682260, 42.546476471215, 42.490235260168, 42.433994049118, + 42.377752838066, 42.321511627012, 42.265270415956, 42.209029204898, 42.152787993837, 42.096546782774, + 42.040305571709, 41.984064360641, 41.927823149572, 41.871581938500, 41.815340727426, 41.759099516350, + 41.702858305272, 41.646617094191, 41.590375883109, 41.534134672024, 41.477893460937, 41.421652249848, + 41.365411038757, 41.309169827664, 41.252928616569, 41.196687405472, 41.140446194372, 41.084204983271, + 41.027963772167, 40.971722561062, 40.915481349954, 40.859240138844, 40.802998927732, 40.746757716619, + 40.690516505503, 40.634275294385, 40.578034083265, 40.521792872143, 40.465551661019, 40.409310449894, + 40.353069238766, 40.296828027636, 40.240586816504, 40.184345605371, 40.128104394235, 40.071863183097, + 40.015621971958, 39.959380760816, 39.903139549673, 39.846898338528, 39.790657127381, 39.734415916231, + 39.678174705080, 39.621933493928, 39.565692282773, 39.509451071616, 39.453209860458, 39.396968649297, + 39.340727438135, 39.284486226971, 39.228245015805, 39.172003804637, 39.115762593468, 39.059521382297, + 39.003280171123, 38.947038959948, 38.890797748772, 38.834556537593, 38.778315326413, 38.722074115230, + 38.665832904047, 38.609591692861, 38.553350481673, 38.497109270484, 38.440868059293, 38.384626848100, + 38.328385636906, 38.272144425710, 38.215903214512, 38.159662003312, 38.103420792111, 38.047179580908, + 37.990938369703, 37.934697158497, 37.878455947289, 37.822214736079, 37.765973524867, 37.709732313654, + 37.653491102439, 37.597249891223, 37.541008680005, 37.484767468785, 37.428526257564, 37.372285046341, + 37.316043835116, 37.259802623890, 37.203561412662, 37.147320201432, 37.091078990201, 37.034837778968, + 36.978596567734, 36.922355356498, 36.866114145260, 36.809872934021, 36.753631722781, 36.697390511538, + 36.641149300295, 36.584908089049, 36.528666877802, 36.472425666554, 36.416184455304, 36.359943244052, + 36.303702032799, 36.247460821545, 36.191219610289, 36.134978399031, 36.078737187772, 36.022495976511, + 35.966254765249, 35.910013553986, 35.853772342721, 35.797531131454, 35.741289920186, 35.685048708916, + 35.628807497645, 35.572566286373, 35.516325075099, 35.460083863824, 35.403842652547, 35.347601441269, + 35.291360229989, 35.235119018708, 35.178877807425, 35.122636596141, 35.066395384856, 35.010154173569, + 34.953912962281, 34.897671750991, 34.841430539700, 34.785189328408, 34.728948117114, 34.672706905819, + 34.616465694522, 34.560224483224, 34.503983271925, 34.447742060625, 34.391500849323, 34.335259638019, + 34.279018426714, 34.222777215408, 34.166536004101, 34.110294792792, 34.054053581482, 33.997812370171, + 33.941571158858, 33.885329947544, 33.829088736229, 33.772847524912, 33.716606313594, 33.660365102275, + 33.604123890954, 33.547882679632, 33.491641468309, 33.435400256985, 33.379159045659, 33.322917834332, + 33.266676623004, 33.210435411675, 33.154194200344, 33.097952989012, 33.041711777679, 32.985470566344, + 32.929229355008, 32.872988143671, 32.816746932333, 32.760505720994, 32.704264509653, 32.648023298311, + 32.591782086968, 32.535540875624, 32.479299664278, 32.423058452931, 32.366817241583, 32.310576030234, + 32.254334818884, 32.198093607532, 32.141852396180, 32.085611184826, 32.029369973471, 31.973128762114, + 31.916887550757, 31.860646339398, 31.804405128039, 31.748163916678, 31.691922705316, 31.635681493953, + 31.579440282588, 31.523199071223, 31.466957859856, 31.410716648488, 31.354475437119, 31.298234225749, + 31.241993014378, 31.185751803006, 31.129510591633, 31.073269380258, 31.017028168883, 30.960786957506, + 30.904545746128, 30.848304534749, 30.792063323369, 30.735822111988, 30.679580900606, 30.623339689223, + 30.567098477839, 30.510857266453, 30.454616055067, 30.398374843679, 30.342133632291, 30.285892420901, + 30.229651209510, 30.173409998119, 30.117168786726, 30.060927575332, 30.004686363937, 29.948445152541, + 29.892203941144, 29.835962729746, 29.779721518347, 29.723480306947, 29.667239095546, 29.610997884144, + 29.554756672741, 29.498515461337, 29.442274249932, 29.386033038526, 29.329791827119, 29.273550615711, + 29.217309404302, 29.161068192891, 29.104826981480, 29.048585770068, 28.992344558655, 28.936103347241, + 28.879862135826, 28.823620924410, 28.767379712994, 28.711138501576, 28.654897290157, 28.598656078737, + 28.542414867316, 28.486173655895, 28.429932444472, 28.373691233049, 28.317450021624, 28.261208810199, + 28.204967598772, 28.148726387345, 28.092485175917, 28.036243964487, 27.980002753057, 27.923761541626, + 27.867520330194, 27.811279118762, 27.755037907328, 27.698796695893, 27.642555484458, 27.586314273021, + 27.530073061584, 27.473831850146, 27.417590638707, 27.361349427267, 27.305108215826, 27.248867004384, + 27.192625792941, 27.136384581498, 27.080143370053, 27.023902158608, 26.967660947162, 26.911419735715, + 26.855178524267, 26.798937312818, 26.742696101369, 26.686454889918, 26.630213678467, 26.573972467015, + 26.517731255562, 26.461490044108, 26.405248832653, 26.349007621198, 26.292766409742, 26.236525198285, + 26.180283986827, 26.124042775368, 26.067801563908, 26.011560352448, 25.955319140987, 25.899077929525, + 25.842836718062, 25.786595506598, 25.730354295134, 25.674113083668, 25.617871872202, 25.561630660735, + 25.505389449268, 25.449148237799, 25.392907026330, 25.336665814860, 25.280424603389, 25.224183391918, + 25.167942180446, 25.111700968972, 25.055459757499, 24.999218546024, 24.942977334548, 24.886736123072, + 24.830494911595, 24.774253700118, 24.718012488639, 24.661771277160, 24.605530065680, 24.549288854199, + 24.493047642718, 24.436806431236, 24.380565219753, 24.324324008269, 24.268082796785, 24.211841585300, + 24.155600373814, 24.099359162327, 24.043117950840, 23.986876739352, 23.930635527863, 23.874394316374, + 23.818153104884, 23.761911893393, 23.705670681901, 23.649429470409, 23.593188258916, 23.536947047422, + 23.480705835928, 23.424464624433, 23.368223412937, 23.311982201441, 23.255740989943, 23.199499778446, + 23.143258566947, 23.087017355448, 23.030776143948, 22.974534932447, 22.918293720946, 22.862052509444, + 22.805811297942, 22.749570086438, 22.693328874935, 22.637087663430, 22.580846451925, 22.524605240419, + 22.468364028912, 22.412122817405, 22.355881605897, 22.299640394389, 22.243399182880, 22.187157971370, + 22.130916759859, 22.074675548348, 22.018434336837, 21.962193125324, 21.905951913811, 21.849710702298, + 21.793469490784, 21.737228279269, 21.680987067753, 21.624745856237, 21.568504644721, 21.512263433203, + 21.456022221685, 21.399781010167, 21.343539798648, 21.287298587128, 21.231057375607, 21.174816164087, + 21.118574952565, 21.062333741043, 21.006092529520, 20.949851317997, 20.893610106473, 20.837368894948, + 20.781127683423, 20.724886471897, 20.668645260371, 20.612404048844, 20.556162837317, 20.499921625789, + 20.443680414260, 20.387439202731, 20.331197991201, 20.274956779671, 20.218715568140, 20.162474356609, + 20.106233145077, 20.049991933544, 19.993750722011, 19.937509510477, 19.881268298943, 19.825027087408, + 19.768785875873, 19.712544664337, 19.656303452801, 19.600062241264, 19.543821029726, 19.487579818188, + 19.431338606650, 19.375097395110, 19.318856183571, 19.262614972031, 19.206373760490, 19.150132548949, + 19.093891337407, 19.037650125865, 18.981408914322, 18.925167702779, 18.868926491235, 18.812685279690, + 18.756444068146, 18.700202856600, 18.643961645054, 18.587720433508, 18.531479221961, 18.475238010414, + 18.418996798866, 18.362755587317, 18.306514375769, 18.250273164219, 18.194031952669, 18.137790741119, + 18.081549529568, 18.025308318017, 17.969067106465, 17.912825894913, 17.856584683360, 17.800343471807, + 17.744102260253, 17.687861048699, 17.631619837144, 17.575378625589, 17.519137414033, 17.462896202477, + 17.406654990920, 17.350413779363, 17.294172567806, 17.237931356248, 17.181690144690, 17.125448933131, + 17.069207721571, 17.012966510012, 16.956725298451, 16.900484086891, 16.844242875330, 16.788001663768, + 16.731760452206, 16.675519240644, 16.619278029081, 16.563036817517, 16.506795605954, 16.450554394389, + 16.394313182825, 16.338071971260, 16.281830759694, 16.225589548128, 16.169348336562, 16.113107124995, + 16.056865913428, 16.000624701860, 15.944383490292, 15.888142278724, 15.831901067155, 15.775659855586, + 15.719418644016, 15.663177432446, 15.606936220876, 15.550695009305, 15.494453797733, 15.438212586162, + 15.381971374590, 15.325730163017, 15.269488951444, 15.213247739871, 15.157006528297, 15.100765316723, + 15.044524105149, 14.988282893574, 14.932041681998, 14.875800470423, 14.819559258847, 14.763318047270, + 14.707076835694, 14.650835624116, 14.594594412539, 14.538353200961, 14.482111989383, 14.425870777804, + 14.369629566225, 14.313388354646, 14.257147143066, 14.200905931486, 14.144664719905, 14.088423508324, + 14.032182296743, 13.975941085162, 13.919699873580, 13.863458661998, 13.807217450415, 13.750976238832, + 13.694735027249, 13.638493815665, 13.582252604081, 13.526011392497, 13.469770180912, 13.413528969327, + 13.357287757741, 13.301046546156, 13.244805334570, 13.188564122983, 13.132322911396, 13.076081699809, + 13.019840488222, 12.963599276634, 12.907358065046, 12.851116853458, 12.794875641869, 12.738634430280, + 12.682393218691, 12.626152007101, 12.569910795511, 12.513669583921, 12.457428372330, 12.401187160739, + 12.344945949148, 12.288704737557, 12.232463525965, 12.176222314373, 12.119981102780, 12.063739891187, + 12.007498679594, 11.951257468001, 11.895016256407, 11.838775044813, 11.782533833219, 11.726292621625, + 11.670051410030, 11.613810198435, 11.557568986839, 11.501327775244, 11.445086563648, 11.388845352051, + 11.332604140455, 11.276362928858, 11.220121717261, 11.163880505664, 11.107639294066, 11.051398082468, + 10.995156870870, 10.938915659271, 10.882674447672, 10.826433236073, 10.770192024474, 10.713950812875, + 10.657709601275, 10.601468389675, 10.545227178074, 10.488985966474, 10.432744754873, 10.376503543272, + 10.320262331670, 10.264021120069, 10.207779908467, 10.151538696865, 10.095297485262, 10.039056273660, + 9.982815062057, 9.926573850454, 9.870332638851, 9.814091427247, 9.757850215643, 9.701609004039, 9.645367792435, + 9.589126580830, 9.532885369225, 9.476644157620, 9.420402946015, 9.364161734410, 9.307920522804, 9.251679311198, + 9.195438099592, 9.139196887985, 9.082955676379, 9.026714464772, 8.970473253165, 8.914232041558, 8.857990829950, + 8.801749618343, 8.745508406735, 8.689267195127, 8.633025983518, 8.576784771910, 8.520543560301, 8.464302348692, + 8.408061137083, 8.351819925473, 8.295578713864, 8.239337502254, 8.183096290644, 8.126855079034, 8.070613867424, + 8.014372655813, 7.958131444202, 7.901890232591, 7.845649020980, 7.789407809369, 7.733166597758, 7.676925386146, + 7.620684174534, 7.564442962922, 7.508201751310, 7.451960539697, 7.395719328085, 7.339478116472, 7.283236904859, + 7.226995693246, 7.170754481632, 7.114513270019, 7.058272058405, 7.002030846792, 6.945789635178, 6.889548423563, + 6.833307211949, 6.777066000335, 6.720824788720, 6.664583577105, 6.608342365490, 6.552101153875, 6.495859942260, + 6.439618730644, 6.383377519029, 6.327136307413, 6.270895095797, 6.214653884181, 6.158412672565, 6.102171460949, + 6.045930249332, 5.989689037715, 5.933447826099, 5.877206614482, 5.820965402865, 5.764724191248, 5.708482979630, + 5.652241768013, 5.596000556395, 5.539759344777, 5.483518133160, 5.427276921542, 5.371035709923, 5.314794498305, + 5.258553286687, 5.202312075068, 5.146070863450, 5.089829651831, 5.033588440212, 4.977347228593, 4.921106016974, + 4.864864805355, 4.808623593735, 4.752382382116, 4.696141170496, 4.639899958877, 4.583658747257, 4.527417535637, + 4.471176324017, 4.414935112397, 4.358693900777, 4.302452689156, 4.246211477536, 4.189970265915, 4.133729054295, + 4.077487842674, 4.021246631053, 3.965005419432, 3.908764207811, 3.852522996190, 3.796281784569, 3.740040572948, + 3.683799361327, 3.627558149705, 3.571316938084, 3.515075726462, 3.458834514840, 3.402593303218, 3.346352091597, + 3.290110879975, 3.233869668353, 3.177628456730, 3.121387245108, 3.065146033486, 3.008904821864, 2.952663610241, + 2.896422398619, 2.840181186996, 2.783939975374, 2.727698763751, 2.671457552128, 2.615216340506, 2.558975128883, + 2.502733917260, 2.446492705637, 2.390251494014, 2.334010282391, 2.277769070768, 2.221527859144, 2.165286647521, + 2.109045435898, 2.052804224275, 1.996563012651, 1.940321801028, 1.884080589404, 1.827839377781, 1.771598166157, + 1.715356954533, 1.659115742910, 1.602874531286, 1.546633319662, 1.490392108039, 1.434150896415, 1.377909684791, + 1.321668473167, 1.265427261543, 1.209186049919, 1.152944838295, 1.096703626671, 1.040462415047, 0.984221203423, + 0.927979991799, 0.871738780175, 0.815497568551, 0.759256356927, 0.703015145303, 0.646773933679, 0.590532722054, + 0.534291510430, 0.478050298806, 0.421809087182, 0.365567875558, 0.309326663933, 0.253085452309, 0.196844240685, + 0.140603029061, 0.084361817436, 0.028120605812 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N200.cc b/src/atlas/grid/detail/spacing/gaussian/N200.cc index 761d85ea9..a6aa53cba 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N200.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N200.cc @@ -7,51 +7,43 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(200,LIST( - 89.655964246870, 89.210294391654, 88.761992615075, 88.313096175209, 87.863974165523, - 87.414743002061, 86.965450837218, 86.516121156344, 86.066766768868, 85.617395252044, - 85.168011373562, 84.718618282731, 84.269218143214, 83.819812490525, 83.370402444494, - 82.920988840982, 82.471572316507, 82.022153364315, 81.572732372538, 81.123309650771, - 80.673885448980, 80.224459971196, 79.775033385601, 79.325605832072, 78.876177427890, - 78.426748272132, 77.977318449063, 77.527888030811, 77.078457079472, 76.629025648798, - 76.179593785550, 75.730161530601, 75.280728919836, 74.831295984884, 74.381862753740, - 73.932429251264, 73.482995499613, 73.033561518596, 72.584127325979, 72.134692937741, - 71.685258368293, 71.235823630664, 70.786388736668, 70.336953697036, 69.887518521543, - 69.438083219108, 68.988647797888, 68.539212265356, 68.089776628374, 67.640340893252, - 67.190905065802, 66.741469151388, 66.292033154968, 65.842597081130, 65.393160934128, - 64.943724717911, 64.494288436150, 64.044852092262, 63.595415689431, 63.145979230630, - 62.696542718633, 62.247106156039, 61.797669545278, 61.348232888629, 60.898796188231, - 60.449359446093, 59.999922664103, 59.550485844039, 59.101048987575, 58.651612096289, - 58.202175171671, 57.752738215127, 57.303301227987, 56.853864211509, 56.404427166883, - 55.954990095237, 55.505552997640, 55.056115875108, 54.606678728603, 54.157241559042, - 53.707804367293, 53.258367154186, 52.808929920507, 52.359492667008, 51.910055394404, - 51.460618103377, 51.011180794579, 50.561743468631, 50.112306126128, 49.662868767636, - 49.213431393698, 48.763994004835, 48.314556601543, 47.865119184298, 47.415681753557, - 46.966244309758, 46.516806853321, 46.067369384648, 45.617931904125, 45.168494412125, - 44.719056909005, 44.269619395107, 43.820181870762, 43.370744336287, 42.921306791988, - 42.471869238160, 42.022431675086, 41.572994103039, 41.123556522283, 40.674118933073, - 40.224681335653, 39.775243730260, 39.325806117123, 38.876368496463, 38.426930868493, - 37.977493233419, 37.528055591442, 37.078617942753, 36.629180287541, 36.179742625985, - 35.730304958260, 35.280867284537, 34.831429604979, 34.381991919747, 33.932554228994, - 33.483116532871, 33.033678831522, 32.584241125090, 32.134803413711, 31.685365697518, - 31.235927976641, 30.786490251206, 30.337052521334, 29.887614787146, 29.438177048755, - 28.988739306277, 28.539301559819, 28.089863809488, 27.640426055390, 27.190988297625, - 26.741550536291, 26.292112771486, 25.842675003304, 25.393237231836, 24.943799457171, - 24.494361679398, 24.044923898602, 23.595486114866, 23.146048328272, 22.696610538899, - 22.247172746826, 21.797734952130, 21.348297154884, 20.898859355163, 20.449421553037, - 19.999983748578, 19.550545941853, 19.101108132931, 18.651670321878, 18.202232508759, - 17.752794693638, 17.303356876577, 16.853919057638, 16.404481236882, 15.955043414368, - 15.505605590154, 15.056167764299, 14.606729936858, 14.157292107888, 13.707854277444, - 13.258416445580, 12.808978612349, 12.359540777805, 11.910102941998, 11.460665104981, - 11.011227266804, 10.561789427517, 10.112351587170, 9.662913745812, 9.213475903492, - 8.764038060256, 8.314600216153, 7.865162371230, 7.415724525534, 6.966286679110, - 6.516848832004, 6.067410984263, 5.617973135931, 5.168535287054, 4.719097437675, - 4.269659587839, 3.820221737591, 3.370783886975, 2.921346036033, 2.471908184811, - 2.022470333351, 1.573032481696, 1.123594629891, 0.674156777978, 0.224718926000 - )) +DEFINE_GAUSSIAN_LATITUDES( + 200, LIST( 89.655964246870, 89.210294391654, 88.761992615075, 88.313096175209, 87.863974165523, 87.414743002061, + 86.965450837218, 86.516121156344, 86.066766768868, 85.617395252044, 85.168011373562, 84.718618282731, + 84.269218143214, 83.819812490525, 83.370402444494, 82.920988840982, 82.471572316507, 82.022153364315, + 81.572732372538, 81.123309650771, 80.673885448980, 80.224459971196, 79.775033385601, 79.325605832072, + 78.876177427890, 78.426748272132, 77.977318449063, 77.527888030811, 77.078457079472, 76.629025648798, + 76.179593785550, 75.730161530601, 75.280728919836, 74.831295984884, 74.381862753740, 73.932429251264, + 73.482995499613, 73.033561518596, 72.584127325979, 72.134692937741, 71.685258368293, 71.235823630664, + 70.786388736668, 70.336953697036, 69.887518521543, 69.438083219108, 68.988647797888, 68.539212265356, + 68.089776628374, 67.640340893252, 67.190905065802, 66.741469151388, 66.292033154968, 65.842597081130, + 65.393160934128, 64.943724717911, 64.494288436150, 64.044852092262, 63.595415689431, 63.145979230630, + 62.696542718633, 62.247106156039, 61.797669545278, 61.348232888629, 60.898796188231, 60.449359446093, + 59.999922664103, 59.550485844039, 59.101048987575, 58.651612096289, 58.202175171671, 57.752738215127, + 57.303301227987, 56.853864211509, 56.404427166883, 55.954990095237, 55.505552997640, 55.056115875108, + 54.606678728603, 54.157241559042, 53.707804367293, 53.258367154186, 52.808929920507, 52.359492667008, + 51.910055394404, 51.460618103377, 51.011180794579, 50.561743468631, 50.112306126128, 49.662868767636, + 49.213431393698, 48.763994004835, 48.314556601543, 47.865119184298, 47.415681753557, 46.966244309758, + 46.516806853321, 46.067369384648, 45.617931904125, 45.168494412125, 44.719056909005, 44.269619395107, + 43.820181870762, 43.370744336287, 42.921306791988, 42.471869238160, 42.022431675086, 41.572994103039, + 41.123556522283, 40.674118933073, 40.224681335653, 39.775243730260, 39.325806117123, 38.876368496463, + 38.426930868493, 37.977493233419, 37.528055591442, 37.078617942753, 36.629180287541, 36.179742625985, + 35.730304958260, 35.280867284537, 34.831429604979, 34.381991919747, 33.932554228994, 33.483116532871, + 33.033678831522, 32.584241125090, 32.134803413711, 31.685365697518, 31.235927976641, 30.786490251206, + 30.337052521334, 29.887614787146, 29.438177048755, 28.988739306277, 28.539301559819, 28.089863809488, + 27.640426055390, 27.190988297625, 26.741550536291, 26.292112771486, 25.842675003304, 25.393237231836, + 24.943799457171, 24.494361679398, 24.044923898602, 23.595486114866, 23.146048328272, 22.696610538899, + 22.247172746826, 21.797734952130, 21.348297154884, 20.898859355163, 20.449421553037, 19.999983748578, + 19.550545941853, 19.101108132931, 18.651670321878, 18.202232508759, 17.752794693638, 17.303356876577, + 16.853919057638, 16.404481236882, 15.955043414368, 15.505605590154, 15.056167764299, 14.606729936858, + 14.157292107888, 13.707854277444, 13.258416445580, 12.808978612349, 12.359540777805, 11.910102941998, + 11.460665104981, 11.011227266804, 10.561789427517, 10.112351587170, 9.662913745812, 9.213475903492, + 8.764038060256, 8.314600216153, 7.865162371230, 7.415724525534, 6.966286679110, 6.516848832004, + 6.067410984263, 5.617973135931, 5.168535287054, 4.719097437675, 4.269659587839, 3.820221737591, + 3.370783886975, 2.921346036033, 2.471908184811, 2.022470333351, 1.573032481696, 1.123594629891, + 0.674156777978, 0.224718926000 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N2000.cc b/src/atlas/grid/detail/spacing/gaussian/N2000.cc index 47eed81e6..123df8f13 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N2000.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N2000.cc @@ -7,411 +7,340 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(2000,LIST( - 89.965557716640, 89.920940588056, 89.876059971209, 89.831119821127, 89.786157088682, - 89.741183428577, 89.696203661469, 89.651220138535, 89.606234142158, 89.561246430917, - 89.516257482116, 89.471267611042, 89.426277034302, 89.381285905620, 89.336294337107, - 89.291302412440, 89.246310195345, 89.201317735199, 89.156325070860, 89.111332233323, - 89.066339247611, 89.021346134150, 88.976352909776, 88.931359588494, 88.886366182044, - 88.841372700344, 88.796379151831, 88.751385543725, 88.706391882242, 88.661398172763, - 88.616404419970, 88.571410627953, 88.526416800305, 88.481422940193, 88.436429050418, - 88.391435133469, 88.346441191564, 88.301447226685, 88.256453240612, 88.211459234943, - 88.166465211121, 88.121471170450, 88.076477114112, 88.031483043182, 87.986488958637, - 87.941494861370, 87.896500752197, 87.851506631867, 87.806512501066, 87.761518360424, - 87.716524210525, 87.671530051904, 87.626535885058, 87.581541710445, 87.536547528491, - 87.491553339591, 87.446559144112, 87.401564942396, 87.356570734762, 87.311576521506, - 87.266582302906, 87.221588079222, 87.176593850696, 87.131599617557, 87.086605380019, - 87.041611138281, 86.996616892534, 86.951622642953, 86.906628389707, 86.861634132954, - 86.816639872841, 86.771645609509, 86.726651343092, 86.681657073714, 86.636662801495, - 86.591668526547, 86.546674248976, 86.501679968884, 86.456685686367, 86.411691401516, - 86.366697114417, 86.321702825154, 86.276708533805, 86.231714240444, 86.186719945143, - 86.141725647969, 86.096731348988, 86.051737048260, 86.006742745846, 85.961748441801, - 85.916754136180, 85.871759829034, 85.826765520411, 85.781771210361, 85.736776898926, - 85.691782586152, 85.646788272080, 85.601793956749, 85.556799640198, 85.511805322463, - 85.466811003580, 85.421816683582, 85.376822362502, 85.331828040372, 85.286833717221, - 85.241839393078, 85.196845067971, 85.151850741928, 85.106856414973, 85.061862087133, - 85.016867758430, 84.971873428888, 84.926879098529, 84.881884767375, 84.836890435447, - 84.791896102764, 84.746901769347, 84.701907435213, 84.656913100381, 84.611918764868, - 84.566924428692, 84.521930091868, 84.476935754413, 84.431941416342, 84.386947077669, - 84.341952738409, 84.296958398576, 84.251964058183, 84.206969717244, 84.161975375770, - 84.116981033775, 84.071986691270, 84.026992348266, 83.981998004775, 83.937003660808, - 83.892009316375, 83.847014971487, 83.802020626152, 83.757026280382, 83.712031934185, - 83.667037587570, 83.622043240547, 83.577048893124, 83.532054545308, 83.487060197109, - 83.442065848534, 83.397071499592, 83.352077150288, 83.307082800631, 83.262088450628, - 83.217094100285, 83.172099749610, 83.127105398609, 83.082111047287, 83.037116695653, - 82.992122343710, 82.947127991466, 82.902133638926, 82.857139286096, 82.812144932981, - 82.767150579586, 82.722156225917, 82.677161871979, 82.632167517776, 82.587173163314, - 82.542178808596, 82.497184453629, 82.452190098415, 82.407195742961, 82.362201387269, - 82.317207031344, 82.272212675190, 82.227218318811, 82.182223962211, 82.137229605394, - 82.092235248363, 82.047240891122, 82.002246533675, 81.957252176025, 81.912257818176, - 81.867263460130, 81.822269101891, 81.777274743462, 81.732280384847, 81.687286026048, - 81.642291667068, 81.597297307910, 81.552302948577, 81.507308589073, 81.462314229398, - 81.417319869557, 81.372325509552, 81.327331149384, 81.282336789058, 81.237342428575, - 81.192348067938, 81.147353707149, 81.102359346210, 81.057364985124, 81.012370623893, - 80.967376262518, 80.922381901003, 80.877387539349, 80.832393177558, 80.787398815633, - 80.742404453575, 80.697410091386, 80.652415729068, 80.607421366622, 80.562427004052, - 80.517432641358, 80.472438278542, 80.427443915607, 80.382449552553, 80.337455189382, - 80.292460826096, 80.247466462697, 80.202472099185, 80.157477735564, 80.112483371833, - 80.067489007995, 80.022494644051, 79.977500280003, 79.932505915852, 79.887511551598, - 79.842517187245, 79.797522822792, 79.752528458242, 79.707534093595, 79.662539728853, - 79.617545364016, 79.572550999088, 79.527556634067, 79.482562268956, 79.437567903756, - 79.392573538468, 79.347579173093, 79.302584807632, 79.257590442086, 79.212596076457, - 79.167601710745, 79.122607344951, 79.077612979076, 79.032618613122, 78.987624247089, - 78.942629880979, 78.897635514791, 78.852641148528, 78.807646782190, 78.762652415777, - 78.717658049292, 78.672663682734, 78.627669316105, 78.582674949405, 78.537680582636, - 78.492686215798, 78.447691848891, 78.402697481917, 78.357703114877, 78.312708747771, - 78.267714380599, 78.222720013364, 78.177725646065, 78.132731278703, 78.087736911279, - 78.042742543794, 77.997748176248, 77.952753808642, 77.907759440976, 77.862765073252, - 77.817770705470, 77.772776337630, 77.727781969733, 77.682787601781, 77.637793233773, - 77.592798865709, 77.547804497592, 77.502810129421, 77.457815761196, 77.412821392919, - 77.367827024590, 77.322832656210, 77.277838287778, 77.232843919296, 77.187849550764, - 77.142855182183, 77.097860813553, 77.052866444875, 77.007872076149, 76.962877707375, - 76.917883338555, 76.872888969688, 76.827894600776, 76.782900231818, 76.737905862815, - 76.692911493767, 76.647917124676, 76.602922755540, 76.557928386362, 76.512934017141, - 76.467939647878, 76.422945278573, 76.377950909226, 76.332956539838, 76.287962170410, - 76.242967800941, 76.197973431433, 76.152979061885, 76.107984692297, 76.062990322672, - 76.017995953007, 75.973001583305, 75.928007213566, 75.883012843789, 75.838018473975, - 75.793024104124, 75.748029734238, 75.703035364315, 75.658040994357, 75.613046624364, - 75.568052254336, 75.523057884273, 75.478063514177, 75.433069144046, 75.388074773882, - 75.343080403684, 75.298086033454, 75.253091663191, 75.208097292895, 75.163102922567, - 75.118108552208, 75.073114181817, 75.028119811395, 74.983125440942, 74.938131070459, - 74.893136699945, 74.848142329401, 74.803147958827, 74.758153588223, 74.713159217590, - 74.668164846929, 74.623170476238, 74.578176105519, 74.533181734771, 74.488187363996, - 74.443192993192, 74.398198622361, 74.353204251503, 74.308209880618, 74.263215509706, - 74.218221138767, 74.173226767802, 74.128232396810, 74.083238025793, 74.038243654750, - 73.993249283681, 73.948254912587, 73.903260541468, 73.858266170324, 73.813271799156, - 73.768277427963, 73.723283056746, 73.678288685504, 73.633294314239, 73.588299942950, - 73.543305571638, 73.498311200302, 73.453316828943, 73.408322457562, 73.363328086157, - 73.318333714730, 73.273339343281, 73.228344971810, 73.183350600316, 73.138356228801, - 73.093361857264, 73.048367485706, 73.003373114126, 72.958378742525, 72.913384370904, - 72.868389999261, 72.823395627598, 72.778401255914, 72.733406884210, 72.688412512486, - 72.643418140742, 72.598423768978, 72.553429397194, 72.508435025391, 72.463440653568, - 72.418446281727, 72.373451909866, 72.328457537986, 72.283463166087, 72.238468794170, - 72.193474422234, 72.148480050280, 72.103485678307, 72.058491306317, 72.013496934308, - 71.968502562282, 71.923508190238, 71.878513818176, 71.833519446097, 71.788525074001, - 71.743530701887, 71.698536329757, 71.653541957609, 71.608547585445, 71.563553213264, - 71.518558841066, 71.473564468852, 71.428570096622, 71.383575724376, 71.338581352113, - 71.293586979834, 71.248592607540, 71.203598235230, 71.158603862904, 71.113609490563, - 71.068615118206, 71.023620745834, 70.978626373447, 70.933632001045, 70.888637628628, - 70.843643256196, 70.798648883749, 70.753654511288, 70.708660138812, 70.663665766321, - 70.618671393817, 70.573677021298, 70.528682648765, 70.483688276217, 70.438693903656, - 70.393699531081, 70.348705158492, 70.303710785890, 70.258716413274, 70.213722040644, - 70.168727668002, 70.123733295345, 70.078738922676, 70.033744549993, 69.988750177298, - 69.943755804589, 69.898761431868, 69.853767059134, 69.808772686387, 69.763778313628, - 69.718783940856, 69.673789568072, 69.628795195275, 69.583800822466, 69.538806449645, - 69.493812076812, 69.448817703966, 69.403823331109, 69.358828958240, 69.313834585359, - 69.268840212466, 69.223845839562, 69.178851466646, 69.133857093719, 69.088862720780, - 69.043868347830, 68.998873974869, 68.953879601897, 68.908885228913, 68.863890855918, - 68.818896482913, 68.773902109896, 68.728907736869, 68.683913363831, 68.638918990782, - 68.593924617722, 68.548930244652, 68.503935871572, 68.458941498480, 68.413947125379, - 68.368952752267, 68.323958379145, 68.278964006013, 68.233969632871, 68.188975259719, - 68.143980886557, 68.098986513384, 68.053992140202, 68.008997767010, 67.964003393809, - 67.919009020597, 67.874014647376, 67.829020274146, 67.784025900906, 67.739031527656, - 67.694037154397, 67.649042781129, 67.604048407852, 67.559054034565, 67.514059661269, - 67.469065287964, 67.424070914650, 67.379076541327, 67.334082167995, 67.289087794654, - 67.244093421304, 67.199099047946, 67.154104674578, 67.109110301202, 67.064115927817, - 67.019121554424, 66.974127181022, 66.929132807612, 66.884138434193, 66.839144060766, - 66.794149687331, 66.749155313887, 66.704160940435, 66.659166566975, 66.614172193507, - 66.569177820030, 66.524183446546, 66.479189073053, 66.434194699553, 66.389200326044, - 66.344205952528, 66.299211579004, 66.254217205472, 66.209222831933, 66.164228458385, - 66.119234084830, 66.074239711268, 66.029245337698, 65.984250964120, 65.939256590535, - 65.894262216943, 65.849267843343, 65.804273469735, 65.759279096121, 65.714284722499, - 65.669290348870, 65.624295975233, 65.579301601590, 65.534307227939, 65.489312854282, - 65.444318480617, 65.399324106945, 65.354329733267, 65.309335359581, 65.264340985889, - 65.219346612190, 65.174352238484, 65.129357864771, 65.084363491051, 65.039369117325, - 64.994374743592, 64.949380369852, 64.904385996106, 64.859391622354, 64.814397248594, - 64.769402874829, 64.724408501057, 64.679414127278, 64.634419753493, 64.589425379702, - 64.544431005904, 64.499436632100, 64.454442258290, 64.409447884474, 64.364453510652, - 64.319459136823, 64.274464762988, 64.229470389147, 64.184476015301, 64.139481641448, - 64.094487267589, 64.049492893724, 64.004498519853, 63.959504145977, 63.914509772094, - 63.869515398206, 63.824521024312, 63.779526650412, 63.734532276506, 63.689537902595, - 63.644543528678, 63.599549154755, 63.554554780827, 63.509560406893, 63.464566032953, - 63.419571659008, 63.374577285058, 63.329582911102, 63.284588537140, 63.239594163174, - 63.194599789201, 63.149605415224, 63.104611041241, 63.059616667252, 63.014622293259, - 62.969627919260, 62.924633545256, 62.879639171246, 62.834644797232, 62.789650423212, - 62.744656049187, 62.699661675157, 62.654667301123, 62.609672927082, 62.564678553037, - 62.519684178987, 62.474689804932, 62.429695430872, 62.384701056807, 62.339706682737, - 62.294712308663, 62.249717934583, 62.204723560498, 62.159729186409, 62.114734812315, - 62.069740438216, 62.024746064113, 61.979751690004, 61.934757315891, 61.889762941774, - 61.844768567651, 61.799774193524, 61.754779819393, 61.709785445257, 61.664791071116, - 61.619796696970, 61.574802322821, 61.529807948666, 61.484813574508, 61.439819200344, - 61.394824826177, 61.349830452005, 61.304836077828, 61.259841703647, 61.214847329462, - 61.169852955272, 61.124858581079, 61.079864206880, 61.034869832678, 60.989875458471, - 60.944881084260, 60.899886710045, 60.854892335826, 60.809897961603, 60.764903587375, - 60.719909213143, 60.674914838907, 60.629920464667, 60.584926090423, 60.539931716175, - 60.494937341923, 60.449942967667, 60.404948593406, 60.359954219142, 60.314959844874, - 60.269965470602, 60.224971096326, 60.179976722046, 60.134982347762, 60.089987973475, - 60.044993599183, 59.999999224888, 59.955004850588, 59.910010476285, 59.865016101979, - 59.820021727668, 59.775027353354, 59.730032979036, 59.685038604714, 59.640044230388, - 59.595049856059, 59.550055481726, 59.505061107390, 59.460066733049, 59.415072358706, - 59.370077984358, 59.325083610007, 59.280089235653, 59.235094861295, 59.190100486933, - 59.145106112568, 59.100111738199, 59.055117363827, 59.010122989451, 58.965128615072, - 58.920134240689, 58.875139866303, 58.830145491914, 58.785151117521, 58.740156743125, - 58.695162368725, 58.650167994322, 58.605173619916, 58.560179245506, 58.515184871093, - 58.470190496677, 58.425196122257, 58.380201747834, 58.335207373408, 58.290212998979, - 58.245218624546, 58.200224250110, 58.155229875671, 58.110235501229, 58.065241126784, - 58.020246752335, 57.975252377883, 57.930258003428, 57.885263628970, 57.840269254509, - 57.795274880045, 57.750280505578, 57.705286131108, 57.660291756634, 57.615297382158, - 57.570303007678, 57.525308633196, 57.480314258710, 57.435319884222, 57.390325509730, - 57.345331135236, 57.300336760738, 57.255342386238, 57.210348011735, 57.165353637228, - 57.120359262719, 57.075364888207, 57.030370513692, 56.985376139174, 56.940381764654, - 56.895387390130, 56.850393015604, 56.805398641075, 56.760404266543, 56.715409892008, - 56.670415517470, 56.625421142930, 56.580426768387, 56.535432393841, 56.490438019292, - 56.445443644741, 56.400449270187, 56.355454895630, 56.310460521071, 56.265466146508, - 56.220471771943, 56.175477397376, 56.130483022806, 56.085488648233, 56.040494273657, - 55.995499899079, 55.950505524499, 55.905511149915, 55.860516775329, 55.815522400741, - 55.770528026150, 55.725533651556, 55.680539276960, 55.635544902361, 55.590550527760, - 55.545556153156, 55.500561778550, 55.455567403941, 55.410573029329, 55.365578654716, - 55.320584280099, 55.275589905481, 55.230595530859, 55.185601156236, 55.140606781610, - 55.095612406981, 55.050618032350, 55.005623657717, 54.960629283081, 54.915634908443, - 54.870640533803, 54.825646159160, 54.780651784515, 54.735657409867, 54.690663035217, - 54.645668660565, 54.600674285910, 54.555679911253, 54.510685536594, 54.465691161933, - 54.420696787269, 54.375702412603, 54.330708037935, 54.285713663264, 54.240719288591, - 54.195724913916, 54.150730539239, 54.105736164559, 54.060741789877, 54.015747415193, - 53.970753040507, 53.925758665819, 53.880764291128, 53.835769916436, 53.790775541741, - 53.745781167044, 53.700786792344, 53.655792417643, 53.610798042940, 53.565803668234, - 53.520809293526, 53.475814918816, 53.430820544104, 53.385826169390, 53.340831794674, - 53.295837419956, 53.250843045236, 53.205848670513, 53.160854295789, 53.115859921062, - 53.070865546334, 53.025871171603, 52.980876796871, 52.935882422136, 52.890888047400, - 52.845893672661, 52.800899297920, 52.755904923178, 52.710910548433, 52.665916173687, - 52.620921798938, 52.575927424188, 52.530933049435, 52.485938674681, 52.440944299925, - 52.395949925166, 52.350955550406, 52.305961175644, 52.260966800880, 52.215972426114, - 52.170978051346, 52.125983676577, 52.080989301805, 52.035994927032, 51.991000552256, - 51.946006177479, 51.901011802700, 51.856017427919, 51.811023053137, 51.766028678352, - 51.721034303566, 51.676039928777, 51.631045553987, 51.586051179196, 51.541056804402, - 51.496062429606, 51.451068054809, 51.406073680010, 51.361079305209, 51.316084930407, - 51.271090555603, 51.226096180796, 51.181101805989, 51.136107431179, 51.091113056368, - 51.046118681555, 51.001124306740, 50.956129931923, 50.911135557105, 50.866141182285, - 50.821146807464, 50.776152432640, 50.731158057815, 50.686163682989, 50.641169308160, - 50.596174933330, 50.551180558498, 50.506186183665, 50.461191808830, 50.416197433993, - 50.371203059155, 50.326208684315, 50.281214309473, 50.236219934630, 50.191225559785, - 50.146231184939, 50.101236810091, 50.056242435241, 50.011248060390, 49.966253685537, - 49.921259310682, 49.876264935826, 49.831270560969, 49.786276186110, 49.741281811249, - 49.696287436387, 49.651293061523, 49.606298686657, 49.561304311790, 49.516309936922, - 49.471315562052, 49.426321187180, 49.381326812307, 49.336332437432, 49.291338062556, - 49.246343687679, 49.201349312800, 49.156354937919, 49.111360563037, 49.066366188153, - 49.021371813268, 48.976377438381, 48.931383063493, 48.886388688604, 48.841394313713, - 48.796399938820, 48.751405563927, 48.706411189031, 48.661416814134, 48.616422439236, - 48.571428064337, 48.526433689435, 48.481439314533, 48.436444939629, 48.391450564724, - 48.346456189817, 48.301461814909, 48.256467439999, 48.211473065088, 48.166478690176, - 48.121484315262, 48.076489940347, 48.031495565431, 47.986501190513, 47.941506815594, - 47.896512440673, 47.851518065751, 47.806523690828, 47.761529315903, 47.716534940977, - 47.671540566050, 47.626546191121, 47.581551816191, 47.536557441260, 47.491563066327, - 47.446568691393, 47.401574316458, 47.356579941521, 47.311585566583, 47.266591191644, - 47.221596816704, 47.176602441762, 47.131608066819, 47.086613691874, 47.041619316929, - 46.996624941982, 46.951630567034, 46.906636192084, 46.861641817133, 46.816647442181, - 46.771653067228, 46.726658692274, 46.681664317318, 46.636669942361, 46.591675567403, - 46.546681192443, 46.501686817482, 46.456692442521, 46.411698067557, 46.366703692593, - 46.321709317627, 46.276714942661, 46.231720567693, 46.186726192723, 46.141731817753, - 46.096737442781, 46.051743067809, 46.006748692835, 45.961754317859, 45.916759942883, - 45.871765567906, 45.826771192927, 45.781776817947, 45.736782442966, 45.691788067984, - 45.646793693000, 45.601799318016, 45.556804943030, 45.511810568043, 45.466816193055, - 45.421821818066, 45.376827443076, 45.331833068085, 45.286838693092, 45.241844318099, - 45.196849943104, 45.151855568108, 45.106861193111, 45.061866818113, 45.016872443114, - 44.971878068113, 44.926883693112, 44.881889318109, 44.836894943106, 44.791900568101, - 44.746906193095, 44.701911818088, 44.656917443080, 44.611923068071, 44.566928693061, - 44.521934318050, 44.476939943038, 44.431945568025, 44.386951193010, 44.341956817995, - 44.296962442978, 44.251968067961, 44.206973692942, 44.161979317923, 44.116984942902, - 44.071990567880, 44.026996192857, 43.982001817834, 43.937007442809, 43.892013067783, - 43.847018692756, 43.802024317728, 43.757029942699, 43.712035567670, 43.667041192639, - 43.622046817607, 43.577052442574, 43.532058067540, 43.487063692505, 43.442069317469, - 43.397074942432, 43.352080567394, 43.307086192355, 43.262091817315, 43.217097442275, - 43.172103067233, 43.127108692190, 43.082114317146, 43.037119942102, 42.992125567056, - 42.947131192009, 42.902136816962, 42.857142441913, 42.812148066863, 42.767153691813, - 42.722159316762, 42.677164941709, 42.632170566656, 42.587176191602, 42.542181816546, - 42.497187441490, 42.452193066433, 42.407198691375, 42.362204316316, 42.317209941257, - 42.272215566196, 42.227221191134, 42.182226816072, 42.137232441008, 42.092238065944, - 42.047243690878, 42.002249315812, 41.957254940745, 41.912260565677, 41.867266190608, - 41.822271815539, 41.777277440468, 41.732283065396, 41.687288690324, 41.642294315251, - 41.597299940176, 41.552305565101, 41.507311190025, 41.462316814949, 41.417322439871, - 41.372328064792, 41.327333689713, 41.282339314633, 41.237344939551, 41.192350564469, - 41.147356189387, 41.102361814303, 41.057367439218, 41.012373064133, 40.967378689047, - 40.922384313960, 40.877389938872, 40.832395563783, 40.787401188693, 40.742406813603, - 40.697412438512, 40.652418063420, 40.607423688327, 40.562429313233, 40.517434938139, - 40.472440563043, 40.427446187947, 40.382451812850, 40.337457437752, 40.292463062654, - 40.247468687554, 40.202474312454, 40.157479937353, 40.112485562251, 40.067491187149, - 40.022496812045, 39.977502436941, 39.932508061836, 39.887513686731, 39.842519311624, - 39.797524936517, 39.752530561409, 39.707536186300, 39.662541811190, 39.617547436080, - 39.572553060968, 39.527558685857, 39.482564310744, 39.437569935630, 39.392575560516, - 39.347581185401, 39.302586810285, 39.257592435169, 39.212598060052, 39.167603684934, - 39.122609309815, 39.077614934695, 39.032620559575, 38.987626184454, 38.942631809332, - 38.897637434210, 38.852643059087, 38.807648683963, 38.762654308838, 38.717659933713, - 38.672665558587, 38.627671183460, 38.582676808332, 38.537682433204, 38.492688058075, - 38.447693682945, 38.402699307815, 38.357704932684, 38.312710557552, 38.267716182419, - 38.222721807286, 38.177727432152, 38.132733057017, 38.087738681882, 38.042744306746, - 37.997749931609, 37.952755556471, 37.907761181333, 37.862766806194, 37.817772431055, - 37.772778055915, 37.727783680774, 37.682789305632, 37.637794930490, 37.592800555347, - 37.547806180203, 37.502811805059, 37.457817429914, 37.412823054768, 37.367828679622, - 37.322834304475, 37.277839929327, 37.232845554179, 37.187851179030, 37.142856803880, - 37.097862428730, 37.052868053579, 37.007873678428, 36.962879303275, 36.917884928122, - 36.872890552969, 36.827896177815, 36.782901802660, 36.737907427504, 36.692913052348, - 36.647918677191, 36.602924302034, 36.557929926876, 36.512935551717, 36.467941176558, - 36.422946801398, 36.377952426237, 36.332958051076, 36.287963675914, 36.242969300752, - 36.197974925589, 36.152980550425, 36.107986175261, 36.062991800096, 36.017997424930, - 35.973003049764, 35.928008674597, 35.883014299430, 35.838019924262, 35.793025549093, - 35.748031173924, 35.703036798754, 35.658042423584, 35.613048048413, 35.568053673241, - 35.523059298069, 35.478064922896, 35.433070547723, 35.388076172549, 35.343081797374, - 35.298087422199, 35.253093047024, 35.208098671847, 35.163104296670, 35.118109921493, - 35.073115546315, 35.028121171136, 34.983126795957, 34.938132420777, 34.893138045597, - 34.848143670416, 34.803149295234, 34.758154920052, 34.713160544869, 34.668166169686, - 34.623171794502, 34.578177419318, 34.533183044133, 34.488188668948, 34.443194293762, - 34.398199918575, 34.353205543388, 34.308211168200, 34.263216793012, 34.218222417823, - 34.173228042634, 34.128233667444, 34.083239292254, 34.038244917063, 33.993250541871, - 33.948256166679, 33.903261791486, 33.858267416293, 33.813273041099, 33.768278665905, - 33.723284290711, 33.678289915515, 33.633295540319, 33.588301165123, 33.543306789926, - 33.498312414729, 33.453318039531, 33.408323664332, 33.363329289133, 33.318334913934, - 33.273340538734, 33.228346163533, 33.183351788332, 33.138357413131, 33.093363037929, - 33.048368662726, 33.003374287523, 32.958379912319, 32.913385537115, 32.868391161911, - 32.823396786705, 32.778402411500, 32.733408036294, 32.688413661087, 32.643419285880, - 32.598424910672, 32.553430535464, 32.508436160255, 32.463441785046, 32.418447409837, - 32.373453034627, 32.328458659416, 32.283464284205, 32.238469908993, 32.193475533781, - 32.148481158569, 32.103486783356, 32.058492408142, 32.013498032928, 31.968503657714, - 31.923509282499, 31.878514907283, 31.833520532067, 31.788526156851, 31.743531781634, - 31.698537406417, 31.653543031199, 31.608548655981, 31.563554280762, 31.518559905543, - 31.473565530323, 31.428571155103, 31.383576779882, 31.338582404661, 31.293588029440, - 31.248593654218, 31.203599278995, 31.158604903772, 31.113610528549, 31.068616153325, - 31.023621778101, 30.978627402876, 30.933633027651, 30.888638652425, 30.843644277199, - 30.798649901973, 30.753655526746, 30.708661151519, 30.663666776291, 30.618672401062, - 30.573678025834, 30.528683650604, 30.483689275375, 30.438694900145, 30.393700524914, - 30.348706149683, 30.303711774452, 30.258717399220, 30.213723023988, 30.168728648755, - 30.123734273522, 30.078739898289, 30.033745523055, 29.988751147821, 29.943756772586, - 29.898762397351, 29.853768022115, 29.808773646879, 29.763779271642, 29.718784896406, - 29.673790521168, 29.628796145931, 29.583801770692, 29.538807395454, 29.493813020215, - 29.448818644975, 29.403824269736, 29.358829894496, 29.313835519255, 29.268841144014, - 29.223846768772, 29.178852393531, 29.133858018288, 29.088863643046, 29.043869267803, - 28.998874892559, 28.953880517315, 28.908886142071, 28.863891766827, 28.818897391582, - 28.773903016336, 28.728908641090, 28.683914265844, 28.638919890598, 28.593925515351, - 28.548931140103, 28.503936764855, 28.458942389607, 28.413948014359, 28.368953639110, - 28.323959263860, 28.278964888611, 28.233970513361, 28.188976138110, 28.143981762859, - 28.098987387608, 28.053993012356, 28.008998637104, 27.964004261852, 27.919009886599, - 27.874015511346, 27.829021136093, 27.784026760839, 27.739032385585, 27.694038010330, - 27.649043635075, 27.604049259820, 27.559054884564, 27.514060509308, 27.469066134051, - 27.424071758795, 27.379077383538, 27.334083008280, 27.289088633022, 27.244094257764, - 27.199099882505, 27.154105507246, 27.109111131987, 27.064116756727, 27.019122381467, - 26.974128006207, 26.929133630946, 26.884139255685, 26.839144880423, 26.794150505162, - 26.749156129900, 26.704161754637, 26.659167379374, 26.614173004111, 26.569178628847, - 26.524184253584, 26.479189878319, 26.434195503055, 26.389201127790, 26.344206752525, - 26.299212377259, 26.254218001993, 26.209223626727, 26.164229251460, 26.119234876193, - 26.074240500926, 26.029246125658, 25.984251750390, 25.939257375122, 25.894262999853, - 25.849268624584, 25.804274249315, 25.759279874046, 25.714285498776, 25.669291123505, - 25.624296748235, 25.579302372964, 25.534307997693, 25.489313622421, 25.444319247149, - 25.399324871877, 25.354330496604, 25.309336121332, 25.264341746058, 25.219347370785, - 25.174352995511, 25.129358620237, 25.084364244962, 25.039369869688, 24.994375494413, - 24.949381119137, 24.904386743862, 24.859392368586, 24.814397993309, 24.769403618033, - 24.724409242756, 24.679414867478, 24.634420492201, 24.589426116923, 24.544431741645, - 24.499437366366, 24.454442991088, 24.409448615808, 24.364454240529, 24.319459865249, - 24.274465489969, 24.229471114689, 24.184476739409, 24.139482364128, 24.094487988847, - 24.049493613565, 24.004499238283, 23.959504863001, 23.914510487719, 23.869516112436, - 23.824521737153, 23.779527361870, 23.734532986587, 23.689538611303, 23.644544236019, - 23.599549860734, 23.554555485450, 23.509561110165, 23.464566734879, 23.419572359594, - 23.374577984308, 23.329583609022, 23.284589233736, 23.239594858449, 23.194600483162, - 23.149606107875, 23.104611732587, 23.059617357299, 23.014622982011, 22.969628606723, - 22.924634231434, 22.879639856146, 22.834645480856, 22.789651105567, 22.744656730277, - 22.699662354987, 22.654667979697, 22.609673604406, 22.564679229116, 22.519684853825, - 22.474690478533, 22.429696103242, 22.384701727950, 22.339707352658, 22.294712977365, - 22.249718602073, 22.204724226780, 22.159729851487, 22.114735476193, 22.069741100899, - 22.024746725605, 21.979752350311, 21.934757975017, 21.889763599722, 21.844769224427, - 21.799774849132, 21.754780473836, 21.709786098540, 21.664791723244, 21.619797347948, - 21.574802972652, 21.529808597355, 21.484814222058, 21.439819846761, 21.394825471463, - 21.349831096165, 21.304836720867, 21.259842345569, 21.214847970270, 21.169853594972, - 21.124859219673, 21.079864844373, 21.034870469074, 20.989876093774, 20.944881718474, - 20.899887343174, 20.854892967873, 20.809898592573, 20.764904217272, 20.719909841970, - 20.674915466669, 20.629921091367, 20.584926716065, 20.539932340763, 20.494937965461, - 20.449943590158, 20.404949214855, 20.359954839552, 20.314960464249, 20.269966088945, - 20.224971713642, 20.179977338338, 20.134982963033, 20.089988587729, 20.044994212424, - 19.999999837119, 19.955005461814, 19.910011086509, 19.865016711203, 19.820022335897, - 19.775027960591, 19.730033585285, 19.685039209978, 19.640044834672, 19.595050459365, - 19.550056084057, 19.505061708750, 19.460067333442, 19.415072958135, 19.370078582826, - 19.325084207518, 19.280089832210, 19.235095456901, 19.190101081592, 19.145106706283, - 19.100112330974, 19.055117955664, 19.010123580354, 18.965129205044, 18.920134829734, - 18.875140454424, 18.830146079113, 18.785151703802, 18.740157328491, 18.695162953180, - 18.650168577868, 18.605174202557, 18.560179827245, 18.515185451933, 18.470191076620, - 18.425196701308, 18.380202325995, 18.335207950682, 18.290213575369, 18.245219200056, - 18.200224824742, 18.155230449429, 18.110236074115, 18.065241698801, 18.020247323486, - 17.975252948172, 17.930258572857, 17.885264197542, 17.840269822227, 17.795275446912, - 17.750281071596, 17.705286696281, 17.660292320965, 17.615297945649, 17.570303570332, - 17.525309195016, 17.480314819699, 17.435320444382, 17.390326069065, 17.345331693748, - 17.300337318431, 17.255342943113, 17.210348567795, 17.165354192477, 17.120359817159, - 17.075365441841, 17.030371066522, 16.985376691203, 16.940382315885, 16.895387940565, - 16.850393565246, 16.805399189927, 16.760404814607, 16.715410439287, 16.670416063967, - 16.625421688647, 16.580427313327, 16.535432938006, 16.490438562685, 16.445444187365, - 16.400449812043, 16.355455436722, 16.310461061401, 16.265466686079, 16.220472310757, - 16.175477935435, 16.130483560113, 16.085489184791, 16.040494809469, 15.995500434146, - 15.950506058823, 15.905511683500, 15.860517308177, 15.815522932854, 15.770528557530, - 15.725534182206, 15.680539806883, 15.635545431559, 15.590551056234, 15.545556680910, - 15.500562305586, 15.455567930261, 15.410573554936, 15.365579179611, 15.320584804286, - 15.275590428961, 15.230596053635, 15.185601678310, 15.140607302984, 15.095612927658, - 15.050618552332, 15.005624177005, 14.960629801679, 14.915635426352, 14.870641051026, - 14.825646675699, 14.780652300372, 14.735657925045, 14.690663549717, 14.645669174390, - 14.600674799062, 14.555680423734, 14.510686048406, 14.465691673078, 14.420697297750, - 14.375702922421, 14.330708547093, 14.285714171764, 14.240719796435, 14.195725421106, - 14.150731045777, 14.105736670447, 14.060742295118, 14.015747919788, 13.970753544459, - 13.925759169129, 13.880764793799, 13.835770418468, 13.790776043138, 13.745781667807, - 13.700787292477, 13.655792917146, 13.610798541815, 13.565804166484, 13.520809791153, - 13.475815415821, 13.430821040490, 13.385826665158, 13.340832289826, 13.295837914495, - 13.250843539163, 13.205849163830, 13.160854788498, 13.115860413166, 13.070866037833, - 13.025871662500, 12.980877287167, 12.935882911834, 12.890888536501, 12.845894161168, - 12.800899785835, 12.755905410501, 12.710911035167, 12.665916659834, 12.620922284500, - 12.575927909166, 12.530933533831, 12.485939158497, 12.440944783163, 12.395950407828, - 12.350956032493, 12.305961657159, 12.260967281824, 12.215972906489, 12.170978531153, - 12.125984155818, 12.080989780483, 12.035995405147, 11.991001029811, 11.946006654476, - 11.901012279140, 11.856017903804, 11.811023528467, 11.766029153131, 11.721034777795, - 11.676040402458, 11.631046027121, 11.586051651785, 11.541057276448, 11.496062901111, - 11.451068525774, 11.406074150436, 11.361079775099, 11.316085399762, 11.271091024424, - 11.226096649086, 11.181102273748, 11.136107898411, 11.091113523072, 11.046119147734, - 11.001124772396, 10.956130397058, 10.911136021719, 10.866141646381, 10.821147271042, - 10.776152895703, 10.731158520364, 10.686164145025, 10.641169769686, 10.596175394347, - 10.551181019007, 10.506186643668, 10.461192268328, 10.416197892989, 10.371203517649, - 10.326209142309, 10.281214766969, 10.236220391629, 10.191226016289, 10.146231640948, - 10.101237265608, 10.056242890267, 10.011248514927, 9.966254139586, 9.921259764245, - 9.876265388904, 9.831271013563, 9.786276638222, 9.741282262881, 9.696287887540, - 9.651293512198, 9.606299136857, 9.561304761515, 9.516310386174, 9.471316010832, - 9.426321635490, 9.381327260148, 9.336332884806, 9.291338509464, 9.246344134122, - 9.201349758779, 9.156355383437, 9.111361008094, 9.066366632752, 9.021372257409, - 8.976377882066, 8.931383506723, 8.886389131380, 8.841394756037, 8.796400380694, - 8.751406005351, 8.706411630008, 8.661417254664, 8.616422879321, 8.571428503977, - 8.526434128633, 8.481439753290, 8.436445377946, 8.391451002602, 8.346456627258, - 8.301462251914, 8.256467876570, 8.211473501225, 8.166479125881, 8.121484750537, - 8.076490375192, 8.031495999848, 7.986501624503, 7.941507249158, 7.896512873813, - 7.851518498469, 7.806524123124, 7.761529747779, 7.716535372433, 7.671540997088, - 7.626546621743, 7.581552246398, 7.536557871052, 7.491563495707, 7.446569120361, - 7.401574745016, 7.356580369670, 7.311585994324, 7.266591618978, 7.221597243632, - 7.176602868286, 7.131608492940, 7.086614117594, 7.041619742248, 6.996625366902, - 6.951630991555, 6.906636616209, 6.861642240862, 6.816647865516, 6.771653490169, - 6.726659114822, 6.681664739476, 6.636670364129, 6.591675988782, 6.546681613435, - 6.501687238088, 6.456692862741, 6.411698487394, 6.366704112047, 6.321709736699, - 6.276715361352, 6.231720986005, 6.186726610657, 6.141732235310, 6.096737859962, - 6.051743484615, 6.006749109267, 5.961754733919, 5.916760358571, 5.871765983223, - 5.826771607875, 5.781777232528, 5.736782857179, 5.691788481831, 5.646794106483, - 5.601799731135, 5.556805355787, 5.511810980438, 5.466816605090, 5.421822229742, - 5.376827854393, 5.331833479045, 5.286839103696, 5.241844728348, 5.196850352999, - 5.151855977650, 5.106861602301, 5.061867226953, 5.016872851604, 4.971878476255, - 4.926884100906, 4.881889725557, 4.836895350208, 4.791900974859, 4.746906599509, - 4.701912224160, 4.656917848811, 4.611923473462, 4.566929098112, 4.521934722763, - 4.476940347414, 4.431945972064, 4.386951596715, 4.341957221365, 4.296962846015, - 4.251968470666, 4.206974095316, 4.161979719966, 4.116985344617, 4.071990969267, - 4.026996593917, 3.982002218567, 3.937007843217, 3.892013467867, 3.847019092517, - 3.802024717167, 3.757030341817, 3.712035966467, 3.667041591117, 3.622047215767, - 3.577052840416, 3.532058465066, 3.487064089716, 3.442069714366, 3.397075339015, - 3.352080963665, 3.307086588314, 3.262092212964, 3.217097837613, 3.172103462263, - 3.127109086912, 3.082114711562, 3.037120336211, 2.992125960861, 2.947131585510, - 2.902137210159, 2.857142834808, 2.812148459458, 2.767154084107, 2.722159708756, - 2.677165333405, 2.632170958055, 2.587176582704, 2.542182207353, 2.497187832002, - 2.452193456651, 2.407199081300, 2.362204705949, 2.317210330598, 2.272215955247, - 2.227221579896, 2.182227204545, 2.137232829194, 2.092238453842, 2.047244078491, - 2.002249703140, 1.957255327789, 1.912260952438, 1.867266577087, 1.822272201735, - 1.777277826384, 1.732283451033, 1.687289075681, 1.642294700330, 1.597300324979, - 1.552305949627, 1.507311574276, 1.462317198925, 1.417322823573, 1.372328448222, - 1.327334072871, 1.282339697519, 1.237345322168, 1.192350946816, 1.147356571465, - 1.102362196113, 1.057367820762, 1.012373445410, 0.967379070059, 0.922384694707, - 0.877390319356, 0.832395944004, 0.787401568653, 0.742407193301, 0.697412817950, - 0.652418442598, 0.607424067247, 0.562429691895, 0.517435316543, 0.472440941192, - 0.427446565840, 0.382452190489, 0.337457815137, 0.292463439785, 0.247469064434, - 0.202474689082, 0.157480313731, 0.112485938379, 0.067491563027, 0.022497187676 - )) +DEFINE_GAUSSIAN_LATITUDES( + 2000, + LIST( + 89.965557716640, 89.920940588056, 89.876059971209, 89.831119821127, 89.786157088682, 89.741183428577, + 89.696203661469, 89.651220138535, 89.606234142158, 89.561246430917, 89.516257482116, 89.471267611042, + 89.426277034302, 89.381285905620, 89.336294337107, 89.291302412440, 89.246310195345, 89.201317735199, + 89.156325070860, 89.111332233323, 89.066339247611, 89.021346134150, 88.976352909776, 88.931359588494, + 88.886366182044, 88.841372700344, 88.796379151831, 88.751385543725, 88.706391882242, 88.661398172763, + 88.616404419970, 88.571410627953, 88.526416800305, 88.481422940193, 88.436429050418, 88.391435133469, + 88.346441191564, 88.301447226685, 88.256453240612, 88.211459234943, 88.166465211121, 88.121471170450, + 88.076477114112, 88.031483043182, 87.986488958637, 87.941494861370, 87.896500752197, 87.851506631867, + 87.806512501066, 87.761518360424, 87.716524210525, 87.671530051904, 87.626535885058, 87.581541710445, + 87.536547528491, 87.491553339591, 87.446559144112, 87.401564942396, 87.356570734762, 87.311576521506, + 87.266582302906, 87.221588079222, 87.176593850696, 87.131599617557, 87.086605380019, 87.041611138281, + 86.996616892534, 86.951622642953, 86.906628389707, 86.861634132954, 86.816639872841, 86.771645609509, + 86.726651343092, 86.681657073714, 86.636662801495, 86.591668526547, 86.546674248976, 86.501679968884, + 86.456685686367, 86.411691401516, 86.366697114417, 86.321702825154, 86.276708533805, 86.231714240444, + 86.186719945143, 86.141725647969, 86.096731348988, 86.051737048260, 86.006742745846, 85.961748441801, + 85.916754136180, 85.871759829034, 85.826765520411, 85.781771210361, 85.736776898926, 85.691782586152, + 85.646788272080, 85.601793956749, 85.556799640198, 85.511805322463, 85.466811003580, 85.421816683582, + 85.376822362502, 85.331828040372, 85.286833717221, 85.241839393078, 85.196845067971, 85.151850741928, + 85.106856414973, 85.061862087133, 85.016867758430, 84.971873428888, 84.926879098529, 84.881884767375, + 84.836890435447, 84.791896102764, 84.746901769347, 84.701907435213, 84.656913100381, 84.611918764868, + 84.566924428692, 84.521930091868, 84.476935754413, 84.431941416342, 84.386947077669, 84.341952738409, + 84.296958398576, 84.251964058183, 84.206969717244, 84.161975375770, 84.116981033775, 84.071986691270, + 84.026992348266, 83.981998004775, 83.937003660808, 83.892009316375, 83.847014971487, 83.802020626152, + 83.757026280382, 83.712031934185, 83.667037587570, 83.622043240547, 83.577048893124, 83.532054545308, + 83.487060197109, 83.442065848534, 83.397071499592, 83.352077150288, 83.307082800631, 83.262088450628, + 83.217094100285, 83.172099749610, 83.127105398609, 83.082111047287, 83.037116695653, 82.992122343710, + 82.947127991466, 82.902133638926, 82.857139286096, 82.812144932981, 82.767150579586, 82.722156225917, + 82.677161871979, 82.632167517776, 82.587173163314, 82.542178808596, 82.497184453629, 82.452190098415, + 82.407195742961, 82.362201387269, 82.317207031344, 82.272212675190, 82.227218318811, 82.182223962211, + 82.137229605394, 82.092235248363, 82.047240891122, 82.002246533675, 81.957252176025, 81.912257818176, + 81.867263460130, 81.822269101891, 81.777274743462, 81.732280384847, 81.687286026048, 81.642291667068, + 81.597297307910, 81.552302948577, 81.507308589073, 81.462314229398, 81.417319869557, 81.372325509552, + 81.327331149384, 81.282336789058, 81.237342428575, 81.192348067938, 81.147353707149, 81.102359346210, + 81.057364985124, 81.012370623893, 80.967376262518, 80.922381901003, 80.877387539349, 80.832393177558, + 80.787398815633, 80.742404453575, 80.697410091386, 80.652415729068, 80.607421366622, 80.562427004052, + 80.517432641358, 80.472438278542, 80.427443915607, 80.382449552553, 80.337455189382, 80.292460826096, + 80.247466462697, 80.202472099185, 80.157477735564, 80.112483371833, 80.067489007995, 80.022494644051, + 79.977500280003, 79.932505915852, 79.887511551598, 79.842517187245, 79.797522822792, 79.752528458242, + 79.707534093595, 79.662539728853, 79.617545364016, 79.572550999088, 79.527556634067, 79.482562268956, + 79.437567903756, 79.392573538468, 79.347579173093, 79.302584807632, 79.257590442086, 79.212596076457, + 79.167601710745, 79.122607344951, 79.077612979076, 79.032618613122, 78.987624247089, 78.942629880979, + 78.897635514791, 78.852641148528, 78.807646782190, 78.762652415777, 78.717658049292, 78.672663682734, + 78.627669316105, 78.582674949405, 78.537680582636, 78.492686215798, 78.447691848891, 78.402697481917, + 78.357703114877, 78.312708747771, 78.267714380599, 78.222720013364, 78.177725646065, 78.132731278703, + 78.087736911279, 78.042742543794, 77.997748176248, 77.952753808642, 77.907759440976, 77.862765073252, + 77.817770705470, 77.772776337630, 77.727781969733, 77.682787601781, 77.637793233773, 77.592798865709, + 77.547804497592, 77.502810129421, 77.457815761196, 77.412821392919, 77.367827024590, 77.322832656210, + 77.277838287778, 77.232843919296, 77.187849550764, 77.142855182183, 77.097860813553, 77.052866444875, + 77.007872076149, 76.962877707375, 76.917883338555, 76.872888969688, 76.827894600776, 76.782900231818, + 76.737905862815, 76.692911493767, 76.647917124676, 76.602922755540, 76.557928386362, 76.512934017141, + 76.467939647878, 76.422945278573, 76.377950909226, 76.332956539838, 76.287962170410, 76.242967800941, + 76.197973431433, 76.152979061885, 76.107984692297, 76.062990322672, 76.017995953007, 75.973001583305, + 75.928007213566, 75.883012843789, 75.838018473975, 75.793024104124, 75.748029734238, 75.703035364315, + 75.658040994357, 75.613046624364, 75.568052254336, 75.523057884273, 75.478063514177, 75.433069144046, + 75.388074773882, 75.343080403684, 75.298086033454, 75.253091663191, 75.208097292895, 75.163102922567, + 75.118108552208, 75.073114181817, 75.028119811395, 74.983125440942, 74.938131070459, 74.893136699945, + 74.848142329401, 74.803147958827, 74.758153588223, 74.713159217590, 74.668164846929, 74.623170476238, + 74.578176105519, 74.533181734771, 74.488187363996, 74.443192993192, 74.398198622361, 74.353204251503, + 74.308209880618, 74.263215509706, 74.218221138767, 74.173226767802, 74.128232396810, 74.083238025793, + 74.038243654750, 73.993249283681, 73.948254912587, 73.903260541468, 73.858266170324, 73.813271799156, + 73.768277427963, 73.723283056746, 73.678288685504, 73.633294314239, 73.588299942950, 73.543305571638, + 73.498311200302, 73.453316828943, 73.408322457562, 73.363328086157, 73.318333714730, 73.273339343281, + 73.228344971810, 73.183350600316, 73.138356228801, 73.093361857264, 73.048367485706, 73.003373114126, + 72.958378742525, 72.913384370904, 72.868389999261, 72.823395627598, 72.778401255914, 72.733406884210, + 72.688412512486, 72.643418140742, 72.598423768978, 72.553429397194, 72.508435025391, 72.463440653568, + 72.418446281727, 72.373451909866, 72.328457537986, 72.283463166087, 72.238468794170, 72.193474422234, + 72.148480050280, 72.103485678307, 72.058491306317, 72.013496934308, 71.968502562282, 71.923508190238, + 71.878513818176, 71.833519446097, 71.788525074001, 71.743530701887, 71.698536329757, 71.653541957609, + 71.608547585445, 71.563553213264, 71.518558841066, 71.473564468852, 71.428570096622, 71.383575724376, + 71.338581352113, 71.293586979834, 71.248592607540, 71.203598235230, 71.158603862904, 71.113609490563, + 71.068615118206, 71.023620745834, 70.978626373447, 70.933632001045, 70.888637628628, 70.843643256196, + 70.798648883749, 70.753654511288, 70.708660138812, 70.663665766321, 70.618671393817, 70.573677021298, + 70.528682648765, 70.483688276217, 70.438693903656, 70.393699531081, 70.348705158492, 70.303710785890, + 70.258716413274, 70.213722040644, 70.168727668002, 70.123733295345, 70.078738922676, 70.033744549993, + 69.988750177298, 69.943755804589, 69.898761431868, 69.853767059134, 69.808772686387, 69.763778313628, + 69.718783940856, 69.673789568072, 69.628795195275, 69.583800822466, 69.538806449645, 69.493812076812, + 69.448817703966, 69.403823331109, 69.358828958240, 69.313834585359, 69.268840212466, 69.223845839562, + 69.178851466646, 69.133857093719, 69.088862720780, 69.043868347830, 68.998873974869, 68.953879601897, + 68.908885228913, 68.863890855918, 68.818896482913, 68.773902109896, 68.728907736869, 68.683913363831, + 68.638918990782, 68.593924617722, 68.548930244652, 68.503935871572, 68.458941498480, 68.413947125379, + 68.368952752267, 68.323958379145, 68.278964006013, 68.233969632871, 68.188975259719, 68.143980886557, + 68.098986513384, 68.053992140202, 68.008997767010, 67.964003393809, 67.919009020597, 67.874014647376, + 67.829020274146, 67.784025900906, 67.739031527656, 67.694037154397, 67.649042781129, 67.604048407852, + 67.559054034565, 67.514059661269, 67.469065287964, 67.424070914650, 67.379076541327, 67.334082167995, + 67.289087794654, 67.244093421304, 67.199099047946, 67.154104674578, 67.109110301202, 67.064115927817, + 67.019121554424, 66.974127181022, 66.929132807612, 66.884138434193, 66.839144060766, 66.794149687331, + 66.749155313887, 66.704160940435, 66.659166566975, 66.614172193507, 66.569177820030, 66.524183446546, + 66.479189073053, 66.434194699553, 66.389200326044, 66.344205952528, 66.299211579004, 66.254217205472, + 66.209222831933, 66.164228458385, 66.119234084830, 66.074239711268, 66.029245337698, 65.984250964120, + 65.939256590535, 65.894262216943, 65.849267843343, 65.804273469735, 65.759279096121, 65.714284722499, + 65.669290348870, 65.624295975233, 65.579301601590, 65.534307227939, 65.489312854282, 65.444318480617, + 65.399324106945, 65.354329733267, 65.309335359581, 65.264340985889, 65.219346612190, 65.174352238484, + 65.129357864771, 65.084363491051, 65.039369117325, 64.994374743592, 64.949380369852, 64.904385996106, + 64.859391622354, 64.814397248594, 64.769402874829, 64.724408501057, 64.679414127278, 64.634419753493, + 64.589425379702, 64.544431005904, 64.499436632100, 64.454442258290, 64.409447884474, 64.364453510652, + 64.319459136823, 64.274464762988, 64.229470389147, 64.184476015301, 64.139481641448, 64.094487267589, + 64.049492893724, 64.004498519853, 63.959504145977, 63.914509772094, 63.869515398206, 63.824521024312, + 63.779526650412, 63.734532276506, 63.689537902595, 63.644543528678, 63.599549154755, 63.554554780827, + 63.509560406893, 63.464566032953, 63.419571659008, 63.374577285058, 63.329582911102, 63.284588537140, + 63.239594163174, 63.194599789201, 63.149605415224, 63.104611041241, 63.059616667252, 63.014622293259, + 62.969627919260, 62.924633545256, 62.879639171246, 62.834644797232, 62.789650423212, 62.744656049187, + 62.699661675157, 62.654667301123, 62.609672927082, 62.564678553037, 62.519684178987, 62.474689804932, + 62.429695430872, 62.384701056807, 62.339706682737, 62.294712308663, 62.249717934583, 62.204723560498, + 62.159729186409, 62.114734812315, 62.069740438216, 62.024746064113, 61.979751690004, 61.934757315891, + 61.889762941774, 61.844768567651, 61.799774193524, 61.754779819393, 61.709785445257, 61.664791071116, + 61.619796696970, 61.574802322821, 61.529807948666, 61.484813574508, 61.439819200344, 61.394824826177, + 61.349830452005, 61.304836077828, 61.259841703647, 61.214847329462, 61.169852955272, 61.124858581079, + 61.079864206880, 61.034869832678, 60.989875458471, 60.944881084260, 60.899886710045, 60.854892335826, + 60.809897961603, 60.764903587375, 60.719909213143, 60.674914838907, 60.629920464667, 60.584926090423, + 60.539931716175, 60.494937341923, 60.449942967667, 60.404948593406, 60.359954219142, 60.314959844874, + 60.269965470602, 60.224971096326, 60.179976722046, 60.134982347762, 60.089987973475, 60.044993599183, + 59.999999224888, 59.955004850588, 59.910010476285, 59.865016101979, 59.820021727668, 59.775027353354, + 59.730032979036, 59.685038604714, 59.640044230388, 59.595049856059, 59.550055481726, 59.505061107390, + 59.460066733049, 59.415072358706, 59.370077984358, 59.325083610007, 59.280089235653, 59.235094861295, + 59.190100486933, 59.145106112568, 59.100111738199, 59.055117363827, 59.010122989451, 58.965128615072, + 58.920134240689, 58.875139866303, 58.830145491914, 58.785151117521, 58.740156743125, 58.695162368725, + 58.650167994322, 58.605173619916, 58.560179245506, 58.515184871093, 58.470190496677, 58.425196122257, + 58.380201747834, 58.335207373408, 58.290212998979, 58.245218624546, 58.200224250110, 58.155229875671, + 58.110235501229, 58.065241126784, 58.020246752335, 57.975252377883, 57.930258003428, 57.885263628970, + 57.840269254509, 57.795274880045, 57.750280505578, 57.705286131108, 57.660291756634, 57.615297382158, + 57.570303007678, 57.525308633196, 57.480314258710, 57.435319884222, 57.390325509730, 57.345331135236, + 57.300336760738, 57.255342386238, 57.210348011735, 57.165353637228, 57.120359262719, 57.075364888207, + 57.030370513692, 56.985376139174, 56.940381764654, 56.895387390130, 56.850393015604, 56.805398641075, + 56.760404266543, 56.715409892008, 56.670415517470, 56.625421142930, 56.580426768387, 56.535432393841, + 56.490438019292, 56.445443644741, 56.400449270187, 56.355454895630, 56.310460521071, 56.265466146508, + 56.220471771943, 56.175477397376, 56.130483022806, 56.085488648233, 56.040494273657, 55.995499899079, + 55.950505524499, 55.905511149915, 55.860516775329, 55.815522400741, 55.770528026150, 55.725533651556, + 55.680539276960, 55.635544902361, 55.590550527760, 55.545556153156, 55.500561778550, 55.455567403941, + 55.410573029329, 55.365578654716, 55.320584280099, 55.275589905481, 55.230595530859, 55.185601156236, + 55.140606781610, 55.095612406981, 55.050618032350, 55.005623657717, 54.960629283081, 54.915634908443, + 54.870640533803, 54.825646159160, 54.780651784515, 54.735657409867, 54.690663035217, 54.645668660565, + 54.600674285910, 54.555679911253, 54.510685536594, 54.465691161933, 54.420696787269, 54.375702412603, + 54.330708037935, 54.285713663264, 54.240719288591, 54.195724913916, 54.150730539239, 54.105736164559, + 54.060741789877, 54.015747415193, 53.970753040507, 53.925758665819, 53.880764291128, 53.835769916436, + 53.790775541741, 53.745781167044, 53.700786792344, 53.655792417643, 53.610798042940, 53.565803668234, + 53.520809293526, 53.475814918816, 53.430820544104, 53.385826169390, 53.340831794674, 53.295837419956, + 53.250843045236, 53.205848670513, 53.160854295789, 53.115859921062, 53.070865546334, 53.025871171603, + 52.980876796871, 52.935882422136, 52.890888047400, 52.845893672661, 52.800899297920, 52.755904923178, + 52.710910548433, 52.665916173687, 52.620921798938, 52.575927424188, 52.530933049435, 52.485938674681, + 52.440944299925, 52.395949925166, 52.350955550406, 52.305961175644, 52.260966800880, 52.215972426114, + 52.170978051346, 52.125983676577, 52.080989301805, 52.035994927032, 51.991000552256, 51.946006177479, + 51.901011802700, 51.856017427919, 51.811023053137, 51.766028678352, 51.721034303566, 51.676039928777, + 51.631045553987, 51.586051179196, 51.541056804402, 51.496062429606, 51.451068054809, 51.406073680010, + 51.361079305209, 51.316084930407, 51.271090555603, 51.226096180796, 51.181101805989, 51.136107431179, + 51.091113056368, 51.046118681555, 51.001124306740, 50.956129931923, 50.911135557105, 50.866141182285, + 50.821146807464, 50.776152432640, 50.731158057815, 50.686163682989, 50.641169308160, 50.596174933330, + 50.551180558498, 50.506186183665, 50.461191808830, 50.416197433993, 50.371203059155, 50.326208684315, + 50.281214309473, 50.236219934630, 50.191225559785, 50.146231184939, 50.101236810091, 50.056242435241, + 50.011248060390, 49.966253685537, 49.921259310682, 49.876264935826, 49.831270560969, 49.786276186110, + 49.741281811249, 49.696287436387, 49.651293061523, 49.606298686657, 49.561304311790, 49.516309936922, + 49.471315562052, 49.426321187180, 49.381326812307, 49.336332437432, 49.291338062556, 49.246343687679, + 49.201349312800, 49.156354937919, 49.111360563037, 49.066366188153, 49.021371813268, 48.976377438381, + 48.931383063493, 48.886388688604, 48.841394313713, 48.796399938820, 48.751405563927, 48.706411189031, + 48.661416814134, 48.616422439236, 48.571428064337, 48.526433689435, 48.481439314533, 48.436444939629, + 48.391450564724, 48.346456189817, 48.301461814909, 48.256467439999, 48.211473065088, 48.166478690176, + 48.121484315262, 48.076489940347, 48.031495565431, 47.986501190513, 47.941506815594, 47.896512440673, + 47.851518065751, 47.806523690828, 47.761529315903, 47.716534940977, 47.671540566050, 47.626546191121, + 47.581551816191, 47.536557441260, 47.491563066327, 47.446568691393, 47.401574316458, 47.356579941521, + 47.311585566583, 47.266591191644, 47.221596816704, 47.176602441762, 47.131608066819, 47.086613691874, + 47.041619316929, 46.996624941982, 46.951630567034, 46.906636192084, 46.861641817133, 46.816647442181, + 46.771653067228, 46.726658692274, 46.681664317318, 46.636669942361, 46.591675567403, 46.546681192443, + 46.501686817482, 46.456692442521, 46.411698067557, 46.366703692593, 46.321709317627, 46.276714942661, + 46.231720567693, 46.186726192723, 46.141731817753, 46.096737442781, 46.051743067809, 46.006748692835, + 45.961754317859, 45.916759942883, 45.871765567906, 45.826771192927, 45.781776817947, 45.736782442966, + 45.691788067984, 45.646793693000, 45.601799318016, 45.556804943030, 45.511810568043, 45.466816193055, + 45.421821818066, 45.376827443076, 45.331833068085, 45.286838693092, 45.241844318099, 45.196849943104, + 45.151855568108, 45.106861193111, 45.061866818113, 45.016872443114, 44.971878068113, 44.926883693112, + 44.881889318109, 44.836894943106, 44.791900568101, 44.746906193095, 44.701911818088, 44.656917443080, + 44.611923068071, 44.566928693061, 44.521934318050, 44.476939943038, 44.431945568025, 44.386951193010, + 44.341956817995, 44.296962442978, 44.251968067961, 44.206973692942, 44.161979317923, 44.116984942902, + 44.071990567880, 44.026996192857, 43.982001817834, 43.937007442809, 43.892013067783, 43.847018692756, + 43.802024317728, 43.757029942699, 43.712035567670, 43.667041192639, 43.622046817607, 43.577052442574, + 43.532058067540, 43.487063692505, 43.442069317469, 43.397074942432, 43.352080567394, 43.307086192355, + 43.262091817315, 43.217097442275, 43.172103067233, 43.127108692190, 43.082114317146, 43.037119942102, + 42.992125567056, 42.947131192009, 42.902136816962, 42.857142441913, 42.812148066863, 42.767153691813, + 42.722159316762, 42.677164941709, 42.632170566656, 42.587176191602, 42.542181816546, 42.497187441490, + 42.452193066433, 42.407198691375, 42.362204316316, 42.317209941257, 42.272215566196, 42.227221191134, + 42.182226816072, 42.137232441008, 42.092238065944, 42.047243690878, 42.002249315812, 41.957254940745, + 41.912260565677, 41.867266190608, 41.822271815539, 41.777277440468, 41.732283065396, 41.687288690324, + 41.642294315251, 41.597299940176, 41.552305565101, 41.507311190025, 41.462316814949, 41.417322439871, + 41.372328064792, 41.327333689713, 41.282339314633, 41.237344939551, 41.192350564469, 41.147356189387, + 41.102361814303, 41.057367439218, 41.012373064133, 40.967378689047, 40.922384313960, 40.877389938872, + 40.832395563783, 40.787401188693, 40.742406813603, 40.697412438512, 40.652418063420, 40.607423688327, + 40.562429313233, 40.517434938139, 40.472440563043, 40.427446187947, 40.382451812850, 40.337457437752, + 40.292463062654, 40.247468687554, 40.202474312454, 40.157479937353, 40.112485562251, 40.067491187149, + 40.022496812045, 39.977502436941, 39.932508061836, 39.887513686731, 39.842519311624, 39.797524936517, + 39.752530561409, 39.707536186300, 39.662541811190, 39.617547436080, 39.572553060968, 39.527558685857, + 39.482564310744, 39.437569935630, 39.392575560516, 39.347581185401, 39.302586810285, 39.257592435169, + 39.212598060052, 39.167603684934, 39.122609309815, 39.077614934695, 39.032620559575, 38.987626184454, + 38.942631809332, 38.897637434210, 38.852643059087, 38.807648683963, 38.762654308838, 38.717659933713, + 38.672665558587, 38.627671183460, 38.582676808332, 38.537682433204, 38.492688058075, 38.447693682945, + 38.402699307815, 38.357704932684, 38.312710557552, 38.267716182419, 38.222721807286, 38.177727432152, + 38.132733057017, 38.087738681882, 38.042744306746, 37.997749931609, 37.952755556471, 37.907761181333, + 37.862766806194, 37.817772431055, 37.772778055915, 37.727783680774, 37.682789305632, 37.637794930490, + 37.592800555347, 37.547806180203, 37.502811805059, 37.457817429914, 37.412823054768, 37.367828679622, + 37.322834304475, 37.277839929327, 37.232845554179, 37.187851179030, 37.142856803880, 37.097862428730, + 37.052868053579, 37.007873678428, 36.962879303275, 36.917884928122, 36.872890552969, 36.827896177815, + 36.782901802660, 36.737907427504, 36.692913052348, 36.647918677191, 36.602924302034, 36.557929926876, + 36.512935551717, 36.467941176558, 36.422946801398, 36.377952426237, 36.332958051076, 36.287963675914, + 36.242969300752, 36.197974925589, 36.152980550425, 36.107986175261, 36.062991800096, 36.017997424930, + 35.973003049764, 35.928008674597, 35.883014299430, 35.838019924262, 35.793025549093, 35.748031173924, + 35.703036798754, 35.658042423584, 35.613048048413, 35.568053673241, 35.523059298069, 35.478064922896, + 35.433070547723, 35.388076172549, 35.343081797374, 35.298087422199, 35.253093047024, 35.208098671847, + 35.163104296670, 35.118109921493, 35.073115546315, 35.028121171136, 34.983126795957, 34.938132420777, + 34.893138045597, 34.848143670416, 34.803149295234, 34.758154920052, 34.713160544869, 34.668166169686, + 34.623171794502, 34.578177419318, 34.533183044133, 34.488188668948, 34.443194293762, 34.398199918575, + 34.353205543388, 34.308211168200, 34.263216793012, 34.218222417823, 34.173228042634, 34.128233667444, + 34.083239292254, 34.038244917063, 33.993250541871, 33.948256166679, 33.903261791486, 33.858267416293, + 33.813273041099, 33.768278665905, 33.723284290711, 33.678289915515, 33.633295540319, 33.588301165123, + 33.543306789926, 33.498312414729, 33.453318039531, 33.408323664332, 33.363329289133, 33.318334913934, + 33.273340538734, 33.228346163533, 33.183351788332, 33.138357413131, 33.093363037929, 33.048368662726, + 33.003374287523, 32.958379912319, 32.913385537115, 32.868391161911, 32.823396786705, 32.778402411500, + 32.733408036294, 32.688413661087, 32.643419285880, 32.598424910672, 32.553430535464, 32.508436160255, + 32.463441785046, 32.418447409837, 32.373453034627, 32.328458659416, 32.283464284205, 32.238469908993, + 32.193475533781, 32.148481158569, 32.103486783356, 32.058492408142, 32.013498032928, 31.968503657714, + 31.923509282499, 31.878514907283, 31.833520532067, 31.788526156851, 31.743531781634, 31.698537406417, + 31.653543031199, 31.608548655981, 31.563554280762, 31.518559905543, 31.473565530323, 31.428571155103, + 31.383576779882, 31.338582404661, 31.293588029440, 31.248593654218, 31.203599278995, 31.158604903772, + 31.113610528549, 31.068616153325, 31.023621778101, 30.978627402876, 30.933633027651, 30.888638652425, + 30.843644277199, 30.798649901973, 30.753655526746, 30.708661151519, 30.663666776291, 30.618672401062, + 30.573678025834, 30.528683650604, 30.483689275375, 30.438694900145, 30.393700524914, 30.348706149683, + 30.303711774452, 30.258717399220, 30.213723023988, 30.168728648755, 30.123734273522, 30.078739898289, + 30.033745523055, 29.988751147821, 29.943756772586, 29.898762397351, 29.853768022115, 29.808773646879, + 29.763779271642, 29.718784896406, 29.673790521168, 29.628796145931, 29.583801770692, 29.538807395454, + 29.493813020215, 29.448818644975, 29.403824269736, 29.358829894496, 29.313835519255, 29.268841144014, + 29.223846768772, 29.178852393531, 29.133858018288, 29.088863643046, 29.043869267803, 28.998874892559, + 28.953880517315, 28.908886142071, 28.863891766827, 28.818897391582, 28.773903016336, 28.728908641090, + 28.683914265844, 28.638919890598, 28.593925515351, 28.548931140103, 28.503936764855, 28.458942389607, + 28.413948014359, 28.368953639110, 28.323959263860, 28.278964888611, 28.233970513361, 28.188976138110, + 28.143981762859, 28.098987387608, 28.053993012356, 28.008998637104, 27.964004261852, 27.919009886599, + 27.874015511346, 27.829021136093, 27.784026760839, 27.739032385585, 27.694038010330, 27.649043635075, + 27.604049259820, 27.559054884564, 27.514060509308, 27.469066134051, 27.424071758795, 27.379077383538, + 27.334083008280, 27.289088633022, 27.244094257764, 27.199099882505, 27.154105507246, 27.109111131987, + 27.064116756727, 27.019122381467, 26.974128006207, 26.929133630946, 26.884139255685, 26.839144880423, + 26.794150505162, 26.749156129900, 26.704161754637, 26.659167379374, 26.614173004111, 26.569178628847, + 26.524184253584, 26.479189878319, 26.434195503055, 26.389201127790, 26.344206752525, 26.299212377259, + 26.254218001993, 26.209223626727, 26.164229251460, 26.119234876193, 26.074240500926, 26.029246125658, + 25.984251750390, 25.939257375122, 25.894262999853, 25.849268624584, 25.804274249315, 25.759279874046, + 25.714285498776, 25.669291123505, 25.624296748235, 25.579302372964, 25.534307997693, 25.489313622421, + 25.444319247149, 25.399324871877, 25.354330496604, 25.309336121332, 25.264341746058, 25.219347370785, + 25.174352995511, 25.129358620237, 25.084364244962, 25.039369869688, 24.994375494413, 24.949381119137, + 24.904386743862, 24.859392368586, 24.814397993309, 24.769403618033, 24.724409242756, 24.679414867478, + 24.634420492201, 24.589426116923, 24.544431741645, 24.499437366366, 24.454442991088, 24.409448615808, + 24.364454240529, 24.319459865249, 24.274465489969, 24.229471114689, 24.184476739409, 24.139482364128, + 24.094487988847, 24.049493613565, 24.004499238283, 23.959504863001, 23.914510487719, 23.869516112436, + 23.824521737153, 23.779527361870, 23.734532986587, 23.689538611303, 23.644544236019, 23.599549860734, + 23.554555485450, 23.509561110165, 23.464566734879, 23.419572359594, 23.374577984308, 23.329583609022, + 23.284589233736, 23.239594858449, 23.194600483162, 23.149606107875, 23.104611732587, 23.059617357299, + 23.014622982011, 22.969628606723, 22.924634231434, 22.879639856146, 22.834645480856, 22.789651105567, + 22.744656730277, 22.699662354987, 22.654667979697, 22.609673604406, 22.564679229116, 22.519684853825, + 22.474690478533, 22.429696103242, 22.384701727950, 22.339707352658, 22.294712977365, 22.249718602073, + 22.204724226780, 22.159729851487, 22.114735476193, 22.069741100899, 22.024746725605, 21.979752350311, + 21.934757975017, 21.889763599722, 21.844769224427, 21.799774849132, 21.754780473836, 21.709786098540, + 21.664791723244, 21.619797347948, 21.574802972652, 21.529808597355, 21.484814222058, 21.439819846761, + 21.394825471463, 21.349831096165, 21.304836720867, 21.259842345569, 21.214847970270, 21.169853594972, + 21.124859219673, 21.079864844373, 21.034870469074, 20.989876093774, 20.944881718474, 20.899887343174, + 20.854892967873, 20.809898592573, 20.764904217272, 20.719909841970, 20.674915466669, 20.629921091367, + 20.584926716065, 20.539932340763, 20.494937965461, 20.449943590158, 20.404949214855, 20.359954839552, + 20.314960464249, 20.269966088945, 20.224971713642, 20.179977338338, 20.134982963033, 20.089988587729, + 20.044994212424, 19.999999837119, 19.955005461814, 19.910011086509, 19.865016711203, 19.820022335897, + 19.775027960591, 19.730033585285, 19.685039209978, 19.640044834672, 19.595050459365, 19.550056084057, + 19.505061708750, 19.460067333442, 19.415072958135, 19.370078582826, 19.325084207518, 19.280089832210, + 19.235095456901, 19.190101081592, 19.145106706283, 19.100112330974, 19.055117955664, 19.010123580354, + 18.965129205044, 18.920134829734, 18.875140454424, 18.830146079113, 18.785151703802, 18.740157328491, + 18.695162953180, 18.650168577868, 18.605174202557, 18.560179827245, 18.515185451933, 18.470191076620, + 18.425196701308, 18.380202325995, 18.335207950682, 18.290213575369, 18.245219200056, 18.200224824742, + 18.155230449429, 18.110236074115, 18.065241698801, 18.020247323486, 17.975252948172, 17.930258572857, + 17.885264197542, 17.840269822227, 17.795275446912, 17.750281071596, 17.705286696281, 17.660292320965, + 17.615297945649, 17.570303570332, 17.525309195016, 17.480314819699, 17.435320444382, 17.390326069065, + 17.345331693748, 17.300337318431, 17.255342943113, 17.210348567795, 17.165354192477, 17.120359817159, + 17.075365441841, 17.030371066522, 16.985376691203, 16.940382315885, 16.895387940565, 16.850393565246, + 16.805399189927, 16.760404814607, 16.715410439287, 16.670416063967, 16.625421688647, 16.580427313327, + 16.535432938006, 16.490438562685, 16.445444187365, 16.400449812043, 16.355455436722, 16.310461061401, + 16.265466686079, 16.220472310757, 16.175477935435, 16.130483560113, 16.085489184791, 16.040494809469, + 15.995500434146, 15.950506058823, 15.905511683500, 15.860517308177, 15.815522932854, 15.770528557530, + 15.725534182206, 15.680539806883, 15.635545431559, 15.590551056234, 15.545556680910, 15.500562305586, + 15.455567930261, 15.410573554936, 15.365579179611, 15.320584804286, 15.275590428961, 15.230596053635, + 15.185601678310, 15.140607302984, 15.095612927658, 15.050618552332, 15.005624177005, 14.960629801679, + 14.915635426352, 14.870641051026, 14.825646675699, 14.780652300372, 14.735657925045, 14.690663549717, + 14.645669174390, 14.600674799062, 14.555680423734, 14.510686048406, 14.465691673078, 14.420697297750, + 14.375702922421, 14.330708547093, 14.285714171764, 14.240719796435, 14.195725421106, 14.150731045777, + 14.105736670447, 14.060742295118, 14.015747919788, 13.970753544459, 13.925759169129, 13.880764793799, + 13.835770418468, 13.790776043138, 13.745781667807, 13.700787292477, 13.655792917146, 13.610798541815, + 13.565804166484, 13.520809791153, 13.475815415821, 13.430821040490, 13.385826665158, 13.340832289826, + 13.295837914495, 13.250843539163, 13.205849163830, 13.160854788498, 13.115860413166, 13.070866037833, + 13.025871662500, 12.980877287167, 12.935882911834, 12.890888536501, 12.845894161168, 12.800899785835, + 12.755905410501, 12.710911035167, 12.665916659834, 12.620922284500, 12.575927909166, 12.530933533831, + 12.485939158497, 12.440944783163, 12.395950407828, 12.350956032493, 12.305961657159, 12.260967281824, + 12.215972906489, 12.170978531153, 12.125984155818, 12.080989780483, 12.035995405147, 11.991001029811, + 11.946006654476, 11.901012279140, 11.856017903804, 11.811023528467, 11.766029153131, 11.721034777795, + 11.676040402458, 11.631046027121, 11.586051651785, 11.541057276448, 11.496062901111, 11.451068525774, + 11.406074150436, 11.361079775099, 11.316085399762, 11.271091024424, 11.226096649086, 11.181102273748, + 11.136107898411, 11.091113523072, 11.046119147734, 11.001124772396, 10.956130397058, 10.911136021719, + 10.866141646381, 10.821147271042, 10.776152895703, 10.731158520364, 10.686164145025, 10.641169769686, + 10.596175394347, 10.551181019007, 10.506186643668, 10.461192268328, 10.416197892989, 10.371203517649, + 10.326209142309, 10.281214766969, 10.236220391629, 10.191226016289, 10.146231640948, 10.101237265608, + 10.056242890267, 10.011248514927, 9.966254139586, 9.921259764245, 9.876265388904, 9.831271013563, + 9.786276638222, 9.741282262881, 9.696287887540, 9.651293512198, 9.606299136857, 9.561304761515, 9.516310386174, + 9.471316010832, 9.426321635490, 9.381327260148, 9.336332884806, 9.291338509464, 9.246344134122, 9.201349758779, + 9.156355383437, 9.111361008094, 9.066366632752, 9.021372257409, 8.976377882066, 8.931383506723, 8.886389131380, + 8.841394756037, 8.796400380694, 8.751406005351, 8.706411630008, 8.661417254664, 8.616422879321, 8.571428503977, + 8.526434128633, 8.481439753290, 8.436445377946, 8.391451002602, 8.346456627258, 8.301462251914, 8.256467876570, + 8.211473501225, 8.166479125881, 8.121484750537, 8.076490375192, 8.031495999848, 7.986501624503, 7.941507249158, + 7.896512873813, 7.851518498469, 7.806524123124, 7.761529747779, 7.716535372433, 7.671540997088, 7.626546621743, + 7.581552246398, 7.536557871052, 7.491563495707, 7.446569120361, 7.401574745016, 7.356580369670, 7.311585994324, + 7.266591618978, 7.221597243632, 7.176602868286, 7.131608492940, 7.086614117594, 7.041619742248, 6.996625366902, + 6.951630991555, 6.906636616209, 6.861642240862, 6.816647865516, 6.771653490169, 6.726659114822, 6.681664739476, + 6.636670364129, 6.591675988782, 6.546681613435, 6.501687238088, 6.456692862741, 6.411698487394, 6.366704112047, + 6.321709736699, 6.276715361352, 6.231720986005, 6.186726610657, 6.141732235310, 6.096737859962, 6.051743484615, + 6.006749109267, 5.961754733919, 5.916760358571, 5.871765983223, 5.826771607875, 5.781777232528, 5.736782857179, + 5.691788481831, 5.646794106483, 5.601799731135, 5.556805355787, 5.511810980438, 5.466816605090, 5.421822229742, + 5.376827854393, 5.331833479045, 5.286839103696, 5.241844728348, 5.196850352999, 5.151855977650, 5.106861602301, + 5.061867226953, 5.016872851604, 4.971878476255, 4.926884100906, 4.881889725557, 4.836895350208, 4.791900974859, + 4.746906599509, 4.701912224160, 4.656917848811, 4.611923473462, 4.566929098112, 4.521934722763, 4.476940347414, + 4.431945972064, 4.386951596715, 4.341957221365, 4.296962846015, 4.251968470666, 4.206974095316, 4.161979719966, + 4.116985344617, 4.071990969267, 4.026996593917, 3.982002218567, 3.937007843217, 3.892013467867, 3.847019092517, + 3.802024717167, 3.757030341817, 3.712035966467, 3.667041591117, 3.622047215767, 3.577052840416, 3.532058465066, + 3.487064089716, 3.442069714366, 3.397075339015, 3.352080963665, 3.307086588314, 3.262092212964, 3.217097837613, + 3.172103462263, 3.127109086912, 3.082114711562, 3.037120336211, 2.992125960861, 2.947131585510, 2.902137210159, + 2.857142834808, 2.812148459458, 2.767154084107, 2.722159708756, 2.677165333405, 2.632170958055, 2.587176582704, + 2.542182207353, 2.497187832002, 2.452193456651, 2.407199081300, 2.362204705949, 2.317210330598, 2.272215955247, + 2.227221579896, 2.182227204545, 2.137232829194, 2.092238453842, 2.047244078491, 2.002249703140, 1.957255327789, + 1.912260952438, 1.867266577087, 1.822272201735, 1.777277826384, 1.732283451033, 1.687289075681, 1.642294700330, + 1.597300324979, 1.552305949627, 1.507311574276, 1.462317198925, 1.417322823573, 1.372328448222, 1.327334072871, + 1.282339697519, 1.237345322168, 1.192350946816, 1.147356571465, 1.102362196113, 1.057367820762, 1.012373445410, + 0.967379070059, 0.922384694707, 0.877390319356, 0.832395944004, 0.787401568653, 0.742407193301, 0.697412817950, + 0.652418442598, 0.607424067247, 0.562429691895, 0.517435316543, 0.472440941192, 0.427446565840, 0.382452190489, + 0.337457815137, 0.292463439785, 0.247469064434, 0.202474689082, 0.157480313731, 0.112485938379, 0.067491563027, + 0.022497187676 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N24.cc b/src/atlas/grid/detail/spacing/gaussian/N24.cc index 80ca071c6..2935d6cf5 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N24.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N24.cc @@ -7,35 +7,14 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(24,LIST( - 87.1590945558628505, - 83.4789366693171644, - 79.7770456548256419, - 76.0702444625451335, - 72.3615810293448476, - 68.6520167895174893, - 64.9419494887575155, - 61.2315731880771352, - 57.5209937979699646, - 53.8102740319414252, - 50.0994534129868470, - 46.3885581116054269, - 42.6776061726049036, - 38.9666104694540252, - 35.2555804613681829, - 31.5445232840216754, - 27.8334444519932376, - 24.1223483260879874, - 20.4112384335677852, - 16.7001176938426745, - 12.9889885820881474, - 9.2778532515078656, - 5.5667136279135834, - 1.8555714859932551 - )) +DEFINE_GAUSSIAN_LATITUDES( 24, LIST( 87.1590945558628505, 83.4789366693171644, 79.7770456548256419, 76.0702444625451335, + 72.3615810293448476, 68.6520167895174893, 64.9419494887575155, 61.2315731880771352, + 57.5209937979699646, 53.8102740319414252, 50.0994534129868470, 46.3885581116054269, + 42.6776061726049036, 38.9666104694540252, 35.2555804613681829, 31.5445232840216754, + 27.8334444519932376, 24.1223483260879874, 20.4112384335677852, 16.7001176938426745, + 12.9889885820881474, 9.2778532515078656, 5.5667136279135834, 1.8555714859932551 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N256.cc b/src/atlas/grid/detail/spacing/gaussian/N256.cc index 373985a5f..fa73bc930 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N256.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N256.cc @@ -7,63 +7,52 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(256,LIST( - 89.731148618413, 89.382873896334, 89.032542423790, 88.681746243591, 88.330773788807, - 87.979716034326, 87.628610609484, 87.277475867224, 86.926321817646, 86.575154382095, - 86.223977286346, 85.872792991467, 85.521603188281, 85.170409076734, 84.819211531931, - 84.468011207066, 84.116808599553, 83.765604094844, 83.414397996248, 83.063190545702, - 82.711981938543, 82.360772334213, 82.009561864138, 81.658350637624, 81.307138746324, - 80.955926267657, 80.604713267476, 80.253499802142, 79.902285920181, 79.551071663595, - 79.199857068926, 78.848642168112, 78.497426989195, 78.146211556892, 77.794995893075, - 77.443780017172, 77.092563946496, 76.741347696526, 76.390131281143, 76.038914712832, - 75.687698002854, 75.336481161390, 74.985264197669, 74.634047120076, 74.282829936248, - 73.931612653153, 73.580395277164, 73.229177814120, 72.877960269381, 72.526742647876, - 72.175524954146, 71.824307192381, 71.473089366452, 71.121871479946, 70.770653536183, - 70.419435538248, 70.068217489009, 69.716999391133, 69.365781247107, 69.014563059252, - 68.663344829736, 68.312126560585, 67.960908253699, 67.609689910856, 67.258471533726, - 66.907253123876, 66.556034682780, 66.204816211827, 65.853597712321, 65.502379185494, - 65.151160632510, 64.799942054463, 64.448723452393, 64.097504827279, 63.746286180050, - 63.395067511586, 63.043848822719, 62.692630114242, 62.341411386903, 61.990192641418, - 61.638973878463, 61.287755098684, 60.936536302693, 60.585317491076, 60.234098664389, - 59.882879823163, 59.531660967905, 59.180442099098, 58.829223217203, 58.478004322663, - 58.126785415899, 57.775566497315, 57.424347567296, 57.073128626212, 56.721909674418, - 56.370690712253, 56.019471740043, 55.668252758099, 55.317033766721, 54.965814766198, - 54.614595756804, 54.263376738806, 53.912157712459, 53.560938678008, 53.209719635690, - 52.858500585731, 52.507281528350, 52.156062463759, 51.804843392159, 51.453624313747, - 51.102405228712, 50.751186137234, 50.399967039491, 50.048747935650, 49.697528825877, - 49.346309710328, 48.995090589156, 48.643871462509, 48.292652330530, 47.941433193356, - 47.590214051120, 47.238994903953, 46.887775751977, 46.536556595315, 46.185337434084, - 45.834118268396, 45.482899098363, 45.131679924089, 44.780460745679, 44.429241563233, - 44.078022376847, 43.726803186616, 43.375583992632, 43.024364794983, 42.673145593755, - 42.321926389033, 41.970707180896, 41.619487969425, 41.268268754697, 40.917049536785, - 40.565830315762, 40.214611091700, 39.863391864666, 39.512172634728, 39.160953401950, - 38.809734166396, 38.458514928128, 38.107295687205, 37.756076443686, 37.404857197628, - 37.053637949087, 36.702418698117, 36.351199444770, 35.999980189098, 35.648760931151, - 35.297541670979, 34.946322408628, 34.595103144147, 34.243883877579, 33.892664608970, - 33.541445338363, 33.190226065800, 32.839006791323, 32.487787514973, 32.136568236789, - 31.785348956809, 31.434129675072, 31.082910391614, 30.731691106472, 30.380471819681, - 30.029252531276, 29.678033241291, 29.326813949758, 28.975594656711, 28.624375362181, - 28.273156066200, 27.921936768798, 27.570717470004, 27.219498169849, 26.868278868361, - 26.517059565568, 26.165840261498, 25.814620956179, 25.463401649636, 25.112182341895, - 24.760963032984, 24.409743722926, 24.058524411747, 23.707305099470, 23.356085786120, - 23.004866471720, 22.653647156293, 22.302427839862, 21.951208522449, 21.599989204076, - 21.248769884764, 20.897550564535, 20.546331243409, 20.195111921408, 19.843892598551, - 19.492673274857, 19.141453950348, 18.790234625041, 18.439015298957, 18.087795972114, - 17.736576644529, 17.385357316222, 17.034137987211, 16.682918657513, 16.331699327146, - 15.980479996126, 15.629260664472, 15.278041332199, 14.926821999325, 14.575602665866, - 14.224383331838, 13.873163997257, 13.521944662139, 13.170725326500, 12.819505990355, - 12.468286653719, 12.117067316609, 11.765847979038, 11.414628641021, 11.063409302574, - 10.712189963711, 10.360970624447, 10.009751284795, 9.658531944770, 9.307312604387, - 8.956093263659, 8.604873922599, 8.253654581223, 7.902435239543, 7.551215897573, - 7.199996555326, 6.848777212817, 6.497557870058, 6.146338527062, 5.795119183843, - 5.443899840414, 5.092680496788, 4.741461152978, 4.390241808997, 4.039022464858, - 3.687803120573, 3.336583776155, 2.985364431618, 2.634145086974, 2.282925742235, - 1.931706397414, 1.580487052524, 1.229267707577, 0.878048362586, 0.526829017564, - 0.175609672524 -)) +DEFINE_GAUSSIAN_LATITUDES( + 256, LIST( 89.731148618413, 89.382873896334, 89.032542423790, 88.681746243591, 88.330773788807, 87.979716034326, + 87.628610609484, 87.277475867224, 86.926321817646, 86.575154382095, 86.223977286346, 85.872792991467, + 85.521603188281, 85.170409076734, 84.819211531931, 84.468011207066, 84.116808599553, 83.765604094844, + 83.414397996248, 83.063190545702, 82.711981938543, 82.360772334213, 82.009561864138, 81.658350637624, + 81.307138746324, 80.955926267657, 80.604713267476, 80.253499802142, 79.902285920181, 79.551071663595, + 79.199857068926, 78.848642168112, 78.497426989195, 78.146211556892, 77.794995893075, 77.443780017172, + 77.092563946496, 76.741347696526, 76.390131281143, 76.038914712832, 75.687698002854, 75.336481161390, + 74.985264197669, 74.634047120076, 74.282829936248, 73.931612653153, 73.580395277164, 73.229177814120, + 72.877960269381, 72.526742647876, 72.175524954146, 71.824307192381, 71.473089366452, 71.121871479946, + 70.770653536183, 70.419435538248, 70.068217489009, 69.716999391133, 69.365781247107, 69.014563059252, + 68.663344829736, 68.312126560585, 67.960908253699, 67.609689910856, 67.258471533726, 66.907253123876, + 66.556034682780, 66.204816211827, 65.853597712321, 65.502379185494, 65.151160632510, 64.799942054463, + 64.448723452393, 64.097504827279, 63.746286180050, 63.395067511586, 63.043848822719, 62.692630114242, + 62.341411386903, 61.990192641418, 61.638973878463, 61.287755098684, 60.936536302693, 60.585317491076, + 60.234098664389, 59.882879823163, 59.531660967905, 59.180442099098, 58.829223217203, 58.478004322663, + 58.126785415899, 57.775566497315, 57.424347567296, 57.073128626212, 56.721909674418, 56.370690712253, + 56.019471740043, 55.668252758099, 55.317033766721, 54.965814766198, 54.614595756804, 54.263376738806, + 53.912157712459, 53.560938678008, 53.209719635690, 52.858500585731, 52.507281528350, 52.156062463759, + 51.804843392159, 51.453624313747, 51.102405228712, 50.751186137234, 50.399967039491, 50.048747935650, + 49.697528825877, 49.346309710328, 48.995090589156, 48.643871462509, 48.292652330530, 47.941433193356, + 47.590214051120, 47.238994903953, 46.887775751977, 46.536556595315, 46.185337434084, 45.834118268396, + 45.482899098363, 45.131679924089, 44.780460745679, 44.429241563233, 44.078022376847, 43.726803186616, + 43.375583992632, 43.024364794983, 42.673145593755, 42.321926389033, 41.970707180896, 41.619487969425, + 41.268268754697, 40.917049536785, 40.565830315762, 40.214611091700, 39.863391864666, 39.512172634728, + 39.160953401950, 38.809734166396, 38.458514928128, 38.107295687205, 37.756076443686, 37.404857197628, + 37.053637949087, 36.702418698117, 36.351199444770, 35.999980189098, 35.648760931151, 35.297541670979, + 34.946322408628, 34.595103144147, 34.243883877579, 33.892664608970, 33.541445338363, 33.190226065800, + 32.839006791323, 32.487787514973, 32.136568236789, 31.785348956809, 31.434129675072, 31.082910391614, + 30.731691106472, 30.380471819681, 30.029252531276, 29.678033241291, 29.326813949758, 28.975594656711, + 28.624375362181, 28.273156066200, 27.921936768798, 27.570717470004, 27.219498169849, 26.868278868361, + 26.517059565568, 26.165840261498, 25.814620956179, 25.463401649636, 25.112182341895, 24.760963032984, + 24.409743722926, 24.058524411747, 23.707305099470, 23.356085786120, 23.004866471720, 22.653647156293, + 22.302427839862, 21.951208522449, 21.599989204076, 21.248769884764, 20.897550564535, 20.546331243409, + 20.195111921408, 19.843892598551, 19.492673274857, 19.141453950348, 18.790234625041, 18.439015298957, + 18.087795972114, 17.736576644529, 17.385357316222, 17.034137987211, 16.682918657513, 16.331699327146, + 15.980479996126, 15.629260664472, 15.278041332199, 14.926821999325, 14.575602665866, 14.224383331838, + 13.873163997257, 13.521944662139, 13.170725326500, 12.819505990355, 12.468286653719, 12.117067316609, + 11.765847979038, 11.414628641021, 11.063409302574, 10.712189963711, 10.360970624447, 10.009751284795, + 9.658531944770, 9.307312604387, 8.956093263659, 8.604873922599, 8.253654581223, 7.902435239543, + 7.551215897573, 7.199996555326, 6.848777212817, 6.497557870058, 6.146338527062, 5.795119183843, + 5.443899840414, 5.092680496788, 4.741461152978, 4.390241808997, 4.039022464858, 3.687803120573, + 3.336583776155, 2.985364431618, 2.634145086974, 2.282925742235, 1.931706397414, 1.580487052524, + 1.229267707577, 0.878048362586, 0.526829017564, 0.175609672524 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N32.cc b/src/atlas/grid/detail/spacing/gaussian/N32.cc index 073ab08e7..cc886f7b7 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N32.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N32.cc @@ -7,43 +7,16 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(32,LIST( - 87.863798839233, - 85.096526988317, - 82.312912947886, - 79.525606572659, - 76.736899680368, - 73.947515153990, - 71.157752011587, - 68.367756108313, - 65.577607010828, - 62.787351798963, - 59.997020108491, - 57.206631527643, - 54.416199526086, - 51.625733674938, - 48.835240966251, - 46.044726631102, - 43.254194665351, - 40.463648178115, - 37.673089629045, - 34.882520993773, - 32.091943881744, - 29.301359621763, - 26.510769325211, - 23.720173933535, - 20.929574254490, - 18.138970990239, - 15.348364759491, - 12.557756115231, - 9.767145559196, - 6.976533553949, - 4.185920533189, - 1.395306910819 -)) +DEFINE_GAUSSIAN_LATITUDES( 32, + LIST( 87.863798839233, 85.096526988317, 82.312912947886, 79.525606572659, 76.736899680368, + 73.947515153990, 71.157752011587, 68.367756108313, 65.577607010828, 62.787351798963, + 59.997020108491, 57.206631527643, 54.416199526086, 51.625733674938, 48.835240966251, + 46.044726631102, 43.254194665351, 40.463648178115, 37.673089629045, 34.882520993773, + 32.091943881744, 29.301359621763, 26.510769325211, 23.720173933535, 20.929574254490, + 18.138970990239, 15.348364759491, 12.557756115231, 9.767145559196, 6.976533553949, + 4.185920533189, 1.395306910819 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N320.cc b/src/atlas/grid/detail/spacing/gaussian/N320.cc index 993483fd0..93921bc8a 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N320.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N320.cc @@ -7,75 +7,63 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(320,LIST( - 89.784876907219, 89.506202738206, 89.225882847612, 88.945191118316, 88.664358341823, - 88.383457312248, 88.102518138937, 87.821555507111, 87.540577426411, 87.259588634840, - 86.978592113597, 86.697589831922, 86.416583142736, 86.135573006184, 85.854560122485, - 85.573545014297, 85.292528079627, 85.011509626898, 84.730489898803, 84.449469088929, - 84.168447353577, 83.887424820323, 83.606401594330, 83.325377763059, 83.044353399845, - 82.763328566637, 82.482303316125, 82.201277693408, 81.920251737312, 81.639225481447, - 81.358198955050, 81.077172183679, 80.796145189767, 80.515117993094, 80.234090611161, - 79.953063059512, 79.672035351999, 79.391007501008, 79.109979517646, 78.828951411902, - 78.547923192786, 78.266894868445, 77.985866446261, 77.704837932945, 77.423809334606, - 77.142780656820, 76.861751904686, 76.580723082875, 76.299694195676, 76.018665247032, - 75.737636240576, 75.456607179661, 75.175578067384, 74.894548906612, 74.613519700005, - 74.332490450030, 74.051461158979, 73.770431828988, 73.489402462046, 73.208373060010, - 72.927343624612, 72.646314157476, 72.365284660120, 72.084255133966, 71.803225580350, - 71.522196000526, 71.241166395673, 70.960136766901, 70.679107115253, 70.398077441716, - 70.117047747219, 69.836018032638, 69.554988298803, 69.273958546499, 68.992928776468, - 68.711898989413, 68.430869186000, 68.149839366862, 67.868809532599, 67.587779683782, - 67.306749820951, 67.025719944623, 66.744690055288, 66.463660153412, 66.182630239442, - 65.901600313801, 65.620570376894, 65.339540429107, 65.058510470810, 64.777480502355, - 64.496450524078, 64.215420536303, 63.934390539337, 63.653360533475, 63.372330519002, - 63.091300496187, 62.810270465291, 62.529240426562, 62.248210380240, 61.967180326555, - 61.686150265726, 61.405120197967, 61.124090123479, 60.843060042460, 60.562029955097, - 60.280999861572, 59.999969762058, 59.718939656725, 59.437909545733, 59.156879429239, - 58.875849307392, 58.594819180339, 58.313789048218, 58.032758911165, 57.751728769309, - 57.470698622777, 57.189668471689, 56.908638316164, 56.627608156315, 56.346577992251, - 56.065547824077, 55.784517651898, 55.503487475812, 55.222457295914, 54.941427112298, - 54.660396925054, 54.379366734270, 54.098336540028, 53.817306342412, 53.536276141501, - 53.255245937372, 52.974215730098, 52.693185519753, 52.412155306407, 52.131125090128, - 51.850094870983, 51.569064649034, 51.288034424345, 51.007004196977, 50.725973966988, - 50.444943734435, 50.163913499374, 49.882883261860, 49.601853021944, 49.320822779679, - 49.039792535112, 48.758762288294, 48.477732039272, 48.196701788090, 47.915671534794, - 47.634641279427, 47.353611022031, 47.072580762649, 46.791550501320, 46.510520238082, - 46.229489972975, 45.948459706036, 45.667429437301, 45.386399166805, 45.105368894583, - 44.824338620668, 44.543308345094, 44.262278067892, 43.981247789094, 43.700217508730, - 43.419187226830, 43.138156943424, 42.857126658539, 42.576096372204, 42.295066084446, - 42.014035795291, 41.733005504765, 41.451975212893, 41.170944919701, 40.889914625212, - 40.608884329450, 40.327854032439, 40.046823734201, 39.765793434758, 39.484763134131, - 39.203732832343, 38.922702529414, 38.641672225364, 38.360641920213, 38.079611613981, - 37.798581306687, 37.517550998349, 37.236520688986, 36.955490378616, 36.674460067255, - 36.393429754923, 36.112399441635, 35.831369127408, 35.550338812258, 35.269308496201, - 34.988278179253, 34.707247861429, 34.426217542744, 34.145187223213, 33.864156902850, - 33.583126581669, 33.302096259685, 33.021065936911, 32.740035613361, 32.459005289046, - 32.177974963982, 31.896944638180, 31.615914311652, 31.334883984411, 31.053853656469, - 30.772823327839, 30.491792998530, 30.210762668555, 29.929732337926, 29.648702006652, - 29.367671674745, 29.086641342216, 28.805611009075, 28.524580675333, 28.243550340999, - 27.962520006084, 27.681489670597, 27.400459334548, 27.119428997946, 26.838398660802, - 26.557368323123, 26.276337984920, 25.995307646201, 25.714277306975, 25.433246967251, - 25.152216627037, 24.871186286341, 24.590155945173, 24.309125603539, 24.028095261449, - 23.747064918910, 23.466034575929, 23.185004232515, 22.903973888676, 22.622943544418, - 22.341913199749, 22.060882854677, 21.779852509208, 21.498822163351, 21.217791817111, - 20.936761470495, 20.655731123512, 20.374700776166, 20.093670428466, 19.812640080417, - 19.531609732026, 19.250579383300, 18.969549034245, 18.688518684866, 18.407488335171, - 18.126457985166, 17.845427634856, 17.564397284248, 17.283366933347, 17.002336582159, - 16.721306230691, 16.440275878947, 16.159245526934, 15.878215174657, 15.597184822122, - 15.316154469334, 15.035124116299, 14.754093763022, 14.473063409508, 14.192033055763, - 13.911002701792, 13.629972347600, 13.348941993193, 13.067911638575, 12.786881283751, - 12.505850928727, 12.224820573508, 11.943790218098, 11.662759862502, 11.381729506726, - 11.100699150774, 10.819668794650, 10.538638438360, 10.257608081908, 9.976577725300, - 9.695547368539, 9.414517011630, 9.133486654578, 8.852456297388, 8.571425940064, - 8.290395582610, 8.009365225031, 7.728334867332, 7.447304509516, 7.166274151589, - 6.885243793555, 6.604213435417, 6.323183077181, 6.042152718851, 5.761122360431, - 5.480092001926, 5.199061643339, 4.918031284674, 4.637000925938, 4.355970567132, - 4.074940208262, 3.793909849332, 3.512879490347, 3.231849131309, 2.950818772224, - 2.669788413095, 2.388758053927, 2.107727694724, 1.826697335490, 1.545666976229, - 1.264636616946, 0.983606257644, 0.702575898327, 0.421545539000, 0.140515179668 -)) +DEFINE_GAUSSIAN_LATITUDES( + 320, LIST( 89.784876907219, 89.506202738206, 89.225882847612, 88.945191118316, 88.664358341823, 88.383457312248, + 88.102518138937, 87.821555507111, 87.540577426411, 87.259588634840, 86.978592113597, 86.697589831922, + 86.416583142736, 86.135573006184, 85.854560122485, 85.573545014297, 85.292528079627, 85.011509626898, + 84.730489898803, 84.449469088929, 84.168447353577, 83.887424820323, 83.606401594330, 83.325377763059, + 83.044353399845, 82.763328566637, 82.482303316125, 82.201277693408, 81.920251737312, 81.639225481447, + 81.358198955050, 81.077172183679, 80.796145189767, 80.515117993094, 80.234090611161, 79.953063059512, + 79.672035351999, 79.391007501008, 79.109979517646, 78.828951411902, 78.547923192786, 78.266894868445, + 77.985866446261, 77.704837932945, 77.423809334606, 77.142780656820, 76.861751904686, 76.580723082875, + 76.299694195676, 76.018665247032, 75.737636240576, 75.456607179661, 75.175578067384, 74.894548906612, + 74.613519700005, 74.332490450030, 74.051461158979, 73.770431828988, 73.489402462046, 73.208373060010, + 72.927343624612, 72.646314157476, 72.365284660120, 72.084255133966, 71.803225580350, 71.522196000526, + 71.241166395673, 70.960136766901, 70.679107115253, 70.398077441716, 70.117047747219, 69.836018032638, + 69.554988298803, 69.273958546499, 68.992928776468, 68.711898989413, 68.430869186000, 68.149839366862, + 67.868809532599, 67.587779683782, 67.306749820951, 67.025719944623, 66.744690055288, 66.463660153412, + 66.182630239442, 65.901600313801, 65.620570376894, 65.339540429107, 65.058510470810, 64.777480502355, + 64.496450524078, 64.215420536303, 63.934390539337, 63.653360533475, 63.372330519002, 63.091300496187, + 62.810270465291, 62.529240426562, 62.248210380240, 61.967180326555, 61.686150265726, 61.405120197967, + 61.124090123479, 60.843060042460, 60.562029955097, 60.280999861572, 59.999969762058, 59.718939656725, + 59.437909545733, 59.156879429239, 58.875849307392, 58.594819180339, 58.313789048218, 58.032758911165, + 57.751728769309, 57.470698622777, 57.189668471689, 56.908638316164, 56.627608156315, 56.346577992251, + 56.065547824077, 55.784517651898, 55.503487475812, 55.222457295914, 54.941427112298, 54.660396925054, + 54.379366734270, 54.098336540028, 53.817306342412, 53.536276141501, 53.255245937372, 52.974215730098, + 52.693185519753, 52.412155306407, 52.131125090128, 51.850094870983, 51.569064649034, 51.288034424345, + 51.007004196977, 50.725973966988, 50.444943734435, 50.163913499374, 49.882883261860, 49.601853021944, + 49.320822779679, 49.039792535112, 48.758762288294, 48.477732039272, 48.196701788090, 47.915671534794, + 47.634641279427, 47.353611022031, 47.072580762649, 46.791550501320, 46.510520238082, 46.229489972975, + 45.948459706036, 45.667429437301, 45.386399166805, 45.105368894583, 44.824338620668, 44.543308345094, + 44.262278067892, 43.981247789094, 43.700217508730, 43.419187226830, 43.138156943424, 42.857126658539, + 42.576096372204, 42.295066084446, 42.014035795291, 41.733005504765, 41.451975212893, 41.170944919701, + 40.889914625212, 40.608884329450, 40.327854032439, 40.046823734201, 39.765793434758, 39.484763134131, + 39.203732832343, 38.922702529414, 38.641672225364, 38.360641920213, 38.079611613981, 37.798581306687, + 37.517550998349, 37.236520688986, 36.955490378616, 36.674460067255, 36.393429754923, 36.112399441635, + 35.831369127408, 35.550338812258, 35.269308496201, 34.988278179253, 34.707247861429, 34.426217542744, + 34.145187223213, 33.864156902850, 33.583126581669, 33.302096259685, 33.021065936911, 32.740035613361, + 32.459005289046, 32.177974963982, 31.896944638180, 31.615914311652, 31.334883984411, 31.053853656469, + 30.772823327839, 30.491792998530, 30.210762668555, 29.929732337926, 29.648702006652, 29.367671674745, + 29.086641342216, 28.805611009075, 28.524580675333, 28.243550340999, 27.962520006084, 27.681489670597, + 27.400459334548, 27.119428997946, 26.838398660802, 26.557368323123, 26.276337984920, 25.995307646201, + 25.714277306975, 25.433246967251, 25.152216627037, 24.871186286341, 24.590155945173, 24.309125603539, + 24.028095261449, 23.747064918910, 23.466034575929, 23.185004232515, 22.903973888676, 22.622943544418, + 22.341913199749, 22.060882854677, 21.779852509208, 21.498822163351, 21.217791817111, 20.936761470495, + 20.655731123512, 20.374700776166, 20.093670428466, 19.812640080417, 19.531609732026, 19.250579383300, + 18.969549034245, 18.688518684866, 18.407488335171, 18.126457985166, 17.845427634856, 17.564397284248, + 17.283366933347, 17.002336582159, 16.721306230691, 16.440275878947, 16.159245526934, 15.878215174657, + 15.597184822122, 15.316154469334, 15.035124116299, 14.754093763022, 14.473063409508, 14.192033055763, + 13.911002701792, 13.629972347600, 13.348941993193, 13.067911638575, 12.786881283751, 12.505850928727, + 12.224820573508, 11.943790218098, 11.662759862502, 11.381729506726, 11.100699150774, 10.819668794650, + 10.538638438360, 10.257608081908, 9.976577725300, 9.695547368539, 9.414517011630, 9.133486654578, + 8.852456297388, 8.571425940064, 8.290395582610, 8.009365225031, 7.728334867332, 7.447304509516, + 7.166274151589, 6.885243793555, 6.604213435417, 6.323183077181, 6.042152718851, 5.761122360431, + 5.480092001926, 5.199061643339, 4.918031284674, 4.637000925938, 4.355970567132, 4.074940208262, + 3.793909849332, 3.512879490347, 3.231849131309, 2.950818772224, 2.669788413095, 2.388758053927, + 2.107727694724, 1.826697335490, 1.545666976229, 1.264636616946, 0.983606257644, 0.702575898327, + 0.421545539000, 0.140515179668 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N400.cc b/src/atlas/grid/detail/spacing/gaussian/N400.cc index c6d94b95f..e31f90664 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N400.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N400.cc @@ -7,91 +7,76 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(400,LIST( - 89.827874645894, 89.604900490023, 89.380609551250, 89.156021095055, 88.931319783477, - 88.706563860905, 88.481777418577, 88.256972206505, 88.032154633403, 87.807328490264, - 87.582496162420, 87.357659225510, 87.132818762040, 86.907975540243, 86.683130120384, - 86.458282920653, 86.233434259507, 86.008584383722, 85.783733487483, 85.558881725682, - 85.334029223381, 85.109176082657, 84.884322387651, 84.659468208345, 84.434613603414, - 84.209758622426, 83.984903307540, 83.760047694839, 83.535191815391, 83.310335696085, - 83.085479360317, 82.860622828534, 82.635766118687, 82.410909246602, 82.186052226280, - 81.961195070160, 81.736337789325, 81.511480393685, 81.286622892127, 81.061765292642, - 80.836907602441, 80.612049828040, 80.387191975348, 80.162334049733, 79.937476056084, - 79.712617998861, 79.487759882144, 79.262901709670, 79.038043484872, 78.813185210903, - 78.588326890672, 78.363468526859, 78.138610121943, 77.913751678220, 77.688893197814, - 77.464034682701, 77.239176134715, 77.014317555565, 76.789458946841, 76.564600310030, - 76.339741646518, 76.114882957602, 75.890024244498, 75.665165508344, 75.440306750209, - 75.215447971095, 74.990589171946, 74.765730353650, 74.540871517041, 74.316012662908, - 74.091153791995, 73.866294905004, 73.641436002597, 73.416577085402, 73.191718154013, - 72.966859208993, 72.742000250874, 72.517141280163, 72.292282297339, 72.067423302858, - 71.842564297155, 71.617705280640, 71.392846253707, 71.167987216729, 70.943128170062, - 70.718269114045, 70.493410049002, 70.268550975241, 70.043691893059, 69.818832802736, - 69.593973704543, 69.369114598736, 69.144255485563, 68.919396365260, 68.694537238053, - 68.469678104158, 68.244818963783, 68.019959817128, 67.795100664383, 67.570241505733, - 67.345382341353, 67.120523171413, 66.895663996075, 66.670804815496, 66.445945629826, - 66.221086439211, 65.996227243789, 65.771368043695, 65.546508839058, 65.321649630002, - 65.096790416648, 64.871931199112, 64.647071977504, 64.422212751934, 64.197353522504, - 63.972494289316, 63.747635052466, 63.522775812048, 63.297916568152, 63.073057320866, - 62.848198070275, 62.623338816461, 62.398479559501, 62.173620299475, 61.948761036454, - 61.723901770512, 61.499042501718, 61.274183230138, 61.049323955840, 60.824464678885, - 60.599605399335, 60.374746117249, 60.149886832686, 59.925027545701, 59.700168256349, - 59.475308964682, 59.250449670751, 59.025590374607, 58.800731076297, 58.575871775869, - 58.351012473367, 58.126153168837, 57.901293862321, 57.676434553861, 57.451575243498, - 57.226715931271, 57.001856617219, 56.776997301380, 56.552137983789, 56.327278664483, - 56.102419343496, 55.877560020861, 55.652700696612, 55.427841370780, 55.202982043397, - 54.978122714492, 54.753263384095, 54.528404052236, 54.303544718941, 54.078685384240, - 53.853826048157, 53.628966710720, 53.404107371953, 53.179248031881, 52.954388690530, - 52.729529347921, 52.504670004079, 52.279810659026, 52.054951312783, 51.830091965373, - 51.605232616816, 51.380373267132, 51.155513916343, 50.930654564466, 50.705795211522, - 50.480935857528, 50.256076502504, 50.031217146467, 49.806357789435, 49.581498431424, - 49.356639072452, 49.131779712534, 48.906920351687, 48.682060989925, 48.457201627266, - 48.232342263723, 48.007482899311, 47.782623534045, 47.557764167938, 47.332904801005, - 47.108045433258, 46.883186064711, 46.658326695378, 46.433467325269, 46.208607954399, - 45.983748582779, 45.758889210421, 45.534029837336, 45.309170463537, 45.084311089034, - 44.859451713839, 44.634592337961, 44.409732961412, 44.184873584203, 43.960014206342, - 43.735154827841, 43.510295448709, 43.285436068955, 43.060576688590, 42.835717307622, - 42.610857926060, 42.385998543914, 42.161139161191, 41.936279777901, 41.711420394052, - 41.486561009653, 41.261701624711, 41.036842239234, 40.811982853231, 40.587123466709, - 40.362264079675, 40.137404692137, 39.912545304103, 39.687685915579, 39.462826526572, - 39.237967137090, 39.013107747139, 38.788248356727, 38.563388965859, 38.338529574541, - 38.113670182782, 37.888810790586, 37.663951397960, 37.439092004910, 37.214232611441, - 36.989373217561, 36.764513823274, 36.539654428586, 36.314795033503, 36.089935638030, - 35.865076242173, 35.640216845937, 35.415357449327, 35.190498052348, 34.965638655006, - 34.740779257306, 34.515919859252, 34.291060460849, 34.066201062102, 33.841341663016, - 33.616482263595, 33.391622863845, 33.166763463768, 32.941904063371, 32.717044662657, - 32.492185261630, 32.267325860296, 32.042466458657, 31.817607056718, 31.592747654483, - 31.367888251957, 31.143028849143, 30.918169446044, 30.693310042666, 30.468450639011, - 30.243591235084, 30.018731830887, 29.793872426425, 29.569013021702, 29.344153616720, - 29.119294211484, 28.894434805996, 28.669575400260, 28.444715994280, 28.219856588059, - 27.994997181599, 27.770137774905, 27.545278367979, 27.320418960825, 27.095559553446, - 26.870700145844, 26.645840738023, 26.420981329986, 26.196121921735, 25.971262513275, - 25.746403104606, 25.521543695733, 25.296684286658, 25.071824877385, 24.846965467914, - 24.622106058250, 24.397246648396, 24.172387238353, 23.947527828124, 23.722668417712, - 23.497809007120, 23.272949596350, 23.048090185404, 22.823230774285, 22.598371362996, - 22.373511951538, 22.148652539915, 21.923793128129, 21.698933716181, 21.474074304075, - 21.249214891812, 21.024355479395, 20.799496066827, 20.574636654109, 20.349777241243, - 20.124917828232, 19.900058415078, 19.675199001783, 19.450339588349, 19.225480174778, - 19.000620761073, 18.775761347235, 18.550901933267, 18.326042519170, 18.101183104946, - 17.876323690598, 17.651464276127, 17.426604861536, 17.201745446826, 16.976886031999, - 16.752026617057, 16.527167202002, 16.302307786836, 16.077448371561, 15.852588956178, - 15.627729540690, 15.402870125097, 15.178010709403, 14.953151293609, 14.728291877716, - 14.503432461726, 14.278573045641, 14.053713629463, 13.828854213193, 13.603994796833, - 13.379135380386, 13.154275963851, 12.929416547232, 12.704557130530, 12.479697713746, - 12.254838296882, 12.029978879940, 11.805119462921, 11.580260045827, 11.355400628659, - 11.130541211420, 10.905681794110, 10.680822376731, 10.455962959286, 10.231103541774, - 10.006244124198, 9.781384706560, 9.556525288861, 9.331665871102, 9.106806453284, - 8.881947035411, 8.657087617482, 8.432228199499, 8.207368781465, 7.982509363379, - 7.757649945245, 7.532790527062, 7.307931108834, 7.083071690560, 6.858212272243, - 6.633352853884, 6.408493435484, 6.183634017046, 5.958774598569, 5.733915180056, - 5.509055761509, 5.284196342927, 5.059336924314, 4.834477505670, 4.609618086996, - 4.384758668295, 4.159899249567, 3.935039830814, 3.710180412037, 3.485320993238, - 3.260461574418, 3.035602155578, 2.810742736719, 2.585883317844, 2.361023898953, - 2.136164480048, 1.911305061130, 1.686445642201, 1.461586223261, 1.236726804313, - 1.011867385357, 0.787007966395, 0.562148547428, 0.337289128458, 0.112429709486 -)) +DEFINE_GAUSSIAN_LATITUDES( + 400, LIST( 89.827874645894, 89.604900490023, 89.380609551250, 89.156021095055, 88.931319783477, 88.706563860905, + 88.481777418577, 88.256972206505, 88.032154633403, 87.807328490264, 87.582496162420, 87.357659225510, + 87.132818762040, 86.907975540243, 86.683130120384, 86.458282920653, 86.233434259507, 86.008584383722, + 85.783733487483, 85.558881725682, 85.334029223381, 85.109176082657, 84.884322387651, 84.659468208345, + 84.434613603414, 84.209758622426, 83.984903307540, 83.760047694839, 83.535191815391, 83.310335696085, + 83.085479360317, 82.860622828534, 82.635766118687, 82.410909246602, 82.186052226280, 81.961195070160, + 81.736337789325, 81.511480393685, 81.286622892127, 81.061765292642, 80.836907602441, 80.612049828040, + 80.387191975348, 80.162334049733, 79.937476056084, 79.712617998861, 79.487759882144, 79.262901709670, + 79.038043484872, 78.813185210903, 78.588326890672, 78.363468526859, 78.138610121943, 77.913751678220, + 77.688893197814, 77.464034682701, 77.239176134715, 77.014317555565, 76.789458946841, 76.564600310030, + 76.339741646518, 76.114882957602, 75.890024244498, 75.665165508344, 75.440306750209, 75.215447971095, + 74.990589171946, 74.765730353650, 74.540871517041, 74.316012662908, 74.091153791995, 73.866294905004, + 73.641436002597, 73.416577085402, 73.191718154013, 72.966859208993, 72.742000250874, 72.517141280163, + 72.292282297339, 72.067423302858, 71.842564297155, 71.617705280640, 71.392846253707, 71.167987216729, + 70.943128170062, 70.718269114045, 70.493410049002, 70.268550975241, 70.043691893059, 69.818832802736, + 69.593973704543, 69.369114598736, 69.144255485563, 68.919396365260, 68.694537238053, 68.469678104158, + 68.244818963783, 68.019959817128, 67.795100664383, 67.570241505733, 67.345382341353, 67.120523171413, + 66.895663996075, 66.670804815496, 66.445945629826, 66.221086439211, 65.996227243789, 65.771368043695, + 65.546508839058, 65.321649630002, 65.096790416648, 64.871931199112, 64.647071977504, 64.422212751934, + 64.197353522504, 63.972494289316, 63.747635052466, 63.522775812048, 63.297916568152, 63.073057320866, + 62.848198070275, 62.623338816461, 62.398479559501, 62.173620299475, 61.948761036454, 61.723901770512, + 61.499042501718, 61.274183230138, 61.049323955840, 60.824464678885, 60.599605399335, 60.374746117249, + 60.149886832686, 59.925027545701, 59.700168256349, 59.475308964682, 59.250449670751, 59.025590374607, + 58.800731076297, 58.575871775869, 58.351012473367, 58.126153168837, 57.901293862321, 57.676434553861, + 57.451575243498, 57.226715931271, 57.001856617219, 56.776997301380, 56.552137983789, 56.327278664483, + 56.102419343496, 55.877560020861, 55.652700696612, 55.427841370780, 55.202982043397, 54.978122714492, + 54.753263384095, 54.528404052236, 54.303544718941, 54.078685384240, 53.853826048157, 53.628966710720, + 53.404107371953, 53.179248031881, 52.954388690530, 52.729529347921, 52.504670004079, 52.279810659026, + 52.054951312783, 51.830091965373, 51.605232616816, 51.380373267132, 51.155513916343, 50.930654564466, + 50.705795211522, 50.480935857528, 50.256076502504, 50.031217146467, 49.806357789435, 49.581498431424, + 49.356639072452, 49.131779712534, 48.906920351687, 48.682060989925, 48.457201627266, 48.232342263723, + 48.007482899311, 47.782623534045, 47.557764167938, 47.332904801005, 47.108045433258, 46.883186064711, + 46.658326695378, 46.433467325269, 46.208607954399, 45.983748582779, 45.758889210421, 45.534029837336, + 45.309170463537, 45.084311089034, 44.859451713839, 44.634592337961, 44.409732961412, 44.184873584203, + 43.960014206342, 43.735154827841, 43.510295448709, 43.285436068955, 43.060576688590, 42.835717307622, + 42.610857926060, 42.385998543914, 42.161139161191, 41.936279777901, 41.711420394052, 41.486561009653, + 41.261701624711, 41.036842239234, 40.811982853231, 40.587123466709, 40.362264079675, 40.137404692137, + 39.912545304103, 39.687685915579, 39.462826526572, 39.237967137090, 39.013107747139, 38.788248356727, + 38.563388965859, 38.338529574541, 38.113670182782, 37.888810790586, 37.663951397960, 37.439092004910, + 37.214232611441, 36.989373217561, 36.764513823274, 36.539654428586, 36.314795033503, 36.089935638030, + 35.865076242173, 35.640216845937, 35.415357449327, 35.190498052348, 34.965638655006, 34.740779257306, + 34.515919859252, 34.291060460849, 34.066201062102, 33.841341663016, 33.616482263595, 33.391622863845, + 33.166763463768, 32.941904063371, 32.717044662657, 32.492185261630, 32.267325860296, 32.042466458657, + 31.817607056718, 31.592747654483, 31.367888251957, 31.143028849143, 30.918169446044, 30.693310042666, + 30.468450639011, 30.243591235084, 30.018731830887, 29.793872426425, 29.569013021702, 29.344153616720, + 29.119294211484, 28.894434805996, 28.669575400260, 28.444715994280, 28.219856588059, 27.994997181599, + 27.770137774905, 27.545278367979, 27.320418960825, 27.095559553446, 26.870700145844, 26.645840738023, + 26.420981329986, 26.196121921735, 25.971262513275, 25.746403104606, 25.521543695733, 25.296684286658, + 25.071824877385, 24.846965467914, 24.622106058250, 24.397246648396, 24.172387238353, 23.947527828124, + 23.722668417712, 23.497809007120, 23.272949596350, 23.048090185404, 22.823230774285, 22.598371362996, + 22.373511951538, 22.148652539915, 21.923793128129, 21.698933716181, 21.474074304075, 21.249214891812, + 21.024355479395, 20.799496066827, 20.574636654109, 20.349777241243, 20.124917828232, 19.900058415078, + 19.675199001783, 19.450339588349, 19.225480174778, 19.000620761073, 18.775761347235, 18.550901933267, + 18.326042519170, 18.101183104946, 17.876323690598, 17.651464276127, 17.426604861536, 17.201745446826, + 16.976886031999, 16.752026617057, 16.527167202002, 16.302307786836, 16.077448371561, 15.852588956178, + 15.627729540690, 15.402870125097, 15.178010709403, 14.953151293609, 14.728291877716, 14.503432461726, + 14.278573045641, 14.053713629463, 13.828854213193, 13.603994796833, 13.379135380386, 13.154275963851, + 12.929416547232, 12.704557130530, 12.479697713746, 12.254838296882, 12.029978879940, 11.805119462921, + 11.580260045827, 11.355400628659, 11.130541211420, 10.905681794110, 10.680822376731, 10.455962959286, + 10.231103541774, 10.006244124198, 9.781384706560, 9.556525288861, 9.331665871102, 9.106806453284, + 8.881947035411, 8.657087617482, 8.432228199499, 8.207368781465, 7.982509363379, 7.757649945245, + 7.532790527062, 7.307931108834, 7.083071690560, 6.858212272243, 6.633352853884, 6.408493435484, + 6.183634017046, 5.958774598569, 5.733915180056, 5.509055761509, 5.284196342927, 5.059336924314, + 4.834477505670, 4.609618086996, 4.384758668295, 4.159899249567, 3.935039830814, 3.710180412037, + 3.485320993238, 3.260461574418, 3.035602155578, 2.810742736719, 2.585883317844, 2.361023898953, + 2.136164480048, 1.911305061130, 1.686445642201, 1.461586223261, 1.236726804313, 1.011867385357, + 0.787007966395, 0.562148547428, 0.337289128458, 0.112429709486 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N4000.cc b/src/atlas/grid/detail/spacing/gaussian/N4000.cc index a29ec91a4..7f707d18b 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N4000.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N4000.cc @@ -7,811 +7,668 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(4000,LIST( - 89.982777782041, 89.960467823498, 89.938026112601, 89.915554633223, 89.893071861958, - 89.870583626524, 89.848092337395, 89.825599170237, 89.803104766281, 89.780609504838, - 89.758113624578, 89.735617283150, 89.713120588868, 89.690623618599, 89.668126428400, - 89.645629060112, 89.623131545602, 89.600633909559, 89.578136171413, 89.555638346662, - 89.533140447819, 89.510642485097, 89.488144466917, 89.465646400278, 89.443148291053, - 89.420650144201, 89.398151963940, 89.375653753880, 89.353155517131, 89.330657256382, - 89.308158973974, 89.285660671954, 89.263162352116, 89.240664016047, 89.218165665144, - 89.195667300653, 89.173168923684, 89.150670535227, 89.128172136173, 89.105673727319, - 89.083175309389, 89.060676883034, 89.038178448845, 89.015680007358, 88.993181559065, - 88.970683104410, 88.948184643801, 88.925686177614, 88.903187706190, 88.880689229847, - 88.858190748874, 88.835692263540, 88.813193774093, 88.790695280762, 88.768196783761, - 88.745698283287, 88.723199779523, 88.700701272640, 88.678202762798, 88.655704250144, - 88.633205734819, 88.610707216951, 88.588208696663, 88.565710174068, 88.543211649272, - 88.520713122378, 88.498214593477, 88.475716062661, 88.453217530011, 88.430718995608, - 88.408220459525, 88.385721921832, 88.363223382596, 88.340724841881, 88.318226299744, - 88.295727756243, 88.273229211430, 88.250730665357, 88.228232118071, 88.205733569618, - 88.183235020041, 88.160736469382, 88.138237917679, 88.115739364971, 88.093240811293, - 88.070742256678, 88.048243701159, 88.025745144768, 88.003246587532, 87.980748029482, - 87.958249470643, 87.935750911042, 87.913252350702, 87.890753789648, 87.868255227903, - 87.845756665488, 87.823258102423, 87.800759538729, 87.778260974425, 87.755762409529, - 87.733263844059, 87.710765278031, 87.688266711463, 87.665768144369, 87.643269576765, - 87.620771008664, 87.598272440082, 87.575773871032, 87.553275301526, 87.530776731576, - 87.508278161196, 87.485779590396, 87.463281019188, 87.440782447582, 87.418283875589, - 87.395785303218, 87.373286730480, 87.350788157385, 87.328289583939, 87.305791010154, - 87.283292436037, 87.260793861596, 87.238295286839, 87.215796711774, 87.193298136408, - 87.170799560749, 87.148300984803, 87.125802408577, 87.103303832079, 87.080805255312, - 87.058306678285, 87.035808101003, 87.013309523472, 86.990810945697, 86.968312367684, - 86.945813789438, 86.923315210965, 86.900816632268, 86.878318053353, 86.855819474226, - 86.833320894889, 86.810822315347, 86.788323735606, 86.765825155669, 86.743326575540, - 86.720827995223, 86.698329414722, 86.675830834040, 86.653332253182, 86.630833672151, - 86.608335090950, 86.585836509583, 86.563337928052, 86.540839346362, 86.518340764515, - 86.495842182514, 86.473343600362, 86.450845018063, 86.428346435618, 86.405847853031, - 86.383349270303, 86.360850687439, 86.338352104440, 86.315853521309, 86.293354938048, - 86.270856354659, 86.248357771146, 86.225859187509, 86.203360603752, 86.180862019876, - 86.158363435884, 86.135864851777, 86.113366267558, 86.090867683228, 86.068369098789, - 86.045870514244, 86.023371929594, 86.000873344840, 85.978374759985, 85.955876175031, - 85.933377589978, 85.910879004828, 85.888380419584, 85.865881834246, 85.843383248817, - 85.820884663297, 85.798386077688, 85.775887491991, 85.753388906209, 85.730890320342, - 85.708391734391, 85.685893148358, 85.663394562245, 85.640895976052, 85.618397389780, - 85.595898803431, 85.573400217007, 85.550901630507, 85.528403043934, 85.505904457288, - 85.483405870571, 85.460907283783, 85.438408696926, 85.415910110001, 85.393411523008, - 85.370912935948, 85.348414348824, 85.325915761635, 85.303417174382, 85.280918587066, - 85.258419999689, 85.235921412251, 85.213422824753, 85.190924237196, 85.168425649580, - 85.145927061907, 85.123428474177, 85.100929886391, 85.078431298550, 85.055932710655, - 85.033434122705, 85.010935534703, 84.988436946649, 84.965938358543, 84.943439770386, - 84.920941182179, 84.898442593922, 84.875944005617, 84.853445417263, 84.830946828862, - 84.808448240413, 84.785949651918, 84.763451063378, 84.740952474792, 84.718453886162, - 84.695955297487, 84.673456708770, 84.650958120009, 84.628459531205, 84.605960942360, - 84.583462353474, 84.560963764546, 84.538465175579, 84.515966586571, 84.493467997524, - 84.470969408439, 84.448470819315, 84.425972230153, 84.403473640953, 84.380975051717, - 84.358476462443, 84.335977873134, 84.313479283789, 84.290980694409, 84.268482104994, - 84.245983515544, 84.223484926060, 84.200986336543, 84.178487746992, 84.155989157409, - 84.133490567792, 84.110991978144, 84.088493388464, 84.065994798753, 84.043496209010, - 84.020997619237, 83.998499029433, 83.976000439600, 83.953501849737, 83.931003259844, - 83.908504669922, 83.886006079972, 83.863507489993, 83.841008899986, 83.818510309952, - 83.796011719889, 83.773513129800, 83.751014539684, 83.728515949541, 83.706017359372, - 83.683518769177, 83.661020178956, 83.638521588710, 83.616022998438, 83.593524408141, - 83.571025817820, 83.548527227475, 83.526028637105, 83.503530046711, 83.481031456294, - 83.458532865853, 83.436034275389, 83.413535684902, 83.391037094392, 83.368538503860, - 83.346039913306, 83.323541322729, 83.301042732131, 83.278544141511, 83.256045550870, - 83.233546960207, 83.211048369524, 83.188549778820, 83.166051188095, 83.143552597351, - 83.121054006585, 83.098555415800, 83.076056824996, 83.053558234171, 83.031059643328, - 83.008561052465, 82.986062461583, 82.963563870682, 82.941065279763, 82.918566688825, - 82.896068097869, 82.873569506895, 82.851070915903, 82.828572324893, 82.806073733866, - 82.783575142821, 82.761076551759, 82.738577960680, 82.716079369584, 82.693580778471, - 82.671082187341, 82.648583596195, 82.626085005032, 82.603586413854, 82.581087822659, - 82.558589231449, 82.536090640222, 82.513592048980, 82.491093457723, 82.468594866450, - 82.446096275163, 82.423597683860, 82.401099092542, 82.378600501209, 82.356101909862, - 82.333603318500, 82.311104727124, 82.288606135733, 82.266107544328, 82.243608952910, - 82.221110361477, 82.198611770031, 82.176113178570, 82.153614587097, 82.131115995610, - 82.108617404109, 82.086118812596, 82.063620221069, 82.041121629529, 82.018623037977, - 81.996124446412, 81.973625854834, 81.951127263243, 81.928628671640, 81.906130080025, - 81.883631488397, 81.861132896757, 81.838634305106, 81.816135713442, 81.793637121767, - 81.771138530079, 81.748639938380, 81.726141346670, 81.703642754948, 81.681144163215, - 81.658645571470, 81.636146979714, 81.613648387948, 81.591149796170, 81.568651204381, - 81.546152612581, 81.523654020771, 81.501155428950, 81.478656837119, 81.456158245277, - 81.433659653424, 81.411161061561, 81.388662469688, 81.366163877805, 81.343665285912, - 81.321166694009, 81.298668102095, 81.276169510172, 81.253670918240, 81.231172326297, - 81.208673734345, 81.186175142383, 81.163676550412, 81.141177958431, 81.118679366442, - 81.096180774442, 81.073682182434, 81.051183590416, 81.028684998390, 81.006186406354, - 80.983687814310, 80.961189222257, 80.938690630195, 80.916192038124, 80.893693446044, - 80.871194853956, 80.848696261860, 80.826197669754, 80.803699077641, 80.781200485519, - 80.758701893389, 80.736203301251, 80.713704709104, 80.691206116950, 80.668707524787, - 80.646208932616, 80.623710340438, 80.601211748251, 80.578713156057, 80.556214563855, - 80.533715971645, 80.511217379428, 80.488718787203, 80.466220194970, 80.443721602730, - 80.421223010483, 80.398724418228, 80.376225825966, 80.353727233696, 80.331228641420, - 80.308730049136, 80.286231456845, 80.263732864547, 80.241234272242, 80.218735679930, - 80.196237087611, 80.173738495285, 80.151239902952, 80.128741310612, 80.106242718266, - 80.083744125913, 80.061245533554, 80.038746941187, 80.016248348815, 79.993749756435, - 79.971251164049, 79.948752571657, 79.926253979258, 79.903755386853, 79.881256794442, - 79.858758202025, 79.836259609601, 79.813761017171, 79.791262424735, 79.768763832293, - 79.746265239844, 79.723766647390, 79.701268054930, 79.678769462464, 79.656270869991, - 79.633772277514, 79.611273685030, 79.588775092540, 79.566276500045, 79.543777907544, - 79.521279315037, 79.498780722525, 79.476282130007, 79.453783537483, 79.431284944954, - 79.408786352420, 79.386287759879, 79.363789167334, 79.341290574783, 79.318791982227, - 79.296293389665, 79.273794797099, 79.251296204526, 79.228797611949, 79.206299019367, - 79.183800426779, 79.161301834186, 79.138803241588, 79.116304648985, 79.093806056377, - 79.071307463764, 79.048808871146, 79.026310278523, 79.003811685896, 78.981313093263, - 78.958814500625, 78.936315907983, 78.913817315336, 78.891318722684, 78.868820130027, - 78.846321537366, 78.823822944700, 78.801324352029, 78.778825759354, 78.756327166674, - 78.733828573989, 78.711329981300, 78.688831388607, 78.666332795909, 78.643834203206, - 78.621335610500, 78.598837017788, 78.576338425073, 78.553839832353, 78.531341239628, - 78.508842646900, 78.486344054167, 78.463845461429, 78.441346868688, 78.418848275942, - 78.396349683193, 78.373851090439, 78.351352497681, 78.328853904918, 78.306355312152, - 78.283856719382, 78.261358126607, 78.238859533829, 78.216360941047, 78.193862348260, - 78.171363755470, 78.148865162676, 78.126366569878, 78.103867977076, 78.081369384270, - 78.058870791460, 78.036372198647, 78.013873605830, 77.991375013009, 77.968876420184, - 77.946377827355, 77.923879234523, 77.901380641687, 77.878882048848, 77.856383456004, - 77.833884863158, 77.811386270307, 77.788887677453, 77.766389084596, 77.743890491735, - 77.721391898870, 77.698893306002, 77.676394713130, 77.653896120255, 77.631397527376, - 77.608898934494, 77.586400341609, 77.563901748720, 77.541403155828, 77.518904562933, - 77.496405970034, 77.473907377132, 77.451408784226, 77.428910191317, 77.406411598405, - 77.383913005490, 77.361414412572, 77.338915819650, 77.316417226725, 77.293918633797, - 77.271420040866, 77.248921447931, 77.226422854994, 77.203924262053, 77.181425669109, - 77.158927076162, 77.136428483213, 77.113929890260, 77.091431297304, 77.068932704345, - 77.046434111383, 77.023935518418, 77.001436925450, 76.978938332479, 76.956439739505, - 76.933941146528, 76.911442553549, 76.888943960566, 76.866445367581, 76.843946774592, - 76.821448181601, 76.798949588607, 76.776450995610, 76.753952402611, 76.731453809608, - 76.708955216603, 76.686456623595, 76.663958030584, 76.641459437571, 76.618960844555, - 76.596462251536, 76.573963658514, 76.551465065490, 76.528966472463, 76.506467879434, - 76.483969286401, 76.461470693367, 76.438972100329, 76.416473507289, 76.393974914246, - 76.371476321201, 76.348977728153, 76.326479135103, 76.303980542050, 76.281481948995, - 76.258983355937, 76.236484762876, 76.213986169813, 76.191487576748, 76.168988983680, - 76.146490390610, 76.123991797537, 76.101493204462, 76.078994611385, 76.056496018304, - 76.033997425222, 76.011498832137, 75.989000239050, 75.966501645961, 75.944003052869, - 75.921504459775, 75.899005866678, 75.876507273579, 75.854008680478, 75.831510087375, - 75.809011494269, 75.786512901161, 75.764014308051, 75.741515714939, 75.719017121824, - 75.696518528707, 75.674019935588, 75.651521342466, 75.629022749343, 75.606524156217, - 75.584025563089, 75.561526969959, 75.539028376827, 75.516529783692, 75.494031190556, - 75.471532597417, 75.449034004276, 75.426535411134, 75.404036817989, 75.381538224842, - 75.359039631692, 75.336541038541, 75.314042445388, 75.291543852233, 75.269045259075, - 75.246546665916, 75.224048072755, 75.201549479591, 75.179050886426, 75.156552293258, - 75.134053700089, 75.111555106918, 75.089056513744, 75.066557920569, 75.044059327392, - 75.021560734213, 74.999062141031, 74.976563547848, 74.954064954664, 74.931566361477, - 74.909067768288, 74.886569175097, 74.864070581905, 74.841571988710, 74.819073395514, - 74.796574802316, 74.774076209116, 74.751577615914, 74.729079022711, 74.706580429505, - 74.684081836298, 74.661583243089, 74.639084649878, 74.616586056666, 74.594087463451, - 74.571588870235, 74.549090277017, 74.526591683797, 74.504093090576, 74.481594497353, - 74.459095904128, 74.436597310901, 74.414098717673, 74.391600124442, 74.369101531211, - 74.346602937977, 74.324104344742, 74.301605751505, 74.279107158266, 74.256608565026, - 74.234109971784, 74.211611378541, 74.189112785296, 74.166614192049, 74.144115598800, - 74.121617005550, 74.099118412298, 74.076619819045, 74.054121225790, 74.031622632533, - 74.009124039275, 73.986625446016, 73.964126852754, 73.941628259491, 73.919129666227, - 73.896631072961, 73.874132479693, 73.851633886424, 73.829135293154, 73.806636699881, - 73.784138106608, 73.761639513332, 73.739140920056, 73.716642326777, 73.694143733498, - 73.671645140216, 73.649146546934, 73.626647953649, 73.604149360364, 73.581650767077, - 73.559152173788, 73.536653580498, 73.514154987206, 73.491656393913, 73.469157800619, - 73.446659207323, 73.424160614026, 73.401662020727, 73.379163427427, 73.356664834125, - 73.334166240822, 73.311667647518, 73.289169054212, 73.266670460905, 73.244171867596, - 73.221673274286, 73.199174680975, 73.176676087662, 73.154177494348, 73.131678901033, - 73.109180307716, 73.086681714398, 73.064183121079, 73.041684527758, 73.019185934436, - 72.996687341112, 72.974188747788, 72.951690154462, 72.929191561134, 72.906692967806, - 72.884194374476, 72.861695781144, 72.839197187812, 72.816698594478, 72.794200001143, - 72.771701407806, 72.749202814469, 72.726704221130, 72.704205627790, 72.681707034448, - 72.659208441106, 72.636709847762, 72.614211254416, 72.591712661070, 72.569214067722, - 72.546715474374, 72.524216881024, 72.501718287672, 72.479219694320, 72.456721100966, - 72.434222507611, 72.411723914255, 72.389225320898, 72.366726727539, 72.344228134180, - 72.321729540819, 72.299230947457, 72.276732354094, 72.254233760729, 72.231735167364, - 72.209236573997, 72.186737980629, 72.164239387260, 72.141740793890, 72.119242200519, - 72.096743607146, 72.074245013773, 72.051746420398, 72.029247827023, 72.006749233646, - 71.984250640268, 71.961752046889, 71.939253453508, 71.916754860127, 71.894256266745, - 71.871757673361, 71.849259079977, 71.826760486591, 71.804261893204, 71.781763299816, - 71.759264706427, 71.736766113037, 71.714267519646, 71.691768926254, 71.669270332861, - 71.646771739467, 71.624273146072, 71.601774552675, 71.579275959278, 71.556777365880, - 71.534278772480, 71.511780179080, 71.489281585678, 71.466782992276, 71.444284398872, - 71.421785805468, 71.399287212062, 71.376788618656, 71.354290025248, 71.331791431840, - 71.309292838430, 71.286794245020, 71.264295651608, 71.241797058196, 71.219298464782, - 71.196799871368, 71.174301277952, 71.151802684536, 71.129304091118, 71.106805497700, - 71.084306904281, 71.061808310860, 71.039309717439, 71.016811124017, 70.994312530594, - 70.971813937170, 70.949315343745, 70.926816750319, 70.904318156892, 70.881819563464, - 70.859320970035, 70.836822376606, 70.814323783175, 70.791825189744, 70.769326596311, - 70.746828002878, 70.724329409444, 70.701830816008, 70.679332222572, 70.656833629135, - 70.634335035698, 70.611836442259, 70.589337848819, 70.566839255379, 70.544340661937, - 70.521842068495, 70.499343475052, 70.476844881608, 70.454346288163, 70.431847694717, - 70.409349101270, 70.386850507823, 70.364351914375, 70.341853320925, 70.319354727475, - 70.296856134024, 70.274357540573, 70.251858947120, 70.229360353667, 70.206861760212, - 70.184363166757, 70.161864573301, 70.139365979844, 70.116867386387, 70.094368792928, - 70.071870199469, 70.049371606009, 70.026873012548, 70.004374419086, 69.981875825624, - 69.959377232160, 69.936878638696, 69.914380045231, 69.891881451766, 69.869382858299, - 69.846884264832, 69.824385671364, 69.801887077895, 69.779388484425, 69.756889890954, - 69.734391297483, 69.711892704011, 69.689394110538, 69.666895517065, 69.644396923590, - 69.621898330115, 69.599399736639, 69.576901143163, 69.554402549685, 69.531903956207, - 69.509405362728, 69.486906769248, 69.464408175768, 69.441909582287, 69.419410988805, - 69.396912395322, 69.374413801839, 69.351915208354, 69.329416614870, 69.306918021384, - 69.284419427897, 69.261920834410, 69.239422240923, 69.216923647434, 69.194425053945, - 69.171926460455, 69.149427866964, 69.126929273473, 69.104430679980, 69.081932086488, - 69.059433492994, 69.036934899500, 69.014436306005, 68.991937712509, 68.969439119013, - 68.946940525516, 68.924441932018, 68.901943338519, 68.879444745020, 68.856946151521, - 68.834447558020, 68.811948964519, 68.789450371017, 68.766951777514, 68.744453184011, - 68.721954590507, 68.699455997003, 68.676957403497, 68.654458809991, 68.631960216485, - 68.609461622978, 68.586963029470, 68.564464435961, 68.541965842452, 68.519467248942, - 68.496968655431, 68.474470061920, 68.451971468408, 68.429472874896, 68.406974281383, - 68.384475687869, 68.361977094355, 68.339478500839, 68.316979907324, 68.294481313807, - 68.271982720290, 68.249484126773, 68.226985533255, 68.204486939736, 68.181988346216, - 68.159489752696, 68.136991159175, 68.114492565654, 68.091993972132, 68.069495378609, - 68.046996785086, 68.024498191562, 68.001999598038, 67.979501004513, 67.957002410987, - 67.934503817461, 67.912005223934, 67.889506630407, 67.867008036879, 67.844509443350, - 67.822010849821, 67.799512256291, 67.777013662761, 67.754515069230, 67.732016475698, - 67.709517882166, 67.687019288633, 67.664520695100, 67.642022101566, 67.619523508031, - 67.597024914496, 67.574526320960, 67.552027727424, 67.529529133887, 67.507030540350, - 67.484531946812, 67.462033353273, 67.439534759734, 67.417036166195, 67.394537572654, - 67.372038979113, 67.349540385572, 67.327041792030, 67.304543198488, 67.282044604945, - 67.259546011401, 67.237047417857, 67.214548824312, 67.192050230767, 67.169551637221, - 67.147053043675, 67.124554450128, 67.102055856581, 67.079557263033, 67.057058669484, - 67.034560075935, 67.012061482386, 66.989562888836, 66.967064295285, 66.944565701734, - 66.922067108182, 66.899568514630, 66.877069921077, 66.854571327524, 66.832072733970, - 66.809574140416, 66.787075546861, 66.764576953306, 66.742078359750, 66.719579766194, - 66.697081172637, 66.674582579080, 66.652083985522, 66.629585391963, 66.607086798404, - 66.584588204845, 66.562089611285, 66.539591017725, 66.517092424164, 66.494593830602, - 66.472095237040, 66.449596643478, 66.427098049915, 66.404599456352, 66.382100862788, - 66.359602269223, 66.337103675658, 66.314605082093, 66.292106488527, 66.269607894961, - 66.247109301394, 66.224610707827, 66.202112114259, 66.179613520691, 66.157114927122, - 66.134616333553, 66.112117739983, 66.089619146413, 66.067120552842, 66.044621959271, - 66.022123365699, 65.999624772127, 65.977126178555, 65.954627584982, 65.932128991408, - 65.909630397834, 65.887131804260, 65.864633210685, 65.842134617110, 65.819636023534, - 65.797137429958, 65.774638836381, 65.752140242804, 65.729641649226, 65.707143055648, - 65.684644462070, 65.662145868491, 65.639647274911, 65.617148681331, 65.594650087751, - 65.572151494170, 65.549652900589, 65.527154307008, 65.504655713425, 65.482157119843, - 65.459658526260, 65.437159932677, 65.414661339093, 65.392162745508, 65.369664151924, - 65.347165558339, 65.324666964753, 65.302168371167, 65.279669777581, 65.257171183994, - 65.234672590406, 65.212173996819, 65.189675403231, 65.167176809642, 65.144678216053, - 65.122179622464, 65.099681028874, 65.077182435284, 65.054683841693, 65.032185248102, - 65.009686654510, 64.987188060918, 64.964689467326, 64.942190873733, 64.919692280140, - 64.897193686547, 64.874695092953, 64.852196499358, 64.829697905764, 64.807199312168, - 64.784700718573, 64.762202124977, 64.739703531380, 64.717204937784, 64.694706344186, - 64.672207750589, 64.649709156991, 64.627210563392, 64.604711969793, 64.582213376194, - 64.559714782595, 64.537216188995, 64.514717595394, 64.492219001794, 64.469720408192, - 64.447221814591, 64.424723220989, 64.402224627387, 64.379726033784, 64.357227440181, - 64.334728846577, 64.312230252974, 64.289731659369, 64.267233065765, 64.244734472160, - 64.222235878554, 64.199737284949, 64.177238691342, 64.154740097736, 64.132241504129, - 64.109742910522, 64.087244316914, 64.064745723306, 64.042247129698, 64.019748536089, - 63.997249942480, 63.974751348870, 63.952252755261, 63.929754161650, 63.907255568040, - 63.884756974429, 63.862258380818, 63.839759787206, 63.817261193594, 63.794762599982, - 63.772264006369, 63.749765412756, 63.727266819142, 63.704768225528, 63.682269631914, - 63.659771038300, 63.637272444685, 63.614773851070, 63.592275257454, 63.569776663838, - 63.547278070222, 63.524779476605, 63.502280882988, 63.479782289371, 63.457283695753, - 63.434785102135, 63.412286508517, 63.389787914898, 63.367289321279, 63.344790727660, - 63.322292134040, 63.299793540420, 63.277294946799, 63.254796353178, 63.232297759557, - 63.209799165936, 63.187300572314, 63.164801978692, 63.142303385070, 63.119804791447, - 63.097306197824, 63.074807604200, 63.052309010576, 63.029810416952, 63.007311823328, - 62.984813229703, 62.962314636078, 62.939816042453, 62.917317448827, 62.894818855201, - 62.872320261574, 62.849821667948, 62.827323074321, 62.804824480693, 62.782325887066, - 62.759827293438, 62.737328699809, 62.714830106181, 62.692331512552, 62.669832918922, - 62.647334325293, 62.624835731663, 62.602337138033, 62.579838544402, 62.557339950771, - 62.534841357140, 62.512342763509, 62.489844169877, 62.467345576245, 62.444846982612, - 62.422348388979, 62.399849795346, 62.377351201713, 62.354852608079, 62.332354014446, - 62.309855420811, 62.287356827177, 62.264858233542, 62.242359639907, 62.219861046271, - 62.197362452635, 62.174863858999, 62.152365265363, 62.129866671726, 62.107368078089, - 62.084869484452, 62.062370890814, 62.039872297177, 62.017373703538, 61.994875109900, - 61.972376516261, 61.949877922622, 61.927379328983, 61.904880735343, 61.882382141703, - 61.859883548063, 61.837384954423, 61.814886360782, 61.792387767141, 61.769889173499, - 61.747390579858, 61.724891986216, 61.702393392573, 61.679894798931, 61.657396205288, - 61.634897611645, 61.612399018002, 61.589900424358, 61.567401830714, 61.544903237070, - 61.522404643425, 61.499906049781, 61.477407456136, 61.454908862490, 61.432410268845, - 61.409911675199, 61.387413081553, 61.364914487906, 61.342415894260, 61.319917300613, - 61.297418706965, 61.274920113318, 61.252421519670, 61.229922926022, 61.207424332374, - 61.184925738725, 61.162427145076, 61.139928551427, 61.117429957777, 61.094931364128, - 61.072432770478, 61.049934176828, 61.027435583177, 61.004936989526, 60.982438395875, - 60.959939802224, 60.937441208572, 60.914942614921, 60.892444021269, 60.869945427616, - 60.847446833964, 60.824948240311, 60.802449646658, 60.779951053004, 60.757452459351, - 60.734953865697, 60.712455272043, 60.689956678388, 60.667458084733, 60.644959491079, - 60.622460897423, 60.599962303768, 60.577463710112, 60.554965116456, 60.532466522800, - 60.509967929144, 60.487469335487, 60.464970741830, 60.442472148173, 60.419973554515, - 60.397474960858, 60.374976367200, 60.352477773541, 60.329979179883, 60.307480586224, - 60.284981992565, 60.262483398906, 60.239984805247, 60.217486211587, 60.194987617927, - 60.172489024267, 60.149990430607, 60.127491836946, 60.104993243285, 60.082494649624, - 60.059996055963, 60.037497462301, 60.014998868639, 59.992500274977, 59.970001681315, - 59.947503087652, 59.925004493989, 59.902505900326, 59.880007306663, 59.857508712999, - 59.835010119336, 59.812511525672, 59.790012932007, 59.767514338343, 59.745015744678, - 59.722517151013, 59.700018557348, 59.677519963683, 59.655021370017, 59.632522776351, - 59.610024182685, 59.587525589019, 59.565026995352, 59.542528401686, 59.520029808019, - 59.497531214351, 59.475032620684, 59.452534027016, 59.430035433348, 59.407536839680, - 59.385038246012, 59.362539652343, 59.340041058674, 59.317542465005, 59.295043871336, - 59.272545277667, 59.250046683997, 59.227548090327, 59.205049496657, 59.182550902986, - 59.160052309316, 59.137553715645, 59.115055121974, 59.092556528303, 59.070057934631, - 59.047559340960, 59.025060747288, 59.002562153616, 58.980063559943, 58.957564966271, - 58.935066372598, 58.912567778925, 58.890069185252, 58.867570591578, 58.845071997905, - 58.822573404231, 58.800074810557, 58.777576216883, 58.755077623208, 58.732579029533, - 58.710080435859, 58.687581842183, 58.665083248508, 58.642584654833, 58.620086061157, - 58.597587467481, 58.575088873805, 58.552590280128, 58.530091686452, 58.507593092775, - 58.485094499098, 58.462595905421, 58.440097311744, 58.417598718066, 58.395100124388, - 58.372601530710, 58.350102937032, 58.327604343353, 58.305105749675, 58.282607155996, - 58.260108562317, 58.237609968638, 58.215111374958, 58.192612781279, 58.170114187599, - 58.147615593919, 58.125117000239, 58.102618406558, 58.080119812878, 58.057621219197, - 58.035122625516, 58.012624031835, 57.990125438153, 57.967626844472, 57.945128250790, - 57.922629657108, 57.900131063426, 57.877632469743, 57.855133876061, 57.832635282378, - 57.810136688695, 57.787638095012, 57.765139501328, 57.742640907645, 57.720142313961, - 57.697643720277, 57.675145126593, 57.652646532909, 57.630147939224, 57.607649345540, - 57.585150751855, 57.562652158170, 57.540153564484, 57.517654970799, 57.495156377113, - 57.472657783427, 57.450159189741, 57.427660596055, 57.405162002369, 57.382663408682, - 57.360164814995, 57.337666221309, 57.315167627621, 57.292669033934, 57.270170440247, - 57.247671846559, 57.225173252871, 57.202674659183, 57.180176065495, 57.157677471806, - 57.135178878118, 57.112680284429, 57.090181690740, 57.067683097051, 57.045184503362, - 57.022685909672, 57.000187315982, 56.977688722293, 56.955190128603, 56.932691534912, - 56.910192941222, 56.887694347531, 56.865195753841, 56.842697160150, 56.820198566459, - 56.797699972767, 56.775201379076, 56.752702785384, 56.730204191692, 56.707705598001, - 56.685207004308, 56.662708410616, 56.640209816924, 56.617711223231, 56.595212629538, - 56.572714035845, 56.550215442152, 56.527716848458, 56.505218254765, 56.482719661071, - 56.460221067377, 56.437722473683, 56.415223879989, 56.392725286295, 56.370226692600, - 56.347728098905, 56.325229505211, 56.302730911515, 56.280232317820, 56.257733724125, - 56.235235130429, 56.212736536734, 56.190237943038, 56.167739349342, 56.145240755645, - 56.122742161949, 56.100243568252, 56.077744974556, 56.055246380859, 56.032747787162, - 56.010249193465, 55.987750599767, 55.965252006070, 55.942753412372, 55.920254818674, - 55.897756224976, 55.875257631278, 55.852759037579, 55.830260443881, 55.807761850182, - 55.785263256483, 55.762764662784, 55.740266069085, 55.717767475386, 55.695268881686, - 55.672770287987, 55.650271694287, 55.627773100587, 55.605274506887, 55.582775913187, - 55.560277319486, 55.537778725786, 55.515280132085, 55.492781538384, 55.470282944683, - 55.447784350982, 55.425285757280, 55.402787163579, 55.380288569877, 55.357789976175, - 55.335291382473, 55.312792788771, 55.290294195069, 55.267795601366, 55.245297007664, - 55.222798413961, 55.200299820258, 55.177801226555, 55.155302632852, 55.132804039148, - 55.110305445445, 55.087806851741, 55.065308258037, 55.042809664333, 55.020311070629, - 54.997812476925, 54.975313883221, 54.952815289516, 54.930316695811, 54.907818102107, - 54.885319508401, 54.862820914696, 54.840322320991, 54.817823727286, 54.795325133580, - 54.772826539874, 54.750327946168, 54.727829352462, 54.705330758756, 54.682832165050, - 54.660333571343, 54.637834977637, 54.615336383930, 54.592837790223, 54.570339196516, - 54.547840602809, 54.525342009101, 54.502843415394, 54.480344821686, 54.457846227978, - 54.435347634270, 54.412849040562, 54.390350446854, 54.367851853146, 54.345353259437, - 54.322854665729, 54.300356072020, 54.277857478311, 54.255358884602, 54.232860290893, - 54.210361697183, 54.187863103474, 54.165364509764, 54.142865916054, 54.120367322344, - 54.097868728634, 54.075370134924, 54.052871541214, 54.030372947503, 54.007874353793, - 53.985375760082, 53.962877166371, 53.940378572660, 53.917879978949, 53.895381385238, - 53.872882791526, 53.850384197815, 53.827885604103, 53.805387010391, 53.782888416679, - 53.760389822967, 53.737891229255, 53.715392635543, 53.692894041830, 53.670395448118, - 53.647896854405, 53.625398260692, 53.602899666979, 53.580401073266, 53.557902479552, - 53.535403885839, 53.512905292125, 53.490406698412, 53.467908104698, 53.445409510984, - 53.422910917270, 53.400412323556, 53.377913729841, 53.355415136127, 53.332916542412, - 53.310417948697, 53.287919354983, 53.265420761268, 53.242922167552, 53.220423573837, - 53.197924980122, 53.175426386406, 53.152927792691, 53.130429198975, 53.107930605259, - 53.085432011543, 53.062933417827, 53.040434824110, 53.017936230394, 52.995437636678, - 52.972939042961, 52.950440449244, 52.927941855527, 52.905443261810, 52.882944668093, - 52.860446074376, 52.837947480658, 52.815448886941, 52.792950293223, 52.770451699505, - 52.747953105787, 52.725454512069, 52.702955918351, 52.680457324633, 52.657958730914, - 52.635460137196, 52.612961543477, 52.590462949759, 52.567964356040, 52.545465762321, - 52.522967168601, 52.500468574882, 52.477969981163, 52.455471387443, 52.432972793724, - 52.410474200004, 52.387975606284, 52.365477012564, 52.342978418844, 52.320479825124, - 52.297981231403, 52.275482637683, 52.252984043962, 52.230485450242, 52.207986856521, - 52.185488262800, 52.162989669079, 52.140491075358, 52.117992481636, 52.095493887915, - 52.072995294193, 52.050496700472, 52.027998106750, 52.005499513028, 51.983000919306, - 51.960502325584, 51.938003731862, 51.915505138139, 51.893006544417, 51.870507950694, - 51.848009356972, 51.825510763249, 51.803012169526, 51.780513575803, 51.758014982080, - 51.735516388357, 51.713017794633, 51.690519200910, 51.668020607186, 51.645522013462, - 51.623023419738, 51.600524826015, 51.578026232290, 51.555527638566, 51.533029044842, - 51.510530451118, 51.488031857393, 51.465533263668, 51.443034669944, 51.420536076219, - 51.398037482494, 51.375538888769, 51.353040295044, 51.330541701318, 51.308043107593, - 51.285544513868, 51.263045920142, 51.240547326416, 51.218048732690, 51.195550138964, - 51.173051545238, 51.150552951512, 51.128054357786, 51.105555764059, 51.083057170333, - 51.060558576606, 51.038059982880, 51.015561389153, 50.993062795426, 50.970564201699, - 50.948065607972, 50.925567014245, 50.903068420517, 50.880569826790, 50.858071233062, - 50.835572639334, 50.813074045607, 50.790575451879, 50.768076858151, 50.745578264423, - 50.723079670695, 50.700581076966, 50.678082483238, 50.655583889509, 50.633085295781, - 50.610586702052, 50.588088108323, 50.565589514594, 50.543090920865, 50.520592327136, - 50.498093733407, 50.475595139677, 50.453096545948, 50.430597952218, 50.408099358489, - 50.385600764759, 50.363102171029, 50.340603577299, 50.318104983569, 50.295606389839, - 50.273107796109, 50.250609202378, 50.228110608648, 50.205612014917, 50.183113421187, - 50.160614827456, 50.138116233725, 50.115617639994, 50.093119046263, 50.070620452532, - 50.048121858800, 50.025623265069, 50.003124671337, 49.980626077606, 49.958127483874, - 49.935628890142, 49.913130296411, 49.890631702679, 49.868133108946, 49.845634515214, - 49.823135921482, 49.800637327750, 49.778138734017, 49.755640140285, 49.733141546552, - 49.710642952819, 49.688144359086, 49.665645765353, 49.643147171620, 49.620648577887, - 49.598149984154, 49.575651390421, 49.553152796687, 49.530654202954, 49.508155609220, - 49.485657015486, 49.463158421752, 49.440659828018, 49.418161234284, 49.395662640550, - 49.373164046816, 49.350665453082, 49.328166859347, 49.305668265613, 49.283169671878, - 49.260671078144, 49.238172484409, 49.215673890674, 49.193175296939, 49.170676703204, - 49.148178109469, 49.125679515734, 49.103180921998, 49.080682328263, 49.058183734527, - 49.035685140792, 49.013186547056, 48.990687953320, 48.968189359584, 48.945690765848, - 48.923192172112, 48.900693578376, 48.878194984640, 48.855696390904, 48.833197797167, - 48.810699203431, 48.788200609694, 48.765702015957, 48.743203422220, 48.720704828484, - 48.698206234747, 48.675707641010, 48.653209047272, 48.630710453535, 48.608211859798, - 48.585713266060, 48.563214672323, 48.540716078585, 48.518217484848, 48.495718891110, - 48.473220297372, 48.450721703634, 48.428223109896, 48.405724516158, 48.383225922419, - 48.360727328681, 48.338228734943, 48.315730141204, 48.293231547466, 48.270732953727, - 48.248234359988, 48.225735766249, 48.203237172510, 48.180738578771, 48.158239985032, - 48.135741391293, 48.113242797554, 48.090744203815, 48.068245610075, 48.045747016336, - 48.023248422596, 48.000749828856, 47.978251235116, 47.955752641377, 47.933254047637, - 47.910755453897, 47.888256860156, 47.865758266416, 47.843259672676, 47.820761078935, - 47.798262485195, 47.775763891454, 47.753265297714, 47.730766703973, 47.708268110232, - 47.685769516491, 47.663270922750, 47.640772329009, 47.618273735268, 47.595775141527, - 47.573276547786, 47.550777954044, 47.528279360303, 47.505780766561, 47.483282172820, - 47.460783579078, 47.438284985336, 47.415786391594, 47.393287797852, 47.370789204110, - 47.348290610368, 47.325792016626, 47.303293422883, 47.280794829141, 47.258296235399, - 47.235797641656, 47.213299047913, 47.190800454171, 47.168301860428, 47.145803266685, - 47.123304672942, 47.100806079199, 47.078307485456, 47.055808891713, 47.033310297970, - 47.010811704226, 46.988313110483, 46.965814516739, 46.943315922996, 46.920817329252, - 46.898318735508, 46.875820141765, 46.853321548021, 46.830822954277, 46.808324360533, - 46.785825766788, 46.763327173044, 46.740828579300, 46.718329985556, 46.695831391811, - 46.673332798067, 46.650834204322, 46.628335610577, 46.605837016833, 46.583338423088, - 46.560839829343, 46.538341235598, 46.515842641853, 46.493344048108, 46.470845454362, - 46.448346860617, 46.425848266872, 46.403349673126, 46.380851079381, 46.358352485635, - 46.335853891890, 46.313355298144, 46.290856704398, 46.268358110652, 46.245859516906, - 46.223360923160, 46.200862329414, 46.178363735668, 46.155865141921, 46.133366548175, - 46.110867954429, 46.088369360682, 46.065870766936, 46.043372173189, 46.020873579442, - 45.998374985695, 45.975876391948, 45.953377798202, 45.930879204454, 45.908380610707, - 45.885882016960, 45.863383423213, 45.840884829466, 45.818386235718, 45.795887641971, - 45.773389048223, 45.750890454476, 45.728391860728, 45.705893266980, 45.683394673232, - 45.660896079485, 45.638397485737, 45.615898891988, 45.593400298240, 45.570901704492, - 45.548403110744, 45.525904516996, 45.503405923247, 45.480907329499, 45.458408735750, - 45.435910142002, 45.413411548253, 45.390912954504, 45.368414360755, 45.345915767006, - 45.323417173257, 45.300918579508, 45.278419985759, 45.255921392010, 45.233422798261, - 45.210924204511, 45.188425610762, 45.165927017013, 45.143428423263, 45.120929829513, - 45.098431235764, 45.075932642014, 45.053434048264, 45.030935454514, 45.008436860764, - 44.985938267014, 44.963439673264, 44.940941079514, 44.918442485764, 44.895943892014, - 44.873445298263, 44.850946704513, 44.828448110762, 44.805949517012, 44.783450923261, - 44.760952329510, 44.738453735760, 44.715955142009, 44.693456548258, 44.670957954507, - 44.648459360756, 44.625960767005, 44.603462173254, 44.580963579502, 44.558464985751, - 44.535966392000, 44.513467798248, 44.490969204497, 44.468470610745, 44.445972016993, - 44.423473423242, 44.400974829490, 44.378476235738, 44.355977641986, 44.333479048234, - 44.310980454482, 44.288481860730, 44.265983266978, 44.243484673226, 44.220986079473, - 44.198487485721, 44.175988891969, 44.153490298216, 44.130991704464, 44.108493110711, - 44.085994516958, 44.063495923205, 44.040997329453, 44.018498735700, 43.996000141947, - 43.973501548194, 43.951002954441, 43.928504360688, 43.906005766934, 43.883507173181, - 43.861008579428, 43.838509985674, 43.816011391921, 43.793512798167, 43.771014204414, - 43.748515610660, 43.726017016906, 43.703518423153, 43.681019829399, 43.658521235645, - 43.636022641891, 43.613524048137, 43.591025454383, 43.568526860629, 43.546028266874, - 43.523529673120, 43.501031079366, 43.478532485611, 43.456033891857, 43.433535298102, - 43.411036704348, 43.388538110593, 43.366039516838, 43.343540923084, 43.321042329329, - 43.298543735574, 43.276045141819, 43.253546548064, 43.231047954309, 43.208549360554, - 43.186050766798, 43.163552173043, 43.141053579288, 43.118554985532, 43.096056391777, - 43.073557798021, 43.051059204266, 43.028560610510, 43.006062016754, 42.983563422999, - 42.961064829243, 42.938566235487, 42.916067641731, 42.893569047975, 42.871070454219, - 42.848571860463, 42.826073266707, 42.803574672951, 42.781076079194, 42.758577485438, - 42.736078891681, 42.713580297925, 42.691081704168, 42.668583110412, 42.646084516655, - 42.623585922899, 42.601087329142, 42.578588735385, 42.556090141628, 42.533591547871, - 42.511092954114, 42.488594360357, 42.466095766600, 42.443597172843, 42.421098579086, - 42.398599985328, 42.376101391571, 42.353602797814, 42.331104204056, 42.308605610299, - 42.286107016541, 42.263608422783, 42.241109829026, 42.218611235268, 42.196112641510, - 42.173614047752, 42.151115453994, 42.128616860236, 42.106118266478, 42.083619672720, - 42.061121078962, 42.038622485204, 42.016123891446, 41.993625297687, 41.971126703929, - 41.948628110170, 41.926129516412, 41.903630922653, 41.881132328895, 41.858633735136, - 41.836135141378, 41.813636547619, 41.791137953860, 41.768639360101, 41.746140766342, - 41.723642172583, 41.701143578824, 41.678644985065, 41.656146391306, 41.633647797547, - 41.611149203787, 41.588650610028, 41.566152016269, 41.543653422509, 41.521154828750, - 41.498656234990, 41.476157641231, 41.453659047471, 41.431160453711, 41.408661859952, - 41.386163266192, 41.363664672432, 41.341166078672, 41.318667484912, 41.296168891152, - 41.273670297392, 41.251171703632, 41.228673109872, 41.206174516111, 41.183675922351, - 41.161177328591, 41.138678734830, 41.116180141070, 41.093681547309, 41.071182953549, - 41.048684359788, 41.026185766028, 41.003687172267, 40.981188578506, 40.958689984745, - 40.936191390984, 40.913692797224, 40.891194203463, 40.868695609702, 40.846197015940, - 40.823698422179, 40.801199828418, 40.778701234657, 40.756202640896, 40.733704047134, - 40.711205453373, 40.688706859611, 40.666208265850, 40.643709672088, 40.621211078327, - 40.598712484565, 40.576213890803, 40.553715297042, 40.531216703280, 40.508718109518, - 40.486219515756, 40.463720921994, 40.441222328232, 40.418723734470, 40.396225140708, - 40.373726546946, 40.351227953184, 40.328729359421, 40.306230765659, 40.283732171897, - 40.261233578134, 40.238734984372, 40.216236390609, 40.193737796847, 40.171239203084, - 40.148740609322, 40.126242015559, 40.103743421796, 40.081244828033, 40.058746234270, - 40.036247640508, 40.013749046745, 39.991250452982, 39.968751859218, 39.946253265455, - 39.923754671692, 39.901256077929, 39.878757484166, 39.856258890402, 39.833760296639, - 39.811261702876, 39.788763109112, 39.766264515349, 39.743765921585, 39.721267327822, - 39.698768734058, 39.676270140294, 39.653771546531, 39.631272952767, 39.608774359003, - 39.586275765239, 39.563777171475, 39.541278577711, 39.518779983947, 39.496281390183, - 39.473782796419, 39.451284202655, 39.428785608891, 39.406287015126, 39.383788421362, - 39.361289827598, 39.338791233833, 39.316292640069, 39.293794046304, 39.271295452540, - 39.248796858775, 39.226298265010, 39.203799671246, 39.181301077481, 39.158802483716, - 39.136303889951, 39.113805296187, 39.091306702422, 39.068808108657, 39.046309514892, - 39.023810921127, 39.001312327361, 38.978813733596, 38.956315139831, 38.933816546066, - 38.911317952301, 38.888819358535, 38.866320764770, 38.843822171004, 38.821323577239, - 38.798824983473, 38.776326389708, 38.753827795942, 38.731329202177, 38.708830608411, - 38.686332014645, 38.663833420879, 38.641334827113, 38.618836233348, 38.596337639582, - 38.573839045816, 38.551340452050, 38.528841858284, 38.506343264517, 38.483844670751, - 38.461346076985, 38.438847483219, 38.416348889453, 38.393850295686, 38.371351701920, - 38.348853108153, 38.326354514387, 38.303855920620, 38.281357326854, 38.258858733087, - 38.236360139321, 38.213861545554, 38.191362951787, 38.168864358020, 38.146365764254, - 38.123867170487, 38.101368576720, 38.078869982953, 38.056371389186, 38.033872795419, - 38.011374201652, 37.988875607885, 37.966377014117, 37.943878420350, 37.921379826583, - 37.898881232816, 37.876382639048, 37.853884045281, 37.831385451513, 37.808886857746, - 37.786388263978, 37.763889670211, 37.741391076443, 37.718892482676, 37.696393888908, - 37.673895295140, 37.651396701372, 37.628898107605, 37.606399513837, 37.583900920069, - 37.561402326301, 37.538903732533, 37.516405138765, 37.493906544997, 37.471407951229, - 37.448909357461, 37.426410763692, 37.403912169924, 37.381413576156, 37.358914982388, - 37.336416388619, 37.313917794851, 37.291419201082, 37.268920607314, 37.246422013545, - 37.223923419777, 37.201424826008, 37.178926232240, 37.156427638471, 37.133929044702, - 37.111430450933, 37.088931857164, 37.066433263396, 37.043934669627, 37.021436075858, - 36.998937482089, 36.976438888320, 36.953940294551, 36.931441700782, 36.908943107012, - 36.886444513243, 36.863945919474, 36.841447325705, 36.818948731936, 36.796450138166, - 36.773951544397, 36.751452950627, 36.728954356858, 36.706455763088, 36.683957169319, - 36.661458575549, 36.638959981780, 36.616461388010, 36.593962794240, 36.571464200471, - 36.548965606701, 36.526467012931, 36.503968419161, 36.481469825391, 36.458971231621, - 36.436472637851, 36.413974044081, 36.391475450311, 36.368976856541, 36.346478262771, - 36.323979669001, 36.301481075230, 36.278982481460, 36.256483887690, 36.233985293920, - 36.211486700149, 36.188988106379, 36.166489512608, 36.143990918838, 36.121492325067, - 36.098993731297, 36.076495137526, 36.053996543756, 36.031497949985, 36.008999356214, - 35.986500762443, 35.964002168673, 35.941503574902, 35.919004981131, 35.896506387360, - 35.874007793589, 35.851509199818, 35.829010606047, 35.806512012276, 35.784013418505, - 35.761514824734, 35.739016230963, 35.716517637191, 35.694019043420, 35.671520449649, - 35.649021855877, 35.626523262106, 35.604024668335, 35.581526074563, 35.559027480792, - 35.536528887020, 35.514030293249, 35.491531699477, 35.469033105705, 35.446534511934, - 35.424035918162, 35.401537324390, 35.379038730619, 35.356540136847, 35.334041543075, - 35.311542949303, 35.289044355531, 35.266545761759, 35.244047167987, 35.221548574215, - 35.199049980443, 35.176551386671, 35.154052792899, 35.131554199127, 35.109055605354, - 35.086557011582, 35.064058417810, 35.041559824038, 35.019061230265, 34.996562636493, - 34.974064042720, 34.951565448948, 34.929066855175, 34.906568261403, 34.884069667630, - 34.861571073858, 34.839072480085, 34.816573886312, 34.794075292540, 34.771576698767, - 34.749078104994, 34.726579511221, 34.704080917448, 34.681582323676, 34.659083729903, - 34.636585136130, 34.614086542357, 34.591587948584, 34.569089354811, 34.546590761037, - 34.524092167264, 34.501593573491, 34.479094979718, 34.456596385945, 34.434097792171, - 34.411599198398, 34.389100604625, 34.366602010851, 34.344103417078, 34.321604823304, - 34.299106229531, 34.276607635757, 34.254109041984, 34.231610448210, 34.209111854437, - 34.186613260663, 34.164114666889, 34.141616073116, 34.119117479342, 34.096618885568, - 34.074120291794, 34.051621698020, 34.029123104246, 34.006624510473, 33.984125916699, - 33.961627322925, 33.939128729151, 33.916630135376, 33.894131541602, 33.871632947828, - 33.849134354054, 33.826635760280, 33.804137166506, 33.781638572731, 33.759139978957, - 33.736641385183, 33.714142791408, 33.691644197634, 33.669145603860, 33.646647010085, - 33.624148416311, 33.601649822536, 33.579151228761, 33.556652634987, 33.534154041212, - 33.511655447438, 33.489156853663, 33.466658259888, 33.444159666113, 33.421661072339, - 33.399162478564, 33.376663884789, 33.354165291014, 33.331666697239, 33.309168103464, - 33.286669509689, 33.264170915914, 33.241672322139, 33.219173728364, 33.196675134589, - 33.174176540814, 33.151677947038, 33.129179353263, 33.106680759488, 33.084182165713, - 33.061683571937, 33.039184978162, 33.016686384387, 32.994187790611, 32.971689196836, - 32.949190603060, 32.926692009285, 32.904193415509, 32.881694821734, 32.859196227958, - 32.836697634183, 32.814199040407, 32.791700446631, 32.769201852855, 32.746703259080, - 32.724204665304, 32.701706071528, 32.679207477752, 32.656708883976, 32.634210290200, - 32.611711696424, 32.589213102648, 32.566714508872, 32.544215915096, 32.521717321320, - 32.499218727544, 32.476720133768, 32.454221539992, 32.431722946216, 32.409224352440, - 32.386725758663, 32.364227164887, 32.341728571111, 32.319229977334, 32.296731383558, - 32.274232789782, 32.251734196005, 32.229235602229, 32.206737008452, 32.184238414676, - 32.161739820899, 32.139241227122, 32.116742633346, 32.094244039569, 32.071745445793, - 32.049246852016, 32.026748258239, 32.004249664462, 31.981751070685, 31.959252476909, - 31.936753883132, 31.914255289355, 31.891756695578, 31.869258101801, 31.846759508024, - 31.824260914247, 31.801762320470, 31.779263726693, 31.756765132916, 31.734266539139, - 31.711767945362, 31.689269351584, 31.666770757807, 31.644272164030, 31.621773570253, - 31.599274976475, 31.576776382698, 31.554277788921, 31.531779195143, 31.509280601366, - 31.486782007588, 31.464283413811, 31.441784820033, 31.419286226256, 31.396787632478, - 31.374289038701, 31.351790444923, 31.329291851145, 31.306793257368, 31.284294663590, - 31.261796069812, 31.239297476034, 31.216798882257, 31.194300288479, 31.171801694701, - 31.149303100923, 31.126804507145, 31.104305913367, 31.081807319589, 31.059308725811, - 31.036810132033, 31.014311538255, 30.991812944477, 30.969314350699, 30.946815756921, - 30.924317163143, 30.901818569365, 30.879319975586, 30.856821381808, 30.834322788030, - 30.811824194251, 30.789325600473, 30.766827006695, 30.744328412916, 30.721829819138, - 30.699331225360, 30.676832631581, 30.654334037803, 30.631835444024, 30.609336850245, - 30.586838256467, 30.564339662688, 30.541841068910, 30.519342475131, 30.496843881352, - 30.474345287574, 30.451846693795, 30.429348100016, 30.406849506237, 30.384350912458, - 30.361852318680, 30.339353724901, 30.316855131122, 30.294356537343, 30.271857943564, - 30.249359349785, 30.226860756006, 30.204362162227, 30.181863568448, 30.159364974669, - 30.136866380889, 30.114367787110, 30.091869193331, 30.069370599552, 30.046872005773, - 30.024373411993, 30.001874818214, 29.979376224435, 29.956877630656, 29.934379036876, - 29.911880443097, 29.889381849317, 29.866883255538, 29.844384661758, 29.821886067979, - 29.799387474199, 29.776888880420, 29.754390286640, 29.731891692861, 29.709393099081, - 29.686894505301, 29.664395911522, 29.641897317742, 29.619398723962, 29.596900130182, - 29.574401536403, 29.551902942623, 29.529404348843, 29.506905755063, 29.484407161283, - 29.461908567503, 29.439409973723, 29.416911379943, 29.394412786163, 29.371914192383, - 29.349415598603, 29.326917004823, 29.304418411043, 29.281919817263, 29.259421223483, - 29.236922629703, 29.214424035923, 29.191925442142, 29.169426848362, 29.146928254582, - 29.124429660802, 29.101931067021, 29.079432473241, 29.056933879461, 29.034435285680, - 29.011936691900, 28.989438098119, 28.966939504339, 28.944440910558, 28.921942316778, - 28.899443722997, 28.876945129217, 28.854446535436, 28.831947941655, 28.809449347875, - 28.786950754094, 28.764452160313, 28.741953566533, 28.719454972752, 28.696956378971, - 28.674457785190, 28.651959191410, 28.629460597629, 28.606962003848, 28.584463410067, - 28.561964816286, 28.539466222505, 28.516967628724, 28.494469034943, 28.471970441162, - 28.449471847381, 28.426973253600, 28.404474659819, 28.381976066038, 28.359477472257, - 28.336978878476, 28.314480284694, 28.291981690913, 28.269483097132, 28.246984503351, - 28.224485909569, 28.201987315788, 28.179488722007, 28.156990128225, 28.134491534444, - 28.111992940663, 28.089494346881, 28.066995753100, 28.044497159318, 28.021998565537, - 27.999499971755, 27.977001377974, 27.954502784192, 27.932004190411, 27.909505596629, - 27.887007002847, 27.864508409066, 27.842009815284, 27.819511221502, 27.797012627721, - 27.774514033939, 27.752015440157, 27.729516846375, 27.707018252594, 27.684519658812, - 27.662021065030, 27.639522471248, 27.617023877466, 27.594525283684, 27.572026689902, - 27.549528096120, 27.527029502338, 27.504530908556, 27.482032314774, 27.459533720992, - 27.437035127210, 27.414536533428, 27.392037939646, 27.369539345863, 27.347040752081, - 27.324542158299, 27.302043564517, 27.279544970735, 27.257046376952, 27.234547783170, - 27.212049189388, 27.189550595605, 27.167052001823, 27.144553408041, 27.122054814258, - 27.099556220476, 27.077057626693, 27.054559032911, 27.032060439128, 27.009561845346, - 26.987063251563, 26.964564657781, 26.942066063998, 26.919567470216, 26.897068876433, - 26.874570282650, 26.852071688868, 26.829573095085, 26.807074501302, 26.784575907519, - 26.762077313737, 26.739578719954, 26.717080126171, 26.694581532388, 26.672082938605, - 26.649584344823, 26.627085751040, 26.604587157257, 26.582088563474, 26.559589969691, - 26.537091375908, 26.514592782125, 26.492094188342, 26.469595594559, 26.447097000776, - 26.424598406993, 26.402099813210, 26.379601219426, 26.357102625643, 26.334604031860, - 26.312105438077, 26.289606844294, 26.267108250510, 26.244609656727, 26.222111062944, - 26.199612469161, 26.177113875377, 26.154615281594, 26.132116687811, 26.109618094027, - 26.087119500244, 26.064620906460, 26.042122312677, 26.019623718893, 25.997125125110, - 25.974626531326, 25.952127937543, 25.929629343759, 25.907130749976, 25.884632156192, - 25.862133562409, 25.839634968625, 25.817136374841, 25.794637781058, 25.772139187274, - 25.749640593490, 25.727141999706, 25.704643405923, 25.682144812139, 25.659646218355, - 25.637147624571, 25.614649030787, 25.592150437004, 25.569651843220, 25.547153249436, - 25.524654655652, 25.502156061868, 25.479657468084, 25.457158874300, 25.434660280516, - 25.412161686732, 25.389663092948, 25.367164499164, 25.344665905380, 25.322167311596, - 25.299668717812, 25.277170124027, 25.254671530243, 25.232172936459, 25.209674342675, - 25.187175748891, 25.164677155106, 25.142178561322, 25.119679967538, 25.097181373754, - 25.074682779969, 25.052184186185, 25.029685592401, 25.007186998616, 24.984688404832, - 24.962189811047, 24.939691217263, 24.917192623479, 24.894694029694, 24.872195435910, - 24.849696842125, 24.827198248340, 24.804699654556, 24.782201060771, 24.759702466987, - 24.737203873202, 24.714705279418, 24.692206685633, 24.669708091848, 24.647209498064, - 24.624710904279, 24.602212310494, 24.579713716709, 24.557215122925, 24.534716529140, - 24.512217935355, 24.489719341570, 24.467220747785, 24.444722154000, 24.422223560216, - 24.399724966431, 24.377226372646, 24.354727778861, 24.332229185076, 24.309730591291, - 24.287231997506, 24.264733403721, 24.242234809936, 24.219736216151, 24.197237622366, - 24.174739028581, 24.152240434796, 24.129741841010, 24.107243247225, 24.084744653440, - 24.062246059655, 24.039747465870, 24.017248872085, 23.994750278299, 23.972251684514, - 23.949753090729, 23.927254496944, 23.904755903158, 23.882257309373, 23.859758715588, - 23.837260121802, 23.814761528017, 23.792262934231, 23.769764340446, 23.747265746661, - 23.724767152875, 23.702268559090, 23.679769965304, 23.657271371519, 23.634772777733, - 23.612274183948, 23.589775590162, 23.567276996376, 23.544778402591, 23.522279808805, - 23.499781215020, 23.477282621234, 23.454784027448, 23.432285433663, 23.409786839877, - 23.387288246091, 23.364789652305, 23.342291058520, 23.319792464734, 23.297293870948, - 23.274795277162, 23.252296683376, 23.229798089591, 23.207299495805, 23.184800902019, - 23.162302308233, 23.139803714447, 23.117305120661, 23.094806526875, 23.072307933089, - 23.049809339303, 23.027310745517, 23.004812151731, 22.982313557945, 22.959814964159, - 22.937316370373, 22.914817776587, 22.892319182801, 22.869820589015, 22.847321995229, - 22.824823401442, 22.802324807656, 22.779826213870, 22.757327620084, 22.734829026298, - 22.712330432511, 22.689831838725, 22.667333244939, 22.644834651153, 22.622336057366, - 22.599837463580, 22.577338869794, 22.554840276007, 22.532341682221, 22.509843088434, - 22.487344494648, 22.464845900862, 22.442347307075, 22.419848713289, 22.397350119502, - 22.374851525716, 22.352352931929, 22.329854338143, 22.307355744356, 22.284857150570, - 22.262358556783, 22.239859962996, 22.217361369210, 22.194862775423, 22.172364181637, - 22.149865587850, 22.127366994063, 22.104868400277, 22.082369806490, 22.059871212703, - 22.037372618916, 22.014874025130, 21.992375431343, 21.969876837556, 21.947378243769, - 21.924879649982, 21.902381056196, 21.879882462409, 21.857383868622, 21.834885274835, - 21.812386681048, 21.789888087261, 21.767389493474, 21.744890899687, 21.722392305900, - 21.699893712113, 21.677395118326, 21.654896524539, 21.632397930752, 21.609899336965, - 21.587400743178, 21.564902149391, 21.542403555604, 21.519904961817, 21.497406368030, - 21.474907774243, 21.452409180455, 21.429910586668, 21.407411992881, 21.384913399094, - 21.362414805307, 21.339916211519, 21.317417617732, 21.294919023945, 21.272420430158, - 21.249921836370, 21.227423242583, 21.204924648796, 21.182426055008, 21.159927461221, - 21.137428867434, 21.114930273646, 21.092431679859, 21.069933086071, 21.047434492284, - 21.024935898497, 21.002437304709, 20.979938710922, 20.957440117134, 20.934941523347, - 20.912442929559, 20.889944335772, 20.867445741984, 20.844947148196, 20.822448554409, - 20.799949960621, 20.777451366834, 20.754952773046, 20.732454179258, 20.709955585471, - 20.687456991683, 20.664958397895, 20.642459804108, 20.619961210320, 20.597462616532, - 20.574964022744, 20.552465428957, 20.529966835169, 20.507468241381, 20.484969647593, - 20.462471053805, 20.439972460018, 20.417473866230, 20.394975272442, 20.372476678654, - 20.349978084866, 20.327479491078, 20.304980897290, 20.282482303502, 20.259983709714, - 20.237485115926, 20.214986522138, 20.192487928350, 20.169989334562, 20.147490740774, - 20.124992146986, 20.102493553198, 20.079994959410, 20.057496365622, 20.034997771834, - 20.012499178046, 19.990000584258, 19.967501990470, 19.945003396681, 19.922504802893, - 19.900006209105, 19.877507615317, 19.855009021529, 19.832510427740, 19.810011833952, - 19.787513240164, 19.765014646376, 19.742516052587, 19.720017458799, 19.697518865011, - 19.675020271223, 19.652521677434, 19.630023083646, 19.607524489857, 19.585025896069, - 19.562527302281, 19.540028708492, 19.517530114704, 19.495031520915, 19.472532927127, - 19.450034333339, 19.427535739550, 19.405037145762, 19.382538551973, 19.360039958185, - 19.337541364396, 19.315042770607, 19.292544176819, 19.270045583030, 19.247546989242, - 19.225048395453, 19.202549801665, 19.180051207876, 19.157552614087, 19.135054020299, - 19.112555426510, 19.090056832721, 19.067558238933, 19.045059645144, 19.022561051355, - 19.000062457566, 18.977563863778, 18.955065269989, 18.932566676200, 18.910068082411, - 18.887569488623, 18.865070894834, 18.842572301045, 18.820073707256, 18.797575113467, - 18.775076519678, 18.752577925889, 18.730079332101, 18.707580738312, 18.685082144523, - 18.662583550734, 18.640084956945, 18.617586363156, 18.595087769367, 18.572589175578, - 18.550090581789, 18.527591988000, 18.505093394211, 18.482594800422, 18.460096206633, - 18.437597612844, 18.415099019055, 18.392600425266, 18.370101831477, 18.347603237687, - 18.325104643898, 18.302606050109, 18.280107456320, 18.257608862531, 18.235110268742, - 18.212611674953, 18.190113081163, 18.167614487374, 18.145115893585, 18.122617299796, - 18.100118706006, 18.077620112217, 18.055121518428, 18.032622924639, 18.010124330849, - 17.987625737060, 17.965127143271, 17.942628549481, 17.920129955692, 17.897631361903, - 17.875132768113, 17.852634174324, 17.830135580535, 17.807636986745, 17.785138392956, - 17.762639799166, 17.740141205377, 17.717642611587, 17.695144017798, 17.672645424008, - 17.650146830219, 17.627648236429, 17.605149642640, 17.582651048850, 17.560152455061, - 17.537653861271, 17.515155267482, 17.492656673692, 17.470158079903, 17.447659486113, - 17.425160892323, 17.402662298534, 17.380163704744, 17.357665110954, 17.335166517165, - 17.312667923375, 17.290169329585, 17.267670735796, 17.245172142006, 17.222673548216, - 17.200174954427, 17.177676360637, 17.155177766847, 17.132679173057, 17.110180579267, - 17.087681985478, 17.065183391688, 17.042684797898, 17.020186204108, 16.997687610318, - 16.975189016529, 16.952690422739, 16.930191828949, 16.907693235159, 16.885194641369, - 16.862696047579, 16.840197453789, 16.817698859999, 16.795200266209, 16.772701672419, - 16.750203078629, 16.727704484839, 16.705205891049, 16.682707297259, 16.660208703469, - 16.637710109679, 16.615211515889, 16.592712922099, 16.570214328309, 16.547715734519, - 16.525217140729, 16.502718546939, 16.480219953149, 16.457721359359, 16.435222765569, - 16.412724171779, 16.390225577989, 16.367726984198, 16.345228390408, 16.322729796618, - 16.300231202828, 16.277732609038, 16.255234015247, 16.232735421457, 16.210236827667, - 16.187738233877, 16.165239640086, 16.142741046296, 16.120242452506, 16.097743858716, - 16.075245264925, 16.052746671135, 16.030248077345, 16.007749483554, 15.985250889764, - 15.962752295974, 15.940253702183, 15.917755108393, 15.895256514603, 15.872757920812, - 15.850259327022, 15.827760733231, 15.805262139441, 15.782763545651, 15.760264951860, - 15.737766358070, 15.715267764279, 15.692769170489, 15.670270576698, 15.647771982908, - 15.625273389117, 15.602774795327, 15.580276201536, 15.557777607746, 15.535279013955, - 15.512780420165, 15.490281826374, 15.467783232583, 15.445284638793, 15.422786045002, - 15.400287451212, 15.377788857421, 15.355290263630, 15.332791669840, 15.310293076049, - 15.287794482258, 15.265295888468, 15.242797294677, 15.220298700886, 15.197800107096, - 15.175301513305, 15.152802919514, 15.130304325724, 15.107805731933, 15.085307138142, - 15.062808544351, 15.040309950560, 15.017811356770, 14.995312762979, 14.972814169188, - 14.950315575397, 14.927816981606, 14.905318387816, 14.882819794025, 14.860321200234, - 14.837822606443, 14.815324012652, 14.792825418861, 14.770326825070, 14.747828231280, - 14.725329637489, 14.702831043698, 14.680332449907, 14.657833856116, 14.635335262325, - 14.612836668534, 14.590338074743, 14.567839480952, 14.545340887161, 14.522842293370, - 14.500343699579, 14.477845105788, 14.455346511997, 14.432847918206, 14.410349324415, - 14.387850730624, 14.365352136833, 14.342853543042, 14.320354949251, 14.297856355460, - 14.275357761668, 14.252859167877, 14.230360574086, 14.207861980295, 14.185363386504, - 14.162864792713, 14.140366198922, 14.117867605131, 14.095369011339, 14.072870417548, - 14.050371823757, 14.027873229966, 14.005374636175, 13.982876042383, 13.960377448592, - 13.937878854801, 13.915380261010, 13.892881667218, 13.870383073427, 13.847884479636, - 13.825385885845, 13.802887292053, 13.780388698262, 13.757890104471, 13.735391510679, - 13.712892916888, 13.690394323097, 13.667895729305, 13.645397135514, 13.622898541723, - 13.600399947931, 13.577901354140, 13.555402760348, 13.532904166557, 13.510405572766, - 13.487906978974, 13.465408385183, 13.442909791391, 13.420411197600, 13.397912603809, - 13.375414010017, 13.352915416226, 13.330416822434, 13.307918228643, 13.285419634851, - 13.262921041060, 13.240422447268, 13.217923853477, 13.195425259685, 13.172926665894, - 13.150428072102, 13.127929478310, 13.105430884519, 13.082932290727, 13.060433696936, - 13.037935103144, 13.015436509353, 12.992937915561, 12.970439321769, 12.947940727978, - 12.925442134186, 12.902943540394, 12.880444946603, 12.857946352811, 12.835447759019, - 12.812949165228, 12.790450571436, 12.767951977644, 12.745453383853, 12.722954790061, - 12.700456196269, 12.677957602478, 12.655459008686, 12.632960414894, 12.610461821102, - 12.587963227311, 12.565464633519, 12.542966039727, 12.520467445935, 12.497968852144, - 12.475470258352, 12.452971664560, 12.430473070768, 12.407974476976, 12.385475883184, - 12.362977289393, 12.340478695601, 12.317980101809, 12.295481508017, 12.272982914225, - 12.250484320433, 12.227985726641, 12.205487132850, 12.182988539058, 12.160489945266, - 12.137991351474, 12.115492757682, 12.092994163890, 12.070495570098, 12.047996976306, - 12.025498382514, 12.002999788722, 11.980501194930, 11.958002601138, 11.935504007346, - 11.913005413554, 11.890506819762, 11.868008225970, 11.845509632178, 11.823011038386, - 11.800512444594, 11.778013850802, 11.755515257010, 11.733016663218, 11.710518069426, - 11.688019475634, 11.665520881842, 11.643022288050, 11.620523694258, 11.598025100466, - 11.575526506674, 11.553027912882, 11.530529319089, 11.508030725297, 11.485532131505, - 11.463033537713, 11.440534943921, 11.418036350129, 11.395537756337, 11.373039162544, - 11.350540568752, 11.328041974960, 11.305543381168, 11.283044787376, 11.260546193583, - 11.238047599791, 11.215549005999, 11.193050412207, 11.170551818415, 11.148053224622, - 11.125554630830, 11.103056037038, 11.080557443246, 11.058058849453, 11.035560255661, - 11.013061661869, 10.990563068076, 10.968064474284, 10.945565880492, 10.923067286700, - 10.900568692907, 10.878070099115, 10.855571505323, 10.833072911530, 10.810574317738, - 10.788075723946, 10.765577130153, 10.743078536361, 10.720579942568, 10.698081348776, - 10.675582754984, 10.653084161191, 10.630585567399, 10.608086973607, 10.585588379814, - 10.563089786022, 10.540591192229, 10.518092598437, 10.495594004644, 10.473095410852, - 10.450596817059, 10.428098223267, 10.405599629475, 10.383101035682, 10.360602441890, - 10.338103848097, 10.315605254305, 10.293106660512, 10.270608066720, 10.248109472927, - 10.225610879135, 10.203112285342, 10.180613691550, 10.158115097757, 10.135616503965, - 10.113117910172, 10.090619316379, 10.068120722587, 10.045622128794, 10.023123535002, - 10.000624941209, 9.978126347417, 9.955627753624, 9.933129159831, 9.910630566039, - 9.888131972246, 9.865633378454, 9.843134784661, 9.820636190868, 9.798137597076, - 9.775639003283, 9.753140409490, 9.730641815698, 9.708143221905, 9.685644628112, - 9.663146034320, 9.640647440527, 9.618148846734, 9.595650252942, 9.573151659149, - 9.550653065356, 9.528154471564, 9.505655877771, 9.483157283978, 9.460658690185, - 9.438160096393, 9.415661502600, 9.393162908807, 9.370664315014, 9.348165721222, - 9.325667127429, 9.303168533636, 9.280669939843, 9.258171346051, 9.235672752258, - 9.213174158465, 9.190675564672, 9.168176970879, 9.145678377087, 9.123179783294, - 9.100681189501, 9.078182595708, 9.055684001915, 9.033185408123, 9.010686814330, - 8.988188220537, 8.965689626744, 8.943191032951, 8.920692439158, 8.898193845365, - 8.875695251573, 8.853196657780, 8.830698063987, 8.808199470194, 8.785700876401, - 8.763202282608, 8.740703688815, 8.718205095022, 8.695706501229, 8.673207907436, - 8.650709313643, 8.628210719851, 8.605712126058, 8.583213532265, 8.560714938472, - 8.538216344679, 8.515717750886, 8.493219157093, 8.470720563300, 8.448221969507, - 8.425723375714, 8.403224781921, 8.380726188128, 8.358227594335, 8.335729000542, - 8.313230406749, 8.290731812956, 8.268233219163, 8.245734625370, 8.223236031577, - 8.200737437784, 8.178238843991, 8.155740250198, 8.133241656405, 8.110743062612, - 8.088244468819, 8.065745875025, 8.043247281232, 8.020748687439, 7.998250093646, - 7.975751499853, 7.953252906060, 7.930754312267, 7.908255718474, 7.885757124681, - 7.863258530888, 7.840759937095, 7.818261343301, 7.795762749508, 7.773264155715, - 7.750765561922, 7.728266968129, 7.705768374336, 7.683269780543, 7.660771186750, - 7.638272592956, 7.615773999163, 7.593275405370, 7.570776811577, 7.548278217784, - 7.525779623991, 7.503281030197, 7.480782436404, 7.458283842611, 7.435785248818, - 7.413286655025, 7.390788061231, 7.368289467438, 7.345790873645, 7.323292279852, - 7.300793686058, 7.278295092265, 7.255796498472, 7.233297904679, 7.210799310886, - 7.188300717092, 7.165802123299, 7.143303529506, 7.120804935713, 7.098306341919, - 7.075807748126, 7.053309154333, 7.030810560539, 7.008311966746, 6.985813372953, - 6.963314779160, 6.940816185366, 6.918317591573, 6.895818997780, 6.873320403986, - 6.850821810193, 6.828323216400, 6.805824622606, 6.783326028813, 6.760827435020, - 6.738328841226, 6.715830247433, 6.693331653640, 6.670833059846, 6.648334466053, - 6.625835872260, 6.603337278466, 6.580838684673, 6.558340090880, 6.535841497086, - 6.513342903293, 6.490844309500, 6.468345715706, 6.445847121913, 6.423348528119, - 6.400849934326, 6.378351340533, 6.355852746739, 6.333354152946, 6.310855559152, - 6.288356965359, 6.265858371566, 6.243359777772, 6.220861183979, 6.198362590185, - 6.175863996392, 6.153365402598, 6.130866808805, 6.108368215011, 6.085869621218, - 6.063371027425, 6.040872433631, 6.018373839838, 5.995875246044, 5.973376652251, - 5.950878058457, 5.928379464664, 5.905880870870, 5.883382277077, 5.860883683283, - 5.838385089490, 5.815886495696, 5.793387901903, 5.770889308109, 5.748390714316, - 5.725892120522, 5.703393526729, 5.680894932935, 5.658396339142, 5.635897745348, - 5.613399151555, 5.590900557761, 5.568401963968, 5.545903370174, 5.523404776381, - 5.500906182587, 5.478407588794, 5.455908995000, 5.433410401207, 5.410911807413, - 5.388413213619, 5.365914619826, 5.343416026032, 5.320917432239, 5.298418838445, - 5.275920244652, 5.253421650858, 5.230923057064, 5.208424463271, 5.185925869477, - 5.163427275684, 5.140928681890, 5.118430088097, 5.095931494303, 5.073432900509, - 5.050934306716, 5.028435712922, 5.005937119128, 4.983438525335, 4.960939931541, - 4.938441337748, 4.915942743954, 4.893444150160, 4.870945556367, 4.848446962573, - 4.825948368780, 4.803449774986, 4.780951181192, 4.758452587399, 4.735953993605, - 4.713455399811, 4.690956806018, 4.668458212224, 4.645959618430, 4.623461024637, - 4.600962430843, 4.578463837049, 4.555965243256, 4.533466649462, 4.510968055668, - 4.488469461875, 4.465970868081, 4.443472274287, 4.420973680494, 4.398475086700, - 4.375976492906, 4.353477899113, 4.330979305319, 4.308480711525, 4.285982117731, - 4.263483523938, 4.240984930144, 4.218486336350, 4.195987742557, 4.173489148763, - 4.150990554969, 4.128491961175, 4.105993367382, 4.083494773588, 4.060996179794, - 4.038497586001, 4.015998992207, 3.993500398413, 3.971001804619, 3.948503210826, - 3.926004617032, 3.903506023238, 3.881007429444, 3.858508835651, 3.836010241857, - 3.813511648063, 3.791013054269, 3.768514460476, 3.746015866682, 3.723517272888, - 3.701018679094, 3.678520085301, 3.656021491507, 3.633522897713, 3.611024303919, - 3.588525710126, 3.566027116332, 3.543528522538, 3.521029928744, 3.498531334950, - 3.476032741157, 3.453534147363, 3.431035553569, 3.408536959775, 3.386038365981, - 3.363539772188, 3.341041178394, 3.318542584600, 3.296043990806, 3.273545397012, - 3.251046803219, 3.228548209425, 3.206049615631, 3.183551021837, 3.161052428043, - 3.138553834250, 3.116055240456, 3.093556646662, 3.071058052868, 3.048559459074, - 3.026060865281, 3.003562271487, 2.981063677693, 2.958565083899, 2.936066490105, - 2.913567896311, 2.891069302518, 2.868570708724, 2.846072114930, 2.823573521136, - 2.801074927342, 2.778576333548, 2.756077739754, 2.733579145961, 2.711080552167, - 2.688581958373, 2.666083364579, 2.643584770785, 2.621086176991, 2.598587583198, - 2.576088989404, 2.553590395610, 2.531091801816, 2.508593208022, 2.486094614228, - 2.463596020434, 2.441097426640, 2.418598832847, 2.396100239053, 2.373601645259, - 2.351103051465, 2.328604457671, 2.306105863877, 2.283607270083, 2.261108676289, - 2.238610082496, 2.216111488702, 2.193612894908, 2.171114301114, 2.148615707320, - 2.126117113526, 2.103618519732, 2.081119925938, 2.058621332145, 2.036122738351, - 2.013624144557, 1.991125550763, 1.968626956969, 1.946128363175, 1.923629769381, - 1.901131175587, 1.878632581793, 1.856133987999, 1.833635394206, 1.811136800412, - 1.788638206618, 1.766139612824, 1.743641019030, 1.721142425236, 1.698643831442, - 1.676145237648, 1.653646643854, 1.631148050060, 1.608649456266, 1.586150862473, - 1.563652268679, 1.541153674885, 1.518655081091, 1.496156487297, 1.473657893503, - 1.451159299709, 1.428660705915, 1.406162112121, 1.383663518327, 1.361164924533, - 1.338666330739, 1.316167736946, 1.293669143152, 1.271170549358, 1.248671955564, - 1.226173361770, 1.203674767976, 1.181176174182, 1.158677580388, 1.136178986594, - 1.113680392800, 1.091181799006, 1.068683205212, 1.046184611418, 1.023686017624, - 1.001187423830, 0.978688830037, 0.956190236243, 0.933691642449, 0.911193048655, - 0.888694454861, 0.866195861067, 0.843697267273, 0.821198673479, 0.798700079685, - 0.776201485891, 0.753702892097, 0.731204298303, 0.708705704509, 0.686207110715, - 0.663708516921, 0.641209923127, 0.618711329334, 0.596212735540, 0.573714141746, - 0.551215547952, 0.528716954158, 0.506218360364, 0.483719766570, 0.461221172776, - 0.438722578982, 0.416223985188, 0.393725391394, 0.371226797600, 0.348728203806, - 0.326229610012, 0.303731016218, 0.281232422424, 0.258733828630, 0.236235234836, - 0.213736641043, 0.191238047249, 0.168739453455, 0.146240859661, 0.123742265867, - 0.101243672073, 0.078745078279, 0.056246484485, 0.033747890691, 0.011249296897 - )) +DEFINE_GAUSSIAN_LATITUDES( + 4000, + LIST( + 89.982777782041, 89.960467823498, 89.938026112601, 89.915554633223, 89.893071861958, 89.870583626524, + 89.848092337395, 89.825599170237, 89.803104766281, 89.780609504838, 89.758113624578, 89.735617283150, + 89.713120588868, 89.690623618599, 89.668126428400, 89.645629060112, 89.623131545602, 89.600633909559, + 89.578136171413, 89.555638346662, 89.533140447819, 89.510642485097, 89.488144466917, 89.465646400278, + 89.443148291053, 89.420650144201, 89.398151963940, 89.375653753880, 89.353155517131, 89.330657256382, + 89.308158973974, 89.285660671954, 89.263162352116, 89.240664016047, 89.218165665144, 89.195667300653, + 89.173168923684, 89.150670535227, 89.128172136173, 89.105673727319, 89.083175309389, 89.060676883034, + 89.038178448845, 89.015680007358, 88.993181559065, 88.970683104410, 88.948184643801, 88.925686177614, + 88.903187706190, 88.880689229847, 88.858190748874, 88.835692263540, 88.813193774093, 88.790695280762, + 88.768196783761, 88.745698283287, 88.723199779523, 88.700701272640, 88.678202762798, 88.655704250144, + 88.633205734819, 88.610707216951, 88.588208696663, 88.565710174068, 88.543211649272, 88.520713122378, + 88.498214593477, 88.475716062661, 88.453217530011, 88.430718995608, 88.408220459525, 88.385721921832, + 88.363223382596, 88.340724841881, 88.318226299744, 88.295727756243, 88.273229211430, 88.250730665357, + 88.228232118071, 88.205733569618, 88.183235020041, 88.160736469382, 88.138237917679, 88.115739364971, + 88.093240811293, 88.070742256678, 88.048243701159, 88.025745144768, 88.003246587532, 87.980748029482, + 87.958249470643, 87.935750911042, 87.913252350702, 87.890753789648, 87.868255227903, 87.845756665488, + 87.823258102423, 87.800759538729, 87.778260974425, 87.755762409529, 87.733263844059, 87.710765278031, + 87.688266711463, 87.665768144369, 87.643269576765, 87.620771008664, 87.598272440082, 87.575773871032, + 87.553275301526, 87.530776731576, 87.508278161196, 87.485779590396, 87.463281019188, 87.440782447582, + 87.418283875589, 87.395785303218, 87.373286730480, 87.350788157385, 87.328289583939, 87.305791010154, + 87.283292436037, 87.260793861596, 87.238295286839, 87.215796711774, 87.193298136408, 87.170799560749, + 87.148300984803, 87.125802408577, 87.103303832079, 87.080805255312, 87.058306678285, 87.035808101003, + 87.013309523472, 86.990810945697, 86.968312367684, 86.945813789438, 86.923315210965, 86.900816632268, + 86.878318053353, 86.855819474226, 86.833320894889, 86.810822315347, 86.788323735606, 86.765825155669, + 86.743326575540, 86.720827995223, 86.698329414722, 86.675830834040, 86.653332253182, 86.630833672151, + 86.608335090950, 86.585836509583, 86.563337928052, 86.540839346362, 86.518340764515, 86.495842182514, + 86.473343600362, 86.450845018063, 86.428346435618, 86.405847853031, 86.383349270303, 86.360850687439, + 86.338352104440, 86.315853521309, 86.293354938048, 86.270856354659, 86.248357771146, 86.225859187509, + 86.203360603752, 86.180862019876, 86.158363435884, 86.135864851777, 86.113366267558, 86.090867683228, + 86.068369098789, 86.045870514244, 86.023371929594, 86.000873344840, 85.978374759985, 85.955876175031, + 85.933377589978, 85.910879004828, 85.888380419584, 85.865881834246, 85.843383248817, 85.820884663297, + 85.798386077688, 85.775887491991, 85.753388906209, 85.730890320342, 85.708391734391, 85.685893148358, + 85.663394562245, 85.640895976052, 85.618397389780, 85.595898803431, 85.573400217007, 85.550901630507, + 85.528403043934, 85.505904457288, 85.483405870571, 85.460907283783, 85.438408696926, 85.415910110001, + 85.393411523008, 85.370912935948, 85.348414348824, 85.325915761635, 85.303417174382, 85.280918587066, + 85.258419999689, 85.235921412251, 85.213422824753, 85.190924237196, 85.168425649580, 85.145927061907, + 85.123428474177, 85.100929886391, 85.078431298550, 85.055932710655, 85.033434122705, 85.010935534703, + 84.988436946649, 84.965938358543, 84.943439770386, 84.920941182179, 84.898442593922, 84.875944005617, + 84.853445417263, 84.830946828862, 84.808448240413, 84.785949651918, 84.763451063378, 84.740952474792, + 84.718453886162, 84.695955297487, 84.673456708770, 84.650958120009, 84.628459531205, 84.605960942360, + 84.583462353474, 84.560963764546, 84.538465175579, 84.515966586571, 84.493467997524, 84.470969408439, + 84.448470819315, 84.425972230153, 84.403473640953, 84.380975051717, 84.358476462443, 84.335977873134, + 84.313479283789, 84.290980694409, 84.268482104994, 84.245983515544, 84.223484926060, 84.200986336543, + 84.178487746992, 84.155989157409, 84.133490567792, 84.110991978144, 84.088493388464, 84.065994798753, + 84.043496209010, 84.020997619237, 83.998499029433, 83.976000439600, 83.953501849737, 83.931003259844, + 83.908504669922, 83.886006079972, 83.863507489993, 83.841008899986, 83.818510309952, 83.796011719889, + 83.773513129800, 83.751014539684, 83.728515949541, 83.706017359372, 83.683518769177, 83.661020178956, + 83.638521588710, 83.616022998438, 83.593524408141, 83.571025817820, 83.548527227475, 83.526028637105, + 83.503530046711, 83.481031456294, 83.458532865853, 83.436034275389, 83.413535684902, 83.391037094392, + 83.368538503860, 83.346039913306, 83.323541322729, 83.301042732131, 83.278544141511, 83.256045550870, + 83.233546960207, 83.211048369524, 83.188549778820, 83.166051188095, 83.143552597351, 83.121054006585, + 83.098555415800, 83.076056824996, 83.053558234171, 83.031059643328, 83.008561052465, 82.986062461583, + 82.963563870682, 82.941065279763, 82.918566688825, 82.896068097869, 82.873569506895, 82.851070915903, + 82.828572324893, 82.806073733866, 82.783575142821, 82.761076551759, 82.738577960680, 82.716079369584, + 82.693580778471, 82.671082187341, 82.648583596195, 82.626085005032, 82.603586413854, 82.581087822659, + 82.558589231449, 82.536090640222, 82.513592048980, 82.491093457723, 82.468594866450, 82.446096275163, + 82.423597683860, 82.401099092542, 82.378600501209, 82.356101909862, 82.333603318500, 82.311104727124, + 82.288606135733, 82.266107544328, 82.243608952910, 82.221110361477, 82.198611770031, 82.176113178570, + 82.153614587097, 82.131115995610, 82.108617404109, 82.086118812596, 82.063620221069, 82.041121629529, + 82.018623037977, 81.996124446412, 81.973625854834, 81.951127263243, 81.928628671640, 81.906130080025, + 81.883631488397, 81.861132896757, 81.838634305106, 81.816135713442, 81.793637121767, 81.771138530079, + 81.748639938380, 81.726141346670, 81.703642754948, 81.681144163215, 81.658645571470, 81.636146979714, + 81.613648387948, 81.591149796170, 81.568651204381, 81.546152612581, 81.523654020771, 81.501155428950, + 81.478656837119, 81.456158245277, 81.433659653424, 81.411161061561, 81.388662469688, 81.366163877805, + 81.343665285912, 81.321166694009, 81.298668102095, 81.276169510172, 81.253670918240, 81.231172326297, + 81.208673734345, 81.186175142383, 81.163676550412, 81.141177958431, 81.118679366442, 81.096180774442, + 81.073682182434, 81.051183590416, 81.028684998390, 81.006186406354, 80.983687814310, 80.961189222257, + 80.938690630195, 80.916192038124, 80.893693446044, 80.871194853956, 80.848696261860, 80.826197669754, + 80.803699077641, 80.781200485519, 80.758701893389, 80.736203301251, 80.713704709104, 80.691206116950, + 80.668707524787, 80.646208932616, 80.623710340438, 80.601211748251, 80.578713156057, 80.556214563855, + 80.533715971645, 80.511217379428, 80.488718787203, 80.466220194970, 80.443721602730, 80.421223010483, + 80.398724418228, 80.376225825966, 80.353727233696, 80.331228641420, 80.308730049136, 80.286231456845, + 80.263732864547, 80.241234272242, 80.218735679930, 80.196237087611, 80.173738495285, 80.151239902952, + 80.128741310612, 80.106242718266, 80.083744125913, 80.061245533554, 80.038746941187, 80.016248348815, + 79.993749756435, 79.971251164049, 79.948752571657, 79.926253979258, 79.903755386853, 79.881256794442, + 79.858758202025, 79.836259609601, 79.813761017171, 79.791262424735, 79.768763832293, 79.746265239844, + 79.723766647390, 79.701268054930, 79.678769462464, 79.656270869991, 79.633772277514, 79.611273685030, + 79.588775092540, 79.566276500045, 79.543777907544, 79.521279315037, 79.498780722525, 79.476282130007, + 79.453783537483, 79.431284944954, 79.408786352420, 79.386287759879, 79.363789167334, 79.341290574783, + 79.318791982227, 79.296293389665, 79.273794797099, 79.251296204526, 79.228797611949, 79.206299019367, + 79.183800426779, 79.161301834186, 79.138803241588, 79.116304648985, 79.093806056377, 79.071307463764, + 79.048808871146, 79.026310278523, 79.003811685896, 78.981313093263, 78.958814500625, 78.936315907983, + 78.913817315336, 78.891318722684, 78.868820130027, 78.846321537366, 78.823822944700, 78.801324352029, + 78.778825759354, 78.756327166674, 78.733828573989, 78.711329981300, 78.688831388607, 78.666332795909, + 78.643834203206, 78.621335610500, 78.598837017788, 78.576338425073, 78.553839832353, 78.531341239628, + 78.508842646900, 78.486344054167, 78.463845461429, 78.441346868688, 78.418848275942, 78.396349683193, + 78.373851090439, 78.351352497681, 78.328853904918, 78.306355312152, 78.283856719382, 78.261358126607, + 78.238859533829, 78.216360941047, 78.193862348260, 78.171363755470, 78.148865162676, 78.126366569878, + 78.103867977076, 78.081369384270, 78.058870791460, 78.036372198647, 78.013873605830, 77.991375013009, + 77.968876420184, 77.946377827355, 77.923879234523, 77.901380641687, 77.878882048848, 77.856383456004, + 77.833884863158, 77.811386270307, 77.788887677453, 77.766389084596, 77.743890491735, 77.721391898870, + 77.698893306002, 77.676394713130, 77.653896120255, 77.631397527376, 77.608898934494, 77.586400341609, + 77.563901748720, 77.541403155828, 77.518904562933, 77.496405970034, 77.473907377132, 77.451408784226, + 77.428910191317, 77.406411598405, 77.383913005490, 77.361414412572, 77.338915819650, 77.316417226725, + 77.293918633797, 77.271420040866, 77.248921447931, 77.226422854994, 77.203924262053, 77.181425669109, + 77.158927076162, 77.136428483213, 77.113929890260, 77.091431297304, 77.068932704345, 77.046434111383, + 77.023935518418, 77.001436925450, 76.978938332479, 76.956439739505, 76.933941146528, 76.911442553549, + 76.888943960566, 76.866445367581, 76.843946774592, 76.821448181601, 76.798949588607, 76.776450995610, + 76.753952402611, 76.731453809608, 76.708955216603, 76.686456623595, 76.663958030584, 76.641459437571, + 76.618960844555, 76.596462251536, 76.573963658514, 76.551465065490, 76.528966472463, 76.506467879434, + 76.483969286401, 76.461470693367, 76.438972100329, 76.416473507289, 76.393974914246, 76.371476321201, + 76.348977728153, 76.326479135103, 76.303980542050, 76.281481948995, 76.258983355937, 76.236484762876, + 76.213986169813, 76.191487576748, 76.168988983680, 76.146490390610, 76.123991797537, 76.101493204462, + 76.078994611385, 76.056496018304, 76.033997425222, 76.011498832137, 75.989000239050, 75.966501645961, + 75.944003052869, 75.921504459775, 75.899005866678, 75.876507273579, 75.854008680478, 75.831510087375, + 75.809011494269, 75.786512901161, 75.764014308051, 75.741515714939, 75.719017121824, 75.696518528707, + 75.674019935588, 75.651521342466, 75.629022749343, 75.606524156217, 75.584025563089, 75.561526969959, + 75.539028376827, 75.516529783692, 75.494031190556, 75.471532597417, 75.449034004276, 75.426535411134, + 75.404036817989, 75.381538224842, 75.359039631692, 75.336541038541, 75.314042445388, 75.291543852233, + 75.269045259075, 75.246546665916, 75.224048072755, 75.201549479591, 75.179050886426, 75.156552293258, + 75.134053700089, 75.111555106918, 75.089056513744, 75.066557920569, 75.044059327392, 75.021560734213, + 74.999062141031, 74.976563547848, 74.954064954664, 74.931566361477, 74.909067768288, 74.886569175097, + 74.864070581905, 74.841571988710, 74.819073395514, 74.796574802316, 74.774076209116, 74.751577615914, + 74.729079022711, 74.706580429505, 74.684081836298, 74.661583243089, 74.639084649878, 74.616586056666, + 74.594087463451, 74.571588870235, 74.549090277017, 74.526591683797, 74.504093090576, 74.481594497353, + 74.459095904128, 74.436597310901, 74.414098717673, 74.391600124442, 74.369101531211, 74.346602937977, + 74.324104344742, 74.301605751505, 74.279107158266, 74.256608565026, 74.234109971784, 74.211611378541, + 74.189112785296, 74.166614192049, 74.144115598800, 74.121617005550, 74.099118412298, 74.076619819045, + 74.054121225790, 74.031622632533, 74.009124039275, 73.986625446016, 73.964126852754, 73.941628259491, + 73.919129666227, 73.896631072961, 73.874132479693, 73.851633886424, 73.829135293154, 73.806636699881, + 73.784138106608, 73.761639513332, 73.739140920056, 73.716642326777, 73.694143733498, 73.671645140216, + 73.649146546934, 73.626647953649, 73.604149360364, 73.581650767077, 73.559152173788, 73.536653580498, + 73.514154987206, 73.491656393913, 73.469157800619, 73.446659207323, 73.424160614026, 73.401662020727, + 73.379163427427, 73.356664834125, 73.334166240822, 73.311667647518, 73.289169054212, 73.266670460905, + 73.244171867596, 73.221673274286, 73.199174680975, 73.176676087662, 73.154177494348, 73.131678901033, + 73.109180307716, 73.086681714398, 73.064183121079, 73.041684527758, 73.019185934436, 72.996687341112, + 72.974188747788, 72.951690154462, 72.929191561134, 72.906692967806, 72.884194374476, 72.861695781144, + 72.839197187812, 72.816698594478, 72.794200001143, 72.771701407806, 72.749202814469, 72.726704221130, + 72.704205627790, 72.681707034448, 72.659208441106, 72.636709847762, 72.614211254416, 72.591712661070, + 72.569214067722, 72.546715474374, 72.524216881024, 72.501718287672, 72.479219694320, 72.456721100966, + 72.434222507611, 72.411723914255, 72.389225320898, 72.366726727539, 72.344228134180, 72.321729540819, + 72.299230947457, 72.276732354094, 72.254233760729, 72.231735167364, 72.209236573997, 72.186737980629, + 72.164239387260, 72.141740793890, 72.119242200519, 72.096743607146, 72.074245013773, 72.051746420398, + 72.029247827023, 72.006749233646, 71.984250640268, 71.961752046889, 71.939253453508, 71.916754860127, + 71.894256266745, 71.871757673361, 71.849259079977, 71.826760486591, 71.804261893204, 71.781763299816, + 71.759264706427, 71.736766113037, 71.714267519646, 71.691768926254, 71.669270332861, 71.646771739467, + 71.624273146072, 71.601774552675, 71.579275959278, 71.556777365880, 71.534278772480, 71.511780179080, + 71.489281585678, 71.466782992276, 71.444284398872, 71.421785805468, 71.399287212062, 71.376788618656, + 71.354290025248, 71.331791431840, 71.309292838430, 71.286794245020, 71.264295651608, 71.241797058196, + 71.219298464782, 71.196799871368, 71.174301277952, 71.151802684536, 71.129304091118, 71.106805497700, + 71.084306904281, 71.061808310860, 71.039309717439, 71.016811124017, 70.994312530594, 70.971813937170, + 70.949315343745, 70.926816750319, 70.904318156892, 70.881819563464, 70.859320970035, 70.836822376606, + 70.814323783175, 70.791825189744, 70.769326596311, 70.746828002878, 70.724329409444, 70.701830816008, + 70.679332222572, 70.656833629135, 70.634335035698, 70.611836442259, 70.589337848819, 70.566839255379, + 70.544340661937, 70.521842068495, 70.499343475052, 70.476844881608, 70.454346288163, 70.431847694717, + 70.409349101270, 70.386850507823, 70.364351914375, 70.341853320925, 70.319354727475, 70.296856134024, + 70.274357540573, 70.251858947120, 70.229360353667, 70.206861760212, 70.184363166757, 70.161864573301, + 70.139365979844, 70.116867386387, 70.094368792928, 70.071870199469, 70.049371606009, 70.026873012548, + 70.004374419086, 69.981875825624, 69.959377232160, 69.936878638696, 69.914380045231, 69.891881451766, + 69.869382858299, 69.846884264832, 69.824385671364, 69.801887077895, 69.779388484425, 69.756889890954, + 69.734391297483, 69.711892704011, 69.689394110538, 69.666895517065, 69.644396923590, 69.621898330115, + 69.599399736639, 69.576901143163, 69.554402549685, 69.531903956207, 69.509405362728, 69.486906769248, + 69.464408175768, 69.441909582287, 69.419410988805, 69.396912395322, 69.374413801839, 69.351915208354, + 69.329416614870, 69.306918021384, 69.284419427897, 69.261920834410, 69.239422240923, 69.216923647434, + 69.194425053945, 69.171926460455, 69.149427866964, 69.126929273473, 69.104430679980, 69.081932086488, + 69.059433492994, 69.036934899500, 69.014436306005, 68.991937712509, 68.969439119013, 68.946940525516, + 68.924441932018, 68.901943338519, 68.879444745020, 68.856946151521, 68.834447558020, 68.811948964519, + 68.789450371017, 68.766951777514, 68.744453184011, 68.721954590507, 68.699455997003, 68.676957403497, + 68.654458809991, 68.631960216485, 68.609461622978, 68.586963029470, 68.564464435961, 68.541965842452, + 68.519467248942, 68.496968655431, 68.474470061920, 68.451971468408, 68.429472874896, 68.406974281383, + 68.384475687869, 68.361977094355, 68.339478500839, 68.316979907324, 68.294481313807, 68.271982720290, + 68.249484126773, 68.226985533255, 68.204486939736, 68.181988346216, 68.159489752696, 68.136991159175, + 68.114492565654, 68.091993972132, 68.069495378609, 68.046996785086, 68.024498191562, 68.001999598038, + 67.979501004513, 67.957002410987, 67.934503817461, 67.912005223934, 67.889506630407, 67.867008036879, + 67.844509443350, 67.822010849821, 67.799512256291, 67.777013662761, 67.754515069230, 67.732016475698, + 67.709517882166, 67.687019288633, 67.664520695100, 67.642022101566, 67.619523508031, 67.597024914496, + 67.574526320960, 67.552027727424, 67.529529133887, 67.507030540350, 67.484531946812, 67.462033353273, + 67.439534759734, 67.417036166195, 67.394537572654, 67.372038979113, 67.349540385572, 67.327041792030, + 67.304543198488, 67.282044604945, 67.259546011401, 67.237047417857, 67.214548824312, 67.192050230767, + 67.169551637221, 67.147053043675, 67.124554450128, 67.102055856581, 67.079557263033, 67.057058669484, + 67.034560075935, 67.012061482386, 66.989562888836, 66.967064295285, 66.944565701734, 66.922067108182, + 66.899568514630, 66.877069921077, 66.854571327524, 66.832072733970, 66.809574140416, 66.787075546861, + 66.764576953306, 66.742078359750, 66.719579766194, 66.697081172637, 66.674582579080, 66.652083985522, + 66.629585391963, 66.607086798404, 66.584588204845, 66.562089611285, 66.539591017725, 66.517092424164, + 66.494593830602, 66.472095237040, 66.449596643478, 66.427098049915, 66.404599456352, 66.382100862788, + 66.359602269223, 66.337103675658, 66.314605082093, 66.292106488527, 66.269607894961, 66.247109301394, + 66.224610707827, 66.202112114259, 66.179613520691, 66.157114927122, 66.134616333553, 66.112117739983, + 66.089619146413, 66.067120552842, 66.044621959271, 66.022123365699, 65.999624772127, 65.977126178555, + 65.954627584982, 65.932128991408, 65.909630397834, 65.887131804260, 65.864633210685, 65.842134617110, + 65.819636023534, 65.797137429958, 65.774638836381, 65.752140242804, 65.729641649226, 65.707143055648, + 65.684644462070, 65.662145868491, 65.639647274911, 65.617148681331, 65.594650087751, 65.572151494170, + 65.549652900589, 65.527154307008, 65.504655713425, 65.482157119843, 65.459658526260, 65.437159932677, + 65.414661339093, 65.392162745508, 65.369664151924, 65.347165558339, 65.324666964753, 65.302168371167, + 65.279669777581, 65.257171183994, 65.234672590406, 65.212173996819, 65.189675403231, 65.167176809642, + 65.144678216053, 65.122179622464, 65.099681028874, 65.077182435284, 65.054683841693, 65.032185248102, + 65.009686654510, 64.987188060918, 64.964689467326, 64.942190873733, 64.919692280140, 64.897193686547, + 64.874695092953, 64.852196499358, 64.829697905764, 64.807199312168, 64.784700718573, 64.762202124977, + 64.739703531380, 64.717204937784, 64.694706344186, 64.672207750589, 64.649709156991, 64.627210563392, + 64.604711969793, 64.582213376194, 64.559714782595, 64.537216188995, 64.514717595394, 64.492219001794, + 64.469720408192, 64.447221814591, 64.424723220989, 64.402224627387, 64.379726033784, 64.357227440181, + 64.334728846577, 64.312230252974, 64.289731659369, 64.267233065765, 64.244734472160, 64.222235878554, + 64.199737284949, 64.177238691342, 64.154740097736, 64.132241504129, 64.109742910522, 64.087244316914, + 64.064745723306, 64.042247129698, 64.019748536089, 63.997249942480, 63.974751348870, 63.952252755261, + 63.929754161650, 63.907255568040, 63.884756974429, 63.862258380818, 63.839759787206, 63.817261193594, + 63.794762599982, 63.772264006369, 63.749765412756, 63.727266819142, 63.704768225528, 63.682269631914, + 63.659771038300, 63.637272444685, 63.614773851070, 63.592275257454, 63.569776663838, 63.547278070222, + 63.524779476605, 63.502280882988, 63.479782289371, 63.457283695753, 63.434785102135, 63.412286508517, + 63.389787914898, 63.367289321279, 63.344790727660, 63.322292134040, 63.299793540420, 63.277294946799, + 63.254796353178, 63.232297759557, 63.209799165936, 63.187300572314, 63.164801978692, 63.142303385070, + 63.119804791447, 63.097306197824, 63.074807604200, 63.052309010576, 63.029810416952, 63.007311823328, + 62.984813229703, 62.962314636078, 62.939816042453, 62.917317448827, 62.894818855201, 62.872320261574, + 62.849821667948, 62.827323074321, 62.804824480693, 62.782325887066, 62.759827293438, 62.737328699809, + 62.714830106181, 62.692331512552, 62.669832918922, 62.647334325293, 62.624835731663, 62.602337138033, + 62.579838544402, 62.557339950771, 62.534841357140, 62.512342763509, 62.489844169877, 62.467345576245, + 62.444846982612, 62.422348388979, 62.399849795346, 62.377351201713, 62.354852608079, 62.332354014446, + 62.309855420811, 62.287356827177, 62.264858233542, 62.242359639907, 62.219861046271, 62.197362452635, + 62.174863858999, 62.152365265363, 62.129866671726, 62.107368078089, 62.084869484452, 62.062370890814, + 62.039872297177, 62.017373703538, 61.994875109900, 61.972376516261, 61.949877922622, 61.927379328983, + 61.904880735343, 61.882382141703, 61.859883548063, 61.837384954423, 61.814886360782, 61.792387767141, + 61.769889173499, 61.747390579858, 61.724891986216, 61.702393392573, 61.679894798931, 61.657396205288, + 61.634897611645, 61.612399018002, 61.589900424358, 61.567401830714, 61.544903237070, 61.522404643425, + 61.499906049781, 61.477407456136, 61.454908862490, 61.432410268845, 61.409911675199, 61.387413081553, + 61.364914487906, 61.342415894260, 61.319917300613, 61.297418706965, 61.274920113318, 61.252421519670, + 61.229922926022, 61.207424332374, 61.184925738725, 61.162427145076, 61.139928551427, 61.117429957777, + 61.094931364128, 61.072432770478, 61.049934176828, 61.027435583177, 61.004936989526, 60.982438395875, + 60.959939802224, 60.937441208572, 60.914942614921, 60.892444021269, 60.869945427616, 60.847446833964, + 60.824948240311, 60.802449646658, 60.779951053004, 60.757452459351, 60.734953865697, 60.712455272043, + 60.689956678388, 60.667458084733, 60.644959491079, 60.622460897423, 60.599962303768, 60.577463710112, + 60.554965116456, 60.532466522800, 60.509967929144, 60.487469335487, 60.464970741830, 60.442472148173, + 60.419973554515, 60.397474960858, 60.374976367200, 60.352477773541, 60.329979179883, 60.307480586224, + 60.284981992565, 60.262483398906, 60.239984805247, 60.217486211587, 60.194987617927, 60.172489024267, + 60.149990430607, 60.127491836946, 60.104993243285, 60.082494649624, 60.059996055963, 60.037497462301, + 60.014998868639, 59.992500274977, 59.970001681315, 59.947503087652, 59.925004493989, 59.902505900326, + 59.880007306663, 59.857508712999, 59.835010119336, 59.812511525672, 59.790012932007, 59.767514338343, + 59.745015744678, 59.722517151013, 59.700018557348, 59.677519963683, 59.655021370017, 59.632522776351, + 59.610024182685, 59.587525589019, 59.565026995352, 59.542528401686, 59.520029808019, 59.497531214351, + 59.475032620684, 59.452534027016, 59.430035433348, 59.407536839680, 59.385038246012, 59.362539652343, + 59.340041058674, 59.317542465005, 59.295043871336, 59.272545277667, 59.250046683997, 59.227548090327, + 59.205049496657, 59.182550902986, 59.160052309316, 59.137553715645, 59.115055121974, 59.092556528303, + 59.070057934631, 59.047559340960, 59.025060747288, 59.002562153616, 58.980063559943, 58.957564966271, + 58.935066372598, 58.912567778925, 58.890069185252, 58.867570591578, 58.845071997905, 58.822573404231, + 58.800074810557, 58.777576216883, 58.755077623208, 58.732579029533, 58.710080435859, 58.687581842183, + 58.665083248508, 58.642584654833, 58.620086061157, 58.597587467481, 58.575088873805, 58.552590280128, + 58.530091686452, 58.507593092775, 58.485094499098, 58.462595905421, 58.440097311744, 58.417598718066, + 58.395100124388, 58.372601530710, 58.350102937032, 58.327604343353, 58.305105749675, 58.282607155996, + 58.260108562317, 58.237609968638, 58.215111374958, 58.192612781279, 58.170114187599, 58.147615593919, + 58.125117000239, 58.102618406558, 58.080119812878, 58.057621219197, 58.035122625516, 58.012624031835, + 57.990125438153, 57.967626844472, 57.945128250790, 57.922629657108, 57.900131063426, 57.877632469743, + 57.855133876061, 57.832635282378, 57.810136688695, 57.787638095012, 57.765139501328, 57.742640907645, + 57.720142313961, 57.697643720277, 57.675145126593, 57.652646532909, 57.630147939224, 57.607649345540, + 57.585150751855, 57.562652158170, 57.540153564484, 57.517654970799, 57.495156377113, 57.472657783427, + 57.450159189741, 57.427660596055, 57.405162002369, 57.382663408682, 57.360164814995, 57.337666221309, + 57.315167627621, 57.292669033934, 57.270170440247, 57.247671846559, 57.225173252871, 57.202674659183, + 57.180176065495, 57.157677471806, 57.135178878118, 57.112680284429, 57.090181690740, 57.067683097051, + 57.045184503362, 57.022685909672, 57.000187315982, 56.977688722293, 56.955190128603, 56.932691534912, + 56.910192941222, 56.887694347531, 56.865195753841, 56.842697160150, 56.820198566459, 56.797699972767, + 56.775201379076, 56.752702785384, 56.730204191692, 56.707705598001, 56.685207004308, 56.662708410616, + 56.640209816924, 56.617711223231, 56.595212629538, 56.572714035845, 56.550215442152, 56.527716848458, + 56.505218254765, 56.482719661071, 56.460221067377, 56.437722473683, 56.415223879989, 56.392725286295, + 56.370226692600, 56.347728098905, 56.325229505211, 56.302730911515, 56.280232317820, 56.257733724125, + 56.235235130429, 56.212736536734, 56.190237943038, 56.167739349342, 56.145240755645, 56.122742161949, + 56.100243568252, 56.077744974556, 56.055246380859, 56.032747787162, 56.010249193465, 55.987750599767, + 55.965252006070, 55.942753412372, 55.920254818674, 55.897756224976, 55.875257631278, 55.852759037579, + 55.830260443881, 55.807761850182, 55.785263256483, 55.762764662784, 55.740266069085, 55.717767475386, + 55.695268881686, 55.672770287987, 55.650271694287, 55.627773100587, 55.605274506887, 55.582775913187, + 55.560277319486, 55.537778725786, 55.515280132085, 55.492781538384, 55.470282944683, 55.447784350982, + 55.425285757280, 55.402787163579, 55.380288569877, 55.357789976175, 55.335291382473, 55.312792788771, + 55.290294195069, 55.267795601366, 55.245297007664, 55.222798413961, 55.200299820258, 55.177801226555, + 55.155302632852, 55.132804039148, 55.110305445445, 55.087806851741, 55.065308258037, 55.042809664333, + 55.020311070629, 54.997812476925, 54.975313883221, 54.952815289516, 54.930316695811, 54.907818102107, + 54.885319508401, 54.862820914696, 54.840322320991, 54.817823727286, 54.795325133580, 54.772826539874, + 54.750327946168, 54.727829352462, 54.705330758756, 54.682832165050, 54.660333571343, 54.637834977637, + 54.615336383930, 54.592837790223, 54.570339196516, 54.547840602809, 54.525342009101, 54.502843415394, + 54.480344821686, 54.457846227978, 54.435347634270, 54.412849040562, 54.390350446854, 54.367851853146, + 54.345353259437, 54.322854665729, 54.300356072020, 54.277857478311, 54.255358884602, 54.232860290893, + 54.210361697183, 54.187863103474, 54.165364509764, 54.142865916054, 54.120367322344, 54.097868728634, + 54.075370134924, 54.052871541214, 54.030372947503, 54.007874353793, 53.985375760082, 53.962877166371, + 53.940378572660, 53.917879978949, 53.895381385238, 53.872882791526, 53.850384197815, 53.827885604103, + 53.805387010391, 53.782888416679, 53.760389822967, 53.737891229255, 53.715392635543, 53.692894041830, + 53.670395448118, 53.647896854405, 53.625398260692, 53.602899666979, 53.580401073266, 53.557902479552, + 53.535403885839, 53.512905292125, 53.490406698412, 53.467908104698, 53.445409510984, 53.422910917270, + 53.400412323556, 53.377913729841, 53.355415136127, 53.332916542412, 53.310417948697, 53.287919354983, + 53.265420761268, 53.242922167552, 53.220423573837, 53.197924980122, 53.175426386406, 53.152927792691, + 53.130429198975, 53.107930605259, 53.085432011543, 53.062933417827, 53.040434824110, 53.017936230394, + 52.995437636678, 52.972939042961, 52.950440449244, 52.927941855527, 52.905443261810, 52.882944668093, + 52.860446074376, 52.837947480658, 52.815448886941, 52.792950293223, 52.770451699505, 52.747953105787, + 52.725454512069, 52.702955918351, 52.680457324633, 52.657958730914, 52.635460137196, 52.612961543477, + 52.590462949759, 52.567964356040, 52.545465762321, 52.522967168601, 52.500468574882, 52.477969981163, + 52.455471387443, 52.432972793724, 52.410474200004, 52.387975606284, 52.365477012564, 52.342978418844, + 52.320479825124, 52.297981231403, 52.275482637683, 52.252984043962, 52.230485450242, 52.207986856521, + 52.185488262800, 52.162989669079, 52.140491075358, 52.117992481636, 52.095493887915, 52.072995294193, + 52.050496700472, 52.027998106750, 52.005499513028, 51.983000919306, 51.960502325584, 51.938003731862, + 51.915505138139, 51.893006544417, 51.870507950694, 51.848009356972, 51.825510763249, 51.803012169526, + 51.780513575803, 51.758014982080, 51.735516388357, 51.713017794633, 51.690519200910, 51.668020607186, + 51.645522013462, 51.623023419738, 51.600524826015, 51.578026232290, 51.555527638566, 51.533029044842, + 51.510530451118, 51.488031857393, 51.465533263668, 51.443034669944, 51.420536076219, 51.398037482494, + 51.375538888769, 51.353040295044, 51.330541701318, 51.308043107593, 51.285544513868, 51.263045920142, + 51.240547326416, 51.218048732690, 51.195550138964, 51.173051545238, 51.150552951512, 51.128054357786, + 51.105555764059, 51.083057170333, 51.060558576606, 51.038059982880, 51.015561389153, 50.993062795426, + 50.970564201699, 50.948065607972, 50.925567014245, 50.903068420517, 50.880569826790, 50.858071233062, + 50.835572639334, 50.813074045607, 50.790575451879, 50.768076858151, 50.745578264423, 50.723079670695, + 50.700581076966, 50.678082483238, 50.655583889509, 50.633085295781, 50.610586702052, 50.588088108323, + 50.565589514594, 50.543090920865, 50.520592327136, 50.498093733407, 50.475595139677, 50.453096545948, + 50.430597952218, 50.408099358489, 50.385600764759, 50.363102171029, 50.340603577299, 50.318104983569, + 50.295606389839, 50.273107796109, 50.250609202378, 50.228110608648, 50.205612014917, 50.183113421187, + 50.160614827456, 50.138116233725, 50.115617639994, 50.093119046263, 50.070620452532, 50.048121858800, + 50.025623265069, 50.003124671337, 49.980626077606, 49.958127483874, 49.935628890142, 49.913130296411, + 49.890631702679, 49.868133108946, 49.845634515214, 49.823135921482, 49.800637327750, 49.778138734017, + 49.755640140285, 49.733141546552, 49.710642952819, 49.688144359086, 49.665645765353, 49.643147171620, + 49.620648577887, 49.598149984154, 49.575651390421, 49.553152796687, 49.530654202954, 49.508155609220, + 49.485657015486, 49.463158421752, 49.440659828018, 49.418161234284, 49.395662640550, 49.373164046816, + 49.350665453082, 49.328166859347, 49.305668265613, 49.283169671878, 49.260671078144, 49.238172484409, + 49.215673890674, 49.193175296939, 49.170676703204, 49.148178109469, 49.125679515734, 49.103180921998, + 49.080682328263, 49.058183734527, 49.035685140792, 49.013186547056, 48.990687953320, 48.968189359584, + 48.945690765848, 48.923192172112, 48.900693578376, 48.878194984640, 48.855696390904, 48.833197797167, + 48.810699203431, 48.788200609694, 48.765702015957, 48.743203422220, 48.720704828484, 48.698206234747, + 48.675707641010, 48.653209047272, 48.630710453535, 48.608211859798, 48.585713266060, 48.563214672323, + 48.540716078585, 48.518217484848, 48.495718891110, 48.473220297372, 48.450721703634, 48.428223109896, + 48.405724516158, 48.383225922419, 48.360727328681, 48.338228734943, 48.315730141204, 48.293231547466, + 48.270732953727, 48.248234359988, 48.225735766249, 48.203237172510, 48.180738578771, 48.158239985032, + 48.135741391293, 48.113242797554, 48.090744203815, 48.068245610075, 48.045747016336, 48.023248422596, + 48.000749828856, 47.978251235116, 47.955752641377, 47.933254047637, 47.910755453897, 47.888256860156, + 47.865758266416, 47.843259672676, 47.820761078935, 47.798262485195, 47.775763891454, 47.753265297714, + 47.730766703973, 47.708268110232, 47.685769516491, 47.663270922750, 47.640772329009, 47.618273735268, + 47.595775141527, 47.573276547786, 47.550777954044, 47.528279360303, 47.505780766561, 47.483282172820, + 47.460783579078, 47.438284985336, 47.415786391594, 47.393287797852, 47.370789204110, 47.348290610368, + 47.325792016626, 47.303293422883, 47.280794829141, 47.258296235399, 47.235797641656, 47.213299047913, + 47.190800454171, 47.168301860428, 47.145803266685, 47.123304672942, 47.100806079199, 47.078307485456, + 47.055808891713, 47.033310297970, 47.010811704226, 46.988313110483, 46.965814516739, 46.943315922996, + 46.920817329252, 46.898318735508, 46.875820141765, 46.853321548021, 46.830822954277, 46.808324360533, + 46.785825766788, 46.763327173044, 46.740828579300, 46.718329985556, 46.695831391811, 46.673332798067, + 46.650834204322, 46.628335610577, 46.605837016833, 46.583338423088, 46.560839829343, 46.538341235598, + 46.515842641853, 46.493344048108, 46.470845454362, 46.448346860617, 46.425848266872, 46.403349673126, + 46.380851079381, 46.358352485635, 46.335853891890, 46.313355298144, 46.290856704398, 46.268358110652, + 46.245859516906, 46.223360923160, 46.200862329414, 46.178363735668, 46.155865141921, 46.133366548175, + 46.110867954429, 46.088369360682, 46.065870766936, 46.043372173189, 46.020873579442, 45.998374985695, + 45.975876391948, 45.953377798202, 45.930879204454, 45.908380610707, 45.885882016960, 45.863383423213, + 45.840884829466, 45.818386235718, 45.795887641971, 45.773389048223, 45.750890454476, 45.728391860728, + 45.705893266980, 45.683394673232, 45.660896079485, 45.638397485737, 45.615898891988, 45.593400298240, + 45.570901704492, 45.548403110744, 45.525904516996, 45.503405923247, 45.480907329499, 45.458408735750, + 45.435910142002, 45.413411548253, 45.390912954504, 45.368414360755, 45.345915767006, 45.323417173257, + 45.300918579508, 45.278419985759, 45.255921392010, 45.233422798261, 45.210924204511, 45.188425610762, + 45.165927017013, 45.143428423263, 45.120929829513, 45.098431235764, 45.075932642014, 45.053434048264, + 45.030935454514, 45.008436860764, 44.985938267014, 44.963439673264, 44.940941079514, 44.918442485764, + 44.895943892014, 44.873445298263, 44.850946704513, 44.828448110762, 44.805949517012, 44.783450923261, + 44.760952329510, 44.738453735760, 44.715955142009, 44.693456548258, 44.670957954507, 44.648459360756, + 44.625960767005, 44.603462173254, 44.580963579502, 44.558464985751, 44.535966392000, 44.513467798248, + 44.490969204497, 44.468470610745, 44.445972016993, 44.423473423242, 44.400974829490, 44.378476235738, + 44.355977641986, 44.333479048234, 44.310980454482, 44.288481860730, 44.265983266978, 44.243484673226, + 44.220986079473, 44.198487485721, 44.175988891969, 44.153490298216, 44.130991704464, 44.108493110711, + 44.085994516958, 44.063495923205, 44.040997329453, 44.018498735700, 43.996000141947, 43.973501548194, + 43.951002954441, 43.928504360688, 43.906005766934, 43.883507173181, 43.861008579428, 43.838509985674, + 43.816011391921, 43.793512798167, 43.771014204414, 43.748515610660, 43.726017016906, 43.703518423153, + 43.681019829399, 43.658521235645, 43.636022641891, 43.613524048137, 43.591025454383, 43.568526860629, + 43.546028266874, 43.523529673120, 43.501031079366, 43.478532485611, 43.456033891857, 43.433535298102, + 43.411036704348, 43.388538110593, 43.366039516838, 43.343540923084, 43.321042329329, 43.298543735574, + 43.276045141819, 43.253546548064, 43.231047954309, 43.208549360554, 43.186050766798, 43.163552173043, + 43.141053579288, 43.118554985532, 43.096056391777, 43.073557798021, 43.051059204266, 43.028560610510, + 43.006062016754, 42.983563422999, 42.961064829243, 42.938566235487, 42.916067641731, 42.893569047975, + 42.871070454219, 42.848571860463, 42.826073266707, 42.803574672951, 42.781076079194, 42.758577485438, + 42.736078891681, 42.713580297925, 42.691081704168, 42.668583110412, 42.646084516655, 42.623585922899, + 42.601087329142, 42.578588735385, 42.556090141628, 42.533591547871, 42.511092954114, 42.488594360357, + 42.466095766600, 42.443597172843, 42.421098579086, 42.398599985328, 42.376101391571, 42.353602797814, + 42.331104204056, 42.308605610299, 42.286107016541, 42.263608422783, 42.241109829026, 42.218611235268, + 42.196112641510, 42.173614047752, 42.151115453994, 42.128616860236, 42.106118266478, 42.083619672720, + 42.061121078962, 42.038622485204, 42.016123891446, 41.993625297687, 41.971126703929, 41.948628110170, + 41.926129516412, 41.903630922653, 41.881132328895, 41.858633735136, 41.836135141378, 41.813636547619, + 41.791137953860, 41.768639360101, 41.746140766342, 41.723642172583, 41.701143578824, 41.678644985065, + 41.656146391306, 41.633647797547, 41.611149203787, 41.588650610028, 41.566152016269, 41.543653422509, + 41.521154828750, 41.498656234990, 41.476157641231, 41.453659047471, 41.431160453711, 41.408661859952, + 41.386163266192, 41.363664672432, 41.341166078672, 41.318667484912, 41.296168891152, 41.273670297392, + 41.251171703632, 41.228673109872, 41.206174516111, 41.183675922351, 41.161177328591, 41.138678734830, + 41.116180141070, 41.093681547309, 41.071182953549, 41.048684359788, 41.026185766028, 41.003687172267, + 40.981188578506, 40.958689984745, 40.936191390984, 40.913692797224, 40.891194203463, 40.868695609702, + 40.846197015940, 40.823698422179, 40.801199828418, 40.778701234657, 40.756202640896, 40.733704047134, + 40.711205453373, 40.688706859611, 40.666208265850, 40.643709672088, 40.621211078327, 40.598712484565, + 40.576213890803, 40.553715297042, 40.531216703280, 40.508718109518, 40.486219515756, 40.463720921994, + 40.441222328232, 40.418723734470, 40.396225140708, 40.373726546946, 40.351227953184, 40.328729359421, + 40.306230765659, 40.283732171897, 40.261233578134, 40.238734984372, 40.216236390609, 40.193737796847, + 40.171239203084, 40.148740609322, 40.126242015559, 40.103743421796, 40.081244828033, 40.058746234270, + 40.036247640508, 40.013749046745, 39.991250452982, 39.968751859218, 39.946253265455, 39.923754671692, + 39.901256077929, 39.878757484166, 39.856258890402, 39.833760296639, 39.811261702876, 39.788763109112, + 39.766264515349, 39.743765921585, 39.721267327822, 39.698768734058, 39.676270140294, 39.653771546531, + 39.631272952767, 39.608774359003, 39.586275765239, 39.563777171475, 39.541278577711, 39.518779983947, + 39.496281390183, 39.473782796419, 39.451284202655, 39.428785608891, 39.406287015126, 39.383788421362, + 39.361289827598, 39.338791233833, 39.316292640069, 39.293794046304, 39.271295452540, 39.248796858775, + 39.226298265010, 39.203799671246, 39.181301077481, 39.158802483716, 39.136303889951, 39.113805296187, + 39.091306702422, 39.068808108657, 39.046309514892, 39.023810921127, 39.001312327361, 38.978813733596, + 38.956315139831, 38.933816546066, 38.911317952301, 38.888819358535, 38.866320764770, 38.843822171004, + 38.821323577239, 38.798824983473, 38.776326389708, 38.753827795942, 38.731329202177, 38.708830608411, + 38.686332014645, 38.663833420879, 38.641334827113, 38.618836233348, 38.596337639582, 38.573839045816, + 38.551340452050, 38.528841858284, 38.506343264517, 38.483844670751, 38.461346076985, 38.438847483219, + 38.416348889453, 38.393850295686, 38.371351701920, 38.348853108153, 38.326354514387, 38.303855920620, + 38.281357326854, 38.258858733087, 38.236360139321, 38.213861545554, 38.191362951787, 38.168864358020, + 38.146365764254, 38.123867170487, 38.101368576720, 38.078869982953, 38.056371389186, 38.033872795419, + 38.011374201652, 37.988875607885, 37.966377014117, 37.943878420350, 37.921379826583, 37.898881232816, + 37.876382639048, 37.853884045281, 37.831385451513, 37.808886857746, 37.786388263978, 37.763889670211, + 37.741391076443, 37.718892482676, 37.696393888908, 37.673895295140, 37.651396701372, 37.628898107605, + 37.606399513837, 37.583900920069, 37.561402326301, 37.538903732533, 37.516405138765, 37.493906544997, + 37.471407951229, 37.448909357461, 37.426410763692, 37.403912169924, 37.381413576156, 37.358914982388, + 37.336416388619, 37.313917794851, 37.291419201082, 37.268920607314, 37.246422013545, 37.223923419777, + 37.201424826008, 37.178926232240, 37.156427638471, 37.133929044702, 37.111430450933, 37.088931857164, + 37.066433263396, 37.043934669627, 37.021436075858, 36.998937482089, 36.976438888320, 36.953940294551, + 36.931441700782, 36.908943107012, 36.886444513243, 36.863945919474, 36.841447325705, 36.818948731936, + 36.796450138166, 36.773951544397, 36.751452950627, 36.728954356858, 36.706455763088, 36.683957169319, + 36.661458575549, 36.638959981780, 36.616461388010, 36.593962794240, 36.571464200471, 36.548965606701, + 36.526467012931, 36.503968419161, 36.481469825391, 36.458971231621, 36.436472637851, 36.413974044081, + 36.391475450311, 36.368976856541, 36.346478262771, 36.323979669001, 36.301481075230, 36.278982481460, + 36.256483887690, 36.233985293920, 36.211486700149, 36.188988106379, 36.166489512608, 36.143990918838, + 36.121492325067, 36.098993731297, 36.076495137526, 36.053996543756, 36.031497949985, 36.008999356214, + 35.986500762443, 35.964002168673, 35.941503574902, 35.919004981131, 35.896506387360, 35.874007793589, + 35.851509199818, 35.829010606047, 35.806512012276, 35.784013418505, 35.761514824734, 35.739016230963, + 35.716517637191, 35.694019043420, 35.671520449649, 35.649021855877, 35.626523262106, 35.604024668335, + 35.581526074563, 35.559027480792, 35.536528887020, 35.514030293249, 35.491531699477, 35.469033105705, + 35.446534511934, 35.424035918162, 35.401537324390, 35.379038730619, 35.356540136847, 35.334041543075, + 35.311542949303, 35.289044355531, 35.266545761759, 35.244047167987, 35.221548574215, 35.199049980443, + 35.176551386671, 35.154052792899, 35.131554199127, 35.109055605354, 35.086557011582, 35.064058417810, + 35.041559824038, 35.019061230265, 34.996562636493, 34.974064042720, 34.951565448948, 34.929066855175, + 34.906568261403, 34.884069667630, 34.861571073858, 34.839072480085, 34.816573886312, 34.794075292540, + 34.771576698767, 34.749078104994, 34.726579511221, 34.704080917448, 34.681582323676, 34.659083729903, + 34.636585136130, 34.614086542357, 34.591587948584, 34.569089354811, 34.546590761037, 34.524092167264, + 34.501593573491, 34.479094979718, 34.456596385945, 34.434097792171, 34.411599198398, 34.389100604625, + 34.366602010851, 34.344103417078, 34.321604823304, 34.299106229531, 34.276607635757, 34.254109041984, + 34.231610448210, 34.209111854437, 34.186613260663, 34.164114666889, 34.141616073116, 34.119117479342, + 34.096618885568, 34.074120291794, 34.051621698020, 34.029123104246, 34.006624510473, 33.984125916699, + 33.961627322925, 33.939128729151, 33.916630135376, 33.894131541602, 33.871632947828, 33.849134354054, + 33.826635760280, 33.804137166506, 33.781638572731, 33.759139978957, 33.736641385183, 33.714142791408, + 33.691644197634, 33.669145603860, 33.646647010085, 33.624148416311, 33.601649822536, 33.579151228761, + 33.556652634987, 33.534154041212, 33.511655447438, 33.489156853663, 33.466658259888, 33.444159666113, + 33.421661072339, 33.399162478564, 33.376663884789, 33.354165291014, 33.331666697239, 33.309168103464, + 33.286669509689, 33.264170915914, 33.241672322139, 33.219173728364, 33.196675134589, 33.174176540814, + 33.151677947038, 33.129179353263, 33.106680759488, 33.084182165713, 33.061683571937, 33.039184978162, + 33.016686384387, 32.994187790611, 32.971689196836, 32.949190603060, 32.926692009285, 32.904193415509, + 32.881694821734, 32.859196227958, 32.836697634183, 32.814199040407, 32.791700446631, 32.769201852855, + 32.746703259080, 32.724204665304, 32.701706071528, 32.679207477752, 32.656708883976, 32.634210290200, + 32.611711696424, 32.589213102648, 32.566714508872, 32.544215915096, 32.521717321320, 32.499218727544, + 32.476720133768, 32.454221539992, 32.431722946216, 32.409224352440, 32.386725758663, 32.364227164887, + 32.341728571111, 32.319229977334, 32.296731383558, 32.274232789782, 32.251734196005, 32.229235602229, + 32.206737008452, 32.184238414676, 32.161739820899, 32.139241227122, 32.116742633346, 32.094244039569, + 32.071745445793, 32.049246852016, 32.026748258239, 32.004249664462, 31.981751070685, 31.959252476909, + 31.936753883132, 31.914255289355, 31.891756695578, 31.869258101801, 31.846759508024, 31.824260914247, + 31.801762320470, 31.779263726693, 31.756765132916, 31.734266539139, 31.711767945362, 31.689269351584, + 31.666770757807, 31.644272164030, 31.621773570253, 31.599274976475, 31.576776382698, 31.554277788921, + 31.531779195143, 31.509280601366, 31.486782007588, 31.464283413811, 31.441784820033, 31.419286226256, + 31.396787632478, 31.374289038701, 31.351790444923, 31.329291851145, 31.306793257368, 31.284294663590, + 31.261796069812, 31.239297476034, 31.216798882257, 31.194300288479, 31.171801694701, 31.149303100923, + 31.126804507145, 31.104305913367, 31.081807319589, 31.059308725811, 31.036810132033, 31.014311538255, + 30.991812944477, 30.969314350699, 30.946815756921, 30.924317163143, 30.901818569365, 30.879319975586, + 30.856821381808, 30.834322788030, 30.811824194251, 30.789325600473, 30.766827006695, 30.744328412916, + 30.721829819138, 30.699331225360, 30.676832631581, 30.654334037803, 30.631835444024, 30.609336850245, + 30.586838256467, 30.564339662688, 30.541841068910, 30.519342475131, 30.496843881352, 30.474345287574, + 30.451846693795, 30.429348100016, 30.406849506237, 30.384350912458, 30.361852318680, 30.339353724901, + 30.316855131122, 30.294356537343, 30.271857943564, 30.249359349785, 30.226860756006, 30.204362162227, + 30.181863568448, 30.159364974669, 30.136866380889, 30.114367787110, 30.091869193331, 30.069370599552, + 30.046872005773, 30.024373411993, 30.001874818214, 29.979376224435, 29.956877630656, 29.934379036876, + 29.911880443097, 29.889381849317, 29.866883255538, 29.844384661758, 29.821886067979, 29.799387474199, + 29.776888880420, 29.754390286640, 29.731891692861, 29.709393099081, 29.686894505301, 29.664395911522, + 29.641897317742, 29.619398723962, 29.596900130182, 29.574401536403, 29.551902942623, 29.529404348843, + 29.506905755063, 29.484407161283, 29.461908567503, 29.439409973723, 29.416911379943, 29.394412786163, + 29.371914192383, 29.349415598603, 29.326917004823, 29.304418411043, 29.281919817263, 29.259421223483, + 29.236922629703, 29.214424035923, 29.191925442142, 29.169426848362, 29.146928254582, 29.124429660802, + 29.101931067021, 29.079432473241, 29.056933879461, 29.034435285680, 29.011936691900, 28.989438098119, + 28.966939504339, 28.944440910558, 28.921942316778, 28.899443722997, 28.876945129217, 28.854446535436, + 28.831947941655, 28.809449347875, 28.786950754094, 28.764452160313, 28.741953566533, 28.719454972752, + 28.696956378971, 28.674457785190, 28.651959191410, 28.629460597629, 28.606962003848, 28.584463410067, + 28.561964816286, 28.539466222505, 28.516967628724, 28.494469034943, 28.471970441162, 28.449471847381, + 28.426973253600, 28.404474659819, 28.381976066038, 28.359477472257, 28.336978878476, 28.314480284694, + 28.291981690913, 28.269483097132, 28.246984503351, 28.224485909569, 28.201987315788, 28.179488722007, + 28.156990128225, 28.134491534444, 28.111992940663, 28.089494346881, 28.066995753100, 28.044497159318, + 28.021998565537, 27.999499971755, 27.977001377974, 27.954502784192, 27.932004190411, 27.909505596629, + 27.887007002847, 27.864508409066, 27.842009815284, 27.819511221502, 27.797012627721, 27.774514033939, + 27.752015440157, 27.729516846375, 27.707018252594, 27.684519658812, 27.662021065030, 27.639522471248, + 27.617023877466, 27.594525283684, 27.572026689902, 27.549528096120, 27.527029502338, 27.504530908556, + 27.482032314774, 27.459533720992, 27.437035127210, 27.414536533428, 27.392037939646, 27.369539345863, + 27.347040752081, 27.324542158299, 27.302043564517, 27.279544970735, 27.257046376952, 27.234547783170, + 27.212049189388, 27.189550595605, 27.167052001823, 27.144553408041, 27.122054814258, 27.099556220476, + 27.077057626693, 27.054559032911, 27.032060439128, 27.009561845346, 26.987063251563, 26.964564657781, + 26.942066063998, 26.919567470216, 26.897068876433, 26.874570282650, 26.852071688868, 26.829573095085, + 26.807074501302, 26.784575907519, 26.762077313737, 26.739578719954, 26.717080126171, 26.694581532388, + 26.672082938605, 26.649584344823, 26.627085751040, 26.604587157257, 26.582088563474, 26.559589969691, + 26.537091375908, 26.514592782125, 26.492094188342, 26.469595594559, 26.447097000776, 26.424598406993, + 26.402099813210, 26.379601219426, 26.357102625643, 26.334604031860, 26.312105438077, 26.289606844294, + 26.267108250510, 26.244609656727, 26.222111062944, 26.199612469161, 26.177113875377, 26.154615281594, + 26.132116687811, 26.109618094027, 26.087119500244, 26.064620906460, 26.042122312677, 26.019623718893, + 25.997125125110, 25.974626531326, 25.952127937543, 25.929629343759, 25.907130749976, 25.884632156192, + 25.862133562409, 25.839634968625, 25.817136374841, 25.794637781058, 25.772139187274, 25.749640593490, + 25.727141999706, 25.704643405923, 25.682144812139, 25.659646218355, 25.637147624571, 25.614649030787, + 25.592150437004, 25.569651843220, 25.547153249436, 25.524654655652, 25.502156061868, 25.479657468084, + 25.457158874300, 25.434660280516, 25.412161686732, 25.389663092948, 25.367164499164, 25.344665905380, + 25.322167311596, 25.299668717812, 25.277170124027, 25.254671530243, 25.232172936459, 25.209674342675, + 25.187175748891, 25.164677155106, 25.142178561322, 25.119679967538, 25.097181373754, 25.074682779969, + 25.052184186185, 25.029685592401, 25.007186998616, 24.984688404832, 24.962189811047, 24.939691217263, + 24.917192623479, 24.894694029694, 24.872195435910, 24.849696842125, 24.827198248340, 24.804699654556, + 24.782201060771, 24.759702466987, 24.737203873202, 24.714705279418, 24.692206685633, 24.669708091848, + 24.647209498064, 24.624710904279, 24.602212310494, 24.579713716709, 24.557215122925, 24.534716529140, + 24.512217935355, 24.489719341570, 24.467220747785, 24.444722154000, 24.422223560216, 24.399724966431, + 24.377226372646, 24.354727778861, 24.332229185076, 24.309730591291, 24.287231997506, 24.264733403721, + 24.242234809936, 24.219736216151, 24.197237622366, 24.174739028581, 24.152240434796, 24.129741841010, + 24.107243247225, 24.084744653440, 24.062246059655, 24.039747465870, 24.017248872085, 23.994750278299, + 23.972251684514, 23.949753090729, 23.927254496944, 23.904755903158, 23.882257309373, 23.859758715588, + 23.837260121802, 23.814761528017, 23.792262934231, 23.769764340446, 23.747265746661, 23.724767152875, + 23.702268559090, 23.679769965304, 23.657271371519, 23.634772777733, 23.612274183948, 23.589775590162, + 23.567276996376, 23.544778402591, 23.522279808805, 23.499781215020, 23.477282621234, 23.454784027448, + 23.432285433663, 23.409786839877, 23.387288246091, 23.364789652305, 23.342291058520, 23.319792464734, + 23.297293870948, 23.274795277162, 23.252296683376, 23.229798089591, 23.207299495805, 23.184800902019, + 23.162302308233, 23.139803714447, 23.117305120661, 23.094806526875, 23.072307933089, 23.049809339303, + 23.027310745517, 23.004812151731, 22.982313557945, 22.959814964159, 22.937316370373, 22.914817776587, + 22.892319182801, 22.869820589015, 22.847321995229, 22.824823401442, 22.802324807656, 22.779826213870, + 22.757327620084, 22.734829026298, 22.712330432511, 22.689831838725, 22.667333244939, 22.644834651153, + 22.622336057366, 22.599837463580, 22.577338869794, 22.554840276007, 22.532341682221, 22.509843088434, + 22.487344494648, 22.464845900862, 22.442347307075, 22.419848713289, 22.397350119502, 22.374851525716, + 22.352352931929, 22.329854338143, 22.307355744356, 22.284857150570, 22.262358556783, 22.239859962996, + 22.217361369210, 22.194862775423, 22.172364181637, 22.149865587850, 22.127366994063, 22.104868400277, + 22.082369806490, 22.059871212703, 22.037372618916, 22.014874025130, 21.992375431343, 21.969876837556, + 21.947378243769, 21.924879649982, 21.902381056196, 21.879882462409, 21.857383868622, 21.834885274835, + 21.812386681048, 21.789888087261, 21.767389493474, 21.744890899687, 21.722392305900, 21.699893712113, + 21.677395118326, 21.654896524539, 21.632397930752, 21.609899336965, 21.587400743178, 21.564902149391, + 21.542403555604, 21.519904961817, 21.497406368030, 21.474907774243, 21.452409180455, 21.429910586668, + 21.407411992881, 21.384913399094, 21.362414805307, 21.339916211519, 21.317417617732, 21.294919023945, + 21.272420430158, 21.249921836370, 21.227423242583, 21.204924648796, 21.182426055008, 21.159927461221, + 21.137428867434, 21.114930273646, 21.092431679859, 21.069933086071, 21.047434492284, 21.024935898497, + 21.002437304709, 20.979938710922, 20.957440117134, 20.934941523347, 20.912442929559, 20.889944335772, + 20.867445741984, 20.844947148196, 20.822448554409, 20.799949960621, 20.777451366834, 20.754952773046, + 20.732454179258, 20.709955585471, 20.687456991683, 20.664958397895, 20.642459804108, 20.619961210320, + 20.597462616532, 20.574964022744, 20.552465428957, 20.529966835169, 20.507468241381, 20.484969647593, + 20.462471053805, 20.439972460018, 20.417473866230, 20.394975272442, 20.372476678654, 20.349978084866, + 20.327479491078, 20.304980897290, 20.282482303502, 20.259983709714, 20.237485115926, 20.214986522138, + 20.192487928350, 20.169989334562, 20.147490740774, 20.124992146986, 20.102493553198, 20.079994959410, + 20.057496365622, 20.034997771834, 20.012499178046, 19.990000584258, 19.967501990470, 19.945003396681, + 19.922504802893, 19.900006209105, 19.877507615317, 19.855009021529, 19.832510427740, 19.810011833952, + 19.787513240164, 19.765014646376, 19.742516052587, 19.720017458799, 19.697518865011, 19.675020271223, + 19.652521677434, 19.630023083646, 19.607524489857, 19.585025896069, 19.562527302281, 19.540028708492, + 19.517530114704, 19.495031520915, 19.472532927127, 19.450034333339, 19.427535739550, 19.405037145762, + 19.382538551973, 19.360039958185, 19.337541364396, 19.315042770607, 19.292544176819, 19.270045583030, + 19.247546989242, 19.225048395453, 19.202549801665, 19.180051207876, 19.157552614087, 19.135054020299, + 19.112555426510, 19.090056832721, 19.067558238933, 19.045059645144, 19.022561051355, 19.000062457566, + 18.977563863778, 18.955065269989, 18.932566676200, 18.910068082411, 18.887569488623, 18.865070894834, + 18.842572301045, 18.820073707256, 18.797575113467, 18.775076519678, 18.752577925889, 18.730079332101, + 18.707580738312, 18.685082144523, 18.662583550734, 18.640084956945, 18.617586363156, 18.595087769367, + 18.572589175578, 18.550090581789, 18.527591988000, 18.505093394211, 18.482594800422, 18.460096206633, + 18.437597612844, 18.415099019055, 18.392600425266, 18.370101831477, 18.347603237687, 18.325104643898, + 18.302606050109, 18.280107456320, 18.257608862531, 18.235110268742, 18.212611674953, 18.190113081163, + 18.167614487374, 18.145115893585, 18.122617299796, 18.100118706006, 18.077620112217, 18.055121518428, + 18.032622924639, 18.010124330849, 17.987625737060, 17.965127143271, 17.942628549481, 17.920129955692, + 17.897631361903, 17.875132768113, 17.852634174324, 17.830135580535, 17.807636986745, 17.785138392956, + 17.762639799166, 17.740141205377, 17.717642611587, 17.695144017798, 17.672645424008, 17.650146830219, + 17.627648236429, 17.605149642640, 17.582651048850, 17.560152455061, 17.537653861271, 17.515155267482, + 17.492656673692, 17.470158079903, 17.447659486113, 17.425160892323, 17.402662298534, 17.380163704744, + 17.357665110954, 17.335166517165, 17.312667923375, 17.290169329585, 17.267670735796, 17.245172142006, + 17.222673548216, 17.200174954427, 17.177676360637, 17.155177766847, 17.132679173057, 17.110180579267, + 17.087681985478, 17.065183391688, 17.042684797898, 17.020186204108, 16.997687610318, 16.975189016529, + 16.952690422739, 16.930191828949, 16.907693235159, 16.885194641369, 16.862696047579, 16.840197453789, + 16.817698859999, 16.795200266209, 16.772701672419, 16.750203078629, 16.727704484839, 16.705205891049, + 16.682707297259, 16.660208703469, 16.637710109679, 16.615211515889, 16.592712922099, 16.570214328309, + 16.547715734519, 16.525217140729, 16.502718546939, 16.480219953149, 16.457721359359, 16.435222765569, + 16.412724171779, 16.390225577989, 16.367726984198, 16.345228390408, 16.322729796618, 16.300231202828, + 16.277732609038, 16.255234015247, 16.232735421457, 16.210236827667, 16.187738233877, 16.165239640086, + 16.142741046296, 16.120242452506, 16.097743858716, 16.075245264925, 16.052746671135, 16.030248077345, + 16.007749483554, 15.985250889764, 15.962752295974, 15.940253702183, 15.917755108393, 15.895256514603, + 15.872757920812, 15.850259327022, 15.827760733231, 15.805262139441, 15.782763545651, 15.760264951860, + 15.737766358070, 15.715267764279, 15.692769170489, 15.670270576698, 15.647771982908, 15.625273389117, + 15.602774795327, 15.580276201536, 15.557777607746, 15.535279013955, 15.512780420165, 15.490281826374, + 15.467783232583, 15.445284638793, 15.422786045002, 15.400287451212, 15.377788857421, 15.355290263630, + 15.332791669840, 15.310293076049, 15.287794482258, 15.265295888468, 15.242797294677, 15.220298700886, + 15.197800107096, 15.175301513305, 15.152802919514, 15.130304325724, 15.107805731933, 15.085307138142, + 15.062808544351, 15.040309950560, 15.017811356770, 14.995312762979, 14.972814169188, 14.950315575397, + 14.927816981606, 14.905318387816, 14.882819794025, 14.860321200234, 14.837822606443, 14.815324012652, + 14.792825418861, 14.770326825070, 14.747828231280, 14.725329637489, 14.702831043698, 14.680332449907, + 14.657833856116, 14.635335262325, 14.612836668534, 14.590338074743, 14.567839480952, 14.545340887161, + 14.522842293370, 14.500343699579, 14.477845105788, 14.455346511997, 14.432847918206, 14.410349324415, + 14.387850730624, 14.365352136833, 14.342853543042, 14.320354949251, 14.297856355460, 14.275357761668, + 14.252859167877, 14.230360574086, 14.207861980295, 14.185363386504, 14.162864792713, 14.140366198922, + 14.117867605131, 14.095369011339, 14.072870417548, 14.050371823757, 14.027873229966, 14.005374636175, + 13.982876042383, 13.960377448592, 13.937878854801, 13.915380261010, 13.892881667218, 13.870383073427, + 13.847884479636, 13.825385885845, 13.802887292053, 13.780388698262, 13.757890104471, 13.735391510679, + 13.712892916888, 13.690394323097, 13.667895729305, 13.645397135514, 13.622898541723, 13.600399947931, + 13.577901354140, 13.555402760348, 13.532904166557, 13.510405572766, 13.487906978974, 13.465408385183, + 13.442909791391, 13.420411197600, 13.397912603809, 13.375414010017, 13.352915416226, 13.330416822434, + 13.307918228643, 13.285419634851, 13.262921041060, 13.240422447268, 13.217923853477, 13.195425259685, + 13.172926665894, 13.150428072102, 13.127929478310, 13.105430884519, 13.082932290727, 13.060433696936, + 13.037935103144, 13.015436509353, 12.992937915561, 12.970439321769, 12.947940727978, 12.925442134186, + 12.902943540394, 12.880444946603, 12.857946352811, 12.835447759019, 12.812949165228, 12.790450571436, + 12.767951977644, 12.745453383853, 12.722954790061, 12.700456196269, 12.677957602478, 12.655459008686, + 12.632960414894, 12.610461821102, 12.587963227311, 12.565464633519, 12.542966039727, 12.520467445935, + 12.497968852144, 12.475470258352, 12.452971664560, 12.430473070768, 12.407974476976, 12.385475883184, + 12.362977289393, 12.340478695601, 12.317980101809, 12.295481508017, 12.272982914225, 12.250484320433, + 12.227985726641, 12.205487132850, 12.182988539058, 12.160489945266, 12.137991351474, 12.115492757682, + 12.092994163890, 12.070495570098, 12.047996976306, 12.025498382514, 12.002999788722, 11.980501194930, + 11.958002601138, 11.935504007346, 11.913005413554, 11.890506819762, 11.868008225970, 11.845509632178, + 11.823011038386, 11.800512444594, 11.778013850802, 11.755515257010, 11.733016663218, 11.710518069426, + 11.688019475634, 11.665520881842, 11.643022288050, 11.620523694258, 11.598025100466, 11.575526506674, + 11.553027912882, 11.530529319089, 11.508030725297, 11.485532131505, 11.463033537713, 11.440534943921, + 11.418036350129, 11.395537756337, 11.373039162544, 11.350540568752, 11.328041974960, 11.305543381168, + 11.283044787376, 11.260546193583, 11.238047599791, 11.215549005999, 11.193050412207, 11.170551818415, + 11.148053224622, 11.125554630830, 11.103056037038, 11.080557443246, 11.058058849453, 11.035560255661, + 11.013061661869, 10.990563068076, 10.968064474284, 10.945565880492, 10.923067286700, 10.900568692907, + 10.878070099115, 10.855571505323, 10.833072911530, 10.810574317738, 10.788075723946, 10.765577130153, + 10.743078536361, 10.720579942568, 10.698081348776, 10.675582754984, 10.653084161191, 10.630585567399, + 10.608086973607, 10.585588379814, 10.563089786022, 10.540591192229, 10.518092598437, 10.495594004644, + 10.473095410852, 10.450596817059, 10.428098223267, 10.405599629475, 10.383101035682, 10.360602441890, + 10.338103848097, 10.315605254305, 10.293106660512, 10.270608066720, 10.248109472927, 10.225610879135, + 10.203112285342, 10.180613691550, 10.158115097757, 10.135616503965, 10.113117910172, 10.090619316379, + 10.068120722587, 10.045622128794, 10.023123535002, 10.000624941209, 9.978126347417, 9.955627753624, + 9.933129159831, 9.910630566039, 9.888131972246, 9.865633378454, 9.843134784661, 9.820636190868, 9.798137597076, + 9.775639003283, 9.753140409490, 9.730641815698, 9.708143221905, 9.685644628112, 9.663146034320, 9.640647440527, + 9.618148846734, 9.595650252942, 9.573151659149, 9.550653065356, 9.528154471564, 9.505655877771, 9.483157283978, + 9.460658690185, 9.438160096393, 9.415661502600, 9.393162908807, 9.370664315014, 9.348165721222, 9.325667127429, + 9.303168533636, 9.280669939843, 9.258171346051, 9.235672752258, 9.213174158465, 9.190675564672, 9.168176970879, + 9.145678377087, 9.123179783294, 9.100681189501, 9.078182595708, 9.055684001915, 9.033185408123, 9.010686814330, + 8.988188220537, 8.965689626744, 8.943191032951, 8.920692439158, 8.898193845365, 8.875695251573, 8.853196657780, + 8.830698063987, 8.808199470194, 8.785700876401, 8.763202282608, 8.740703688815, 8.718205095022, 8.695706501229, + 8.673207907436, 8.650709313643, 8.628210719851, 8.605712126058, 8.583213532265, 8.560714938472, 8.538216344679, + 8.515717750886, 8.493219157093, 8.470720563300, 8.448221969507, 8.425723375714, 8.403224781921, 8.380726188128, + 8.358227594335, 8.335729000542, 8.313230406749, 8.290731812956, 8.268233219163, 8.245734625370, 8.223236031577, + 8.200737437784, 8.178238843991, 8.155740250198, 8.133241656405, 8.110743062612, 8.088244468819, 8.065745875025, + 8.043247281232, 8.020748687439, 7.998250093646, 7.975751499853, 7.953252906060, 7.930754312267, 7.908255718474, + 7.885757124681, 7.863258530888, 7.840759937095, 7.818261343301, 7.795762749508, 7.773264155715, 7.750765561922, + 7.728266968129, 7.705768374336, 7.683269780543, 7.660771186750, 7.638272592956, 7.615773999163, 7.593275405370, + 7.570776811577, 7.548278217784, 7.525779623991, 7.503281030197, 7.480782436404, 7.458283842611, 7.435785248818, + 7.413286655025, 7.390788061231, 7.368289467438, 7.345790873645, 7.323292279852, 7.300793686058, 7.278295092265, + 7.255796498472, 7.233297904679, 7.210799310886, 7.188300717092, 7.165802123299, 7.143303529506, 7.120804935713, + 7.098306341919, 7.075807748126, 7.053309154333, 7.030810560539, 7.008311966746, 6.985813372953, 6.963314779160, + 6.940816185366, 6.918317591573, 6.895818997780, 6.873320403986, 6.850821810193, 6.828323216400, 6.805824622606, + 6.783326028813, 6.760827435020, 6.738328841226, 6.715830247433, 6.693331653640, 6.670833059846, 6.648334466053, + 6.625835872260, 6.603337278466, 6.580838684673, 6.558340090880, 6.535841497086, 6.513342903293, 6.490844309500, + 6.468345715706, 6.445847121913, 6.423348528119, 6.400849934326, 6.378351340533, 6.355852746739, 6.333354152946, + 6.310855559152, 6.288356965359, 6.265858371566, 6.243359777772, 6.220861183979, 6.198362590185, 6.175863996392, + 6.153365402598, 6.130866808805, 6.108368215011, 6.085869621218, 6.063371027425, 6.040872433631, 6.018373839838, + 5.995875246044, 5.973376652251, 5.950878058457, 5.928379464664, 5.905880870870, 5.883382277077, 5.860883683283, + 5.838385089490, 5.815886495696, 5.793387901903, 5.770889308109, 5.748390714316, 5.725892120522, 5.703393526729, + 5.680894932935, 5.658396339142, 5.635897745348, 5.613399151555, 5.590900557761, 5.568401963968, 5.545903370174, + 5.523404776381, 5.500906182587, 5.478407588794, 5.455908995000, 5.433410401207, 5.410911807413, 5.388413213619, + 5.365914619826, 5.343416026032, 5.320917432239, 5.298418838445, 5.275920244652, 5.253421650858, 5.230923057064, + 5.208424463271, 5.185925869477, 5.163427275684, 5.140928681890, 5.118430088097, 5.095931494303, 5.073432900509, + 5.050934306716, 5.028435712922, 5.005937119128, 4.983438525335, 4.960939931541, 4.938441337748, 4.915942743954, + 4.893444150160, 4.870945556367, 4.848446962573, 4.825948368780, 4.803449774986, 4.780951181192, 4.758452587399, + 4.735953993605, 4.713455399811, 4.690956806018, 4.668458212224, 4.645959618430, 4.623461024637, 4.600962430843, + 4.578463837049, 4.555965243256, 4.533466649462, 4.510968055668, 4.488469461875, 4.465970868081, 4.443472274287, + 4.420973680494, 4.398475086700, 4.375976492906, 4.353477899113, 4.330979305319, 4.308480711525, 4.285982117731, + 4.263483523938, 4.240984930144, 4.218486336350, 4.195987742557, 4.173489148763, 4.150990554969, 4.128491961175, + 4.105993367382, 4.083494773588, 4.060996179794, 4.038497586001, 4.015998992207, 3.993500398413, 3.971001804619, + 3.948503210826, 3.926004617032, 3.903506023238, 3.881007429444, 3.858508835651, 3.836010241857, 3.813511648063, + 3.791013054269, 3.768514460476, 3.746015866682, 3.723517272888, 3.701018679094, 3.678520085301, 3.656021491507, + 3.633522897713, 3.611024303919, 3.588525710126, 3.566027116332, 3.543528522538, 3.521029928744, 3.498531334950, + 3.476032741157, 3.453534147363, 3.431035553569, 3.408536959775, 3.386038365981, 3.363539772188, 3.341041178394, + 3.318542584600, 3.296043990806, 3.273545397012, 3.251046803219, 3.228548209425, 3.206049615631, 3.183551021837, + 3.161052428043, 3.138553834250, 3.116055240456, 3.093556646662, 3.071058052868, 3.048559459074, 3.026060865281, + 3.003562271487, 2.981063677693, 2.958565083899, 2.936066490105, 2.913567896311, 2.891069302518, 2.868570708724, + 2.846072114930, 2.823573521136, 2.801074927342, 2.778576333548, 2.756077739754, 2.733579145961, 2.711080552167, + 2.688581958373, 2.666083364579, 2.643584770785, 2.621086176991, 2.598587583198, 2.576088989404, 2.553590395610, + 2.531091801816, 2.508593208022, 2.486094614228, 2.463596020434, 2.441097426640, 2.418598832847, 2.396100239053, + 2.373601645259, 2.351103051465, 2.328604457671, 2.306105863877, 2.283607270083, 2.261108676289, 2.238610082496, + 2.216111488702, 2.193612894908, 2.171114301114, 2.148615707320, 2.126117113526, 2.103618519732, 2.081119925938, + 2.058621332145, 2.036122738351, 2.013624144557, 1.991125550763, 1.968626956969, 1.946128363175, 1.923629769381, + 1.901131175587, 1.878632581793, 1.856133987999, 1.833635394206, 1.811136800412, 1.788638206618, 1.766139612824, + 1.743641019030, 1.721142425236, 1.698643831442, 1.676145237648, 1.653646643854, 1.631148050060, 1.608649456266, + 1.586150862473, 1.563652268679, 1.541153674885, 1.518655081091, 1.496156487297, 1.473657893503, 1.451159299709, + 1.428660705915, 1.406162112121, 1.383663518327, 1.361164924533, 1.338666330739, 1.316167736946, 1.293669143152, + 1.271170549358, 1.248671955564, 1.226173361770, 1.203674767976, 1.181176174182, 1.158677580388, 1.136178986594, + 1.113680392800, 1.091181799006, 1.068683205212, 1.046184611418, 1.023686017624, 1.001187423830, 0.978688830037, + 0.956190236243, 0.933691642449, 0.911193048655, 0.888694454861, 0.866195861067, 0.843697267273, 0.821198673479, + 0.798700079685, 0.776201485891, 0.753702892097, 0.731204298303, 0.708705704509, 0.686207110715, 0.663708516921, + 0.641209923127, 0.618711329334, 0.596212735540, 0.573714141746, 0.551215547952, 0.528716954158, 0.506218360364, + 0.483719766570, 0.461221172776, 0.438722578982, 0.416223985188, 0.393725391394, 0.371226797600, 0.348728203806, + 0.326229610012, 0.303731016218, 0.281232422424, 0.258733828630, 0.236235234836, 0.213736641043, 0.191238047249, + 0.168739453455, 0.146240859661, 0.123742265867, 0.101243672073, 0.078745078279, 0.056246484485, 0.033747890691, + 0.011249296897 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N48.cc b/src/atlas/grid/detail/spacing/gaussian/N48.cc index 3bfa26f39..273e49e0f 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N48.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N48.cc @@ -7,59 +7,17 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(48,LIST( - 88.572168514007, - 86.722530954668, - 84.861970292042, - 82.998941642838, - 81.134976837677, - 79.270559034860, - 77.405888082079, - 75.541061452879, - 73.676132313209, - 71.811132114274, - 69.946080646983, - 68.080990985651, - 66.215872113999, - 64.350730408872, - 62.485570522036, - 60.620395926826, - 58.755209269380, - 56.890012601357, - 55.024807538312, - 53.159595370020, - 51.294377138951, - 49.429153697123, - 47.563925747979, - 45.698693877702, - 43.833458578951, - 41.968220269075, - 40.102979304249, - 38.237735990565, - 36.372490592812, - 34.507243341501, - 32.641994438518, - 30.776744061723, - 28.911492368718, - 27.046239499945, - 25.180985581271, - 23.315730726141, - 21.450475037398, - 19.585218608822, - 17.719961526447, - 15.854703869695, - 13.989445712357, - 12.124187123456, - 10.258928168006, - 8.393668907692, - 6.528409401480, - 4.663149706178, - 2.797889876957, - 0.932629967838 - )) +DEFINE_GAUSSIAN_LATITUDES( + 48, LIST( 88.572168514007, 86.722530954668, 84.861970292042, 82.998941642838, 81.134976837677, 79.270559034860, + 77.405888082079, 75.541061452879, 73.676132313209, 71.811132114274, 69.946080646983, 68.080990985651, + 66.215872113999, 64.350730408872, 62.485570522036, 60.620395926826, 58.755209269380, 56.890012601357, + 55.024807538312, 53.159595370020, 51.294377138951, 49.429153697123, 47.563925747979, 45.698693877702, + 43.833458578951, 41.968220269075, 40.102979304249, 38.237735990565, 36.372490592812, 34.507243341501, + 32.641994438518, 30.776744061723, 28.911492368718, 27.046239499945, 25.180985581271, 23.315730726141, + 21.450475037398, 19.585218608822, 17.719961526447, 15.854703869695, 13.989445712357, 12.124187123456, + 10.258928168006, 8.393668907692, 6.528409401480, 4.663149706178, 2.797889876957, 0.932629967838 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N512.cc b/src/atlas/grid/detail/spacing/gaussian/N512.cc index 7da1946da..2df73e9cf 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N512.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N512.cc @@ -7,114 +7,95 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(512,LIST( - 89.865508687700, 89.691286319427, 89.516035073908, 89.340551361134, 89.164979468040, - 88.989364904277, 88.813726493695, 88.638073417245, 88.462410682421, 88.286741251340, - 88.111066987798, 87.935389122929, 87.759708502558, 87.584025726950, 87.408341233871, - 87.232655350076, 87.056968324394, 86.881280349644, 86.705591577554, 86.529902129152, - 86.354212102154, 86.178521576318, 86.002830617390, 85.827139280050, 85.651447610144, - 85.475755646402, 85.300063421765, 85.124370964427, 84.948678298664, 84.772985445485, - 84.597292423170, 84.421599247696, 84.245905933089, 84.070212491715, 83.894518934514, - 83.718825271204, 83.543131510446, 83.367437659983, 83.191743726757, 83.016049717015, - 82.840355636389, 82.664661489971, 82.488967282378, 82.313273017804, 82.137578700070, - 81.961884332659, 81.786189918760, 81.610495461294, 81.434800962941, 81.259106426166, - 81.083411853242, 80.907717246262, 80.732022607164, 80.556327937741, 80.380633239654, - 80.204938514445, 80.029243763549, 79.853548988299, 79.677854189940, 79.502159369631, - 79.326464528457, 79.150769667431, 78.975074787502, 78.799379889560, 78.623684974440, - 78.447990042926, 78.272295095754, 78.096600133617, 77.920905157170, 77.745210167027, - 77.569515163769, 77.393820147944, 77.218125120072, 77.042430080642, 76.866735030118, - 76.691039968939, 76.515344897522, 76.339649816263, 76.163954725535, 75.988259625697, - 75.812564517085, 75.636869400022, 75.461174274815, 75.285479141756, 75.109784001121, - 74.934088853178, 74.758393698178, 74.582698536362, 74.407003367962, 74.231308193198, - 74.055613012279, 73.879917825408, 73.704222632776, 73.528527434569, 73.352832230963, - 73.177137022127, 73.001441808224, 72.825746589409, 72.650051365831, 72.474356137634, - 72.298660904956, 72.122965667928, 71.947270426678, 71.771575181328, 71.595879931995, - 71.420184678794, 71.244489421831, 71.068794161213, 70.893098897040, 70.717403629410, - 70.541708358415, 70.366013084148, 70.190317806694, 70.014622526138, 69.838927242562, - 69.663231956043, 69.487536666658, 69.311841374478, 69.136146079577, 68.960450782020, - 68.784755481875, 68.609060179206, 68.433364874073, 68.257669566538, 68.081974256658, - 67.906278944489, 67.730583630085, 67.554888313498, 67.379192994781, 67.203497673982, - 67.027802351149, 66.852107026329, 66.676411699566, 66.500716370904, 66.325021040386, - 66.149325708053, 65.973630373944, 65.797935038099, 65.622239700555, 65.446544361348, - 65.270849020515, 65.095153678090, 64.919458334106, 64.743762988596, 64.568067641592, - 64.392372293124, 64.216676943223, 64.040981591918, 63.865286239237, 63.689590885209, - 63.513895529859, 63.338200173214, 63.162504815300, 62.986809456141, 62.811114095763, - 62.635418734187, 62.459723371438, 62.284028007538, 62.108332642509, 61.932637276372, - 61.756941909148, 61.581246540857, 61.405551171518, 61.229855801152, 61.054160429778, - 60.878465057412, 60.702769684074, 60.527074309781, 60.351378934550, 60.175683558397, - 59.999988181339, 59.824292803393, 59.648597424573, 59.472902044894, 59.297206664372, - 59.121511283021, 58.945815900855, 58.770120517889, 58.594425134135, 58.418729749607, - 58.243034364318, 58.067338978280, 57.891643591507, 57.715948204009, 57.540252815800, - 57.364557426890, 57.188862037291, 57.013166647015, 56.837471256071, 56.661775864471, - 56.486080472225, 56.310385079344, 56.134689685836, 55.958994291713, 55.783298896984, - 55.607603501658, 55.431908105745, 55.256212709253, 55.080517312191, 54.904821914568, - 54.729126516393, 54.553431117674, 54.377735718419, 54.202040318635, 54.026344918332, - 53.850649517516, 53.674954116196, 53.499258714378, 53.323563312070, 53.147867909279, - 52.972172506012, 52.796477102275, 52.620781698077, 52.445086293423, 52.269390888319, - 52.093695482773, 51.918000076789, 51.742304670376, 51.566609263538, 51.390913856281, - 51.215218448612, 51.039523040536, 50.863827632058, 50.688132223185, 50.512436813921, - 50.336741404272, 50.161045994243, 49.985350583839, 49.809655173065, 49.633959761927, - 49.458264350429, 49.282568938576, 49.106873526372, 48.931178113822, 48.755482700932, - 48.579787287704, 48.404091874145, 48.228396460257, 48.052701046046, 47.877005631515, - 47.701310216668, 47.525614801510, 47.349919386045, 47.174223970276, 46.998528554208, - 46.822833137844, 46.647137721187, 46.471442304243, 46.295746887013, 46.120051469502, - 45.944356051714, 45.768660633651, 45.592965215317, 45.417269796716, 45.241574377850, - 45.065878958724, 44.890183539339, 44.714488119700, 44.538792699810, 44.363097279670, - 44.187401859285, 44.011706438658, 43.836011017791, 43.660315596687, 43.484620175349, - 43.308924753780, 43.133229331982, 42.957533909959, 42.781838487713, 42.606143065246, - 42.430447642561, 42.254752219661, 42.079056796548, 41.903361373225, 41.727665949694, - 41.551970525957, 41.376275102018, 41.200579677877, 41.024884253538, 40.849188829003, - 40.673493404274, 40.497797979354, 40.322102554244, 40.146407128946, 39.970711703463, - 39.795016277797, 39.619320851950, 39.443625425924, 39.267929999721, 39.092234573343, - 38.916539146792, 38.740843720069, 38.565148293178, 38.389452866119, 38.213757438895, - 38.038062011506, 37.862366583957, 37.686671156247, 37.510975728378, 37.335280300353, - 37.159584872174, 36.983889443841, 36.808194015357, 36.632498586723, 36.456803157940, - 36.281107729011, 36.105412299938, 35.929716870721, 35.754021441362, 35.578326011862, - 35.402630582224, 35.226935152449, 35.051239722538, 34.875544292492, 34.699848862314, - 34.524153432004, 34.348458001564, 34.172762570996, 33.997067140300, 33.821371709478, - 33.645676278532, 33.469980847462, 33.294285416271, 33.118589984959, 32.942894553528, - 32.767199121978, 32.591503690312, 32.415808258530, 32.240112826634, 32.064417394624, - 31.888721962503, 31.713026530271, 31.537331097929, 31.361635665479, 31.185940232922, - 31.010244800259, 30.834549367490, 30.658853934618, 30.483158501643, 30.307463068566, - 30.131767635389, 29.956072202111, 29.780376768736, 29.604681335263, 29.428985901693, - 29.253290468028, 29.077595034269, 28.901899600416, 28.726204166471, 28.550508732434, - 28.374813298307, 28.199117864090, 28.023422429785, 27.847726995392, 27.672031560912, - 27.496336126347, 27.320640691697, 27.144945256962, 26.969249822145, 26.793554387245, - 26.617858952264, 26.442163517203, 26.266468082062, 26.090772646842, 25.915077211544, - 25.739381776169, 25.563686340718, 25.387990905192, 25.212295469591, 25.036600033916, - 24.860904598168, 24.685209162348, 24.509513726456, 24.333818290494, 24.158122854462, - 23.982427418361, 23.806731982191, 23.631036545954, 23.455341109649, 23.279645673279, - 23.103950236843, 22.928254800343, 22.752559363778, 22.576863927150, 22.401168490460, - 22.225473053708, 22.049777616894, 21.874082180020, 21.698386743087, 21.522691306094, - 21.346995869042, 21.171300431933, 20.995604994767, 20.819909557544, 20.644214120265, - 20.468518682931, 20.292823245543, 20.117127808100, 19.941432370604, 19.765736933056, - 19.590041495455, 19.414346057803, 19.238650620101, 19.062955182348, 18.887259744545, - 18.711564306693, 18.535868868793, 18.360173430845, 18.184477992850, 18.008782554808, - 17.833087116719, 17.657391678586, 17.481696240407, 17.306000802184, 17.130305363917, - 16.954609925607, 16.778914487254, 16.603219048858, 16.427523610421, 16.251828171943, - 16.076132733425, 15.900437294866, 15.724741856268, 15.549046417630, 15.373350978955, - 15.197655540241, 15.021960101490, 14.846264662702, 14.670569223878, 14.494873785017, - 14.319178346122, 14.143482907191, 13.967787468226, 13.792092029227, 13.616396590195, - 13.440701151130, 13.265005712032, 13.089310272903, 12.913614833742, 12.737919394550, - 12.562223955327, 12.386528516075, 12.210833076793, 12.035137637482, 11.859442198142, - 11.683746758774, 11.508051319379, 11.332355879956, 11.156660440507, 10.980965001031, - 10.805269561530, 10.629574122003, 10.453878682451, 10.278183242874, 10.102487803274, - 9.926792363650, 9.751096924003, 9.575401484333, 9.399706044641, 9.224010604927, - 9.048315165192, 8.872619725435, 8.696924285659, 8.521228845862, 8.345533406045, - 8.169837966209, 7.994142526355, 7.818447086482, 7.642751646591, 7.467056206682, - 7.291360766757, 7.115665326815, 6.939969886856, 6.764274446882, 6.588579006892, - 6.412883566887, 6.237188126868, 6.061492686834, 5.885797246787, 5.710101806726, - 5.534406366652, 5.358710926566, 5.183015486468, 5.007320046358, 4.831624606236, - 4.655929166104, 4.480233725961, 4.304538285808, 4.128842845645, 3.953147405473, - 3.777451965292, 3.601756525102, 3.426061084905, 3.250365644700, 3.074670204487, - 2.898974764267, 2.723279324041, 2.547583883809, 2.371888443571, 2.196193003328, - 2.020497563080, 1.844802122827, 1.669106682571, 1.493411242310, 1.317715802046, - 1.142020361779, 0.966324921510, 0.790629481238, 0.614934040965, 0.439238600690, - 0.263543160415, 0.087847720138 - )) +DEFINE_GAUSSIAN_LATITUDES( + 512, LIST( 89.865508687700, 89.691286319427, 89.516035073908, 89.340551361134, 89.164979468040, 88.989364904277, + 88.813726493695, 88.638073417245, 88.462410682421, 88.286741251340, 88.111066987798, 87.935389122929, + 87.759708502558, 87.584025726950, 87.408341233871, 87.232655350076, 87.056968324394, 86.881280349644, + 86.705591577554, 86.529902129152, 86.354212102154, 86.178521576318, 86.002830617390, 85.827139280050, + 85.651447610144, 85.475755646402, 85.300063421765, 85.124370964427, 84.948678298664, 84.772985445485, + 84.597292423170, 84.421599247696, 84.245905933089, 84.070212491715, 83.894518934514, 83.718825271204, + 83.543131510446, 83.367437659983, 83.191743726757, 83.016049717015, 82.840355636389, 82.664661489971, + 82.488967282378, 82.313273017804, 82.137578700070, 81.961884332659, 81.786189918760, 81.610495461294, + 81.434800962941, 81.259106426166, 81.083411853242, 80.907717246262, 80.732022607164, 80.556327937741, + 80.380633239654, 80.204938514445, 80.029243763549, 79.853548988299, 79.677854189940, 79.502159369631, + 79.326464528457, 79.150769667431, 78.975074787502, 78.799379889560, 78.623684974440, 78.447990042926, + 78.272295095754, 78.096600133617, 77.920905157170, 77.745210167027, 77.569515163769, 77.393820147944, + 77.218125120072, 77.042430080642, 76.866735030118, 76.691039968939, 76.515344897522, 76.339649816263, + 76.163954725535, 75.988259625697, 75.812564517085, 75.636869400022, 75.461174274815, 75.285479141756, + 75.109784001121, 74.934088853178, 74.758393698178, 74.582698536362, 74.407003367962, 74.231308193198, + 74.055613012279, 73.879917825408, 73.704222632776, 73.528527434569, 73.352832230963, 73.177137022127, + 73.001441808224, 72.825746589409, 72.650051365831, 72.474356137634, 72.298660904956, 72.122965667928, + 71.947270426678, 71.771575181328, 71.595879931995, 71.420184678794, 71.244489421831, 71.068794161213, + 70.893098897040, 70.717403629410, 70.541708358415, 70.366013084148, 70.190317806694, 70.014622526138, + 69.838927242562, 69.663231956043, 69.487536666658, 69.311841374478, 69.136146079577, 68.960450782020, + 68.784755481875, 68.609060179206, 68.433364874073, 68.257669566538, 68.081974256658, 67.906278944489, + 67.730583630085, 67.554888313498, 67.379192994781, 67.203497673982, 67.027802351149, 66.852107026329, + 66.676411699566, 66.500716370904, 66.325021040386, 66.149325708053, 65.973630373944, 65.797935038099, + 65.622239700555, 65.446544361348, 65.270849020515, 65.095153678090, 64.919458334106, 64.743762988596, + 64.568067641592, 64.392372293124, 64.216676943223, 64.040981591918, 63.865286239237, 63.689590885209, + 63.513895529859, 63.338200173214, 63.162504815300, 62.986809456141, 62.811114095763, 62.635418734187, + 62.459723371438, 62.284028007538, 62.108332642509, 61.932637276372, 61.756941909148, 61.581246540857, + 61.405551171518, 61.229855801152, 61.054160429778, 60.878465057412, 60.702769684074, 60.527074309781, + 60.351378934550, 60.175683558397, 59.999988181339, 59.824292803393, 59.648597424573, 59.472902044894, + 59.297206664372, 59.121511283021, 58.945815900855, 58.770120517889, 58.594425134135, 58.418729749607, + 58.243034364318, 58.067338978280, 57.891643591507, 57.715948204009, 57.540252815800, 57.364557426890, + 57.188862037291, 57.013166647015, 56.837471256071, 56.661775864471, 56.486080472225, 56.310385079344, + 56.134689685836, 55.958994291713, 55.783298896984, 55.607603501658, 55.431908105745, 55.256212709253, + 55.080517312191, 54.904821914568, 54.729126516393, 54.553431117674, 54.377735718419, 54.202040318635, + 54.026344918332, 53.850649517516, 53.674954116196, 53.499258714378, 53.323563312070, 53.147867909279, + 52.972172506012, 52.796477102275, 52.620781698077, 52.445086293423, 52.269390888319, 52.093695482773, + 51.918000076789, 51.742304670376, 51.566609263538, 51.390913856281, 51.215218448612, 51.039523040536, + 50.863827632058, 50.688132223185, 50.512436813921, 50.336741404272, 50.161045994243, 49.985350583839, + 49.809655173065, 49.633959761927, 49.458264350429, 49.282568938576, 49.106873526372, 48.931178113822, + 48.755482700932, 48.579787287704, 48.404091874145, 48.228396460257, 48.052701046046, 47.877005631515, + 47.701310216668, 47.525614801510, 47.349919386045, 47.174223970276, 46.998528554208, 46.822833137844, + 46.647137721187, 46.471442304243, 46.295746887013, 46.120051469502, 45.944356051714, 45.768660633651, + 45.592965215317, 45.417269796716, 45.241574377850, 45.065878958724, 44.890183539339, 44.714488119700, + 44.538792699810, 44.363097279670, 44.187401859285, 44.011706438658, 43.836011017791, 43.660315596687, + 43.484620175349, 43.308924753780, 43.133229331982, 42.957533909959, 42.781838487713, 42.606143065246, + 42.430447642561, 42.254752219661, 42.079056796548, 41.903361373225, 41.727665949694, 41.551970525957, + 41.376275102018, 41.200579677877, 41.024884253538, 40.849188829003, 40.673493404274, 40.497797979354, + 40.322102554244, 40.146407128946, 39.970711703463, 39.795016277797, 39.619320851950, 39.443625425924, + 39.267929999721, 39.092234573343, 38.916539146792, 38.740843720069, 38.565148293178, 38.389452866119, + 38.213757438895, 38.038062011506, 37.862366583957, 37.686671156247, 37.510975728378, 37.335280300353, + 37.159584872174, 36.983889443841, 36.808194015357, 36.632498586723, 36.456803157940, 36.281107729011, + 36.105412299938, 35.929716870721, 35.754021441362, 35.578326011862, 35.402630582224, 35.226935152449, + 35.051239722538, 34.875544292492, 34.699848862314, 34.524153432004, 34.348458001564, 34.172762570996, + 33.997067140300, 33.821371709478, 33.645676278532, 33.469980847462, 33.294285416271, 33.118589984959, + 32.942894553528, 32.767199121978, 32.591503690312, 32.415808258530, 32.240112826634, 32.064417394624, + 31.888721962503, 31.713026530271, 31.537331097929, 31.361635665479, 31.185940232922, 31.010244800259, + 30.834549367490, 30.658853934618, 30.483158501643, 30.307463068566, 30.131767635389, 29.956072202111, + 29.780376768736, 29.604681335263, 29.428985901693, 29.253290468028, 29.077595034269, 28.901899600416, + 28.726204166471, 28.550508732434, 28.374813298307, 28.199117864090, 28.023422429785, 27.847726995392, + 27.672031560912, 27.496336126347, 27.320640691697, 27.144945256962, 26.969249822145, 26.793554387245, + 26.617858952264, 26.442163517203, 26.266468082062, 26.090772646842, 25.915077211544, 25.739381776169, + 25.563686340718, 25.387990905192, 25.212295469591, 25.036600033916, 24.860904598168, 24.685209162348, + 24.509513726456, 24.333818290494, 24.158122854462, 23.982427418361, 23.806731982191, 23.631036545954, + 23.455341109649, 23.279645673279, 23.103950236843, 22.928254800343, 22.752559363778, 22.576863927150, + 22.401168490460, 22.225473053708, 22.049777616894, 21.874082180020, 21.698386743087, 21.522691306094, + 21.346995869042, 21.171300431933, 20.995604994767, 20.819909557544, 20.644214120265, 20.468518682931, + 20.292823245543, 20.117127808100, 19.941432370604, 19.765736933056, 19.590041495455, 19.414346057803, + 19.238650620101, 19.062955182348, 18.887259744545, 18.711564306693, 18.535868868793, 18.360173430845, + 18.184477992850, 18.008782554808, 17.833087116719, 17.657391678586, 17.481696240407, 17.306000802184, + 17.130305363917, 16.954609925607, 16.778914487254, 16.603219048858, 16.427523610421, 16.251828171943, + 16.076132733425, 15.900437294866, 15.724741856268, 15.549046417630, 15.373350978955, 15.197655540241, + 15.021960101490, 14.846264662702, 14.670569223878, 14.494873785017, 14.319178346122, 14.143482907191, + 13.967787468226, 13.792092029227, 13.616396590195, 13.440701151130, 13.265005712032, 13.089310272903, + 12.913614833742, 12.737919394550, 12.562223955327, 12.386528516075, 12.210833076793, 12.035137637482, + 11.859442198142, 11.683746758774, 11.508051319379, 11.332355879956, 11.156660440507, 10.980965001031, + 10.805269561530, 10.629574122003, 10.453878682451, 10.278183242874, 10.102487803274, 9.926792363650, + 9.751096924003, 9.575401484333, 9.399706044641, 9.224010604927, 9.048315165192, 8.872619725435, + 8.696924285659, 8.521228845862, 8.345533406045, 8.169837966209, 7.994142526355, 7.818447086482, + 7.642751646591, 7.467056206682, 7.291360766757, 7.115665326815, 6.939969886856, 6.764274446882, + 6.588579006892, 6.412883566887, 6.237188126868, 6.061492686834, 5.885797246787, 5.710101806726, + 5.534406366652, 5.358710926566, 5.183015486468, 5.007320046358, 4.831624606236, 4.655929166104, + 4.480233725961, 4.304538285808, 4.128842845645, 3.953147405473, 3.777451965292, 3.601756525102, + 3.426061084905, 3.250365644700, 3.074670204487, 2.898974764267, 2.723279324041, 2.547583883809, + 2.371888443571, 2.196193003328, 2.020497563080, 1.844802122827, 1.669106682571, 1.493411242310, + 1.317715802046, 1.142020361779, 0.966324921510, 0.790629481238, 0.614934040965, 0.439238600690, + 0.263543160415, 0.087847720138 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N576.cc b/src/atlas/grid/detail/spacing/gaussian/N576.cc index 32fcd727c..57c5a5b1a 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N576.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N576.cc @@ -7,127 +7,105 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(576,LIST( - 89.880445682778, 89.725572955853, 89.569785621770, 89.413791638920, 89.257719269313, - 89.101608968163, 88.945477468692, 88.789332932188, 88.633179809996, 88.477020735252, - 88.320857364755, 88.164690792905, 88.008521771586, 87.852350834397, 87.696178370484, - 87.540004670312, 87.383829955074, 87.227654396174, 87.071478128490, 86.915301259606, - 86.759123876386, 86.602946049731, 86.446767838084, 86.290589290052, 86.134410446389, - 85.978231341525, 85.822052004742, 85.665872461102, 85.509692732184, 85.353512836665, - 85.197332790795, 85.041152608776, 84.884972303076, 84.728791884688, 84.572611363337, - 84.416430747661, 84.260250045360, 84.104069263315, 83.947888407701, 83.791707484067, - 83.635526497422, 83.479345452291, 83.323164352780, 83.166983202616, 83.010802005194, - 82.854620763613, 82.698439480708, 82.542258159072, 82.386076801091, 82.229895408955, - 82.073713984683, 81.917532530138, 81.761351047042, 81.605169536987, 81.448988001452, - 81.292806441807, 81.136624859327, 80.980443255198, 80.824261630525, 80.668079986340, - 80.511898323606, 80.355716643225, 80.199534946040, 80.043353232842, 79.887171504373, - 79.730989761330, 79.574808004367, 79.418626234102, 79.262444451114, 79.106262655951, - 78.950080849129, 78.793899031136, 78.637717202433, 78.481535363454, 78.325353514613, - 78.169171656300, 78.012989788886, 77.856807912721, 77.700626028139, 77.544444135457, - 77.388262234976, 77.232080326982, 77.075898411747, 76.919716489531, 76.763534560580, - 76.607352625132, 76.451170683410, 76.294988735628, 76.138806781993, 75.982624822699, - 75.826442857934, 75.670260887876, 75.514078912697, 75.357896932561, 75.201714947624, - 75.045532958038, 74.889350963947, 74.733168965488, 74.576986962794, 74.420804955994, - 74.264622945209, 74.108440930556, 73.952258912150, 73.796076890098, 73.639894864504, - 73.483712835471, 73.327530803093, 73.171348767464, 73.015166728675, 72.858984686811, - 72.702802641956, 72.546620594190, 72.390438543591, 72.234256490233, 72.078074434189, - 71.921892375528, 71.765710314318, 71.609528250623, 71.453346184507, 71.297164116031, - 71.140982045252, 70.984799972227, 70.828617897013, 70.672435819661, 70.516253740223, - 70.360071658750, 70.203889575289, 70.047707489886, 69.891525402589, 69.735343313439, - 69.579161222480, 69.422979129753, 69.266797035298, 69.110614939154, 68.954432841359, - 68.798250741949, 68.642068640959, 68.485886538424, 68.329704434378, 68.173522328853, - 68.017340221880, 67.861158113491, 67.704976003715, 67.548793892581, 67.392611780117, - 67.236429666351, 67.080247551309, 66.924065435018, 66.767883317503, 66.611701198788, - 66.455519078897, 66.299336957853, 66.143154835680, 65.986972712399, 65.830790588032, - 65.674608462599, 65.518426336122, 65.362244208621, 65.206062080113, 65.049879950620, - 64.893697820158, 64.737515688747, 64.581333556403, 64.425151423144, 64.268969288986, - 64.112787153947, 63.956605018041, 63.800422881284, 63.644240743692, 63.488058605279, - 63.331876466060, 63.175694326050, 63.019512185260, 62.863330043707, 62.707147901401, - 62.550965758357, 62.394783614587, 62.238601470103, 62.082419324918, 61.926237179043, - 61.770055032489, 61.613872885268, 61.457690737392, 61.301508588870, 61.145326439713, - 60.989144289931, 60.832962139536, 60.676779988535, 60.520597836940, 60.364415684760, - 60.208233532004, 60.052051378680, 59.895869224799, 59.739687070368, 59.583504915396, - 59.427322759892, 59.271140603863, 59.114958447319, 58.958776290265, 58.802594132711, - 58.646411974664, 58.490229816131, 58.334047657120, 58.177865497637, 58.021683337689, - 57.865501177284, 57.709319016429, 57.553136855128, 57.396954693390, 57.240772531221, - 57.084590368626, 56.928408205612, 56.772226042184, 56.616043878350, 56.459861714113, - 56.303679549481, 56.147497384458, 55.991315219050, 55.835133053263, 55.678950887101, - 55.522768720570, 55.366586553675, 55.210404386421, 55.054222218812, 54.898040050854, - 54.741857882551, 54.585675713908, 54.429493544930, 54.273311375620, 54.117129205983, - 53.960947036024, 53.804764865747, 53.648582695156, 53.492400524255, 53.336218353048, - 53.180036181539, 53.023854009733, 52.867671837632, 52.711489665240, 52.555307492562, - 52.399125319601, 52.242943146360, 52.086760972843, 51.930578799054, 51.774396624996, - 51.618214450672, 51.462032276086, 51.305850101240, 51.149667926139, 50.993485750784, - 50.837303575180, 50.681121399330, 50.524939223235, 50.368757046900, 50.212574870327, - 50.056392693519, 49.900210516479, 49.744028339210, 49.587846161714, 49.431663983994, - 49.275481806052, 49.119299627893, 48.963117449517, 48.806935270927, 48.650753092126, - 48.494570913117, 48.338388733901, 48.182206554482, 48.026024374861, 47.869842195041, - 47.713660015024, 47.557477834813, 47.401295654409, 47.245113473815, 47.088931293033, - 46.932749112065, 46.776566930913, 46.620384749579, 46.464202568066, 46.308020386375, - 46.151838204508, 45.995656022467, 45.839473840254, 45.683291657872, 45.527109475321, - 45.370927292603, 45.214745109722, 45.058562926678, 44.902380743472, 44.746198560108, - 44.590016376586, 44.433834192908, 44.277652009077, 44.121469825092, 43.965287640958, - 43.809105456673, 43.652923272242, 43.496741087664, 43.340558902942, 43.184376718076, - 43.028194533070, 42.872012347923, 42.715830162638, 42.559647977216, 42.403465791658, - 42.247283605966, 42.091101420141, 41.934919234185, 41.778737048098, 41.622554861883, - 41.466372675541, 41.310190489072, 41.154008302479, 40.997826115762, 40.841643928923, - 40.685461741962, 40.529279554882, 40.373097367684, 40.216915180368, 40.060732992935, - 39.904550805388, 39.748368617727, 39.592186429953, 39.436004242067, 39.279822054071, - 39.123639865966, 38.967457677752, 38.811275489432, 38.655093301005, 38.498911112472, - 38.342728923836, 38.186546735097, 38.030364546256, 37.874182357314, 37.718000168271, - 37.561817979130, 37.405635789891, 37.249453600554, 37.093271411121, 36.937089221594, - 36.780907031971, 36.624724842256, 36.468542652448, 36.312360462548, 36.156178272558, - 35.999996082478, 35.843813892309, 35.687631702051, 35.531449511707, 35.375267321276, - 35.219085130760, 35.062902940159, 34.906720749474, 34.750538558705, 34.594356367855, - 34.438174176923, 34.281991985910, 34.125809794817, 33.969627603645, 33.813445412394, - 33.657263221065, 33.501081029660, 33.344898838178, 33.188716646621, 33.032534454989, - 32.876352263283, 32.720170071503, 32.563987879651, 32.407805687726, 32.251623495730, - 32.095441303664, 31.939259111527, 31.783076919322, 31.626894727047, 31.470712534704, - 31.314530342294, 31.158348149817, 31.002165957274, 30.845983764666, 30.689801571992, - 30.533619379254, 30.377437186453, 30.221254993588, 30.065072800661, 29.908890607672, - 29.752708414622, 29.596526221510, 29.440344028339, 29.284161835108, 29.127979641818, - 28.971797448469, 28.815615255063, 28.659433061599, 28.503250868078, 28.347068674501, - 28.190886480867, 28.034704287179, 27.878522093436, 27.722339899639, 27.566157705788, - 27.409975511883, 27.253793317926, 27.097611123917, 26.941428929856, 26.785246735744, - 26.629064541581, 26.472882347367, 26.316700153104, 26.160517958792, 26.004335764431, - 25.848153570021, 25.691971375563, 25.535789181058, 25.379606986506, 25.223424791908, - 25.067242597263, 24.911060402572, 24.754878207837, 24.598696013056, 24.442513818231, - 24.286331623362, 24.130149428450, 23.973967233495, 23.817785038496, 23.661602843456, - 23.505420648374, 23.349238453250, 23.193056258085, 23.036874062880, 22.880691867634, - 22.724509672349, 22.568327477024, 22.412145281660, 22.255963086258, 22.099780890817, - 21.943598695338, 21.787416499822, 21.631234304268, 21.475052108678, 21.318869913051, - 21.162687717389, 21.006505521690, 20.850323325957, 20.694141130188, 20.537958934385, - 20.381776738547, 20.225594542676, 20.069412346771, 19.913230150833, 19.757047954862, - 19.600865758859, 19.444683562824, 19.288501366756, 19.132319170658, 18.976136974528, - 18.819954778367, 18.663772582176, 18.507590385954, 18.351408189703, 18.195225993422, - 18.039043797112, 17.882861600774, 17.726679404406, 17.570497208011, 17.414315011587, - 17.258132815136, 17.101950618658, 16.945768422153, 16.789586225620, 16.633404029062, - 16.477221832478, 16.321039635867, 16.164857439232, 16.008675242571, 15.852493045885, - 15.696310849174, 15.540128652440, 15.383946455681, 15.227764258899, 15.071582062093, - 14.915399865264, 14.759217668412, 14.603035471538, 14.446853274641, 14.290671077722, - 14.134488880782, 13.978306683820, 13.822124486837, 13.665942289833, 13.509760092808, - 13.353577895763, 13.197395698698, 13.041213501613, 12.885031304509, 12.728849107385, - 12.572666910242, 12.416484713080, 12.260302515900, 12.104120318702, 11.947938121486, - 11.791755924252, 11.635573727000, 11.479391529732, 11.323209332446, 11.167027135144, - 11.010844937825, 10.854662740490, 10.698480543140, 10.542298345773, 10.386116148391, - 10.229933950994, 10.073751753582, 9.917569556155, 9.761387358714, 9.605205161259, - 9.449022963790, 9.292840766307, 9.136658568810, 8.980476371300, 8.824294173778, - 8.668111976242, 8.511929778694, 8.355747581134, 8.199565383562, 8.043383185978, - 7.887200988383, 7.731018790776, 7.574836593158, 7.418654395529, 7.262472197890, - 7.106290000240, 6.950107802580, 6.793925604910, 6.637743407231, 6.481561209542, - 6.325379011844, 6.169196814136, 6.013014616420, 5.856832418696, 5.700650220963, - 5.544468023222, 5.388285825474, 5.232103627717, 5.075921429954, 4.919739232183, - 4.763557034405, 4.607374836620, 4.451192638829, 4.295010441032, 4.138828243229, - 3.982646045419, 3.826463847605, 3.670281649784, 3.514099451959, 3.357917254129, - 3.201735056294, 3.045552858454, 2.889370660610, 2.733188462763, 2.577006264911, - 2.420824067056, 2.264641869197, 2.108459671335, 1.952277473470, 1.796095275603, - 1.639913077733, 1.483730879860, 1.327548681986, 1.171366484109, 1.015184286231, - 0.859002088352, 0.702819890472, 0.546637692590, 0.390455494708, 0.234273296825, - 0.078091098942 - )) +DEFINE_GAUSSIAN_LATITUDES( + 576, LIST( 89.880445682778, 89.725572955853, 89.569785621770, 89.413791638920, 89.257719269313, 89.101608968163, + 88.945477468692, 88.789332932188, 88.633179809996, 88.477020735252, 88.320857364755, 88.164690792905, + 88.008521771586, 87.852350834397, 87.696178370484, 87.540004670312, 87.383829955074, 87.227654396174, + 87.071478128490, 86.915301259606, 86.759123876386, 86.602946049731, 86.446767838084, 86.290589290052, + 86.134410446389, 85.978231341525, 85.822052004742, 85.665872461102, 85.509692732184, 85.353512836665, + 85.197332790795, 85.041152608776, 84.884972303076, 84.728791884688, 84.572611363337, 84.416430747661, + 84.260250045360, 84.104069263315, 83.947888407701, 83.791707484067, 83.635526497422, 83.479345452291, + 83.323164352780, 83.166983202616, 83.010802005194, 82.854620763613, 82.698439480708, 82.542258159072, + 82.386076801091, 82.229895408955, 82.073713984683, 81.917532530138, 81.761351047042, 81.605169536987, + 81.448988001452, 81.292806441807, 81.136624859327, 80.980443255198, 80.824261630525, 80.668079986340, + 80.511898323606, 80.355716643225, 80.199534946040, 80.043353232842, 79.887171504373, 79.730989761330, + 79.574808004367, 79.418626234102, 79.262444451114, 79.106262655951, 78.950080849129, 78.793899031136, + 78.637717202433, 78.481535363454, 78.325353514613, 78.169171656300, 78.012989788886, 77.856807912721, + 77.700626028139, 77.544444135457, 77.388262234976, 77.232080326982, 77.075898411747, 76.919716489531, + 76.763534560580, 76.607352625132, 76.451170683410, 76.294988735628, 76.138806781993, 75.982624822699, + 75.826442857934, 75.670260887876, 75.514078912697, 75.357896932561, 75.201714947624, 75.045532958038, + 74.889350963947, 74.733168965488, 74.576986962794, 74.420804955994, 74.264622945209, 74.108440930556, + 73.952258912150, 73.796076890098, 73.639894864504, 73.483712835471, 73.327530803093, 73.171348767464, + 73.015166728675, 72.858984686811, 72.702802641956, 72.546620594190, 72.390438543591, 72.234256490233, + 72.078074434189, 71.921892375528, 71.765710314318, 71.609528250623, 71.453346184507, 71.297164116031, + 71.140982045252, 70.984799972227, 70.828617897013, 70.672435819661, 70.516253740223, 70.360071658750, + 70.203889575289, 70.047707489886, 69.891525402589, 69.735343313439, 69.579161222480, 69.422979129753, + 69.266797035298, 69.110614939154, 68.954432841359, 68.798250741949, 68.642068640959, 68.485886538424, + 68.329704434378, 68.173522328853, 68.017340221880, 67.861158113491, 67.704976003715, 67.548793892581, + 67.392611780117, 67.236429666351, 67.080247551309, 66.924065435018, 66.767883317503, 66.611701198788, + 66.455519078897, 66.299336957853, 66.143154835680, 65.986972712399, 65.830790588032, 65.674608462599, + 65.518426336122, 65.362244208621, 65.206062080113, 65.049879950620, 64.893697820158, 64.737515688747, + 64.581333556403, 64.425151423144, 64.268969288986, 64.112787153947, 63.956605018041, 63.800422881284, + 63.644240743692, 63.488058605279, 63.331876466060, 63.175694326050, 63.019512185260, 62.863330043707, + 62.707147901401, 62.550965758357, 62.394783614587, 62.238601470103, 62.082419324918, 61.926237179043, + 61.770055032489, 61.613872885268, 61.457690737392, 61.301508588870, 61.145326439713, 60.989144289931, + 60.832962139536, 60.676779988535, 60.520597836940, 60.364415684760, 60.208233532004, 60.052051378680, + 59.895869224799, 59.739687070368, 59.583504915396, 59.427322759892, 59.271140603863, 59.114958447319, + 58.958776290265, 58.802594132711, 58.646411974664, 58.490229816131, 58.334047657120, 58.177865497637, + 58.021683337689, 57.865501177284, 57.709319016429, 57.553136855128, 57.396954693390, 57.240772531221, + 57.084590368626, 56.928408205612, 56.772226042184, 56.616043878350, 56.459861714113, 56.303679549481, + 56.147497384458, 55.991315219050, 55.835133053263, 55.678950887101, 55.522768720570, 55.366586553675, + 55.210404386421, 55.054222218812, 54.898040050854, 54.741857882551, 54.585675713908, 54.429493544930, + 54.273311375620, 54.117129205983, 53.960947036024, 53.804764865747, 53.648582695156, 53.492400524255, + 53.336218353048, 53.180036181539, 53.023854009733, 52.867671837632, 52.711489665240, 52.555307492562, + 52.399125319601, 52.242943146360, 52.086760972843, 51.930578799054, 51.774396624996, 51.618214450672, + 51.462032276086, 51.305850101240, 51.149667926139, 50.993485750784, 50.837303575180, 50.681121399330, + 50.524939223235, 50.368757046900, 50.212574870327, 50.056392693519, 49.900210516479, 49.744028339210, + 49.587846161714, 49.431663983994, 49.275481806052, 49.119299627893, 48.963117449517, 48.806935270927, + 48.650753092126, 48.494570913117, 48.338388733901, 48.182206554482, 48.026024374861, 47.869842195041, + 47.713660015024, 47.557477834813, 47.401295654409, 47.245113473815, 47.088931293033, 46.932749112065, + 46.776566930913, 46.620384749579, 46.464202568066, 46.308020386375, 46.151838204508, 45.995656022467, + 45.839473840254, 45.683291657872, 45.527109475321, 45.370927292603, 45.214745109722, 45.058562926678, + 44.902380743472, 44.746198560108, 44.590016376586, 44.433834192908, 44.277652009077, 44.121469825092, + 43.965287640958, 43.809105456673, 43.652923272242, 43.496741087664, 43.340558902942, 43.184376718076, + 43.028194533070, 42.872012347923, 42.715830162638, 42.559647977216, 42.403465791658, 42.247283605966, + 42.091101420141, 41.934919234185, 41.778737048098, 41.622554861883, 41.466372675541, 41.310190489072, + 41.154008302479, 40.997826115762, 40.841643928923, 40.685461741962, 40.529279554882, 40.373097367684, + 40.216915180368, 40.060732992935, 39.904550805388, 39.748368617727, 39.592186429953, 39.436004242067, + 39.279822054071, 39.123639865966, 38.967457677752, 38.811275489432, 38.655093301005, 38.498911112472, + 38.342728923836, 38.186546735097, 38.030364546256, 37.874182357314, 37.718000168271, 37.561817979130, + 37.405635789891, 37.249453600554, 37.093271411121, 36.937089221594, 36.780907031971, 36.624724842256, + 36.468542652448, 36.312360462548, 36.156178272558, 35.999996082478, 35.843813892309, 35.687631702051, + 35.531449511707, 35.375267321276, 35.219085130760, 35.062902940159, 34.906720749474, 34.750538558705, + 34.594356367855, 34.438174176923, 34.281991985910, 34.125809794817, 33.969627603645, 33.813445412394, + 33.657263221065, 33.501081029660, 33.344898838178, 33.188716646621, 33.032534454989, 32.876352263283, + 32.720170071503, 32.563987879651, 32.407805687726, 32.251623495730, 32.095441303664, 31.939259111527, + 31.783076919322, 31.626894727047, 31.470712534704, 31.314530342294, 31.158348149817, 31.002165957274, + 30.845983764666, 30.689801571992, 30.533619379254, 30.377437186453, 30.221254993588, 30.065072800661, + 29.908890607672, 29.752708414622, 29.596526221510, 29.440344028339, 29.284161835108, 29.127979641818, + 28.971797448469, 28.815615255063, 28.659433061599, 28.503250868078, 28.347068674501, 28.190886480867, + 28.034704287179, 27.878522093436, 27.722339899639, 27.566157705788, 27.409975511883, 27.253793317926, + 27.097611123917, 26.941428929856, 26.785246735744, 26.629064541581, 26.472882347367, 26.316700153104, + 26.160517958792, 26.004335764431, 25.848153570021, 25.691971375563, 25.535789181058, 25.379606986506, + 25.223424791908, 25.067242597263, 24.911060402572, 24.754878207837, 24.598696013056, 24.442513818231, + 24.286331623362, 24.130149428450, 23.973967233495, 23.817785038496, 23.661602843456, 23.505420648374, + 23.349238453250, 23.193056258085, 23.036874062880, 22.880691867634, 22.724509672349, 22.568327477024, + 22.412145281660, 22.255963086258, 22.099780890817, 21.943598695338, 21.787416499822, 21.631234304268, + 21.475052108678, 21.318869913051, 21.162687717389, 21.006505521690, 20.850323325957, 20.694141130188, + 20.537958934385, 20.381776738547, 20.225594542676, 20.069412346771, 19.913230150833, 19.757047954862, + 19.600865758859, 19.444683562824, 19.288501366756, 19.132319170658, 18.976136974528, 18.819954778367, + 18.663772582176, 18.507590385954, 18.351408189703, 18.195225993422, 18.039043797112, 17.882861600774, + 17.726679404406, 17.570497208011, 17.414315011587, 17.258132815136, 17.101950618658, 16.945768422153, + 16.789586225620, 16.633404029062, 16.477221832478, 16.321039635867, 16.164857439232, 16.008675242571, + 15.852493045885, 15.696310849174, 15.540128652440, 15.383946455681, 15.227764258899, 15.071582062093, + 14.915399865264, 14.759217668412, 14.603035471538, 14.446853274641, 14.290671077722, 14.134488880782, + 13.978306683820, 13.822124486837, 13.665942289833, 13.509760092808, 13.353577895763, 13.197395698698, + 13.041213501613, 12.885031304509, 12.728849107385, 12.572666910242, 12.416484713080, 12.260302515900, + 12.104120318702, 11.947938121486, 11.791755924252, 11.635573727000, 11.479391529732, 11.323209332446, + 11.167027135144, 11.010844937825, 10.854662740490, 10.698480543140, 10.542298345773, 10.386116148391, + 10.229933950994, 10.073751753582, 9.917569556155, 9.761387358714, 9.605205161259, 9.449022963790, + 9.292840766307, 9.136658568810, 8.980476371300, 8.824294173778, 8.668111976242, 8.511929778694, + 8.355747581134, 8.199565383562, 8.043383185978, 7.887200988383, 7.731018790776, 7.574836593158, + 7.418654395529, 7.262472197890, 7.106290000240, 6.950107802580, 6.793925604910, 6.637743407231, + 6.481561209542, 6.325379011844, 6.169196814136, 6.013014616420, 5.856832418696, 5.700650220963, + 5.544468023222, 5.388285825474, 5.232103627717, 5.075921429954, 4.919739232183, 4.763557034405, + 4.607374836620, 4.451192638829, 4.295010441032, 4.138828243229, 3.982646045419, 3.826463847605, + 3.670281649784, 3.514099451959, 3.357917254129, 3.201735056294, 3.045552858454, 2.889370660610, + 2.733188462763, 2.577006264911, 2.420824067056, 2.264641869197, 2.108459671335, 1.952277473470, + 1.796095275603, 1.639913077733, 1.483730879860, 1.327548681986, 1.171366484109, 1.015184286231, + 0.859002088352, 0.702819890472, 0.546637692590, 0.390455494708, 0.234273296825, 0.078091098942 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N64.cc b/src/atlas/grid/detail/spacing/gaussian/N64.cc index 9f08385bc..4d43b3628 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N64.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N64.cc @@ -7,24 +7,20 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(64,LIST( - 88.927735352296, 87.538705213027, 86.141472101528, 84.742385590714, 83.342596044070, - 81.942466299173, 80.542146434617, 79.141709648622, 77.741195865514, 76.340628702372, - 74.940023019649, 73.539388633767, 72.138732289162, 70.738058772518, 69.337371574961, - 67.936673302579, 66.535965940176, 65.135251026035, 63.734529770843, 62.333803140532, - 60.933071915207, 59.532336731827, 58.131598115644, 56.730856503714, 55.330112262703, - 53.929365702556, 52.528617087100, 51.127866642353, 49.727114563110, 48.326361018188, - 46.925606154665, 45.524850101302, 44.124092971356, 42.723334864877, 41.322575870623, - 39.921816067646, 38.521055526624, 37.120294310979, 35.719532477824, 34.318770078771, - 32.918007160614, 31.517243765923, 30.116479933546, 28.715715699055, 27.314951095120, - 25.914186151847, 24.513420897063, 23.112655356578, 21.711889554404, 20.311123512960, - 18.910357253245, 17.509590794999, 16.108824156841, 14.708057356405, 13.307290410446, - 11.906523334954, 10.505756145244, 9.104988856049, 7.704221481600, 6.303454035708, - 4.902686531827, 3.501918983131, 2.101151402579, 0.700383802973 - )) +DEFINE_GAUSSIAN_LATITUDES( + 64, LIST( 88.927735352296, 87.538705213027, 86.141472101528, 84.742385590714, 83.342596044070, 81.942466299173, + 80.542146434617, 79.141709648622, 77.741195865514, 76.340628702372, 74.940023019649, 73.539388633767, + 72.138732289162, 70.738058772518, 69.337371574961, 67.936673302579, 66.535965940176, 65.135251026035, + 63.734529770843, 62.333803140532, 60.933071915207, 59.532336731827, 58.131598115644, 56.730856503714, + 55.330112262703, 53.929365702556, 52.528617087100, 51.127866642353, 49.727114563110, 48.326361018188, + 46.925606154665, 45.524850101302, 44.124092971356, 42.723334864877, 41.322575870623, 39.921816067646, + 38.521055526624, 37.120294310979, 35.719532477824, 34.318770078771, 32.918007160614, 31.517243765923, + 30.116479933546, 28.715715699055, 27.314951095120, 25.914186151847, 24.513420897063, 23.112655356578, + 21.711889554404, 20.311123512960, 18.910357253245, 17.509590794999, 16.108824156841, 14.708057356405, + 13.307290410446, 11.906523334954, 10.505756145244, 9.104988856049, 7.704221481600, 6.303454035708, + 4.902686531827, 3.501918983131, 2.101151402579, 0.700383802973 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N640.cc b/src/atlas/grid/detail/spacing/gaussian/N640.cc index d0086f099..db04e8554 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N640.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N640.cc @@ -7,139 +7,116 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(640,LIST( - 89.892396445590, 89.753004943174, 89.612790258599, 89.472389582061, 89.331918354382, - 89.191412986832, 89.050888539966, 88.910352359260, 88.769808451100, 88.629259185412, - 88.488706053376, 88.348150039999, 88.207591822004, 88.067031879651, 87.926470563186, - 87.785908134041, 87.645344791296, 87.504780689222, 87.364215949215, 87.223650668104, - 87.083084924071, 86.942518780929, 86.801952291278, 86.661385498868, 86.520818440380, - 86.380251146799, 86.239683644481, 86.099115955985, 85.958548100731, 85.817980095530, - 85.677411955006, 85.536843691943, 85.396275317563, 85.255706841758, 85.115138273282, - 84.974569619910, 84.834000888572, 84.693432085462, 84.552863216136, 84.412294285589, - 84.271725298330, 84.131156258431, 83.990587169587, 83.850018035154, 83.709448858186, - 83.568879641474, 83.428310387568, 83.287741098803, 83.147171777324, 83.006602425105, - 82.866033043963, 82.725463635573, 82.584894201486, 82.444324743135, 82.303755261850, - 82.163185758865, 82.022616235328, 81.882046692304, 81.741477130791, 81.600907551716, - 81.460337955946, 81.319768344292, 81.179198717514, 81.038629076323, 80.898059421388, - 80.757489753335, 80.616920072753, 80.476350380198, 80.335780676193, 80.195210961228, - 80.054641235771, 79.914071500258, 79.773501755105, 79.632932000703, 79.492362237425, - 79.351792465622, 79.211222685626, 79.070652897754, 78.930083102307, 78.789513299568, - 78.648943489809, 78.508373673288, 78.367803850250, 78.227234020928, 78.086664185545, - 77.946094344312, 77.805524497433, 77.664954645100, 77.524384787497, 77.383814924802, - 77.243245057181, 77.102675184796, 76.962105307802, 76.821535426346, 76.680965540569, - 76.540395650606, 76.399825756588, 76.259255858639, 76.118685956878, 75.978116051420, - 75.837546142375, 75.696976229850, 75.556406313944, 75.415836394757, 75.275266472383, - 75.134696546911, 74.994126618429, 74.853556687021, 74.712986752768, 74.572416815746, - 74.431846876032, 74.291276933698, 74.150706988813, 74.010137041445, 73.869567091658, - 73.728997139516, 73.588427185079, 73.447857228405, 73.307287269551, 73.166717308572, - 73.026147345520, 72.885577380447, 72.745007413401, 72.604437444432, 72.463867473585, - 72.323297500905, 72.182727526435, 72.042157550217, 71.901587572293, 71.761017592701, - 71.620447611481, 71.479877628669, 71.339307644300, 71.198737658411, 71.058167671035, - 70.917597682205, 70.777027691952, 70.636457700309, 70.495887707304, 70.355317712967, - 70.214747717328, 70.074177720412, 69.933607722247, 69.793037722860, 69.652467722275, - 69.511897720517, 69.371327717611, 69.230757713579, 69.090187708444, 68.949617702229, - 68.809047694955, 68.668477686643, 68.527907677314, 68.387337666986, 68.246767655681, - 68.106197643416, 67.965627630209, 67.825057616080, 67.684487601045, 67.543917585122, - 67.403347568326, 67.262777550675, 67.122207532184, 66.981637512868, 66.841067492743, - 66.700497471823, 66.559927450122, 66.419357427655, 66.278787404436, 66.138217380477, - 65.997647355791, 65.857077330392, 65.716507304291, 65.575937277502, 65.435367250035, - 65.294797221902, 65.154227193115, 65.013657163685, 64.873087133622, 64.732517102938, - 64.591947071642, 64.451377039745, 64.310807007256, 64.170236974186, 64.029666940544, - 63.889096906338, 63.748526871579, 63.607956836274, 63.467386800434, 63.326816764065, - 63.186246727177, 63.045676689778, 62.905106651876, 62.764536613478, 62.623966574592, - 62.483396535226, 62.342826495387, 62.202256455083, 62.061686414319, 61.921116373105, - 61.780546331445, 61.639976289347, 61.499406246817, 61.358836203862, 61.218266160488, - 61.077696116701, 60.937126072507, 60.796556027912, 60.655985982922, 60.515415937542, - 60.374845891778, 60.234275845637, 60.093705799122, 59.953135752239, 59.812565704993, - 59.671995657391, 59.531425609435, 59.390855561132, 59.250285512486, 59.109715463502, - 58.969145414185, 58.828575364539, 58.688005314568, 58.547435264277, 58.406865213671, - 58.266295162752, 58.125725111527, 57.985155059998, 57.844585008170, 57.704014956047, - 57.563444903632, 57.422874850930, 57.282304797944, 57.141734744678, 57.001164691135, - 56.860594637319, 56.720024583233, 56.579454528882, 56.438884474268, 56.298314419394, - 56.157744364265, 56.017174308882, 55.876604253250, 55.736034197372, 55.595464141249, - 55.454894084887, 55.314324028286, 55.173753971452, 55.033183914385, 54.892613857089, - 54.752043799568, 54.611473741823, 54.470903683857, 54.330333625673, 54.189763567274, - 54.049193508662, 53.908623449839, 53.768053390809, 53.627483331573, 53.486913272134, - 53.346343212494, 53.205773152657, 53.065203092623, 52.924633032395, 52.784062971976, - 52.643492911368, 52.502922850573, 52.362352789593, 52.221782728430, 52.081212667086, - 51.940642605563, 51.800072543864, 51.659502481990, 51.518932419943, 51.378362357725, - 51.237792295338, 51.097222232785, 50.956652170066, 50.816082107184, 50.675512044140, - 50.534941980936, 50.394371917574, 50.253801854056, 50.113231790383, 49.972661726557, - 49.832091662580, 49.691521598453, 49.550951534178, 49.410381469756, 49.269811405190, - 49.129241340479, 48.988671275628, 48.848101210635, 48.707531145504, 48.566961080235, - 48.426391014830, 48.285820949291, 48.145250883618, 48.004680817814, 47.864110751879, - 47.723540685814, 47.582970619622, 47.442400553304, 47.301830486860, 47.161260420293, - 47.020690353603, 46.880120286791, 46.739550219859, 46.598980152808, 46.458410085640, - 46.317840018355, 46.177269950954, 46.036699883439, 45.896129815811, 45.755559748071, - 45.614989680220, 45.474419612259, 45.333849544190, 45.193279476013, 45.052709407729, - 44.912139339340, 44.771569270846, 44.630999202249, 44.490429133549, 44.349859064748, - 44.209288995846, 44.068718926845, 43.928148857745, 43.787578788547, 43.647008719253, - 43.506438649863, 43.365868580378, 43.225298510799, 43.084728441127, 42.944158371362, - 42.803588301507, 42.663018231561, 42.522448161525, 42.381878091401, 42.241308021188, - 42.100737950889, 41.960167880503, 41.819597810032, 41.679027739476, 41.538457668836, - 41.397887598112, 41.257317527307, 41.116747456420, 40.976177385452, 40.835607314404, - 40.695037243276, 40.554467172070, 40.413897100786, 40.273327029425, 40.132756957987, - 39.992186886473, 39.851616814884, 39.711046743221, 39.570476671484, 39.429906599674, - 39.289336527791, 39.148766455836, 39.008196383811, 38.867626311714, 38.727056239548, - 38.586486167313, 38.445916095009, 38.305346022636, 38.164775950197, 38.024205877690, - 37.883635805117, 37.743065732479, 37.602495659776, 37.461925587007, 37.321355514176, - 37.180785441280, 37.040215368322, 36.899645295301, 36.759075222219, 36.618505149076, - 36.477935075872, 36.337365002607, 36.196794929284, 36.056224855901, 35.915654782459, - 35.775084708960, 35.634514635403, 35.493944561788, 35.353374488118, 35.212804414391, - 35.072234340608, 34.931664266771, 34.791094192879, 34.650524118932, 34.509954044932, - 34.369383970879, 34.228813896773, 34.088243822614, 33.947673748404, 33.807103674142, - 33.666533599830, 33.525963525466, 33.385393451053, 33.244823376590, 33.104253302077, - 32.963683227516, 32.823113152906, 32.682543078249, 32.541973003543, 32.401402928791, - 32.260832853991, 32.120262779145, 31.979692704254, 31.839122629316, 31.698552554333, - 31.557982479306, 31.417412404234, 31.276842329118, 31.136272253958, 30.995702178755, - 30.855132103508, 30.714562028220, 30.573991952888, 30.433421877515, 30.292851802101, - 30.152281726645, 30.011711651148, 29.871141575611, 29.730571500034, 29.590001424417, - 29.449431348760, 29.308861273064, 29.168291197330, 29.027721121557, 28.887151045746, - 28.746580969896, 28.606010894010, 28.465440818086, 28.324870742125, 28.184300666128, - 28.043730590094, 27.903160514025, 27.762590437920, 27.622020361779, 27.481450285604, - 27.340880209393, 27.200310133149, 27.059740056870, 26.919169980557, 26.778599904211, - 26.638029827831, 26.497459751418, 26.356889674973, 26.216319598495, 26.075749521985, - 25.935179445443, 25.794609368869, 25.654039292264, 25.513469215628, 25.372899138962, - 25.232329062264, 25.091758985537, 24.951188908779, 24.810618831992, 24.670048755175, - 24.529478678328, 24.388908601453, 24.248338524549, 24.107768447617, 23.967198370656, - 23.826628293668, 23.686058216651, 23.545488139607, 23.404918062536, 23.264347985438, - 23.123777908313, 22.983207831162, 22.842637753984, 22.702067676780, 22.561497599550, - 22.420927522295, 22.280357445014, 22.139787367708, 21.999217290377, 21.858647213022, - 21.718077135642, 21.577507058237, 21.436936980809, 21.296366903357, 21.155796825881, - 21.015226748382, 20.874656670859, 20.734086593314, 20.593516515746, 20.452946438155, - 20.312376360542, 20.171806282907, 20.031236205250, 19.890666127571, 19.750096049871, - 19.609525972149, 19.468955894407, 19.328385816643, 19.187815738859, 19.047245661054, - 18.906675583229, 18.766105505383, 18.625535427518, 18.484965349633, 18.344395271729, - 18.203825193805, 18.063255115862, 17.922685037900, 17.782114959919, 17.641544881920, - 17.500974803902, 17.360404725866, 17.219834647812, 17.079264569740, 16.938694491650, - 16.798124413543, 16.657554335419, 16.516984257277, 16.376414179119, 16.235844100943, - 16.095274022751, 15.954703944543, 15.814133866318, 15.673563788078, 15.532993709821, - 15.392423631549, 15.251853553261, 15.111283474957, 14.970713396639, 14.830143318305, - 14.689573239957, 14.549003161593, 14.408433083215, 14.267863004823, 14.127292926417, - 13.986722847996, 13.846152769562, 13.705582691113, 13.565012612652, 13.424442534176, - 13.283872455688, 13.143302377186, 13.002732298672, 12.862162220144, 12.721592141604, - 12.581022063052, 12.440451984487, 12.299881905910, 12.159311827321, 12.018741748721, - 11.878171670108, 11.737601591484, 11.597031512849, 11.456461434202, 11.315891355544, - 11.175321276875, 11.034751198196, 10.894181119506, 10.753611040805, 10.613040962094, - 10.472470883373, 10.331900804641, 10.191330725900, 10.050760647149, 9.910190568389, - 9.769620489619, 9.629050410840, 9.488480332051, 9.347910253253, 9.207340174447, - 9.066770095632, 8.926200016808, 8.785629937976, 8.645059859135, 8.504489780287, - 8.363919701430, 8.223349622565, 8.082779543693, 7.942209464813, 7.801639385925, - 7.661069307030, 7.520499228128, 7.379929149219, 7.239359070303, 7.098788991380, - 6.958218912450, 6.817648833514, 6.677078754572, 6.536508675623, 6.395938596669, - 6.255368517708, 6.114798438741, 5.974228359769, 5.833658280791, 5.693088201808, - 5.552518122820, 5.411948043826, 5.271377964827, 5.130807885824, 4.990237806815, - 4.849667727802, 4.709097648785, 4.568527569763, 4.427957490737, 4.287387411707, - 4.146817332673, 4.006247253635, 3.865677174593, 3.725107095548, 3.584537016499, - 3.443966937447, 3.303396858392, 3.162826779334, 3.022256700273, 2.881686621209, - 2.741116542142, 2.600546463073, 2.459976384002, 2.319406304928, 2.178836225852, - 2.038266146774, 1.897696067694, 1.757125988613, 1.616555909530, 1.475985830445, - 1.335415751359, 1.194845672272, 1.054275593184, 0.913705514095, 0.773135435005, - 0.632565355914, 0.491995276822, 0.351425197731, 0.210855118639, 0.070285039546 -)) +DEFINE_GAUSSIAN_LATITUDES( + 640, LIST( 89.892396445590, 89.753004943174, 89.612790258599, 89.472389582061, 89.331918354382, 89.191412986832, + 89.050888539966, 88.910352359260, 88.769808451100, 88.629259185412, 88.488706053376, 88.348150039999, + 88.207591822004, 88.067031879651, 87.926470563186, 87.785908134041, 87.645344791296, 87.504780689222, + 87.364215949215, 87.223650668104, 87.083084924071, 86.942518780929, 86.801952291278, 86.661385498868, + 86.520818440380, 86.380251146799, 86.239683644481, 86.099115955985, 85.958548100731, 85.817980095530, + 85.677411955006, 85.536843691943, 85.396275317563, 85.255706841758, 85.115138273282, 84.974569619910, + 84.834000888572, 84.693432085462, 84.552863216136, 84.412294285589, 84.271725298330, 84.131156258431, + 83.990587169587, 83.850018035154, 83.709448858186, 83.568879641474, 83.428310387568, 83.287741098803, + 83.147171777324, 83.006602425105, 82.866033043963, 82.725463635573, 82.584894201486, 82.444324743135, + 82.303755261850, 82.163185758865, 82.022616235328, 81.882046692304, 81.741477130791, 81.600907551716, + 81.460337955946, 81.319768344292, 81.179198717514, 81.038629076323, 80.898059421388, 80.757489753335, + 80.616920072753, 80.476350380198, 80.335780676193, 80.195210961228, 80.054641235771, 79.914071500258, + 79.773501755105, 79.632932000703, 79.492362237425, 79.351792465622, 79.211222685626, 79.070652897754, + 78.930083102307, 78.789513299568, 78.648943489809, 78.508373673288, 78.367803850250, 78.227234020928, + 78.086664185545, 77.946094344312, 77.805524497433, 77.664954645100, 77.524384787497, 77.383814924802, + 77.243245057181, 77.102675184796, 76.962105307802, 76.821535426346, 76.680965540569, 76.540395650606, + 76.399825756588, 76.259255858639, 76.118685956878, 75.978116051420, 75.837546142375, 75.696976229850, + 75.556406313944, 75.415836394757, 75.275266472383, 75.134696546911, 74.994126618429, 74.853556687021, + 74.712986752768, 74.572416815746, 74.431846876032, 74.291276933698, 74.150706988813, 74.010137041445, + 73.869567091658, 73.728997139516, 73.588427185079, 73.447857228405, 73.307287269551, 73.166717308572, + 73.026147345520, 72.885577380447, 72.745007413401, 72.604437444432, 72.463867473585, 72.323297500905, + 72.182727526435, 72.042157550217, 71.901587572293, 71.761017592701, 71.620447611481, 71.479877628669, + 71.339307644300, 71.198737658411, 71.058167671035, 70.917597682205, 70.777027691952, 70.636457700309, + 70.495887707304, 70.355317712967, 70.214747717328, 70.074177720412, 69.933607722247, 69.793037722860, + 69.652467722275, 69.511897720517, 69.371327717611, 69.230757713579, 69.090187708444, 68.949617702229, + 68.809047694955, 68.668477686643, 68.527907677314, 68.387337666986, 68.246767655681, 68.106197643416, + 67.965627630209, 67.825057616080, 67.684487601045, 67.543917585122, 67.403347568326, 67.262777550675, + 67.122207532184, 66.981637512868, 66.841067492743, 66.700497471823, 66.559927450122, 66.419357427655, + 66.278787404436, 66.138217380477, 65.997647355791, 65.857077330392, 65.716507304291, 65.575937277502, + 65.435367250035, 65.294797221902, 65.154227193115, 65.013657163685, 64.873087133622, 64.732517102938, + 64.591947071642, 64.451377039745, 64.310807007256, 64.170236974186, 64.029666940544, 63.889096906338, + 63.748526871579, 63.607956836274, 63.467386800434, 63.326816764065, 63.186246727177, 63.045676689778, + 62.905106651876, 62.764536613478, 62.623966574592, 62.483396535226, 62.342826495387, 62.202256455083, + 62.061686414319, 61.921116373105, 61.780546331445, 61.639976289347, 61.499406246817, 61.358836203862, + 61.218266160488, 61.077696116701, 60.937126072507, 60.796556027912, 60.655985982922, 60.515415937542, + 60.374845891778, 60.234275845637, 60.093705799122, 59.953135752239, 59.812565704993, 59.671995657391, + 59.531425609435, 59.390855561132, 59.250285512486, 59.109715463502, 58.969145414185, 58.828575364539, + 58.688005314568, 58.547435264277, 58.406865213671, 58.266295162752, 58.125725111527, 57.985155059998, + 57.844585008170, 57.704014956047, 57.563444903632, 57.422874850930, 57.282304797944, 57.141734744678, + 57.001164691135, 56.860594637319, 56.720024583233, 56.579454528882, 56.438884474268, 56.298314419394, + 56.157744364265, 56.017174308882, 55.876604253250, 55.736034197372, 55.595464141249, 55.454894084887, + 55.314324028286, 55.173753971452, 55.033183914385, 54.892613857089, 54.752043799568, 54.611473741823, + 54.470903683857, 54.330333625673, 54.189763567274, 54.049193508662, 53.908623449839, 53.768053390809, + 53.627483331573, 53.486913272134, 53.346343212494, 53.205773152657, 53.065203092623, 52.924633032395, + 52.784062971976, 52.643492911368, 52.502922850573, 52.362352789593, 52.221782728430, 52.081212667086, + 51.940642605563, 51.800072543864, 51.659502481990, 51.518932419943, 51.378362357725, 51.237792295338, + 51.097222232785, 50.956652170066, 50.816082107184, 50.675512044140, 50.534941980936, 50.394371917574, + 50.253801854056, 50.113231790383, 49.972661726557, 49.832091662580, 49.691521598453, 49.550951534178, + 49.410381469756, 49.269811405190, 49.129241340479, 48.988671275628, 48.848101210635, 48.707531145504, + 48.566961080235, 48.426391014830, 48.285820949291, 48.145250883618, 48.004680817814, 47.864110751879, + 47.723540685814, 47.582970619622, 47.442400553304, 47.301830486860, 47.161260420293, 47.020690353603, + 46.880120286791, 46.739550219859, 46.598980152808, 46.458410085640, 46.317840018355, 46.177269950954, + 46.036699883439, 45.896129815811, 45.755559748071, 45.614989680220, 45.474419612259, 45.333849544190, + 45.193279476013, 45.052709407729, 44.912139339340, 44.771569270846, 44.630999202249, 44.490429133549, + 44.349859064748, 44.209288995846, 44.068718926845, 43.928148857745, 43.787578788547, 43.647008719253, + 43.506438649863, 43.365868580378, 43.225298510799, 43.084728441127, 42.944158371362, 42.803588301507, + 42.663018231561, 42.522448161525, 42.381878091401, 42.241308021188, 42.100737950889, 41.960167880503, + 41.819597810032, 41.679027739476, 41.538457668836, 41.397887598112, 41.257317527307, 41.116747456420, + 40.976177385452, 40.835607314404, 40.695037243276, 40.554467172070, 40.413897100786, 40.273327029425, + 40.132756957987, 39.992186886473, 39.851616814884, 39.711046743221, 39.570476671484, 39.429906599674, + 39.289336527791, 39.148766455836, 39.008196383811, 38.867626311714, 38.727056239548, 38.586486167313, + 38.445916095009, 38.305346022636, 38.164775950197, 38.024205877690, 37.883635805117, 37.743065732479, + 37.602495659776, 37.461925587007, 37.321355514176, 37.180785441280, 37.040215368322, 36.899645295301, + 36.759075222219, 36.618505149076, 36.477935075872, 36.337365002607, 36.196794929284, 36.056224855901, + 35.915654782459, 35.775084708960, 35.634514635403, 35.493944561788, 35.353374488118, 35.212804414391, + 35.072234340608, 34.931664266771, 34.791094192879, 34.650524118932, 34.509954044932, 34.369383970879, + 34.228813896773, 34.088243822614, 33.947673748404, 33.807103674142, 33.666533599830, 33.525963525466, + 33.385393451053, 33.244823376590, 33.104253302077, 32.963683227516, 32.823113152906, 32.682543078249, + 32.541973003543, 32.401402928791, 32.260832853991, 32.120262779145, 31.979692704254, 31.839122629316, + 31.698552554333, 31.557982479306, 31.417412404234, 31.276842329118, 31.136272253958, 30.995702178755, + 30.855132103508, 30.714562028220, 30.573991952888, 30.433421877515, 30.292851802101, 30.152281726645, + 30.011711651148, 29.871141575611, 29.730571500034, 29.590001424417, 29.449431348760, 29.308861273064, + 29.168291197330, 29.027721121557, 28.887151045746, 28.746580969896, 28.606010894010, 28.465440818086, + 28.324870742125, 28.184300666128, 28.043730590094, 27.903160514025, 27.762590437920, 27.622020361779, + 27.481450285604, 27.340880209393, 27.200310133149, 27.059740056870, 26.919169980557, 26.778599904211, + 26.638029827831, 26.497459751418, 26.356889674973, 26.216319598495, 26.075749521985, 25.935179445443, + 25.794609368869, 25.654039292264, 25.513469215628, 25.372899138962, 25.232329062264, 25.091758985537, + 24.951188908779, 24.810618831992, 24.670048755175, 24.529478678328, 24.388908601453, 24.248338524549, + 24.107768447617, 23.967198370656, 23.826628293668, 23.686058216651, 23.545488139607, 23.404918062536, + 23.264347985438, 23.123777908313, 22.983207831162, 22.842637753984, 22.702067676780, 22.561497599550, + 22.420927522295, 22.280357445014, 22.139787367708, 21.999217290377, 21.858647213022, 21.718077135642, + 21.577507058237, 21.436936980809, 21.296366903357, 21.155796825881, 21.015226748382, 20.874656670859, + 20.734086593314, 20.593516515746, 20.452946438155, 20.312376360542, 20.171806282907, 20.031236205250, + 19.890666127571, 19.750096049871, 19.609525972149, 19.468955894407, 19.328385816643, 19.187815738859, + 19.047245661054, 18.906675583229, 18.766105505383, 18.625535427518, 18.484965349633, 18.344395271729, + 18.203825193805, 18.063255115862, 17.922685037900, 17.782114959919, 17.641544881920, 17.500974803902, + 17.360404725866, 17.219834647812, 17.079264569740, 16.938694491650, 16.798124413543, 16.657554335419, + 16.516984257277, 16.376414179119, 16.235844100943, 16.095274022751, 15.954703944543, 15.814133866318, + 15.673563788078, 15.532993709821, 15.392423631549, 15.251853553261, 15.111283474957, 14.970713396639, + 14.830143318305, 14.689573239957, 14.549003161593, 14.408433083215, 14.267863004823, 14.127292926417, + 13.986722847996, 13.846152769562, 13.705582691113, 13.565012612652, 13.424442534176, 13.283872455688, + 13.143302377186, 13.002732298672, 12.862162220144, 12.721592141604, 12.581022063052, 12.440451984487, + 12.299881905910, 12.159311827321, 12.018741748721, 11.878171670108, 11.737601591484, 11.597031512849, + 11.456461434202, 11.315891355544, 11.175321276875, 11.034751198196, 10.894181119506, 10.753611040805, + 10.613040962094, 10.472470883373, 10.331900804641, 10.191330725900, 10.050760647149, 9.910190568389, + 9.769620489619, 9.629050410840, 9.488480332051, 9.347910253253, 9.207340174447, 9.066770095632, + 8.926200016808, 8.785629937976, 8.645059859135, 8.504489780287, 8.363919701430, 8.223349622565, + 8.082779543693, 7.942209464813, 7.801639385925, 7.661069307030, 7.520499228128, 7.379929149219, + 7.239359070303, 7.098788991380, 6.958218912450, 6.817648833514, 6.677078754572, 6.536508675623, + 6.395938596669, 6.255368517708, 6.114798438741, 5.974228359769, 5.833658280791, 5.693088201808, + 5.552518122820, 5.411948043826, 5.271377964827, 5.130807885824, 4.990237806815, 4.849667727802, + 4.709097648785, 4.568527569763, 4.427957490737, 4.287387411707, 4.146817332673, 4.006247253635, + 3.865677174593, 3.725107095548, 3.584537016499, 3.443966937447, 3.303396858392, 3.162826779334, + 3.022256700273, 2.881686621209, 2.741116542142, 2.600546463073, 2.459976384002, 2.319406304928, + 2.178836225852, 2.038266146774, 1.897696067694, 1.757125988613, 1.616555909530, 1.475985830445, + 1.335415751359, 1.194845672272, 1.054275593184, 0.913705514095, 0.773135435005, 0.632565355914, + 0.491995276822, 0.351425197731, 0.210855118639, 0.070285039546 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N80.cc b/src/atlas/grid/detail/spacing/gaussian/N80.cc index c9ac23b9b..7ca4b5d55 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N80.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N80.cc @@ -7,27 +7,23 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(80,LIST( - 89.141519426461, 88.029428867952, 86.910770814124, 85.790628883637, 84.669924084447, - 83.548946912542, 82.427817524008, 81.306594522669, 80.185309872477, 79.063982481409, - 77.942624246673, 76.821243027100, 75.699844222011, 74.578431663296, 73.457008145583, - 72.335575754909, 71.214136079887, 70.092690351624, 68.971239538936, 67.849784414670, - 66.728325602882, 65.606863613010, 64.485398865043, 63.363931708341, 62.242462435891, - 61.120991295252, 59.999518497040, 58.878044221583, 57.756568624184, 56.635091839330, - 55.513613984077, 54.392135160792, 53.270655459398, 52.149174959220, 51.027693730509, - 49.906211835711, 48.784729330535, 47.663246264843, 46.541762683406, 45.420278626548, - 44.298794130694, 43.177309228835, 42.055823950935, 40.934338324279, 39.812852373771, - 38.691366122202, 37.569879590471, 36.448392797794, 35.326905761872, 34.205418499049, - 33.083931024447, 31.962443352088, 30.840955495002, 29.719467465319, 28.597979274357, - 27.476490932696, 26.355002450251, 25.233513836324, 24.112025099671, 22.990536248541, - 21.869047290730, 20.747558233616, 19.626069084199, 18.504579849136, 17.383090534771, - 16.261601147162, 15.140111692111, 14.018622175186, 12.897132601745, 11.775642976956, - 10.654153305818, 9.532663593176, 8.411173843743, 7.289684062115, 6.168194252784, - 5.046704420157, 3.925214568566, 2.803724702287, 1.682234825547, 0.560744942544 -)) +DEFINE_GAUSSIAN_LATITUDES( + 80, LIST( 89.141519426461, 88.029428867952, 86.910770814124, 85.790628883637, 84.669924084447, 83.548946912542, + 82.427817524008, 81.306594522669, 80.185309872477, 79.063982481409, 77.942624246673, 76.821243027100, + 75.699844222011, 74.578431663296, 73.457008145583, 72.335575754909, 71.214136079887, 70.092690351624, + 68.971239538936, 67.849784414670, 66.728325602882, 65.606863613010, 64.485398865043, 63.363931708341, + 62.242462435891, 61.120991295252, 59.999518497040, 58.878044221583, 57.756568624184, 56.635091839330, + 55.513613984077, 54.392135160792, 53.270655459398, 52.149174959220, 51.027693730509, 49.906211835711, + 48.784729330535, 47.663246264843, 46.541762683406, 45.420278626548, 44.298794130694, 43.177309228835, + 42.055823950935, 40.934338324279, 39.812852373771, 38.691366122202, 37.569879590471, 36.448392797794, + 35.326905761872, 34.205418499049, 33.083931024447, 31.962443352088, 30.840955495002, 29.719467465319, + 28.597979274357, 27.476490932696, 26.355002450251, 25.233513836324, 24.112025099671, 22.990536248541, + 21.869047290730, 20.747558233616, 19.626069084199, 18.504579849136, 17.383090534771, 16.261601147162, + 15.140111692111, 14.018622175186, 12.897132601745, 11.775642976956, 10.654153305818, 9.532663593176, + 8.411173843743, 7.289684062115, 6.168194252784, 5.046704420157, 3.925214568566, 2.803724702287, + 1.682234825547, 0.560744942544 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N800.cc b/src/atlas/grid/detail/spacing/gaussian/N800.cc index 138909c50..00ade7469 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N800.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N800.cc @@ -7,171 +7,143 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(800,LIST( - 89.913910432567, 89.802388520364, 89.690208010997, 89.577878696439, 89.465492936558, - 89.353079862649, 89.240651524094, 89.128213797733, 89.015769888926, 88.903321693762, - 88.790870405278, 88.678416811542, 88.565961453973, 88.453504716809, 88.341046880271, - 88.228588153518, 88.116128695829, 88.003668630629, 87.891208055042, 87.778747046539, - 87.666285667668, 87.553823969486, 87.441361994075, 87.328899776437, 87.216437345920, - 87.103974727314, 86.991511941706, 86.879049007143, 86.766585939163, 86.654122751216, - 86.541659455003, 86.429196060750, 86.316732577436, 86.204269012976, 86.091805374374, - 85.979341667850, 85.866877898947, 85.754414072622, 85.641950193319, 85.529486265037, - 85.417022291380, 85.304558275609, 85.192094220678, 85.079630129273, 84.967166003838, - 84.854701846604, 84.742237659612, 84.629773444731, 84.517309203677, 84.404844938029, - 84.292380649239, 84.179916338650, 84.067452007501, 83.954987656940, 83.842523288029, - 83.730058901757, 83.617594499041, 83.505130080736, 83.392665647637, 83.280201200487, - 83.167736739980, 83.055272266765, 82.942807781449, 82.830343284601, 82.717878776757, - 82.605414258418, 82.492949730055, 82.380485192112, 82.268020645007, 82.155556089135, - 82.043091524867, 81.930626952554, 81.818162372528, 81.705697785102, 81.593233190575, - 81.480768589225, 81.368303981322, 81.255839367117, 81.143374746850, 81.030910120750, - 80.918445489032, 80.805980851905, 80.693516209562, 80.581051562192, 80.468586909973, - 80.356122253073, 80.243657591655, 80.131192925873, 80.018728255875, 79.906263581802, - 79.793798903788, 79.681334221962, 79.568869536448, 79.456404847364, 79.343940154822, - 79.231475458931, 79.119010759796, 79.006546057514, 78.894081352183, 78.781616643893, - 78.669151932734, 78.556687218788, 78.444222502139, 78.331757782864, 78.219293061038, - 78.106828336733, 77.994363610020, 77.881898880965, 77.769434149634, 77.656969416087, - 77.544504680386, 77.432039942588, 77.319575202748, 77.207110460921, 77.094645717159, - 76.982180971512, 76.869716224029, 76.757251474755, 76.644786723737, 76.532321971017, - 76.419857216639, 76.307392460644, 76.194927703070, 76.082462943956, 75.969998183339, - 75.857533421255, 75.745068657739, 75.632603892824, 75.520139126543, 75.407674358928, - 75.295209590008, 75.182744819815, 75.070280048376, 74.957815275720, 74.845350501873, - 74.732885726863, 74.620420950714, 74.507956173452, 74.395491395100, 74.283026615682, - 74.170561835220, 74.058097053737, 73.945632271255, 73.833167487793, 73.720702703373, - 73.608237918014, 73.495773131735, 73.383308344555, 73.270843556493, 73.158378767565, - 73.045913977789, 72.933449187182, 72.820984395761, 72.708519603540, 72.596054810536, - 72.483590016764, 72.371125222239, 72.258660426974, 72.146195630983, 72.033730834282, - 71.921266036881, 71.808801238796, 71.696336440038, 71.583871640619, 71.471406840552, - 71.358942039849, 71.246477238520, 71.134012436578, 71.021547634032, 70.909082830894, - 70.796618027174, 70.684153222883, 70.571688418029, 70.459223612624, 70.346758806675, - 70.234294000194, 70.121829193188, 70.009364385667, 69.896899577639, 69.784434769113, - 69.671969960097, 69.559505150599, 69.447040340627, 69.334575530189, 69.222110719292, - 69.109645907944, 68.997181096152, 68.884716283923, 68.772251471264, 68.659786658182, - 68.547321844684, 68.434857030775, 68.322392216464, 68.209927401755, 68.097462586655, - 67.984997771169, 67.872532955305, 67.760068139067, 67.647603322461, 67.535138505493, - 67.422673688169, 67.310208870492, 67.197744052469, 67.085279234106, 66.972814415406, - 66.860349596374, 66.747884777016, 66.635419957337, 66.522955137340, 66.410490317031, - 66.298025496414, 66.185560675493, 66.073095854272, 65.960631032757, 65.848166210950, - 65.735701388856, 65.623236566480, 65.510771743824, 65.398306920893, 65.285842097690, - 65.173377274220, 65.060912450485, 64.948447626490, 64.835982802238, 64.723517977732, - 64.611053152976, 64.498588327972, 64.386123502726, 64.273658677238, 64.161193851514, - 64.048729025555, 63.936264199365, 63.823799372947, 63.711334546304, 63.598869719438, - 63.486404892353, 63.373940065051, 63.261475237535, 63.149010409808, 63.036545581872, - 62.924080753730, 62.811615925385, 62.699151096839, 62.586686268095, 62.474221439154, - 62.361756610020, 62.249291780695, 62.136826951181, 62.024362121480, 61.911897291595, - 61.799432461528, 61.686967631281, 61.574502800856, 61.462037970255, 61.349573139481, - 61.237108308536, 61.124643477421, 61.012178646138, 60.899713814690, 60.787248983078, - 60.674784151304, 60.562319319371, 60.449854487279, 60.337389655031, 60.224924822629, - 60.112459990074, 59.999995157368, 59.887530324513, 59.775065491510, 59.662600658361, - 59.550135825068, 59.437670991632, 59.325206158055, 59.212741324339, 59.100276490485, - 58.987811656494, 58.875346822368, 58.762881988108, 58.650417153717, 58.537952319194, - 58.425487484543, 58.313022649763, 58.200557814858, 58.088092979827, 57.975628144672, - 57.863163309394, 57.750698473996, 57.638233638477, 57.525768802840, 57.413303967086, - 57.300839131215, 57.188374295229, 57.075909459130, 56.963444622917, 56.850979786594, - 56.738514950160, 56.626050113617, 56.513585276965, 56.401120440207, 56.288655603343, - 56.176190766374, 56.063725929301, 55.951261092126, 55.838796254849, 55.726331417471, - 55.613866579993, 55.501401742417, 55.388936904743, 55.276472066972, 55.164007229106, - 55.051542391144, 54.939077553089, 54.826612714941, 54.714147876700, 54.601683038368, - 54.489218199946, 54.376753361435, 54.264288522834, 54.151823684146, 54.039358845371, - 53.926894006510, 53.814429167564, 53.701964328533, 53.589499489418, 53.477034650221, - 53.364569810941, 53.252104971580, 53.139640132139, 53.027175292617, 52.914710453017, - 52.802245613338, 52.689780773581, 52.577315933747, 52.464851093838, 52.352386253852, - 52.239921413792, 52.127456573658, 52.014991733450, 51.902526893169, 51.790062052816, - 51.677597212392, 51.565132371896, 51.452667531331, 51.340202690695, 51.227737849991, - 51.115273009218, 51.002808168378, 50.890343327470, 50.777878486496, 50.665413645456, - 50.552948804350, 50.440483963179, 50.328019121945, 50.215554280646, 50.103089439284, - 49.990624597860, 49.878159756373, 49.765694914825, 49.653230073216, 49.540765231546, - 49.428300389817, 49.315835548028, 49.203370706180, 49.090905864273, 48.978441022308, - 48.865976180286, 48.753511338207, 48.641046496072, 48.528581653880, 48.416116811633, - 48.303651969331, 48.191187126974, 48.078722284563, 47.966257442098, 47.853792599579, - 47.741327757008, 47.628862914385, 47.516398071709, 47.403933228982, 47.291468386204, - 47.179003543375, 47.066538700496, 46.954073857566, 46.841609014588, 46.729144171560, - 46.616679328483, 46.504214485358, 46.391749642185, 46.279284798965, 46.166819955698, - 46.054355112383, 45.941890269023, 45.829425425616, 45.716960582163, 45.604495738666, - 45.492030895123, 45.379566051536, 45.267101207904, 45.154636364228, 45.042171520509, - 44.929706676747, 44.817241832942, 44.704776989094, 44.592312145205, 44.479847301273, - 44.367382457299, 44.254917613285, 44.142452769229, 44.029987925133, 43.917523080997, - 43.805058236821, 43.692593392605, 43.580128548349, 43.467663704055, 43.355198859722, - 43.242734015350, 43.130269170940, 43.017804326492, 42.905339482007, 42.792874637484, - 42.680409792924, 42.567944948328, 42.455480103695, 42.343015259025, 42.230550414320, - 42.118085569579, 42.005620724803, 41.893155879992, 41.780691035146, 41.668226190265, - 41.555761345350, 41.443296500400, 41.330831655417, 41.218366810400, 41.105901965350, - 40.993437120267, 40.880972275151, 40.768507430002, 40.656042584821, 40.543577739608, - 40.431112894362, 40.318648049085, 40.206183203777, 40.093718358438, 39.981253513067, - 39.868788667666, 39.756323822234, 39.643858976772, 39.531394131279, 39.418929285757, - 39.306464440205, 39.193999594624, 39.081534749013, 38.969069903374, 38.856605057705, - 38.744140212008, 38.631675366283, 38.519210520529, 38.406745674747, 38.294280828938, - 38.181815983101, 38.069351137236, 37.956886291344, 37.844421445426, 37.731956599480, - 37.619491753508, 37.507026907509, 37.394562061484, 37.282097215433, 37.169632369356, - 37.057167523253, 36.944702677124, 36.832237830971, 36.719772984792, 36.607308138588, - 36.494843292359, 36.382378446106, 36.269913599828, 36.157448753526, 36.044983907199, - 35.932519060849, 35.820054214475, 35.707589368077, 35.595124521656, 35.482659675211, - 35.370194828743, 35.257729982253, 35.145265135739, 35.032800289203, 34.920335442644, - 34.807870596063, 34.695405749459, 34.582940902834, 34.470476056186, 34.358011209517, - 34.245546362826, 34.133081516114, 34.020616669381, 33.908151822626, 33.795686975850, - 33.683222129054, 33.570757282236, 33.458292435398, 33.345827588540, 33.233362741661, - 33.120897894762, 33.008433047843, 32.895968200904, 32.783503353946, 32.671038506967, - 32.558573659970, 32.446108812953, 32.333643965916, 32.221179118861, 32.108714271786, - 31.996249424693, 31.883784577581, 31.771319730451, 31.658854883301, 31.546390036134, - 31.433925188949, 31.321460341745, 31.208995494523, 31.096530647284, 30.984065800027, - 30.871600952752, 30.759136105459, 30.646671258150, 30.534206410823, 30.421741563479, - 30.309276716118, 30.196811868740, 30.084347021345, 29.971882173934, 29.859417326506, - 29.746952479061, 29.634487631601, 29.522022784124, 29.409557936631, 29.297093089122, - 29.184628241597, 29.072163394056, 28.959698546500, 28.847233698928, 28.734768851340, - 28.622304003737, 28.509839156119, 28.397374308486, 28.284909460838, 28.172444613174, - 28.059979765496, 27.947514917803, 27.835050070096, 27.722585222374, 27.610120374637, - 27.497655526887, 27.385190679122, 27.272725831342, 27.160260983549, 27.047796135742, - 26.935331287921, 26.822866440086, 26.710401592237, 26.597936744375, 26.485471896499, - 26.373007048610, 26.260542200708, 26.148077352792, 26.035612504863, 25.923147656922, - 25.810682808967, 25.698217960999, 25.585753113019, 25.473288265026, 25.360823417021, - 25.248358569002, 25.135893720972, 25.023428872929, 24.910964024874, 24.798499176807, - 24.686034328727, 24.573569480636, 24.461104632533, 24.348639784418, 24.236174936291, - 24.123710088152, 24.011245240002, 23.898780391841, 23.786315543668, 23.673850695483, - 23.561385847288, 23.448920999081, 23.336456150863, 23.223991302634, 23.111526454394, - 22.999061606143, 22.886596757882, 22.774131909610, 22.661667061327, 22.549202213033, - 22.436737364729, 22.324272516415, 22.211807668090, 22.099342819755, 21.986877971410, - 21.874413123055, 21.761948274690, 21.649483426314, 21.537018577929, 21.424553729534, - 21.312088881129, 21.199624032715, 21.087159184291, 20.974694335857, 20.862229487414, - 20.749764638962, 20.637299790500, 20.524834942029, 20.412370093549, 20.299905245059, - 20.187440396561, 20.074975548053, 19.962510699537, 19.850045851012, 19.737581002478, - 19.625116153935, 19.512651305384, 19.400186456824, 19.287721608255, 19.175256759678, - 19.062791911093, 18.950327062499, 18.837862213897, 18.725397365287, 18.612932516668, - 18.500467668042, 18.388002819407, 18.275537970765, 18.163073122115, 18.050608273457, - 17.938143424791, 17.825678576117, 17.713213727436, 17.600748878747, 17.488284030051, - 17.375819181347, 17.263354332636, 17.150889483917, 17.038424635192, 16.925959786458, - 16.813494937718, 16.701030088971, 16.588565240217, 16.476100391455, 16.363635542687, - 16.251170693912, 16.138705845130, 16.026240996341, 15.913776147546, 15.801311298744, - 15.688846449935, 15.576381601120, 15.463916752298, 15.351451903470, 15.238987054636, - 15.126522205795, 15.014057356948, 14.901592508095, 14.789127659235, 14.676662810370, - 14.564197961499, 14.451733112621, 14.339268263738, 14.226803414849, 14.114338565954, - 14.001873717053, 13.889408868147, 13.776944019234, 13.664479170317, 13.552014321393, - 13.439549472465, 13.327084623530, 13.214619774591, 13.102154925646, 12.989690076696, - 12.877225227740, 12.764760378780, 12.652295529814, 12.539830680843, 12.427365831867, - 12.314900982886, 12.202436133900, 12.089971284910, 11.977506435914, 11.865041586914, - 11.752576737909, 11.640111888899, 11.527647039885, 11.415182190866, 11.302717341843, - 11.190252492815, 11.077787643783, 10.965322794746, 10.852857945705, 10.740393096660, - 10.627928247610, 10.515463398556, 10.402998549498, 10.290533700437, 10.178068851371, - 10.065604002301, 9.953139153227, 9.840674304149, 9.728209455067, 9.615744605982, - 9.503279756892, 9.390814907800, 9.278350058703, 9.165885209603, 9.053420360499, - 8.940955511392, 8.828490662281, 8.716025813167, 8.603560964049, 8.491096114928, - 8.378631265804, 8.266166416677, 8.153701567546, 8.041236718412, 7.928771869275, - 7.816307020135, 7.703842170992, 7.591377321846, 7.478912472698, 7.366447623546, - 7.253982774391, 7.141517925234, 7.029053076074, 6.916588226911, 6.804123377746, - 6.691658528578, 6.579193679407, 6.466728830234, 6.354263981058, 6.241799131880, - 6.129334282700, 6.016869433517, 5.904404584332, 5.791939735145, 5.679474885955, - 5.567010036763, 5.454545187570, 5.342080338374, 5.229615489176, 5.117150639976, - 5.004685790774, 4.892220941570, 4.779756092365, 4.667291243157, 4.554826393948, - 4.442361544737, 4.329896695525, 4.217431846311, 4.104966997095, 3.992502147877, - 3.880037298658, 3.767572449438, 3.655107600216, 3.542642750993, 3.430177901769, - 3.317713052543, 3.205248203316, 3.092783354087, 2.980318504858, 2.867853655627, - 2.755388806396, 2.642923957163, 2.530459107929, 2.417994258695, 2.305529409459, - 2.193064560223, 2.080599710986, 1.968134861748, 1.855670012509, 1.743205163269, - 1.630740314029, 1.518275464789, 1.405810615547, 1.293345766305, 1.180880917063, - 1.068416067820, 0.955951218577, 0.843486369334, 0.731021520090, 0.618556670846, - 0.506091821601, 0.393626972357, 0.281162123112, 0.168697273867, 0.056232424622 -)) +DEFINE_GAUSSIAN_LATITUDES( + 800, LIST( 89.913910432567, 89.802388520364, 89.690208010997, 89.577878696439, 89.465492936558, 89.353079862649, + 89.240651524094, 89.128213797733, 89.015769888926, 88.903321693762, 88.790870405278, 88.678416811542, + 88.565961453973, 88.453504716809, 88.341046880271, 88.228588153518, 88.116128695829, 88.003668630629, + 87.891208055042, 87.778747046539, 87.666285667668, 87.553823969486, 87.441361994075, 87.328899776437, + 87.216437345920, 87.103974727314, 86.991511941706, 86.879049007143, 86.766585939163, 86.654122751216, + 86.541659455003, 86.429196060750, 86.316732577436, 86.204269012976, 86.091805374374, 85.979341667850, + 85.866877898947, 85.754414072622, 85.641950193319, 85.529486265037, 85.417022291380, 85.304558275609, + 85.192094220678, 85.079630129273, 84.967166003838, 84.854701846604, 84.742237659612, 84.629773444731, + 84.517309203677, 84.404844938029, 84.292380649239, 84.179916338650, 84.067452007501, 83.954987656940, + 83.842523288029, 83.730058901757, 83.617594499041, 83.505130080736, 83.392665647637, 83.280201200487, + 83.167736739980, 83.055272266765, 82.942807781449, 82.830343284601, 82.717878776757, 82.605414258418, + 82.492949730055, 82.380485192112, 82.268020645007, 82.155556089135, 82.043091524867, 81.930626952554, + 81.818162372528, 81.705697785102, 81.593233190575, 81.480768589225, 81.368303981322, 81.255839367117, + 81.143374746850, 81.030910120750, 80.918445489032, 80.805980851905, 80.693516209562, 80.581051562192, + 80.468586909973, 80.356122253073, 80.243657591655, 80.131192925873, 80.018728255875, 79.906263581802, + 79.793798903788, 79.681334221962, 79.568869536448, 79.456404847364, 79.343940154822, 79.231475458931, + 79.119010759796, 79.006546057514, 78.894081352183, 78.781616643893, 78.669151932734, 78.556687218788, + 78.444222502139, 78.331757782864, 78.219293061038, 78.106828336733, 77.994363610020, 77.881898880965, + 77.769434149634, 77.656969416087, 77.544504680386, 77.432039942588, 77.319575202748, 77.207110460921, + 77.094645717159, 76.982180971512, 76.869716224029, 76.757251474755, 76.644786723737, 76.532321971017, + 76.419857216639, 76.307392460644, 76.194927703070, 76.082462943956, 75.969998183339, 75.857533421255, + 75.745068657739, 75.632603892824, 75.520139126543, 75.407674358928, 75.295209590008, 75.182744819815, + 75.070280048376, 74.957815275720, 74.845350501873, 74.732885726863, 74.620420950714, 74.507956173452, + 74.395491395100, 74.283026615682, 74.170561835220, 74.058097053737, 73.945632271255, 73.833167487793, + 73.720702703373, 73.608237918014, 73.495773131735, 73.383308344555, 73.270843556493, 73.158378767565, + 73.045913977789, 72.933449187182, 72.820984395761, 72.708519603540, 72.596054810536, 72.483590016764, + 72.371125222239, 72.258660426974, 72.146195630983, 72.033730834282, 71.921266036881, 71.808801238796, + 71.696336440038, 71.583871640619, 71.471406840552, 71.358942039849, 71.246477238520, 71.134012436578, + 71.021547634032, 70.909082830894, 70.796618027174, 70.684153222883, 70.571688418029, 70.459223612624, + 70.346758806675, 70.234294000194, 70.121829193188, 70.009364385667, 69.896899577639, 69.784434769113, + 69.671969960097, 69.559505150599, 69.447040340627, 69.334575530189, 69.222110719292, 69.109645907944, + 68.997181096152, 68.884716283923, 68.772251471264, 68.659786658182, 68.547321844684, 68.434857030775, + 68.322392216464, 68.209927401755, 68.097462586655, 67.984997771169, 67.872532955305, 67.760068139067, + 67.647603322461, 67.535138505493, 67.422673688169, 67.310208870492, 67.197744052469, 67.085279234106, + 66.972814415406, 66.860349596374, 66.747884777016, 66.635419957337, 66.522955137340, 66.410490317031, + 66.298025496414, 66.185560675493, 66.073095854272, 65.960631032757, 65.848166210950, 65.735701388856, + 65.623236566480, 65.510771743824, 65.398306920893, 65.285842097690, 65.173377274220, 65.060912450485, + 64.948447626490, 64.835982802238, 64.723517977732, 64.611053152976, 64.498588327972, 64.386123502726, + 64.273658677238, 64.161193851514, 64.048729025555, 63.936264199365, 63.823799372947, 63.711334546304, + 63.598869719438, 63.486404892353, 63.373940065051, 63.261475237535, 63.149010409808, 63.036545581872, + 62.924080753730, 62.811615925385, 62.699151096839, 62.586686268095, 62.474221439154, 62.361756610020, + 62.249291780695, 62.136826951181, 62.024362121480, 61.911897291595, 61.799432461528, 61.686967631281, + 61.574502800856, 61.462037970255, 61.349573139481, 61.237108308536, 61.124643477421, 61.012178646138, + 60.899713814690, 60.787248983078, 60.674784151304, 60.562319319371, 60.449854487279, 60.337389655031, + 60.224924822629, 60.112459990074, 59.999995157368, 59.887530324513, 59.775065491510, 59.662600658361, + 59.550135825068, 59.437670991632, 59.325206158055, 59.212741324339, 59.100276490485, 58.987811656494, + 58.875346822368, 58.762881988108, 58.650417153717, 58.537952319194, 58.425487484543, 58.313022649763, + 58.200557814858, 58.088092979827, 57.975628144672, 57.863163309394, 57.750698473996, 57.638233638477, + 57.525768802840, 57.413303967086, 57.300839131215, 57.188374295229, 57.075909459130, 56.963444622917, + 56.850979786594, 56.738514950160, 56.626050113617, 56.513585276965, 56.401120440207, 56.288655603343, + 56.176190766374, 56.063725929301, 55.951261092126, 55.838796254849, 55.726331417471, 55.613866579993, + 55.501401742417, 55.388936904743, 55.276472066972, 55.164007229106, 55.051542391144, 54.939077553089, + 54.826612714941, 54.714147876700, 54.601683038368, 54.489218199946, 54.376753361435, 54.264288522834, + 54.151823684146, 54.039358845371, 53.926894006510, 53.814429167564, 53.701964328533, 53.589499489418, + 53.477034650221, 53.364569810941, 53.252104971580, 53.139640132139, 53.027175292617, 52.914710453017, + 52.802245613338, 52.689780773581, 52.577315933747, 52.464851093838, 52.352386253852, 52.239921413792, + 52.127456573658, 52.014991733450, 51.902526893169, 51.790062052816, 51.677597212392, 51.565132371896, + 51.452667531331, 51.340202690695, 51.227737849991, 51.115273009218, 51.002808168378, 50.890343327470, + 50.777878486496, 50.665413645456, 50.552948804350, 50.440483963179, 50.328019121945, 50.215554280646, + 50.103089439284, 49.990624597860, 49.878159756373, 49.765694914825, 49.653230073216, 49.540765231546, + 49.428300389817, 49.315835548028, 49.203370706180, 49.090905864273, 48.978441022308, 48.865976180286, + 48.753511338207, 48.641046496072, 48.528581653880, 48.416116811633, 48.303651969331, 48.191187126974, + 48.078722284563, 47.966257442098, 47.853792599579, 47.741327757008, 47.628862914385, 47.516398071709, + 47.403933228982, 47.291468386204, 47.179003543375, 47.066538700496, 46.954073857566, 46.841609014588, + 46.729144171560, 46.616679328483, 46.504214485358, 46.391749642185, 46.279284798965, 46.166819955698, + 46.054355112383, 45.941890269023, 45.829425425616, 45.716960582163, 45.604495738666, 45.492030895123, + 45.379566051536, 45.267101207904, 45.154636364228, 45.042171520509, 44.929706676747, 44.817241832942, + 44.704776989094, 44.592312145205, 44.479847301273, 44.367382457299, 44.254917613285, 44.142452769229, + 44.029987925133, 43.917523080997, 43.805058236821, 43.692593392605, 43.580128548349, 43.467663704055, + 43.355198859722, 43.242734015350, 43.130269170940, 43.017804326492, 42.905339482007, 42.792874637484, + 42.680409792924, 42.567944948328, 42.455480103695, 42.343015259025, 42.230550414320, 42.118085569579, + 42.005620724803, 41.893155879992, 41.780691035146, 41.668226190265, 41.555761345350, 41.443296500400, + 41.330831655417, 41.218366810400, 41.105901965350, 40.993437120267, 40.880972275151, 40.768507430002, + 40.656042584821, 40.543577739608, 40.431112894362, 40.318648049085, 40.206183203777, 40.093718358438, + 39.981253513067, 39.868788667666, 39.756323822234, 39.643858976772, 39.531394131279, 39.418929285757, + 39.306464440205, 39.193999594624, 39.081534749013, 38.969069903374, 38.856605057705, 38.744140212008, + 38.631675366283, 38.519210520529, 38.406745674747, 38.294280828938, 38.181815983101, 38.069351137236, + 37.956886291344, 37.844421445426, 37.731956599480, 37.619491753508, 37.507026907509, 37.394562061484, + 37.282097215433, 37.169632369356, 37.057167523253, 36.944702677124, 36.832237830971, 36.719772984792, + 36.607308138588, 36.494843292359, 36.382378446106, 36.269913599828, 36.157448753526, 36.044983907199, + 35.932519060849, 35.820054214475, 35.707589368077, 35.595124521656, 35.482659675211, 35.370194828743, + 35.257729982253, 35.145265135739, 35.032800289203, 34.920335442644, 34.807870596063, 34.695405749459, + 34.582940902834, 34.470476056186, 34.358011209517, 34.245546362826, 34.133081516114, 34.020616669381, + 33.908151822626, 33.795686975850, 33.683222129054, 33.570757282236, 33.458292435398, 33.345827588540, + 33.233362741661, 33.120897894762, 33.008433047843, 32.895968200904, 32.783503353946, 32.671038506967, + 32.558573659970, 32.446108812953, 32.333643965916, 32.221179118861, 32.108714271786, 31.996249424693, + 31.883784577581, 31.771319730451, 31.658854883301, 31.546390036134, 31.433925188949, 31.321460341745, + 31.208995494523, 31.096530647284, 30.984065800027, 30.871600952752, 30.759136105459, 30.646671258150, + 30.534206410823, 30.421741563479, 30.309276716118, 30.196811868740, 30.084347021345, 29.971882173934, + 29.859417326506, 29.746952479061, 29.634487631601, 29.522022784124, 29.409557936631, 29.297093089122, + 29.184628241597, 29.072163394056, 28.959698546500, 28.847233698928, 28.734768851340, 28.622304003737, + 28.509839156119, 28.397374308486, 28.284909460838, 28.172444613174, 28.059979765496, 27.947514917803, + 27.835050070096, 27.722585222374, 27.610120374637, 27.497655526887, 27.385190679122, 27.272725831342, + 27.160260983549, 27.047796135742, 26.935331287921, 26.822866440086, 26.710401592237, 26.597936744375, + 26.485471896499, 26.373007048610, 26.260542200708, 26.148077352792, 26.035612504863, 25.923147656922, + 25.810682808967, 25.698217960999, 25.585753113019, 25.473288265026, 25.360823417021, 25.248358569002, + 25.135893720972, 25.023428872929, 24.910964024874, 24.798499176807, 24.686034328727, 24.573569480636, + 24.461104632533, 24.348639784418, 24.236174936291, 24.123710088152, 24.011245240002, 23.898780391841, + 23.786315543668, 23.673850695483, 23.561385847288, 23.448920999081, 23.336456150863, 23.223991302634, + 23.111526454394, 22.999061606143, 22.886596757882, 22.774131909610, 22.661667061327, 22.549202213033, + 22.436737364729, 22.324272516415, 22.211807668090, 22.099342819755, 21.986877971410, 21.874413123055, + 21.761948274690, 21.649483426314, 21.537018577929, 21.424553729534, 21.312088881129, 21.199624032715, + 21.087159184291, 20.974694335857, 20.862229487414, 20.749764638962, 20.637299790500, 20.524834942029, + 20.412370093549, 20.299905245059, 20.187440396561, 20.074975548053, 19.962510699537, 19.850045851012, + 19.737581002478, 19.625116153935, 19.512651305384, 19.400186456824, 19.287721608255, 19.175256759678, + 19.062791911093, 18.950327062499, 18.837862213897, 18.725397365287, 18.612932516668, 18.500467668042, + 18.388002819407, 18.275537970765, 18.163073122115, 18.050608273457, 17.938143424791, 17.825678576117, + 17.713213727436, 17.600748878747, 17.488284030051, 17.375819181347, 17.263354332636, 17.150889483917, + 17.038424635192, 16.925959786458, 16.813494937718, 16.701030088971, 16.588565240217, 16.476100391455, + 16.363635542687, 16.251170693912, 16.138705845130, 16.026240996341, 15.913776147546, 15.801311298744, + 15.688846449935, 15.576381601120, 15.463916752298, 15.351451903470, 15.238987054636, 15.126522205795, + 15.014057356948, 14.901592508095, 14.789127659235, 14.676662810370, 14.564197961499, 14.451733112621, + 14.339268263738, 14.226803414849, 14.114338565954, 14.001873717053, 13.889408868147, 13.776944019234, + 13.664479170317, 13.552014321393, 13.439549472465, 13.327084623530, 13.214619774591, 13.102154925646, + 12.989690076696, 12.877225227740, 12.764760378780, 12.652295529814, 12.539830680843, 12.427365831867, + 12.314900982886, 12.202436133900, 12.089971284910, 11.977506435914, 11.865041586914, 11.752576737909, + 11.640111888899, 11.527647039885, 11.415182190866, 11.302717341843, 11.190252492815, 11.077787643783, + 10.965322794746, 10.852857945705, 10.740393096660, 10.627928247610, 10.515463398556, 10.402998549498, + 10.290533700437, 10.178068851371, 10.065604002301, 9.953139153227, 9.840674304149, 9.728209455067, + 9.615744605982, 9.503279756892, 9.390814907800, 9.278350058703, 9.165885209603, 9.053420360499, + 8.940955511392, 8.828490662281, 8.716025813167, 8.603560964049, 8.491096114928, 8.378631265804, + 8.266166416677, 8.153701567546, 8.041236718412, 7.928771869275, 7.816307020135, 7.703842170992, + 7.591377321846, 7.478912472698, 7.366447623546, 7.253982774391, 7.141517925234, 7.029053076074, + 6.916588226911, 6.804123377746, 6.691658528578, 6.579193679407, 6.466728830234, 6.354263981058, + 6.241799131880, 6.129334282700, 6.016869433517, 5.904404584332, 5.791939735145, 5.679474885955, + 5.567010036763, 5.454545187570, 5.342080338374, 5.229615489176, 5.117150639976, 5.004685790774, + 4.892220941570, 4.779756092365, 4.667291243157, 4.554826393948, 4.442361544737, 4.329896695525, + 4.217431846311, 4.104966997095, 3.992502147877, 3.880037298658, 3.767572449438, 3.655107600216, + 3.542642750993, 3.430177901769, 3.317713052543, 3.205248203316, 3.092783354087, 2.980318504858, + 2.867853655627, 2.755388806396, 2.642923957163, 2.530459107929, 2.417994258695, 2.305529409459, + 2.193064560223, 2.080599710986, 1.968134861748, 1.855670012509, 1.743205163269, 1.630740314029, + 1.518275464789, 1.405810615547, 1.293345766305, 1.180880917063, 1.068416067820, 0.955951218577, + 0.843486369334, 0.731021520090, 0.618556670846, 0.506091821601, 0.393626972357, 0.281162123112, + 0.168697273867, 0.056232424622 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N8000.cc b/src/atlas/grid/detail/spacing/gaussian/N8000.cc index c097ec50b..f4d552a9a 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N8000.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N8000.cc @@ -7,1611 +7,1324 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(8000,LIST( - 89.991388621915, 89.980233294064, 89.969012087973, 89.957775997170, 89.946534260250, - 89.935289791164, 89.924043795176, 89.912796860149, 89.901549306701, 89.890301324497, - 89.879053032872, 89.867804510659, 89.856555812013, 89.845306975370, 89.834058028757, - 89.822808993098, 89.811559884324, 89.800310714781, 89.789061494187, 89.777812230288, - 89.766562929342, 89.755313596457, 89.744064235840, 89.732814850994, 89.721565444855, - 89.710316019900, 89.699066578241, 89.687817121682, 89.676567651779, 89.665318169874, - 89.654068677140, 89.642819174600, 89.631569663150, 89.620320143583, 89.609070616601, - 89.597821082824, 89.586571542809, 89.575321997048, 89.564072445989, 89.552822890030, - 89.541573329533, 89.530323764823, 89.519074196195, 89.507824623919, 89.496575048240, - 89.485325469380, 89.474075887543, 89.462826302916, 89.451576715671, 89.440327125966, - 89.429077533946, 89.417827939746, 89.406578343489, 89.395328745290, 89.384079145256, - 89.372829543485, 89.361579940070, 89.350330335095, 89.339080728640, 89.327831120779, - 89.316581511583, 89.305331901115, 89.294082289437, 89.282832676606, 89.271583062674, - 89.260333447692, 89.249083831708, 89.237834214766, 89.226584596907, 89.215334978171, - 89.204085358595, 89.192835738215, 89.181586117063, 89.170336495171, 89.159086872568, - 89.147837249283, 89.136587625343, 89.125338000772, 89.114088375595, 89.102838749834, - 89.091589123511, 89.080339496647, 89.069089869262, 89.057840241373, 89.046590612999, - 89.035340984158, 89.024091354864, 89.012841725134, 89.001592094982, 88.990342464422, - 88.979092833468, 88.967843202133, 88.956593570428, 88.945343938367, 88.934094305960, - 88.922844673218, 88.911595040151, 88.900345406769, 88.889095773083, 88.877846139100, - 88.866596504830, 88.855346870282, 88.844097235463, 88.832847600381, 88.821597965045, - 88.810348329460, 88.799098693634, 88.787849057574, 88.776599421287, 88.765349784777, - 88.754100148052, 88.742850511118, 88.731600873979, 88.720351236641, 88.709101599110, - 88.697851961390, 88.686602323487, 88.675352685404, 88.664103047147, 88.652853408719, - 88.641603770126, 88.630354131371, 88.619104492457, 88.607854853390, 88.596605214173, - 88.585355574808, 88.574105935301, 88.562856295653, 88.551606655869, 88.540357015951, - 88.529107375903, 88.517857735727, 88.506608095426, 88.495358455004, 88.484108814463, - 88.472859173805, 88.461609533033, 88.450359892150, 88.439110251158, 88.427860610059, - 88.416610968856, 88.405361327551, 88.394111686145, 88.382862044642, 88.371612403043, - 88.360362761349, 88.349113119564, 88.337863477688, 88.326613835725, 88.315364193674, - 88.304114551539, 88.292864909320, 88.281615267020, 88.270365624640, 88.259115982182, - 88.247866339647, 88.236616697036, 88.225367054351, 88.214117411594, 88.202867768765, - 88.191618125867, 88.180368482900, 88.169118839865, 88.157869196765, 88.146619553599, - 88.135369910370, 88.124120267079, 88.112870623726, 88.101620980312, 88.090371336839, - 88.079121693308, 88.067872049720, 88.056622406075, 88.045372762376, 88.034123118621, - 88.022873474814, 88.011623830954, 88.000374187042, 87.989124543080, 87.977874899067, - 87.966625255006, 87.955375610897, 87.944125966739, 87.932876322536, 87.921626678286, - 87.910377033991, 87.899127389652, 87.887877745269, 87.876628100842, 87.865378456374, - 87.854128811864, 87.842879167313, 87.831629522721, 87.820379878089, 87.809130233419, - 87.797880588709, 87.786630943962, 87.775381299177, 87.764131654356, 87.752882009498, - 87.741632364604, 87.730382719676, 87.719133074712, 87.707883429714, 87.696633784683, - 87.685384139618, 87.674134494521, 87.662884849392, 87.651635204230, 87.640385559038, - 87.629135913814, 87.617886268560, 87.606636623276, 87.595386977963, 87.584137332620, - 87.572887687248, 87.561638041848, 87.550388396420, 87.539138750965, 87.527889105482, - 87.516639459973, 87.505389814437, 87.494140168875, 87.482890523287, 87.471640877673, - 87.460391232035, 87.449141586371, 87.437891940684, 87.426642294972, 87.415392649236, - 87.404143003477, 87.392893357695, 87.381643711889, 87.370394066062, 87.359144420212, - 87.347894774339, 87.336645128445, 87.325395482530, 87.314145836593, 87.302896190636, - 87.291646544658, 87.280396898659, 87.269147252640, 87.257897606602, 87.246647960543, - 87.235398314465, 87.224148668368, 87.212899022252, 87.201649376117, 87.190399729964, - 87.179150083793, 87.167900437603, 87.156650791396, 87.145401145170, 87.134151498928, - 87.122901852668, 87.111652206391, 87.100402560097, 87.089152913787, 87.077903267461, - 87.066653621117, 87.055403974758, 87.044154328383, 87.032904681993, 87.021655035586, - 87.010405389165, 86.999155742728, 86.987906096276, 86.976656449810, 86.965406803328, - 86.954157156832, 86.942907510322, 86.931657863798, 86.920408217259, 86.909158570707, - 86.897908924141, 86.886659277561, 86.875409630968, 86.864159984362, 86.852910337742, - 86.841660691110, 86.830411044464, 86.819161397806, 86.807911751135, 86.796662104452, - 86.785412457757, 86.774162811049, 86.762913164329, 86.751663517597, 86.740413870853, - 86.729164224098, 86.717914577331, 86.706664930552, 86.695415283763, 86.684165636961, - 86.672915990149, 86.661666343326, 86.650416696492, 86.639167049647, 86.627917402791, - 86.616667755925, 86.605418109048, 86.594168462161, 86.582918815264, 86.571669168357, - 86.560419521439, 86.549169874512, 86.537920227574, 86.526670580627, 86.515420933670, - 86.504171286704, 86.492921639728, 86.481671992742, 86.470422345748, 86.459172698744, - 86.447923051731, 86.436673404709, 86.425423757678, 86.414174110638, 86.402924463589, - 86.391674816532, 86.380425169466, 86.369175522391, 86.357925875308, 86.346676228216, - 86.335426581117, 86.324176934009, 86.312927286892, 86.301677639768, 86.290427992636, - 86.279178345495, 86.267928698347, 86.256679051191, 86.245429404028, 86.234179756856, - 86.222930109677, 86.211680462491, 86.200430815297, 86.189181168095, 86.177931520887, - 86.166681873671, 86.155432226448, 86.144182579217, 86.132932931980, 86.121683284736, - 86.110433637484, 86.099183990226, 86.087934342961, 86.076684695689, 86.065435048411, - 86.054185401125, 86.042935753833, 86.031686106535, 86.020436459230, 86.009186811919, - 85.997937164601, 85.986687517277, 85.975437869947, 85.964188222610, 85.952938575268, - 85.941688927919, 85.930439280564, 85.919189633203, 85.907939985836, 85.896690338463, - 85.885440691085, 85.874191043700, 85.862941396310, 85.851691748914, 85.840442101512, - 85.829192454105, 85.817942806692, 85.806693159274, 85.795443511850, 85.784193864420, - 85.772944216986, 85.761694569545, 85.750444922100, 85.739195274649, 85.727945627193, - 85.716695979732, 85.705446332265, 85.694196684794, 85.682947037317, 85.671697389835, - 85.660447742349, 85.649198094857, 85.637948447361, 85.626698799859, 85.615449152353, - 85.604199504842, 85.592949857326, 85.581700209805, 85.570450562280, 85.559200914750, - 85.547951267215, 85.536701619676, 85.525451972132, 85.514202324584, 85.502952677031, - 85.491703029474, 85.480453381912, 85.469203734346, 85.457954086776, 85.446704439201, - 85.435454791622, 85.424205144038, 85.412955496451, 85.401705848859, 85.390456201263, - 85.379206553663, 85.367956906059, 85.356707258450, 85.345457610838, 85.334207963222, - 85.322958315601, 85.311708667977, 85.300459020349, 85.289209372717, 85.277959725081, - 85.266710077441, 85.255460429797, 85.244210782149, 85.232961134498, 85.221711486843, - 85.210461839184, 85.199212191522, 85.187962543856, 85.176712896186, 85.165463248512, - 85.154213600835, 85.142963953155, 85.131714305471, 85.120464657783, 85.109215010092, - 85.097965362398, 85.086715714700, 85.075466066998, 85.064216419293, 85.052966771585, - 85.041717123874, 85.030467476159, 85.019217828441, 85.007968180719, 84.996718532994, - 84.985468885266, 84.974219237535, 84.962969589801, 84.951719942063, 84.940470294323, - 84.929220646579, 84.917970998832, 84.906721351082, 84.895471703329, 84.884222055572, - 84.872972407813, 84.861722760051, 84.850473112286, 84.839223464518, 84.827973816747, - 84.816724168973, 84.805474521196, 84.794224873416, 84.782975225633, 84.771725577847, - 84.760475930059, 84.749226282268, 84.737976634474, 84.726726986677, 84.715477338877, - 84.704227691075, 84.692978043270, 84.681728395462, 84.670478747652, 84.659229099838, - 84.647979452023, 84.636729804204, 84.625480156383, 84.614230508559, 84.602980860733, - 84.591731212904, 84.580481565073, 84.569231917239, 84.557982269402, 84.546732621563, - 84.535482973721, 84.524233325877, 84.512983678031, 84.501734030182, 84.490484382331, - 84.479234734477, 84.467985086620, 84.456735438762, 84.445485790901, 84.434236143037, - 84.422986495172, 84.411736847303, 84.400487199433, 84.389237551560, 84.377987903685, - 84.366738255808, 84.355488607928, 84.344238960047, 84.332989312163, 84.321739664276, - 84.310490016388, 84.299240368497, 84.287990720604, 84.276741072709, 84.265491424812, - 84.254241776912, 84.242992129011, 84.231742481107, 84.220492833201, 84.209243185293, - 84.197993537383, 84.186743889471, 84.175494241557, 84.164244593641, 84.152994945723, - 84.141745297803, 84.130495649880, 84.119246001956, 84.107996354030, 84.096746706102, - 84.085497058171, 84.074247410239, 84.062997762305, 84.051748114369, 84.040498466431, - 84.029248818491, 84.017999170549, 84.006749522606, 83.995499874660, 83.984250226713, - 83.973000578763, 83.961750930812, 83.950501282859, 83.939251634904, 83.928001986948, - 83.916752338989, 83.905502691029, 83.894253043067, 83.883003395103, 83.871753747137, - 83.860504099170, 83.849254451201, 83.838004803230, 83.826755155257, 83.815505507283, - 83.804255859307, 83.793006211329, 83.781756563349, 83.770506915368, 83.759257267385, - 83.748007619401, 83.736757971415, 83.725508323427, 83.714258675437, 83.703009027446, - 83.691759379453, 83.680509731459, 83.669260083463, 83.658010435466, 83.646760787467, - 83.635511139466, 83.624261491464, 83.613011843460, 83.601762195454, 83.590512547447, - 83.579262899439, 83.568013251429, 83.556763603417, 83.545513955404, 83.534264307390, - 83.523014659373, 83.511765011356, 83.500515363337, 83.489265715316, 83.478016067294, - 83.466766419271, 83.455516771246, 83.444267123219, 83.433017475192, 83.421767827162, - 83.410518179132, 83.399268531100, 83.388018883066, 83.376769235031, 83.365519586995, - 83.354269938957, 83.343020290918, 83.331770642878, 83.320520994836, 83.309271346793, - 83.298021698748, 83.286772050702, 83.275522402655, 83.264272754606, 83.253023106557, - 83.241773458505, 83.230523810453, 83.219274162399, 83.208024514344, 83.196774866287, - 83.185525218230, 83.174275570171, 83.163025922110, 83.151776274049, 83.140526625986, - 83.129276977922, 83.118027329857, 83.106777681790, 83.095528033722, 83.084278385653, - 83.073028737583, 83.061779089512, 83.050529441439, 83.039279793365, 83.028030145290, - 83.016780497214, 83.005530849136, 82.994281201058, 82.983031552978, 82.971781904897, - 82.960532256814, 82.949282608731, 82.938032960647, 82.926783312561, 82.915533664474, - 82.904284016386, 82.893034368297, 82.881784720207, 82.870535072115, 82.859285424023, - 82.848035775929, 82.836786127835, 82.825536479739, 82.814286831642, 82.803037183544, - 82.791787535445, 82.780537887345, 82.769288239244, 82.758038591141, 82.746788943038, - 82.735539294933, 82.724289646828, 82.713039998721, 82.701790350614, 82.690540702505, - 82.679291054396, 82.668041406285, 82.656791758173, 82.645542110060, 82.634292461947, - 82.623042813832, 82.611793165716, 82.600543517599, 82.589293869481, 82.578044221362, - 82.566794573243, 82.555544925122, 82.544295277000, 82.533045628877, 82.521795980754, - 82.510546332629, 82.499296684503, 82.488047036377, 82.476797388249, 82.465547740120, - 82.454298091991, 82.443048443860, 82.431798795729, 82.420549147597, 82.409299499464, - 82.398049851329, 82.386800203194, 82.375550555058, 82.364300906921, 82.353051258784, - 82.341801610645, 82.330551962505, 82.319302314365, 82.308052666223, 82.296803018081, - 82.285553369938, 82.274303721793, 82.263054073648, 82.251804425503, 82.240554777356, - 82.229305129208, 82.218055481060, 82.206805832910, 82.195556184760, 82.184306536609, - 82.173056888457, 82.161807240305, 82.150557592151, 82.139307943997, 82.128058295841, - 82.116808647685, 82.105558999528, 82.094309351371, 82.083059703212, 82.071810055053, - 82.060560406893, 82.049310758732, 82.038061110570, 82.026811462407, 82.015561814244, - 82.004312166079, 81.993062517914, 81.981812869749, 81.970563221582, 81.959313573415, - 81.948063925247, 81.936814277078, 81.925564628908, 81.914314980738, 81.903065332566, - 81.891815684394, 81.880566036222, 81.869316388048, 81.858066739874, 81.846817091699, - 81.835567443523, 81.824317795346, 81.813068147169, 81.801818498991, 81.790568850812, - 81.779319202633, 81.768069554453, 81.756819906272, 81.745570258090, 81.734320609908, - 81.723070961725, 81.711821313541, 81.700571665356, 81.689322017171, 81.678072368985, - 81.666822720799, 81.655573072611, 81.644323424423, 81.633073776235, 81.621824128045, - 81.610574479855, 81.599324831664, 81.588075183473, 81.576825535281, 81.565575887088, - 81.554326238894, 81.543076590700, 81.531826942505, 81.520577294310, 81.509327646113, - 81.498077997917, 81.486828349719, 81.475578701521, 81.464329053322, 81.453079405123, - 81.441829756922, 81.430580108722, 81.419330460520, 81.408080812318, 81.396831164115, - 81.385581515912, 81.374331867708, 81.363082219503, 81.351832571298, 81.340582923092, - 81.329333274886, 81.318083626679, 81.306833978471, 81.295584330263, 81.284334682054, - 81.273085033844, 81.261835385634, 81.250585737423, 81.239336089212, 81.228086441000, - 81.216836792787, 81.205587144574, 81.194337496360, 81.183087848146, 81.171838199931, - 81.160588551715, 81.149338903499, 81.138089255282, 81.126839607065, 81.115589958847, - 81.104340310628, 81.093090662409, 81.081841014190, 81.070591365969, 81.059341717749, - 81.048092069527, 81.036842421305, 81.025592773083, 81.014343124860, 81.003093476636, - 80.991843828412, 80.980594180187, 80.969344531962, 80.958094883736, 80.946845235510, - 80.935595587283, 80.924345939056, 80.913096290828, 80.901846642599, 80.890596994370, - 80.879347346140, 80.868097697910, 80.856848049679, 80.845598401448, 80.834348753217, - 80.823099104984, 80.811849456751, 80.800599808518, 80.789350160284, 80.778100512050, - 80.766850863815, 80.755601215580, 80.744351567344, 80.733101919107, 80.721852270870, - 80.710602622633, 80.699352974395, 80.688103326157, 80.676853677918, 80.665604029678, - 80.654354381438, 80.643104733198, 80.631855084957, 80.620605436715, 80.609355788473, - 80.598106140231, 80.586856491988, 80.575606843745, 80.564357195501, 80.553107547256, - 80.541857899012, 80.530608250766, 80.519358602521, 80.508108954274, 80.496859306028, - 80.485609657780, 80.474360009533, 80.463110361284, 80.451860713036, 80.440611064787, - 80.429361416537, 80.418111768287, 80.406862120037, 80.395612471786, 80.384362823534, - 80.373113175282, 80.361863527030, 80.350613878777, 80.339364230524, 80.328114582270, - 80.316864934016, 80.305615285762, 80.294365637507, 80.283115989251, 80.271866340995, - 80.260616692739, 80.249367044482, 80.238117396225, 80.226867747968, 80.215618099709, - 80.204368451451, 80.193118803192, 80.181869154933, 80.170619506673, 80.159369858413, - 80.148120210152, 80.136870561891, 80.125620913629, 80.114371265367, 80.103121617105, - 80.091871968842, 80.080622320579, 80.069372672315, 80.058123024052, 80.046873375787, - 80.035623727522, 80.024374079257, 80.013124430991, 80.001874782725, 79.990625134459, - 79.979375486192, 79.968125837925, 79.956876189657, 79.945626541389, 79.934376893120, - 79.923127244852, 79.911877596582, 79.900627948313, 79.889378300043, 79.878128651772, - 79.866879003501, 79.855629355230, 79.844379706958, 79.833130058686, 79.821880410414, - 79.810630762141, 79.799381113868, 79.788131465595, 79.776881817321, 79.765632169046, - 79.754382520772, 79.743132872497, 79.731883224221, 79.720633575945, 79.709383927669, - 79.698134279393, 79.686884631116, 79.675634982838, 79.664385334561, 79.653135686283, - 79.641886038004, 79.630636389726, 79.619386741446, 79.608137093167, 79.596887444887, - 79.585637796607, 79.574388148326, 79.563138500045, 79.551888851764, 79.540639203482, - 79.529389555200, 79.518139906918, 79.506890258635, 79.495640610352, 79.484390962069, - 79.473141313785, 79.461891665501, 79.450642017217, 79.439392368932, 79.428142720647, - 79.416893072361, 79.405643424075, 79.394393775789, 79.383144127503, 79.371894479216, - 79.360644830929, 79.349395182641, 79.338145534353, 79.326895886065, 79.315646237777, - 79.304396589488, 79.293146941199, 79.281897292909, 79.270647644619, 79.259397996329, - 79.248148348038, 79.236898699748, 79.225649051457, 79.214399403165, 79.203149754873, - 79.191900106581, 79.180650458289, 79.169400809996, 79.158151161703, 79.146901513409, - 79.135651865116, 79.124402216822, 79.113152568527, 79.101902920233, 79.090653271938, - 79.079403623642, 79.068153975347, 79.056904327051, 79.045654678755, 79.034405030458, - 79.023155382161, 79.011905733864, 79.000656085567, 78.989406437269, 78.978156788971, - 78.966907140672, 78.955657492374, 78.944407844075, 78.933158195776, 78.921908547476, - 78.910658899176, 78.899409250876, 78.888159602576, 78.876909954275, 78.865660305974, - 78.854410657672, 78.843161009371, 78.831911361069, 78.820661712767, 78.809412064464, - 78.798162416161, 78.786912767858, 78.775663119555, 78.764413471251, 78.753163822947, - 78.741914174643, 78.730664526338, 78.719414878034, 78.708165229729, 78.696915581423, - 78.685665933118, 78.674416284812, 78.663166636505, 78.651916988199, 78.640667339892, - 78.629417691585, 78.618168043278, 78.606918394970, 78.595668746662, 78.584419098354, - 78.573169450046, 78.561919801737, 78.550670153428, 78.539420505119, 78.528170856809, - 78.516921208500, 78.505671560190, 78.494421911879, 78.483172263569, 78.471922615258, - 78.460672966947, 78.449423318636, 78.438173670324, 78.426924022012, 78.415674373700, - 78.404424725387, 78.393175077075, 78.381925428762, 78.370675780449, 78.359426132135, - 78.348176483822, 78.336926835508, 78.325677187193, 78.314427538879, 78.303177890564, - 78.291928242249, 78.280678593934, 78.269428945619, 78.258179297303, 78.246929648987, - 78.235680000671, 78.224430352354, 78.213180704037, 78.201931055720, 78.190681407403, - 78.179431759086, 78.168182110768, 78.156932462450, 78.145682814132, 78.134433165813, - 78.123183517495, 78.111933869176, 78.100684220857, 78.089434572537, 78.078184924218, - 78.066935275898, 78.055685627578, 78.044435979257, 78.033186330937, 78.021936682616, - 78.010687034295, 77.999437385973, 77.988187737652, 77.976938089330, 77.965688441008, - 77.954438792686, 77.943189144363, 77.931939496040, 77.920689847718, 77.909440199394, - 77.898190551071, 77.886940902747, 77.875691254423, 77.864441606099, 77.853191957775, - 77.841942309451, 77.830692661126, 77.819443012801, 77.808193364476, 77.796943716150, - 77.785694067824, 77.774444419499, 77.763194771172, 77.751945122846, 77.740695474520, - 77.729445826193, 77.718196177866, 77.706946529539, 77.695696881211, 77.684447232884, - 77.673197584556, 77.661947936228, 77.650698287899, 77.639448639571, 77.628198991242, - 77.616949342913, 77.605699694584, 77.594450046255, 77.583200397925, 77.571950749595, - 77.560701101265, 77.549451452935, 77.538201804605, 77.526952156274, 77.515702507943, - 77.504452859612, 77.493203211281, 77.481953562949, 77.470703914618, 77.459454266286, - 77.448204617954, 77.436954969621, 77.425705321289, 77.414455672956, 77.403206024623, - 77.391956376290, 77.380706727957, 77.369457079623, 77.358207431290, 77.346957782956, - 77.335708134622, 77.324458486287, 77.313208837953, 77.301959189618, 77.290709541283, - 77.279459892948, 77.268210244613, 77.256960596277, 77.245710947942, 77.234461299606, - 77.223211651270, 77.211962002933, 77.200712354597, 77.189462706260, 77.178213057923, - 77.166963409586, 77.155713761249, 77.144464112912, 77.133214464574, 77.121964816236, - 77.110715167898, 77.099465519560, 77.088215871222, 77.076966222883, 77.065716574544, - 77.054466926205, 77.043217277866, 77.031967629527, 77.020717981187, 77.009468332848, - 76.998218684508, 76.986969036168, 76.975719387827, 76.964469739487, 76.953220091146, - 76.941970442806, 76.930720794465, 76.919471146123, 76.908221497782, 76.896971849441, - 76.885722201099, 76.874472552757, 76.863222904415, 76.851973256073, 76.840723607730, - 76.829473959388, 76.818224311045, 76.806974662702, 76.795725014359, 76.784475366016, - 76.773225717672, 76.761976069328, 76.750726420985, 76.739476772641, 76.728227124296, - 76.716977475952, 76.705727827607, 76.694478179263, 76.683228530918, 76.671978882573, - 76.660729234228, 76.649479585882, 76.638229937537, 76.626980289191, 76.615730640845, - 76.604480992499, 76.593231344153, 76.581981695806, 76.570732047460, 76.559482399113, - 76.548232750766, 76.536983102419, 76.525733454072, 76.514483805724, 76.503234157377, - 76.491984509029, 76.480734860681, 76.469485212333, 76.458235563985, 76.446985915637, - 76.435736267288, 76.424486618939, 76.413236970590, 76.401987322241, 76.390737673892, - 76.379488025543, 76.368238377193, 76.356988728844, 76.345739080494, 76.334489432144, - 76.323239783794, 76.311990135443, 76.300740487093, 76.289490838742, 76.278241190391, - 76.266991542041, 76.255741893689, 76.244492245338, 76.233242596987, 76.221992948635, - 76.210743300283, 76.199493651932, 76.188244003580, 76.176994355227, 76.165744706875, - 76.154495058523, 76.143245410170, 76.131995761817, 76.120746113464, 76.109496465111, - 76.098246816758, 76.086997168404, 76.075747520051, 76.064497871697, 76.053248223343, - 76.041998574989, 76.030748926635, 76.019499278281, 76.008249629926, 75.996999981572, - 75.985750333217, 75.974500684862, 75.963251036507, 75.952001388152, 75.940751739796, - 75.929502091441, 75.918252443085, 75.907002794730, 75.895753146374, 75.884503498018, - 75.873253849661, 75.862004201305, 75.850754552949, 75.839504904592, 75.828255256235, - 75.817005607878, 75.805755959521, 75.794506311164, 75.783256662807, 75.772007014449, - 75.760757366091, 75.749507717734, 75.738258069376, 75.727008421018, 75.715758772660, - 75.704509124301, 75.693259475943, 75.682009827584, 75.670760179225, 75.659510530866, - 75.648260882507, 75.637011234148, 75.625761585789, 75.614511937430, 75.603262289070, - 75.592012640710, 75.580762992350, 75.569513343991, 75.558263695630, 75.547014047270, - 75.535764398910, 75.524514750549, 75.513265102189, 75.502015453828, 75.490765805467, - 75.479516157106, 75.468266508745, 75.457016860383, 75.445767212022, 75.434517563660, - 75.423267915299, 75.412018266937, 75.400768618575, 75.389518970213, 75.378269321851, - 75.367019673488, 75.355770025126, 75.344520376763, 75.333270728400, 75.322021080037, - 75.310771431674, 75.299521783311, 75.288272134948, 75.277022486585, 75.265772838221, - 75.254523189858, 75.243273541494, 75.232023893130, 75.220774244766, 75.209524596402, - 75.198274948037, 75.187025299673, 75.175775651309, 75.164526002944, 75.153276354579, - 75.142026706214, 75.130777057849, 75.119527409484, 75.108277761119, 75.097028112753, - 75.085778464388, 75.074528816022, 75.063279167657, 75.052029519291, 75.040779870925, - 75.029530222559, 75.018280574192, 75.007030925826, 74.995781277460, 74.984531629093, - 74.973281980726, 74.962032332359, 74.950782683992, 74.939533035625, 74.928283387258, - 74.917033738891, 74.905784090523, 74.894534442156, 74.883284793788, 74.872035145420, - 74.860785497053, 74.849535848685, 74.838286200316, 74.827036551948, 74.815786903580, - 74.804537255211, 74.793287606843, 74.782037958474, 74.770788310105, 74.759538661736, - 74.748289013367, 74.737039364998, 74.725789716629, 74.714540068259, 74.703290419890, - 74.692040771520, 74.680791123150, 74.669541474781, 74.658291826411, 74.647042178041, - 74.635792529670, 74.624542881300, 74.613293232930, 74.602043584559, 74.590793936189, - 74.579544287818, 74.568294639447, 74.557044991076, 74.545795342705, 74.534545694334, - 74.523296045962, 74.512046397591, 74.500796749219, 74.489547100848, 74.478297452476, - 74.467047804104, 74.455798155732, 74.444548507360, 74.433298858988, 74.422049210616, - 74.410799562243, 74.399549913871, 74.388300265498, 74.377050617126, 74.365800968753, - 74.354551320380, 74.343301672007, 74.332052023634, 74.320802375261, 74.309552726887, - 74.298303078514, 74.287053430140, 74.275803781767, 74.264554133393, 74.253304485019, - 74.242054836645, 74.230805188271, 74.219555539897, 74.208305891523, 74.197056243148, - 74.185806594774, 74.174556946399, 74.163307298024, 74.152057649650, 74.140808001275, - 74.129558352900, 74.118308704525, 74.107059056150, 74.095809407774, 74.084559759399, - 74.073310111023, 74.062060462648, 74.050810814272, 74.039561165896, 74.028311517520, - 74.017061869144, 74.005812220768, 73.994562572392, 73.983312924016, 73.972063275639, - 73.960813627263, 73.949563978886, 73.938314330510, 73.927064682133, 73.915815033756, - 73.904565385379, 73.893315737002, 73.882066088625, 73.870816440248, 73.859566791870, - 73.848317143493, 73.837067495115, 73.825817846738, 73.814568198360, 73.803318549982, - 73.792068901604, 73.780819253226, 73.769569604848, 73.758319956470, 73.747070308091, - 73.735820659713, 73.724571011334, 73.713321362956, 73.702071714577, 73.690822066198, - 73.679572417819, 73.668322769440, 73.657073121061, 73.645823472682, 73.634573824303, - 73.623324175924, 73.612074527544, 73.600824879165, 73.589575230785, 73.578325582405, - 73.567075934025, 73.555826285646, 73.544576637266, 73.533326988885, 73.522077340505, - 73.510827692125, 73.499578043745, 73.488328395364, 73.477078746984, 73.465829098603, - 73.454579450222, 73.443329801842, 73.432080153461, 73.420830505080, 73.409580856699, - 73.398331208318, 73.387081559936, 73.375831911555, 73.364582263174, 73.353332614792, - 73.342082966410, 73.330833318029, 73.319583669647, 73.308334021265, 73.297084372883, - 73.285834724501, 73.274585076119, 73.263335427737, 73.252085779354, 73.240836130972, - 73.229586482590, 73.218336834207, 73.207087185824, 73.195837537442, 73.184587889059, - 73.173338240676, 73.162088592293, 73.150838943910, 73.139589295527, 73.128339647144, - 73.117089998760, 73.105840350377, 73.094590701993, 73.083341053610, 73.072091405226, - 73.060841756842, 73.049592108459, 73.038342460075, 73.027092811691, 73.015843163307, - 73.004593514922, 72.993343866538, 72.982094218154, 72.970844569769, 72.959594921385, - 72.948345273000, 72.937095624616, 72.925845976231, 72.914596327846, 72.903346679461, - 72.892097031076, 72.880847382691, 72.869597734306, 72.858348085921, 72.847098437536, - 72.835848789150, 72.824599140765, 72.813349492379, 72.802099843994, 72.790850195608, - 72.779600547222, 72.768350898836, 72.757101250450, 72.745851602064, 72.734601953678, - 72.723352305292, 72.712102656906, 72.700853008520, 72.689603360133, 72.678353711747, - 72.667104063360, 72.655854414973, 72.644604766587, 72.633355118200, 72.622105469813, - 72.610855821426, 72.599606173039, 72.588356524652, 72.577106876265, 72.565857227878, - 72.554607579490, 72.543357931103, 72.532108282715, 72.520858634328, 72.509608985940, - 72.498359337552, 72.487109689165, 72.475860040777, 72.464610392389, 72.453360744001, - 72.442111095613, 72.430861447224, 72.419611798836, 72.408362150448, 72.397112502060, - 72.385862853671, 72.374613205283, 72.363363556894, 72.352113908505, 72.340864260116, - 72.329614611728, 72.318364963339, 72.307115314950, 72.295865666561, 72.284616018172, - 72.273366369782, 72.262116721393, 72.250867073004, 72.239617424614, 72.228367776225, - 72.217118127835, 72.205868479446, 72.194618831056, 72.183369182666, 72.172119534276, - 72.160869885886, 72.149620237496, 72.138370589106, 72.127120940716, 72.115871292326, - 72.104621643936, 72.093371995545, 72.082122347155, 72.070872698764, 72.059623050374, - 72.048373401983, 72.037123753593, 72.025874105202, 72.014624456811, 72.003374808420, - 71.992125160029, 71.980875511638, 71.969625863247, 71.958376214856, 71.947126566464, - 71.935876918073, 71.924627269682, 71.913377621290, 71.902127972899, 71.890878324507, - 71.879628676115, 71.868379027724, 71.857129379332, 71.845879730940, 71.834630082548, - 71.823380434156, 71.812130785764, 71.800881137372, 71.789631488980, 71.778381840587, - 71.767132192195, 71.755882543803, 71.744632895410, 71.733383247018, 71.722133598625, - 71.710883950232, 71.699634301840, 71.688384653447, 71.677135005054, 71.665885356661, - 71.654635708268, 71.643386059875, 71.632136411482, 71.620886763088, 71.609637114695, - 71.598387466302, 71.587137817908, 71.575888169515, 71.564638521121, 71.553388872728, - 71.542139224334, 71.530889575941, 71.519639927547, 71.508390279153, 71.497140630759, - 71.485890982365, 71.474641333971, 71.463391685577, 71.452142037183, 71.440892388788, - 71.429642740394, 71.418393092000, 71.407143443605, 71.395893795211, 71.384644146816, - 71.373394498422, 71.362144850027, 71.350895201632, 71.339645553237, 71.328395904843, - 71.317146256448, 71.305896608053, 71.294646959658, 71.283397311263, 71.272147662867, - 71.260898014472, 71.249648366077, 71.238398717681, 71.227149069286, 71.215899420891, - 71.204649772495, 71.193400124099, 71.182150475704, 71.170900827308, 71.159651178912, - 71.148401530516, 71.137151882120, 71.125902233725, 71.114652585328, 71.103402936932, - 71.092153288536, 71.080903640140, 71.069653991744, 71.058404343347, 71.047154694951, - 71.035905046555, 71.024655398158, 71.013405749762, 71.002156101365, 70.990906452968, - 70.979656804571, 70.968407156175, 70.957157507778, 70.945907859381, 70.934658210984, - 70.923408562587, 70.912158914190, 70.900909265793, 70.889659617395, 70.878409968998, - 70.867160320601, 70.855910672203, 70.844661023806, 70.833411375409, 70.822161727011, - 70.810912078613, 70.799662430216, 70.788412781818, 70.777163133420, 70.765913485022, - 70.754663836624, 70.743414188226, 70.732164539828, 70.720914891430, 70.709665243032, - 70.698415594634, 70.687165946236, 70.675916297837, 70.664666649439, 70.653417001041, - 70.642167352642, 70.630917704244, 70.619668055845, 70.608418407447, 70.597168759048, - 70.585919110649, 70.574669462250, 70.563419813851, 70.552170165453, 70.540920517054, - 70.529670868655, 70.518421220255, 70.507171571856, 70.495921923457, 70.484672275058, - 70.473422626659, 70.462172978259, 70.450923329860, 70.439673681460, 70.428424033061, - 70.417174384661, 70.405924736262, 70.394675087862, 70.383425439462, 70.372175791063, - 70.360926142663, 70.349676494263, 70.338426845863, 70.327177197463, 70.315927549063, - 70.304677900663, 70.293428252263, 70.282178603862, 70.270928955462, 70.259679307062, - 70.248429658661, 70.237180010261, 70.225930361861, 70.214680713460, 70.203431065059, - 70.192181416659, 70.180931768258, 70.169682119857, 70.158432471457, 70.147182823056, - 70.135933174655, 70.124683526254, 70.113433877853, 70.102184229452, 70.090934581051, - 70.079684932650, 70.068435284248, 70.057185635847, 70.045935987446, 70.034686339045, - 70.023436690643, 70.012187042242, 70.000937393840, 69.989687745439, 69.978438097037, - 69.967188448635, 69.955938800234, 69.944689151832, 69.933439503430, 69.922189855028, - 69.910940206626, 69.899690558224, 69.888440909822, 69.877191261420, 69.865941613018, - 69.854691964616, 69.843442316214, 69.832192667812, 69.820943019409, 69.809693371007, - 69.798443722605, 69.787194074202, 69.775944425800, 69.764694777397, 69.753445128995, - 69.742195480592, 69.730945832189, 69.719696183786, 69.708446535384, 69.697196886981, - 69.685947238578, 69.674697590175, 69.663447941772, 69.652198293369, 69.640948644966, - 69.629698996563, 69.618449348160, 69.607199699756, 69.595950051353, 69.584700402950, - 69.573450754546, 69.562201106143, 69.550951457740, 69.539701809336, 69.528452160932, - 69.517202512529, 69.505952864125, 69.494703215722, 69.483453567318, 69.472203918914, - 69.460954270510, 69.449704622106, 69.438454973702, 69.427205325298, 69.415955676894, - 69.404706028490, 69.393456380086, 69.382206731682, 69.370957083278, 69.359707434873, - 69.348457786469, 69.337208138065, 69.325958489660, 69.314708841256, 69.303459192851, - 69.292209544447, 69.280959896042, 69.269710247638, 69.258460599233, 69.247210950828, - 69.235961302424, 69.224711654019, 69.213462005614, 69.202212357209, 69.190962708804, - 69.179713060399, 69.168463411994, 69.157213763589, 69.145964115184, 69.134714466779, - 69.123464818373, 69.112215169968, 69.100965521563, 69.089715873158, 69.078466224752, - 69.067216576347, 69.055966927941, 69.044717279536, 69.033467631130, 69.022217982725, - 69.010968334319, 68.999718685913, 68.988469037508, 68.977219389102, 68.965969740696, - 68.954720092290, 68.943470443884, 68.932220795478, 68.920971147072, 68.909721498666, - 68.898471850260, 68.887222201854, 68.875972553448, 68.864722905042, 68.853473256635, - 68.842223608229, 68.830973959823, 68.819724311416, 68.808474663010, 68.797225014603, - 68.785975366197, 68.774725717790, 68.763476069384, 68.752226420977, 68.740976772570, - 68.729727124164, 68.718477475757, 68.707227827350, 68.695978178943, 68.684728530536, - 68.673478882129, 68.662229233722, 68.650979585315, 68.639729936908, 68.628480288501, - 68.617230640094, 68.605980991687, 68.594731343280, 68.583481694872, 68.572232046465, - 68.560982398058, 68.549732749650, 68.538483101243, 68.527233452835, 68.515983804428, - 68.504734156020, 68.493484507613, 68.482234859205, 68.470985210797, 68.459735562390, - 68.448485913982, 68.437236265574, 68.425986617166, 68.414736968758, 68.403487320350, - 68.392237671942, 68.380988023534, 68.369738375126, 68.358488726718, 68.347239078310, - 68.335989429902, 68.324739781494, 68.313490133086, 68.302240484677, 68.290990836269, - 68.279741187861, 68.268491539452, 68.257241891044, 68.245992242635, 68.234742594227, - 68.223492945818, 68.212243297410, 68.200993649001, 68.189744000592, 68.178494352184, - 68.167244703775, 68.155995055366, 68.144745406957, 68.133495758548, 68.122246110139, - 68.110996461731, 68.099746813322, 68.088497164913, 68.077247516503, 68.065997868094, - 68.054748219685, 68.043498571276, 68.032248922867, 68.020999274458, 68.009749626048, - 67.998499977639, 67.987250329230, 67.976000680820, 67.964751032411, 67.953501384001, - 67.942251735592, 67.931002087182, 67.919752438773, 67.908502790363, 67.897253141953, - 67.886003493544, 67.874753845134, 67.863504196724, 67.852254548314, 67.841004899904, - 67.829755251494, 67.818505603085, 67.807255954675, 67.796006306265, 67.784756657854, - 67.773507009444, 67.762257361034, 67.751007712624, 67.739758064214, 67.728508415804, - 67.717258767393, 67.706009118983, 67.694759470573, 67.683509822162, 67.672260173752, - 67.661010525342, 67.649760876931, 67.638511228521, 67.627261580110, 67.616011931699, - 67.604762283289, 67.593512634878, 67.582262986467, 67.571013338057, 67.559763689646, - 67.548514041235, 67.537264392824, 67.526014744413, 67.514765096002, 67.503515447592, - 67.492265799181, 67.481016150770, 67.469766502358, 67.458516853947, 67.447267205536, - 67.436017557125, 67.424767908714, 67.413518260303, 67.402268611891, 67.391018963480, - 67.379769315069, 67.368519666657, 67.357270018246, 67.346020369834, 67.334770721423, - 67.323521073012, 67.312271424600, 67.301021776188, 67.289772127777, 67.278522479365, - 67.267272830953, 67.256023182542, 67.244773534130, 67.233523885718, 67.222274237306, - 67.211024588894, 67.199774940483, 67.188525292071, 67.177275643659, 67.166025995247, - 67.154776346835, 67.143526698423, 67.132277050010, 67.121027401598, 67.109777753186, - 67.098528104774, 67.087278456362, 67.076028807950, 67.064779159537, 67.053529511125, - 67.042279862713, 67.031030214300, 67.019780565888, 67.008530917475, 66.997281269063, - 66.986031620650, 66.974781972238, 66.963532323825, 66.952282675412, 66.941033027000, - 66.929783378587, 66.918533730174, 66.907284081762, 66.896034433349, 66.884784784936, - 66.873535136523, 66.862285488110, 66.851035839697, 66.839786191284, 66.828536542871, - 66.817286894458, 66.806037246045, 66.794787597632, 66.783537949219, 66.772288300806, - 66.761038652393, 66.749789003979, 66.738539355566, 66.727289707153, 66.716040058740, - 66.704790410326, 66.693540761913, 66.682291113499, 66.671041465086, 66.659791816672, - 66.648542168259, 66.637292519845, 66.626042871432, 66.614793223018, 66.603543574605, - 66.592293926191, 66.581044277777, 66.569794629363, 66.558544980950, 66.547295332536, - 66.536045684122, 66.524796035708, 66.513546387294, 66.502296738880, 66.491047090466, - 66.479797442053, 66.468547793638, 66.457298145224, 66.446048496810, 66.434798848396, - 66.423549199982, 66.412299551568, 66.401049903154, 66.389800254740, 66.378550606325, - 66.367300957911, 66.356051309497, 66.344801661082, 66.333552012668, 66.322302364254, - 66.311052715839, 66.299803067425, 66.288553419010, 66.277303770596, 66.266054122181, - 66.254804473766, 66.243554825352, 66.232305176937, 66.221055528522, 66.209805880108, - 66.198556231693, 66.187306583278, 66.176056934863, 66.164807286449, 66.153557638034, - 66.142307989619, 66.131058341204, 66.119808692789, 66.108559044374, 66.097309395959, - 66.086059747544, 66.074810099129, 66.063560450714, 66.052310802299, 66.041061153883, - 66.029811505468, 66.018561857053, 66.007312208638, 65.996062560222, 65.984812911807, - 65.973563263392, 65.962313614976, 65.951063966561, 65.939814318146, 65.928564669730, - 65.917315021315, 65.906065372899, 65.894815724484, 65.883566076068, 65.872316427652, - 65.861066779237, 65.849817130821, 65.838567482405, 65.827317833990, 65.816068185574, - 65.804818537158, 65.793568888742, 65.782319240327, 65.771069591911, 65.759819943495, - 65.748570295079, 65.737320646663, 65.726070998247, 65.714821349831, 65.703571701415, - 65.692322052999, 65.681072404583, 65.669822756167, 65.658573107751, 65.647323459334, - 65.636073810918, 65.624824162502, 65.613574514086, 65.602324865669, 65.591075217253, - 65.579825568837, 65.568575920420, 65.557326272004, 65.546076623588, 65.534826975171, - 65.523577326755, 65.512327678338, 65.501078029922, 65.489828381505, 65.478578733089, - 65.467329084672, 65.456079436255, 65.444829787839, 65.433580139422, 65.422330491005, - 65.411080842588, 65.399831194172, 65.388581545755, 65.377331897338, 65.366082248921, - 65.354832600504, 65.343582952087, 65.332333303670, 65.321083655253, 65.309834006837, - 65.298584358419, 65.287334710002, 65.276085061585, 65.264835413168, 65.253585764751, - 65.242336116334, 65.231086467917, 65.219836819500, 65.208587171082, 65.197337522665, - 65.186087874248, 65.174838225830, 65.163588577413, 65.152338928996, 65.141089280578, - 65.129839632161, 65.118589983744, 65.107340335326, 65.096090686909, 65.084841038491, - 65.073591390073, 65.062341741656, 65.051092093238, 65.039842444821, 65.028592796403, - 65.017343147985, 65.006093499568, 64.994843851150, 64.983594202732, 64.972344554314, - 64.961094905897, 64.949845257479, 64.938595609061, 64.927345960643, 64.916096312225, - 64.904846663807, 64.893597015389, 64.882347366971, 64.871097718553, 64.859848070135, - 64.848598421717, 64.837348773299, 64.826099124881, 64.814849476463, 64.803599828045, - 64.792350179626, 64.781100531208, 64.769850882790, 64.758601234372, 64.747351585953, - 64.736101937535, 64.724852289117, 64.713602640698, 64.702352992280, 64.691103343861, - 64.679853695443, 64.668604047025, 64.657354398606, 64.646104750188, 64.634855101769, - 64.623605453350, 64.612355804932, 64.601106156513, 64.589856508095, 64.578606859676, - 64.567357211257, 64.556107562839, 64.544857914420, 64.533608266001, 64.522358617582, - 64.511108969163, 64.499859320745, 64.488609672326, 64.477360023907, 64.466110375488, - 64.454860727069, 64.443611078650, 64.432361430231, 64.421111781812, 64.409862133393, - 64.398612484974, 64.387362836555, 64.376113188136, 64.364863539717, 64.353613891297, - 64.342364242878, 64.331114594459, 64.319864946040, 64.308615297621, 64.297365649201, - 64.286116000782, 64.274866352363, 64.263616703943, 64.252367055524, 64.241117407105, - 64.229867758685, 64.218618110266, 64.207368461846, 64.196118813427, 64.184869165007, - 64.173619516588, 64.162369868168, 64.151120219749, 64.139870571329, 64.128620922909, - 64.117371274490, 64.106121626070, 64.094871977650, 64.083622329231, 64.072372680811, - 64.061123032391, 64.049873383971, 64.038623735552, 64.027374087132, 64.016124438712, - 64.004874790292, 63.993625141872, 63.982375493452, 63.971125845032, 63.959876196612, - 63.948626548192, 63.937376899772, 63.926127251352, 63.914877602932, 63.903627954512, - 63.892378306092, 63.881128657672, 63.869879009252, 63.858629360831, 63.847379712411, - 63.836130063991, 63.824880415571, 63.813630767150, 63.802381118730, 63.791131470310, - 63.779881821890, 63.768632173469, 63.757382525049, 63.746132876628, 63.734883228208, - 63.723633579788, 63.712383931367, 63.701134282947, 63.689884634526, 63.678634986106, - 63.667385337685, 63.656135689264, 63.644886040844, 63.633636392423, 63.622386744002, - 63.611137095582, 63.599887447161, 63.588637798740, 63.577388150320, 63.566138501899, - 63.554888853478, 63.543639205057, 63.532389556636, 63.521139908216, 63.509890259795, - 63.498640611374, 63.487390962953, 63.476141314532, 63.464891666111, 63.453642017690, - 63.442392369269, 63.431142720848, 63.419893072427, 63.408643424006, 63.397393775585, - 63.386144127164, 63.374894478743, 63.363644830322, 63.352395181900, 63.341145533479, - 63.329895885058, 63.318646236637, 63.307396588215, 63.296146939794, 63.284897291373, - 63.273647642952, 63.262397994530, 63.251148346109, 63.239898697688, 63.228649049266, - 63.217399400845, 63.206149752423, 63.194900104002, 63.183650455580, 63.172400807159, - 63.161151158737, 63.149901510316, 63.138651861894, 63.127402213473, 63.116152565051, - 63.104902916629, 63.093653268208, 63.082403619786, 63.071153971364, 63.059904322943, - 63.048654674521, 63.037405026099, 63.026155377677, 63.014905729255, 63.003656080834, - 62.992406432412, 62.981156783990, 62.969907135568, 62.958657487146, 62.947407838724, - 62.936158190302, 62.924908541880, 62.913658893458, 62.902409245036, 62.891159596614, - 62.879909948192, 62.868660299770, 62.857410651348, 62.846161002926, 62.834911354504, - 62.823661706082, 62.812412057660, 62.801162409237, 62.789912760815, 62.778663112393, - 62.767413463971, 62.756163815548, 62.744914167126, 62.733664518704, 62.722414870282, - 62.711165221859, 62.699915573437, 62.688665925014, 62.677416276592, 62.666166628170, - 62.654916979747, 62.643667331325, 62.632417682902, 62.621168034480, 62.609918386057, - 62.598668737635, 62.587419089212, 62.576169440790, 62.564919792367, 62.553670143944, - 62.542420495522, 62.531170847099, 62.519921198676, 62.508671550254, 62.497421901831, - 62.486172253408, 62.474922604985, 62.463672956563, 62.452423308140, 62.441173659717, - 62.429924011294, 62.418674362871, 62.407424714448, 62.396175066026, 62.384925417603, - 62.373675769180, 62.362426120757, 62.351176472334, 62.339926823911, 62.328677175488, - 62.317427527065, 62.306177878642, 62.294928230219, 62.283678581796, 62.272428933372, - 62.261179284949, 62.249929636526, 62.238679988103, 62.227430339680, 62.216180691257, - 62.204931042833, 62.193681394410, 62.182431745987, 62.171182097564, 62.159932449140, - 62.148682800717, 62.137433152294, 62.126183503870, 62.114933855447, 62.103684207024, - 62.092434558600, 62.081184910177, 62.069935261753, 62.058685613330, 62.047435964906, - 62.036186316483, 62.024936668059, 62.013687019636, 62.002437371212, 61.991187722789, - 61.979938074365, 61.968688425942, 61.957438777518, 61.946189129094, 61.934939480671, - 61.923689832247, 61.912440183823, 61.901190535400, 61.889940886976, 61.878691238552, - 61.867441590128, 61.856191941705, 61.844942293281, 61.833692644857, 61.822442996433, - 61.811193348009, 61.799943699585, 61.788694051161, 61.777444402737, 61.766194754314, - 61.754945105890, 61.743695457466, 61.732445809042, 61.721196160618, 61.709946512194, - 61.698696863770, 61.687447215346, 61.676197566921, 61.664947918497, 61.653698270073, - 61.642448621649, 61.631198973225, 61.619949324801, 61.608699676377, 61.597450027952, - 61.586200379528, 61.574950731104, 61.563701082680, 61.552451434255, 61.541201785831, - 61.529952137407, 61.518702488982, 61.507452840558, 61.496203192134, 61.484953543709, - 61.473703895285, 61.462454246861, 61.451204598436, 61.439954950012, 61.428705301587, - 61.417455653163, 61.406206004738, 61.394956356314, 61.383706707889, 61.372457059465, - 61.361207411040, 61.349957762616, 61.338708114191, 61.327458465766, 61.316208817342, - 61.304959168917, 61.293709520492, 61.282459872068, 61.271210223643, 61.259960575218, - 61.248710926794, 61.237461278369, 61.226211629944, 61.214961981519, 61.203712333094, - 61.192462684670, 61.181213036245, 61.169963387820, 61.158713739395, 61.147464090970, - 61.136214442545, 61.124964794120, 61.113715145695, 61.102465497270, 61.091215848845, - 61.079966200420, 61.068716551995, 61.057466903570, 61.046217255145, 61.034967606720, - 61.023717958295, 61.012468309870, 61.001218661445, 60.989969013020, 60.978719364595, - 60.967469716170, 60.956220067744, 60.944970419319, 60.933720770894, 60.922471122469, - 60.911221474044, 60.899971825618, 60.888722177193, 60.877472528768, 60.866222880342, - 60.854973231917, 60.843723583492, 60.832473935066, 60.821224286641, 60.809974638216, - 60.798724989790, 60.787475341365, 60.776225692939, 60.764976044514, 60.753726396089, - 60.742476747663, 60.731227099238, 60.719977450812, 60.708727802386, 60.697478153961, - 60.686228505535, 60.674978857110, 60.663729208684, 60.652479560259, 60.641229911833, - 60.629980263407, 60.618730614982, 60.607480966556, 60.596231318130, 60.584981669705, - 60.573732021279, 60.562482372853, 60.551232724427, 60.539983076002, 60.528733427576, - 60.517483779150, 60.506234130724, 60.494984482298, 60.483734833873, 60.472485185447, - 60.461235537021, 60.449985888595, 60.438736240169, 60.427486591743, 60.416236943317, - 60.404987294891, 60.393737646465, 60.382487998039, 60.371238349613, 60.359988701187, - 60.348739052761, 60.337489404335, 60.326239755909, 60.314990107483, 60.303740459057, - 60.292490810631, 60.281241162205, 60.269991513778, 60.258741865352, 60.247492216926, - 60.236242568500, 60.224992920074, 60.213743271647, 60.202493623221, 60.191243974795, - 60.179994326369, 60.168744677942, 60.157495029516, 60.146245381090, 60.134995732663, - 60.123746084237, 60.112496435811, 60.101246787384, 60.089997138958, 60.078747490532, - 60.067497842105, 60.056248193679, 60.044998545252, 60.033748896826, 60.022499248399, - 60.011249599973, 59.999999951546, 59.988750303120, 59.977500654693, 59.966251006267, - 59.955001357840, 59.943751709414, 59.932502060987, 59.921252412560, 59.910002764134, - 59.898753115707, 59.887503467280, 59.876253818854, 59.865004170427, 59.853754522000, - 59.842504873574, 59.831255225147, 59.820005576720, 59.808755928293, 59.797506279867, - 59.786256631440, 59.775006983013, 59.763757334586, 59.752507686159, 59.741258037733, - 59.730008389306, 59.718758740879, 59.707509092452, 59.696259444025, 59.685009795598, - 59.673760147171, 59.662510498744, 59.651260850317, 59.640011201890, 59.628761553463, - 59.617511905036, 59.606262256609, 59.595012608182, 59.583762959755, 59.572513311328, - 59.561263662901, 59.550014014474, 59.538764366047, 59.527514717620, 59.516265069193, - 59.505015420765, 59.493765772338, 59.482516123911, 59.471266475484, 59.460016827057, - 59.448767178630, 59.437517530202, 59.426267881775, 59.415018233348, 59.403768584920, - 59.392518936493, 59.381269288066, 59.370019639639, 59.358769991211, 59.347520342784, - 59.336270694357, 59.325021045929, 59.313771397502, 59.302521749074, 59.291272100647, - 59.280022452220, 59.268772803792, 59.257523155365, 59.246273506937, 59.235023858510, - 59.223774210082, 59.212524561655, 59.201274913227, 59.190025264800, 59.178775616372, - 59.167525967944, 59.156276319517, 59.145026671089, 59.133777022662, 59.122527374234, - 59.111277725806, 59.100028077379, 59.088778428951, 59.077528780523, 59.066279132096, - 59.055029483668, 59.043779835240, 59.032530186813, 59.021280538385, 59.010030889957, - 58.998781241529, 58.987531593101, 58.976281944674, 58.965032296246, 58.953782647818, - 58.942532999390, 58.931283350962, 58.920033702534, 58.908784054107, 58.897534405679, - 58.886284757251, 58.875035108823, 58.863785460395, 58.852535811967, 58.841286163539, - 58.830036515111, 58.818786866683, 58.807537218255, 58.796287569827, 58.785037921399, - 58.773788272971, 58.762538624543, 58.751288976115, 58.740039327687, 58.728789679259, - 58.717540030831, 58.706290382402, 58.695040733974, 58.683791085546, 58.672541437118, - 58.661291788690, 58.650042140262, 58.638792491833, 58.627542843405, 58.616293194977, - 58.605043546549, 58.593793898120, 58.582544249692, 58.571294601264, 58.560044952836, - 58.548795304407, 58.537545655979, 58.526296007551, 58.515046359122, 58.503796710694, - 58.492547062266, 58.481297413837, 58.470047765409, 58.458798116980, 58.447548468552, - 58.436298820124, 58.425049171695, 58.413799523267, 58.402549874838, 58.391300226410, - 58.380050577981, 58.368800929553, 58.357551281124, 58.346301632696, 58.335051984267, - 58.323802335839, 58.312552687410, 58.301303038981, 58.290053390553, 58.278803742124, - 58.267554093696, 58.256304445267, 58.245054796838, 58.233805148410, 58.222555499981, - 58.211305851552, 58.200056203124, 58.188806554695, 58.177556906266, 58.166307257837, - 58.155057609409, 58.143807960980, 58.132558312551, 58.121308664122, 58.110059015694, - 58.098809367265, 58.087559718836, 58.076310070407, 58.065060421978, 58.053810773549, - 58.042561125120, 58.031311476692, 58.020061828263, 58.008812179834, 57.997562531405, - 57.986312882976, 57.975063234547, 57.963813586118, 57.952563937689, 57.941314289260, - 57.930064640831, 57.918814992402, 57.907565343973, 57.896315695544, 57.885066047115, - 57.873816398686, 57.862566750257, 57.851317101828, 57.840067453399, 57.828817804970, - 57.817568156540, 57.806318508111, 57.795068859682, 57.783819211253, 57.772569562824, - 57.761319914395, 57.750070265965, 57.738820617536, 57.727570969107, 57.716321320678, - 57.705071672249, 57.693822023819, 57.682572375390, 57.671322726961, 57.660073078532, - 57.648823430102, 57.637573781673, 57.626324133244, 57.615074484814, 57.603824836385, - 57.592575187956, 57.581325539526, 57.570075891097, 57.558826242667, 57.547576594238, - 57.536326945809, 57.525077297379, 57.513827648950, 57.502578000520, 57.491328352091, - 57.480078703661, 57.468829055232, 57.457579406802, 57.446329758373, 57.435080109943, - 57.423830461514, 57.412580813084, 57.401331164655, 57.390081516225, 57.378831867796, - 57.367582219366, 57.356332570936, 57.345082922507, 57.333833274077, 57.322583625647, - 57.311333977218, 57.300084328788, 57.288834680358, 57.277585031929, 57.266335383499, - 57.255085735069, 57.243836086640, 57.232586438210, 57.221336789780, 57.210087141350, - 57.198837492921, 57.187587844491, 57.176338196061, 57.165088547631, 57.153838899202, - 57.142589250772, 57.131339602342, 57.120089953912, 57.108840305482, 57.097590657052, - 57.086341008622, 57.075091360193, 57.063841711763, 57.052592063333, 57.041342414903, - 57.030092766473, 57.018843118043, 57.007593469613, 56.996343821183, 56.985094172753, - 56.973844524323, 56.962594875893, 56.951345227463, 56.940095579033, 56.928845930603, - 56.917596282173, 56.906346633743, 56.895096985313, 56.883847336883, 56.872597688453, - 56.861348040023, 56.850098391592, 56.838848743162, 56.827599094732, 56.816349446302, - 56.805099797872, 56.793850149442, 56.782600501011, 56.771350852581, 56.760101204151, - 56.748851555721, 56.737601907291, 56.726352258860, 56.715102610430, 56.703852962000, - 56.692603313570, 56.681353665139, 56.670104016709, 56.658854368279, 56.647604719849, - 56.636355071418, 56.625105422988, 56.613855774558, 56.602606126127, 56.591356477697, - 56.580106829266, 56.568857180836, 56.557607532406, 56.546357883975, 56.535108235545, - 56.523858587114, 56.512608938684, 56.501359290254, 56.490109641823, 56.478859993393, - 56.467610344962, 56.456360696532, 56.445111048101, 56.433861399671, 56.422611751240, - 56.411362102810, 56.400112454379, 56.388862805948, 56.377613157518, 56.366363509087, - 56.355113860657, 56.343864212226, 56.332614563796, 56.321364915365, 56.310115266934, - 56.298865618504, 56.287615970073, 56.276366321642, 56.265116673212, 56.253867024781, - 56.242617376350, 56.231367727920, 56.220118079489, 56.208868431058, 56.197618782627, - 56.186369134197, 56.175119485766, 56.163869837335, 56.152620188904, 56.141370540474, - 56.130120892043, 56.118871243612, 56.107621595181, 56.096371946750, 56.085122298319, - 56.073872649889, 56.062623001458, 56.051373353027, 56.040123704596, 56.028874056165, - 56.017624407734, 56.006374759303, 55.995125110872, 55.983875462441, 55.972625814011, - 55.961376165580, 55.950126517149, 55.938876868718, 55.927627220287, 55.916377571856, - 55.905127923425, 55.893878274994, 55.882628626563, 55.871378978132, 55.860129329701, - 55.848879681270, 55.837630032838, 55.826380384407, 55.815130735976, 55.803881087545, - 55.792631439114, 55.781381790683, 55.770132142252, 55.758882493821, 55.747632845390, - 55.736383196958, 55.725133548527, 55.713883900096, 55.702634251665, 55.691384603234, - 55.680134954803, 55.668885306371, 55.657635657940, 55.646386009509, 55.635136361078, - 55.623886712646, 55.612637064215, 55.601387415784, 55.590137767353, 55.578888118921, - 55.567638470490, 55.556388822059, 55.545139173627, 55.533889525196, 55.522639876765, - 55.511390228333, 55.500140579902, 55.488890931471, 55.477641283039, 55.466391634608, - 55.455141986176, 55.443892337745, 55.432642689314, 55.421393040882, 55.410143392451, - 55.398893744019, 55.387644095588, 55.376394447156, 55.365144798725, 55.353895150293, - 55.342645501862, 55.331395853430, 55.320146204999, 55.308896556567, 55.297646908136, - 55.286397259704, 55.275147611273, 55.263897962841, 55.252648314410, 55.241398665978, - 55.230149017546, 55.218899369115, 55.207649720683, 55.196400072252, 55.185150423820, - 55.173900775388, 55.162651126957, 55.151401478525, 55.140151830093, 55.128902181662, - 55.117652533230, 55.106402884798, 55.095153236367, 55.083903587935, 55.072653939503, - 55.061404291071, 55.050154642640, 55.038904994208, 55.027655345776, 55.016405697344, - 55.005156048913, 54.993906400481, 54.982656752049, 54.971407103617, 54.960157455185, - 54.948907806754, 54.937658158322, 54.926408509890, 54.915158861458, 54.903909213026, - 54.892659564594, 54.881409916162, 54.870160267730, 54.858910619299, 54.847660970867, - 54.836411322435, 54.825161674003, 54.813912025571, 54.802662377139, 54.791412728707, - 54.780163080275, 54.768913431843, 54.757663783411, 54.746414134979, 54.735164486547, - 54.723914838115, 54.712665189683, 54.701415541251, 54.690165892819, 54.678916244387, - 54.667666595955, 54.656416947523, 54.645167299091, 54.633917650659, 54.622668002226, - 54.611418353794, 54.600168705362, 54.588919056930, 54.577669408498, 54.566419760066, - 54.555170111634, 54.543920463202, 54.532670814769, 54.521421166337, 54.510171517905, - 54.498921869473, 54.487672221041, 54.476422572608, 54.465172924176, 54.453923275744, - 54.442673627312, 54.431423978879, 54.420174330447, 54.408924682015, 54.397675033583, - 54.386425385150, 54.375175736718, 54.363926088286, 54.352676439853, 54.341426791421, - 54.330177142989, 54.318927494557, 54.307677846124, 54.296428197692, 54.285178549259, - 54.273928900827, 54.262679252395, 54.251429603962, 54.240179955530, 54.228930307097, - 54.217680658665, 54.206431010233, 54.195181361800, 54.183931713368, 54.172682064935, - 54.161432416503, 54.150182768070, 54.138933119638, 54.127683471205, 54.116433822773, - 54.105184174340, 54.093934525908, 54.082684877475, 54.071435229043, 54.060185580610, - 54.048935932178, 54.037686283745, 54.026436635313, 54.015186986880, 54.003937338448, - 53.992687690015, 53.981438041582, 53.970188393150, 53.958938744717, 53.947689096284, - 53.936439447852, 53.925189799419, 53.913940150987, 53.902690502554, 53.891440854121, - 53.880191205689, 53.868941557256, 53.857691908823, 53.846442260391, 53.835192611958, - 53.823942963525, 53.812693315092, 53.801443666660, 53.790194018227, 53.778944369794, - 53.767694721361, 53.756445072929, 53.745195424496, 53.733945776063, 53.722696127630, - 53.711446479197, 53.700196830765, 53.688947182332, 53.677697533899, 53.666447885466, - 53.655198237033, 53.643948588600, 53.632698940168, 53.621449291735, 53.610199643302, - 53.598949994869, 53.587700346436, 53.576450698003, 53.565201049570, 53.553951401137, - 53.542701752704, 53.531452104271, 53.520202455839, 53.508952807406, 53.497703158973, - 53.486453510540, 53.475203862107, 53.463954213674, 53.452704565241, 53.441454916808, - 53.430205268375, 53.418955619942, 53.407705971509, 53.396456323076, 53.385206674643, - 53.373957026210, 53.362707377776, 53.351457729343, 53.340208080910, 53.328958432477, - 53.317708784044, 53.306459135611, 53.295209487178, 53.283959838745, 53.272710190312, - 53.261460541879, 53.250210893445, 53.238961245012, 53.227711596579, 53.216461948146, - 53.205212299713, 53.193962651280, 53.182713002846, 53.171463354413, 53.160213705980, - 53.148964057547, 53.137714409114, 53.126464760680, 53.115215112247, 53.103965463814, - 53.092715815381, 53.081466166947, 53.070216518514, 53.058966870081, 53.047717221648, - 53.036467573214, 53.025217924781, 53.013968276348, 53.002718627914, 52.991468979481, - 52.980219331048, 52.968969682614, 52.957720034181, 52.946470385748, 52.935220737314, - 52.923971088881, 52.912721440448, 52.901471792014, 52.890222143581, 52.878972495147, - 52.867722846714, 52.856473198281, 52.845223549847, 52.833973901414, 52.822724252980, - 52.811474604547, 52.800224956113, 52.788975307680, 52.777725659246, 52.766476010813, - 52.755226362379, 52.743976713946, 52.732727065512, 52.721477417079, 52.710227768645, - 52.698978120212, 52.687728471778, 52.676478823345, 52.665229174911, 52.653979526478, - 52.642729878044, 52.631480229611, 52.620230581177, 52.608980932743, 52.597731284310, - 52.586481635876, 52.575231987443, 52.563982339009, 52.552732690575, 52.541483042142, - 52.530233393708, 52.518983745274, 52.507734096841, 52.496484448407, 52.485234799973, - 52.473985151540, 52.462735503106, 52.451485854672, 52.440236206239, 52.428986557805, - 52.417736909371, 52.406487260938, 52.395237612504, 52.383987964070, 52.372738315636, - 52.361488667203, 52.350239018769, 52.338989370335, 52.327739721901, 52.316490073467, - 52.305240425034, 52.293990776600, 52.282741128166, 52.271491479732, 52.260241831298, - 52.248992182865, 52.237742534431, 52.226492885997, 52.215243237563, 52.203993589129, - 52.192743940695, 52.181494292262, 52.170244643828, 52.158994995394, 52.147745346960, - 52.136495698526, 52.125246050092, 52.113996401658, 52.102746753224, 52.091497104790, - 52.080247456356, 52.068997807922, 52.057748159488, 52.046498511054, 52.035248862620, - 52.023999214187, 52.012749565753, 52.001499917319, 51.990250268885, 51.979000620451, - 51.967750972017, 51.956501323583, 51.945251675148, 51.934002026714, 51.922752378280, - 51.911502729846, 51.900253081412, 51.889003432978, 51.877753784544, 51.866504136110, - 51.855254487676, 51.844004839242, 51.832755190808, 51.821505542374, 51.810255893940, - 51.799006245505, 51.787756597071, 51.776506948637, 51.765257300203, 51.754007651769, - 51.742758003335, 51.731508354901, 51.720258706466, 51.709009058032, 51.697759409598, - 51.686509761164, 51.675260112730, 51.664010464295, 51.652760815861, 51.641511167427, - 51.630261518993, 51.619011870559, 51.607762222124, 51.596512573690, 51.585262925256, - 51.574013276822, 51.562763628387, 51.551513979953, 51.540264331519, 51.529014683084, - 51.517765034650, 51.506515386216, 51.495265737782, 51.484016089347, 51.472766440913, - 51.461516792479, 51.450267144044, 51.439017495610, 51.427767847176, 51.416518198741, - 51.405268550307, 51.394018901872, 51.382769253438, 51.371519605004, 51.360269956569, - 51.349020308135, 51.337770659700, 51.326521011266, 51.315271362832, 51.304021714397, - 51.292772065963, 51.281522417528, 51.270272769094, 51.259023120659, 51.247773472225, - 51.236523823790, 51.225274175356, 51.214024526921, 51.202774878487, 51.191525230052, - 51.180275581618, 51.169025933183, 51.157776284749, 51.146526636314, 51.135276987880, - 51.124027339445, 51.112777691011, 51.101528042576, 51.090278394142, 51.079028745707, - 51.067779097273, 51.056529448838, 51.045279800403, 51.034030151969, 51.022780503534, - 51.011530855100, 51.000281206665, 50.989031558230, 50.977781909796, 50.966532261361, - 50.955282612926, 50.944032964492, 50.932783316057, 50.921533667622, 50.910284019188, - 50.899034370753, 50.887784722318, 50.876535073884, 50.865285425449, 50.854035777014, - 50.842786128580, 50.831536480145, 50.820286831710, 50.809037183276, 50.797787534841, - 50.786537886406, 50.775288237971, 50.764038589537, 50.752788941102, 50.741539292667, - 50.730289644232, 50.719039995797, 50.707790347363, 50.696540698928, 50.685291050493, - 50.674041402058, 50.662791753623, 50.651542105189, 50.640292456754, 50.629042808319, - 50.617793159884, 50.606543511449, 50.595293863014, 50.584044214580, 50.572794566145, - 50.561544917710, 50.550295269275, 50.539045620840, 50.527795972405, 50.516546323970, - 50.505296675535, 50.494047027100, 50.482797378666, 50.471547730231, 50.460298081796, - 50.449048433361, 50.437798784926, 50.426549136491, 50.415299488056, 50.404049839621, - 50.392800191186, 50.381550542751, 50.370300894316, 50.359051245881, 50.347801597446, - 50.336551949011, 50.325302300576, 50.314052652141, 50.302803003706, 50.291553355271, - 50.280303706836, 50.269054058401, 50.257804409966, 50.246554761531, 50.235305113096, - 50.224055464661, 50.212805816226, 50.201556167791, 50.190306519355, 50.179056870920, - 50.167807222485, 50.156557574050, 50.145307925615, 50.134058277180, 50.122808628745, - 50.111558980310, 50.100309331875, 50.089059683439, 50.077810035004, 50.066560386569, - 50.055310738134, 50.044061089699, 50.032811441264, 50.021561792828, 50.010312144393, - 49.999062495958, 49.987812847523, 49.976563199088, 49.965313550653, 49.954063902217, - 49.942814253782, 49.931564605347, 49.920314956912, 49.909065308476, 49.897815660041, - 49.886566011606, 49.875316363171, 49.864066714735, 49.852817066300, 49.841567417865, - 49.830317769430, 49.819068120994, 49.807818472559, 49.796568824124, 49.785319175688, - 49.774069527253, 49.762819878818, 49.751570230382, 49.740320581947, 49.729070933512, - 49.717821285076, 49.706571636641, 49.695321988206, 49.684072339770, 49.672822691335, - 49.661573042900, 49.650323394464, 49.639073746029, 49.627824097593, 49.616574449158, - 49.605324800723, 49.594075152287, 49.582825503852, 49.571575855416, 49.560326206981, - 49.549076558545, 49.537826910110, 49.526577261675, 49.515327613239, 49.504077964804, - 49.492828316368, 49.481578667933, 49.470329019497, 49.459079371062, 49.447829722626, - 49.436580074191, 49.425330425755, 49.414080777320, 49.402831128884, 49.391581480449, - 49.380331832013, 49.369082183578, 49.357832535142, 49.346582886707, 49.335333238271, - 49.324083589836, 49.312833941400, 49.301584292964, 49.290334644529, 49.279084996093, - 49.267835347658, 49.256585699222, 49.245336050787, 49.234086402351, 49.222836753915, - 49.211587105480, 49.200337457044, 49.189087808608, 49.177838160173, 49.166588511737, - 49.155338863302, 49.144089214866, 49.132839566430, 49.121589917995, 49.110340269559, - 49.099090621123, 49.087840972688, 49.076591324252, 49.065341675816, 49.054092027380, - 49.042842378945, 49.031592730509, 49.020343082073, 49.009093433638, 48.997843785202, - 48.986594136766, 48.975344488330, 48.964094839895, 48.952845191459, 48.941595543023, - 48.930345894587, 48.919096246152, 48.907846597716, 48.896596949280, 48.885347300844, - 48.874097652409, 48.862848003973, 48.851598355537, 48.840348707101, 48.829099058665, - 48.817849410230, 48.806599761794, 48.795350113358, 48.784100464922, 48.772850816486, - 48.761601168050, 48.750351519615, 48.739101871179, 48.727852222743, 48.716602574307, - 48.705352925871, 48.694103277435, 48.682853628999, 48.671603980563, 48.660354332128, - 48.649104683692, 48.637855035256, 48.626605386820, 48.615355738384, 48.604106089948, - 48.592856441512, 48.581606793076, 48.570357144640, 48.559107496204, 48.547857847768, - 48.536608199332, 48.525358550896, 48.514108902460, 48.502859254024, 48.491609605589, - 48.480359957153, 48.469110308717, 48.457860660281, 48.446611011845, 48.435361363409, - 48.424111714973, 48.412862066537, 48.401612418100, 48.390362769664, 48.379113121228, - 48.367863472792, 48.356613824356, 48.345364175920, 48.334114527484, 48.322864879048, - 48.311615230612, 48.300365582176, 48.289115933740, 48.277866285304, 48.266616636868, - 48.255366988432, 48.244117339996, 48.232867691560, 48.221618043123, 48.210368394687, - 48.199118746251, 48.187869097815, 48.176619449379, 48.165369800943, 48.154120152507, - 48.142870504070, 48.131620855634, 48.120371207198, 48.109121558762, 48.097871910326, - 48.086622261890, 48.075372613453, 48.064122965017, 48.052873316581, 48.041623668145, - 48.030374019709, 48.019124371273, 48.007874722836, 47.996625074400, 47.985375425964, - 47.974125777528, 47.962876129091, 47.951626480655, 47.940376832219, 47.929127183783, - 47.917877535346, 47.906627886910, 47.895378238474, 47.884128590038, 47.872878941601, - 47.861629293165, 47.850379644729, 47.839129996292, 47.827880347856, 47.816630699420, - 47.805381050984, 47.794131402547, 47.782881754111, 47.771632105675, 47.760382457238, - 47.749132808802, 47.737883160366, 47.726633511929, 47.715383863493, 47.704134215057, - 47.692884566620, 47.681634918184, 47.670385269747, 47.659135621311, 47.647885972875, - 47.636636324438, 47.625386676002, 47.614137027566, 47.602887379129, 47.591637730693, - 47.580388082256, 47.569138433820, 47.557888785383, 47.546639136947, 47.535389488511, - 47.524139840074, 47.512890191638, 47.501640543201, 47.490390894765, 47.479141246328, - 47.467891597892, 47.456641949455, 47.445392301019, 47.434142652582, 47.422893004146, - 47.411643355710, 47.400393707273, 47.389144058837, 47.377894410400, 47.366644761963, - 47.355395113527, 47.344145465090, 47.332895816654, 47.321646168217, 47.310396519781, - 47.299146871344, 47.287897222908, 47.276647574471, 47.265397926035, 47.254148277598, - 47.242898629162, 47.231648980725, 47.220399332288, 47.209149683852, 47.197900035415, - 47.186650386979, 47.175400738542, 47.164151090105, 47.152901441669, 47.141651793232, - 47.130402144796, 47.119152496359, 47.107902847922, 47.096653199486, 47.085403551049, - 47.074153902612, 47.062904254176, 47.051654605739, 47.040404957302, 47.029155308866, - 47.017905660429, 47.006656011993, 46.995406363556, 46.984156715119, 46.972907066682, - 46.961657418246, 46.950407769809, 46.939158121372, 46.927908472936, 46.916658824499, - 46.905409176062, 46.894159527626, 46.882909879189, 46.871660230752, 46.860410582315, - 46.849160933879, 46.837911285442, 46.826661637005, 46.815411988568, 46.804162340132, - 46.792912691695, 46.781663043258, 46.770413394821, 46.759163746384, 46.747914097948, - 46.736664449511, 46.725414801074, 46.714165152637, 46.702915504201, 46.691665855764, - 46.680416207327, 46.669166558890, 46.657916910453, 46.646667262016, 46.635417613580, - 46.624167965143, 46.612918316706, 46.601668668269, 46.590419019832, 46.579169371395, - 46.567919722958, 46.556670074522, 46.545420426085, 46.534170777648, 46.522921129211, - 46.511671480774, 46.500421832337, 46.489172183900, 46.477922535463, 46.466672887026, - 46.455423238590, 46.444173590153, 46.432923941716, 46.421674293279, 46.410424644842, - 46.399174996405, 46.387925347968, 46.376675699531, 46.365426051094, 46.354176402657, - 46.342926754220, 46.331677105783, 46.320427457346, 46.309177808909, 46.297928160472, - 46.286678512035, 46.275428863598, 46.264179215161, 46.252929566724, 46.241679918287, - 46.230430269850, 46.219180621413, 46.207930972976, 46.196681324539, 46.185431676102, - 46.174182027665, 46.162932379228, 46.151682730791, 46.140433082354, 46.129183433917, - 46.117933785480, 46.106684137043, 46.095434488606, 46.084184840169, 46.072935191732, - 46.061685543295, 46.050435894858, 46.039186246421, 46.027936597983, 46.016686949546, - 46.005437301109, 45.994187652672, 45.982938004235, 45.971688355798, 45.960438707361, - 45.949189058924, 45.937939410487, 45.926689762049, 45.915440113612, 45.904190465175, - 45.892940816738, 45.881691168301, 45.870441519864, 45.859191871427, 45.847942222989, - 45.836692574552, 45.825442926115, 45.814193277678, 45.802943629241, 45.791693980804, - 45.780444332366, 45.769194683929, 45.757945035492, 45.746695387055, 45.735445738618, - 45.724196090180, 45.712946441743, 45.701696793306, 45.690447144869, 45.679197496431, - 45.667947847994, 45.656698199557, 45.645448551120, 45.634198902682, 45.622949254245, - 45.611699605808, 45.600449957371, 45.589200308933, 45.577950660496, 45.566701012059, - 45.555451363622, 45.544201715184, 45.532952066747, 45.521702418310, 45.510452769872, - 45.499203121435, 45.487953472998, 45.476703824560, 45.465454176123, 45.454204527686, - 45.442954879249, 45.431705230811, 45.420455582374, 45.409205933936, 45.397956285499, - 45.386706637062, 45.375456988624, 45.364207340187, 45.352957691750, 45.341708043312, - 45.330458394875, 45.319208746438, 45.307959098000, 45.296709449563, 45.285459801125, - 45.274210152688, 45.262960504251, 45.251710855813, 45.240461207376, 45.229211558938, - 45.217961910501, 45.206712262064, 45.195462613626, 45.184212965189, 45.172963316751, - 45.161713668314, 45.150464019876, 45.139214371439, 45.127964723002, 45.116715074564, - 45.105465426127, 45.094215777689, 45.082966129252, 45.071716480814, 45.060466832377, - 45.049217183939, 45.037967535502, 45.026717887064, 45.015468238627, 45.004218590189, - 44.992968941752, 44.981719293314, 44.970469644877, 44.959219996439, 44.947970348002, - 44.936720699564, 44.925471051127, 44.914221402689, 44.902971754252, 44.891722105814, - 44.880472457377, 44.869222808939, 44.857973160502, 44.846723512064, 44.835473863626, - 44.824224215189, 44.812974566751, 44.801724918314, 44.790475269876, 44.779225621439, - 44.767975973001, 44.756726324563, 44.745476676126, 44.734227027688, 44.722977379251, - 44.711727730813, 44.700478082375, 44.689228433938, 44.677978785500, 44.666729137062, - 44.655479488625, 44.644229840187, 44.632980191750, 44.621730543312, 44.610480894874, - 44.599231246437, 44.587981597999, 44.576731949561, 44.565482301124, 44.554232652686, - 44.542983004248, 44.531733355811, 44.520483707373, 44.509234058935, 44.497984410498, - 44.486734762060, 44.475485113622, 44.464235465184, 44.452985816747, 44.441736168309, - 44.430486519871, 44.419236871434, 44.407987222996, 44.396737574558, 44.385487926120, - 44.374238277683, 44.362988629245, 44.351738980807, 44.340489332370, 44.329239683932, - 44.317990035494, 44.306740387056, 44.295490738618, 44.284241090181, 44.272991441743, - 44.261741793305, 44.250492144867, 44.239242496430, 44.227992847992, 44.216743199554, - 44.205493551116, 44.194243902678, 44.182994254241, 44.171744605803, 44.160494957365, - 44.149245308927, 44.137995660489, 44.126746012052, 44.115496363614, 44.104246715176, - 44.092997066738, 44.081747418300, 44.070497769862, 44.059248121425, 44.047998472987, - 44.036748824549, 44.025499176111, 44.014249527673, 44.002999879235, 43.991750230797, - 43.980500582359, 43.969250933922, 43.958001285484, 43.946751637046, 43.935501988608, - 43.924252340170, 43.913002691732, 43.901753043294, 43.890503394856, 43.879253746418, - 43.868004097981, 43.856754449543, 43.845504801105, 43.834255152667, 43.823005504229, - 43.811755855791, 43.800506207353, 43.789256558915, 43.778006910477, 43.766757262039, - 43.755507613601, 43.744257965163, 43.733008316725, 43.721758668287, 43.710509019849, - 43.699259371411, 43.688009722973, 43.676760074535, 43.665510426097, 43.654260777659, - 43.643011129221, 43.631761480783, 43.620511832345, 43.609262183907, 43.598012535469, - 43.586762887031, 43.575513238593, 43.564263590155, 43.553013941717, 43.541764293279, - 43.530514644841, 43.519264996403, 43.508015347965, 43.496765699527, 43.485516051089, - 43.474266402651, 43.463016754213, 43.451767105775, 43.440517457337, 43.429267808899, - 43.418018160461, 43.406768512023, 43.395518863584, 43.384269215146, 43.373019566708, - 43.361769918270, 43.350520269832, 43.339270621394, 43.328020972956, 43.316771324518, - 43.305521676080, 43.294272027642, 43.283022379203, 43.271772730765, 43.260523082327, - 43.249273433889, 43.238023785451, 43.226774137013, 43.215524488575, 43.204274840136, - 43.193025191698, 43.181775543260, 43.170525894822, 43.159276246384, 43.148026597946, - 43.136776949508, 43.125527301069, 43.114277652631, 43.103028004193, 43.091778355755, - 43.080528707317, 43.069279058878, 43.058029410440, 43.046779762002, 43.035530113564, - 43.024280465126, 43.013030816687, 43.001781168249, 42.990531519811, 42.979281871373, - 42.968032222935, 42.956782574496, 42.945532926058, 42.934283277620, 42.923033629182, - 42.911783980743, 42.900534332305, 42.889284683867, 42.878035035429, 42.866785386990, - 42.855535738552, 42.844286090114, 42.833036441676, 42.821786793237, 42.810537144799, - 42.799287496361, 42.788037847922, 42.776788199484, 42.765538551046, 42.754288902608, - 42.743039254169, 42.731789605731, 42.720539957293, 42.709290308854, 42.698040660416, - 42.686791011978, 42.675541363539, 42.664291715101, 42.653042066663, 42.641792418224, - 42.630542769786, 42.619293121348, 42.608043472909, 42.596793824471, 42.585544176033, - 42.574294527594, 42.563044879156, 42.551795230718, 42.540545582279, 42.529295933841, - 42.518046285402, 42.506796636964, 42.495546988526, 42.484297340087, 42.473047691649, - 42.461798043211, 42.450548394772, 42.439298746334, 42.428049097895, 42.416799449457, - 42.405549801019, 42.394300152580, 42.383050504142, 42.371800855703, 42.360551207265, - 42.349301558826, 42.338051910388, 42.326802261950, 42.315552613511, 42.304302965073, - 42.293053316634, 42.281803668196, 42.270554019757, 42.259304371319, 42.248054722880, - 42.236805074442, 42.225555426003, 42.214305777565, 42.203056129127, 42.191806480688, - 42.180556832250, 42.169307183811, 42.158057535373, 42.146807886934, 42.135558238496, - 42.124308590057, 42.113058941619, 42.101809293180, 42.090559644742, 42.079309996303, - 42.068060347865, 42.056810699426, 42.045561050988, 42.034311402549, 42.023061754110, - 42.011812105672, 42.000562457233, 41.989312808795, 41.978063160356, 41.966813511918, - 41.955563863479, 41.944314215041, 41.933064566602, 41.921814918164, 41.910565269725, - 41.899315621286, 41.888065972848, 41.876816324409, 41.865566675971, 41.854317027532, - 41.843067379093, 41.831817730655, 41.820568082216, 41.809318433778, 41.798068785339, - 41.786819136900, 41.775569488462, 41.764319840023, 41.753070191585, 41.741820543146, - 41.730570894707, 41.719321246269, 41.708071597830, 41.696821949392, 41.685572300953, - 41.674322652514, 41.663073004076, 41.651823355637, 41.640573707198, 41.629324058760, - 41.618074410321, 41.606824761882, 41.595575113444, 41.584325465005, 41.573075816566, - 41.561826168128, 41.550576519689, 41.539326871250, 41.528077222812, 41.516827574373, - 41.505577925934, 41.494328277496, 41.483078629057, 41.471828980618, 41.460579332179, - 41.449329683741, 41.438080035302, 41.426830386863, 41.415580738425, 41.404331089986, - 41.393081441547, 41.381831793108, 41.370582144670, 41.359332496231, 41.348082847792, - 41.336833199353, 41.325583550915, 41.314333902476, 41.303084254037, 41.291834605598, - 41.280584957160, 41.269335308721, 41.258085660282, 41.246836011843, 41.235586363405, - 41.224336714966, 41.213087066527, 41.201837418088, 41.190587769650, 41.179338121211, - 41.168088472772, 41.156838824333, 41.145589175894, 41.134339527456, 41.123089879017, - 41.111840230578, 41.100590582139, 41.089340933700, 41.078091285262, 41.066841636823, - 41.055591988384, 41.044342339945, 41.033092691506, 41.021843043067, 41.010593394629, - 40.999343746190, 40.988094097751, 40.976844449312, 40.965594800873, 40.954345152434, - 40.943095503995, 40.931845855557, 40.920596207118, 40.909346558679, 40.898096910240, - 40.886847261801, 40.875597613362, 40.864347964923, 40.853098316484, 40.841848668046, - 40.830599019607, 40.819349371168, 40.808099722729, 40.796850074290, 40.785600425851, - 40.774350777412, 40.763101128973, 40.751851480534, 40.740601832095, 40.729352183657, - 40.718102535218, 40.706852886779, 40.695603238340, 40.684353589901, 40.673103941462, - 40.661854293023, 40.650604644584, 40.639354996145, 40.628105347706, 40.616855699267, - 40.605606050828, 40.594356402389, 40.583106753950, 40.571857105511, 40.560607457072, - 40.549357808633, 40.538108160194, 40.526858511755, 40.515608863316, 40.504359214877, - 40.493109566438, 40.481859917999, 40.470610269560, 40.459360621121, 40.448110972682, - 40.436861324243, 40.425611675804, 40.414362027365, 40.403112378926, 40.391862730487, - 40.380613082048, 40.369363433609, 40.358113785170, 40.346864136731, 40.335614488292, - 40.324364839853, 40.313115191414, 40.301865542975, 40.290615894536, 40.279366246097, - 40.268116597658, 40.256866949219, 40.245617300780, 40.234367652341, 40.223118003902, - 40.211868355463, 40.200618707024, 40.189369058585, 40.178119410146, 40.166869761706, - 40.155620113267, 40.144370464828, 40.133120816389, 40.121871167950, 40.110621519511, - 40.099371871072, 40.088122222633, 40.076872574194, 40.065622925755, 40.054373277316, - 40.043123628876, 40.031873980437, 40.020624331998, 40.009374683559, 39.998125035120, - 39.986875386681, 39.975625738242, 39.964376089803, 39.953126441363, 39.941876792924, - 39.930627144485, 39.919377496046, 39.908127847607, 39.896878199168, 39.885628550728, - 39.874378902289, 39.863129253850, 39.851879605411, 39.840629956972, 39.829380308533, - 39.818130660093, 39.806881011654, 39.795631363215, 39.784381714776, 39.773132066337, - 39.761882417898, 39.750632769458, 39.739383121019, 39.728133472580, 39.716883824141, - 39.705634175702, 39.694384527262, 39.683134878823, 39.671885230384, 39.660635581945, - 39.649385933506, 39.638136285066, 39.626886636627, 39.615636988188, 39.604387339749, - 39.593137691309, 39.581888042870, 39.570638394431, 39.559388745992, 39.548139097552, - 39.536889449113, 39.525639800674, 39.514390152235, 39.503140503795, 39.491890855356, - 39.480641206917, 39.469391558478, 39.458141910038, 39.446892261599, 39.435642613160, - 39.424392964720, 39.413143316281, 39.401893667842, 39.390644019403, 39.379394370963, - 39.368144722524, 39.356895074085, 39.345645425645, 39.334395777206, 39.323146128767, - 39.311896480328, 39.300646831888, 39.289397183449, 39.278147535010, 39.266897886570, - 39.255648238131, 39.244398589692, 39.233148941252, 39.221899292813, 39.210649644374, - 39.199399995934, 39.188150347495, 39.176900699056, 39.165651050616, 39.154401402177, - 39.143151753738, 39.131902105298, 39.120652456859, 39.109402808419, 39.098153159980, - 39.086903511541, 39.075653863101, 39.064404214662, 39.053154566223, 39.041904917783, - 39.030655269344, 39.019405620904, 39.008155972465, 38.996906324026, 38.985656675586, - 38.974407027147, 38.963157378708, 38.951907730268, 38.940658081829, 38.929408433389, - 38.918158784950, 38.906909136510, 38.895659488071, 38.884409839632, 38.873160191192, - 38.861910542753, 38.850660894313, 38.839411245874, 38.828161597434, 38.816911948995, - 38.805662300556, 38.794412652116, 38.783163003677, 38.771913355237, 38.760663706798, - 38.749414058358, 38.738164409919, 38.726914761479, 38.715665113040, 38.704415464601, - 38.693165816161, 38.681916167722, 38.670666519282, 38.659416870843, 38.648167222403, - 38.636917573964, 38.625667925524, 38.614418277085, 38.603168628645, 38.591918980206, - 38.580669331766, 38.569419683327, 38.558170034887, 38.546920386448, 38.535670738008, - 38.524421089569, 38.513171441129, 38.501921792690, 38.490672144250, 38.479422495811, - 38.468172847371, 38.456923198932, 38.445673550492, 38.434423902053, 38.423174253613, - 38.411924605173, 38.400674956734, 38.389425308294, 38.378175659855, 38.366926011415, - 38.355676362976, 38.344426714536, 38.333177066097, 38.321927417657, 38.310677769217, - 38.299428120778, 38.288178472338, 38.276928823899, 38.265679175459, 38.254429527020, - 38.243179878580, 38.231930230140, 38.220680581701, 38.209430933261, 38.198181284822, - 38.186931636382, 38.175681987942, 38.164432339503, 38.153182691063, 38.141933042624, - 38.130683394184, 38.119433745744, 38.108184097305, 38.096934448865, 38.085684800426, - 38.074435151986, 38.063185503546, 38.051935855107, 38.040686206667, 38.029436558227, - 38.018186909788, 38.006937261348, 37.995687612909, 37.984437964469, 37.973188316029, - 37.961938667590, 37.950689019150, 37.939439370710, 37.928189722271, 37.916940073831, - 37.905690425391, 37.894440776952, 37.883191128512, 37.871941480072, 37.860691831633, - 37.849442183193, 37.838192534753, 37.826942886314, 37.815693237874, 37.804443589434, - 37.793193940995, 37.781944292555, 37.770694644115, 37.759444995676, 37.748195347236, - 37.736945698796, 37.725696050356, 37.714446401917, 37.703196753477, 37.691947105037, - 37.680697456598, 37.669447808158, 37.658198159718, 37.646948511278, 37.635698862839, - 37.624449214399, 37.613199565959, 37.601949917519, 37.590700269080, 37.579450620640, - 37.568200972200, 37.556951323761, 37.545701675321, 37.534452026881, 37.523202378441, - 37.511952730001, 37.500703081562, 37.489453433122, 37.478203784682, 37.466954136242, - 37.455704487803, 37.444454839363, 37.433205190923, 37.421955542483, 37.410705894044, - 37.399456245604, 37.388206597164, 37.376956948724, 37.365707300284, 37.354457651845, - 37.343208003405, 37.331958354965, 37.320708706525, 37.309459058085, 37.298209409646, - 37.286959761206, 37.275710112766, 37.264460464326, 37.253210815886, 37.241961167447, - 37.230711519007, 37.219461870567, 37.208212222127, 37.196962573687, 37.185712925247, - 37.174463276808, 37.163213628368, 37.151963979928, 37.140714331488, 37.129464683048, - 37.118215034608, 37.106965386169, 37.095715737729, 37.084466089289, 37.073216440849, - 37.061966792409, 37.050717143969, 37.039467495529, 37.028217847090, 37.016968198650, - 37.005718550210, 36.994468901770, 36.983219253330, 36.971969604890, 36.960719956450, - 36.949470308010, 36.938220659571, 36.926971011131, 36.915721362691, 36.904471714251, - 36.893222065811, 36.881972417371, 36.870722768931, 36.859473120491, 36.848223472051, - 36.836973823611, 36.825724175172, 36.814474526732, 36.803224878292, 36.791975229852, - 36.780725581412, 36.769475932972, 36.758226284532, 36.746976636092, 36.735726987652, - 36.724477339212, 36.713227690772, 36.701978042332, 36.690728393892, 36.679478745452, - 36.668229097012, 36.656979448573, 36.645729800133, 36.634480151693, 36.623230503253, - 36.611980854813, 36.600731206373, 36.589481557933, 36.578231909493, 36.566982261053, - 36.555732612613, 36.544482964173, 36.533233315733, 36.521983667293, 36.510734018853, - 36.499484370413, 36.488234721973, 36.476985073533, 36.465735425093, 36.454485776653, - 36.443236128213, 36.431986479773, 36.420736831333, 36.409487182893, 36.398237534453, - 36.386987886013, 36.375738237573, 36.364488589133, 36.353238940693, 36.341989292253, - 36.330739643813, 36.319489995373, 36.308240346933, 36.296990698493, 36.285741050053, - 36.274491401613, 36.263241753173, 36.251992104733, 36.240742456293, 36.229492807853, - 36.218243159413, 36.206993510973, 36.195743862532, 36.184494214092, 36.173244565652, - 36.161994917212, 36.150745268772, 36.139495620332, 36.128245971892, 36.116996323452, - 36.105746675012, 36.094497026572, 36.083247378132, 36.071997729692, 36.060748081252, - 36.049498432812, 36.038248784371, 36.026999135931, 36.015749487491, 36.004499839051, - 35.993250190611, 35.982000542171, 35.970750893731, 35.959501245291, 35.948251596851, - 35.937001948411, 35.925752299971, 35.914502651530, 35.903253003090, 35.892003354650, - 35.880753706210, 35.869504057770, 35.858254409330, 35.847004760890, 35.835755112450, - 35.824505464009, 35.813255815569, 35.802006167129, 35.790756518689, 35.779506870249, - 35.768257221809, 35.757007573369, 35.745757924928, 35.734508276488, 35.723258628048, - 35.712008979608, 35.700759331168, 35.689509682728, 35.678260034288, 35.667010385847, - 35.655760737407, 35.644511088967, 35.633261440527, 35.622011792087, 35.610762143647, - 35.599512495206, 35.588262846766, 35.577013198326, 35.565763549886, 35.554513901446, - 35.543264253005, 35.532014604565, 35.520764956125, 35.509515307685, 35.498265659245, - 35.487016010804, 35.475766362364, 35.464516713924, 35.453267065484, 35.442017417044, - 35.430767768603, 35.419518120163, 35.408268471723, 35.397018823283, 35.385769174843, - 35.374519526402, 35.363269877962, 35.352020229522, 35.340770581082, 35.329520932641, - 35.318271284201, 35.307021635761, 35.295771987321, 35.284522338880, 35.273272690440, - 35.262023042000, 35.250773393560, 35.239523745119, 35.228274096679, 35.217024448239, - 35.205774799799, 35.194525151358, 35.183275502918, 35.172025854478, 35.160776206038, - 35.149526557597, 35.138276909157, 35.127027260717, 35.115777612277, 35.104527963836, - 35.093278315396, 35.082028666956, 35.070779018515, 35.059529370075, 35.048279721635, - 35.037030073195, 35.025780424754, 35.014530776314, 35.003281127874, 34.992031479433, - 34.980781830993, 34.969532182553, 34.958282534112, 34.947032885672, 34.935783237232, - 34.924533588792, 34.913283940351, 34.902034291911, 34.890784643471, 34.879534995030, - 34.868285346590, 34.857035698150, 34.845786049709, 34.834536401269, 34.823286752829, - 34.812037104388, 34.800787455948, 34.789537807508, 34.778288159067, 34.767038510627, - 34.755788862187, 34.744539213746, 34.733289565306, 34.722039916865, 34.710790268425, - 34.699540619985, 34.688290971544, 34.677041323104, 34.665791674664, 34.654542026223, - 34.643292377783, 34.632042729343, 34.620793080902, 34.609543432462, 34.598293784021, - 34.587044135581, 34.575794487141, 34.564544838700, 34.553295190260, 34.542045541819, - 34.530795893379, 34.519546244939, 34.508296596498, 34.497046948058, 34.485797299618, - 34.474547651177, 34.463298002737, 34.452048354296, 34.440798705856, 34.429549057415, - 34.418299408975, 34.407049760535, 34.395800112094, 34.384550463654, 34.373300815213, - 34.362051166773, 34.350801518333, 34.339551869892, 34.328302221452, 34.317052573011, - 34.305802924571, 34.294553276130, 34.283303627690, 34.272053979249, 34.260804330809, - 34.249554682369, 34.238305033928, 34.227055385488, 34.215805737047, 34.204556088607, - 34.193306440166, 34.182056791726, 34.170807143285, 34.159557494845, 34.148307846404, - 34.137058197964, 34.125808549524, 34.114558901083, 34.103309252643, 34.092059604202, - 34.080809955762, 34.069560307321, 34.058310658881, 34.047061010440, 34.035811362000, - 34.024561713559, 34.013312065119, 34.002062416678, 33.990812768238, 33.979563119797, - 33.968313471357, 33.957063822916, 33.945814174476, 33.934564526035, 33.923314877595, - 33.912065229154, 33.900815580714, 33.889565932273, 33.878316283833, 33.867066635392, - 33.855816986952, 33.844567338511, 33.833317690071, 33.822068041630, 33.810818393190, - 33.799568744749, 33.788319096308, 33.777069447868, 33.765819799427, 33.754570150987, - 33.743320502546, 33.732070854106, 33.720821205665, 33.709571557225, 33.698321908784, - 33.687072260344, 33.675822611903, 33.664572963462, 33.653323315022, 33.642073666581, - 33.630824018141, 33.619574369700, 33.608324721260, 33.597075072819, 33.585825424379, - 33.574575775938, 33.563326127497, 33.552076479057, 33.540826830616, 33.529577182176, - 33.518327533735, 33.507077885294, 33.495828236854, 33.484578588413, 33.473328939973, - 33.462079291532, 33.450829643092, 33.439579994651, 33.428330346210, 33.417080697770, - 33.405831049329, 33.394581400889, 33.383331752448, 33.372082104007, 33.360832455567, - 33.349582807126, 33.338333158685, 33.327083510245, 33.315833861804, 33.304584213364, - 33.293334564923, 33.282084916482, 33.270835268042, 33.259585619601, 33.248335971160, - 33.237086322720, 33.225836674279, 33.214587025839, 33.203337377398, 33.192087728957, - 33.180838080517, 33.169588432076, 33.158338783635, 33.147089135195, 33.135839486754, - 33.124589838313, 33.113340189873, 33.102090541432, 33.090840892991, 33.079591244551, - 33.068341596110, 33.057091947669, 33.045842299229, 33.034592650788, 33.023343002347, - 33.012093353907, 33.000843705466, 32.989594057025, 32.978344408585, 32.967094760144, - 32.955845111703, 32.944595463263, 32.933345814822, 32.922096166381, 32.910846517941, - 32.899596869500, 32.888347221059, 32.877097572619, 32.865847924178, 32.854598275737, - 32.843348627296, 32.832098978856, 32.820849330415, 32.809599681974, 32.798350033534, - 32.787100385093, 32.775850736652, 32.764601088211, 32.753351439771, 32.742101791330, - 32.730852142889, 32.719602494449, 32.708352846008, 32.697103197567, 32.685853549126, - 32.674603900686, 32.663354252245, 32.652104603804, 32.640854955363, 32.629605306923, - 32.618355658482, 32.607106010041, 32.595856361600, 32.584606713160, 32.573357064719, - 32.562107416278, 32.550857767837, 32.539608119397, 32.528358470956, 32.517108822515, - 32.505859174074, 32.494609525634, 32.483359877193, 32.472110228752, 32.460860580311, - 32.449610931871, 32.438361283430, 32.427111634989, 32.415861986548, 32.404612338107, - 32.393362689667, 32.382113041226, 32.370863392785, 32.359613744344, 32.348364095904, - 32.337114447463, 32.325864799022, 32.314615150581, 32.303365502140, 32.292115853700, - 32.280866205259, 32.269616556818, 32.258366908377, 32.247117259936, 32.235867611496, - 32.224617963055, 32.213368314614, 32.202118666173, 32.190869017732, 32.179619369291, - 32.168369720851, 32.157120072410, 32.145870423969, 32.134620775528, 32.123371127087, - 32.112121478646, 32.100871830206, 32.089622181765, 32.078372533324, 32.067122884883, - 32.055873236442, 32.044623588001, 32.033373939561, 32.022124291120, 32.010874642679, - 31.999624994238, 31.988375345797, 31.977125697356, 31.965876048916, 31.954626400475, - 31.943376752034, 31.932127103593, 31.920877455152, 31.909627806711, 31.898378158270, - 31.887128509830, 31.875878861389, 31.864629212948, 31.853379564507, 31.842129916066, - 31.830880267625, 31.819630619184, 31.808380970743, 31.797131322303, 31.785881673862, - 31.774632025421, 31.763382376980, 31.752132728539, 31.740883080098, 31.729633431657, - 31.718383783216, 31.707134134775, 31.695884486335, 31.684634837894, 31.673385189453, - 31.662135541012, 31.650885892571, 31.639636244130, 31.628386595689, 31.617136947248, - 31.605887298807, 31.594637650366, 31.583388001925, 31.572138353485, 31.560888705044, - 31.549639056603, 31.538389408162, 31.527139759721, 31.515890111280, 31.504640462839, - 31.493390814398, 31.482141165957, 31.470891517516, 31.459641869075, 31.448392220634, - 31.437142572193, 31.425892923752, 31.414643275311, 31.403393626871, 31.392143978430, - 31.380894329989, 31.369644681548, 31.358395033107, 31.347145384666, 31.335895736225, - 31.324646087784, 31.313396439343, 31.302146790902, 31.290897142461, 31.279647494020, - 31.268397845579, 31.257148197138, 31.245898548697, 31.234648900256, 31.223399251815, - 31.212149603374, 31.200899954933, 31.189650306492, 31.178400658051, 31.167151009610, - 31.155901361169, 31.144651712728, 31.133402064287, 31.122152415846, 31.110902767405, - 31.099653118964, 31.088403470523, 31.077153822082, 31.065904173641, 31.054654525200, - 31.043404876759, 31.032155228318, 31.020905579877, 31.009655931436, 30.998406282995, - 30.987156634554, 30.975906986113, 30.964657337672, 30.953407689231, 30.942158040790, - 30.930908392349, 30.919658743908, 30.908409095467, 30.897159447026, 30.885909798585, - 30.874660150144, 30.863410501703, 30.852160853262, 30.840911204821, 30.829661556380, - 30.818411907939, 30.807162259498, 30.795912611057, 30.784662962616, 30.773413314175, - 30.762163665734, 30.750914017293, 30.739664368852, 30.728414720411, 30.717165071969, - 30.705915423528, 30.694665775087, 30.683416126646, 30.672166478205, 30.660916829764, - 30.649667181323, 30.638417532882, 30.627167884441, 30.615918236000, 30.604668587559, - 30.593418939118, 30.582169290677, 30.570919642236, 30.559669993795, 30.548420345353, - 30.537170696912, 30.525921048471, 30.514671400030, 30.503421751589, 30.492172103148, - 30.480922454707, 30.469672806266, 30.458423157825, 30.447173509384, 30.435923860943, - 30.424674212501, 30.413424564060, 30.402174915619, 30.390925267178, 30.379675618737, - 30.368425970296, 30.357176321855, 30.345926673414, 30.334677024973, 30.323427376532, - 30.312177728090, 30.300928079649, 30.289678431208, 30.278428782767, 30.267179134326, - 30.255929485885, 30.244679837444, 30.233430189003, 30.222180540561, 30.210930892120, - 30.199681243679, 30.188431595238, 30.177181946797, 30.165932298356, 30.154682649915, - 30.143433001473, 30.132183353032, 30.120933704591, 30.109684056150, 30.098434407709, - 30.087184759268, 30.075935110827, 30.064685462385, 30.053435813944, 30.042186165503, - 30.030936517062, 30.019686868621, 30.008437220180, 29.997187571739, 29.985937923297, - 29.974688274856, 29.963438626415, 29.952188977974, 29.940939329533, 29.929689681091, - 29.918440032650, 29.907190384209, 29.895940735768, 29.884691087327, 29.873441438886, - 29.862191790444, 29.850942142003, 29.839692493562, 29.828442845121, 29.817193196680, - 29.805943548238, 29.794693899797, 29.783444251356, 29.772194602915, 29.760944954474, - 29.749695306033, 29.738445657591, 29.727196009150, 29.715946360709, 29.704696712268, - 29.693447063827, 29.682197415385, 29.670947766944, 29.659698118503, 29.648448470062, - 29.637198821620, 29.625949173179, 29.614699524738, 29.603449876297, 29.592200227856, - 29.580950579414, 29.569700930973, 29.558451282532, 29.547201634091, 29.535951985649, - 29.524702337208, 29.513452688767, 29.502203040326, 29.490953391885, 29.479703743443, - 29.468454095002, 29.457204446561, 29.445954798120, 29.434705149678, 29.423455501237, - 29.412205852796, 29.400956204355, 29.389706555913, 29.378456907472, 29.367207259031, - 29.355957610590, 29.344707962148, 29.333458313707, 29.322208665266, 29.310959016825, - 29.299709368383, 29.288459719942, 29.277210071501, 29.265960423059, 29.254710774618, - 29.243461126177, 29.232211477736, 29.220961829294, 29.209712180853, 29.198462532412, - 29.187212883971, 29.175963235529, 29.164713587088, 29.153463938647, 29.142214290205, - 29.130964641764, 29.119714993323, 29.108465344882, 29.097215696440, 29.085966047999, - 29.074716399558, 29.063466751116, 29.052217102675, 29.040967454234, 29.029717805792, - 29.018468157351, 29.007218508910, 28.995968860469, 28.984719212027, 28.973469563586, - 28.962219915145, 28.950970266703, 28.939720618262, 28.928470969821, 28.917221321379, - 28.905971672938, 28.894722024497, 28.883472376055, 28.872222727614, 28.860973079173, - 28.849723430731, 28.838473782290, 28.827224133849, 28.815974485407, 28.804724836966, - 28.793475188525, 28.782225540083, 28.770975891642, 28.759726243201, 28.748476594759, - 28.737226946318, 28.725977297877, 28.714727649435, 28.703478000994, 28.692228352553, - 28.680978704111, 28.669729055670, 28.658479407229, 28.647229758787, 28.635980110346, - 28.624730461905, 28.613480813463, 28.602231165022, 28.590981516581, 28.579731868139, - 28.568482219698, 28.557232571256, 28.545982922815, 28.534733274374, 28.523483625932, - 28.512233977491, 28.500984329050, 28.489734680608, 28.478485032167, 28.467235383725, - 28.455985735284, 28.444736086843, 28.433486438401, 28.422236789960, 28.410987141519, - 28.399737493077, 28.388487844636, 28.377238196194, 28.365988547753, 28.354738899312, - 28.343489250870, 28.332239602429, 28.320989953987, 28.309740305546, 28.298490657105, - 28.287241008663, 28.275991360222, 28.264741711780, 28.253492063339, 28.242242414898, - 28.230992766456, 28.219743118015, 28.208493469573, 28.197243821132, 28.185994172691, - 28.174744524249, 28.163494875808, 28.152245227366, 28.140995578925, 28.129745930483, - 28.118496282042, 28.107246633601, 28.095996985159, 28.084747336718, 28.073497688276, - 28.062248039835, 28.050998391393, 28.039748742952, 28.028499094511, 28.017249446069, - 28.005999797628, 27.994750149186, 27.983500500745, 27.972250852303, 27.961001203862, - 27.949751555420, 27.938501906979, 27.927252258538, 27.916002610096, 27.904752961655, - 27.893503313213, 27.882253664772, 27.871004016330, 27.859754367889, 27.848504719447, - 27.837255071006, 27.826005422564, 27.814755774123, 27.803506125682, 27.792256477240, - 27.781006828799, 27.769757180357, 27.758507531916, 27.747257883474, 27.736008235033, - 27.724758586591, 27.713508938150, 27.702259289708, 27.691009641267, 27.679759992825, - 27.668510344384, 27.657260695942, 27.646011047501, 27.634761399059, 27.623511750618, - 27.612262102176, 27.601012453735, 27.589762805293, 27.578513156852, 27.567263508410, - 27.556013859969, 27.544764211527, 27.533514563086, 27.522264914644, 27.511015266203, - 27.499765617761, 27.488515969320, 27.477266320878, 27.466016672437, 27.454767023995, - 27.443517375554, 27.432267727112, 27.421018078671, 27.409768430229, 27.398518781788, - 27.387269133346, 27.376019484905, 27.364769836463, 27.353520188022, 27.342270539580, - 27.331020891139, 27.319771242697, 27.308521594256, 27.297271945814, 27.286022297373, - 27.274772648931, 27.263523000490, 27.252273352048, 27.241023703606, 27.229774055165, - 27.218524406723, 27.207274758282, 27.196025109840, 27.184775461399, 27.173525812957, - 27.162276164516, 27.151026516074, 27.139776867633, 27.128527219191, 27.117277570749, - 27.106027922308, 27.094778273866, 27.083528625425, 27.072278976983, 27.061029328542, - 27.049779680100, 27.038530031659, 27.027280383217, 27.016030734775, 27.004781086334, - 26.993531437892, 26.982281789451, 26.971032141009, 26.959782492568, 26.948532844126, - 26.937283195684, 26.926033547243, 26.914783898801, 26.903534250360, 26.892284601918, - 26.881034953477, 26.869785305035, 26.858535656593, 26.847286008152, 26.836036359710, - 26.824786711269, 26.813537062827, 26.802287414385, 26.791037765944, 26.779788117502, - 26.768538469061, 26.757288820619, 26.746039172177, 26.734789523736, 26.723539875294, - 26.712290226853, 26.701040578411, 26.689790929969, 26.678541281528, 26.667291633086, - 26.656041984645, 26.644792336203, 26.633542687761, 26.622293039320, 26.611043390878, - 26.599793742437, 26.588544093995, 26.577294445553, 26.566044797112, 26.554795148670, - 26.543545500228, 26.532295851787, 26.521046203345, 26.509796554904, 26.498546906462, - 26.487297258020, 26.476047609579, 26.464797961137, 26.453548312695, 26.442298664254, - 26.431049015812, 26.419799367371, 26.408549718929, 26.397300070487, 26.386050422046, - 26.374800773604, 26.363551125162, 26.352301476721, 26.341051828279, 26.329802179837, - 26.318552531396, 26.307302882954, 26.296053234512, 26.284803586071, 26.273553937629, - 26.262304289187, 26.251054640746, 26.239804992304, 26.228555343862, 26.217305695421, - 26.206056046979, 26.194806398538, 26.183556750096, 26.172307101654, 26.161057453213, - 26.149807804771, 26.138558156329, 26.127308507887, 26.116058859446, 26.104809211004, - 26.093559562562, 26.082309914121, 26.071060265679, 26.059810617237, 26.048560968796, - 26.037311320354, 26.026061671912, 26.014812023471, 26.003562375029, 25.992312726587, - 25.981063078146, 25.969813429704, 25.958563781262, 25.947314132821, 25.936064484379, - 25.924814835937, 25.913565187495, 25.902315539054, 25.891065890612, 25.879816242170, - 25.868566593729, 25.857316945287, 25.846067296845, 25.834817648404, 25.823567999962, - 25.812318351520, 25.801068703078, 25.789819054637, 25.778569406195, 25.767319757753, - 25.756070109312, 25.744820460870, 25.733570812428, 25.722321163986, 25.711071515545, - 25.699821867103, 25.688572218661, 25.677322570220, 25.666072921778, 25.654823273336, - 25.643573624894, 25.632323976453, 25.621074328011, 25.609824679569, 25.598575031127, - 25.587325382686, 25.576075734244, 25.564826085802, 25.553576437361, 25.542326788919, - 25.531077140477, 25.519827492035, 25.508577843594, 25.497328195152, 25.486078546710, - 25.474828898268, 25.463579249827, 25.452329601385, 25.441079952943, 25.429830304501, - 25.418580656060, 25.407331007618, 25.396081359176, 25.384831710734, 25.373582062293, - 25.362332413851, 25.351082765409, 25.339833116967, 25.328583468526, 25.317333820084, - 25.306084171642, 25.294834523200, 25.283584874758, 25.272335226317, 25.261085577875, - 25.249835929433, 25.238586280991, 25.227336632550, 25.216086984108, 25.204837335666, - 25.193587687224, 25.182338038783, 25.171088390341, 25.159838741899, 25.148589093457, - 25.137339445015, 25.126089796574, 25.114840148132, 25.103590499690, 25.092340851248, - 25.081091202806, 25.069841554365, 25.058591905923, 25.047342257481, 25.036092609039, - 25.024842960597, 25.013593312156, 25.002343663714, 24.991094015272, 24.979844366830, - 24.968594718388, 24.957345069947, 24.946095421505, 24.934845773063, 24.923596124621, - 24.912346476179, 24.901096827738, 24.889847179296, 24.878597530854, 24.867347882412, - 24.856098233970, 24.844848585529, 24.833598937087, 24.822349288645, 24.811099640203, - 24.799849991761, 24.788600343319, 24.777350694878, 24.766101046436, 24.754851397994, - 24.743601749552, 24.732352101110, 24.721102452669, 24.709852804227, 24.698603155785, - 24.687353507343, 24.676103858901, 24.664854210459, 24.653604562018, 24.642354913576, - 24.631105265134, 24.619855616692, 24.608605968250, 24.597356319808, 24.586106671367, - 24.574857022925, 24.563607374483, 24.552357726041, 24.541108077599, 24.529858429157, - 24.518608780715, 24.507359132274, 24.496109483832, 24.484859835390, 24.473610186948, - 24.462360538506, 24.451110890064, 24.439861241622, 24.428611593181, 24.417361944739, - 24.406112296297, 24.394862647855, 24.383612999413, 24.372363350971, 24.361113702529, - 24.349864054088, 24.338614405646, 24.327364757204, 24.316115108762, 24.304865460320, - 24.293615811878, 24.282366163436, 24.271116514994, 24.259866866553, 24.248617218111, - 24.237367569669, 24.226117921227, 24.214868272785, 24.203618624343, 24.192368975901, - 24.181119327459, 24.169869679017, 24.158620030576, 24.147370382134, 24.136120733692, - 24.124871085250, 24.113621436808, 24.102371788366, 24.091122139924, 24.079872491482, - 24.068622843040, 24.057373194599, 24.046123546157, 24.034873897715, 24.023624249273, - 24.012374600831, 24.001124952389, 23.989875303947, 23.978625655505, 23.967376007063, - 23.956126358621, 23.944876710180, 23.933627061738, 23.922377413296, 23.911127764854, - 23.899878116412, 23.888628467970, 23.877378819528, 23.866129171086, 23.854879522644, - 23.843629874202, 23.832380225760, 23.821130577318, 23.809880928877, 23.798631280435, - 23.787381631993, 23.776131983551, 23.764882335109, 23.753632686667, 23.742383038225, - 23.731133389783, 23.719883741341, 23.708634092899, 23.697384444457, 23.686134796015, - 23.674885147573, 23.663635499131, 23.652385850689, 23.641136202248, 23.629886553806, - 23.618636905364, 23.607387256922, 23.596137608480, 23.584887960038, 23.573638311596, - 23.562388663154, 23.551139014712, 23.539889366270, 23.528639717828, 23.517390069386, - 23.506140420944, 23.494890772502, 23.483641124060, 23.472391475618, 23.461141827176, - 23.449892178734, 23.438642530292, 23.427392881850, 23.416143233408, 23.404893584967, - 23.393643936525, 23.382394288083, 23.371144639641, 23.359894991199, 23.348645342757, - 23.337395694315, 23.326146045873, 23.314896397431, 23.303646748989, 23.292397100547, - 23.281147452105, 23.269897803663, 23.258648155221, 23.247398506779, 23.236148858337, - 23.224899209895, 23.213649561453, 23.202399913011, 23.191150264569, 23.179900616127, - 23.168650967685, 23.157401319243, 23.146151670801, 23.134902022359, 23.123652373917, - 23.112402725475, 23.101153077033, 23.089903428591, 23.078653780149, 23.067404131707, - 23.056154483265, 23.044904834823, 23.033655186381, 23.022405537939, 23.011155889497, - 22.999906241055, 22.988656592613, 22.977406944171, 22.966157295729, 22.954907647287, - 22.943657998845, 22.932408350403, 22.921158701961, 22.909909053519, 22.898659405077, - 22.887409756635, 22.876160108193, 22.864910459751, 22.853660811309, 22.842411162867, - 22.831161514425, 22.819911865983, 22.808662217541, 22.797412569099, 22.786162920657, - 22.774913272215, 22.763663623773, 22.752413975331, 22.741164326889, 22.729914678447, - 22.718665030005, 22.707415381563, 22.696165733121, 22.684916084679, 22.673666436237, - 22.662416787794, 22.651167139352, 22.639917490910, 22.628667842468, 22.617418194026, - 22.606168545584, 22.594918897142, 22.583669248700, 22.572419600258, 22.561169951816, - 22.549920303374, 22.538670654932, 22.527421006490, 22.516171358048, 22.504921709606, - 22.493672061164, 22.482422412722, 22.471172764280, 22.459923115838, 22.448673467396, - 22.437423818954, 22.426174170512, 22.414924522069, 22.403674873627, 22.392425225185, - 22.381175576743, 22.369925928301, 22.358676279859, 22.347426631417, 22.336176982975, - 22.324927334533, 22.313677686091, 22.302428037649, 22.291178389207, 22.279928740765, - 22.268679092323, 22.257429443881, 22.246179795438, 22.234930146996, 22.223680498554, - 22.212430850112, 22.201181201670, 22.189931553228, 22.178681904786, 22.167432256344, - 22.156182607902, 22.144932959460, 22.133683311018, 22.122433662576, 22.111184014133, - 22.099934365691, 22.088684717249, 22.077435068807, 22.066185420365, 22.054935771923, - 22.043686123481, 22.032436475039, 22.021186826597, 22.009937178155, 21.998687529713, - 21.987437881270, 21.976188232828, 21.964938584386, 21.953688935944, 21.942439287502, - 21.931189639060, 21.919939990618, 21.908690342176, 21.897440693734, 21.886191045292, - 21.874941396849, 21.863691748407, 21.852442099965, 21.841192451523, 21.829942803081, - 21.818693154639, 21.807443506197, 21.796193857755, 21.784944209313, 21.773694560870, - 21.762444912428, 21.751195263986, 21.739945615544, 21.728695967102, 21.717446318660, - 21.706196670218, 21.694947021776, 21.683697373333, 21.672447724891, 21.661198076449, - 21.649948428007, 21.638698779565, 21.627449131123, 21.616199482681, 21.604949834239, - 21.593700185796, 21.582450537354, 21.571200888912, 21.559951240470, 21.548701592028, - 21.537451943586, 21.526202295144, 21.514952646701, 21.503702998259, 21.492453349817, - 21.481203701375, 21.469954052933, 21.458704404491, 21.447454756049, 21.436205107606, - 21.424955459164, 21.413705810722, 21.402456162280, 21.391206513838, 21.379956865396, - 21.368707216954, 21.357457568511, 21.346207920069, 21.334958271627, 21.323708623185, - 21.312458974743, 21.301209326301, 21.289959677858, 21.278710029416, 21.267460380974, - 21.256210732532, 21.244961084090, 21.233711435648, 21.222461787206, 21.211212138763, - 21.199962490321, 21.188712841879, 21.177463193437, 21.166213544995, 21.154963896553, - 21.143714248110, 21.132464599668, 21.121214951226, 21.109965302784, 21.098715654342, - 21.087466005899, 21.076216357457, 21.064966709015, 21.053717060573, 21.042467412131, - 21.031217763689, 21.019968115246, 21.008718466804, 20.997468818362, 20.986219169920, - 20.974969521478, 20.963719873035, 20.952470224593, 20.941220576151, 20.929970927709, - 20.918721279267, 20.907471630825, 20.896221982382, 20.884972333940, 20.873722685498, - 20.862473037056, 20.851223388614, 20.839973740171, 20.828724091729, 20.817474443287, - 20.806224794845, 20.794975146403, 20.783725497960, 20.772475849518, 20.761226201076, - 20.749976552634, 20.738726904192, 20.727477255749, 20.716227607307, 20.704977958865, - 20.693728310423, 20.682478661980, 20.671229013538, 20.659979365096, 20.648729716654, - 20.637480068212, 20.626230419769, 20.614980771327, 20.603731122885, 20.592481474443, - 20.581231826001, 20.569982177558, 20.558732529116, 20.547482880674, 20.536233232232, - 20.524983583789, 20.513733935347, 20.502484286905, 20.491234638463, 20.479984990021, - 20.468735341578, 20.457485693136, 20.446236044694, 20.434986396252, 20.423736747809, - 20.412487099367, 20.401237450925, 20.389987802483, 20.378738154040, 20.367488505598, - 20.356238857156, 20.344989208714, 20.333739560272, 20.322489911829, 20.311240263387, - 20.299990614945, 20.288740966503, 20.277491318060, 20.266241669618, 20.254992021176, - 20.243742372734, 20.232492724291, 20.221243075849, 20.209993427407, 20.198743778965, - 20.187494130522, 20.176244482080, 20.164994833638, 20.153745185196, 20.142495536753, - 20.131245888311, 20.119996239869, 20.108746591427, 20.097496942984, 20.086247294542, - 20.074997646100, 20.063747997658, 20.052498349215, 20.041248700773, 20.029999052331, - 20.018749403888, 20.007499755446, 19.996250107004, 19.985000458562, 19.973750810119, - 19.962501161677, 19.951251513235, 19.940001864793, 19.928752216350, 19.917502567908, - 19.906252919466, 19.895003271024, 19.883753622581, 19.872503974139, 19.861254325697, - 19.850004677254, 19.838755028812, 19.827505380370, 19.816255731928, 19.805006083485, - 19.793756435043, 19.782506786601, 19.771257138158, 19.760007489716, 19.748757841274, - 19.737508192832, 19.726258544389, 19.715008895947, 19.703759247505, 19.692509599062, - 19.681259950620, 19.670010302178, 19.658760653736, 19.647511005293, 19.636261356851, - 19.625011708409, 19.613762059966, 19.602512411524, 19.591262763082, 19.580013114640, - 19.568763466197, 19.557513817755, 19.546264169313, 19.535014520870, 19.523764872428, - 19.512515223986, 19.501265575543, 19.490015927101, 19.478766278659, 19.467516630216, - 19.456266981774, 19.445017333332, 19.433767684890, 19.422518036447, 19.411268388005, - 19.400018739563, 19.388769091120, 19.377519442678, 19.366269794236, 19.355020145793, - 19.343770497351, 19.332520848909, 19.321271200466, 19.310021552024, 19.298771903582, - 19.287522255139, 19.276272606697, 19.265022958255, 19.253773309812, 19.242523661370, - 19.231274012928, 19.220024364486, 19.208774716043, 19.197525067601, 19.186275419159, - 19.175025770716, 19.163776122274, 19.152526473832, 19.141276825389, 19.130027176947, - 19.118777528505, 19.107527880062, 19.096278231620, 19.085028583178, 19.073778934735, - 19.062529286293, 19.051279637851, 19.040029989408, 19.028780340966, 19.017530692524, - 19.006281044081, 18.995031395639, 18.983781747196, 18.972532098754, 18.961282450312, - 18.950032801869, 18.938783153427, 18.927533504985, 18.916283856542, 18.905034208100, - 18.893784559658, 18.882534911215, 18.871285262773, 18.860035614331, 18.848785965888, - 18.837536317446, 18.826286669004, 18.815037020561, 18.803787372119, 18.792537723677, - 18.781288075234, 18.770038426792, 18.758788778349, 18.747539129907, 18.736289481465, - 18.725039833022, 18.713790184580, 18.702540536138, 18.691290887695, 18.680041239253, - 18.668791590811, 18.657541942368, 18.646292293926, 18.635042645483, 18.623792997041, - 18.612543348599, 18.601293700156, 18.590044051714, 18.578794403272, 18.567544754829, - 18.556295106387, 18.545045457944, 18.533795809502, 18.522546161060, 18.511296512617, - 18.500046864175, 18.488797215733, 18.477547567290, 18.466297918848, 18.455048270405, - 18.443798621963, 18.432548973521, 18.421299325078, 18.410049676636, 18.398800028194, - 18.387550379751, 18.376300731309, 18.365051082866, 18.353801434424, 18.342551785982, - 18.331302137539, 18.320052489097, 18.308802840654, 18.297553192212, 18.286303543770, - 18.275053895327, 18.263804246885, 18.252554598442, 18.241304950000, 18.230055301558, - 18.218805653115, 18.207556004673, 18.196306356230, 18.185056707788, 18.173807059346, - 18.162557410903, 18.151307762461, 18.140058114018, 18.128808465576, 18.117558817134, - 18.106309168691, 18.095059520249, 18.083809871806, 18.072560223364, 18.061310574922, - 18.050060926479, 18.038811278037, 18.027561629594, 18.016311981152, 18.005062332710, - 17.993812684267, 17.982563035825, 17.971313387382, 17.960063738940, 17.948814090497, - 17.937564442055, 17.926314793613, 17.915065145170, 17.903815496728, 17.892565848285, - 17.881316199843, 17.870066551401, 17.858816902958, 17.847567254516, 17.836317606073, - 17.825067957631, 17.813818309188, 17.802568660746, 17.791319012304, 17.780069363861, - 17.768819715419, 17.757570066976, 17.746320418534, 17.735070770091, 17.723821121649, - 17.712571473207, 17.701321824764, 17.690072176322, 17.678822527879, 17.667572879437, - 17.656323230994, 17.645073582552, 17.633823934110, 17.622574285667, 17.611324637225, - 17.600074988782, 17.588825340340, 17.577575691897, 17.566326043455, 17.555076395012, - 17.543826746570, 17.532577098128, 17.521327449685, 17.510077801243, 17.498828152800, - 17.487578504358, 17.476328855915, 17.465079207473, 17.453829559030, 17.442579910588, - 17.431330262145, 17.420080613703, 17.408830965261, 17.397581316818, 17.386331668376, - 17.375082019933, 17.363832371491, 17.352582723048, 17.341333074606, 17.330083426163, - 17.318833777721, 17.307584129278, 17.296334480836, 17.285084832394, 17.273835183951, - 17.262585535509, 17.251335887066, 17.240086238624, 17.228836590181, 17.217586941739, - 17.206337293296, 17.195087644854, 17.183837996411, 17.172588347969, 17.161338699526, - 17.150089051084, 17.138839402641, 17.127589754199, 17.116340105757, 17.105090457314, - 17.093840808872, 17.082591160429, 17.071341511987, 17.060091863544, 17.048842215102, - 17.037592566659, 17.026342918217, 17.015093269774, 17.003843621332, 16.992593972889, - 16.981344324447, 16.970094676004, 16.958845027562, 16.947595379119, 16.936345730677, - 16.925096082234, 16.913846433792, 16.902596785349, 16.891347136907, 16.880097488464, - 16.868847840022, 16.857598191579, 16.846348543137, 16.835098894695, 16.823849246252, - 16.812599597810, 16.801349949367, 16.790100300925, 16.778850652482, 16.767601004040, - 16.756351355597, 16.745101707155, 16.733852058712, 16.722602410270, 16.711352761827, - 16.700103113385, 16.688853464942, 16.677603816500, 16.666354168057, 16.655104519615, - 16.643854871172, 16.632605222730, 16.621355574287, 16.610105925845, 16.598856277402, - 16.587606628960, 16.576356980517, 16.565107332075, 16.553857683632, 16.542608035190, - 16.531358386747, 16.520108738305, 16.508859089862, 16.497609441419, 16.486359792977, - 16.475110144534, 16.463860496092, 16.452610847649, 16.441361199207, 16.430111550764, - 16.418861902322, 16.407612253879, 16.396362605437, 16.385112956994, 16.373863308552, - 16.362613660109, 16.351364011667, 16.340114363224, 16.328864714782, 16.317615066339, - 16.306365417897, 16.295115769454, 16.283866121012, 16.272616472569, 16.261366824127, - 16.250117175684, 16.238867527242, 16.227617878799, 16.216368230356, 16.205118581914, - 16.193868933471, 16.182619285029, 16.171369636586, 16.160119988144, 16.148870339701, - 16.137620691259, 16.126371042816, 16.115121394374, 16.103871745931, 16.092622097489, - 16.081372449046, 16.070122800604, 16.058873152161, 16.047623503718, 16.036373855276, - 16.025124206833, 16.013874558391, 16.002624909948, 15.991375261506, 15.980125613063, - 15.968875964621, 15.957626316178, 15.946376667736, 15.935127019293, 15.923877370851, - 15.912627722408, 15.901378073965, 15.890128425523, 15.878878777080, 15.867629128638, - 15.856379480195, 15.845129831753, 15.833880183310, 15.822630534868, 15.811380886425, - 15.800131237982, 15.788881589540, 15.777631941097, 15.766382292655, 15.755132644212, - 15.743882995770, 15.732633347327, 15.721383698885, 15.710134050442, 15.698884401999, - 15.687634753557, 15.676385105114, 15.665135456672, 15.653885808229, 15.642636159787, - 15.631386511344, 15.620136862902, 15.608887214459, 15.597637566016, 15.586387917574, - 15.575138269131, 15.563888620689, 15.552638972246, 15.541389323804, 15.530139675361, - 15.518890026918, 15.507640378476, 15.496390730033, 15.485141081591, 15.473891433148, - 15.462641784706, 15.451392136263, 15.440142487820, 15.428892839378, 15.417643190935, - 15.406393542493, 15.395143894050, 15.383894245608, 15.372644597165, 15.361394948722, - 15.350145300280, 15.338895651837, 15.327646003395, 15.316396354952, 15.305146706509, - 15.293897058067, 15.282647409624, 15.271397761182, 15.260148112739, 15.248898464297, - 15.237648815854, 15.226399167411, 15.215149518969, 15.203899870526, 15.192650222084, - 15.181400573641, 15.170150925198, 15.158901276756, 15.147651628313, 15.136401979871, - 15.125152331428, 15.113902682985, 15.102653034543, 15.091403386100, 15.080153737658, - 15.068904089215, 15.057654440773, 15.046404792330, 15.035155143887, 15.023905495445, - 15.012655847002, 15.001406198560, 14.990156550117, 14.978906901674, 14.967657253232, - 14.956407604789, 14.945157956347, 14.933908307904, 14.922658659461, 14.911409011019, - 14.900159362576, 14.888909714134, 14.877660065691, 14.866410417248, 14.855160768806, - 14.843911120363, 14.832661471920, 14.821411823478, 14.810162175035, 14.798912526593, - 14.787662878150, 14.776413229707, 14.765163581265, 14.753913932822, 14.742664284380, - 14.731414635937, 14.720164987494, 14.708915339052, 14.697665690609, 14.686416042167, - 14.675166393724, 14.663916745281, 14.652667096839, 14.641417448396, 14.630167799953, - 14.618918151511, 14.607668503068, 14.596418854626, 14.585169206183, 14.573919557740, - 14.562669909298, 14.551420260855, 14.540170612412, 14.528920963970, 14.517671315527, - 14.506421667085, 14.495172018642, 14.483922370199, 14.472672721757, 14.461423073314, - 14.450173424871, 14.438923776429, 14.427674127986, 14.416424479544, 14.405174831101, - 14.393925182658, 14.382675534216, 14.371425885773, 14.360176237330, 14.348926588888, - 14.337676940445, 14.326427292002, 14.315177643560, 14.303927995117, 14.292678346675, - 14.281428698232, 14.270179049789, 14.258929401347, 14.247679752904, 14.236430104461, - 14.225180456019, 14.213930807576, 14.202681159133, 14.191431510691, 14.180181862248, - 14.168932213806, 14.157682565363, 14.146432916920, 14.135183268478, 14.123933620035, - 14.112683971592, 14.101434323150, 14.090184674707, 14.078935026264, 14.067685377822, - 14.056435729379, 14.045186080936, 14.033936432494, 14.022686784051, 14.011437135608, - 14.000187487166, 13.988937838723, 13.977688190281, 13.966438541838, 13.955188893395, - 13.943939244953, 13.932689596510, 13.921439948067, 13.910190299625, 13.898940651182, - 13.887691002739, 13.876441354297, 13.865191705854, 13.853942057411, 13.842692408969, - 13.831442760526, 13.820193112083, 13.808943463641, 13.797693815198, 13.786444166755, - 13.775194518313, 13.763944869870, 13.752695221427, 13.741445572985, 13.730195924542, - 13.718946276099, 13.707696627657, 13.696446979214, 13.685197330771, 13.673947682329, - 13.662698033886, 13.651448385443, 13.640198737001, 13.628949088558, 13.617699440115, - 13.606449791673, 13.595200143230, 13.583950494787, 13.572700846345, 13.561451197902, - 13.550201549459, 13.538951901017, 13.527702252574, 13.516452604131, 13.505202955689, - 13.493953307246, 13.482703658803, 13.471454010361, 13.460204361918, 13.448954713475, - 13.437705065033, 13.426455416590, 13.415205768147, 13.403956119704, 13.392706471262, - 13.381456822819, 13.370207174376, 13.358957525934, 13.347707877491, 13.336458229048, - 13.325208580606, 13.313958932163, 13.302709283720, 13.291459635278, 13.280209986835, - 13.268960338392, 13.257710689950, 13.246461041507, 13.235211393064, 13.223961744622, - 13.212712096179, 13.201462447736, 13.190212799293, 13.178963150851, 13.167713502408, - 13.156463853965, 13.145214205523, 13.133964557080, 13.122714908637, 13.111465260195, - 13.100215611752, 13.088965963309, 13.077716314867, 13.066466666424, 13.055217017981, - 13.043967369538, 13.032717721096, 13.021468072653, 13.010218424210, 12.998968775768, - 12.987719127325, 12.976469478882, 12.965219830440, 12.953970181997, 12.942720533554, - 12.931470885111, 12.920221236669, 12.908971588226, 12.897721939783, 12.886472291341, - 12.875222642898, 12.863972994455, 12.852723346012, 12.841473697570, 12.830224049127, - 12.818974400684, 12.807724752242, 12.796475103799, 12.785225455356, 12.773975806913, - 12.762726158471, 12.751476510028, 12.740226861585, 12.728977213143, 12.717727564700, - 12.706477916257, 12.695228267815, 12.683978619372, 12.672728970929, 12.661479322486, - 12.650229674044, 12.638980025601, 12.627730377158, 12.616480728715, 12.605231080273, - 12.593981431830, 12.582731783387, 12.571482134945, 12.560232486502, 12.548982838059, - 12.537733189616, 12.526483541174, 12.515233892731, 12.503984244288, 12.492734595846, - 12.481484947403, 12.470235298960, 12.458985650517, 12.447736002075, 12.436486353632, - 12.425236705189, 12.413987056746, 12.402737408304, 12.391487759861, 12.380238111418, - 12.368988462976, 12.357738814533, 12.346489166090, 12.335239517647, 12.323989869205, - 12.312740220762, 12.301490572319, 12.290240923876, 12.278991275434, 12.267741626991, - 12.256491978548, 12.245242330106, 12.233992681663, 12.222743033220, 12.211493384777, - 12.200243736335, 12.188994087892, 12.177744439449, 12.166494791006, 12.155245142564, - 12.143995494121, 12.132745845678, 12.121496197235, 12.110246548793, 12.098996900350, - 12.087747251907, 12.076497603464, 12.065247955022, 12.053998306579, 12.042748658136, - 12.031499009693, 12.020249361251, 12.008999712808, 11.997750064365, 11.986500415922, - 11.975250767480, 11.964001119037, 11.952751470594, 11.941501822152, 11.930252173709, - 11.919002525266, 11.907752876823, 11.896503228381, 11.885253579938, 11.874003931495, - 11.862754283052, 11.851504634610, 11.840254986167, 11.829005337724, 11.817755689281, - 11.806506040839, 11.795256392396, 11.784006743953, 11.772757095510, 11.761507447067, - 11.750257798625, 11.739008150182, 11.727758501739, 11.716508853296, 11.705259204854, - 11.694009556411, 11.682759907968, 11.671510259525, 11.660260611083, 11.649010962640, - 11.637761314197, 11.626511665754, 11.615262017312, 11.604012368869, 11.592762720426, - 11.581513071983, 11.570263423541, 11.559013775098, 11.547764126655, 11.536514478212, - 11.525264829770, 11.514015181327, 11.502765532884, 11.491515884441, 11.480266235998, - 11.469016587556, 11.457766939113, 11.446517290670, 11.435267642227, 11.424017993785, - 11.412768345342, 11.401518696899, 11.390269048456, 11.379019400014, 11.367769751571, - 11.356520103128, 11.345270454685, 11.334020806242, 11.322771157800, 11.311521509357, - 11.300271860914, 11.289022212471, 11.277772564029, 11.266522915586, 11.255273267143, - 11.244023618700, 11.232773970257, 11.221524321815, 11.210274673372, 11.199025024929, - 11.187775376486, 11.176525728044, 11.165276079601, 11.154026431158, 11.142776782715, - 11.131527134272, 11.120277485830, 11.109027837387, 11.097778188944, 11.086528540501, - 11.075278892059, 11.064029243616, 11.052779595173, 11.041529946730, 11.030280298287, - 11.019030649845, 11.007781001402, 10.996531352959, 10.985281704516, 10.974032056074, - 10.962782407631, 10.951532759188, 10.940283110745, 10.929033462302, 10.917783813860, - 10.906534165417, 10.895284516974, 10.884034868531, 10.872785220088, 10.861535571646, - 10.850285923203, 10.839036274760, 10.827786626317, 10.816536977874, 10.805287329432, - 10.794037680989, 10.782788032546, 10.771538384103, 10.760288735660, 10.749039087218, - 10.737789438775, 10.726539790332, 10.715290141889, 10.704040493446, 10.692790845004, - 10.681541196561, 10.670291548118, 10.659041899675, 10.647792251233, 10.636542602790, - 10.625292954347, 10.614043305904, 10.602793657461, 10.591544009019, 10.580294360576, - 10.569044712133, 10.557795063690, 10.546545415247, 10.535295766804, 10.524046118362, - 10.512796469919, 10.501546821476, 10.490297173033, 10.479047524590, 10.467797876148, - 10.456548227705, 10.445298579262, 10.434048930819, 10.422799282376, 10.411549633934, - 10.400299985491, 10.389050337048, 10.377800688605, 10.366551040162, 10.355301391720, - 10.344051743277, 10.332802094834, 10.321552446391, 10.310302797948, 10.299053149506, - 10.287803501063, 10.276553852620, 10.265304204177, 10.254054555734, 10.242804907291, - 10.231555258849, 10.220305610406, 10.209055961963, 10.197806313520, 10.186556665077, - 10.175307016635, 10.164057368192, 10.152807719749, 10.141558071306, 10.130308422863, - 10.119058774420, 10.107809125978, 10.096559477535, 10.085309829092, 10.074060180649, - 10.062810532206, 10.051560883764, 10.040311235321, 10.029061586878, 10.017811938435, - 10.006562289992, 9.995312641549, 9.984062993107, 9.972813344664, 9.961563696221, - 9.950314047778, 9.939064399335, 9.927814750893, 9.916565102450, 9.905315454007, - 9.894065805564, 9.882816157121, 9.871566508678, 9.860316860236, 9.849067211793, - 9.837817563350, 9.826567914907, 9.815318266464, 9.804068618021, 9.792818969579, - 9.781569321136, 9.770319672693, 9.759070024250, 9.747820375807, 9.736570727364, - 9.725321078922, 9.714071430479, 9.702821782036, 9.691572133593, 9.680322485150, - 9.669072836707, 9.657823188265, 9.646573539822, 9.635323891379, 9.624074242936, - 9.612824594493, 9.601574946050, 9.590325297608, 9.579075649165, 9.567826000722, - 9.556576352279, 9.545326703836, 9.534077055393, 9.522827406951, 9.511577758508, - 9.500328110065, 9.489078461622, 9.477828813179, 9.466579164736, 9.455329516294, - 9.444079867851, 9.432830219408, 9.421580570965, 9.410330922522, 9.399081274079, - 9.387831625636, 9.376581977194, 9.365332328751, 9.354082680308, 9.342833031865, - 9.331583383422, 9.320333734979, 9.309084086537, 9.297834438094, 9.286584789651, - 9.275335141208, 9.264085492765, 9.252835844322, 9.241586195879, 9.230336547437, - 9.219086898994, 9.207837250551, 9.196587602108, 9.185337953665, 9.174088305222, - 9.162838656780, 9.151589008337, 9.140339359894, 9.129089711451, 9.117840063008, - 9.106590414565, 9.095340766122, 9.084091117680, 9.072841469237, 9.061591820794, - 9.050342172351, 9.039092523908, 9.027842875465, 9.016593227022, 9.005343578580, - 8.994093930137, 8.982844281694, 8.971594633251, 8.960344984808, 8.949095336365, - 8.937845687922, 8.926596039480, 8.915346391037, 8.904096742594, 8.892847094151, - 8.881597445708, 8.870347797265, 8.859098148822, 8.847848500380, 8.836598851937, - 8.825349203494, 8.814099555051, 8.802849906608, 8.791600258165, 8.780350609722, - 8.769100961280, 8.757851312837, 8.746601664394, 8.735352015951, 8.724102367508, - 8.712852719065, 8.701603070622, 8.690353422180, 8.679103773737, 8.667854125294, - 8.656604476851, 8.645354828408, 8.634105179965, 8.622855531522, 8.611605883079, - 8.600356234637, 8.589106586194, 8.577856937751, 8.566607289308, 8.555357640865, - 8.544107992422, 8.532858343979, 8.521608695537, 8.510359047094, 8.499109398651, - 8.487859750208, 8.476610101765, 8.465360453322, 8.454110804879, 8.442861156436, - 8.431611507994, 8.420361859551, 8.409112211108, 8.397862562665, 8.386612914222, - 8.375363265779, 8.364113617336, 8.352863968893, 8.341614320451, 8.330364672008, - 8.319115023565, 8.307865375122, 8.296615726679, 8.285366078236, 8.274116429793, - 8.262866781350, 8.251617132908, 8.240367484465, 8.229117836022, 8.217868187579, - 8.206618539136, 8.195368890693, 8.184119242250, 8.172869593807, 8.161619945364, - 8.150370296922, 8.139120648479, 8.127871000036, 8.116621351593, 8.105371703150, - 8.094122054707, 8.082872406264, 8.071622757821, 8.060373109379, 8.049123460936, - 8.037873812493, 8.026624164050, 8.015374515607, 8.004124867164, 7.992875218721, - 7.981625570278, 7.970375921835, 7.959126273393, 7.947876624950, 7.936626976507, - 7.925377328064, 7.914127679621, 7.902878031178, 7.891628382735, 7.880378734292, - 7.869129085849, 7.857879437407, 7.846629788964, 7.835380140521, 7.824130492078, - 7.812880843635, 7.801631195192, 7.790381546749, 7.779131898306, 7.767882249863, - 7.756632601421, 7.745382952978, 7.734133304535, 7.722883656092, 7.711634007649, - 7.700384359206, 7.689134710763, 7.677885062320, 7.666635413877, 7.655385765435, - 7.644136116992, 7.632886468549, 7.621636820106, 7.610387171663, 7.599137523220, - 7.587887874777, 7.576638226334, 7.565388577891, 7.554138929449, 7.542889281006, - 7.531639632563, 7.520389984120, 7.509140335677, 7.497890687234, 7.486641038791, - 7.475391390348, 7.464141741905, 7.452892093462, 7.441642445020, 7.430392796577, - 7.419143148134, 7.407893499691, 7.396643851248, 7.385394202805, 7.374144554362, - 7.362894905919, 7.351645257476, 7.340395609033, 7.329145960591, 7.317896312148, - 7.306646663705, 7.295397015262, 7.284147366819, 7.272897718376, 7.261648069933, - 7.250398421490, 7.239148773047, 7.227899124604, 7.216649476161, 7.205399827719, - 7.194150179276, 7.182900530833, 7.171650882390, 7.160401233947, 7.149151585504, - 7.137901937061, 7.126652288618, 7.115402640175, 7.104152991732, 7.092903343289, - 7.081653694847, 7.070404046404, 7.059154397961, 7.047904749518, 7.036655101075, - 7.025405452632, 7.014155804189, 7.002906155746, 6.991656507303, 6.980406858860, - 6.969157210417, 6.957907561975, 6.946657913532, 6.935408265089, 6.924158616646, - 6.912908968203, 6.901659319760, 6.890409671317, 6.879160022874, 6.867910374431, - 6.856660725988, 6.845411077545, 6.834161429103, 6.822911780660, 6.811662132217, - 6.800412483774, 6.789162835331, 6.777913186888, 6.766663538445, 6.755413890002, - 6.744164241559, 6.732914593116, 6.721664944673, 6.710415296230, 6.699165647788, - 6.687915999345, 6.676666350902, 6.665416702459, 6.654167054016, 6.642917405573, - 6.631667757130, 6.620418108687, 6.609168460244, 6.597918811801, 6.586669163358, - 6.575419514915, 6.564169866473, 6.552920218030, 6.541670569587, 6.530420921144, - 6.519171272701, 6.507921624258, 6.496671975815, 6.485422327372, 6.474172678929, - 6.462923030486, 6.451673382043, 6.440423733600, 6.429174085157, 6.417924436715, - 6.406674788272, 6.395425139829, 6.384175491386, 6.372925842943, 6.361676194500, - 6.350426546057, 6.339176897614, 6.327927249171, 6.316677600728, 6.305427952285, - 6.294178303842, 6.282928655399, 6.271679006956, 6.260429358514, 6.249179710071, - 6.237930061628, 6.226680413185, 6.215430764742, 6.204181116299, 6.192931467856, - 6.181681819413, 6.170432170970, 6.159182522527, 6.147932874084, 6.136683225641, - 6.125433577198, 6.114183928755, 6.102934280313, 6.091684631870, 6.080434983427, - 6.069185334984, 6.057935686541, 6.046686038098, 6.035436389655, 6.024186741212, - 6.012937092769, 6.001687444326, 5.990437795883, 5.979188147440, 5.967938498997, - 5.956688850554, 5.945439202112, 5.934189553669, 5.922939905226, 5.911690256783, - 5.900440608340, 5.889190959897, 5.877941311454, 5.866691663011, 5.855442014568, - 5.844192366125, 5.832942717682, 5.821693069239, 5.810443420796, 5.799193772353, - 5.787944123910, 5.776694475467, 5.765444827025, 5.754195178582, 5.742945530139, - 5.731695881696, 5.720446233253, 5.709196584810, 5.697946936367, 5.686697287924, - 5.675447639481, 5.664197991038, 5.652948342595, 5.641698694152, 5.630449045709, - 5.619199397266, 5.607949748823, 5.596700100380, 5.585450451938, 5.574200803495, - 5.562951155052, 5.551701506609, 5.540451858166, 5.529202209723, 5.517952561280, - 5.506702912837, 5.495453264394, 5.484203615951, 5.472953967508, 5.461704319065, - 5.450454670622, 5.439205022179, 5.427955373736, 5.416705725293, 5.405456076850, - 5.394206428407, 5.382956779965, 5.371707131522, 5.360457483079, 5.349207834636, - 5.337958186193, 5.326708537750, 5.315458889307, 5.304209240864, 5.292959592421, - 5.281709943978, 5.270460295535, 5.259210647092, 5.247960998649, 5.236711350206, - 5.225461701763, 5.214212053320, 5.202962404877, 5.191712756434, 5.180463107992, - 5.169213459549, 5.157963811106, 5.146714162663, 5.135464514220, 5.124214865777, - 5.112965217334, 5.101715568891, 5.090465920448, 5.079216272005, 5.067966623562, - 5.056716975119, 5.045467326676, 5.034217678233, 5.022968029790, 5.011718381347, - 5.000468732904, 4.989219084461, 4.977969436018, 4.966719787575, 4.955470139133, - 4.944220490690, 4.932970842247, 4.921721193804, 4.910471545361, 4.899221896918, - 4.887972248475, 4.876722600032, 4.865472951589, 4.854223303146, 4.842973654703, - 4.831724006260, 4.820474357817, 4.809224709374, 4.797975060931, 4.786725412488, - 4.775475764045, 4.764226115602, 4.752976467159, 4.741726818716, 4.730477170273, - 4.719227521830, 4.707977873388, 4.696728224945, 4.685478576502, 4.674228928059, - 4.662979279616, 4.651729631173, 4.640479982730, 4.629230334287, 4.617980685844, - 4.606731037401, 4.595481388958, 4.584231740515, 4.572982092072, 4.561732443629, - 4.550482795186, 4.539233146743, 4.527983498300, 4.516733849857, 4.505484201414, - 4.494234552971, 4.482984904528, 4.471735256085, 4.460485607642, 4.449235959199, - 4.437986310757, 4.426736662314, 4.415487013871, 4.404237365428, 4.392987716985, - 4.381738068542, 4.370488420099, 4.359238771656, 4.347989123213, 4.336739474770, - 4.325489826327, 4.314240177884, 4.302990529441, 4.291740880998, 4.280491232555, - 4.269241584112, 4.257991935669, 4.246742287226, 4.235492638783, 4.224242990340, - 4.212993341897, 4.201743693454, 4.190494045011, 4.179244396568, 4.167994748125, - 4.156745099682, 4.145495451240, 4.134245802797, 4.122996154354, 4.111746505911, - 4.100496857468, 4.089247209025, 4.077997560582, 4.066747912139, 4.055498263696, - 4.044248615253, 4.032998966810, 4.021749318367, 4.010499669924, 3.999250021481, - 3.988000373038, 3.976750724595, 3.965501076152, 3.954251427709, 3.943001779266, - 3.931752130823, 3.920502482380, 3.909252833937, 3.898003185494, 3.886753537051, - 3.875503888608, 3.864254240165, 3.853004591722, 3.841754943279, 3.830505294836, - 3.819255646393, 3.808005997951, 3.796756349508, 3.785506701065, 3.774257052622, - 3.763007404179, 3.751757755736, 3.740508107293, 3.729258458850, 3.718008810407, - 3.706759161964, 3.695509513521, 3.684259865078, 3.673010216635, 3.661760568192, - 3.650510919749, 3.639261271306, 3.628011622863, 3.616761974420, 3.605512325977, - 3.594262677534, 3.583013029091, 3.571763380648, 3.560513732205, 3.549264083762, - 3.538014435319, 3.526764786876, 3.515515138433, 3.504265489990, 3.493015841547, - 3.481766193104, 3.470516544661, 3.459266896218, 3.448017247775, 3.436767599332, - 3.425517950889, 3.414268302447, 3.403018654004, 3.391769005561, 3.380519357118, - 3.369269708675, 3.358020060232, 3.346770411789, 3.335520763346, 3.324271114903, - 3.313021466460, 3.301771818017, 3.290522169574, 3.279272521131, 3.268022872688, - 3.256773224245, 3.245523575802, 3.234273927359, 3.223024278916, 3.211774630473, - 3.200524982030, 3.189275333587, 3.178025685144, 3.166776036701, 3.155526388258, - 3.144276739815, 3.133027091372, 3.121777442929, 3.110527794486, 3.099278146043, - 3.088028497600, 3.076778849157, 3.065529200714, 3.054279552271, 3.043029903828, - 3.031780255385, 3.020530606942, 3.009280958499, 2.998031310056, 2.986781661613, - 2.975532013170, 2.964282364727, 2.953032716284, 2.941783067841, 2.930533419399, - 2.919283770956, 2.908034122513, 2.896784474070, 2.885534825627, 2.874285177184, - 2.863035528741, 2.851785880298, 2.840536231855, 2.829286583412, 2.818036934969, - 2.806787286526, 2.795537638083, 2.784287989640, 2.773038341197, 2.761788692754, - 2.750539044311, 2.739289395868, 2.728039747425, 2.716790098982, 2.705540450539, - 2.694290802096, 2.683041153653, 2.671791505210, 2.660541856767, 2.649292208324, - 2.638042559881, 2.626792911438, 2.615543262995, 2.604293614552, 2.593043966109, - 2.581794317666, 2.570544669223, 2.559295020780, 2.548045372337, 2.536795723894, - 2.525546075451, 2.514296427008, 2.503046778565, 2.491797130122, 2.480547481679, - 2.469297833236, 2.458048184793, 2.446798536350, 2.435548887907, 2.424299239464, - 2.413049591021, 2.401799942578, 2.390550294135, 2.379300645692, 2.368050997249, - 2.356801348806, 2.345551700363, 2.334302051920, 2.323052403478, 2.311802755035, - 2.300553106592, 2.289303458149, 2.278053809706, 2.266804161263, 2.255554512820, - 2.244304864377, 2.233055215934, 2.221805567491, 2.210555919048, 2.199306270605, - 2.188056622162, 2.176806973719, 2.165557325276, 2.154307676833, 2.143058028390, - 2.131808379947, 2.120558731504, 2.109309083061, 2.098059434618, 2.086809786175, - 2.075560137732, 2.064310489289, 2.053060840846, 2.041811192403, 2.030561543960, - 2.019311895517, 2.008062247074, 1.996812598631, 1.985562950188, 1.974313301745, - 1.963063653302, 1.951814004859, 1.940564356416, 1.929314707973, 1.918065059530, - 1.906815411087, 1.895565762644, 1.884316114201, 1.873066465758, 1.861816817315, - 1.850567168872, 1.839317520429, 1.828067871986, 1.816818223543, 1.805568575100, - 1.794318926657, 1.783069278214, 1.771819629771, 1.760569981328, 1.749320332885, - 1.738070684442, 1.726821035999, 1.715571387556, 1.704321739113, 1.693072090670, - 1.681822442227, 1.670572793784, 1.659323145341, 1.648073496898, 1.636823848455, - 1.625574200012, 1.614324551569, 1.603074903126, 1.591825254683, 1.580575606240, - 1.569325957797, 1.558076309354, 1.546826660911, 1.535577012468, 1.524327364025, - 1.513077715582, 1.501828067139, 1.490578418696, 1.479328770253, 1.468079121810, - 1.456829473367, 1.445579824924, 1.434330176482, 1.423080528039, 1.411830879596, - 1.400581231153, 1.389331582710, 1.378081934267, 1.366832285824, 1.355582637381, - 1.344332988938, 1.333083340495, 1.321833692052, 1.310584043609, 1.299334395166, - 1.288084746723, 1.276835098280, 1.265585449837, 1.254335801394, 1.243086152951, - 1.231836504508, 1.220586856065, 1.209337207622, 1.198087559179, 1.186837910736, - 1.175588262293, 1.164338613850, 1.153088965407, 1.141839316964, 1.130589668521, - 1.119340020078, 1.108090371635, 1.096840723192, 1.085591074749, 1.074341426306, - 1.063091777863, 1.051842129420, 1.040592480977, 1.029342832534, 1.018093184091, - 1.006843535648, 0.995593887205, 0.984344238762, 0.973094590319, 0.961844941876, - 0.950595293433, 0.939345644990, 0.928095996547, 0.916846348104, 0.905596699661, - 0.894347051218, 0.883097402775, 0.871847754332, 0.860598105889, 0.849348457446, - 0.838098809003, 0.826849160560, 0.815599512117, 0.804349863674, 0.793100215231, - 0.781850566788, 0.770600918345, 0.759351269902, 0.748101621459, 0.736851973016, - 0.725602324573, 0.714352676130, 0.703103027687, 0.691853379244, 0.680603730801, - 0.669354082358, 0.658104433915, 0.646854785472, 0.635605137029, 0.624355488586, - 0.613105840143, 0.601856191700, 0.590606543257, 0.579356894814, 0.568107246371, - 0.556857597928, 0.545607949485, 0.534358301042, 0.523108652599, 0.511859004156, - 0.500609355713, 0.489359707270, 0.478110058827, 0.466860410384, 0.455610761941, - 0.444361113498, 0.433111465055, 0.421861816612, 0.410612168169, 0.399362519726, - 0.388112871283, 0.376863222840, 0.365613574397, 0.354363925954, 0.343114277511, - 0.331864629068, 0.320614980625, 0.309365332182, 0.298115683739, 0.286866035296, - 0.275616386853, 0.264366738410, 0.253117089967, 0.241867441524, 0.230617793081, - 0.219368144638, 0.208118496195, 0.196868847752, 0.185619199309, 0.174369550866, - 0.163119902423, 0.151870253980, 0.140620605537, 0.129370957094, 0.118121308651, - 0.106871660208, 0.095622011765, 0.084372363322, 0.073122714879, 0.061873066436, - 0.050623417993, 0.039373769550, 0.028124121107, 0.016874472664, 0.005624824221 - )) +DEFINE_GAUSSIAN_LATITUDES( + 8000, + LIST( + 89.991388621915, 89.980233294064, 89.969012087973, 89.957775997170, 89.946534260250, 89.935289791164, + 89.924043795176, 89.912796860149, 89.901549306701, 89.890301324497, 89.879053032872, 89.867804510659, + 89.856555812013, 89.845306975370, 89.834058028757, 89.822808993098, 89.811559884324, 89.800310714781, + 89.789061494187, 89.777812230288, 89.766562929342, 89.755313596457, 89.744064235840, 89.732814850994, + 89.721565444855, 89.710316019900, 89.699066578241, 89.687817121682, 89.676567651779, 89.665318169874, + 89.654068677140, 89.642819174600, 89.631569663150, 89.620320143583, 89.609070616601, 89.597821082824, + 89.586571542809, 89.575321997048, 89.564072445989, 89.552822890030, 89.541573329533, 89.530323764823, + 89.519074196195, 89.507824623919, 89.496575048240, 89.485325469380, 89.474075887543, 89.462826302916, + 89.451576715671, 89.440327125966, 89.429077533946, 89.417827939746, 89.406578343489, 89.395328745290, + 89.384079145256, 89.372829543485, 89.361579940070, 89.350330335095, 89.339080728640, 89.327831120779, + 89.316581511583, 89.305331901115, 89.294082289437, 89.282832676606, 89.271583062674, 89.260333447692, + 89.249083831708, 89.237834214766, 89.226584596907, 89.215334978171, 89.204085358595, 89.192835738215, + 89.181586117063, 89.170336495171, 89.159086872568, 89.147837249283, 89.136587625343, 89.125338000772, + 89.114088375595, 89.102838749834, 89.091589123511, 89.080339496647, 89.069089869262, 89.057840241373, + 89.046590612999, 89.035340984158, 89.024091354864, 89.012841725134, 89.001592094982, 88.990342464422, + 88.979092833468, 88.967843202133, 88.956593570428, 88.945343938367, 88.934094305960, 88.922844673218, + 88.911595040151, 88.900345406769, 88.889095773083, 88.877846139100, 88.866596504830, 88.855346870282, + 88.844097235463, 88.832847600381, 88.821597965045, 88.810348329460, 88.799098693634, 88.787849057574, + 88.776599421287, 88.765349784777, 88.754100148052, 88.742850511118, 88.731600873979, 88.720351236641, + 88.709101599110, 88.697851961390, 88.686602323487, 88.675352685404, 88.664103047147, 88.652853408719, + 88.641603770126, 88.630354131371, 88.619104492457, 88.607854853390, 88.596605214173, 88.585355574808, + 88.574105935301, 88.562856295653, 88.551606655869, 88.540357015951, 88.529107375903, 88.517857735727, + 88.506608095426, 88.495358455004, 88.484108814463, 88.472859173805, 88.461609533033, 88.450359892150, + 88.439110251158, 88.427860610059, 88.416610968856, 88.405361327551, 88.394111686145, 88.382862044642, + 88.371612403043, 88.360362761349, 88.349113119564, 88.337863477688, 88.326613835725, 88.315364193674, + 88.304114551539, 88.292864909320, 88.281615267020, 88.270365624640, 88.259115982182, 88.247866339647, + 88.236616697036, 88.225367054351, 88.214117411594, 88.202867768765, 88.191618125867, 88.180368482900, + 88.169118839865, 88.157869196765, 88.146619553599, 88.135369910370, 88.124120267079, 88.112870623726, + 88.101620980312, 88.090371336839, 88.079121693308, 88.067872049720, 88.056622406075, 88.045372762376, + 88.034123118621, 88.022873474814, 88.011623830954, 88.000374187042, 87.989124543080, 87.977874899067, + 87.966625255006, 87.955375610897, 87.944125966739, 87.932876322536, 87.921626678286, 87.910377033991, + 87.899127389652, 87.887877745269, 87.876628100842, 87.865378456374, 87.854128811864, 87.842879167313, + 87.831629522721, 87.820379878089, 87.809130233419, 87.797880588709, 87.786630943962, 87.775381299177, + 87.764131654356, 87.752882009498, 87.741632364604, 87.730382719676, 87.719133074712, 87.707883429714, + 87.696633784683, 87.685384139618, 87.674134494521, 87.662884849392, 87.651635204230, 87.640385559038, + 87.629135913814, 87.617886268560, 87.606636623276, 87.595386977963, 87.584137332620, 87.572887687248, + 87.561638041848, 87.550388396420, 87.539138750965, 87.527889105482, 87.516639459973, 87.505389814437, + 87.494140168875, 87.482890523287, 87.471640877673, 87.460391232035, 87.449141586371, 87.437891940684, + 87.426642294972, 87.415392649236, 87.404143003477, 87.392893357695, 87.381643711889, 87.370394066062, + 87.359144420212, 87.347894774339, 87.336645128445, 87.325395482530, 87.314145836593, 87.302896190636, + 87.291646544658, 87.280396898659, 87.269147252640, 87.257897606602, 87.246647960543, 87.235398314465, + 87.224148668368, 87.212899022252, 87.201649376117, 87.190399729964, 87.179150083793, 87.167900437603, + 87.156650791396, 87.145401145170, 87.134151498928, 87.122901852668, 87.111652206391, 87.100402560097, + 87.089152913787, 87.077903267461, 87.066653621117, 87.055403974758, 87.044154328383, 87.032904681993, + 87.021655035586, 87.010405389165, 86.999155742728, 86.987906096276, 86.976656449810, 86.965406803328, + 86.954157156832, 86.942907510322, 86.931657863798, 86.920408217259, 86.909158570707, 86.897908924141, + 86.886659277561, 86.875409630968, 86.864159984362, 86.852910337742, 86.841660691110, 86.830411044464, + 86.819161397806, 86.807911751135, 86.796662104452, 86.785412457757, 86.774162811049, 86.762913164329, + 86.751663517597, 86.740413870853, 86.729164224098, 86.717914577331, 86.706664930552, 86.695415283763, + 86.684165636961, 86.672915990149, 86.661666343326, 86.650416696492, 86.639167049647, 86.627917402791, + 86.616667755925, 86.605418109048, 86.594168462161, 86.582918815264, 86.571669168357, 86.560419521439, + 86.549169874512, 86.537920227574, 86.526670580627, 86.515420933670, 86.504171286704, 86.492921639728, + 86.481671992742, 86.470422345748, 86.459172698744, 86.447923051731, 86.436673404709, 86.425423757678, + 86.414174110638, 86.402924463589, 86.391674816532, 86.380425169466, 86.369175522391, 86.357925875308, + 86.346676228216, 86.335426581117, 86.324176934009, 86.312927286892, 86.301677639768, 86.290427992636, + 86.279178345495, 86.267928698347, 86.256679051191, 86.245429404028, 86.234179756856, 86.222930109677, + 86.211680462491, 86.200430815297, 86.189181168095, 86.177931520887, 86.166681873671, 86.155432226448, + 86.144182579217, 86.132932931980, 86.121683284736, 86.110433637484, 86.099183990226, 86.087934342961, + 86.076684695689, 86.065435048411, 86.054185401125, 86.042935753833, 86.031686106535, 86.020436459230, + 86.009186811919, 85.997937164601, 85.986687517277, 85.975437869947, 85.964188222610, 85.952938575268, + 85.941688927919, 85.930439280564, 85.919189633203, 85.907939985836, 85.896690338463, 85.885440691085, + 85.874191043700, 85.862941396310, 85.851691748914, 85.840442101512, 85.829192454105, 85.817942806692, + 85.806693159274, 85.795443511850, 85.784193864420, 85.772944216986, 85.761694569545, 85.750444922100, + 85.739195274649, 85.727945627193, 85.716695979732, 85.705446332265, 85.694196684794, 85.682947037317, + 85.671697389835, 85.660447742349, 85.649198094857, 85.637948447361, 85.626698799859, 85.615449152353, + 85.604199504842, 85.592949857326, 85.581700209805, 85.570450562280, 85.559200914750, 85.547951267215, + 85.536701619676, 85.525451972132, 85.514202324584, 85.502952677031, 85.491703029474, 85.480453381912, + 85.469203734346, 85.457954086776, 85.446704439201, 85.435454791622, 85.424205144038, 85.412955496451, + 85.401705848859, 85.390456201263, 85.379206553663, 85.367956906059, 85.356707258450, 85.345457610838, + 85.334207963222, 85.322958315601, 85.311708667977, 85.300459020349, 85.289209372717, 85.277959725081, + 85.266710077441, 85.255460429797, 85.244210782149, 85.232961134498, 85.221711486843, 85.210461839184, + 85.199212191522, 85.187962543856, 85.176712896186, 85.165463248512, 85.154213600835, 85.142963953155, + 85.131714305471, 85.120464657783, 85.109215010092, 85.097965362398, 85.086715714700, 85.075466066998, + 85.064216419293, 85.052966771585, 85.041717123874, 85.030467476159, 85.019217828441, 85.007968180719, + 84.996718532994, 84.985468885266, 84.974219237535, 84.962969589801, 84.951719942063, 84.940470294323, + 84.929220646579, 84.917970998832, 84.906721351082, 84.895471703329, 84.884222055572, 84.872972407813, + 84.861722760051, 84.850473112286, 84.839223464518, 84.827973816747, 84.816724168973, 84.805474521196, + 84.794224873416, 84.782975225633, 84.771725577847, 84.760475930059, 84.749226282268, 84.737976634474, + 84.726726986677, 84.715477338877, 84.704227691075, 84.692978043270, 84.681728395462, 84.670478747652, + 84.659229099838, 84.647979452023, 84.636729804204, 84.625480156383, 84.614230508559, 84.602980860733, + 84.591731212904, 84.580481565073, 84.569231917239, 84.557982269402, 84.546732621563, 84.535482973721, + 84.524233325877, 84.512983678031, 84.501734030182, 84.490484382331, 84.479234734477, 84.467985086620, + 84.456735438762, 84.445485790901, 84.434236143037, 84.422986495172, 84.411736847303, 84.400487199433, + 84.389237551560, 84.377987903685, 84.366738255808, 84.355488607928, 84.344238960047, 84.332989312163, + 84.321739664276, 84.310490016388, 84.299240368497, 84.287990720604, 84.276741072709, 84.265491424812, + 84.254241776912, 84.242992129011, 84.231742481107, 84.220492833201, 84.209243185293, 84.197993537383, + 84.186743889471, 84.175494241557, 84.164244593641, 84.152994945723, 84.141745297803, 84.130495649880, + 84.119246001956, 84.107996354030, 84.096746706102, 84.085497058171, 84.074247410239, 84.062997762305, + 84.051748114369, 84.040498466431, 84.029248818491, 84.017999170549, 84.006749522606, 83.995499874660, + 83.984250226713, 83.973000578763, 83.961750930812, 83.950501282859, 83.939251634904, 83.928001986948, + 83.916752338989, 83.905502691029, 83.894253043067, 83.883003395103, 83.871753747137, 83.860504099170, + 83.849254451201, 83.838004803230, 83.826755155257, 83.815505507283, 83.804255859307, 83.793006211329, + 83.781756563349, 83.770506915368, 83.759257267385, 83.748007619401, 83.736757971415, 83.725508323427, + 83.714258675437, 83.703009027446, 83.691759379453, 83.680509731459, 83.669260083463, 83.658010435466, + 83.646760787467, 83.635511139466, 83.624261491464, 83.613011843460, 83.601762195454, 83.590512547447, + 83.579262899439, 83.568013251429, 83.556763603417, 83.545513955404, 83.534264307390, 83.523014659373, + 83.511765011356, 83.500515363337, 83.489265715316, 83.478016067294, 83.466766419271, 83.455516771246, + 83.444267123219, 83.433017475192, 83.421767827162, 83.410518179132, 83.399268531100, 83.388018883066, + 83.376769235031, 83.365519586995, 83.354269938957, 83.343020290918, 83.331770642878, 83.320520994836, + 83.309271346793, 83.298021698748, 83.286772050702, 83.275522402655, 83.264272754606, 83.253023106557, + 83.241773458505, 83.230523810453, 83.219274162399, 83.208024514344, 83.196774866287, 83.185525218230, + 83.174275570171, 83.163025922110, 83.151776274049, 83.140526625986, 83.129276977922, 83.118027329857, + 83.106777681790, 83.095528033722, 83.084278385653, 83.073028737583, 83.061779089512, 83.050529441439, + 83.039279793365, 83.028030145290, 83.016780497214, 83.005530849136, 82.994281201058, 82.983031552978, + 82.971781904897, 82.960532256814, 82.949282608731, 82.938032960647, 82.926783312561, 82.915533664474, + 82.904284016386, 82.893034368297, 82.881784720207, 82.870535072115, 82.859285424023, 82.848035775929, + 82.836786127835, 82.825536479739, 82.814286831642, 82.803037183544, 82.791787535445, 82.780537887345, + 82.769288239244, 82.758038591141, 82.746788943038, 82.735539294933, 82.724289646828, 82.713039998721, + 82.701790350614, 82.690540702505, 82.679291054396, 82.668041406285, 82.656791758173, 82.645542110060, + 82.634292461947, 82.623042813832, 82.611793165716, 82.600543517599, 82.589293869481, 82.578044221362, + 82.566794573243, 82.555544925122, 82.544295277000, 82.533045628877, 82.521795980754, 82.510546332629, + 82.499296684503, 82.488047036377, 82.476797388249, 82.465547740120, 82.454298091991, 82.443048443860, + 82.431798795729, 82.420549147597, 82.409299499464, 82.398049851329, 82.386800203194, 82.375550555058, + 82.364300906921, 82.353051258784, 82.341801610645, 82.330551962505, 82.319302314365, 82.308052666223, + 82.296803018081, 82.285553369938, 82.274303721793, 82.263054073648, 82.251804425503, 82.240554777356, + 82.229305129208, 82.218055481060, 82.206805832910, 82.195556184760, 82.184306536609, 82.173056888457, + 82.161807240305, 82.150557592151, 82.139307943997, 82.128058295841, 82.116808647685, 82.105558999528, + 82.094309351371, 82.083059703212, 82.071810055053, 82.060560406893, 82.049310758732, 82.038061110570, + 82.026811462407, 82.015561814244, 82.004312166079, 81.993062517914, 81.981812869749, 81.970563221582, + 81.959313573415, 81.948063925247, 81.936814277078, 81.925564628908, 81.914314980738, 81.903065332566, + 81.891815684394, 81.880566036222, 81.869316388048, 81.858066739874, 81.846817091699, 81.835567443523, + 81.824317795346, 81.813068147169, 81.801818498991, 81.790568850812, 81.779319202633, 81.768069554453, + 81.756819906272, 81.745570258090, 81.734320609908, 81.723070961725, 81.711821313541, 81.700571665356, + 81.689322017171, 81.678072368985, 81.666822720799, 81.655573072611, 81.644323424423, 81.633073776235, + 81.621824128045, 81.610574479855, 81.599324831664, 81.588075183473, 81.576825535281, 81.565575887088, + 81.554326238894, 81.543076590700, 81.531826942505, 81.520577294310, 81.509327646113, 81.498077997917, + 81.486828349719, 81.475578701521, 81.464329053322, 81.453079405123, 81.441829756922, 81.430580108722, + 81.419330460520, 81.408080812318, 81.396831164115, 81.385581515912, 81.374331867708, 81.363082219503, + 81.351832571298, 81.340582923092, 81.329333274886, 81.318083626679, 81.306833978471, 81.295584330263, + 81.284334682054, 81.273085033844, 81.261835385634, 81.250585737423, 81.239336089212, 81.228086441000, + 81.216836792787, 81.205587144574, 81.194337496360, 81.183087848146, 81.171838199931, 81.160588551715, + 81.149338903499, 81.138089255282, 81.126839607065, 81.115589958847, 81.104340310628, 81.093090662409, + 81.081841014190, 81.070591365969, 81.059341717749, 81.048092069527, 81.036842421305, 81.025592773083, + 81.014343124860, 81.003093476636, 80.991843828412, 80.980594180187, 80.969344531962, 80.958094883736, + 80.946845235510, 80.935595587283, 80.924345939056, 80.913096290828, 80.901846642599, 80.890596994370, + 80.879347346140, 80.868097697910, 80.856848049679, 80.845598401448, 80.834348753217, 80.823099104984, + 80.811849456751, 80.800599808518, 80.789350160284, 80.778100512050, 80.766850863815, 80.755601215580, + 80.744351567344, 80.733101919107, 80.721852270870, 80.710602622633, 80.699352974395, 80.688103326157, + 80.676853677918, 80.665604029678, 80.654354381438, 80.643104733198, 80.631855084957, 80.620605436715, + 80.609355788473, 80.598106140231, 80.586856491988, 80.575606843745, 80.564357195501, 80.553107547256, + 80.541857899012, 80.530608250766, 80.519358602521, 80.508108954274, 80.496859306028, 80.485609657780, + 80.474360009533, 80.463110361284, 80.451860713036, 80.440611064787, 80.429361416537, 80.418111768287, + 80.406862120037, 80.395612471786, 80.384362823534, 80.373113175282, 80.361863527030, 80.350613878777, + 80.339364230524, 80.328114582270, 80.316864934016, 80.305615285762, 80.294365637507, 80.283115989251, + 80.271866340995, 80.260616692739, 80.249367044482, 80.238117396225, 80.226867747968, 80.215618099709, + 80.204368451451, 80.193118803192, 80.181869154933, 80.170619506673, 80.159369858413, 80.148120210152, + 80.136870561891, 80.125620913629, 80.114371265367, 80.103121617105, 80.091871968842, 80.080622320579, + 80.069372672315, 80.058123024052, 80.046873375787, 80.035623727522, 80.024374079257, 80.013124430991, + 80.001874782725, 79.990625134459, 79.979375486192, 79.968125837925, 79.956876189657, 79.945626541389, + 79.934376893120, 79.923127244852, 79.911877596582, 79.900627948313, 79.889378300043, 79.878128651772, + 79.866879003501, 79.855629355230, 79.844379706958, 79.833130058686, 79.821880410414, 79.810630762141, + 79.799381113868, 79.788131465595, 79.776881817321, 79.765632169046, 79.754382520772, 79.743132872497, + 79.731883224221, 79.720633575945, 79.709383927669, 79.698134279393, 79.686884631116, 79.675634982838, + 79.664385334561, 79.653135686283, 79.641886038004, 79.630636389726, 79.619386741446, 79.608137093167, + 79.596887444887, 79.585637796607, 79.574388148326, 79.563138500045, 79.551888851764, 79.540639203482, + 79.529389555200, 79.518139906918, 79.506890258635, 79.495640610352, 79.484390962069, 79.473141313785, + 79.461891665501, 79.450642017217, 79.439392368932, 79.428142720647, 79.416893072361, 79.405643424075, + 79.394393775789, 79.383144127503, 79.371894479216, 79.360644830929, 79.349395182641, 79.338145534353, + 79.326895886065, 79.315646237777, 79.304396589488, 79.293146941199, 79.281897292909, 79.270647644619, + 79.259397996329, 79.248148348038, 79.236898699748, 79.225649051457, 79.214399403165, 79.203149754873, + 79.191900106581, 79.180650458289, 79.169400809996, 79.158151161703, 79.146901513409, 79.135651865116, + 79.124402216822, 79.113152568527, 79.101902920233, 79.090653271938, 79.079403623642, 79.068153975347, + 79.056904327051, 79.045654678755, 79.034405030458, 79.023155382161, 79.011905733864, 79.000656085567, + 78.989406437269, 78.978156788971, 78.966907140672, 78.955657492374, 78.944407844075, 78.933158195776, + 78.921908547476, 78.910658899176, 78.899409250876, 78.888159602576, 78.876909954275, 78.865660305974, + 78.854410657672, 78.843161009371, 78.831911361069, 78.820661712767, 78.809412064464, 78.798162416161, + 78.786912767858, 78.775663119555, 78.764413471251, 78.753163822947, 78.741914174643, 78.730664526338, + 78.719414878034, 78.708165229729, 78.696915581423, 78.685665933118, 78.674416284812, 78.663166636505, + 78.651916988199, 78.640667339892, 78.629417691585, 78.618168043278, 78.606918394970, 78.595668746662, + 78.584419098354, 78.573169450046, 78.561919801737, 78.550670153428, 78.539420505119, 78.528170856809, + 78.516921208500, 78.505671560190, 78.494421911879, 78.483172263569, 78.471922615258, 78.460672966947, + 78.449423318636, 78.438173670324, 78.426924022012, 78.415674373700, 78.404424725387, 78.393175077075, + 78.381925428762, 78.370675780449, 78.359426132135, 78.348176483822, 78.336926835508, 78.325677187193, + 78.314427538879, 78.303177890564, 78.291928242249, 78.280678593934, 78.269428945619, 78.258179297303, + 78.246929648987, 78.235680000671, 78.224430352354, 78.213180704037, 78.201931055720, 78.190681407403, + 78.179431759086, 78.168182110768, 78.156932462450, 78.145682814132, 78.134433165813, 78.123183517495, + 78.111933869176, 78.100684220857, 78.089434572537, 78.078184924218, 78.066935275898, 78.055685627578, + 78.044435979257, 78.033186330937, 78.021936682616, 78.010687034295, 77.999437385973, 77.988187737652, + 77.976938089330, 77.965688441008, 77.954438792686, 77.943189144363, 77.931939496040, 77.920689847718, + 77.909440199394, 77.898190551071, 77.886940902747, 77.875691254423, 77.864441606099, 77.853191957775, + 77.841942309451, 77.830692661126, 77.819443012801, 77.808193364476, 77.796943716150, 77.785694067824, + 77.774444419499, 77.763194771172, 77.751945122846, 77.740695474520, 77.729445826193, 77.718196177866, + 77.706946529539, 77.695696881211, 77.684447232884, 77.673197584556, 77.661947936228, 77.650698287899, + 77.639448639571, 77.628198991242, 77.616949342913, 77.605699694584, 77.594450046255, 77.583200397925, + 77.571950749595, 77.560701101265, 77.549451452935, 77.538201804605, 77.526952156274, 77.515702507943, + 77.504452859612, 77.493203211281, 77.481953562949, 77.470703914618, 77.459454266286, 77.448204617954, + 77.436954969621, 77.425705321289, 77.414455672956, 77.403206024623, 77.391956376290, 77.380706727957, + 77.369457079623, 77.358207431290, 77.346957782956, 77.335708134622, 77.324458486287, 77.313208837953, + 77.301959189618, 77.290709541283, 77.279459892948, 77.268210244613, 77.256960596277, 77.245710947942, + 77.234461299606, 77.223211651270, 77.211962002933, 77.200712354597, 77.189462706260, 77.178213057923, + 77.166963409586, 77.155713761249, 77.144464112912, 77.133214464574, 77.121964816236, 77.110715167898, + 77.099465519560, 77.088215871222, 77.076966222883, 77.065716574544, 77.054466926205, 77.043217277866, + 77.031967629527, 77.020717981187, 77.009468332848, 76.998218684508, 76.986969036168, 76.975719387827, + 76.964469739487, 76.953220091146, 76.941970442806, 76.930720794465, 76.919471146123, 76.908221497782, + 76.896971849441, 76.885722201099, 76.874472552757, 76.863222904415, 76.851973256073, 76.840723607730, + 76.829473959388, 76.818224311045, 76.806974662702, 76.795725014359, 76.784475366016, 76.773225717672, + 76.761976069328, 76.750726420985, 76.739476772641, 76.728227124296, 76.716977475952, 76.705727827607, + 76.694478179263, 76.683228530918, 76.671978882573, 76.660729234228, 76.649479585882, 76.638229937537, + 76.626980289191, 76.615730640845, 76.604480992499, 76.593231344153, 76.581981695806, 76.570732047460, + 76.559482399113, 76.548232750766, 76.536983102419, 76.525733454072, 76.514483805724, 76.503234157377, + 76.491984509029, 76.480734860681, 76.469485212333, 76.458235563985, 76.446985915637, 76.435736267288, + 76.424486618939, 76.413236970590, 76.401987322241, 76.390737673892, 76.379488025543, 76.368238377193, + 76.356988728844, 76.345739080494, 76.334489432144, 76.323239783794, 76.311990135443, 76.300740487093, + 76.289490838742, 76.278241190391, 76.266991542041, 76.255741893689, 76.244492245338, 76.233242596987, + 76.221992948635, 76.210743300283, 76.199493651932, 76.188244003580, 76.176994355227, 76.165744706875, + 76.154495058523, 76.143245410170, 76.131995761817, 76.120746113464, 76.109496465111, 76.098246816758, + 76.086997168404, 76.075747520051, 76.064497871697, 76.053248223343, 76.041998574989, 76.030748926635, + 76.019499278281, 76.008249629926, 75.996999981572, 75.985750333217, 75.974500684862, 75.963251036507, + 75.952001388152, 75.940751739796, 75.929502091441, 75.918252443085, 75.907002794730, 75.895753146374, + 75.884503498018, 75.873253849661, 75.862004201305, 75.850754552949, 75.839504904592, 75.828255256235, + 75.817005607878, 75.805755959521, 75.794506311164, 75.783256662807, 75.772007014449, 75.760757366091, + 75.749507717734, 75.738258069376, 75.727008421018, 75.715758772660, 75.704509124301, 75.693259475943, + 75.682009827584, 75.670760179225, 75.659510530866, 75.648260882507, 75.637011234148, 75.625761585789, + 75.614511937430, 75.603262289070, 75.592012640710, 75.580762992350, 75.569513343991, 75.558263695630, + 75.547014047270, 75.535764398910, 75.524514750549, 75.513265102189, 75.502015453828, 75.490765805467, + 75.479516157106, 75.468266508745, 75.457016860383, 75.445767212022, 75.434517563660, 75.423267915299, + 75.412018266937, 75.400768618575, 75.389518970213, 75.378269321851, 75.367019673488, 75.355770025126, + 75.344520376763, 75.333270728400, 75.322021080037, 75.310771431674, 75.299521783311, 75.288272134948, + 75.277022486585, 75.265772838221, 75.254523189858, 75.243273541494, 75.232023893130, 75.220774244766, + 75.209524596402, 75.198274948037, 75.187025299673, 75.175775651309, 75.164526002944, 75.153276354579, + 75.142026706214, 75.130777057849, 75.119527409484, 75.108277761119, 75.097028112753, 75.085778464388, + 75.074528816022, 75.063279167657, 75.052029519291, 75.040779870925, 75.029530222559, 75.018280574192, + 75.007030925826, 74.995781277460, 74.984531629093, 74.973281980726, 74.962032332359, 74.950782683992, + 74.939533035625, 74.928283387258, 74.917033738891, 74.905784090523, 74.894534442156, 74.883284793788, + 74.872035145420, 74.860785497053, 74.849535848685, 74.838286200316, 74.827036551948, 74.815786903580, + 74.804537255211, 74.793287606843, 74.782037958474, 74.770788310105, 74.759538661736, 74.748289013367, + 74.737039364998, 74.725789716629, 74.714540068259, 74.703290419890, 74.692040771520, 74.680791123150, + 74.669541474781, 74.658291826411, 74.647042178041, 74.635792529670, 74.624542881300, 74.613293232930, + 74.602043584559, 74.590793936189, 74.579544287818, 74.568294639447, 74.557044991076, 74.545795342705, + 74.534545694334, 74.523296045962, 74.512046397591, 74.500796749219, 74.489547100848, 74.478297452476, + 74.467047804104, 74.455798155732, 74.444548507360, 74.433298858988, 74.422049210616, 74.410799562243, + 74.399549913871, 74.388300265498, 74.377050617126, 74.365800968753, 74.354551320380, 74.343301672007, + 74.332052023634, 74.320802375261, 74.309552726887, 74.298303078514, 74.287053430140, 74.275803781767, + 74.264554133393, 74.253304485019, 74.242054836645, 74.230805188271, 74.219555539897, 74.208305891523, + 74.197056243148, 74.185806594774, 74.174556946399, 74.163307298024, 74.152057649650, 74.140808001275, + 74.129558352900, 74.118308704525, 74.107059056150, 74.095809407774, 74.084559759399, 74.073310111023, + 74.062060462648, 74.050810814272, 74.039561165896, 74.028311517520, 74.017061869144, 74.005812220768, + 73.994562572392, 73.983312924016, 73.972063275639, 73.960813627263, 73.949563978886, 73.938314330510, + 73.927064682133, 73.915815033756, 73.904565385379, 73.893315737002, 73.882066088625, 73.870816440248, + 73.859566791870, 73.848317143493, 73.837067495115, 73.825817846738, 73.814568198360, 73.803318549982, + 73.792068901604, 73.780819253226, 73.769569604848, 73.758319956470, 73.747070308091, 73.735820659713, + 73.724571011334, 73.713321362956, 73.702071714577, 73.690822066198, 73.679572417819, 73.668322769440, + 73.657073121061, 73.645823472682, 73.634573824303, 73.623324175924, 73.612074527544, 73.600824879165, + 73.589575230785, 73.578325582405, 73.567075934025, 73.555826285646, 73.544576637266, 73.533326988885, + 73.522077340505, 73.510827692125, 73.499578043745, 73.488328395364, 73.477078746984, 73.465829098603, + 73.454579450222, 73.443329801842, 73.432080153461, 73.420830505080, 73.409580856699, 73.398331208318, + 73.387081559936, 73.375831911555, 73.364582263174, 73.353332614792, 73.342082966410, 73.330833318029, + 73.319583669647, 73.308334021265, 73.297084372883, 73.285834724501, 73.274585076119, 73.263335427737, + 73.252085779354, 73.240836130972, 73.229586482590, 73.218336834207, 73.207087185824, 73.195837537442, + 73.184587889059, 73.173338240676, 73.162088592293, 73.150838943910, 73.139589295527, 73.128339647144, + 73.117089998760, 73.105840350377, 73.094590701993, 73.083341053610, 73.072091405226, 73.060841756842, + 73.049592108459, 73.038342460075, 73.027092811691, 73.015843163307, 73.004593514922, 72.993343866538, + 72.982094218154, 72.970844569769, 72.959594921385, 72.948345273000, 72.937095624616, 72.925845976231, + 72.914596327846, 72.903346679461, 72.892097031076, 72.880847382691, 72.869597734306, 72.858348085921, + 72.847098437536, 72.835848789150, 72.824599140765, 72.813349492379, 72.802099843994, 72.790850195608, + 72.779600547222, 72.768350898836, 72.757101250450, 72.745851602064, 72.734601953678, 72.723352305292, + 72.712102656906, 72.700853008520, 72.689603360133, 72.678353711747, 72.667104063360, 72.655854414973, + 72.644604766587, 72.633355118200, 72.622105469813, 72.610855821426, 72.599606173039, 72.588356524652, + 72.577106876265, 72.565857227878, 72.554607579490, 72.543357931103, 72.532108282715, 72.520858634328, + 72.509608985940, 72.498359337552, 72.487109689165, 72.475860040777, 72.464610392389, 72.453360744001, + 72.442111095613, 72.430861447224, 72.419611798836, 72.408362150448, 72.397112502060, 72.385862853671, + 72.374613205283, 72.363363556894, 72.352113908505, 72.340864260116, 72.329614611728, 72.318364963339, + 72.307115314950, 72.295865666561, 72.284616018172, 72.273366369782, 72.262116721393, 72.250867073004, + 72.239617424614, 72.228367776225, 72.217118127835, 72.205868479446, 72.194618831056, 72.183369182666, + 72.172119534276, 72.160869885886, 72.149620237496, 72.138370589106, 72.127120940716, 72.115871292326, + 72.104621643936, 72.093371995545, 72.082122347155, 72.070872698764, 72.059623050374, 72.048373401983, + 72.037123753593, 72.025874105202, 72.014624456811, 72.003374808420, 71.992125160029, 71.980875511638, + 71.969625863247, 71.958376214856, 71.947126566464, 71.935876918073, 71.924627269682, 71.913377621290, + 71.902127972899, 71.890878324507, 71.879628676115, 71.868379027724, 71.857129379332, 71.845879730940, + 71.834630082548, 71.823380434156, 71.812130785764, 71.800881137372, 71.789631488980, 71.778381840587, + 71.767132192195, 71.755882543803, 71.744632895410, 71.733383247018, 71.722133598625, 71.710883950232, + 71.699634301840, 71.688384653447, 71.677135005054, 71.665885356661, 71.654635708268, 71.643386059875, + 71.632136411482, 71.620886763088, 71.609637114695, 71.598387466302, 71.587137817908, 71.575888169515, + 71.564638521121, 71.553388872728, 71.542139224334, 71.530889575941, 71.519639927547, 71.508390279153, + 71.497140630759, 71.485890982365, 71.474641333971, 71.463391685577, 71.452142037183, 71.440892388788, + 71.429642740394, 71.418393092000, 71.407143443605, 71.395893795211, 71.384644146816, 71.373394498422, + 71.362144850027, 71.350895201632, 71.339645553237, 71.328395904843, 71.317146256448, 71.305896608053, + 71.294646959658, 71.283397311263, 71.272147662867, 71.260898014472, 71.249648366077, 71.238398717681, + 71.227149069286, 71.215899420891, 71.204649772495, 71.193400124099, 71.182150475704, 71.170900827308, + 71.159651178912, 71.148401530516, 71.137151882120, 71.125902233725, 71.114652585328, 71.103402936932, + 71.092153288536, 71.080903640140, 71.069653991744, 71.058404343347, 71.047154694951, 71.035905046555, + 71.024655398158, 71.013405749762, 71.002156101365, 70.990906452968, 70.979656804571, 70.968407156175, + 70.957157507778, 70.945907859381, 70.934658210984, 70.923408562587, 70.912158914190, 70.900909265793, + 70.889659617395, 70.878409968998, 70.867160320601, 70.855910672203, 70.844661023806, 70.833411375409, + 70.822161727011, 70.810912078613, 70.799662430216, 70.788412781818, 70.777163133420, 70.765913485022, + 70.754663836624, 70.743414188226, 70.732164539828, 70.720914891430, 70.709665243032, 70.698415594634, + 70.687165946236, 70.675916297837, 70.664666649439, 70.653417001041, 70.642167352642, 70.630917704244, + 70.619668055845, 70.608418407447, 70.597168759048, 70.585919110649, 70.574669462250, 70.563419813851, + 70.552170165453, 70.540920517054, 70.529670868655, 70.518421220255, 70.507171571856, 70.495921923457, + 70.484672275058, 70.473422626659, 70.462172978259, 70.450923329860, 70.439673681460, 70.428424033061, + 70.417174384661, 70.405924736262, 70.394675087862, 70.383425439462, 70.372175791063, 70.360926142663, + 70.349676494263, 70.338426845863, 70.327177197463, 70.315927549063, 70.304677900663, 70.293428252263, + 70.282178603862, 70.270928955462, 70.259679307062, 70.248429658661, 70.237180010261, 70.225930361861, + 70.214680713460, 70.203431065059, 70.192181416659, 70.180931768258, 70.169682119857, 70.158432471457, + 70.147182823056, 70.135933174655, 70.124683526254, 70.113433877853, 70.102184229452, 70.090934581051, + 70.079684932650, 70.068435284248, 70.057185635847, 70.045935987446, 70.034686339045, 70.023436690643, + 70.012187042242, 70.000937393840, 69.989687745439, 69.978438097037, 69.967188448635, 69.955938800234, + 69.944689151832, 69.933439503430, 69.922189855028, 69.910940206626, 69.899690558224, 69.888440909822, + 69.877191261420, 69.865941613018, 69.854691964616, 69.843442316214, 69.832192667812, 69.820943019409, + 69.809693371007, 69.798443722605, 69.787194074202, 69.775944425800, 69.764694777397, 69.753445128995, + 69.742195480592, 69.730945832189, 69.719696183786, 69.708446535384, 69.697196886981, 69.685947238578, + 69.674697590175, 69.663447941772, 69.652198293369, 69.640948644966, 69.629698996563, 69.618449348160, + 69.607199699756, 69.595950051353, 69.584700402950, 69.573450754546, 69.562201106143, 69.550951457740, + 69.539701809336, 69.528452160932, 69.517202512529, 69.505952864125, 69.494703215722, 69.483453567318, + 69.472203918914, 69.460954270510, 69.449704622106, 69.438454973702, 69.427205325298, 69.415955676894, + 69.404706028490, 69.393456380086, 69.382206731682, 69.370957083278, 69.359707434873, 69.348457786469, + 69.337208138065, 69.325958489660, 69.314708841256, 69.303459192851, 69.292209544447, 69.280959896042, + 69.269710247638, 69.258460599233, 69.247210950828, 69.235961302424, 69.224711654019, 69.213462005614, + 69.202212357209, 69.190962708804, 69.179713060399, 69.168463411994, 69.157213763589, 69.145964115184, + 69.134714466779, 69.123464818373, 69.112215169968, 69.100965521563, 69.089715873158, 69.078466224752, + 69.067216576347, 69.055966927941, 69.044717279536, 69.033467631130, 69.022217982725, 69.010968334319, + 68.999718685913, 68.988469037508, 68.977219389102, 68.965969740696, 68.954720092290, 68.943470443884, + 68.932220795478, 68.920971147072, 68.909721498666, 68.898471850260, 68.887222201854, 68.875972553448, + 68.864722905042, 68.853473256635, 68.842223608229, 68.830973959823, 68.819724311416, 68.808474663010, + 68.797225014603, 68.785975366197, 68.774725717790, 68.763476069384, 68.752226420977, 68.740976772570, + 68.729727124164, 68.718477475757, 68.707227827350, 68.695978178943, 68.684728530536, 68.673478882129, + 68.662229233722, 68.650979585315, 68.639729936908, 68.628480288501, 68.617230640094, 68.605980991687, + 68.594731343280, 68.583481694872, 68.572232046465, 68.560982398058, 68.549732749650, 68.538483101243, + 68.527233452835, 68.515983804428, 68.504734156020, 68.493484507613, 68.482234859205, 68.470985210797, + 68.459735562390, 68.448485913982, 68.437236265574, 68.425986617166, 68.414736968758, 68.403487320350, + 68.392237671942, 68.380988023534, 68.369738375126, 68.358488726718, 68.347239078310, 68.335989429902, + 68.324739781494, 68.313490133086, 68.302240484677, 68.290990836269, 68.279741187861, 68.268491539452, + 68.257241891044, 68.245992242635, 68.234742594227, 68.223492945818, 68.212243297410, 68.200993649001, + 68.189744000592, 68.178494352184, 68.167244703775, 68.155995055366, 68.144745406957, 68.133495758548, + 68.122246110139, 68.110996461731, 68.099746813322, 68.088497164913, 68.077247516503, 68.065997868094, + 68.054748219685, 68.043498571276, 68.032248922867, 68.020999274458, 68.009749626048, 67.998499977639, + 67.987250329230, 67.976000680820, 67.964751032411, 67.953501384001, 67.942251735592, 67.931002087182, + 67.919752438773, 67.908502790363, 67.897253141953, 67.886003493544, 67.874753845134, 67.863504196724, + 67.852254548314, 67.841004899904, 67.829755251494, 67.818505603085, 67.807255954675, 67.796006306265, + 67.784756657854, 67.773507009444, 67.762257361034, 67.751007712624, 67.739758064214, 67.728508415804, + 67.717258767393, 67.706009118983, 67.694759470573, 67.683509822162, 67.672260173752, 67.661010525342, + 67.649760876931, 67.638511228521, 67.627261580110, 67.616011931699, 67.604762283289, 67.593512634878, + 67.582262986467, 67.571013338057, 67.559763689646, 67.548514041235, 67.537264392824, 67.526014744413, + 67.514765096002, 67.503515447592, 67.492265799181, 67.481016150770, 67.469766502358, 67.458516853947, + 67.447267205536, 67.436017557125, 67.424767908714, 67.413518260303, 67.402268611891, 67.391018963480, + 67.379769315069, 67.368519666657, 67.357270018246, 67.346020369834, 67.334770721423, 67.323521073012, + 67.312271424600, 67.301021776188, 67.289772127777, 67.278522479365, 67.267272830953, 67.256023182542, + 67.244773534130, 67.233523885718, 67.222274237306, 67.211024588894, 67.199774940483, 67.188525292071, + 67.177275643659, 67.166025995247, 67.154776346835, 67.143526698423, 67.132277050010, 67.121027401598, + 67.109777753186, 67.098528104774, 67.087278456362, 67.076028807950, 67.064779159537, 67.053529511125, + 67.042279862713, 67.031030214300, 67.019780565888, 67.008530917475, 66.997281269063, 66.986031620650, + 66.974781972238, 66.963532323825, 66.952282675412, 66.941033027000, 66.929783378587, 66.918533730174, + 66.907284081762, 66.896034433349, 66.884784784936, 66.873535136523, 66.862285488110, 66.851035839697, + 66.839786191284, 66.828536542871, 66.817286894458, 66.806037246045, 66.794787597632, 66.783537949219, + 66.772288300806, 66.761038652393, 66.749789003979, 66.738539355566, 66.727289707153, 66.716040058740, + 66.704790410326, 66.693540761913, 66.682291113499, 66.671041465086, 66.659791816672, 66.648542168259, + 66.637292519845, 66.626042871432, 66.614793223018, 66.603543574605, 66.592293926191, 66.581044277777, + 66.569794629363, 66.558544980950, 66.547295332536, 66.536045684122, 66.524796035708, 66.513546387294, + 66.502296738880, 66.491047090466, 66.479797442053, 66.468547793638, 66.457298145224, 66.446048496810, + 66.434798848396, 66.423549199982, 66.412299551568, 66.401049903154, 66.389800254740, 66.378550606325, + 66.367300957911, 66.356051309497, 66.344801661082, 66.333552012668, 66.322302364254, 66.311052715839, + 66.299803067425, 66.288553419010, 66.277303770596, 66.266054122181, 66.254804473766, 66.243554825352, + 66.232305176937, 66.221055528522, 66.209805880108, 66.198556231693, 66.187306583278, 66.176056934863, + 66.164807286449, 66.153557638034, 66.142307989619, 66.131058341204, 66.119808692789, 66.108559044374, + 66.097309395959, 66.086059747544, 66.074810099129, 66.063560450714, 66.052310802299, 66.041061153883, + 66.029811505468, 66.018561857053, 66.007312208638, 65.996062560222, 65.984812911807, 65.973563263392, + 65.962313614976, 65.951063966561, 65.939814318146, 65.928564669730, 65.917315021315, 65.906065372899, + 65.894815724484, 65.883566076068, 65.872316427652, 65.861066779237, 65.849817130821, 65.838567482405, + 65.827317833990, 65.816068185574, 65.804818537158, 65.793568888742, 65.782319240327, 65.771069591911, + 65.759819943495, 65.748570295079, 65.737320646663, 65.726070998247, 65.714821349831, 65.703571701415, + 65.692322052999, 65.681072404583, 65.669822756167, 65.658573107751, 65.647323459334, 65.636073810918, + 65.624824162502, 65.613574514086, 65.602324865669, 65.591075217253, 65.579825568837, 65.568575920420, + 65.557326272004, 65.546076623588, 65.534826975171, 65.523577326755, 65.512327678338, 65.501078029922, + 65.489828381505, 65.478578733089, 65.467329084672, 65.456079436255, 65.444829787839, 65.433580139422, + 65.422330491005, 65.411080842588, 65.399831194172, 65.388581545755, 65.377331897338, 65.366082248921, + 65.354832600504, 65.343582952087, 65.332333303670, 65.321083655253, 65.309834006837, 65.298584358419, + 65.287334710002, 65.276085061585, 65.264835413168, 65.253585764751, 65.242336116334, 65.231086467917, + 65.219836819500, 65.208587171082, 65.197337522665, 65.186087874248, 65.174838225830, 65.163588577413, + 65.152338928996, 65.141089280578, 65.129839632161, 65.118589983744, 65.107340335326, 65.096090686909, + 65.084841038491, 65.073591390073, 65.062341741656, 65.051092093238, 65.039842444821, 65.028592796403, + 65.017343147985, 65.006093499568, 64.994843851150, 64.983594202732, 64.972344554314, 64.961094905897, + 64.949845257479, 64.938595609061, 64.927345960643, 64.916096312225, 64.904846663807, 64.893597015389, + 64.882347366971, 64.871097718553, 64.859848070135, 64.848598421717, 64.837348773299, 64.826099124881, + 64.814849476463, 64.803599828045, 64.792350179626, 64.781100531208, 64.769850882790, 64.758601234372, + 64.747351585953, 64.736101937535, 64.724852289117, 64.713602640698, 64.702352992280, 64.691103343861, + 64.679853695443, 64.668604047025, 64.657354398606, 64.646104750188, 64.634855101769, 64.623605453350, + 64.612355804932, 64.601106156513, 64.589856508095, 64.578606859676, 64.567357211257, 64.556107562839, + 64.544857914420, 64.533608266001, 64.522358617582, 64.511108969163, 64.499859320745, 64.488609672326, + 64.477360023907, 64.466110375488, 64.454860727069, 64.443611078650, 64.432361430231, 64.421111781812, + 64.409862133393, 64.398612484974, 64.387362836555, 64.376113188136, 64.364863539717, 64.353613891297, + 64.342364242878, 64.331114594459, 64.319864946040, 64.308615297621, 64.297365649201, 64.286116000782, + 64.274866352363, 64.263616703943, 64.252367055524, 64.241117407105, 64.229867758685, 64.218618110266, + 64.207368461846, 64.196118813427, 64.184869165007, 64.173619516588, 64.162369868168, 64.151120219749, + 64.139870571329, 64.128620922909, 64.117371274490, 64.106121626070, 64.094871977650, 64.083622329231, + 64.072372680811, 64.061123032391, 64.049873383971, 64.038623735552, 64.027374087132, 64.016124438712, + 64.004874790292, 63.993625141872, 63.982375493452, 63.971125845032, 63.959876196612, 63.948626548192, + 63.937376899772, 63.926127251352, 63.914877602932, 63.903627954512, 63.892378306092, 63.881128657672, + 63.869879009252, 63.858629360831, 63.847379712411, 63.836130063991, 63.824880415571, 63.813630767150, + 63.802381118730, 63.791131470310, 63.779881821890, 63.768632173469, 63.757382525049, 63.746132876628, + 63.734883228208, 63.723633579788, 63.712383931367, 63.701134282947, 63.689884634526, 63.678634986106, + 63.667385337685, 63.656135689264, 63.644886040844, 63.633636392423, 63.622386744002, 63.611137095582, + 63.599887447161, 63.588637798740, 63.577388150320, 63.566138501899, 63.554888853478, 63.543639205057, + 63.532389556636, 63.521139908216, 63.509890259795, 63.498640611374, 63.487390962953, 63.476141314532, + 63.464891666111, 63.453642017690, 63.442392369269, 63.431142720848, 63.419893072427, 63.408643424006, + 63.397393775585, 63.386144127164, 63.374894478743, 63.363644830322, 63.352395181900, 63.341145533479, + 63.329895885058, 63.318646236637, 63.307396588215, 63.296146939794, 63.284897291373, 63.273647642952, + 63.262397994530, 63.251148346109, 63.239898697688, 63.228649049266, 63.217399400845, 63.206149752423, + 63.194900104002, 63.183650455580, 63.172400807159, 63.161151158737, 63.149901510316, 63.138651861894, + 63.127402213473, 63.116152565051, 63.104902916629, 63.093653268208, 63.082403619786, 63.071153971364, + 63.059904322943, 63.048654674521, 63.037405026099, 63.026155377677, 63.014905729255, 63.003656080834, + 62.992406432412, 62.981156783990, 62.969907135568, 62.958657487146, 62.947407838724, 62.936158190302, + 62.924908541880, 62.913658893458, 62.902409245036, 62.891159596614, 62.879909948192, 62.868660299770, + 62.857410651348, 62.846161002926, 62.834911354504, 62.823661706082, 62.812412057660, 62.801162409237, + 62.789912760815, 62.778663112393, 62.767413463971, 62.756163815548, 62.744914167126, 62.733664518704, + 62.722414870282, 62.711165221859, 62.699915573437, 62.688665925014, 62.677416276592, 62.666166628170, + 62.654916979747, 62.643667331325, 62.632417682902, 62.621168034480, 62.609918386057, 62.598668737635, + 62.587419089212, 62.576169440790, 62.564919792367, 62.553670143944, 62.542420495522, 62.531170847099, + 62.519921198676, 62.508671550254, 62.497421901831, 62.486172253408, 62.474922604985, 62.463672956563, + 62.452423308140, 62.441173659717, 62.429924011294, 62.418674362871, 62.407424714448, 62.396175066026, + 62.384925417603, 62.373675769180, 62.362426120757, 62.351176472334, 62.339926823911, 62.328677175488, + 62.317427527065, 62.306177878642, 62.294928230219, 62.283678581796, 62.272428933372, 62.261179284949, + 62.249929636526, 62.238679988103, 62.227430339680, 62.216180691257, 62.204931042833, 62.193681394410, + 62.182431745987, 62.171182097564, 62.159932449140, 62.148682800717, 62.137433152294, 62.126183503870, + 62.114933855447, 62.103684207024, 62.092434558600, 62.081184910177, 62.069935261753, 62.058685613330, + 62.047435964906, 62.036186316483, 62.024936668059, 62.013687019636, 62.002437371212, 61.991187722789, + 61.979938074365, 61.968688425942, 61.957438777518, 61.946189129094, 61.934939480671, 61.923689832247, + 61.912440183823, 61.901190535400, 61.889940886976, 61.878691238552, 61.867441590128, 61.856191941705, + 61.844942293281, 61.833692644857, 61.822442996433, 61.811193348009, 61.799943699585, 61.788694051161, + 61.777444402737, 61.766194754314, 61.754945105890, 61.743695457466, 61.732445809042, 61.721196160618, + 61.709946512194, 61.698696863770, 61.687447215346, 61.676197566921, 61.664947918497, 61.653698270073, + 61.642448621649, 61.631198973225, 61.619949324801, 61.608699676377, 61.597450027952, 61.586200379528, + 61.574950731104, 61.563701082680, 61.552451434255, 61.541201785831, 61.529952137407, 61.518702488982, + 61.507452840558, 61.496203192134, 61.484953543709, 61.473703895285, 61.462454246861, 61.451204598436, + 61.439954950012, 61.428705301587, 61.417455653163, 61.406206004738, 61.394956356314, 61.383706707889, + 61.372457059465, 61.361207411040, 61.349957762616, 61.338708114191, 61.327458465766, 61.316208817342, + 61.304959168917, 61.293709520492, 61.282459872068, 61.271210223643, 61.259960575218, 61.248710926794, + 61.237461278369, 61.226211629944, 61.214961981519, 61.203712333094, 61.192462684670, 61.181213036245, + 61.169963387820, 61.158713739395, 61.147464090970, 61.136214442545, 61.124964794120, 61.113715145695, + 61.102465497270, 61.091215848845, 61.079966200420, 61.068716551995, 61.057466903570, 61.046217255145, + 61.034967606720, 61.023717958295, 61.012468309870, 61.001218661445, 60.989969013020, 60.978719364595, + 60.967469716170, 60.956220067744, 60.944970419319, 60.933720770894, 60.922471122469, 60.911221474044, + 60.899971825618, 60.888722177193, 60.877472528768, 60.866222880342, 60.854973231917, 60.843723583492, + 60.832473935066, 60.821224286641, 60.809974638216, 60.798724989790, 60.787475341365, 60.776225692939, + 60.764976044514, 60.753726396089, 60.742476747663, 60.731227099238, 60.719977450812, 60.708727802386, + 60.697478153961, 60.686228505535, 60.674978857110, 60.663729208684, 60.652479560259, 60.641229911833, + 60.629980263407, 60.618730614982, 60.607480966556, 60.596231318130, 60.584981669705, 60.573732021279, + 60.562482372853, 60.551232724427, 60.539983076002, 60.528733427576, 60.517483779150, 60.506234130724, + 60.494984482298, 60.483734833873, 60.472485185447, 60.461235537021, 60.449985888595, 60.438736240169, + 60.427486591743, 60.416236943317, 60.404987294891, 60.393737646465, 60.382487998039, 60.371238349613, + 60.359988701187, 60.348739052761, 60.337489404335, 60.326239755909, 60.314990107483, 60.303740459057, + 60.292490810631, 60.281241162205, 60.269991513778, 60.258741865352, 60.247492216926, 60.236242568500, + 60.224992920074, 60.213743271647, 60.202493623221, 60.191243974795, 60.179994326369, 60.168744677942, + 60.157495029516, 60.146245381090, 60.134995732663, 60.123746084237, 60.112496435811, 60.101246787384, + 60.089997138958, 60.078747490532, 60.067497842105, 60.056248193679, 60.044998545252, 60.033748896826, + 60.022499248399, 60.011249599973, 59.999999951546, 59.988750303120, 59.977500654693, 59.966251006267, + 59.955001357840, 59.943751709414, 59.932502060987, 59.921252412560, 59.910002764134, 59.898753115707, + 59.887503467280, 59.876253818854, 59.865004170427, 59.853754522000, 59.842504873574, 59.831255225147, + 59.820005576720, 59.808755928293, 59.797506279867, 59.786256631440, 59.775006983013, 59.763757334586, + 59.752507686159, 59.741258037733, 59.730008389306, 59.718758740879, 59.707509092452, 59.696259444025, + 59.685009795598, 59.673760147171, 59.662510498744, 59.651260850317, 59.640011201890, 59.628761553463, + 59.617511905036, 59.606262256609, 59.595012608182, 59.583762959755, 59.572513311328, 59.561263662901, + 59.550014014474, 59.538764366047, 59.527514717620, 59.516265069193, 59.505015420765, 59.493765772338, + 59.482516123911, 59.471266475484, 59.460016827057, 59.448767178630, 59.437517530202, 59.426267881775, + 59.415018233348, 59.403768584920, 59.392518936493, 59.381269288066, 59.370019639639, 59.358769991211, + 59.347520342784, 59.336270694357, 59.325021045929, 59.313771397502, 59.302521749074, 59.291272100647, + 59.280022452220, 59.268772803792, 59.257523155365, 59.246273506937, 59.235023858510, 59.223774210082, + 59.212524561655, 59.201274913227, 59.190025264800, 59.178775616372, 59.167525967944, 59.156276319517, + 59.145026671089, 59.133777022662, 59.122527374234, 59.111277725806, 59.100028077379, 59.088778428951, + 59.077528780523, 59.066279132096, 59.055029483668, 59.043779835240, 59.032530186813, 59.021280538385, + 59.010030889957, 58.998781241529, 58.987531593101, 58.976281944674, 58.965032296246, 58.953782647818, + 58.942532999390, 58.931283350962, 58.920033702534, 58.908784054107, 58.897534405679, 58.886284757251, + 58.875035108823, 58.863785460395, 58.852535811967, 58.841286163539, 58.830036515111, 58.818786866683, + 58.807537218255, 58.796287569827, 58.785037921399, 58.773788272971, 58.762538624543, 58.751288976115, + 58.740039327687, 58.728789679259, 58.717540030831, 58.706290382402, 58.695040733974, 58.683791085546, + 58.672541437118, 58.661291788690, 58.650042140262, 58.638792491833, 58.627542843405, 58.616293194977, + 58.605043546549, 58.593793898120, 58.582544249692, 58.571294601264, 58.560044952836, 58.548795304407, + 58.537545655979, 58.526296007551, 58.515046359122, 58.503796710694, 58.492547062266, 58.481297413837, + 58.470047765409, 58.458798116980, 58.447548468552, 58.436298820124, 58.425049171695, 58.413799523267, + 58.402549874838, 58.391300226410, 58.380050577981, 58.368800929553, 58.357551281124, 58.346301632696, + 58.335051984267, 58.323802335839, 58.312552687410, 58.301303038981, 58.290053390553, 58.278803742124, + 58.267554093696, 58.256304445267, 58.245054796838, 58.233805148410, 58.222555499981, 58.211305851552, + 58.200056203124, 58.188806554695, 58.177556906266, 58.166307257837, 58.155057609409, 58.143807960980, + 58.132558312551, 58.121308664122, 58.110059015694, 58.098809367265, 58.087559718836, 58.076310070407, + 58.065060421978, 58.053810773549, 58.042561125120, 58.031311476692, 58.020061828263, 58.008812179834, + 57.997562531405, 57.986312882976, 57.975063234547, 57.963813586118, 57.952563937689, 57.941314289260, + 57.930064640831, 57.918814992402, 57.907565343973, 57.896315695544, 57.885066047115, 57.873816398686, + 57.862566750257, 57.851317101828, 57.840067453399, 57.828817804970, 57.817568156540, 57.806318508111, + 57.795068859682, 57.783819211253, 57.772569562824, 57.761319914395, 57.750070265965, 57.738820617536, + 57.727570969107, 57.716321320678, 57.705071672249, 57.693822023819, 57.682572375390, 57.671322726961, + 57.660073078532, 57.648823430102, 57.637573781673, 57.626324133244, 57.615074484814, 57.603824836385, + 57.592575187956, 57.581325539526, 57.570075891097, 57.558826242667, 57.547576594238, 57.536326945809, + 57.525077297379, 57.513827648950, 57.502578000520, 57.491328352091, 57.480078703661, 57.468829055232, + 57.457579406802, 57.446329758373, 57.435080109943, 57.423830461514, 57.412580813084, 57.401331164655, + 57.390081516225, 57.378831867796, 57.367582219366, 57.356332570936, 57.345082922507, 57.333833274077, + 57.322583625647, 57.311333977218, 57.300084328788, 57.288834680358, 57.277585031929, 57.266335383499, + 57.255085735069, 57.243836086640, 57.232586438210, 57.221336789780, 57.210087141350, 57.198837492921, + 57.187587844491, 57.176338196061, 57.165088547631, 57.153838899202, 57.142589250772, 57.131339602342, + 57.120089953912, 57.108840305482, 57.097590657052, 57.086341008622, 57.075091360193, 57.063841711763, + 57.052592063333, 57.041342414903, 57.030092766473, 57.018843118043, 57.007593469613, 56.996343821183, + 56.985094172753, 56.973844524323, 56.962594875893, 56.951345227463, 56.940095579033, 56.928845930603, + 56.917596282173, 56.906346633743, 56.895096985313, 56.883847336883, 56.872597688453, 56.861348040023, + 56.850098391592, 56.838848743162, 56.827599094732, 56.816349446302, 56.805099797872, 56.793850149442, + 56.782600501011, 56.771350852581, 56.760101204151, 56.748851555721, 56.737601907291, 56.726352258860, + 56.715102610430, 56.703852962000, 56.692603313570, 56.681353665139, 56.670104016709, 56.658854368279, + 56.647604719849, 56.636355071418, 56.625105422988, 56.613855774558, 56.602606126127, 56.591356477697, + 56.580106829266, 56.568857180836, 56.557607532406, 56.546357883975, 56.535108235545, 56.523858587114, + 56.512608938684, 56.501359290254, 56.490109641823, 56.478859993393, 56.467610344962, 56.456360696532, + 56.445111048101, 56.433861399671, 56.422611751240, 56.411362102810, 56.400112454379, 56.388862805948, + 56.377613157518, 56.366363509087, 56.355113860657, 56.343864212226, 56.332614563796, 56.321364915365, + 56.310115266934, 56.298865618504, 56.287615970073, 56.276366321642, 56.265116673212, 56.253867024781, + 56.242617376350, 56.231367727920, 56.220118079489, 56.208868431058, 56.197618782627, 56.186369134197, + 56.175119485766, 56.163869837335, 56.152620188904, 56.141370540474, 56.130120892043, 56.118871243612, + 56.107621595181, 56.096371946750, 56.085122298319, 56.073872649889, 56.062623001458, 56.051373353027, + 56.040123704596, 56.028874056165, 56.017624407734, 56.006374759303, 55.995125110872, 55.983875462441, + 55.972625814011, 55.961376165580, 55.950126517149, 55.938876868718, 55.927627220287, 55.916377571856, + 55.905127923425, 55.893878274994, 55.882628626563, 55.871378978132, 55.860129329701, 55.848879681270, + 55.837630032838, 55.826380384407, 55.815130735976, 55.803881087545, 55.792631439114, 55.781381790683, + 55.770132142252, 55.758882493821, 55.747632845390, 55.736383196958, 55.725133548527, 55.713883900096, + 55.702634251665, 55.691384603234, 55.680134954803, 55.668885306371, 55.657635657940, 55.646386009509, + 55.635136361078, 55.623886712646, 55.612637064215, 55.601387415784, 55.590137767353, 55.578888118921, + 55.567638470490, 55.556388822059, 55.545139173627, 55.533889525196, 55.522639876765, 55.511390228333, + 55.500140579902, 55.488890931471, 55.477641283039, 55.466391634608, 55.455141986176, 55.443892337745, + 55.432642689314, 55.421393040882, 55.410143392451, 55.398893744019, 55.387644095588, 55.376394447156, + 55.365144798725, 55.353895150293, 55.342645501862, 55.331395853430, 55.320146204999, 55.308896556567, + 55.297646908136, 55.286397259704, 55.275147611273, 55.263897962841, 55.252648314410, 55.241398665978, + 55.230149017546, 55.218899369115, 55.207649720683, 55.196400072252, 55.185150423820, 55.173900775388, + 55.162651126957, 55.151401478525, 55.140151830093, 55.128902181662, 55.117652533230, 55.106402884798, + 55.095153236367, 55.083903587935, 55.072653939503, 55.061404291071, 55.050154642640, 55.038904994208, + 55.027655345776, 55.016405697344, 55.005156048913, 54.993906400481, 54.982656752049, 54.971407103617, + 54.960157455185, 54.948907806754, 54.937658158322, 54.926408509890, 54.915158861458, 54.903909213026, + 54.892659564594, 54.881409916162, 54.870160267730, 54.858910619299, 54.847660970867, 54.836411322435, + 54.825161674003, 54.813912025571, 54.802662377139, 54.791412728707, 54.780163080275, 54.768913431843, + 54.757663783411, 54.746414134979, 54.735164486547, 54.723914838115, 54.712665189683, 54.701415541251, + 54.690165892819, 54.678916244387, 54.667666595955, 54.656416947523, 54.645167299091, 54.633917650659, + 54.622668002226, 54.611418353794, 54.600168705362, 54.588919056930, 54.577669408498, 54.566419760066, + 54.555170111634, 54.543920463202, 54.532670814769, 54.521421166337, 54.510171517905, 54.498921869473, + 54.487672221041, 54.476422572608, 54.465172924176, 54.453923275744, 54.442673627312, 54.431423978879, + 54.420174330447, 54.408924682015, 54.397675033583, 54.386425385150, 54.375175736718, 54.363926088286, + 54.352676439853, 54.341426791421, 54.330177142989, 54.318927494557, 54.307677846124, 54.296428197692, + 54.285178549259, 54.273928900827, 54.262679252395, 54.251429603962, 54.240179955530, 54.228930307097, + 54.217680658665, 54.206431010233, 54.195181361800, 54.183931713368, 54.172682064935, 54.161432416503, + 54.150182768070, 54.138933119638, 54.127683471205, 54.116433822773, 54.105184174340, 54.093934525908, + 54.082684877475, 54.071435229043, 54.060185580610, 54.048935932178, 54.037686283745, 54.026436635313, + 54.015186986880, 54.003937338448, 53.992687690015, 53.981438041582, 53.970188393150, 53.958938744717, + 53.947689096284, 53.936439447852, 53.925189799419, 53.913940150987, 53.902690502554, 53.891440854121, + 53.880191205689, 53.868941557256, 53.857691908823, 53.846442260391, 53.835192611958, 53.823942963525, + 53.812693315092, 53.801443666660, 53.790194018227, 53.778944369794, 53.767694721361, 53.756445072929, + 53.745195424496, 53.733945776063, 53.722696127630, 53.711446479197, 53.700196830765, 53.688947182332, + 53.677697533899, 53.666447885466, 53.655198237033, 53.643948588600, 53.632698940168, 53.621449291735, + 53.610199643302, 53.598949994869, 53.587700346436, 53.576450698003, 53.565201049570, 53.553951401137, + 53.542701752704, 53.531452104271, 53.520202455839, 53.508952807406, 53.497703158973, 53.486453510540, + 53.475203862107, 53.463954213674, 53.452704565241, 53.441454916808, 53.430205268375, 53.418955619942, + 53.407705971509, 53.396456323076, 53.385206674643, 53.373957026210, 53.362707377776, 53.351457729343, + 53.340208080910, 53.328958432477, 53.317708784044, 53.306459135611, 53.295209487178, 53.283959838745, + 53.272710190312, 53.261460541879, 53.250210893445, 53.238961245012, 53.227711596579, 53.216461948146, + 53.205212299713, 53.193962651280, 53.182713002846, 53.171463354413, 53.160213705980, 53.148964057547, + 53.137714409114, 53.126464760680, 53.115215112247, 53.103965463814, 53.092715815381, 53.081466166947, + 53.070216518514, 53.058966870081, 53.047717221648, 53.036467573214, 53.025217924781, 53.013968276348, + 53.002718627914, 52.991468979481, 52.980219331048, 52.968969682614, 52.957720034181, 52.946470385748, + 52.935220737314, 52.923971088881, 52.912721440448, 52.901471792014, 52.890222143581, 52.878972495147, + 52.867722846714, 52.856473198281, 52.845223549847, 52.833973901414, 52.822724252980, 52.811474604547, + 52.800224956113, 52.788975307680, 52.777725659246, 52.766476010813, 52.755226362379, 52.743976713946, + 52.732727065512, 52.721477417079, 52.710227768645, 52.698978120212, 52.687728471778, 52.676478823345, + 52.665229174911, 52.653979526478, 52.642729878044, 52.631480229611, 52.620230581177, 52.608980932743, + 52.597731284310, 52.586481635876, 52.575231987443, 52.563982339009, 52.552732690575, 52.541483042142, + 52.530233393708, 52.518983745274, 52.507734096841, 52.496484448407, 52.485234799973, 52.473985151540, + 52.462735503106, 52.451485854672, 52.440236206239, 52.428986557805, 52.417736909371, 52.406487260938, + 52.395237612504, 52.383987964070, 52.372738315636, 52.361488667203, 52.350239018769, 52.338989370335, + 52.327739721901, 52.316490073467, 52.305240425034, 52.293990776600, 52.282741128166, 52.271491479732, + 52.260241831298, 52.248992182865, 52.237742534431, 52.226492885997, 52.215243237563, 52.203993589129, + 52.192743940695, 52.181494292262, 52.170244643828, 52.158994995394, 52.147745346960, 52.136495698526, + 52.125246050092, 52.113996401658, 52.102746753224, 52.091497104790, 52.080247456356, 52.068997807922, + 52.057748159488, 52.046498511054, 52.035248862620, 52.023999214187, 52.012749565753, 52.001499917319, + 51.990250268885, 51.979000620451, 51.967750972017, 51.956501323583, 51.945251675148, 51.934002026714, + 51.922752378280, 51.911502729846, 51.900253081412, 51.889003432978, 51.877753784544, 51.866504136110, + 51.855254487676, 51.844004839242, 51.832755190808, 51.821505542374, 51.810255893940, 51.799006245505, + 51.787756597071, 51.776506948637, 51.765257300203, 51.754007651769, 51.742758003335, 51.731508354901, + 51.720258706466, 51.709009058032, 51.697759409598, 51.686509761164, 51.675260112730, 51.664010464295, + 51.652760815861, 51.641511167427, 51.630261518993, 51.619011870559, 51.607762222124, 51.596512573690, + 51.585262925256, 51.574013276822, 51.562763628387, 51.551513979953, 51.540264331519, 51.529014683084, + 51.517765034650, 51.506515386216, 51.495265737782, 51.484016089347, 51.472766440913, 51.461516792479, + 51.450267144044, 51.439017495610, 51.427767847176, 51.416518198741, 51.405268550307, 51.394018901872, + 51.382769253438, 51.371519605004, 51.360269956569, 51.349020308135, 51.337770659700, 51.326521011266, + 51.315271362832, 51.304021714397, 51.292772065963, 51.281522417528, 51.270272769094, 51.259023120659, + 51.247773472225, 51.236523823790, 51.225274175356, 51.214024526921, 51.202774878487, 51.191525230052, + 51.180275581618, 51.169025933183, 51.157776284749, 51.146526636314, 51.135276987880, 51.124027339445, + 51.112777691011, 51.101528042576, 51.090278394142, 51.079028745707, 51.067779097273, 51.056529448838, + 51.045279800403, 51.034030151969, 51.022780503534, 51.011530855100, 51.000281206665, 50.989031558230, + 50.977781909796, 50.966532261361, 50.955282612926, 50.944032964492, 50.932783316057, 50.921533667622, + 50.910284019188, 50.899034370753, 50.887784722318, 50.876535073884, 50.865285425449, 50.854035777014, + 50.842786128580, 50.831536480145, 50.820286831710, 50.809037183276, 50.797787534841, 50.786537886406, + 50.775288237971, 50.764038589537, 50.752788941102, 50.741539292667, 50.730289644232, 50.719039995797, + 50.707790347363, 50.696540698928, 50.685291050493, 50.674041402058, 50.662791753623, 50.651542105189, + 50.640292456754, 50.629042808319, 50.617793159884, 50.606543511449, 50.595293863014, 50.584044214580, + 50.572794566145, 50.561544917710, 50.550295269275, 50.539045620840, 50.527795972405, 50.516546323970, + 50.505296675535, 50.494047027100, 50.482797378666, 50.471547730231, 50.460298081796, 50.449048433361, + 50.437798784926, 50.426549136491, 50.415299488056, 50.404049839621, 50.392800191186, 50.381550542751, + 50.370300894316, 50.359051245881, 50.347801597446, 50.336551949011, 50.325302300576, 50.314052652141, + 50.302803003706, 50.291553355271, 50.280303706836, 50.269054058401, 50.257804409966, 50.246554761531, + 50.235305113096, 50.224055464661, 50.212805816226, 50.201556167791, 50.190306519355, 50.179056870920, + 50.167807222485, 50.156557574050, 50.145307925615, 50.134058277180, 50.122808628745, 50.111558980310, + 50.100309331875, 50.089059683439, 50.077810035004, 50.066560386569, 50.055310738134, 50.044061089699, + 50.032811441264, 50.021561792828, 50.010312144393, 49.999062495958, 49.987812847523, 49.976563199088, + 49.965313550653, 49.954063902217, 49.942814253782, 49.931564605347, 49.920314956912, 49.909065308476, + 49.897815660041, 49.886566011606, 49.875316363171, 49.864066714735, 49.852817066300, 49.841567417865, + 49.830317769430, 49.819068120994, 49.807818472559, 49.796568824124, 49.785319175688, 49.774069527253, + 49.762819878818, 49.751570230382, 49.740320581947, 49.729070933512, 49.717821285076, 49.706571636641, + 49.695321988206, 49.684072339770, 49.672822691335, 49.661573042900, 49.650323394464, 49.639073746029, + 49.627824097593, 49.616574449158, 49.605324800723, 49.594075152287, 49.582825503852, 49.571575855416, + 49.560326206981, 49.549076558545, 49.537826910110, 49.526577261675, 49.515327613239, 49.504077964804, + 49.492828316368, 49.481578667933, 49.470329019497, 49.459079371062, 49.447829722626, 49.436580074191, + 49.425330425755, 49.414080777320, 49.402831128884, 49.391581480449, 49.380331832013, 49.369082183578, + 49.357832535142, 49.346582886707, 49.335333238271, 49.324083589836, 49.312833941400, 49.301584292964, + 49.290334644529, 49.279084996093, 49.267835347658, 49.256585699222, 49.245336050787, 49.234086402351, + 49.222836753915, 49.211587105480, 49.200337457044, 49.189087808608, 49.177838160173, 49.166588511737, + 49.155338863302, 49.144089214866, 49.132839566430, 49.121589917995, 49.110340269559, 49.099090621123, + 49.087840972688, 49.076591324252, 49.065341675816, 49.054092027380, 49.042842378945, 49.031592730509, + 49.020343082073, 49.009093433638, 48.997843785202, 48.986594136766, 48.975344488330, 48.964094839895, + 48.952845191459, 48.941595543023, 48.930345894587, 48.919096246152, 48.907846597716, 48.896596949280, + 48.885347300844, 48.874097652409, 48.862848003973, 48.851598355537, 48.840348707101, 48.829099058665, + 48.817849410230, 48.806599761794, 48.795350113358, 48.784100464922, 48.772850816486, 48.761601168050, + 48.750351519615, 48.739101871179, 48.727852222743, 48.716602574307, 48.705352925871, 48.694103277435, + 48.682853628999, 48.671603980563, 48.660354332128, 48.649104683692, 48.637855035256, 48.626605386820, + 48.615355738384, 48.604106089948, 48.592856441512, 48.581606793076, 48.570357144640, 48.559107496204, + 48.547857847768, 48.536608199332, 48.525358550896, 48.514108902460, 48.502859254024, 48.491609605589, + 48.480359957153, 48.469110308717, 48.457860660281, 48.446611011845, 48.435361363409, 48.424111714973, + 48.412862066537, 48.401612418100, 48.390362769664, 48.379113121228, 48.367863472792, 48.356613824356, + 48.345364175920, 48.334114527484, 48.322864879048, 48.311615230612, 48.300365582176, 48.289115933740, + 48.277866285304, 48.266616636868, 48.255366988432, 48.244117339996, 48.232867691560, 48.221618043123, + 48.210368394687, 48.199118746251, 48.187869097815, 48.176619449379, 48.165369800943, 48.154120152507, + 48.142870504070, 48.131620855634, 48.120371207198, 48.109121558762, 48.097871910326, 48.086622261890, + 48.075372613453, 48.064122965017, 48.052873316581, 48.041623668145, 48.030374019709, 48.019124371273, + 48.007874722836, 47.996625074400, 47.985375425964, 47.974125777528, 47.962876129091, 47.951626480655, + 47.940376832219, 47.929127183783, 47.917877535346, 47.906627886910, 47.895378238474, 47.884128590038, + 47.872878941601, 47.861629293165, 47.850379644729, 47.839129996292, 47.827880347856, 47.816630699420, + 47.805381050984, 47.794131402547, 47.782881754111, 47.771632105675, 47.760382457238, 47.749132808802, + 47.737883160366, 47.726633511929, 47.715383863493, 47.704134215057, 47.692884566620, 47.681634918184, + 47.670385269747, 47.659135621311, 47.647885972875, 47.636636324438, 47.625386676002, 47.614137027566, + 47.602887379129, 47.591637730693, 47.580388082256, 47.569138433820, 47.557888785383, 47.546639136947, + 47.535389488511, 47.524139840074, 47.512890191638, 47.501640543201, 47.490390894765, 47.479141246328, + 47.467891597892, 47.456641949455, 47.445392301019, 47.434142652582, 47.422893004146, 47.411643355710, + 47.400393707273, 47.389144058837, 47.377894410400, 47.366644761963, 47.355395113527, 47.344145465090, + 47.332895816654, 47.321646168217, 47.310396519781, 47.299146871344, 47.287897222908, 47.276647574471, + 47.265397926035, 47.254148277598, 47.242898629162, 47.231648980725, 47.220399332288, 47.209149683852, + 47.197900035415, 47.186650386979, 47.175400738542, 47.164151090105, 47.152901441669, 47.141651793232, + 47.130402144796, 47.119152496359, 47.107902847922, 47.096653199486, 47.085403551049, 47.074153902612, + 47.062904254176, 47.051654605739, 47.040404957302, 47.029155308866, 47.017905660429, 47.006656011993, + 46.995406363556, 46.984156715119, 46.972907066682, 46.961657418246, 46.950407769809, 46.939158121372, + 46.927908472936, 46.916658824499, 46.905409176062, 46.894159527626, 46.882909879189, 46.871660230752, + 46.860410582315, 46.849160933879, 46.837911285442, 46.826661637005, 46.815411988568, 46.804162340132, + 46.792912691695, 46.781663043258, 46.770413394821, 46.759163746384, 46.747914097948, 46.736664449511, + 46.725414801074, 46.714165152637, 46.702915504201, 46.691665855764, 46.680416207327, 46.669166558890, + 46.657916910453, 46.646667262016, 46.635417613580, 46.624167965143, 46.612918316706, 46.601668668269, + 46.590419019832, 46.579169371395, 46.567919722958, 46.556670074522, 46.545420426085, 46.534170777648, + 46.522921129211, 46.511671480774, 46.500421832337, 46.489172183900, 46.477922535463, 46.466672887026, + 46.455423238590, 46.444173590153, 46.432923941716, 46.421674293279, 46.410424644842, 46.399174996405, + 46.387925347968, 46.376675699531, 46.365426051094, 46.354176402657, 46.342926754220, 46.331677105783, + 46.320427457346, 46.309177808909, 46.297928160472, 46.286678512035, 46.275428863598, 46.264179215161, + 46.252929566724, 46.241679918287, 46.230430269850, 46.219180621413, 46.207930972976, 46.196681324539, + 46.185431676102, 46.174182027665, 46.162932379228, 46.151682730791, 46.140433082354, 46.129183433917, + 46.117933785480, 46.106684137043, 46.095434488606, 46.084184840169, 46.072935191732, 46.061685543295, + 46.050435894858, 46.039186246421, 46.027936597983, 46.016686949546, 46.005437301109, 45.994187652672, + 45.982938004235, 45.971688355798, 45.960438707361, 45.949189058924, 45.937939410487, 45.926689762049, + 45.915440113612, 45.904190465175, 45.892940816738, 45.881691168301, 45.870441519864, 45.859191871427, + 45.847942222989, 45.836692574552, 45.825442926115, 45.814193277678, 45.802943629241, 45.791693980804, + 45.780444332366, 45.769194683929, 45.757945035492, 45.746695387055, 45.735445738618, 45.724196090180, + 45.712946441743, 45.701696793306, 45.690447144869, 45.679197496431, 45.667947847994, 45.656698199557, + 45.645448551120, 45.634198902682, 45.622949254245, 45.611699605808, 45.600449957371, 45.589200308933, + 45.577950660496, 45.566701012059, 45.555451363622, 45.544201715184, 45.532952066747, 45.521702418310, + 45.510452769872, 45.499203121435, 45.487953472998, 45.476703824560, 45.465454176123, 45.454204527686, + 45.442954879249, 45.431705230811, 45.420455582374, 45.409205933936, 45.397956285499, 45.386706637062, + 45.375456988624, 45.364207340187, 45.352957691750, 45.341708043312, 45.330458394875, 45.319208746438, + 45.307959098000, 45.296709449563, 45.285459801125, 45.274210152688, 45.262960504251, 45.251710855813, + 45.240461207376, 45.229211558938, 45.217961910501, 45.206712262064, 45.195462613626, 45.184212965189, + 45.172963316751, 45.161713668314, 45.150464019876, 45.139214371439, 45.127964723002, 45.116715074564, + 45.105465426127, 45.094215777689, 45.082966129252, 45.071716480814, 45.060466832377, 45.049217183939, + 45.037967535502, 45.026717887064, 45.015468238627, 45.004218590189, 44.992968941752, 44.981719293314, + 44.970469644877, 44.959219996439, 44.947970348002, 44.936720699564, 44.925471051127, 44.914221402689, + 44.902971754252, 44.891722105814, 44.880472457377, 44.869222808939, 44.857973160502, 44.846723512064, + 44.835473863626, 44.824224215189, 44.812974566751, 44.801724918314, 44.790475269876, 44.779225621439, + 44.767975973001, 44.756726324563, 44.745476676126, 44.734227027688, 44.722977379251, 44.711727730813, + 44.700478082375, 44.689228433938, 44.677978785500, 44.666729137062, 44.655479488625, 44.644229840187, + 44.632980191750, 44.621730543312, 44.610480894874, 44.599231246437, 44.587981597999, 44.576731949561, + 44.565482301124, 44.554232652686, 44.542983004248, 44.531733355811, 44.520483707373, 44.509234058935, + 44.497984410498, 44.486734762060, 44.475485113622, 44.464235465184, 44.452985816747, 44.441736168309, + 44.430486519871, 44.419236871434, 44.407987222996, 44.396737574558, 44.385487926120, 44.374238277683, + 44.362988629245, 44.351738980807, 44.340489332370, 44.329239683932, 44.317990035494, 44.306740387056, + 44.295490738618, 44.284241090181, 44.272991441743, 44.261741793305, 44.250492144867, 44.239242496430, + 44.227992847992, 44.216743199554, 44.205493551116, 44.194243902678, 44.182994254241, 44.171744605803, + 44.160494957365, 44.149245308927, 44.137995660489, 44.126746012052, 44.115496363614, 44.104246715176, + 44.092997066738, 44.081747418300, 44.070497769862, 44.059248121425, 44.047998472987, 44.036748824549, + 44.025499176111, 44.014249527673, 44.002999879235, 43.991750230797, 43.980500582359, 43.969250933922, + 43.958001285484, 43.946751637046, 43.935501988608, 43.924252340170, 43.913002691732, 43.901753043294, + 43.890503394856, 43.879253746418, 43.868004097981, 43.856754449543, 43.845504801105, 43.834255152667, + 43.823005504229, 43.811755855791, 43.800506207353, 43.789256558915, 43.778006910477, 43.766757262039, + 43.755507613601, 43.744257965163, 43.733008316725, 43.721758668287, 43.710509019849, 43.699259371411, + 43.688009722973, 43.676760074535, 43.665510426097, 43.654260777659, 43.643011129221, 43.631761480783, + 43.620511832345, 43.609262183907, 43.598012535469, 43.586762887031, 43.575513238593, 43.564263590155, + 43.553013941717, 43.541764293279, 43.530514644841, 43.519264996403, 43.508015347965, 43.496765699527, + 43.485516051089, 43.474266402651, 43.463016754213, 43.451767105775, 43.440517457337, 43.429267808899, + 43.418018160461, 43.406768512023, 43.395518863584, 43.384269215146, 43.373019566708, 43.361769918270, + 43.350520269832, 43.339270621394, 43.328020972956, 43.316771324518, 43.305521676080, 43.294272027642, + 43.283022379203, 43.271772730765, 43.260523082327, 43.249273433889, 43.238023785451, 43.226774137013, + 43.215524488575, 43.204274840136, 43.193025191698, 43.181775543260, 43.170525894822, 43.159276246384, + 43.148026597946, 43.136776949508, 43.125527301069, 43.114277652631, 43.103028004193, 43.091778355755, + 43.080528707317, 43.069279058878, 43.058029410440, 43.046779762002, 43.035530113564, 43.024280465126, + 43.013030816687, 43.001781168249, 42.990531519811, 42.979281871373, 42.968032222935, 42.956782574496, + 42.945532926058, 42.934283277620, 42.923033629182, 42.911783980743, 42.900534332305, 42.889284683867, + 42.878035035429, 42.866785386990, 42.855535738552, 42.844286090114, 42.833036441676, 42.821786793237, + 42.810537144799, 42.799287496361, 42.788037847922, 42.776788199484, 42.765538551046, 42.754288902608, + 42.743039254169, 42.731789605731, 42.720539957293, 42.709290308854, 42.698040660416, 42.686791011978, + 42.675541363539, 42.664291715101, 42.653042066663, 42.641792418224, 42.630542769786, 42.619293121348, + 42.608043472909, 42.596793824471, 42.585544176033, 42.574294527594, 42.563044879156, 42.551795230718, + 42.540545582279, 42.529295933841, 42.518046285402, 42.506796636964, 42.495546988526, 42.484297340087, + 42.473047691649, 42.461798043211, 42.450548394772, 42.439298746334, 42.428049097895, 42.416799449457, + 42.405549801019, 42.394300152580, 42.383050504142, 42.371800855703, 42.360551207265, 42.349301558826, + 42.338051910388, 42.326802261950, 42.315552613511, 42.304302965073, 42.293053316634, 42.281803668196, + 42.270554019757, 42.259304371319, 42.248054722880, 42.236805074442, 42.225555426003, 42.214305777565, + 42.203056129127, 42.191806480688, 42.180556832250, 42.169307183811, 42.158057535373, 42.146807886934, + 42.135558238496, 42.124308590057, 42.113058941619, 42.101809293180, 42.090559644742, 42.079309996303, + 42.068060347865, 42.056810699426, 42.045561050988, 42.034311402549, 42.023061754110, 42.011812105672, + 42.000562457233, 41.989312808795, 41.978063160356, 41.966813511918, 41.955563863479, 41.944314215041, + 41.933064566602, 41.921814918164, 41.910565269725, 41.899315621286, 41.888065972848, 41.876816324409, + 41.865566675971, 41.854317027532, 41.843067379093, 41.831817730655, 41.820568082216, 41.809318433778, + 41.798068785339, 41.786819136900, 41.775569488462, 41.764319840023, 41.753070191585, 41.741820543146, + 41.730570894707, 41.719321246269, 41.708071597830, 41.696821949392, 41.685572300953, 41.674322652514, + 41.663073004076, 41.651823355637, 41.640573707198, 41.629324058760, 41.618074410321, 41.606824761882, + 41.595575113444, 41.584325465005, 41.573075816566, 41.561826168128, 41.550576519689, 41.539326871250, + 41.528077222812, 41.516827574373, 41.505577925934, 41.494328277496, 41.483078629057, 41.471828980618, + 41.460579332179, 41.449329683741, 41.438080035302, 41.426830386863, 41.415580738425, 41.404331089986, + 41.393081441547, 41.381831793108, 41.370582144670, 41.359332496231, 41.348082847792, 41.336833199353, + 41.325583550915, 41.314333902476, 41.303084254037, 41.291834605598, 41.280584957160, 41.269335308721, + 41.258085660282, 41.246836011843, 41.235586363405, 41.224336714966, 41.213087066527, 41.201837418088, + 41.190587769650, 41.179338121211, 41.168088472772, 41.156838824333, 41.145589175894, 41.134339527456, + 41.123089879017, 41.111840230578, 41.100590582139, 41.089340933700, 41.078091285262, 41.066841636823, + 41.055591988384, 41.044342339945, 41.033092691506, 41.021843043067, 41.010593394629, 40.999343746190, + 40.988094097751, 40.976844449312, 40.965594800873, 40.954345152434, 40.943095503995, 40.931845855557, + 40.920596207118, 40.909346558679, 40.898096910240, 40.886847261801, 40.875597613362, 40.864347964923, + 40.853098316484, 40.841848668046, 40.830599019607, 40.819349371168, 40.808099722729, 40.796850074290, + 40.785600425851, 40.774350777412, 40.763101128973, 40.751851480534, 40.740601832095, 40.729352183657, + 40.718102535218, 40.706852886779, 40.695603238340, 40.684353589901, 40.673103941462, 40.661854293023, + 40.650604644584, 40.639354996145, 40.628105347706, 40.616855699267, 40.605606050828, 40.594356402389, + 40.583106753950, 40.571857105511, 40.560607457072, 40.549357808633, 40.538108160194, 40.526858511755, + 40.515608863316, 40.504359214877, 40.493109566438, 40.481859917999, 40.470610269560, 40.459360621121, + 40.448110972682, 40.436861324243, 40.425611675804, 40.414362027365, 40.403112378926, 40.391862730487, + 40.380613082048, 40.369363433609, 40.358113785170, 40.346864136731, 40.335614488292, 40.324364839853, + 40.313115191414, 40.301865542975, 40.290615894536, 40.279366246097, 40.268116597658, 40.256866949219, + 40.245617300780, 40.234367652341, 40.223118003902, 40.211868355463, 40.200618707024, 40.189369058585, + 40.178119410146, 40.166869761706, 40.155620113267, 40.144370464828, 40.133120816389, 40.121871167950, + 40.110621519511, 40.099371871072, 40.088122222633, 40.076872574194, 40.065622925755, 40.054373277316, + 40.043123628876, 40.031873980437, 40.020624331998, 40.009374683559, 39.998125035120, 39.986875386681, + 39.975625738242, 39.964376089803, 39.953126441363, 39.941876792924, 39.930627144485, 39.919377496046, + 39.908127847607, 39.896878199168, 39.885628550728, 39.874378902289, 39.863129253850, 39.851879605411, + 39.840629956972, 39.829380308533, 39.818130660093, 39.806881011654, 39.795631363215, 39.784381714776, + 39.773132066337, 39.761882417898, 39.750632769458, 39.739383121019, 39.728133472580, 39.716883824141, + 39.705634175702, 39.694384527262, 39.683134878823, 39.671885230384, 39.660635581945, 39.649385933506, + 39.638136285066, 39.626886636627, 39.615636988188, 39.604387339749, 39.593137691309, 39.581888042870, + 39.570638394431, 39.559388745992, 39.548139097552, 39.536889449113, 39.525639800674, 39.514390152235, + 39.503140503795, 39.491890855356, 39.480641206917, 39.469391558478, 39.458141910038, 39.446892261599, + 39.435642613160, 39.424392964720, 39.413143316281, 39.401893667842, 39.390644019403, 39.379394370963, + 39.368144722524, 39.356895074085, 39.345645425645, 39.334395777206, 39.323146128767, 39.311896480328, + 39.300646831888, 39.289397183449, 39.278147535010, 39.266897886570, 39.255648238131, 39.244398589692, + 39.233148941252, 39.221899292813, 39.210649644374, 39.199399995934, 39.188150347495, 39.176900699056, + 39.165651050616, 39.154401402177, 39.143151753738, 39.131902105298, 39.120652456859, 39.109402808419, + 39.098153159980, 39.086903511541, 39.075653863101, 39.064404214662, 39.053154566223, 39.041904917783, + 39.030655269344, 39.019405620904, 39.008155972465, 38.996906324026, 38.985656675586, 38.974407027147, + 38.963157378708, 38.951907730268, 38.940658081829, 38.929408433389, 38.918158784950, 38.906909136510, + 38.895659488071, 38.884409839632, 38.873160191192, 38.861910542753, 38.850660894313, 38.839411245874, + 38.828161597434, 38.816911948995, 38.805662300556, 38.794412652116, 38.783163003677, 38.771913355237, + 38.760663706798, 38.749414058358, 38.738164409919, 38.726914761479, 38.715665113040, 38.704415464601, + 38.693165816161, 38.681916167722, 38.670666519282, 38.659416870843, 38.648167222403, 38.636917573964, + 38.625667925524, 38.614418277085, 38.603168628645, 38.591918980206, 38.580669331766, 38.569419683327, + 38.558170034887, 38.546920386448, 38.535670738008, 38.524421089569, 38.513171441129, 38.501921792690, + 38.490672144250, 38.479422495811, 38.468172847371, 38.456923198932, 38.445673550492, 38.434423902053, + 38.423174253613, 38.411924605173, 38.400674956734, 38.389425308294, 38.378175659855, 38.366926011415, + 38.355676362976, 38.344426714536, 38.333177066097, 38.321927417657, 38.310677769217, 38.299428120778, + 38.288178472338, 38.276928823899, 38.265679175459, 38.254429527020, 38.243179878580, 38.231930230140, + 38.220680581701, 38.209430933261, 38.198181284822, 38.186931636382, 38.175681987942, 38.164432339503, + 38.153182691063, 38.141933042624, 38.130683394184, 38.119433745744, 38.108184097305, 38.096934448865, + 38.085684800426, 38.074435151986, 38.063185503546, 38.051935855107, 38.040686206667, 38.029436558227, + 38.018186909788, 38.006937261348, 37.995687612909, 37.984437964469, 37.973188316029, 37.961938667590, + 37.950689019150, 37.939439370710, 37.928189722271, 37.916940073831, 37.905690425391, 37.894440776952, + 37.883191128512, 37.871941480072, 37.860691831633, 37.849442183193, 37.838192534753, 37.826942886314, + 37.815693237874, 37.804443589434, 37.793193940995, 37.781944292555, 37.770694644115, 37.759444995676, + 37.748195347236, 37.736945698796, 37.725696050356, 37.714446401917, 37.703196753477, 37.691947105037, + 37.680697456598, 37.669447808158, 37.658198159718, 37.646948511278, 37.635698862839, 37.624449214399, + 37.613199565959, 37.601949917519, 37.590700269080, 37.579450620640, 37.568200972200, 37.556951323761, + 37.545701675321, 37.534452026881, 37.523202378441, 37.511952730001, 37.500703081562, 37.489453433122, + 37.478203784682, 37.466954136242, 37.455704487803, 37.444454839363, 37.433205190923, 37.421955542483, + 37.410705894044, 37.399456245604, 37.388206597164, 37.376956948724, 37.365707300284, 37.354457651845, + 37.343208003405, 37.331958354965, 37.320708706525, 37.309459058085, 37.298209409646, 37.286959761206, + 37.275710112766, 37.264460464326, 37.253210815886, 37.241961167447, 37.230711519007, 37.219461870567, + 37.208212222127, 37.196962573687, 37.185712925247, 37.174463276808, 37.163213628368, 37.151963979928, + 37.140714331488, 37.129464683048, 37.118215034608, 37.106965386169, 37.095715737729, 37.084466089289, + 37.073216440849, 37.061966792409, 37.050717143969, 37.039467495529, 37.028217847090, 37.016968198650, + 37.005718550210, 36.994468901770, 36.983219253330, 36.971969604890, 36.960719956450, 36.949470308010, + 36.938220659571, 36.926971011131, 36.915721362691, 36.904471714251, 36.893222065811, 36.881972417371, + 36.870722768931, 36.859473120491, 36.848223472051, 36.836973823611, 36.825724175172, 36.814474526732, + 36.803224878292, 36.791975229852, 36.780725581412, 36.769475932972, 36.758226284532, 36.746976636092, + 36.735726987652, 36.724477339212, 36.713227690772, 36.701978042332, 36.690728393892, 36.679478745452, + 36.668229097012, 36.656979448573, 36.645729800133, 36.634480151693, 36.623230503253, 36.611980854813, + 36.600731206373, 36.589481557933, 36.578231909493, 36.566982261053, 36.555732612613, 36.544482964173, + 36.533233315733, 36.521983667293, 36.510734018853, 36.499484370413, 36.488234721973, 36.476985073533, + 36.465735425093, 36.454485776653, 36.443236128213, 36.431986479773, 36.420736831333, 36.409487182893, + 36.398237534453, 36.386987886013, 36.375738237573, 36.364488589133, 36.353238940693, 36.341989292253, + 36.330739643813, 36.319489995373, 36.308240346933, 36.296990698493, 36.285741050053, 36.274491401613, + 36.263241753173, 36.251992104733, 36.240742456293, 36.229492807853, 36.218243159413, 36.206993510973, + 36.195743862532, 36.184494214092, 36.173244565652, 36.161994917212, 36.150745268772, 36.139495620332, + 36.128245971892, 36.116996323452, 36.105746675012, 36.094497026572, 36.083247378132, 36.071997729692, + 36.060748081252, 36.049498432812, 36.038248784371, 36.026999135931, 36.015749487491, 36.004499839051, + 35.993250190611, 35.982000542171, 35.970750893731, 35.959501245291, 35.948251596851, 35.937001948411, + 35.925752299971, 35.914502651530, 35.903253003090, 35.892003354650, 35.880753706210, 35.869504057770, + 35.858254409330, 35.847004760890, 35.835755112450, 35.824505464009, 35.813255815569, 35.802006167129, + 35.790756518689, 35.779506870249, 35.768257221809, 35.757007573369, 35.745757924928, 35.734508276488, + 35.723258628048, 35.712008979608, 35.700759331168, 35.689509682728, 35.678260034288, 35.667010385847, + 35.655760737407, 35.644511088967, 35.633261440527, 35.622011792087, 35.610762143647, 35.599512495206, + 35.588262846766, 35.577013198326, 35.565763549886, 35.554513901446, 35.543264253005, 35.532014604565, + 35.520764956125, 35.509515307685, 35.498265659245, 35.487016010804, 35.475766362364, 35.464516713924, + 35.453267065484, 35.442017417044, 35.430767768603, 35.419518120163, 35.408268471723, 35.397018823283, + 35.385769174843, 35.374519526402, 35.363269877962, 35.352020229522, 35.340770581082, 35.329520932641, + 35.318271284201, 35.307021635761, 35.295771987321, 35.284522338880, 35.273272690440, 35.262023042000, + 35.250773393560, 35.239523745119, 35.228274096679, 35.217024448239, 35.205774799799, 35.194525151358, + 35.183275502918, 35.172025854478, 35.160776206038, 35.149526557597, 35.138276909157, 35.127027260717, + 35.115777612277, 35.104527963836, 35.093278315396, 35.082028666956, 35.070779018515, 35.059529370075, + 35.048279721635, 35.037030073195, 35.025780424754, 35.014530776314, 35.003281127874, 34.992031479433, + 34.980781830993, 34.969532182553, 34.958282534112, 34.947032885672, 34.935783237232, 34.924533588792, + 34.913283940351, 34.902034291911, 34.890784643471, 34.879534995030, 34.868285346590, 34.857035698150, + 34.845786049709, 34.834536401269, 34.823286752829, 34.812037104388, 34.800787455948, 34.789537807508, + 34.778288159067, 34.767038510627, 34.755788862187, 34.744539213746, 34.733289565306, 34.722039916865, + 34.710790268425, 34.699540619985, 34.688290971544, 34.677041323104, 34.665791674664, 34.654542026223, + 34.643292377783, 34.632042729343, 34.620793080902, 34.609543432462, 34.598293784021, 34.587044135581, + 34.575794487141, 34.564544838700, 34.553295190260, 34.542045541819, 34.530795893379, 34.519546244939, + 34.508296596498, 34.497046948058, 34.485797299618, 34.474547651177, 34.463298002737, 34.452048354296, + 34.440798705856, 34.429549057415, 34.418299408975, 34.407049760535, 34.395800112094, 34.384550463654, + 34.373300815213, 34.362051166773, 34.350801518333, 34.339551869892, 34.328302221452, 34.317052573011, + 34.305802924571, 34.294553276130, 34.283303627690, 34.272053979249, 34.260804330809, 34.249554682369, + 34.238305033928, 34.227055385488, 34.215805737047, 34.204556088607, 34.193306440166, 34.182056791726, + 34.170807143285, 34.159557494845, 34.148307846404, 34.137058197964, 34.125808549524, 34.114558901083, + 34.103309252643, 34.092059604202, 34.080809955762, 34.069560307321, 34.058310658881, 34.047061010440, + 34.035811362000, 34.024561713559, 34.013312065119, 34.002062416678, 33.990812768238, 33.979563119797, + 33.968313471357, 33.957063822916, 33.945814174476, 33.934564526035, 33.923314877595, 33.912065229154, + 33.900815580714, 33.889565932273, 33.878316283833, 33.867066635392, 33.855816986952, 33.844567338511, + 33.833317690071, 33.822068041630, 33.810818393190, 33.799568744749, 33.788319096308, 33.777069447868, + 33.765819799427, 33.754570150987, 33.743320502546, 33.732070854106, 33.720821205665, 33.709571557225, + 33.698321908784, 33.687072260344, 33.675822611903, 33.664572963462, 33.653323315022, 33.642073666581, + 33.630824018141, 33.619574369700, 33.608324721260, 33.597075072819, 33.585825424379, 33.574575775938, + 33.563326127497, 33.552076479057, 33.540826830616, 33.529577182176, 33.518327533735, 33.507077885294, + 33.495828236854, 33.484578588413, 33.473328939973, 33.462079291532, 33.450829643092, 33.439579994651, + 33.428330346210, 33.417080697770, 33.405831049329, 33.394581400889, 33.383331752448, 33.372082104007, + 33.360832455567, 33.349582807126, 33.338333158685, 33.327083510245, 33.315833861804, 33.304584213364, + 33.293334564923, 33.282084916482, 33.270835268042, 33.259585619601, 33.248335971160, 33.237086322720, + 33.225836674279, 33.214587025839, 33.203337377398, 33.192087728957, 33.180838080517, 33.169588432076, + 33.158338783635, 33.147089135195, 33.135839486754, 33.124589838313, 33.113340189873, 33.102090541432, + 33.090840892991, 33.079591244551, 33.068341596110, 33.057091947669, 33.045842299229, 33.034592650788, + 33.023343002347, 33.012093353907, 33.000843705466, 32.989594057025, 32.978344408585, 32.967094760144, + 32.955845111703, 32.944595463263, 32.933345814822, 32.922096166381, 32.910846517941, 32.899596869500, + 32.888347221059, 32.877097572619, 32.865847924178, 32.854598275737, 32.843348627296, 32.832098978856, + 32.820849330415, 32.809599681974, 32.798350033534, 32.787100385093, 32.775850736652, 32.764601088211, + 32.753351439771, 32.742101791330, 32.730852142889, 32.719602494449, 32.708352846008, 32.697103197567, + 32.685853549126, 32.674603900686, 32.663354252245, 32.652104603804, 32.640854955363, 32.629605306923, + 32.618355658482, 32.607106010041, 32.595856361600, 32.584606713160, 32.573357064719, 32.562107416278, + 32.550857767837, 32.539608119397, 32.528358470956, 32.517108822515, 32.505859174074, 32.494609525634, + 32.483359877193, 32.472110228752, 32.460860580311, 32.449610931871, 32.438361283430, 32.427111634989, + 32.415861986548, 32.404612338107, 32.393362689667, 32.382113041226, 32.370863392785, 32.359613744344, + 32.348364095904, 32.337114447463, 32.325864799022, 32.314615150581, 32.303365502140, 32.292115853700, + 32.280866205259, 32.269616556818, 32.258366908377, 32.247117259936, 32.235867611496, 32.224617963055, + 32.213368314614, 32.202118666173, 32.190869017732, 32.179619369291, 32.168369720851, 32.157120072410, + 32.145870423969, 32.134620775528, 32.123371127087, 32.112121478646, 32.100871830206, 32.089622181765, + 32.078372533324, 32.067122884883, 32.055873236442, 32.044623588001, 32.033373939561, 32.022124291120, + 32.010874642679, 31.999624994238, 31.988375345797, 31.977125697356, 31.965876048916, 31.954626400475, + 31.943376752034, 31.932127103593, 31.920877455152, 31.909627806711, 31.898378158270, 31.887128509830, + 31.875878861389, 31.864629212948, 31.853379564507, 31.842129916066, 31.830880267625, 31.819630619184, + 31.808380970743, 31.797131322303, 31.785881673862, 31.774632025421, 31.763382376980, 31.752132728539, + 31.740883080098, 31.729633431657, 31.718383783216, 31.707134134775, 31.695884486335, 31.684634837894, + 31.673385189453, 31.662135541012, 31.650885892571, 31.639636244130, 31.628386595689, 31.617136947248, + 31.605887298807, 31.594637650366, 31.583388001925, 31.572138353485, 31.560888705044, 31.549639056603, + 31.538389408162, 31.527139759721, 31.515890111280, 31.504640462839, 31.493390814398, 31.482141165957, + 31.470891517516, 31.459641869075, 31.448392220634, 31.437142572193, 31.425892923752, 31.414643275311, + 31.403393626871, 31.392143978430, 31.380894329989, 31.369644681548, 31.358395033107, 31.347145384666, + 31.335895736225, 31.324646087784, 31.313396439343, 31.302146790902, 31.290897142461, 31.279647494020, + 31.268397845579, 31.257148197138, 31.245898548697, 31.234648900256, 31.223399251815, 31.212149603374, + 31.200899954933, 31.189650306492, 31.178400658051, 31.167151009610, 31.155901361169, 31.144651712728, + 31.133402064287, 31.122152415846, 31.110902767405, 31.099653118964, 31.088403470523, 31.077153822082, + 31.065904173641, 31.054654525200, 31.043404876759, 31.032155228318, 31.020905579877, 31.009655931436, + 30.998406282995, 30.987156634554, 30.975906986113, 30.964657337672, 30.953407689231, 30.942158040790, + 30.930908392349, 30.919658743908, 30.908409095467, 30.897159447026, 30.885909798585, 30.874660150144, + 30.863410501703, 30.852160853262, 30.840911204821, 30.829661556380, 30.818411907939, 30.807162259498, + 30.795912611057, 30.784662962616, 30.773413314175, 30.762163665734, 30.750914017293, 30.739664368852, + 30.728414720411, 30.717165071969, 30.705915423528, 30.694665775087, 30.683416126646, 30.672166478205, + 30.660916829764, 30.649667181323, 30.638417532882, 30.627167884441, 30.615918236000, 30.604668587559, + 30.593418939118, 30.582169290677, 30.570919642236, 30.559669993795, 30.548420345353, 30.537170696912, + 30.525921048471, 30.514671400030, 30.503421751589, 30.492172103148, 30.480922454707, 30.469672806266, + 30.458423157825, 30.447173509384, 30.435923860943, 30.424674212501, 30.413424564060, 30.402174915619, + 30.390925267178, 30.379675618737, 30.368425970296, 30.357176321855, 30.345926673414, 30.334677024973, + 30.323427376532, 30.312177728090, 30.300928079649, 30.289678431208, 30.278428782767, 30.267179134326, + 30.255929485885, 30.244679837444, 30.233430189003, 30.222180540561, 30.210930892120, 30.199681243679, + 30.188431595238, 30.177181946797, 30.165932298356, 30.154682649915, 30.143433001473, 30.132183353032, + 30.120933704591, 30.109684056150, 30.098434407709, 30.087184759268, 30.075935110827, 30.064685462385, + 30.053435813944, 30.042186165503, 30.030936517062, 30.019686868621, 30.008437220180, 29.997187571739, + 29.985937923297, 29.974688274856, 29.963438626415, 29.952188977974, 29.940939329533, 29.929689681091, + 29.918440032650, 29.907190384209, 29.895940735768, 29.884691087327, 29.873441438886, 29.862191790444, + 29.850942142003, 29.839692493562, 29.828442845121, 29.817193196680, 29.805943548238, 29.794693899797, + 29.783444251356, 29.772194602915, 29.760944954474, 29.749695306033, 29.738445657591, 29.727196009150, + 29.715946360709, 29.704696712268, 29.693447063827, 29.682197415385, 29.670947766944, 29.659698118503, + 29.648448470062, 29.637198821620, 29.625949173179, 29.614699524738, 29.603449876297, 29.592200227856, + 29.580950579414, 29.569700930973, 29.558451282532, 29.547201634091, 29.535951985649, 29.524702337208, + 29.513452688767, 29.502203040326, 29.490953391885, 29.479703743443, 29.468454095002, 29.457204446561, + 29.445954798120, 29.434705149678, 29.423455501237, 29.412205852796, 29.400956204355, 29.389706555913, + 29.378456907472, 29.367207259031, 29.355957610590, 29.344707962148, 29.333458313707, 29.322208665266, + 29.310959016825, 29.299709368383, 29.288459719942, 29.277210071501, 29.265960423059, 29.254710774618, + 29.243461126177, 29.232211477736, 29.220961829294, 29.209712180853, 29.198462532412, 29.187212883971, + 29.175963235529, 29.164713587088, 29.153463938647, 29.142214290205, 29.130964641764, 29.119714993323, + 29.108465344882, 29.097215696440, 29.085966047999, 29.074716399558, 29.063466751116, 29.052217102675, + 29.040967454234, 29.029717805792, 29.018468157351, 29.007218508910, 28.995968860469, 28.984719212027, + 28.973469563586, 28.962219915145, 28.950970266703, 28.939720618262, 28.928470969821, 28.917221321379, + 28.905971672938, 28.894722024497, 28.883472376055, 28.872222727614, 28.860973079173, 28.849723430731, + 28.838473782290, 28.827224133849, 28.815974485407, 28.804724836966, 28.793475188525, 28.782225540083, + 28.770975891642, 28.759726243201, 28.748476594759, 28.737226946318, 28.725977297877, 28.714727649435, + 28.703478000994, 28.692228352553, 28.680978704111, 28.669729055670, 28.658479407229, 28.647229758787, + 28.635980110346, 28.624730461905, 28.613480813463, 28.602231165022, 28.590981516581, 28.579731868139, + 28.568482219698, 28.557232571256, 28.545982922815, 28.534733274374, 28.523483625932, 28.512233977491, + 28.500984329050, 28.489734680608, 28.478485032167, 28.467235383725, 28.455985735284, 28.444736086843, + 28.433486438401, 28.422236789960, 28.410987141519, 28.399737493077, 28.388487844636, 28.377238196194, + 28.365988547753, 28.354738899312, 28.343489250870, 28.332239602429, 28.320989953987, 28.309740305546, + 28.298490657105, 28.287241008663, 28.275991360222, 28.264741711780, 28.253492063339, 28.242242414898, + 28.230992766456, 28.219743118015, 28.208493469573, 28.197243821132, 28.185994172691, 28.174744524249, + 28.163494875808, 28.152245227366, 28.140995578925, 28.129745930483, 28.118496282042, 28.107246633601, + 28.095996985159, 28.084747336718, 28.073497688276, 28.062248039835, 28.050998391393, 28.039748742952, + 28.028499094511, 28.017249446069, 28.005999797628, 27.994750149186, 27.983500500745, 27.972250852303, + 27.961001203862, 27.949751555420, 27.938501906979, 27.927252258538, 27.916002610096, 27.904752961655, + 27.893503313213, 27.882253664772, 27.871004016330, 27.859754367889, 27.848504719447, 27.837255071006, + 27.826005422564, 27.814755774123, 27.803506125682, 27.792256477240, 27.781006828799, 27.769757180357, + 27.758507531916, 27.747257883474, 27.736008235033, 27.724758586591, 27.713508938150, 27.702259289708, + 27.691009641267, 27.679759992825, 27.668510344384, 27.657260695942, 27.646011047501, 27.634761399059, + 27.623511750618, 27.612262102176, 27.601012453735, 27.589762805293, 27.578513156852, 27.567263508410, + 27.556013859969, 27.544764211527, 27.533514563086, 27.522264914644, 27.511015266203, 27.499765617761, + 27.488515969320, 27.477266320878, 27.466016672437, 27.454767023995, 27.443517375554, 27.432267727112, + 27.421018078671, 27.409768430229, 27.398518781788, 27.387269133346, 27.376019484905, 27.364769836463, + 27.353520188022, 27.342270539580, 27.331020891139, 27.319771242697, 27.308521594256, 27.297271945814, + 27.286022297373, 27.274772648931, 27.263523000490, 27.252273352048, 27.241023703606, 27.229774055165, + 27.218524406723, 27.207274758282, 27.196025109840, 27.184775461399, 27.173525812957, 27.162276164516, + 27.151026516074, 27.139776867633, 27.128527219191, 27.117277570749, 27.106027922308, 27.094778273866, + 27.083528625425, 27.072278976983, 27.061029328542, 27.049779680100, 27.038530031659, 27.027280383217, + 27.016030734775, 27.004781086334, 26.993531437892, 26.982281789451, 26.971032141009, 26.959782492568, + 26.948532844126, 26.937283195684, 26.926033547243, 26.914783898801, 26.903534250360, 26.892284601918, + 26.881034953477, 26.869785305035, 26.858535656593, 26.847286008152, 26.836036359710, 26.824786711269, + 26.813537062827, 26.802287414385, 26.791037765944, 26.779788117502, 26.768538469061, 26.757288820619, + 26.746039172177, 26.734789523736, 26.723539875294, 26.712290226853, 26.701040578411, 26.689790929969, + 26.678541281528, 26.667291633086, 26.656041984645, 26.644792336203, 26.633542687761, 26.622293039320, + 26.611043390878, 26.599793742437, 26.588544093995, 26.577294445553, 26.566044797112, 26.554795148670, + 26.543545500228, 26.532295851787, 26.521046203345, 26.509796554904, 26.498546906462, 26.487297258020, + 26.476047609579, 26.464797961137, 26.453548312695, 26.442298664254, 26.431049015812, 26.419799367371, + 26.408549718929, 26.397300070487, 26.386050422046, 26.374800773604, 26.363551125162, 26.352301476721, + 26.341051828279, 26.329802179837, 26.318552531396, 26.307302882954, 26.296053234512, 26.284803586071, + 26.273553937629, 26.262304289187, 26.251054640746, 26.239804992304, 26.228555343862, 26.217305695421, + 26.206056046979, 26.194806398538, 26.183556750096, 26.172307101654, 26.161057453213, 26.149807804771, + 26.138558156329, 26.127308507887, 26.116058859446, 26.104809211004, 26.093559562562, 26.082309914121, + 26.071060265679, 26.059810617237, 26.048560968796, 26.037311320354, 26.026061671912, 26.014812023471, + 26.003562375029, 25.992312726587, 25.981063078146, 25.969813429704, 25.958563781262, 25.947314132821, + 25.936064484379, 25.924814835937, 25.913565187495, 25.902315539054, 25.891065890612, 25.879816242170, + 25.868566593729, 25.857316945287, 25.846067296845, 25.834817648404, 25.823567999962, 25.812318351520, + 25.801068703078, 25.789819054637, 25.778569406195, 25.767319757753, 25.756070109312, 25.744820460870, + 25.733570812428, 25.722321163986, 25.711071515545, 25.699821867103, 25.688572218661, 25.677322570220, + 25.666072921778, 25.654823273336, 25.643573624894, 25.632323976453, 25.621074328011, 25.609824679569, + 25.598575031127, 25.587325382686, 25.576075734244, 25.564826085802, 25.553576437361, 25.542326788919, + 25.531077140477, 25.519827492035, 25.508577843594, 25.497328195152, 25.486078546710, 25.474828898268, + 25.463579249827, 25.452329601385, 25.441079952943, 25.429830304501, 25.418580656060, 25.407331007618, + 25.396081359176, 25.384831710734, 25.373582062293, 25.362332413851, 25.351082765409, 25.339833116967, + 25.328583468526, 25.317333820084, 25.306084171642, 25.294834523200, 25.283584874758, 25.272335226317, + 25.261085577875, 25.249835929433, 25.238586280991, 25.227336632550, 25.216086984108, 25.204837335666, + 25.193587687224, 25.182338038783, 25.171088390341, 25.159838741899, 25.148589093457, 25.137339445015, + 25.126089796574, 25.114840148132, 25.103590499690, 25.092340851248, 25.081091202806, 25.069841554365, + 25.058591905923, 25.047342257481, 25.036092609039, 25.024842960597, 25.013593312156, 25.002343663714, + 24.991094015272, 24.979844366830, 24.968594718388, 24.957345069947, 24.946095421505, 24.934845773063, + 24.923596124621, 24.912346476179, 24.901096827738, 24.889847179296, 24.878597530854, 24.867347882412, + 24.856098233970, 24.844848585529, 24.833598937087, 24.822349288645, 24.811099640203, 24.799849991761, + 24.788600343319, 24.777350694878, 24.766101046436, 24.754851397994, 24.743601749552, 24.732352101110, + 24.721102452669, 24.709852804227, 24.698603155785, 24.687353507343, 24.676103858901, 24.664854210459, + 24.653604562018, 24.642354913576, 24.631105265134, 24.619855616692, 24.608605968250, 24.597356319808, + 24.586106671367, 24.574857022925, 24.563607374483, 24.552357726041, 24.541108077599, 24.529858429157, + 24.518608780715, 24.507359132274, 24.496109483832, 24.484859835390, 24.473610186948, 24.462360538506, + 24.451110890064, 24.439861241622, 24.428611593181, 24.417361944739, 24.406112296297, 24.394862647855, + 24.383612999413, 24.372363350971, 24.361113702529, 24.349864054088, 24.338614405646, 24.327364757204, + 24.316115108762, 24.304865460320, 24.293615811878, 24.282366163436, 24.271116514994, 24.259866866553, + 24.248617218111, 24.237367569669, 24.226117921227, 24.214868272785, 24.203618624343, 24.192368975901, + 24.181119327459, 24.169869679017, 24.158620030576, 24.147370382134, 24.136120733692, 24.124871085250, + 24.113621436808, 24.102371788366, 24.091122139924, 24.079872491482, 24.068622843040, 24.057373194599, + 24.046123546157, 24.034873897715, 24.023624249273, 24.012374600831, 24.001124952389, 23.989875303947, + 23.978625655505, 23.967376007063, 23.956126358621, 23.944876710180, 23.933627061738, 23.922377413296, + 23.911127764854, 23.899878116412, 23.888628467970, 23.877378819528, 23.866129171086, 23.854879522644, + 23.843629874202, 23.832380225760, 23.821130577318, 23.809880928877, 23.798631280435, 23.787381631993, + 23.776131983551, 23.764882335109, 23.753632686667, 23.742383038225, 23.731133389783, 23.719883741341, + 23.708634092899, 23.697384444457, 23.686134796015, 23.674885147573, 23.663635499131, 23.652385850689, + 23.641136202248, 23.629886553806, 23.618636905364, 23.607387256922, 23.596137608480, 23.584887960038, + 23.573638311596, 23.562388663154, 23.551139014712, 23.539889366270, 23.528639717828, 23.517390069386, + 23.506140420944, 23.494890772502, 23.483641124060, 23.472391475618, 23.461141827176, 23.449892178734, + 23.438642530292, 23.427392881850, 23.416143233408, 23.404893584967, 23.393643936525, 23.382394288083, + 23.371144639641, 23.359894991199, 23.348645342757, 23.337395694315, 23.326146045873, 23.314896397431, + 23.303646748989, 23.292397100547, 23.281147452105, 23.269897803663, 23.258648155221, 23.247398506779, + 23.236148858337, 23.224899209895, 23.213649561453, 23.202399913011, 23.191150264569, 23.179900616127, + 23.168650967685, 23.157401319243, 23.146151670801, 23.134902022359, 23.123652373917, 23.112402725475, + 23.101153077033, 23.089903428591, 23.078653780149, 23.067404131707, 23.056154483265, 23.044904834823, + 23.033655186381, 23.022405537939, 23.011155889497, 22.999906241055, 22.988656592613, 22.977406944171, + 22.966157295729, 22.954907647287, 22.943657998845, 22.932408350403, 22.921158701961, 22.909909053519, + 22.898659405077, 22.887409756635, 22.876160108193, 22.864910459751, 22.853660811309, 22.842411162867, + 22.831161514425, 22.819911865983, 22.808662217541, 22.797412569099, 22.786162920657, 22.774913272215, + 22.763663623773, 22.752413975331, 22.741164326889, 22.729914678447, 22.718665030005, 22.707415381563, + 22.696165733121, 22.684916084679, 22.673666436237, 22.662416787794, 22.651167139352, 22.639917490910, + 22.628667842468, 22.617418194026, 22.606168545584, 22.594918897142, 22.583669248700, 22.572419600258, + 22.561169951816, 22.549920303374, 22.538670654932, 22.527421006490, 22.516171358048, 22.504921709606, + 22.493672061164, 22.482422412722, 22.471172764280, 22.459923115838, 22.448673467396, 22.437423818954, + 22.426174170512, 22.414924522069, 22.403674873627, 22.392425225185, 22.381175576743, 22.369925928301, + 22.358676279859, 22.347426631417, 22.336176982975, 22.324927334533, 22.313677686091, 22.302428037649, + 22.291178389207, 22.279928740765, 22.268679092323, 22.257429443881, 22.246179795438, 22.234930146996, + 22.223680498554, 22.212430850112, 22.201181201670, 22.189931553228, 22.178681904786, 22.167432256344, + 22.156182607902, 22.144932959460, 22.133683311018, 22.122433662576, 22.111184014133, 22.099934365691, + 22.088684717249, 22.077435068807, 22.066185420365, 22.054935771923, 22.043686123481, 22.032436475039, + 22.021186826597, 22.009937178155, 21.998687529713, 21.987437881270, 21.976188232828, 21.964938584386, + 21.953688935944, 21.942439287502, 21.931189639060, 21.919939990618, 21.908690342176, 21.897440693734, + 21.886191045292, 21.874941396849, 21.863691748407, 21.852442099965, 21.841192451523, 21.829942803081, + 21.818693154639, 21.807443506197, 21.796193857755, 21.784944209313, 21.773694560870, 21.762444912428, + 21.751195263986, 21.739945615544, 21.728695967102, 21.717446318660, 21.706196670218, 21.694947021776, + 21.683697373333, 21.672447724891, 21.661198076449, 21.649948428007, 21.638698779565, 21.627449131123, + 21.616199482681, 21.604949834239, 21.593700185796, 21.582450537354, 21.571200888912, 21.559951240470, + 21.548701592028, 21.537451943586, 21.526202295144, 21.514952646701, 21.503702998259, 21.492453349817, + 21.481203701375, 21.469954052933, 21.458704404491, 21.447454756049, 21.436205107606, 21.424955459164, + 21.413705810722, 21.402456162280, 21.391206513838, 21.379956865396, 21.368707216954, 21.357457568511, + 21.346207920069, 21.334958271627, 21.323708623185, 21.312458974743, 21.301209326301, 21.289959677858, + 21.278710029416, 21.267460380974, 21.256210732532, 21.244961084090, 21.233711435648, 21.222461787206, + 21.211212138763, 21.199962490321, 21.188712841879, 21.177463193437, 21.166213544995, 21.154963896553, + 21.143714248110, 21.132464599668, 21.121214951226, 21.109965302784, 21.098715654342, 21.087466005899, + 21.076216357457, 21.064966709015, 21.053717060573, 21.042467412131, 21.031217763689, 21.019968115246, + 21.008718466804, 20.997468818362, 20.986219169920, 20.974969521478, 20.963719873035, 20.952470224593, + 20.941220576151, 20.929970927709, 20.918721279267, 20.907471630825, 20.896221982382, 20.884972333940, + 20.873722685498, 20.862473037056, 20.851223388614, 20.839973740171, 20.828724091729, 20.817474443287, + 20.806224794845, 20.794975146403, 20.783725497960, 20.772475849518, 20.761226201076, 20.749976552634, + 20.738726904192, 20.727477255749, 20.716227607307, 20.704977958865, 20.693728310423, 20.682478661980, + 20.671229013538, 20.659979365096, 20.648729716654, 20.637480068212, 20.626230419769, 20.614980771327, + 20.603731122885, 20.592481474443, 20.581231826001, 20.569982177558, 20.558732529116, 20.547482880674, + 20.536233232232, 20.524983583789, 20.513733935347, 20.502484286905, 20.491234638463, 20.479984990021, + 20.468735341578, 20.457485693136, 20.446236044694, 20.434986396252, 20.423736747809, 20.412487099367, + 20.401237450925, 20.389987802483, 20.378738154040, 20.367488505598, 20.356238857156, 20.344989208714, + 20.333739560272, 20.322489911829, 20.311240263387, 20.299990614945, 20.288740966503, 20.277491318060, + 20.266241669618, 20.254992021176, 20.243742372734, 20.232492724291, 20.221243075849, 20.209993427407, + 20.198743778965, 20.187494130522, 20.176244482080, 20.164994833638, 20.153745185196, 20.142495536753, + 20.131245888311, 20.119996239869, 20.108746591427, 20.097496942984, 20.086247294542, 20.074997646100, + 20.063747997658, 20.052498349215, 20.041248700773, 20.029999052331, 20.018749403888, 20.007499755446, + 19.996250107004, 19.985000458562, 19.973750810119, 19.962501161677, 19.951251513235, 19.940001864793, + 19.928752216350, 19.917502567908, 19.906252919466, 19.895003271024, 19.883753622581, 19.872503974139, + 19.861254325697, 19.850004677254, 19.838755028812, 19.827505380370, 19.816255731928, 19.805006083485, + 19.793756435043, 19.782506786601, 19.771257138158, 19.760007489716, 19.748757841274, 19.737508192832, + 19.726258544389, 19.715008895947, 19.703759247505, 19.692509599062, 19.681259950620, 19.670010302178, + 19.658760653736, 19.647511005293, 19.636261356851, 19.625011708409, 19.613762059966, 19.602512411524, + 19.591262763082, 19.580013114640, 19.568763466197, 19.557513817755, 19.546264169313, 19.535014520870, + 19.523764872428, 19.512515223986, 19.501265575543, 19.490015927101, 19.478766278659, 19.467516630216, + 19.456266981774, 19.445017333332, 19.433767684890, 19.422518036447, 19.411268388005, 19.400018739563, + 19.388769091120, 19.377519442678, 19.366269794236, 19.355020145793, 19.343770497351, 19.332520848909, + 19.321271200466, 19.310021552024, 19.298771903582, 19.287522255139, 19.276272606697, 19.265022958255, + 19.253773309812, 19.242523661370, 19.231274012928, 19.220024364486, 19.208774716043, 19.197525067601, + 19.186275419159, 19.175025770716, 19.163776122274, 19.152526473832, 19.141276825389, 19.130027176947, + 19.118777528505, 19.107527880062, 19.096278231620, 19.085028583178, 19.073778934735, 19.062529286293, + 19.051279637851, 19.040029989408, 19.028780340966, 19.017530692524, 19.006281044081, 18.995031395639, + 18.983781747196, 18.972532098754, 18.961282450312, 18.950032801869, 18.938783153427, 18.927533504985, + 18.916283856542, 18.905034208100, 18.893784559658, 18.882534911215, 18.871285262773, 18.860035614331, + 18.848785965888, 18.837536317446, 18.826286669004, 18.815037020561, 18.803787372119, 18.792537723677, + 18.781288075234, 18.770038426792, 18.758788778349, 18.747539129907, 18.736289481465, 18.725039833022, + 18.713790184580, 18.702540536138, 18.691290887695, 18.680041239253, 18.668791590811, 18.657541942368, + 18.646292293926, 18.635042645483, 18.623792997041, 18.612543348599, 18.601293700156, 18.590044051714, + 18.578794403272, 18.567544754829, 18.556295106387, 18.545045457944, 18.533795809502, 18.522546161060, + 18.511296512617, 18.500046864175, 18.488797215733, 18.477547567290, 18.466297918848, 18.455048270405, + 18.443798621963, 18.432548973521, 18.421299325078, 18.410049676636, 18.398800028194, 18.387550379751, + 18.376300731309, 18.365051082866, 18.353801434424, 18.342551785982, 18.331302137539, 18.320052489097, + 18.308802840654, 18.297553192212, 18.286303543770, 18.275053895327, 18.263804246885, 18.252554598442, + 18.241304950000, 18.230055301558, 18.218805653115, 18.207556004673, 18.196306356230, 18.185056707788, + 18.173807059346, 18.162557410903, 18.151307762461, 18.140058114018, 18.128808465576, 18.117558817134, + 18.106309168691, 18.095059520249, 18.083809871806, 18.072560223364, 18.061310574922, 18.050060926479, + 18.038811278037, 18.027561629594, 18.016311981152, 18.005062332710, 17.993812684267, 17.982563035825, + 17.971313387382, 17.960063738940, 17.948814090497, 17.937564442055, 17.926314793613, 17.915065145170, + 17.903815496728, 17.892565848285, 17.881316199843, 17.870066551401, 17.858816902958, 17.847567254516, + 17.836317606073, 17.825067957631, 17.813818309188, 17.802568660746, 17.791319012304, 17.780069363861, + 17.768819715419, 17.757570066976, 17.746320418534, 17.735070770091, 17.723821121649, 17.712571473207, + 17.701321824764, 17.690072176322, 17.678822527879, 17.667572879437, 17.656323230994, 17.645073582552, + 17.633823934110, 17.622574285667, 17.611324637225, 17.600074988782, 17.588825340340, 17.577575691897, + 17.566326043455, 17.555076395012, 17.543826746570, 17.532577098128, 17.521327449685, 17.510077801243, + 17.498828152800, 17.487578504358, 17.476328855915, 17.465079207473, 17.453829559030, 17.442579910588, + 17.431330262145, 17.420080613703, 17.408830965261, 17.397581316818, 17.386331668376, 17.375082019933, + 17.363832371491, 17.352582723048, 17.341333074606, 17.330083426163, 17.318833777721, 17.307584129278, + 17.296334480836, 17.285084832394, 17.273835183951, 17.262585535509, 17.251335887066, 17.240086238624, + 17.228836590181, 17.217586941739, 17.206337293296, 17.195087644854, 17.183837996411, 17.172588347969, + 17.161338699526, 17.150089051084, 17.138839402641, 17.127589754199, 17.116340105757, 17.105090457314, + 17.093840808872, 17.082591160429, 17.071341511987, 17.060091863544, 17.048842215102, 17.037592566659, + 17.026342918217, 17.015093269774, 17.003843621332, 16.992593972889, 16.981344324447, 16.970094676004, + 16.958845027562, 16.947595379119, 16.936345730677, 16.925096082234, 16.913846433792, 16.902596785349, + 16.891347136907, 16.880097488464, 16.868847840022, 16.857598191579, 16.846348543137, 16.835098894695, + 16.823849246252, 16.812599597810, 16.801349949367, 16.790100300925, 16.778850652482, 16.767601004040, + 16.756351355597, 16.745101707155, 16.733852058712, 16.722602410270, 16.711352761827, 16.700103113385, + 16.688853464942, 16.677603816500, 16.666354168057, 16.655104519615, 16.643854871172, 16.632605222730, + 16.621355574287, 16.610105925845, 16.598856277402, 16.587606628960, 16.576356980517, 16.565107332075, + 16.553857683632, 16.542608035190, 16.531358386747, 16.520108738305, 16.508859089862, 16.497609441419, + 16.486359792977, 16.475110144534, 16.463860496092, 16.452610847649, 16.441361199207, 16.430111550764, + 16.418861902322, 16.407612253879, 16.396362605437, 16.385112956994, 16.373863308552, 16.362613660109, + 16.351364011667, 16.340114363224, 16.328864714782, 16.317615066339, 16.306365417897, 16.295115769454, + 16.283866121012, 16.272616472569, 16.261366824127, 16.250117175684, 16.238867527242, 16.227617878799, + 16.216368230356, 16.205118581914, 16.193868933471, 16.182619285029, 16.171369636586, 16.160119988144, + 16.148870339701, 16.137620691259, 16.126371042816, 16.115121394374, 16.103871745931, 16.092622097489, + 16.081372449046, 16.070122800604, 16.058873152161, 16.047623503718, 16.036373855276, 16.025124206833, + 16.013874558391, 16.002624909948, 15.991375261506, 15.980125613063, 15.968875964621, 15.957626316178, + 15.946376667736, 15.935127019293, 15.923877370851, 15.912627722408, 15.901378073965, 15.890128425523, + 15.878878777080, 15.867629128638, 15.856379480195, 15.845129831753, 15.833880183310, 15.822630534868, + 15.811380886425, 15.800131237982, 15.788881589540, 15.777631941097, 15.766382292655, 15.755132644212, + 15.743882995770, 15.732633347327, 15.721383698885, 15.710134050442, 15.698884401999, 15.687634753557, + 15.676385105114, 15.665135456672, 15.653885808229, 15.642636159787, 15.631386511344, 15.620136862902, + 15.608887214459, 15.597637566016, 15.586387917574, 15.575138269131, 15.563888620689, 15.552638972246, + 15.541389323804, 15.530139675361, 15.518890026918, 15.507640378476, 15.496390730033, 15.485141081591, + 15.473891433148, 15.462641784706, 15.451392136263, 15.440142487820, 15.428892839378, 15.417643190935, + 15.406393542493, 15.395143894050, 15.383894245608, 15.372644597165, 15.361394948722, 15.350145300280, + 15.338895651837, 15.327646003395, 15.316396354952, 15.305146706509, 15.293897058067, 15.282647409624, + 15.271397761182, 15.260148112739, 15.248898464297, 15.237648815854, 15.226399167411, 15.215149518969, + 15.203899870526, 15.192650222084, 15.181400573641, 15.170150925198, 15.158901276756, 15.147651628313, + 15.136401979871, 15.125152331428, 15.113902682985, 15.102653034543, 15.091403386100, 15.080153737658, + 15.068904089215, 15.057654440773, 15.046404792330, 15.035155143887, 15.023905495445, 15.012655847002, + 15.001406198560, 14.990156550117, 14.978906901674, 14.967657253232, 14.956407604789, 14.945157956347, + 14.933908307904, 14.922658659461, 14.911409011019, 14.900159362576, 14.888909714134, 14.877660065691, + 14.866410417248, 14.855160768806, 14.843911120363, 14.832661471920, 14.821411823478, 14.810162175035, + 14.798912526593, 14.787662878150, 14.776413229707, 14.765163581265, 14.753913932822, 14.742664284380, + 14.731414635937, 14.720164987494, 14.708915339052, 14.697665690609, 14.686416042167, 14.675166393724, + 14.663916745281, 14.652667096839, 14.641417448396, 14.630167799953, 14.618918151511, 14.607668503068, + 14.596418854626, 14.585169206183, 14.573919557740, 14.562669909298, 14.551420260855, 14.540170612412, + 14.528920963970, 14.517671315527, 14.506421667085, 14.495172018642, 14.483922370199, 14.472672721757, + 14.461423073314, 14.450173424871, 14.438923776429, 14.427674127986, 14.416424479544, 14.405174831101, + 14.393925182658, 14.382675534216, 14.371425885773, 14.360176237330, 14.348926588888, 14.337676940445, + 14.326427292002, 14.315177643560, 14.303927995117, 14.292678346675, 14.281428698232, 14.270179049789, + 14.258929401347, 14.247679752904, 14.236430104461, 14.225180456019, 14.213930807576, 14.202681159133, + 14.191431510691, 14.180181862248, 14.168932213806, 14.157682565363, 14.146432916920, 14.135183268478, + 14.123933620035, 14.112683971592, 14.101434323150, 14.090184674707, 14.078935026264, 14.067685377822, + 14.056435729379, 14.045186080936, 14.033936432494, 14.022686784051, 14.011437135608, 14.000187487166, + 13.988937838723, 13.977688190281, 13.966438541838, 13.955188893395, 13.943939244953, 13.932689596510, + 13.921439948067, 13.910190299625, 13.898940651182, 13.887691002739, 13.876441354297, 13.865191705854, + 13.853942057411, 13.842692408969, 13.831442760526, 13.820193112083, 13.808943463641, 13.797693815198, + 13.786444166755, 13.775194518313, 13.763944869870, 13.752695221427, 13.741445572985, 13.730195924542, + 13.718946276099, 13.707696627657, 13.696446979214, 13.685197330771, 13.673947682329, 13.662698033886, + 13.651448385443, 13.640198737001, 13.628949088558, 13.617699440115, 13.606449791673, 13.595200143230, + 13.583950494787, 13.572700846345, 13.561451197902, 13.550201549459, 13.538951901017, 13.527702252574, + 13.516452604131, 13.505202955689, 13.493953307246, 13.482703658803, 13.471454010361, 13.460204361918, + 13.448954713475, 13.437705065033, 13.426455416590, 13.415205768147, 13.403956119704, 13.392706471262, + 13.381456822819, 13.370207174376, 13.358957525934, 13.347707877491, 13.336458229048, 13.325208580606, + 13.313958932163, 13.302709283720, 13.291459635278, 13.280209986835, 13.268960338392, 13.257710689950, + 13.246461041507, 13.235211393064, 13.223961744622, 13.212712096179, 13.201462447736, 13.190212799293, + 13.178963150851, 13.167713502408, 13.156463853965, 13.145214205523, 13.133964557080, 13.122714908637, + 13.111465260195, 13.100215611752, 13.088965963309, 13.077716314867, 13.066466666424, 13.055217017981, + 13.043967369538, 13.032717721096, 13.021468072653, 13.010218424210, 12.998968775768, 12.987719127325, + 12.976469478882, 12.965219830440, 12.953970181997, 12.942720533554, 12.931470885111, 12.920221236669, + 12.908971588226, 12.897721939783, 12.886472291341, 12.875222642898, 12.863972994455, 12.852723346012, + 12.841473697570, 12.830224049127, 12.818974400684, 12.807724752242, 12.796475103799, 12.785225455356, + 12.773975806913, 12.762726158471, 12.751476510028, 12.740226861585, 12.728977213143, 12.717727564700, + 12.706477916257, 12.695228267815, 12.683978619372, 12.672728970929, 12.661479322486, 12.650229674044, + 12.638980025601, 12.627730377158, 12.616480728715, 12.605231080273, 12.593981431830, 12.582731783387, + 12.571482134945, 12.560232486502, 12.548982838059, 12.537733189616, 12.526483541174, 12.515233892731, + 12.503984244288, 12.492734595846, 12.481484947403, 12.470235298960, 12.458985650517, 12.447736002075, + 12.436486353632, 12.425236705189, 12.413987056746, 12.402737408304, 12.391487759861, 12.380238111418, + 12.368988462976, 12.357738814533, 12.346489166090, 12.335239517647, 12.323989869205, 12.312740220762, + 12.301490572319, 12.290240923876, 12.278991275434, 12.267741626991, 12.256491978548, 12.245242330106, + 12.233992681663, 12.222743033220, 12.211493384777, 12.200243736335, 12.188994087892, 12.177744439449, + 12.166494791006, 12.155245142564, 12.143995494121, 12.132745845678, 12.121496197235, 12.110246548793, + 12.098996900350, 12.087747251907, 12.076497603464, 12.065247955022, 12.053998306579, 12.042748658136, + 12.031499009693, 12.020249361251, 12.008999712808, 11.997750064365, 11.986500415922, 11.975250767480, + 11.964001119037, 11.952751470594, 11.941501822152, 11.930252173709, 11.919002525266, 11.907752876823, + 11.896503228381, 11.885253579938, 11.874003931495, 11.862754283052, 11.851504634610, 11.840254986167, + 11.829005337724, 11.817755689281, 11.806506040839, 11.795256392396, 11.784006743953, 11.772757095510, + 11.761507447067, 11.750257798625, 11.739008150182, 11.727758501739, 11.716508853296, 11.705259204854, + 11.694009556411, 11.682759907968, 11.671510259525, 11.660260611083, 11.649010962640, 11.637761314197, + 11.626511665754, 11.615262017312, 11.604012368869, 11.592762720426, 11.581513071983, 11.570263423541, + 11.559013775098, 11.547764126655, 11.536514478212, 11.525264829770, 11.514015181327, 11.502765532884, + 11.491515884441, 11.480266235998, 11.469016587556, 11.457766939113, 11.446517290670, 11.435267642227, + 11.424017993785, 11.412768345342, 11.401518696899, 11.390269048456, 11.379019400014, 11.367769751571, + 11.356520103128, 11.345270454685, 11.334020806242, 11.322771157800, 11.311521509357, 11.300271860914, + 11.289022212471, 11.277772564029, 11.266522915586, 11.255273267143, 11.244023618700, 11.232773970257, + 11.221524321815, 11.210274673372, 11.199025024929, 11.187775376486, 11.176525728044, 11.165276079601, + 11.154026431158, 11.142776782715, 11.131527134272, 11.120277485830, 11.109027837387, 11.097778188944, + 11.086528540501, 11.075278892059, 11.064029243616, 11.052779595173, 11.041529946730, 11.030280298287, + 11.019030649845, 11.007781001402, 10.996531352959, 10.985281704516, 10.974032056074, 10.962782407631, + 10.951532759188, 10.940283110745, 10.929033462302, 10.917783813860, 10.906534165417, 10.895284516974, + 10.884034868531, 10.872785220088, 10.861535571646, 10.850285923203, 10.839036274760, 10.827786626317, + 10.816536977874, 10.805287329432, 10.794037680989, 10.782788032546, 10.771538384103, 10.760288735660, + 10.749039087218, 10.737789438775, 10.726539790332, 10.715290141889, 10.704040493446, 10.692790845004, + 10.681541196561, 10.670291548118, 10.659041899675, 10.647792251233, 10.636542602790, 10.625292954347, + 10.614043305904, 10.602793657461, 10.591544009019, 10.580294360576, 10.569044712133, 10.557795063690, + 10.546545415247, 10.535295766804, 10.524046118362, 10.512796469919, 10.501546821476, 10.490297173033, + 10.479047524590, 10.467797876148, 10.456548227705, 10.445298579262, 10.434048930819, 10.422799282376, + 10.411549633934, 10.400299985491, 10.389050337048, 10.377800688605, 10.366551040162, 10.355301391720, + 10.344051743277, 10.332802094834, 10.321552446391, 10.310302797948, 10.299053149506, 10.287803501063, + 10.276553852620, 10.265304204177, 10.254054555734, 10.242804907291, 10.231555258849, 10.220305610406, + 10.209055961963, 10.197806313520, 10.186556665077, 10.175307016635, 10.164057368192, 10.152807719749, + 10.141558071306, 10.130308422863, 10.119058774420, 10.107809125978, 10.096559477535, 10.085309829092, + 10.074060180649, 10.062810532206, 10.051560883764, 10.040311235321, 10.029061586878, 10.017811938435, + 10.006562289992, 9.995312641549, 9.984062993107, 9.972813344664, 9.961563696221, 9.950314047778, 9.939064399335, + 9.927814750893, 9.916565102450, 9.905315454007, 9.894065805564, 9.882816157121, 9.871566508678, 9.860316860236, + 9.849067211793, 9.837817563350, 9.826567914907, 9.815318266464, 9.804068618021, 9.792818969579, 9.781569321136, + 9.770319672693, 9.759070024250, 9.747820375807, 9.736570727364, 9.725321078922, 9.714071430479, 9.702821782036, + 9.691572133593, 9.680322485150, 9.669072836707, 9.657823188265, 9.646573539822, 9.635323891379, 9.624074242936, + 9.612824594493, 9.601574946050, 9.590325297608, 9.579075649165, 9.567826000722, 9.556576352279, 9.545326703836, + 9.534077055393, 9.522827406951, 9.511577758508, 9.500328110065, 9.489078461622, 9.477828813179, 9.466579164736, + 9.455329516294, 9.444079867851, 9.432830219408, 9.421580570965, 9.410330922522, 9.399081274079, 9.387831625636, + 9.376581977194, 9.365332328751, 9.354082680308, 9.342833031865, 9.331583383422, 9.320333734979, 9.309084086537, + 9.297834438094, 9.286584789651, 9.275335141208, 9.264085492765, 9.252835844322, 9.241586195879, 9.230336547437, + 9.219086898994, 9.207837250551, 9.196587602108, 9.185337953665, 9.174088305222, 9.162838656780, 9.151589008337, + 9.140339359894, 9.129089711451, 9.117840063008, 9.106590414565, 9.095340766122, 9.084091117680, 9.072841469237, + 9.061591820794, 9.050342172351, 9.039092523908, 9.027842875465, 9.016593227022, 9.005343578580, 8.994093930137, + 8.982844281694, 8.971594633251, 8.960344984808, 8.949095336365, 8.937845687922, 8.926596039480, 8.915346391037, + 8.904096742594, 8.892847094151, 8.881597445708, 8.870347797265, 8.859098148822, 8.847848500380, 8.836598851937, + 8.825349203494, 8.814099555051, 8.802849906608, 8.791600258165, 8.780350609722, 8.769100961280, 8.757851312837, + 8.746601664394, 8.735352015951, 8.724102367508, 8.712852719065, 8.701603070622, 8.690353422180, 8.679103773737, + 8.667854125294, 8.656604476851, 8.645354828408, 8.634105179965, 8.622855531522, 8.611605883079, 8.600356234637, + 8.589106586194, 8.577856937751, 8.566607289308, 8.555357640865, 8.544107992422, 8.532858343979, 8.521608695537, + 8.510359047094, 8.499109398651, 8.487859750208, 8.476610101765, 8.465360453322, 8.454110804879, 8.442861156436, + 8.431611507994, 8.420361859551, 8.409112211108, 8.397862562665, 8.386612914222, 8.375363265779, 8.364113617336, + 8.352863968893, 8.341614320451, 8.330364672008, 8.319115023565, 8.307865375122, 8.296615726679, 8.285366078236, + 8.274116429793, 8.262866781350, 8.251617132908, 8.240367484465, 8.229117836022, 8.217868187579, 8.206618539136, + 8.195368890693, 8.184119242250, 8.172869593807, 8.161619945364, 8.150370296922, 8.139120648479, 8.127871000036, + 8.116621351593, 8.105371703150, 8.094122054707, 8.082872406264, 8.071622757821, 8.060373109379, 8.049123460936, + 8.037873812493, 8.026624164050, 8.015374515607, 8.004124867164, 7.992875218721, 7.981625570278, 7.970375921835, + 7.959126273393, 7.947876624950, 7.936626976507, 7.925377328064, 7.914127679621, 7.902878031178, 7.891628382735, + 7.880378734292, 7.869129085849, 7.857879437407, 7.846629788964, 7.835380140521, 7.824130492078, 7.812880843635, + 7.801631195192, 7.790381546749, 7.779131898306, 7.767882249863, 7.756632601421, 7.745382952978, 7.734133304535, + 7.722883656092, 7.711634007649, 7.700384359206, 7.689134710763, 7.677885062320, 7.666635413877, 7.655385765435, + 7.644136116992, 7.632886468549, 7.621636820106, 7.610387171663, 7.599137523220, 7.587887874777, 7.576638226334, + 7.565388577891, 7.554138929449, 7.542889281006, 7.531639632563, 7.520389984120, 7.509140335677, 7.497890687234, + 7.486641038791, 7.475391390348, 7.464141741905, 7.452892093462, 7.441642445020, 7.430392796577, 7.419143148134, + 7.407893499691, 7.396643851248, 7.385394202805, 7.374144554362, 7.362894905919, 7.351645257476, 7.340395609033, + 7.329145960591, 7.317896312148, 7.306646663705, 7.295397015262, 7.284147366819, 7.272897718376, 7.261648069933, + 7.250398421490, 7.239148773047, 7.227899124604, 7.216649476161, 7.205399827719, 7.194150179276, 7.182900530833, + 7.171650882390, 7.160401233947, 7.149151585504, 7.137901937061, 7.126652288618, 7.115402640175, 7.104152991732, + 7.092903343289, 7.081653694847, 7.070404046404, 7.059154397961, 7.047904749518, 7.036655101075, 7.025405452632, + 7.014155804189, 7.002906155746, 6.991656507303, 6.980406858860, 6.969157210417, 6.957907561975, 6.946657913532, + 6.935408265089, 6.924158616646, 6.912908968203, 6.901659319760, 6.890409671317, 6.879160022874, 6.867910374431, + 6.856660725988, 6.845411077545, 6.834161429103, 6.822911780660, 6.811662132217, 6.800412483774, 6.789162835331, + 6.777913186888, 6.766663538445, 6.755413890002, 6.744164241559, 6.732914593116, 6.721664944673, 6.710415296230, + 6.699165647788, 6.687915999345, 6.676666350902, 6.665416702459, 6.654167054016, 6.642917405573, 6.631667757130, + 6.620418108687, 6.609168460244, 6.597918811801, 6.586669163358, 6.575419514915, 6.564169866473, 6.552920218030, + 6.541670569587, 6.530420921144, 6.519171272701, 6.507921624258, 6.496671975815, 6.485422327372, 6.474172678929, + 6.462923030486, 6.451673382043, 6.440423733600, 6.429174085157, 6.417924436715, 6.406674788272, 6.395425139829, + 6.384175491386, 6.372925842943, 6.361676194500, 6.350426546057, 6.339176897614, 6.327927249171, 6.316677600728, + 6.305427952285, 6.294178303842, 6.282928655399, 6.271679006956, 6.260429358514, 6.249179710071, 6.237930061628, + 6.226680413185, 6.215430764742, 6.204181116299, 6.192931467856, 6.181681819413, 6.170432170970, 6.159182522527, + 6.147932874084, 6.136683225641, 6.125433577198, 6.114183928755, 6.102934280313, 6.091684631870, 6.080434983427, + 6.069185334984, 6.057935686541, 6.046686038098, 6.035436389655, 6.024186741212, 6.012937092769, 6.001687444326, + 5.990437795883, 5.979188147440, 5.967938498997, 5.956688850554, 5.945439202112, 5.934189553669, 5.922939905226, + 5.911690256783, 5.900440608340, 5.889190959897, 5.877941311454, 5.866691663011, 5.855442014568, 5.844192366125, + 5.832942717682, 5.821693069239, 5.810443420796, 5.799193772353, 5.787944123910, 5.776694475467, 5.765444827025, + 5.754195178582, 5.742945530139, 5.731695881696, 5.720446233253, 5.709196584810, 5.697946936367, 5.686697287924, + 5.675447639481, 5.664197991038, 5.652948342595, 5.641698694152, 5.630449045709, 5.619199397266, 5.607949748823, + 5.596700100380, 5.585450451938, 5.574200803495, 5.562951155052, 5.551701506609, 5.540451858166, 5.529202209723, + 5.517952561280, 5.506702912837, 5.495453264394, 5.484203615951, 5.472953967508, 5.461704319065, 5.450454670622, + 5.439205022179, 5.427955373736, 5.416705725293, 5.405456076850, 5.394206428407, 5.382956779965, 5.371707131522, + 5.360457483079, 5.349207834636, 5.337958186193, 5.326708537750, 5.315458889307, 5.304209240864, 5.292959592421, + 5.281709943978, 5.270460295535, 5.259210647092, 5.247960998649, 5.236711350206, 5.225461701763, 5.214212053320, + 5.202962404877, 5.191712756434, 5.180463107992, 5.169213459549, 5.157963811106, 5.146714162663, 5.135464514220, + 5.124214865777, 5.112965217334, 5.101715568891, 5.090465920448, 5.079216272005, 5.067966623562, 5.056716975119, + 5.045467326676, 5.034217678233, 5.022968029790, 5.011718381347, 5.000468732904, 4.989219084461, 4.977969436018, + 4.966719787575, 4.955470139133, 4.944220490690, 4.932970842247, 4.921721193804, 4.910471545361, 4.899221896918, + 4.887972248475, 4.876722600032, 4.865472951589, 4.854223303146, 4.842973654703, 4.831724006260, 4.820474357817, + 4.809224709374, 4.797975060931, 4.786725412488, 4.775475764045, 4.764226115602, 4.752976467159, 4.741726818716, + 4.730477170273, 4.719227521830, 4.707977873388, 4.696728224945, 4.685478576502, 4.674228928059, 4.662979279616, + 4.651729631173, 4.640479982730, 4.629230334287, 4.617980685844, 4.606731037401, 4.595481388958, 4.584231740515, + 4.572982092072, 4.561732443629, 4.550482795186, 4.539233146743, 4.527983498300, 4.516733849857, 4.505484201414, + 4.494234552971, 4.482984904528, 4.471735256085, 4.460485607642, 4.449235959199, 4.437986310757, 4.426736662314, + 4.415487013871, 4.404237365428, 4.392987716985, 4.381738068542, 4.370488420099, 4.359238771656, 4.347989123213, + 4.336739474770, 4.325489826327, 4.314240177884, 4.302990529441, 4.291740880998, 4.280491232555, 4.269241584112, + 4.257991935669, 4.246742287226, 4.235492638783, 4.224242990340, 4.212993341897, 4.201743693454, 4.190494045011, + 4.179244396568, 4.167994748125, 4.156745099682, 4.145495451240, 4.134245802797, 4.122996154354, 4.111746505911, + 4.100496857468, 4.089247209025, 4.077997560582, 4.066747912139, 4.055498263696, 4.044248615253, 4.032998966810, + 4.021749318367, 4.010499669924, 3.999250021481, 3.988000373038, 3.976750724595, 3.965501076152, 3.954251427709, + 3.943001779266, 3.931752130823, 3.920502482380, 3.909252833937, 3.898003185494, 3.886753537051, 3.875503888608, + 3.864254240165, 3.853004591722, 3.841754943279, 3.830505294836, 3.819255646393, 3.808005997951, 3.796756349508, + 3.785506701065, 3.774257052622, 3.763007404179, 3.751757755736, 3.740508107293, 3.729258458850, 3.718008810407, + 3.706759161964, 3.695509513521, 3.684259865078, 3.673010216635, 3.661760568192, 3.650510919749, 3.639261271306, + 3.628011622863, 3.616761974420, 3.605512325977, 3.594262677534, 3.583013029091, 3.571763380648, 3.560513732205, + 3.549264083762, 3.538014435319, 3.526764786876, 3.515515138433, 3.504265489990, 3.493015841547, 3.481766193104, + 3.470516544661, 3.459266896218, 3.448017247775, 3.436767599332, 3.425517950889, 3.414268302447, 3.403018654004, + 3.391769005561, 3.380519357118, 3.369269708675, 3.358020060232, 3.346770411789, 3.335520763346, 3.324271114903, + 3.313021466460, 3.301771818017, 3.290522169574, 3.279272521131, 3.268022872688, 3.256773224245, 3.245523575802, + 3.234273927359, 3.223024278916, 3.211774630473, 3.200524982030, 3.189275333587, 3.178025685144, 3.166776036701, + 3.155526388258, 3.144276739815, 3.133027091372, 3.121777442929, 3.110527794486, 3.099278146043, 3.088028497600, + 3.076778849157, 3.065529200714, 3.054279552271, 3.043029903828, 3.031780255385, 3.020530606942, 3.009280958499, + 2.998031310056, 2.986781661613, 2.975532013170, 2.964282364727, 2.953032716284, 2.941783067841, 2.930533419399, + 2.919283770956, 2.908034122513, 2.896784474070, 2.885534825627, 2.874285177184, 2.863035528741, 2.851785880298, + 2.840536231855, 2.829286583412, 2.818036934969, 2.806787286526, 2.795537638083, 2.784287989640, 2.773038341197, + 2.761788692754, 2.750539044311, 2.739289395868, 2.728039747425, 2.716790098982, 2.705540450539, 2.694290802096, + 2.683041153653, 2.671791505210, 2.660541856767, 2.649292208324, 2.638042559881, 2.626792911438, 2.615543262995, + 2.604293614552, 2.593043966109, 2.581794317666, 2.570544669223, 2.559295020780, 2.548045372337, 2.536795723894, + 2.525546075451, 2.514296427008, 2.503046778565, 2.491797130122, 2.480547481679, 2.469297833236, 2.458048184793, + 2.446798536350, 2.435548887907, 2.424299239464, 2.413049591021, 2.401799942578, 2.390550294135, 2.379300645692, + 2.368050997249, 2.356801348806, 2.345551700363, 2.334302051920, 2.323052403478, 2.311802755035, 2.300553106592, + 2.289303458149, 2.278053809706, 2.266804161263, 2.255554512820, 2.244304864377, 2.233055215934, 2.221805567491, + 2.210555919048, 2.199306270605, 2.188056622162, 2.176806973719, 2.165557325276, 2.154307676833, 2.143058028390, + 2.131808379947, 2.120558731504, 2.109309083061, 2.098059434618, 2.086809786175, 2.075560137732, 2.064310489289, + 2.053060840846, 2.041811192403, 2.030561543960, 2.019311895517, 2.008062247074, 1.996812598631, 1.985562950188, + 1.974313301745, 1.963063653302, 1.951814004859, 1.940564356416, 1.929314707973, 1.918065059530, 1.906815411087, + 1.895565762644, 1.884316114201, 1.873066465758, 1.861816817315, 1.850567168872, 1.839317520429, 1.828067871986, + 1.816818223543, 1.805568575100, 1.794318926657, 1.783069278214, 1.771819629771, 1.760569981328, 1.749320332885, + 1.738070684442, 1.726821035999, 1.715571387556, 1.704321739113, 1.693072090670, 1.681822442227, 1.670572793784, + 1.659323145341, 1.648073496898, 1.636823848455, 1.625574200012, 1.614324551569, 1.603074903126, 1.591825254683, + 1.580575606240, 1.569325957797, 1.558076309354, 1.546826660911, 1.535577012468, 1.524327364025, 1.513077715582, + 1.501828067139, 1.490578418696, 1.479328770253, 1.468079121810, 1.456829473367, 1.445579824924, 1.434330176482, + 1.423080528039, 1.411830879596, 1.400581231153, 1.389331582710, 1.378081934267, 1.366832285824, 1.355582637381, + 1.344332988938, 1.333083340495, 1.321833692052, 1.310584043609, 1.299334395166, 1.288084746723, 1.276835098280, + 1.265585449837, 1.254335801394, 1.243086152951, 1.231836504508, 1.220586856065, 1.209337207622, 1.198087559179, + 1.186837910736, 1.175588262293, 1.164338613850, 1.153088965407, 1.141839316964, 1.130589668521, 1.119340020078, + 1.108090371635, 1.096840723192, 1.085591074749, 1.074341426306, 1.063091777863, 1.051842129420, 1.040592480977, + 1.029342832534, 1.018093184091, 1.006843535648, 0.995593887205, 0.984344238762, 0.973094590319, 0.961844941876, + 0.950595293433, 0.939345644990, 0.928095996547, 0.916846348104, 0.905596699661, 0.894347051218, 0.883097402775, + 0.871847754332, 0.860598105889, 0.849348457446, 0.838098809003, 0.826849160560, 0.815599512117, 0.804349863674, + 0.793100215231, 0.781850566788, 0.770600918345, 0.759351269902, 0.748101621459, 0.736851973016, 0.725602324573, + 0.714352676130, 0.703103027687, 0.691853379244, 0.680603730801, 0.669354082358, 0.658104433915, 0.646854785472, + 0.635605137029, 0.624355488586, 0.613105840143, 0.601856191700, 0.590606543257, 0.579356894814, 0.568107246371, + 0.556857597928, 0.545607949485, 0.534358301042, 0.523108652599, 0.511859004156, 0.500609355713, 0.489359707270, + 0.478110058827, 0.466860410384, 0.455610761941, 0.444361113498, 0.433111465055, 0.421861816612, 0.410612168169, + 0.399362519726, 0.388112871283, 0.376863222840, 0.365613574397, 0.354363925954, 0.343114277511, 0.331864629068, + 0.320614980625, 0.309365332182, 0.298115683739, 0.286866035296, 0.275616386853, 0.264366738410, 0.253117089967, + 0.241867441524, 0.230617793081, 0.219368144638, 0.208118496195, 0.196868847752, 0.185619199309, 0.174369550866, + 0.163119902423, 0.151870253980, 0.140620605537, 0.129370957094, 0.118121308651, 0.106871660208, 0.095622011765, + 0.084372363322, 0.073122714879, 0.061873066436, 0.050623417993, 0.039373769550, 0.028124121107, 0.016874472664, + 0.005624824221 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/grid/detail/spacing/gaussian/N96.cc b/src/atlas/grid/detail/spacing/gaussian/N96.cc index c82061a33..2aa15b282 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N96.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N96.cc @@ -7,31 +7,25 @@ namespace grid { namespace spacing { namespace gaussian { -DEFINE_GAUSSIAN_LATITUDES(96,LIST( - 89.284227532514, 88.357003518665, 87.424303746070, 86.490366766281, 85.555960484893, - 84.621327107649, 83.686566816564, 82.751728473431, 81.816838728603, 80.881913346797, - 79.946962247386, 79.011991982672, 78.077007054304, 77.142010657054, 76.207005120861, - 75.271992184860, 74.336973173452, 73.401949112957, 72.466920811004, 71.531888911827, - 70.596853935603, 69.661816306938, 68.726776375860, 67.791734433501, 66.856690723993, - 65.921645453587, 64.986598797727, 64.051550906600, 63.116501909529, 62.181451918473, - 61.246401030854, 60.311349331843, 59.376296896232, 58.441243789970, 57.506190071435, - 56.571135792495, 55.636080999393, 54.701025733491, 53.765970031901, 52.830913928020, - 51.895857451987, 50.960800631070, 50.025743490008, 49.090686051296, 48.155628335437, - 47.220570361160, 46.285512145613, 45.350453704525, 44.415395052354, 43.480336202416, - 42.545277166998, 41.610217957456, 40.675158584305, 39.740099057298, 38.805039385498, - 37.869979577337, 36.934919640674, 35.999859582846, 35.064799410712, 34.129739130695, - 33.194678748816, 32.259618270730, 31.324557701757, 30.389497046905, 29.454436310897, - 28.519375498194, 27.584314613017, 26.649253659362, 25.714192641019, 24.779131561590, - 23.844070424500, 22.909009233010, 21.973947990236, 21.038886699150, 20.103825362598, - 19.168763983309, 18.233702563901, 17.298641106891, 16.363579614703, 15.428518089674, - 14.493456534065, 13.558394950061, 12.623333339782, 11.688271705287, 10.753210048579, - 9.818148371612, 8.883086676292, 7.948024964486, 7.012963238024, 6.077901498705, - 5.142839748298, 4.207777988549, 3.272716221183, 2.337654447911, 1.402592670428, - 0.467530890423 -)) +DEFINE_GAUSSIAN_LATITUDES( + 96, LIST( 89.284227532514, 88.357003518665, 87.424303746070, 86.490366766281, 85.555960484893, 84.621327107649, + 83.686566816564, 82.751728473431, 81.816838728603, 80.881913346797, 79.946962247386, 79.011991982672, + 78.077007054304, 77.142010657054, 76.207005120861, 75.271992184860, 74.336973173452, 73.401949112957, + 72.466920811004, 71.531888911827, 70.596853935603, 69.661816306938, 68.726776375860, 67.791734433501, + 66.856690723993, 65.921645453587, 64.986598797727, 64.051550906600, 63.116501909529, 62.181451918473, + 61.246401030854, 60.311349331843, 59.376296896232, 58.441243789970, 57.506190071435, 56.571135792495, + 55.636080999393, 54.701025733491, 53.765970031901, 52.830913928020, 51.895857451987, 50.960800631070, + 50.025743490008, 49.090686051296, 48.155628335437, 47.220570361160, 46.285512145613, 45.350453704525, + 44.415395052354, 43.480336202416, 42.545277166998, 41.610217957456, 40.675158584305, 39.740099057298, + 38.805039385498, 37.869979577337, 36.934919640674, 35.999859582846, 35.064799410712, 34.129739130695, + 33.194678748816, 32.259618270730, 31.324557701757, 30.389497046905, 29.454436310897, 28.519375498194, + 27.584314613017, 26.649253659362, 25.714192641019, 24.779131561590, 23.844070424500, 22.909009233010, + 21.973947990236, 21.038886699150, 20.103825362598, 19.168763983309, 18.233702563901, 17.298641106891, + 16.363579614703, 15.428518089674, 14.493456534065, 13.558394950061, 12.623333339782, 11.688271705287, + 10.753210048579, 9.818148371612, 8.883086676292, 7.948024964486, 7.012963238024, 6.077901498705, + 5.142839748298, 4.207777988549, 3.272716221183, 2.337654447911, 1.402592670428, 0.467530890423 ) ) } // namespace gaussian } // namespace spacing } // namespace grid } // namespace atlas - diff --git a/src/atlas/interpolation.h b/src/atlas/interpolation.h index 10c11c929..ce8e25d7b 100644 --- a/src/atlas/interpolation.h +++ b/src/atlas/interpolation.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ diff --git a/src/atlas/interpolation/Interpolation.cc b/src/atlas/interpolation/Interpolation.cc index ac1d3ebb0..819cb818e 100644 --- a/src/atlas/interpolation/Interpolation.cc +++ b/src/atlas/interpolation/Interpolation.cc @@ -4,60 +4,61 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "atlas/interpolation/Interpolation.h" -#include "eckit/exception/Exceptions.h" #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" +#include "eckit/exception/Exceptions.h" namespace atlas { Interpolation::Interpolation( const Config& config, const FunctionSpace& source, const FunctionSpace& target ) : - implementation_( [&]() -> Implementation* { - std::string type; - config.get("type",type); - Implementation* impl = interpolation::MethodFactory::build(type,config); - impl->setup(source,target); - return impl; }()) { -} + implementation_( [&]() -> Implementation* { + std::string type; + config.get( "type", type ); + Implementation* impl = interpolation::MethodFactory::build( type, config ); + impl->setup( source, target ); + return impl; + }() ) {} -Interpolation::Interpolation( const Interpolation& other ) : - implementation_( other.implementation_ ) { -} +Interpolation::Interpolation( const Interpolation& other ) : implementation_( other.implementation_ ) {} extern "C" { -Interpolation::Implementation* atlas__Interpolation__new(const eckit::Parametrisation* config, const functionspace::FunctionSpaceImpl* source, const functionspace::FunctionSpaceImpl* target) { - Interpolation::Implementation* interpolator; - { - Interpolation im(*config,FunctionSpace(source),FunctionSpace(target)); - interpolator = const_cast(im.get()); - interpolator->attach(); - } - interpolator->detach(); - return interpolator; +Interpolation::Implementation* atlas__Interpolation__new( const eckit::Parametrisation* config, + const functionspace::FunctionSpaceImpl* source, + const functionspace::FunctionSpaceImpl* target ) { + Interpolation::Implementation* interpolator; + { + Interpolation im( *config, FunctionSpace( source ), FunctionSpace( target ) ); + interpolator = const_cast( im.get() ); + interpolator->attach(); + } + interpolator->detach(); + return interpolator; } -void atlas__Interpolation__delete(Interpolation::Implementation* This) { - delete This; +void atlas__Interpolation__delete( Interpolation::Implementation* This ) { + delete This; } -void atlas__Interpolation__execute_field(Interpolation::Implementation* This, const field::FieldImpl* source, field::FieldImpl* target) { - Field t(target); - This->execute( Field(source), t ); +void atlas__Interpolation__execute_field( Interpolation::Implementation* This, const field::FieldImpl* source, + field::FieldImpl* target ) { + Field t( target ); + This->execute( Field( source ), t ); } -void atlas__Interpolation__execute_fieldset(Interpolation::Implementation* This, const field::FieldSetImpl* source, field::FieldSetImpl* target) { - FieldSet t(target); - This->execute( FieldSet(source), t ); +void atlas__Interpolation__execute_fieldset( Interpolation::Implementation* This, const field::FieldSetImpl* source, + field::FieldSetImpl* target ) { + FieldSet t( target ); + This->execute( FieldSet( source ), t ); } -} // extern "C" - -} // atlas +} // extern "C" +} // namespace atlas diff --git a/src/atlas/interpolation/Interpolation.h b/src/atlas/interpolation/Interpolation.h index c60dea734..19eb5119c 100644 --- a/src/atlas/interpolation/Interpolation.h +++ b/src/atlas/interpolation/Interpolation.h @@ -4,64 +4,65 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once +#include "atlas/interpolation/method/Method.h" #include "eckit/config/Configuration.h" #include "eckit/memory/SharedPtr.h" -#include "atlas/interpolation/method/Method.h" namespace atlas { - class Field; - class FieldSet; - class FunctionSpace; -} +class Field; +class FieldSet; +class FunctionSpace; +} // namespace atlas namespace atlas { class Interpolation { public: + using Implementation = interpolation::Method; + using Config = Implementation::Config; - using Implementation = interpolation::Method; - using Config = Implementation::Config; - - Interpolation() {} - Interpolation( const Interpolation& ); - Interpolation( const Config&, const FunctionSpace& source, const FunctionSpace& target ); + Interpolation() {} + Interpolation( const Interpolation& ); + Interpolation( const Config&, const FunctionSpace& source, const FunctionSpace& target ); - void execute(const FieldSet& source, FieldSet& target) const { get()->execute(source,target); } - void execute(const Field& source, Field& target) const { get()->execute(source,target); } + void execute( const FieldSet& source, FieldSet& target ) const { get()->execute( source, target ); } + void execute( const Field& source, Field& target ) const { get()->execute( source, target ); } - const Implementation* get() const { return implementation_.get(); } + const Implementation* get() const { return implementation_.get(); } - operator bool() const { return implementation_; } + operator bool() const { return implementation_; } private: - - eckit::SharedPtr implementation_; - + eckit::SharedPtr implementation_; }; /// C-interface namespace functionspace { - class FunctionSpaceImpl; +class FunctionSpaceImpl; } namespace field { - class FieldImpl; - class FieldSetImpl; -} +class FieldImpl; +class FieldSetImpl; +} // namespace field extern "C" { -Interpolation::Implementation* atlas__Interpolation__new(const eckit::Parametrisation* config, const functionspace::FunctionSpaceImpl* source, const functionspace::FunctionSpaceImpl* target); -void atlas__Interpolation__delete(Interpolation::Implementation* This); -void atlas__Interpolation__execute_field(Interpolation::Implementation* This, const field::FieldImpl* source, field::FieldImpl* target); -void atlas__Interpolation__execute_fieldset(Interpolation::Implementation* This, const field::FieldSetImpl* source, field::FieldSetImpl* target); - +Interpolation::Implementation* atlas__Interpolation__new( const eckit::Parametrisation* config, + const functionspace::FunctionSpaceImpl* source, + const functionspace::FunctionSpaceImpl* target ); +void atlas__Interpolation__delete( Interpolation::Implementation* This ); +void atlas__Interpolation__execute_field( Interpolation::Implementation* This, const field::FieldImpl* source, + field::FieldImpl* target ); +void atlas__Interpolation__execute_fieldset( Interpolation::Implementation* This, const field::FieldSetImpl* source, + field::FieldSetImpl* target ); } -} // atlas +} // namespace atlas diff --git a/src/atlas/interpolation/Vector2D.h b/src/atlas/interpolation/Vector2D.h index dddca2e1e..b982146d2 100644 --- a/src/atlas/interpolation/Vector2D.h +++ b/src/atlas/interpolation/Vector2D.h @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include #include +#include #include "atlas/library/config.h" @@ -33,84 +34,62 @@ namespace interpolation { #ifdef ATLAS_HAVE_EIGEN -typedef Eigen::Vector2d Vector2D; +typedef Eigen::Vector2d Vector2D; #else class Vector2D { - private: - - Vector2D(const double *d) { +private: + Vector2D( const double* d ) { xy_[0] = d[0]; xy_[1] = d[1]; } - Vector2D(double x, double y) { + Vector2D( double x, double y ) { xy_[0] = x; xy_[1] = y; } - public: - +public: Vector2D() { // Warning, data_ is uninitialised } - static Vector2D Map(const double *data) { - return Vector2D(data); - } + static Vector2D Map( const double* data ) { return Vector2D( data ); } // Operators - double operator[](size_t i) const { return xy_[i]; } + double operator[]( size_t i ) const { return xy_[i]; } // Vector2D operator*(const Vector2D &) const; - Vector2D operator-(const Vector2D &other) const { - return Vector2D(x() - other.x(), y() - other.y()); - } + Vector2D operator-( const Vector2D& other ) const { return Vector2D( x() - other.x(), y() - other.y() ); } - Vector2D operator+(const Vector2D &other) const { - return Vector2D(x() + other.x(), y() + other.y()); - } + Vector2D operator+( const Vector2D& other ) const { return Vector2D( x() + other.x(), y() + other.y() ); } - Vector2D operator-() const { - return Vector2D(-x(), -y()); - } + Vector2D operator-() const { return Vector2D( -x(), -y() ); } - double norm() const { - return sqrt(squaredNorm()); - } + double norm() const { return sqrt( squaredNorm() ); } - double squaredNorm() const { - return x() * x() + y() * y(); - } + double squaredNorm() const { return x() * x() + y() * y(); } - double dot(const Vector2D &other) const { - return x() * other.x() + y() * other.y(); - } + double dot( const Vector2D& other ) const { return x() * other.x() + y() * other.y(); } - double cross(const Vector2D &other) const { - return x() * other.y() - y() * other.x(); - } + double cross( const Vector2D& other ) const { return x() * other.y() - y() * other.x(); } - void print(std::ostream &s) const { - s << "[" << x() << "," << y() << "]"; - } + void print( std::ostream& s ) const { s << "[" << x() << "," << y() << "]"; } - friend std::ostream &operator<<(std::ostream &s, const Vector2D &p) { - p.print(s); + friend std::ostream& operator<<( std::ostream& s, const Vector2D& p ) { + p.print( s ); return s; } - private: - +private: double x() const { return xy_[0]; } double y() const { return xy_[1]; } double xy_[2]; - }; -Vector2D operator*(double, const Vector2D &); +Vector2D operator*( double, const Vector2D& ); #endif diff --git a/src/atlas/interpolation/Vector3D.h b/src/atlas/interpolation/Vector3D.h index c4b412d16..bc3c97dae 100644 --- a/src/atlas/interpolation/Vector3D.h +++ b/src/atlas/interpolation/Vector3D.h @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include #include +#include #include "atlas/library/config.h" @@ -33,95 +34,75 @@ namespace interpolation { #ifdef ATLAS_HAVE_EIGEN -typedef Eigen::Vector3d Vector3D; +typedef Eigen::Vector3d Vector3D; #else class Vector3D { - public: - - Vector3D(const double *d) { +public: + Vector3D( const double* d ) { xyz_[0] = d[0]; xyz_[1] = d[1]; xyz_[2] = d[2]; } - Vector3D(double x, double y, double z) { + Vector3D( double x, double y, double z ) { xyz_[0] = x; xyz_[1] = y; xyz_[2] = z; - } + } Vector3D() { // Warning, data_ is uninitialised } - static Vector3D Map(const double *data) { - return Vector3D(data); - } + static Vector3D Map( const double* data ) { return Vector3D( data ); } // Operators - double operator[](size_t i) const { return xyz_[i]; } + double operator[]( size_t i ) const { return xyz_[i]; } // Vector3D operator*(const Vector3D &) const; - Vector3D operator-(const Vector3D &other) const { - return Vector3D(x() - other.x(), y() - other.y(), z() - other.z()); + Vector3D operator-( const Vector3D& other ) const { + return Vector3D( x() - other.x(), y() - other.y(), z() - other.z() ); } - Vector3D operator+(const Vector3D &other) const { - return Vector3D(x() + other.x(), y() + other.y(), z() + other.z()); + Vector3D operator+( const Vector3D& other ) const { + return Vector3D( x() + other.x(), y() + other.y(), z() + other.z() ); } - Vector3D operator-() const { - return Vector3D(-x(), -y(), -z()); - } + Vector3D operator-() const { return Vector3D( -x(), -y(), -z() ); } - double norm() const { - return sqrt(squaredNorm()); - } + double norm() const { return sqrt( squaredNorm() ); } - double squaredNorm() const { - return x() * x() + y() * y() + z() * z(); - } + double squaredNorm() const { return x() * x() + y() * y() + z() * z(); } - double dot(const Vector3D &other) const { - return x() * other.x() + y() * other.y() + z() * other.z(); - } + double dot( const Vector3D& other ) const { return x() * other.x() + y() * other.y() + z() * other.z(); } - Vector3D cross(const Vector3D &other) const { - return Vector3D(y() * other.z() - z() * other.y(), - z() * other.x() - x() * other.z(), - x() * other.y() - y() * other.x()); + Vector3D cross( const Vector3D& other ) const { + return Vector3D( y() * other.z() - z() * other.y(), z() * other.x() - x() * other.z(), + x() * other.y() - y() * other.x() ); } - void print(std::ostream &s) const { - s << "[" << x() << "," << y() << "," << z() << "]"; - } + void print( std::ostream& s ) const { s << "[" << x() << "," << y() << "," << z() << "]"; } - friend std::ostream &operator<<(std::ostream &s, const Vector3D &p) { - p.print(s); + friend std::ostream& operator<<( std::ostream& s, const Vector3D& p ) { + p.print( s ); return s; } - double* data() { - return xyz_; - } + double* data() { return xyz_; } - const double* data() const { - return xyz_; - } - - private: + const double* data() const { return xyz_; } +private: double x() const { return xyz_[0]; } double y() const { return xyz_[1]; } double z() const { return xyz_[2]; } double xyz_[3]; - }; -Vector3D operator*(double, const Vector3D &); +Vector3D operator*( double, const Vector3D& ); #endif diff --git a/src/atlas/interpolation/element/Quad3D.cc b/src/atlas/interpolation/element/Quad3D.cc index 5c7e9e862..01fd43a77 100644 --- a/src/atlas/interpolation/element/Quad3D.cc +++ b/src/atlas/interpolation/element/Quad3D.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,10 +13,10 @@ #include "eckit/exception/Exceptions.h" -#include "atlas/runtime/Log.h" #include "atlas/interpolation/element/Quad3D.h" #include "atlas/interpolation/element/Triag3D.h" #include "atlas/interpolation/method/Ray.h" +#include "atlas/runtime/Log.h" namespace atlas { namespace interpolation { @@ -23,17 +24,16 @@ namespace element { //---------------------------------------------------------------------------------------------------------------------- -method::Intersect Quad3D::intersects(const method::Ray &r, double edgeEpsilon, double epsilon) const { - method::Intersect isect; // intersection is false +method::Intersect Quad3D::intersects( const method::Ray& r, double edgeEpsilon, double epsilon ) const { + method::Intersect isect; // intersection is false - Triag3D T013(v00, v10, v01); - isect = T013.intersects(r, edgeEpsilon, epsilon); - if(isect) - return isect; + Triag3D T013( v00, v10, v01 ); + isect = T013.intersects( r, edgeEpsilon, epsilon ); + if ( isect ) return isect; - Triag3D T231(v11, v01, v10); - isect = T231.intersects(r, edgeEpsilon, epsilon); - if(isect) { + Triag3D T231( v11, v01, v10 ); + isect = T231.intersects( r, edgeEpsilon, epsilon ); + if ( isect ) { isect.u = 1 - isect.u; isect.v = 1 - isect.v; return isect; @@ -43,51 +43,50 @@ method::Intersect Quad3D::intersects(const method::Ray &r, double edgeEpsilon, d } bool Quad3D::validate() const { - // normal for sub-triangle T231 Vector3D E23 = v01 - v11; Vector3D E21 = v10 - v11; - Vector3D N231 = E23.cross(E21); + Vector3D N231 = E23.cross( E21 ); // normal for sub-triangle T013 Vector3D E01 = v10 - v00; Vector3D E03 = v01 - v00; - Vector3D N013 = E01.cross(E03); + Vector3D N013 = E01.cross( E03 ); // normal for sub-triangle T120 - Vector3D E12 = - E21; - Vector3D E10 = - E01; + Vector3D E12 = -E21; + Vector3D E10 = -E01; - Vector3D N120 = E12.cross(E10); + Vector3D N120 = E12.cross( E10 ); // normal for sub-triangle T302 - Vector3D E30 = - E03; - Vector3D E32 = - E23; + Vector3D E30 = -E03; + Vector3D E32 = -E23; - Vector3D N302 = E30.cross(E32); + Vector3D N302 = E30.cross( E32 ); // all normals must point same way - double dot02 = N231.dot(N013); - double dot23 = N013.dot(N120); - double dot31 = N120.dot(N302); - double dot10 = N302.dot(N231); + double dot02 = N231.dot( N013 ); + double dot23 = N013.dot( N120 ); + double dot31 = N120.dot( N302 ); + double dot10 = N302.dot( N231 ); // all normals must point same way - bool is_inside = ( ( dot02 >= 0. && dot23 >= 0. && dot31 >= 0. && dot10 >= 0. ) || - ( dot02 <= 0. && dot23 <= 0. && dot31 <= 0. && dot10 <= 0. ) ); + bool is_inside = ( ( dot02 >= 0. && dot23 >= 0. && dot31 >= 0. && dot10 >= 0. ) || + ( dot02 <= 0. && dot23 <= 0. && dot31 <= 0. && dot10 <= 0. ) ); return is_inside; } double Quad3D::area() const { - Triag3D T013(v00, v10, v01); - Triag3D T231(v11, v01, v10); + Triag3D T013( v00, v10, v01 ); + Triag3D T231( v11, v01, v10 ); return T013.area() + T231.area(); } diff --git a/src/atlas/interpolation/element/Quad3D.h b/src/atlas/interpolation/element/Quad3D.h index 095c8d25e..f71f2b627 100644 --- a/src/atlas/interpolation/element/Quad3D.h +++ b/src/atlas/interpolation/element/Quad3D.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -28,42 +29,36 @@ namespace element { class Quad3D { public: + Quad3D( const double* x0, const double* x1, const double* x2, const double* x3 ) : + v00( x0 ), + v10( x1 ), + v11( x2 ), + v01( x3 ) {} - Quad3D(const double* x0, const double* x1, const double* x2, const double* x3) : - v00(x0), - v10(x1), - v11(x2), - v01(x3) { - } - - Quad3D(const PointXYZ& x0, const PointXYZ& x1, const PointXYZ& x2, const PointXYZ& x3) : - Quad3D(x0.data(),x1.data(),x2.data(),x3.data()) { - } + Quad3D( const PointXYZ& x0, const PointXYZ& x1, const PointXYZ& x2, const PointXYZ& x3 ) : + Quad3D( x0.data(), x1.data(), x2.data(), x3.data() ) {} - method::Intersect intersects( - const method::Ray& r, - double edgeEpsilon = 5 * std::numeric_limits::epsilon(), - double epsilon = 5 * std::numeric_limits::epsilon() ) const; + method::Intersect intersects( const method::Ray& r, double edgeEpsilon = 5 * std::numeric_limits::epsilon(), + double epsilon = 5 * std::numeric_limits::epsilon() ) const; bool validate() const; double area() const; - void print(std::ostream& s) const { + void print( std::ostream& s ) const { s << "Quad3D[v00=" << v00 << ",v10=" << v10 << ",v11=" << v11 << ",v01=" << v01 << "]"; } - friend std::ostream& operator<<(std::ostream& s, const Quad3D& p) { - p.print(s); + friend std::ostream& operator<<( std::ostream& s, const Quad3D& p ) { + p.print( s ); return s; } -private: // members - Vector3D v00; // aka v0 - Vector3D v10; // aka v1 - Vector3D v11; // aka v2 - Vector3D v01; // aka v3 - +private: // members + Vector3D v00; // aka v0 + Vector3D v10; // aka v1 + Vector3D v11; // aka v2 + Vector3D v01; // aka v3 }; //---------------------------------------------------------------------------------------------------------------------- @@ -72,5 +67,4 @@ class Quad3D { } // namespace interpolation } // namespace atlas - #endif diff --git a/src/atlas/interpolation/element/Triag3D.cc b/src/atlas/interpolation/element/Triag3D.cc index 7d4ed6e04..f95ca7979 100644 --- a/src/atlas/interpolation/element/Triag3D.cc +++ b/src/atlas/interpolation/element/Triag3D.cc @@ -4,94 +4,79 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - -#include #include "atlas/interpolation/element/Triag3D.h" +#include #include "atlas/interpolation/method/Intersect.h" #include "atlas/interpolation/method/Ray.h" //---------------------------------------------------------------------------------------------------------------------- - namespace atlas { namespace interpolation { namespace element { -method::Intersect Triag3D::intersects(const method::Ray& r, double edgeEpsilon, double epsilon) const { - +method::Intersect Triag3D::intersects( const method::Ray& r, double edgeEpsilon, double epsilon ) const { method::Intersect isect; Vector3D edge1 = v1 - v0; Vector3D edge2 = v2 - v0; - Vector3D pvec = r.dir.cross(edge2); + Vector3D pvec = r.dir.cross( edge2 ); // ray is parallel to triangle (check?) - const double det = edge1.dot(pvec); - if (fabs(det) < epsilon) { - return isect.fail(); - } + const double det = edge1.dot( pvec ); + if ( fabs( det ) < epsilon ) { return isect.fail(); } const double invDet = 1. / det; Vector3D tvec = r.orig - v0; - Vector3D qvec = tvec.cross(edge1); - - isect.u = tvec.dot(pvec) * invDet; - isect.v = r.dir.dot(qvec) * invDet; - isect.t = edge2.dot(qvec) * invDet; + Vector3D qvec = tvec.cross( edge1 ); - const double w = 1 - (isect.u + isect.v); + isect.u = tvec.dot( pvec ) * invDet; + isect.v = r.dir.dot( qvec ) * invDet; + isect.t = edge2.dot( qvec ) * invDet; - if (w < 0) { + const double w = 1 - ( isect.u + isect.v ); + 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 horizontal edge + // Note: we may still be to the left of vertical edge or below the + // horizontal edge isect.u += 0.5 * w; isect.v += 0.5 * w; } - if (isect.u < 0) { - + if ( isect.u < 0 ) { // check if far outside of triangle, in respect to vertical edge - if ( (isect.u < -edgeEpsilon) || - (isect.v < -edgeEpsilon) || - (isect.v > 1 + edgeEpsilon) ) { + if ( ( isect.u < -edgeEpsilon ) || ( isect.v < -edgeEpsilon ) || ( isect.v > 1 + edgeEpsilon ) ) { return isect.fail(); } // snap to lower/upper left corners isect.u = 0; - if (isect.v < 0) { - isect.v = 0; - } else if (isect.v > 1) { + if ( isect.v < 0 ) { isect.v = 0; } + else if ( isect.v > 1 ) { isect.v = 1; } - } - if (isect.v < 0) { - + if ( isect.v < 0 ) { // check if far outside of triangle, in respect to horizontal edge - if( (isect.v < -edgeEpsilon) || - (isect.u < -edgeEpsilon) || - (isect.u > 1 + edgeEpsilon) ) { + if ( ( isect.v < -edgeEpsilon ) || ( isect.u < -edgeEpsilon ) || ( isect.u > 1 + edgeEpsilon ) ) { return isect.fail(); } // snap to lower left/right corners isect.v = 0; - if (isect.u < 0) { - isect.u = 0; - } else if (isect.u > 1) { + if ( isect.u < 0 ) { isect.u = 0; } + else if ( isect.u > 1 ) { isect.u = 1; } } @@ -99,12 +84,11 @@ method::Intersect Triag3D::intersects(const method::Ray& r, double edgeEpsilon, return isect.success(); } -double Triag3D::area() const -{ +double Triag3D::area() const { Vector3D edge1 = v1 - v0; Vector3D edge2 = v2 - v0; - Vector3D cross = edge1.cross(edge2); + Vector3D cross = edge1.cross( edge2 ); return 0.5 * cross.norm(); } @@ -114,4 +98,3 @@ double Triag3D::area() const } // namespace element } // namespace interpolation } // namespace atlas - diff --git a/src/atlas/interpolation/element/Triag3D.h b/src/atlas/interpolation/element/Triag3D.h index beee30dd0..62b07908d 100644 --- a/src/atlas/interpolation/element/Triag3D.h +++ b/src/atlas/interpolation/element/Triag3D.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -31,50 +32,35 @@ namespace element { /// http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-9-ray-triangle-intersection/m-ller-trumbore-algorithm class Triag3D { +public: // types + Triag3D( const double* x0, const double* x1, const double* x2 ) : v0( x0 ), v1( x1 ), v2( x2 ) {} -public: // types + Triag3D( const PointXYZ& x0, const PointXYZ& x1, const PointXYZ& x2 ) : + Triag3D( x0.data(), x1.data(), x2.data() ) {} + Triag3D( const Vector3D& x0, const Vector3D& x1, const Vector3D& x2 ) : + Triag3D( x0.data(), x1.data(), x2.data() ) {} - Triag3D(const double* x0, const double* x1, const double* x2) : - v0(x0), - v1(x1), - v2(x2) { - } - - Triag3D(const PointXYZ& x0, const PointXYZ& x1, const PointXYZ& x2) : - Triag3D(x0.data(),x1.data(),x2.data()) { - } - - Triag3D(const Vector3D& x0, const Vector3D& x1, const Vector3D& x2) : - Triag3D(x0.data(),x1.data(),x2.data()) { - } - - method::Intersect intersects( - const method::Ray& r, - double edgeEpsilon = 5 * std::numeric_limits::epsilon(), - double epsilon = 5 * std::numeric_limits::epsilon() ) const; + method::Intersect intersects( const method::Ray& r, double edgeEpsilon = 5 * std::numeric_limits::epsilon(), + double epsilon = 5 * std::numeric_limits::epsilon() ) const; double area() const; - void print(std::ostream& s) const { + void print( std::ostream& s ) const { s << "Triag3D[" - << "v0=(" << v0[0] << ", " << v0[1] << ", " << v0[2] - << "), v1=(" << v1[0] << ", " << v1[1] << ", " << v1[2] - << "), v2=(" << v2[0] << ", " << v2[1] << ", " << v2[2] - << ")]"; + << "v0=(" << v0[0] << ", " << v0[1] << ", " << v0[2] << "), v1=(" << v1[0] << ", " << v1[1] << ", " << v1[2] + << "), v2=(" << v2[0] << ", " << v2[1] << ", " << v2[2] << ")]"; } - friend std::ostream& operator<<(std::ostream& s, const Triag3D& p) { - p.print(s); + friend std::ostream& operator<<( std::ostream& s, const Triag3D& p ) { + p.print( s ); return s; } -private: // members - +private: // members Vector3D v0; Vector3D v1; Vector3D v2; - }; //---------------------------------------------------------------------------------------------------------------------- @@ -83,5 +69,4 @@ class Triag3D { } // namespace interpolation } // namespace atlas - #endif diff --git a/src/atlas/interpolation/method/FiniteElement.cc b/src/atlas/interpolation/method/FiniteElement.cc index 46f7c38f0..eb6e039a3 100644 --- a/src/atlas/interpolation/method/FiniteElement.cc +++ b/src/atlas/interpolation/method/FiniteElement.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. and Interpolation */ @@ -12,21 +13,21 @@ #include "atlas/interpolation/method/FiniteElement.h" +#include "eckit/geometry/Point3.h" #include "eckit/log/Plural.h" -#include "eckit/log/Seconds.h" #include "eckit/log/ProgressTimer.h" +#include "eckit/log/Seconds.h" #include "eckit/mpi/Comm.h" -#include "eckit/geometry/Point3.h" +#include "atlas/functionspace/NodeColumns.h" +#include "atlas/functionspace/PointCloud.h" #include "atlas/interpolation/element/Quad3D.h" #include "atlas/interpolation/element/Triag3D.h" #include "atlas/interpolation/method/Ray.h" -#include "atlas/functionspace/NodeColumns.h" -#include "atlas/functionspace/PointCloud.h" -#include "atlas/mesh/actions/BuildCellCentres.h" -#include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/mesh/ElementType.h" #include "atlas/mesh/Nodes.h" +#include "atlas/mesh/actions/BuildCellCentres.h" +#include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" #include "atlas/util/CoordinateEnums.h" @@ -37,255 +38,231 @@ namespace atlas { namespace interpolation { namespace method { - namespace { -MethodBuilder __builder("finite-element"); +MethodBuilder __builder( "finite-element" ); // epsilon used to scale edge tolerance when projecting ray to intesect element static const double parametricEpsilon = 1e-15; -} // (anonymous namespace) +} // namespace -void FiniteElement::setup(const FunctionSpace& source, const FunctionSpace& target) { +void FiniteElement::setup( const FunctionSpace& source, const FunctionSpace& target ) { ATLAS_TRACE( "atlas::interpolation::method::FiniteElement::setup()" ); - if( functionspace::NodeColumns tgt = target ) { - + if ( functionspace::NodeColumns tgt = target ) { Mesh meshTarget = tgt.mesh(); // generate 3D point coordinates - target_xyz_ = mesh::actions::BuildXYZField("xyz")(meshTarget); + target_xyz_ = mesh::actions::BuildXYZField( "xyz" )( meshTarget ); target_ghost_ = meshTarget.nodes().ghost(); - } else if ( functionspace::PointCloud tgt = target ) { - - const size_t N = tgt.size(); - target_xyz_ = Field("xyz", array::make_datatype(), array::make_shape(N,3) ); - target_ghost_ = tgt.ghost(); - array::ArrayView lonlat = array::make_view( tgt.lonlat() ); - array::ArrayView xyz = array::make_view( target_xyz_ ); + const size_t N = tgt.size(); + target_xyz_ = Field( "xyz", array::make_datatype(), array::make_shape( N, 3 ) ); + target_ghost_ = tgt.ghost(); + array::ArrayView lonlat = array::make_view( tgt.lonlat() ); + array::ArrayView xyz = array::make_view( target_xyz_ ); PointXYZ p2; - for( size_t n=0; n eTree( create_element_kdtree( cell_centres ) ); - const mesh::Nodes &i_nodes = meshSource.nodes(); + const mesh::Nodes& i_nodes = meshSource.nodes(); - icoords_.reset( new array::ArrayView( array::make_view(source_xyz)) ); - ocoords_.reset( new array::ArrayView( array::make_view(target_xyz_)) ); + icoords_.reset( new array::ArrayView( array::make_view( source_xyz ) ) ); + ocoords_.reset( new array::ArrayView( array::make_view( target_xyz_ ) ) ); connectivity_ = &meshSource.cells().node_connectivity(); - size_t inp_npts = i_nodes.size(); - size_t out_npts = ocoords_->shape(0); + size_t inp_npts = i_nodes.size(); + size_t out_npts = ocoords_->shape( 0 ); - array::ArrayView out_ghosts = array::make_view(target_ghost_); + array::ArrayView out_ghosts = array::make_view( target_ghost_ ); - size_t Nelements = meshSource.cells().size(); + size_t Nelements = meshSource.cells().size(); const double maxFractionElemsToTry = 0.2; - // weights -- one per vertex of element, triangles (3) or quads (4) - std::vector< eckit::linalg::Triplet > weights_triplets; // structure to fill-in sparse matrix - weights_triplets.reserve( out_npts * 4 ); // preallocate space as if all elements where quads + std::vector weights_triplets; // structure to fill-in sparse matrix + weights_triplets.reserve( out_npts * 4 ); // preallocate space as if all elements where quads // search nearest k cell centres - const size_t maxNbElemsToTry = std::max(64, size_t(Nelements * maxFractionElemsToTry)); - size_t max_neighbours = 0; + const size_t maxNbElemsToTry = std::max( 64, size_t( Nelements * maxFractionElemsToTry ) ); + size_t max_neighbours = 0; std::vector failures; { - eckit::ProgressTimer progress("Computing interpolation weights", out_npts, "point", double(5), Log::debug()); + eckit::ProgressTimer progress( "Computing interpolation weights", out_npts, "point", double( 5 ), + Log::debug() ); for ( size_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 + PointXYZ p{( *ocoords_ )( ip, 0 ), ( *ocoords_ )( ip, 1 ), ( *ocoords_ )( ip, 2 )}; // lookup point - size_t kpts = 1; + size_t kpts = 1; bool success = false; std::ostringstream failures_log; - while (!success && kpts <= maxNbElemsToTry) { - - max_neighbours = std::max(kpts, max_neighbours); + while ( !success && kpts <= maxNbElemsToTry ) { + max_neighbours = std::max( kpts, max_neighbours ); - ElemIndex3::NodeList cs = eTree->kNearestNeighbours(p, kpts); - Triplets triplets = projectPointToElements(ip,cs,failures_log); + ElemIndex3::NodeList cs = eTree->kNearestNeighbours( p, kpts ); + Triplets triplets = projectPointToElements( ip, cs, failures_log ); - if (triplets.size()) { - std::copy(triplets.begin(), triplets.end(), std::back_inserter(weights_triplets)); + if ( triplets.size() ) { + std::copy( triplets.begin(), triplets.end(), std::back_inserter( weights_triplets ) ); success = true; } kpts *= 2; } - if (!success) { - failures.push_back(ip); - Log::debug() << "---------------------------------------------------------------------------\n"; - const PointLonLat pll = util::Earth::convertGeocentricToGeodetic(p); - Log::debug() << "Failed to project point (lon,lat)="<< pll << '\n'; + if ( !success ) { + failures.push_back( ip ); + Log::debug() << "------------------------------------------------------" + "---------------------\n"; + const PointLonLat pll = util::Earth::convertGeocentricToGeodetic( p ); + Log::debug() << "Failed to project point (lon,lat)=" << pll << '\n'; Log::debug() << failures_log.str(); } } } - Log::debug() << "Maximum neighbours searched was " << eckit::Plural(max_neighbours, "element") << std::endl; - + Log::debug() << "Maximum neighbours searched was " << eckit::Plural( max_neighbours, "element" ) << std::endl; eckit::mpi::comm().barrier(); - if (failures.size()) { - + if ( failures.size() ) { // If this fails, consider lowering atlas::grid::parametricEpsilon std::ostringstream msg; msg << "Rank " << eckit::mpi::comm().rank() << " failed to project points:\n"; - for (std::vector::const_iterator i = failures.begin(); i != failures.end(); ++i) { - const PointXYZ p{ (*ocoords_)(*i,0), (*ocoords_)(*i,1), (*ocoords_)(*i,2) }; // lookup point - const PointLonLat pll = util::Earth::convertGeocentricToGeodetic(p); + for ( std::vector::const_iterator i = failures.begin(); i != failures.end(); ++i ) { + const PointXYZ p{( *ocoords_ )( *i, 0 ), ( *ocoords_ )( *i, 1 ), ( *ocoords_ )( *i, 2 )}; // lookup point + const PointLonLat pll = util::Earth::convertGeocentricToGeodetic( p ); msg << "\t(lon,lat) = " << pll << "\n"; } - Log::error() << msg.str() << std::endl; - throw eckit::SeriousBug(msg.str()); + throw eckit::SeriousBug( msg.str() ); } // fill sparse matrix and return - Matrix A(out_npts, inp_npts, weights_triplets); - matrix_.swap(A); + Matrix A( out_npts, inp_npts, weights_triplets ); + matrix_.swap( A ); } +Method::Triplets FiniteElement::projectPointToElements( size_t ip, const ElemIndex3::NodeList& elems, + std::ostream& failures_log ) const { + ASSERT( elems.begin() != elems.end() ); -Method::Triplets FiniteElement::projectPointToElements( - size_t ip, - const ElemIndex3::NodeList& elems, - std::ostream& failures_log ) const { - - ASSERT(elems.begin() != elems.end()); - - const size_t inp_points = icoords_->shape(0); + const size_t inp_points = icoords_->shape( 0 ); size_t idx[4]; double w[4]; Triplets triplets; - Ray ray( PointXYZ{(*ocoords_)(ip,0),(*ocoords_)(ip,1),(*ocoords_)(ip,2)} ); + Ray ray( PointXYZ{( *ocoords_ )( ip, 0 ), ( *ocoords_ )( ip, 1 ), ( *ocoords_ )( ip, 2 )} ); - for (ElemIndex3::NodeList::const_iterator itc = elems.begin(); itc != elems.end(); ++itc) { + for ( ElemIndex3::NodeList::const_iterator itc = elems.begin(); itc != elems.end(); ++itc ) { + const size_t elem_id = ( *itc ).value().payload(); + ASSERT( elem_id < connectivity_->rows() ); - const size_t elem_id = (*itc).value().payload(); - ASSERT(elem_id < connectivity_->rows()); + const size_t nb_cols = connectivity_->cols( elem_id ); + ASSERT( nb_cols == 3 || nb_cols == 4 ); - const size_t nb_cols = connectivity_->cols(elem_id); - ASSERT(nb_cols == 3 || nb_cols == 4); - - for (size_t i = 0; i < nb_cols; ++i) { - idx[i] = size_t((*connectivity_)(elem_id, i)); - ASSERT(idx[i] < inp_points); + for ( size_t i = 0; i < nb_cols; ++i ) { + idx[i] = size_t( ( *connectivity_ )( elem_id, i ) ); + ASSERT( idx[i] < inp_points ); } - if (nb_cols == 3) { - + if ( nb_cols == 3 ) { /* triangle */ element::Triag3D triag( - PointXYZ{(*icoords_)(idx[0],0),(*icoords_)(idx[0],1),(*icoords_)(idx[0],2)}, - PointXYZ{(*icoords_)(idx[1],0),(*icoords_)(idx[1],1),(*icoords_)(idx[1],2)}, - PointXYZ{(*icoords_)(idx[2],0),(*icoords_)(idx[2],1),(*icoords_)(idx[2],2)}); + PointXYZ{( *icoords_ )( idx[0], 0 ), ( *icoords_ )( idx[0], 1 ), ( *icoords_ )( idx[0], 2 )}, + PointXYZ{( *icoords_ )( idx[1], 0 ), ( *icoords_ )( idx[1], 1 ), ( *icoords_ )( idx[1], 2 )}, + PointXYZ{( *icoords_ )( idx[2], 0 ), ( *icoords_ )( idx[2], 1 ), ( *icoords_ )( idx[2], 2 )} ); // pick an epsilon based on a characteristic length (sqrt(area)) // (this scales linearly so it better compares with linear weights u,v,w) - const double edgeEpsilon = parametricEpsilon * std::sqrt(triag.area()); - ASSERT(edgeEpsilon >= 0); + const double edgeEpsilon = parametricEpsilon * std::sqrt( triag.area() ); + ASSERT( edgeEpsilon >= 0 ); - Intersect is = triag.intersects(ray, edgeEpsilon); + Intersect is = triag.intersects( ray, edgeEpsilon ); - if (is) { - - // weights are the linear Lagrange function evaluated at u,v (aka barycentric coordinates) + if ( is ) { + // weights are the linear Lagrange function evaluated at u,v (aka + // barycentric coordinates) w[0] = 1. - is.u - is.v; w[1] = is.u; w[2] = is.v; - for (size_t i = 0; i < 3; ++i) { + for ( size_t i = 0; i < 3; ++i ) { triplets.push_back( Triplet( ip, idx[i], w[i] ) ); } - break; // stop looking for elements + break; // stop looking for elements } - - } else { - + } + else { /* quadrilateral */ element::Quad3D quad( - PointXYZ{(*icoords_)(idx[0],0),(*icoords_)(idx[0],1),(*icoords_)(idx[0],2)}, - PointXYZ{(*icoords_)(idx[1],0),(*icoords_)(idx[1],1),(*icoords_)(idx[1],2)}, - PointXYZ{(*icoords_)(idx[2],0),(*icoords_)(idx[2],1),(*icoords_)(idx[2],2)}, - PointXYZ{(*icoords_)(idx[3],0),(*icoords_)(idx[3],1),(*icoords_)(idx[3],2)}); + PointXYZ{( *icoords_ )( idx[0], 0 ), ( *icoords_ )( idx[0], 1 ), ( *icoords_ )( idx[0], 2 )}, + PointXYZ{( *icoords_ )( idx[1], 0 ), ( *icoords_ )( idx[1], 1 ), ( *icoords_ )( idx[1], 2 )}, + PointXYZ{( *icoords_ )( idx[2], 0 ), ( *icoords_ )( idx[2], 1 ), ( *icoords_ )( idx[2], 2 )}, + PointXYZ{( *icoords_ )( idx[3], 0 ), ( *icoords_ )( idx[3], 1 ), ( *icoords_ )( idx[3], 2 )} ); // pick an epsilon based on a characteristic length (sqrt(area)) // (this scales linearly so it better compares with linear weights u,v,w) - const double edgeEpsilon = parametricEpsilon * std::sqrt(quad.area()); - ASSERT(edgeEpsilon >= 0); - - Intersect is = quad.intersects(ray, edgeEpsilon); + const double edgeEpsilon = parametricEpsilon * std::sqrt( quad.area() ); + ASSERT( edgeEpsilon >= 0 ); - if (is) { + Intersect is = quad.intersects( ray, edgeEpsilon ); + if ( is ) { // weights are the bilinear Lagrange function evaluated at u,v - w[0] = (1. - is.u) * (1. - is.v); - w[1] = is.u * (1. - is.v); - w[2] = is.u * is.v ; - w[3] = (1. - is.u) * is.v ; + w[0] = ( 1. - is.u ) * ( 1. - is.v ); + w[1] = is.u * ( 1. - is.v ); + w[2] = is.u * is.v; + w[3] = ( 1. - is.u ) * is.v; - for (size_t i = 0; i < 4; ++i) { + for ( size_t i = 0; i < 4; ++i ) { triplets.push_back( Triplet( ip, idx[i], w[i] ) ); } - break; // stop looking for elements + break; // stop looking for elements } - } - } // loop over nearest elements + } // loop over nearest elements - if (!triplets.empty()) { - normalise(triplets); - } + if ( !triplets.empty() ) { normalise( triplets ); } return triplets; } - -} // method -} // interpolation -} // atlas - +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/FiniteElement.h b/src/atlas/interpolation/method/FiniteElement.h index 00fa3f77e..12df8aae0 100644 --- a/src/atlas/interpolation/method/FiniteElement.h +++ b/src/atlas/interpolation/method/FiniteElement.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,62 +14,55 @@ #include "atlas/interpolation/method/Method.h" #include -#include "eckit/config/Configuration.h" -#include "eckit/memory/NonCopyable.h" #include "atlas/array/ArrayView.h" #include "atlas/interpolation/method/PointIndex3.h" #include "atlas/mesh/Elements.h" - +#include "eckit/config/Configuration.h" +#include "eckit/memory/NonCopyable.h" namespace atlas { namespace interpolation { namespace method { - class FiniteElement : public Method { public: - - FiniteElement(const Config& config) : - Method(config) { - } + FiniteElement( const Config& config ) : Method( config ) {} virtual ~FiniteElement() {} - virtual void setup(const FunctionSpace& source, const FunctionSpace& target) override; + virtual void setup( const FunctionSpace& source, const FunctionSpace& target ) override; protected: - /** - * @brief Create an interpolant sparse matrix relating two (pre-partitioned) meshes, - * using elements as per the Finite Element Method and ray-tracing to calculate - * source mesh elements intersections (and interpolation weights) with target grid - * node-containing rays - * @param meshSource mesh containing source elements - * @param meshTarget mesh containing target points - */ - void setup(const FunctionSpace& source); + * @brief Create an interpolant sparse matrix relating two (pre-partitioned) + * meshes, + * using elements as per the Finite Element Method and ray-tracing to + * calculate + * source mesh elements intersections (and interpolation weights) with target + * grid + * node-containing rays + * @param meshSource mesh containing source elements + * @param meshTarget mesh containing target points + */ + void setup( const FunctionSpace& source ); /** - * Find in which element the point is contained by projecting (ray-tracing) the - * point to the nearest element(s), returning the (normalized) interpolation weights - */ - Triplets projectPointToElements( - size_t ip, - const ElemIndex3::NodeList& elems, - std::ostream& failures_log ) const; - + * Find in which element the point is contained by projecting (ray-tracing) + * the + * point to the nearest element(s), returning the (normalized) interpolation + * weights + */ + Triplets projectPointToElements( size_t ip, const ElemIndex3::NodeList& elems, std::ostream& failures_log ) const; protected: - mesh::MultiBlockConnectivity* connectivity_; - std::unique_ptr> icoords_; - std::unique_ptr> ocoords_; + std::unique_ptr> icoords_; + std::unique_ptr> ocoords_; Field target_xyz_; Field target_ghost_; }; - -} // method -} // interpolation -} // atlas +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/Intersect.cc b/src/atlas/interpolation/method/Intersect.cc index 71b2b6e88..6ed40cf66 100644 --- a/src/atlas/interpolation/method/Intersect.cc +++ b/src/atlas/interpolation/method/Intersect.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,11 +17,10 @@ namespace atlas { namespace interpolation { namespace method { -Intersect::Intersect() : u(0.), v(0.), t(0.), success_(false) {} +Intersect::Intersect() : u( 0. ), v( 0. ), t( 0. ), success_( false ) {} -void Intersect::print(std::ostream& s) const -{ - s << "Intersect[u=" << u << ",v=" << v << ",t=" << t <<",success=" << success_ << "]"; +void Intersect::print( std::ostream& s ) const { + s << "Intersect[u=" << u << ",v=" << v << ",t=" << t << ",success=" << success_ << "]"; } } // namespace method diff --git a/src/atlas/interpolation/method/Intersect.h b/src/atlas/interpolation/method/Intersect.h index 5af1293f6..8d8e42824 100644 --- a/src/atlas/interpolation/method/Intersect.h +++ b/src/atlas/interpolation/method/Intersect.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -22,29 +23,32 @@ namespace method { /// Intersection data structure struct Intersect { + double u; + double v; + double t; - double u; - double v; - double t; + Intersect(); - Intersect(); + operator bool() const { return success_; } - operator bool() const { return success_; } + Intersect& success() { + success_ = true; + return *this; + } + Intersect& fail() { + success_ = false; + return *this; + } - Intersect& success() { success_ = true; return *this; } - Intersect& fail() { success_ = false; return *this; } + void print( std::ostream& s ) const; - void print(std::ostream& s) const; - - friend std::ostream& operator<<(std::ostream& s, const Intersect& p) { - p.print(s); - return s; - } + friend std::ostream& operator<<( std::ostream& s, const Intersect& p ) { + p.print( s ); + return s; + } private: - - bool success_; - + bool success_; }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/interpolation/method/KNearestNeighbours.cc b/src/atlas/interpolation/method/KNearestNeighbours.cc index 8624d903b..417e571ed 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.cc +++ b/src/atlas/interpolation/method/KNearestNeighbours.cc @@ -4,114 +4,105 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "atlas/interpolation/method/KNearestNeighbours.h" -#include "eckit/log/Plural.h" -#include "eckit/log/Timer.h" +#include "atlas/functionspace/NodeColumns.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "atlas/functionspace/NodeColumns.h" - +#include "eckit/log/Plural.h" +#include "eckit/log/Timer.h" namespace atlas { namespace interpolation { namespace method { - namespace { +MethodBuilder __builder( "k-nearest-neighbours" ); -MethodBuilder __builder("k-nearest-neighbours"); +} // namespace - -} // (anonymous namespace) - - -KNearestNeighbours::KNearestNeighbours(const Method::Config& config) : KNearestNeighboursBase(config) { +KNearestNeighbours::KNearestNeighbours( const Method::Config& config ) : KNearestNeighboursBase( config ) { k_ = 1; - config.get("k-nearest-neighbours", k_); - ASSERT(k_); + config.get( "k-nearest-neighbours", k_ ); + ASSERT( k_ ); } -void KNearestNeighbours::setup(const FunctionSpace& source, const FunctionSpace& target) { +void KNearestNeighbours::setup( const FunctionSpace& source, const FunctionSpace& target ) { functionspace::NodeColumns src = source; functionspace::NodeColumns tgt = target; - ASSERT(src); - ASSERT(tgt); + ASSERT( src ); + ASSERT( tgt ); Mesh meshSource = src.mesh(); Mesh meshTarget = tgt.mesh(); // build point-search tree - buildPointSearchTree(meshSource); - ASSERT(pTree_); - + buildPointSearchTree( meshSource ); + ASSERT( pTree_ ); // generate 3D point coordinates - mesh::actions::BuildXYZField("xyz")(meshTarget); - array::ArrayView< double, 2 > coords = array::make_view(meshTarget.nodes().field( "xyz" )); + mesh::actions::BuildXYZField( "xyz" )( meshTarget ); + array::ArrayView coords = array::make_view( meshTarget.nodes().field( "xyz" ) ); size_t inp_npts = meshSource.nodes().size(); size_t out_npts = meshTarget.nodes().size(); - // fill the sparse matrix - std::vector< Triplet > weights_triplets; - weights_triplets.reserve(out_npts * k_); + std::vector weights_triplets; + weights_triplets.reserve( out_npts * k_ ); { - Trace timer(Here(),"atlas::interpolation::method::NearestNeighbour::setup()"); + Trace timer( Here(), "atlas::interpolation::method::NearestNeighbour::setup()" ); std::vector weights; - for (size_t ip = 0; ip < out_npts; ++ip) { - - if (ip && (ip % 1000 == 0)) { + for ( size_t ip = 0; ip < out_npts; ++ip ) { + if ( ip && ( ip % 1000 == 0 ) ) { double rate = ip / timer.elapsed(); - Log::debug() << eckit::BigNum(ip) << " (at " << rate << " points/s)..." << std::endl; + Log::debug() << eckit::BigNum( ip ) << " (at " << rate << " points/s)..." << std::endl; } // find the closest input points to the output point - PointIndex3::Point p{coords(ip,0),coords(ip,1),coords(ip,2)}; - PointIndex3::NodeList nn = pTree_->kNearestNeighbours(p, k_); + PointIndex3::Point p{coords( ip, 0 ), coords( ip, 1 ), coords( ip, 2 )}; + PointIndex3::NodeList nn = pTree_->kNearestNeighbours( p, k_ ); - // calculate weights (individual and total, to normalise) using distance squared + // calculate weights (individual and total, to normalise) using distance + // squared const size_t npts = nn.size(); - ASSERT(npts); - weights.resize(npts, 0); + ASSERT( npts ); + weights.resize( npts, 0 ); double sum = 0; - for (size_t j = 0; j < npts; ++j) { + for ( size_t j = 0; j < npts; ++j ) { PointIndex3::Point np = nn[j].point(); - const double d2 = eckit::geometry::Point3::distance2(p, np); + const double d2 = eckit::geometry::Point3::distance2( p, np ); - weights[j] = 1. / (1. + d2); + weights[j] = 1. / ( 1. + d2 ); sum += weights[j]; } - ASSERT(sum > 0); + ASSERT( sum > 0 ); // insert weights into the matrix - for (size_t j = 0; j < npts; ++j) { + for ( size_t j = 0; j < npts; ++j ) { size_t jp = nn[j].payload(); - ASSERT(jp < inp_npts); - weights_triplets.push_back(Triplet(ip, jp, weights[j]/sum)); + ASSERT( jp < inp_npts ); + weights_triplets.push_back( Triplet( ip, jp, weights[j] / sum ) ); } } } - // fill sparse matrix and return - Matrix A(out_npts, inp_npts, weights_triplets); - matrix_.swap(A); + Matrix A( out_npts, inp_npts, weights_triplets ); + matrix_.swap( A ); } - -} // method -} // interpolation -} // atlas +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/KNearestNeighbours.h b/src/atlas/interpolation/method/KNearestNeighbours.h index 06311f31c..6b3e39071 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.h +++ b/src/atlas/interpolation/method/KNearestNeighbours.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,33 +13,28 @@ #include "atlas/interpolation/method/KNearestNeighboursBase.h" - namespace atlas { namespace interpolation { namespace method { - class KNearestNeighbours : public KNearestNeighboursBase { public: - - KNearestNeighbours(const Config& config); + KNearestNeighbours( const Config& config ); virtual ~KNearestNeighbours() {} /** - * @brief Create an interpolant sparse matrix relating two (pre-partitioned) meshes, - * using the k-nearest neighbours method - * @param source functionspace containing source elements - * @param target functionspace containing target points - */ - virtual void setup(const FunctionSpace& source, const FunctionSpace& target) override; + * @brief Create an interpolant sparse matrix relating two (pre-partitioned) + * meshes, + * using the k-nearest neighbours method + * @param source functionspace containing source elements + * @param target functionspace containing target points + */ + virtual void setup( const FunctionSpace& source, const FunctionSpace& target ) override; protected: - size_t k_; - }; - -} // method -} // interpolation -} // atlas +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.cc b/src/atlas/interpolation/method/KNearestNeighboursBase.cc index 25e8d4f72..3cf19b166 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.cc +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.cc @@ -4,57 +4,53 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. and Interpolation */ - #include "atlas/interpolation/method/KNearestNeighboursBase.h" -#include "eckit/config/Resource.h" -#include "atlas/mesh/actions/BuildXYZField.h" -#include "atlas/mesh/Nodes.h" #include "atlas/library/Library.h" +#include "atlas/mesh/Nodes.h" +#include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Trace.h" - +#include "eckit/config/Resource.h" namespace atlas { namespace interpolation { namespace method { -void KNearestNeighboursBase::buildPointSearchTree(Mesh& meshSource) { +void KNearestNeighboursBase::buildPointSearchTree( Mesh& meshSource ) { using namespace atlas; - eckit::TraceTimer tim("atlas::interpolation::method::KNearestNeighboursBase::setup()"); - + eckit::TraceTimer tim( "atlas::interpolation::method::KNearestNeighboursBase::setup()" ); // generate 3D point coordinates - mesh::actions::BuildXYZField("xyz")(meshSource); - array::ArrayView< double, 2 > coords = array::make_view(meshSource.nodes().field( "xyz" )); - + mesh::actions::BuildXYZField( "xyz" )( meshSource ); + array::ArrayView coords = array::make_view( meshSource.nodes().field( "xyz" ) ); // build point-search tree - pTree_.reset(new PointIndex3); + pTree_.reset( new PointIndex3 ); - static bool fastBuildKDTrees = eckit::Resource("$ATLAS_FAST_BUILD_KDTREES", true); + static bool fastBuildKDTrees = eckit::Resource( "$ATLAS_FAST_BUILD_KDTREES", true ); - if (fastBuildKDTrees) { + if ( fastBuildKDTrees ) { std::vector pidx; - pidx.reserve(meshSource.nodes().size()); - for (size_t ip = 0; ip < meshSource.nodes().size(); ++ip) { - PointIndex3::Point p{coords(ip,0),coords(ip,1),coords(ip,2)}; - pidx.push_back(PointIndex3::Value(p, ip)); + pidx.reserve( meshSource.nodes().size() ); + for ( size_t ip = 0; ip < meshSource.nodes().size(); ++ip ) { + PointIndex3::Point p{coords( ip, 0 ), coords( ip, 1 ), coords( ip, 2 )}; + pidx.push_back( PointIndex3::Value( p, ip ) ); } - pTree_->build(pidx.begin(), pidx.end()); + pTree_->build( pidx.begin(), pidx.end() ); } else { - for (size_t ip = 0; ip < meshSource.nodes().size(); ++ip) { - PointIndex3::Point p{coords(ip,0),coords(ip,1),coords(ip,2)}; - pTree_->insert(PointIndex3::Value(p, ip)); + for ( size_t ip = 0; ip < meshSource.nodes().size(); ++ip ) { + PointIndex3::Point p{coords( ip, 0 ), coords( ip, 1 ), coords( ip, 2 )}; + pTree_->insert( PointIndex3::Value( p, ip ) ); } } } - -} // method -} // interpolation -} // atlas +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.h b/src/atlas/interpolation/method/KNearestNeighboursBase.h index 336eeb0c5..b46f8324c 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.h +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.h @@ -4,37 +4,32 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "eckit/memory/ScopedPtr.h" #include "atlas/interpolation/method/Method.h" #include "atlas/interpolation/method/PointIndex3.h" - +#include "eckit/memory/ScopedPtr.h" namespace atlas { namespace interpolation { namespace method { - class KNearestNeighboursBase : public Method { public: - - KNearestNeighboursBase(const Config& config) : Method(config) {} + KNearestNeighboursBase( const Config& config ) : Method( config ) {} virtual ~KNearestNeighboursBase() {} protected: - - void buildPointSearchTree(Mesh& meshSource); + void buildPointSearchTree( Mesh& meshSource ); eckit::ScopedPtr pTree_; - }; - -} // method -} // interpolation -} // atlas +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index cb65434cf..8178434a8 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -4,14 +4,18 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "atlas/interpolation/method/Method.h" #include +#include "atlas/field/Field.h" +#include "atlas/field/FieldSet.h" +#include "atlas/runtime/Log.h" +#include "atlas/runtime/Trace.h" #include "eckit/exception/Exceptions.h" #include "eckit/linalg/LinearAlgebra.h" #include "eckit/linalg/Vector.h" @@ -19,10 +23,6 @@ #include "eckit/thread/AutoLock.h" #include "eckit/thread/Mutex.h" #include "eckit/thread/Once.h" -#include "atlas/field/Field.h" -#include "atlas/field/FieldSet.h" -#include "atlas/runtime/Log.h" -#include "atlas/runtime/Trace.h" // for static linking #include "FiniteElement.h" @@ -34,119 +34,107 @@ namespace interpolation { namespace { - typedef std::map MethodFactoryMap_t; -static MethodFactoryMap_t *m = 0; -static eckit::Mutex *local_mutex = 0; -static pthread_once_t once = PTHREAD_ONCE_INIT; - +static MethodFactoryMap_t* m = 0; +static eckit::Mutex* local_mutex = 0; +static pthread_once_t once = PTHREAD_ONCE_INIT; static void init() { local_mutex = new eckit::Mutex(); - m = new MethodFactoryMap_t(); + m = new MethodFactoryMap_t(); } -template void load_builder() { MethodBuilder("tmp"); } +template +void load_builder() { + MethodBuilder( "tmp" ); +} struct force_link { - force_link() - { + force_link() { load_builder(); load_builder(); load_builder(); } }; +} // namespace -} // (anonymous namespace) - +MethodFactory::MethodFactory( const std::string& name ) : name_( name ) { + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); -MethodFactory::MethodFactory(const std::string& name): - name_(name) { - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); + if ( m->find( name ) != m->end() ) { throw eckit::SeriousBug( "MethodFactory duplicate '" + name + "'" ); } - if (m->find(name) != m->end()) { - throw eckit::SeriousBug("MethodFactory duplicate '" + name + "'"); - } - - ASSERT(m->find(name) == m->end()); - (*m)[name] = this; + ASSERT( m->find( name ) == m->end() ); + ( *m )[name] = this; } - MethodFactory::~MethodFactory() { - eckit::AutoLock lock(local_mutex); - m->erase(name_); + eckit::AutoLock lock( local_mutex ); + m->erase( name_ ); } - -Method* MethodFactory::build(const std::string& name, const Method::Config& config) { - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); +Method* MethodFactory::build( const std::string& name, const Method::Config& config ) { + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); force_link(); - MethodFactoryMap_t::const_iterator j = m->find(name); - if (j == m->end()) { + MethodFactoryMap_t::const_iterator j = m->find( name ); + if ( j == m->end() ) { eckit::Log::error() << "MethodFactory '" << name << "' not found." << std::endl; eckit::Log::error() << "MethodFactories are:" << std::endl; - for (j = m->begin() ; j != m->end() ; ++j) { - eckit::Log::error() << '\t' << (*j).first << std::endl; + for ( j = m->begin(); j != m->end(); ++j ) { + eckit::Log::error() << '\t' << ( *j ).first << std::endl; } - throw eckit::SeriousBug("MethodFactory '" + name + "' not found."); + throw eckit::SeriousBug( "MethodFactory '" + name + "' not found." ); } - return (*j).second->make(config); + return ( *j ).second->make( config ); } - -void Method::execute(const FieldSet& fieldsSource, FieldSet& fieldsTarget) const { +void Method::execute( const FieldSet& fieldsSource, FieldSet& fieldsTarget ) const { ATLAS_TRACE( "atlas::interpolation::method::Method::execute()" ); const size_t N = fieldsSource.size(); - ASSERT(N == fieldsTarget.size()); + ASSERT( N == fieldsTarget.size() ); - for (size_t i = 0; i < fieldsSource.size(); ++i) { - Log::debug() << "Method::execute() on field " << (i+1) << '/' << N << "..." << std::endl; + for ( size_t i = 0; i < fieldsSource.size(); ++i ) { + Log::debug() << "Method::execute() on field " << ( i + 1 ) << '/' << N << "..." << std::endl; const Field& src = fieldsSource[i]; - Field& tgt = fieldsTarget[i]; + Field& tgt = fieldsTarget[i]; - eckit::linalg::Vector v_src( const_cast(src.data()), src.shape(0) ); - eckit::linalg::Vector v_tgt( tgt.data(), tgt.shape(0) ); + eckit::linalg::Vector v_src( const_cast( src.data() ), src.shape( 0 ) ); + eckit::linalg::Vector v_tgt( tgt.data(), tgt.shape( 0 ) ); - eckit::linalg::LinearAlgebra::backend().spmv(matrix_, v_src, v_tgt); + eckit::linalg::LinearAlgebra::backend().spmv( matrix_, v_src, v_tgt ); } } - -void Method::execute(const Field& fieldSource, Field& fieldTarget) const { +void Method::execute( const Field& fieldSource, Field& fieldTarget ) const { ATLAS_TRACE( "atlas::interpolation::method::Method::execute()" ); - eckit::linalg::Vector - v_src(const_cast< Field& >(fieldSource).data(), fieldSource.shape(0)), - v_tgt(fieldTarget.data(), fieldTarget.shape(0)); + eckit::linalg::Vector v_src( const_cast( fieldSource ).data(), fieldSource.shape( 0 ) ), + v_tgt( fieldTarget.data(), fieldTarget.shape( 0 ) ); - eckit::linalg::LinearAlgebra::backend().spmv(matrix_, v_src, v_tgt); + eckit::linalg::LinearAlgebra::backend().spmv( matrix_, v_src, v_tgt ); } - -void Method::normalise(Triplets& triplets) { +void Method::normalise( Triplets& triplets ) { // sum all calculated weights for normalisation double sum = 0.0; - for (size_t j = 0; j < triplets.size(); ++j) { + for ( size_t j = 0; j < triplets.size(); ++j ) { sum += triplets[j].value(); } // now normalise all weights according to the total const double invSum = 1.0 / sum; - for (size_t j = 0; j < triplets.size(); ++j) { + for ( size_t j = 0; j < triplets.size(); ++j ) { triplets[j].value() *= invSum; } } -} // interpolation -} // atlas - +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/Method.h b/src/atlas/interpolation/method/Method.h index 77ba62a52..b4e2a8e26 100644 --- a/src/atlas/interpolation/method/Method.h +++ b/src/atlas/interpolation/method/Method.h @@ -4,11 +4,11 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #pragma once #include @@ -18,74 +18,66 @@ #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" - namespace atlas { - class Field; - class FieldSet; - class FunctionSpace; -} - +class Field; +class FieldSet; +class FunctionSpace; +} // namespace atlas namespace atlas { namespace interpolation { class Method : public eckit::Owned { public: - typedef eckit::Parametrisation Config; - Method(const Config& config) : config_(config) {} + Method( const Config& config ) : config_( config ) {} virtual ~Method() {} /** - * @brief Setup the interpolator relating two functionspaces - * @param source functionspace containing source elements - * @param target functionspace containing target points - */ - virtual void setup(const FunctionSpace& source, const FunctionSpace& target) = 0; + * @brief Setup the interpolator relating two functionspaces + * @param source functionspace containing source elements + * @param target functionspace containing target points + */ + virtual void setup( const FunctionSpace& source, const FunctionSpace& target ) = 0; - virtual void execute(const FieldSet& source, FieldSet& target) const; - virtual void execute(const Field& source, Field& target) const; + virtual void execute( const FieldSet& source, FieldSet& target ) const; + virtual void execute( const Field& source, Field& target ) const; protected: - - typedef eckit::linalg::Triplet Triplet; - typedef std::vector< Triplet > Triplets; + typedef eckit::linalg::Triplet Triplet; + typedef std::vector Triplets; typedef eckit::linalg::SparseMatrix Matrix; - static void normalise(Triplets& triplets); + static void normalise( Triplets& triplets ); const Config& config_; - // NOTE : Matrix-free or non-linear interpolation operators do not have matrices, - // so do not expose here, even though only linear operators are now implemented. + // NOTE : Matrix-free or non-linear interpolation operators do not have + // matrices, + // so do not expose here, even though only linear operators are now + // implemented. Matrix matrix_; - }; - struct MethodFactory { - - static Method *build(const std::string& name, const Method::Config&); + static Method* build( const std::string& name, const Method::Config& ); protected: - std::string name_; - virtual Method *make(const Method::Config&) = 0; + virtual Method* make( const Method::Config& ) = 0; - MethodFactory(const std::string&); + MethodFactory( const std::string& ); virtual ~MethodFactory(); }; - -template +template struct MethodBuilder : public MethodFactory { - - MethodBuilder(const std::string &name) : MethodFactory(name) {} + MethodBuilder( const std::string& name ) : MethodFactory( name ) {} private: - virtual Method *make(const Method::Config& config) { return new T(config); } + virtual Method* make( const Method::Config& config ) { return new T( config ); } }; -} // interpolation -} // atlas +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/NearestNeighbour.cc b/src/atlas/interpolation/method/NearestNeighbour.cc index 06fc676d6..ccbfc64d8 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.cc +++ b/src/atlas/interpolation/method/NearestNeighbour.cc @@ -4,85 +4,77 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. and Interpolation */ - #include "atlas/interpolation/method/NearestNeighbour.h" -#include "eckit/log/Plural.h" +#include "atlas/functionspace/NodeColumns.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "atlas/functionspace/NodeColumns.h" +#include "eckit/log/Plural.h" namespace atlas { namespace interpolation { namespace method { - namespace { +MethodBuilder __builder( "nearest-neighbour" ); -MethodBuilder __builder("nearest-neighbour"); - +} // namespace -} // (anonymous namespace) - - -void NearestNeighbour::setup(const FunctionSpace& source, const FunctionSpace& target) { +void NearestNeighbour::setup( const FunctionSpace& source, const FunctionSpace& target ) { functionspace::NodeColumns src = source; functionspace::NodeColumns tgt = target; - ASSERT(src); - ASSERT(tgt); + ASSERT( src ); + ASSERT( tgt ); Mesh meshSource = src.mesh(); Mesh meshTarget = tgt.mesh(); // build point-search tree - buildPointSearchTree(meshSource); - ASSERT(pTree_); - + buildPointSearchTree( meshSource ); + ASSERT( pTree_ ); // generate 3D point coordinates - mesh::actions::BuildXYZField("xyz")(meshTarget); - array::ArrayView< double, 2 > coords = array::make_view(meshTarget.nodes().field( "xyz" )); + mesh::actions::BuildXYZField( "xyz" )( meshTarget ); + array::ArrayView coords = array::make_view( meshTarget.nodes().field( "xyz" ) ); size_t inp_npts = meshSource.nodes().size(); size_t out_npts = meshTarget.nodes().size(); - // fill the sparse matrix - std::vector< Triplet > weights_triplets; - weights_triplets.reserve(out_npts); + std::vector weights_triplets; + weights_triplets.reserve( out_npts ); { Trace timer( Here(), "atlas::interpolation::method::NearestNeighbour::setup()" ); - for (size_t ip = 0; ip < out_npts; ++ip) { - - if (ip && (ip % 1000 == 0)) { + for ( size_t ip = 0; ip < out_npts; ++ip ) { + if ( ip && ( ip % 1000 == 0 ) ) { double rate = ip / timer.elapsed(); - Log::debug() << eckit::BigNum(ip) << " (at " << rate << " points/s)..." << std::endl; + Log::debug() << eckit::BigNum( ip ) << " (at " << rate << " points/s)..." << std::endl; } // find the closest input point to the output point - PointIndex3::Point p{coords(ip,0),coords(ip,1),coords(ip,2)}; - PointIndex3::NodeInfo nn = pTree_->nearestNeighbour(p); - size_t jp = nn.payload(); + PointIndex3::Point p{coords( ip, 0 ), coords( ip, 1 ), coords( ip, 2 )}; + PointIndex3::NodeInfo nn = pTree_->nearestNeighbour( p ); + size_t jp = nn.payload(); // insert the weights into the interpolant matrix - ASSERT(jp < inp_npts); - weights_triplets.push_back(Triplet(ip, jp, 1)); + ASSERT( jp < inp_npts ); + weights_triplets.push_back( Triplet( ip, jp, 1 ) ); } } // fill sparse matrix and return - Matrix A(out_npts, inp_npts, weights_triplets); - matrix_.swap(A); + Matrix A( out_npts, inp_npts, weights_triplets ); + matrix_.swap( A ); } - -} // method -} // interpolation -} // atlas +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/NearestNeighbour.h b/src/atlas/interpolation/method/NearestNeighbour.h index 9bcfb8bc4..38de47c20 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.h +++ b/src/atlas/interpolation/method/NearestNeighbour.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,31 +13,26 @@ #include "atlas/interpolation/method/KNearestNeighboursBase.h" - namespace atlas { namespace interpolation { namespace method { - class NearestNeighbour : public KNearestNeighboursBase { public: - - NearestNeighbour(const Config& config) : KNearestNeighboursBase(config) {} + NearestNeighbour( const Config& config ) : KNearestNeighboursBase( config ) {} virtual ~NearestNeighbour() {} protected: - /** - * @brief Create an interpolant sparse matrix relating two (pre-partitioned) meshes, - * using nearest neighbour method - * @param source functionspace containing source elements - * @param target functionspace containing target points - */ - virtual void setup(const FunctionSpace& source, const FunctionSpace& target) override; - + * @brief Create an interpolant sparse matrix relating two (pre-partitioned) + * meshes, + * using nearest neighbour method + * @param source functionspace containing source elements + * @param target functionspace containing target points + */ + virtual void setup( const FunctionSpace& source, const FunctionSpace& target ) override; }; - -} // method -} // interpolation -} // atlas +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/PointIndex3.cc b/src/atlas/interpolation/method/PointIndex3.cc index f9c9146fc..93acff3af 100644 --- a/src/atlas/interpolation/method/PointIndex3.cc +++ b/src/atlas/interpolation/method/PointIndex3.cc @@ -5,7 +5,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -20,44 +21,38 @@ namespace atlas { namespace interpolation { namespace method { -ElemIndex3* create_element_kdtree(const Field& field_centres) { - +ElemIndex3* create_element_kdtree( const Field& field_centres ) { const array::ArrayView centres = array::make_view( field_centres ); - static bool fastBuildKDTrees = eckit::Resource("$ATLAS_FAST_BUILD_KDTREES", true); + static bool fastBuildKDTrees = eckit::Resource( "$ATLAS_FAST_BUILD_KDTREES", true ); - ElemIndex3* tree = new ElemIndex3(); - const size_t nb_cells = centres.shape(0); + ElemIndex3* tree = new ElemIndex3(); + const size_t nb_cells = centres.shape( 0 ); - if (fastBuildKDTrees) { - std::vector< ElemIndex3::Value > p; - p.reserve(nb_cells); + if ( fastBuildKDTrees ) { + std::vector p; + p.reserve( nb_cells ); - for (size_t j = 0; j < nb_cells; ++j) { - p.push_back(ElemIndex3::Value( - ElemIndex3::Point(centres(j, XX), centres(j, YY), centres(j, ZZ)), - ElemIndex3::Payload(j) )); + for ( size_t j = 0; j < nb_cells; ++j ) { + p.push_back( ElemIndex3::Value( ElemIndex3::Point( centres( j, XX ), centres( j, YY ), centres( j, ZZ ) ), + ElemIndex3::Payload( j ) ) ); } - tree->build(p.begin(), p.end()); + tree->build( p.begin(), p.end() ); } else { - for (size_t j = 0; j < nb_cells; ++j) { - tree->insert(ElemIndex3::Value( - ElemIndex3::Point(centres(j, XX), centres(j, YY), centres(j, ZZ)), - ElemIndex3::Payload(j) )); + for ( size_t j = 0; j < nb_cells; ++j ) { + tree->insert( ElemIndex3::Value( ElemIndex3::Point( centres( j, XX ), centres( j, YY ), centres( j, ZZ ) ), + ElemIndex3::Payload( j ) ) ); } } return tree; } - -ElemIndex3* create_element_centre_index(const Mesh& mesh) { - return create_element_kdtree( mesh.cells().field("centre") ); +ElemIndex3* create_element_centre_index( const Mesh& mesh ) { + return create_element_kdtree( mesh.cells().field( "centre" ) ); } - -} // namespace method -} // namespace interpolation -} // namespace atlas - +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/PointIndex3.h b/src/atlas/interpolation/method/PointIndex3.h index 3d8698121..c3eb1cb11 100644 --- a/src/atlas/interpolation/method/PointIndex3.h +++ b/src/atlas/interpolation/method/PointIndex3.h @@ -4,20 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once +#include "atlas/field/Field.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/util/CoordinateEnums.h" #include "eckit/container/KDMapped.h" #include "eckit/container/KDMemory.h" #include "eckit/container/KDTree.h" #include "eckit/geometry/Point3.h" -#include "atlas/field/Field.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/mesh/Mesh.h" - namespace atlas { namespace interpolation { @@ -25,20 +25,20 @@ namespace method { //---------------------------------------------------------------------------------------------------------------------- -template +template class PointKdTree : public eckit::KDTreeMemory { public: typedef eckit::KDTreeMemory Tree; - typedef typename Tree::Alloc Alloc; - typedef typename Tree::NodeInfo NodeInfo; - typedef typename Tree::NodeList NodeList; + typedef typename Tree::Alloc Alloc; + typedef typename Tree::NodeInfo NodeInfo; + typedef typename Tree::NodeList NodeList; typedef typename Tree::PayloadType Payload; - typedef typename Tree::Point Point; - typedef typename Tree::Value Value; + typedef typename Tree::Point Point; + typedef typename Tree::Value Value; PointKdTree() : eckit::KDTreeMemory() {} - PointKdTree(Alloc& alloc) : Tree(alloc) {} + PointKdTree( Alloc& alloc ) : Tree( alloc ) {} using Tree::findInSphere; using Tree::kNearestNeighbours; @@ -53,7 +53,7 @@ class PointKdTree : public eckit::KDTreeMemory { struct PointIndex3TreeTrait { typedef eckit::geometry::Point3 Point; - typedef size_t Payload; + typedef size_t Payload; }; typedef PointKdTree PointIndex3; @@ -62,18 +62,19 @@ typedef PointKdTree PointIndex3; struct ElemIndex3TreeTrait { typedef eckit::geometry::Point3 Point; - typedef size_t Payload; + typedef size_t Payload; }; typedef PointKdTree ElemIndex3; -ElemIndex3* create_element_kdtree(const Field& field_centres); +ElemIndex3* create_element_kdtree( const Field& field_centres ); -// TODO: remove this function, and use "create_element_kdtree(const Field&)" instead. -ElemIndex3* create_element_centre_index(const Mesh& mesh); +// TODO: remove this function, and use "create_element_kdtree(const Field&)" +// instead. +ElemIndex3* create_element_centre_index( const Mesh& mesh ); //---------------------------------------------------------------------------------------------------------------------- -} // namespace method -} // namespace interpolation -} // namespace atlas +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/PointSet.cc b/src/atlas/interpolation/method/PointSet.cc index d9f0936a1..fa0533d66 100644 --- a/src/atlas/interpolation/method/PointSet.cc +++ b/src/atlas/interpolation/method/PointSet.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,10 +13,9 @@ #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/field/Field.h" -#include "atlas/field/Field.h" #include "eckit/config/Resource.h" using namespace eckit; @@ -26,68 +26,65 @@ namespace method { //---------------------------------------------------------------------------------------------------------------------- -PointSet::PointSet( const std::vector< Point >& ipts ) : npts_(ipts.size()) -{ - build(ipts); +PointSet::PointSet( const std::vector& ipts ) : npts_( ipts.size() ) { + build( ipts ); } -PointSet::PointSet( Mesh& mesh ) -{ +PointSet::PointSet( Mesh& mesh ) { mesh::Nodes& nodes = mesh.nodes(); npts_ = nodes.size(); ASSERT( npts_ > 0 ); - ASSERT( nodes.has_field("xyz") ); + ASSERT( nodes.has_field( "xyz" ) ); - array::ArrayView coords = array::make_view( nodes.field("xyz") ); - static bool fastBuildKDTrees = eckit::Resource("$ATLAS_FAST_BUILD_KDTREES", true); + array::ArrayView coords = array::make_view( nodes.field( "xyz" ) ); + static bool fastBuildKDTrees = eckit::Resource( "$ATLAS_FAST_BUILD_KDTREES", true ); tree_ = new PointIndex3(); - if (fastBuildKDTrees) { - std::vector< PointIndex3::Value > pidx; - pidx.reserve(npts_); + if ( fastBuildKDTrees ) { + std::vector pidx; + pidx.reserve( npts_ ); 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 ) ); + pidx.push_back( + PointIndex3::Value( PointIndex3::Point( coords( ip, 0 ), coords( ip, 1 ), coords( ip, 2 ) ), ip ) ); - - tree_->build(pidx.begin(), pidx.end()); + tree_->build( pidx.begin(), pidx.end() ); } else { for ( size_t ip = 0; ip < npts_; ++ip ) - tree_->insert( PointIndex3::Value( PointIndex3::Point( coords(ip, 0), coords(ip, 1), coords(ip, 2) ) , ip ) ); + tree_->insert( + PointIndex3::Value( PointIndex3::Point( coords( ip, 0 ), coords( ip, 1 ), coords( ip, 2 ) ), ip ) ); } } -size_t PointSet::search_unique( const Point& p, size_t idx, uint32_t n ) -{ - PointIndex3::NodeList nearest = tree_->kNearestNeighbours( p, Kn(n) ); +size_t PointSet::search_unique( const Point& p, size_t idx, uint32_t n ) { + PointIndex3::NodeList nearest = tree_->kNearestNeighbours( p, Kn( n ) ); std::vector equals; equals.reserve( nearest.size() ); - for ( size_t i = 0; i < nearest.size(); ++i ) - { - Point np = nearest[i].value().point(); + for ( size_t i = 0; i < nearest.size(); ++i ) { + Point np = nearest[i].value().point(); size_t nidx = nearest[i].value().payload(); -// std::cout << " - " << nidx << " " << np << std::endl; + // std::cout << " - " << nidx << " " << np << std::endl; - if ( eckit::geometry::points_equal(p, np) ) - { -// std::cout << " EQUAL !!" << std::endl; - equals.push_back(nidx); + if ( eckit::geometry::points_equal( p, np ) ) { + // std::cout << " EQUAL !!" << std::endl; + equals.push_back( nidx ); } else break; } - if ( equals.size() == nearest.size() ) /* need to increase the search to find all duplicates of this point */ + if ( equals.size() == nearest.size() ) /* need to increase the search to find + all duplicates of this point */ { - return this->search_unique(p, idx, ++n); + return this->search_unique( p, idx, ++n ); } else /* stop recursion */ { @@ -97,7 +94,7 @@ size_t PointSet::search_unique( const Point& p, size_t idx, uint32_t n ) ret = equals[0]; for ( size_t n = 1; n < equals.size(); ++n ) - duplicates_[ equals[n] ] = ret; + duplicates_[equals[n]] = ret; return ret; } @@ -105,7 +102,6 @@ size_t PointSet::search_unique( const Point& p, size_t idx, uint32_t n ) //---------------------------------------------------------------------------------------------------------------------- -} // namespace method -} // namespace interpolation -} // namespace atlas - +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/PointSet.h b/src/atlas/interpolation/method/PointSet.h index cbf468e3d..aa2814053 100644 --- a/src/atlas/interpolation/method/PointSet.h +++ b/src/atlas/interpolation/method/PointSet.h @@ -4,26 +4,27 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once +#include #include #include #include #include #include -#include #include -#include "eckit/types/FloatCompare.h" #include "eckit/config/Resource.h" +#include "eckit/types/FloatCompare.h" #include "atlas/interpolation/method/PointIndex3.h" -#include "atlas/runtime/Trace.h" #include "atlas/mesh/Mesh.h" +#include "atlas/runtime/Trace.h" namespace atlas { namespace interpolation { @@ -32,61 +33,53 @@ namespace method { //---------------------------------------------------------------------------------------------------------------------- class PointSet { - -public: // types - +public: // types typedef PointIndex3::Point Point; typedef PointIndex3::iterator iterator; - typedef std::map< size_t, size_t > DupStore_t; - -public: // methods + typedef std::map DupStore_t; - PointSet( const std::vector< Point >& ipts ); +public: // methods + PointSet( const std::vector& ipts ); PointSet( atlas::Mesh& mesh ); - ~PointSet(){ delete tree_; } + ~PointSet() { delete tree_; } DupStore_t& duplicates() { return duplicates_; } - template < typename POINT_T > - void list_unique_points( std::vector< POINT_T >& opts ) - { + template + void list_unique_points( std::vector& opts ) { ATLAS_TRACE( "Finding unique points" ); ASSERT( opts.empty() ); - opts.reserve(npts_); + opts.reserve( npts_ ); - for( PointIndex3::iterator i = tree_->begin(); i != tree_->end(); ++i ) - { - Point p ( i->point() ); - size_t ip = i->payload(); -// std::cout << "point " << ip << " " << p << std::endl; - size_t uidx = unique(p,ip); - if( ip == uidx ) - { + for ( PointIndex3::iterator i = tree_->begin(); i != tree_->end(); ++i ) { + Point p( i->point() ); + size_t ip = i->payload(); + // std::cout << "point " << ip << " " << p << std::endl; + size_t uidx = unique( p, ip ); + if ( ip == uidx ) { opts.push_back( POINT_T( p.data() ) ); -// std::cout << "----> UNIQ " << ip << std::endl; + // std::cout << "----> UNIQ " << ip << std::endl; } - else - { -// std::cout << "----> DUP " << ip << " -> " << uidx << std::endl; + else { + // std::cout << "----> DUP " << ip << " -> " << uidx << + // std::endl; } -// ++show_progress; + // ++show_progress; } } - size_t unique( const Point& p, size_t idx = std::numeric_limits::max() ) - { - DupStore_t::iterator dit = duplicates_.find(idx); - if( dit != duplicates_.end() ) - { -// std::cout << " !! DUPLICATE !!" << std::endl; - return dit->second; + size_t unique( const Point& p, size_t idx = std::numeric_limits::max() ) { + DupStore_t::iterator dit = duplicates_.find( idx ); + if ( dit != duplicates_.end() ) { + // std::cout << " !! DUPLICATE !!" << std::endl; + return dit->second; } else - return this->search_unique(p,idx,0); + return this->search_unique( p, idx, 0 ); } iterator begin() { return tree_->begin(); } @@ -94,56 +87,50 @@ class PointSet { size_t size() const { return npts_; } -protected: // methods +protected: // methods + template + void build( const V& ipts ) { + static bool fastBuildKDTrees = eckit::Resource( "$ATLAS_FAST_BUILD_KDTREES", true ); + tree_ = new PointIndex3(); - template < typename V > - void build( const V& ipts ) - { - static bool fastBuildKDTrees = eckit::Resource("$ATLAS_FAST_BUILD_KDTREES", true); - tree_ = new PointIndex3(); + if ( fastBuildKDTrees ) { + std::vector pidx; + pidx.reserve( npts_ ); - if(fastBuildKDTrees){ - std::vector< PointIndex3::Value > 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( ipts[ip] ), ip ) ); } - tree_->build(pidx.begin(), pidx.end()); + tree_->build( pidx.begin(), pidx.end() ); } else { - for( size_t ip = 0; ip < npts_; ++ip ) { - tree_->insert(PointIndex3::Value( PointIndex3::Point( ipts[ip] ), ip ) ); + for ( size_t ip = 0; ip < npts_; ++ip ) { + tree_->insert( PointIndex3::Value( PointIndex3::Point( ipts[ip] ), ip ) ); } } } - size_t search_unique( const Point& p, size_t idx, uint32_t n ); + size_t search_unique( const Point& p, size_t idx, uint32_t n ); protected: - - size_t Kn( uint32_t n ) - { - if( !n ) + size_t Kn( uint32_t n ) { + if ( !n ) return 2; else - return 2 + std::pow(2,n) * 180; + return 2 + std::pow( 2, n ) * 180; } - bool duplicate( size_t idx ) { return duplicates_.find(idx) != duplicates_.end(); } + bool duplicate( size_t idx ) { return duplicates_.find( idx ) != duplicates_.end(); } private: - size_t npts_; PointIndex3* tree_; - DupStore_t duplicates_; ///< map from duplicate idx to idx representing group of points - + DupStore_t duplicates_; ///< map from duplicate idx to idx representing group + /// of points }; //---------------------------------------------------------------------------------------------------------------------- - -} // namespace method -} // namespace interpolation -} // namespace atlas +} // namespace method +} // namespace interpolation +} // namespace atlas diff --git a/src/atlas/interpolation/method/Ray.cc b/src/atlas/interpolation/method/Ray.cc index e1be87dd1..14dcf3e5e 100644 --- a/src/atlas/interpolation/method/Ray.cc +++ b/src/atlas/interpolation/method/Ray.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -18,30 +19,32 @@ namespace atlas { namespace interpolation { namespace method { -Ray::Ray(const double *p) { - orig = Vector3D::Map(p); - dir = -orig; +Ray::Ray( const double* p ) { + orig = Vector3D::Map( p ); + dir = -orig; } -Ray::Ray(const double* o, const double* d) { - orig = Vector3D::Map(o); - dir = Vector3D::Map(d); +Ray::Ray( const double* o, const double* d ) { + orig = Vector3D::Map( o ); + dir = Vector3D::Map( d ); } -Ray::Ray(const PointXYZ& p ) { - orig = Vector3D::Map(p.data()); - dir = -orig; +Ray::Ray( const PointXYZ& p ) { + orig = Vector3D::Map( p.data() ); + dir = -orig; } -Ray::Ray(const PointXYZ& o, const Vector3D& d) { - orig = Vector3D::Map(o.data()); - dir = d; +Ray::Ray( const PointXYZ& o, const Vector3D& d ) { + orig = Vector3D::Map( o.data() ); + dir = d; } -void Ray::print(std::ostream& s) const { s << "Ray[orig=" << orig << ",dir=" << dir << "]"; } +void Ray::print( std::ostream& s ) const { + s << "Ray[orig=" << orig << ",dir=" << dir << "]"; +} -std::ostream& operator<<(std::ostream& s, const Ray& p) { - p.print(s); +std::ostream& operator<<( std::ostream& s, const Ray& p ) { + p.print( s ); return s; } @@ -50,4 +53,3 @@ std::ostream& operator<<(std::ostream& s, const Ray& p) { } // namespace method } // namespace interpolation } // namespace atlas - diff --git a/src/atlas/interpolation/method/Ray.h b/src/atlas/interpolation/method/Ray.h index 4e0771986..8ed774cd8 100644 --- a/src/atlas/interpolation/method/Ray.h +++ b/src/atlas/interpolation/method/Ray.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -24,25 +25,23 @@ namespace method { /// Ray trace data structure struct Ray { + Vector3D orig; + Vector3D dir; - Vector3D orig; - Vector3D dir; + /// initializes ray with origin in point and direction to (0,0,0) + explicit Ray( const double* p ); - /// initializes ray with origin in point and direction to (0,0,0) - explicit Ray(const double* p); + Ray( const double* o, const double* d ); - Ray(const double* o, const double* d); + explicit Ray( const PointXYZ& ); - explicit Ray( const PointXYZ& ); + Ray( const PointXYZ&, const Vector3D& ); - Ray(const PointXYZ&, const Vector3D&); + Vector3D operator()( double t ) const { return orig + t * dir; } - Vector3D operator()(double t) const { return orig + t * dir; } - - void print(std::ostream& s) const; - - friend std::ostream& operator<<(std::ostream& s, const Ray& p); + void print( std::ostream& s ) const; + friend std::ostream& operator<<( std::ostream& s, const Ray& p ); }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index b7991d25b..4467f69ef 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -4,12 +4,11 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - - #include "atlas/library/config.h" #ifdef ATLAS_HAVE_TRANS @@ -17,75 +16,66 @@ #endif #include "eckit/eckit_config.h" -#include "eckit/runtime/Main.h" -#include "eckit/log/Log.h" -#include "eckit/filesystem/PathName.h" #include "eckit/filesystem/LocalPathName.h" -#include "eckit/utils/Translator.h" -#include "eckit/log/PrefixTarget.h" +#include "eckit/filesystem/PathName.h" +#include "eckit/log/Log.h" #include "eckit/log/OStreamTarget.h" +#include "eckit/log/PrefixTarget.h" +#include "eckit/runtime/Main.h" +#include "eckit/utils/Translator.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/runtime/Log.h" -#include "atlas/util/Config.h" #include "atlas/library/Library.h" -#include "atlas/library/version.h" #include "atlas/library/git_sha1.h" +#include "atlas/library/version.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" +#include "atlas/util/Config.h" -using eckit::PathName; -using eckit::Main; using eckit::LocalPathName; +using eckit::Main; +using eckit::PathName; namespace atlas { - //---------------------------------------------------------------------------------------------------------------------- namespace { - std::string str(bool v) { +std::string str( bool v ) { return v ? "ON" : "OFF"; - } +} - std::string str(const eckit::system::Library& lib) { +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() )); - } - return default_value; - } - - int getEnv( const std::string& env, int default_value ) { - if (::getenv( env.c_str() ) ) { - return eckit::Translator()(::getenv( env.c_str() )); - } - return default_value; - } +} + +bool getEnv( const std::string& env, bool default_value ) { + 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() ) ); } + return default_value; } +} // namespace + //---------------------------------------------------------------------------------------------------------------------- static Library libatlas; - Library::Library() : - eckit::system::Library( std::string("atlas") ), - debug_( eckit::system::Library::debug() ), - info_( getEnv("ATLAS_INFO", true) ), - trace_( getEnv("ATLAS_TRACE", false) ), - trace_report_( getEnv("ATLAS_TRACE_REPORT", false) ), - trace_barriers_( getEnv("ATLAS_TRACE_BARRIERS", false) ) { -} + eckit::system::Library( std::string( "atlas" ) ), + debug_( eckit::system::Library::debug() ), + info_( getEnv( "ATLAS_INFO", true ) ), + trace_( getEnv( "ATLAS_TRACE", false ) ), + trace_report_( getEnv( "ATLAS_TRACE_REPORT", false ) ), + trace_barriers_( getEnv( "ATLAS_TRACE_BARRIERS", false ) ) {} Library& Library::instance() { return libatlas; @@ -99,77 +89,72 @@ std::string Library::version() const { return atlas::library::version(); } -std::string Library::gitsha1(unsigned int count) const { - return atlas::library::git_sha1(count); +std::string Library::gitsha1( unsigned int count ) const { + return atlas::library::git_sha1( count ); } -void Library::initialise(int argc, char **argv) { - if( not Main::ready() ) { - Main::initialise(argc, argv); - Main::instance().taskID( eckit::mpi::comm("world").rank() ); - if( Main::instance().taskID() != 0 ) { - eckit::Log::warning().reset(); - eckit::Log::info().reset(); - eckit::Log::debug().reset(); - atlas::Log::debug().reset(); +void Library::initialise( int argc, char** argv ) { + if ( not Main::ready() ) { + Main::initialise( argc, argv ); + Main::instance().taskID( eckit::mpi::comm( "world" ).rank() ); + if ( Main::instance().taskID() != 0 ) { + eckit::Log::warning().reset(); + eckit::Log::info().reset(); + eckit::Log::debug().reset(); + atlas::Log::debug().reset(); } Log::debug() << "Atlas initialised eckit::Main.\n"; - if( eckit::mpi::comm("world").size() > 1 ) - Log::debug() << - "--> Only MPI rank 0 is logging. Please initialise eckit::Main \n" - " before to avoid this behaviour.\n"; + if ( eckit::mpi::comm( "world" ).size() > 1 ) + Log::debug() << "--> Only MPI rank 0 is logging. Please initialise eckit::Main \n" + " before to avoid this behaviour.\n"; } initialise(); } -void Library::initialise(const eckit::Parametrisation& config) { - - if( config.has("log") ) { - config.get("log.info",info_); - config.get("log.trace",trace_); - config.get("log.debug",debug_); +void Library::initialise( const eckit::Parametrisation& config ) { + if ( config.has( "log" ) ) { + config.get( "log.info", info_ ); + config.get( "log.trace", trace_ ); + config.get( "log.debug", debug_ ); } - if( config.has("trace") ) { - config.get("trace.barriers",trace_barriers_); - config.get("trace.report", trace_report_); + if ( config.has( "trace" ) ) { + config.get( "trace.barriers", trace_barriers_ ); + 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 ) == mpi::comm().rank() ) { - std::ostream& out = Log::debug(); - out << "Executable [" << Main::instance().name() << "]\n"; - out << " \n"; - out << " current dir [" << PathName(LocalPathName::cwd()).fullName() << "]\n"; - out << " \n"; - out << " MPI\n"; - out << " communicator [" << mpi::comm() << "] \n"; - out << " size [" << mpi::comm().size() << "] \n"; - out << " rank [" << mpi::comm().rank() << "] \n"; - out << " \n"; - out << " log.info [" << str(info_) << "] \n"; - out << " log.trace [" << str(trace()) << "] \n"; - out << " log.debug [" << str(debug()) << "] \n"; - out << " trace.barriers [" << str(traceBarriers()) << "] \n"; - out << " trace.report [" << str(trace_report_) << "] \n"; - out << " \n"; - out << atlas::Library::instance().information(); - out << std::flush; + if ( getEnv( "ATLAS_LOG_RANK", 0 ) == mpi::comm().rank() ) { + std::ostream& out = Log::debug(); + out << "Executable [" << Main::instance().name() << "]\n"; + out << " \n"; + out << " current dir [" << PathName( LocalPathName::cwd() ).fullName() << "]\n"; + out << " \n"; + out << " MPI\n"; + out << " communicator [" << mpi::comm() << "] \n"; + out << " size [" << mpi::comm().size() << "] \n"; + out << " rank [" << mpi::comm().rank() << "] \n"; + out << " \n"; + out << " log.info [" << str( info_ ) << "] \n"; + out << " log.trace [" << str( trace() ) << "] \n"; + out << " log.debug [" << str( debug() ) << "] \n"; + out << " trace.barriers [" << str( traceBarriers() ) << "] \n"; + out << " trace.report [" << str( trace_report_ ) << "] \n"; + out << " \n"; + out << atlas::Library::instance().information(); + out << std::flush; } } void Library::initialise() { - initialise( util::NoConfig() ); + initialise( util::NoConfig() ); } 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; } // Make sure that these specialised channels that wrap Log::info() are // destroyed before eckit::Log::info gets destroyed. @@ -182,48 +167,45 @@ void Library::finalise() { } eckit::Channel& Library::infoChannel() const { - if( info_ ) { - return eckit::Log::info(); - } else if( ! info_channel_ ) { - info_channel_.reset( new eckit::Channel() ); - } - return *info_channel_; + if ( info_ ) { return eckit::Log::info(); } + else if ( !info_channel_ ) { + info_channel_.reset( new eckit::Channel() ); + } + return *info_channel_; } eckit::Channel& Library::traceChannel() const { - 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())))); - } else { - trace_channel_.reset( new eckit::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() ) ) ) ); + } + else { + trace_channel_.reset( new eckit::Channel() ); + } + return *trace_channel_; } - eckit::Channel& Library::debugChannel() const { - 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() ); - } - return *debug_channel_; + 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() ); + } + return *debug_channel_; } //---------------------------------------------------------------------------------------------------------------------- void Library::Information::print( std::ostream& out ) const { out << "atlas version (" << atlas::Library::instance().version() << "), " - << "git-sha1 "<< atlas::Library::instance().gitsha1(7) << '\n'; + << "git-sha1 " << atlas::Library::instance().gitsha1( 7 ) << '\n'; out << " \n"; out << " Build:" << std::endl; out << " build type : " << ATLAS_BUILD_TYPE << '\n' << " timestamp : " << ATLAS_BUILD_TIMESTAMP << '\n' - << " op. system : " << ATLAS_OS_NAME << " (" << ATLAS_OS_STR << ")" << '\n' - << " processor : " << ATLAS_SYS_PROCESSOR << std::endl + << " op. system : " << ATLAS_OS_NAME << " (" << ATLAS_OS_STR << ")" << '\n' + << " processor : " << ATLAS_SYS_PROCESSOR << std::endl << " c compiler : " << ATLAS_C_COMPILER_ID << " " << ATLAS_C_COMPILER_VERSION << '\n' << " flags : " << ATLAS_C_FLAGS << '\n' << " c++ compiler : " << ATLAS_CXX_COMPILER_ID << " " << ATLAS_CXX_COMPILER_VERSION << '\n' @@ -231,70 +213,65 @@ void Library::Information::print( std::ostream& out ) const { #ifndef EC_HAVE_FORTRAN << " fortran : NO " << '\n' #else - << " fortran compiler: " << ATLAS_Fortran_COMPILER_ID << " " << ATLAS_Fortran_COMPILER_VERSION << '\n' - << " flags : " << ATLAS_Fortran_FLAGS << '\n' + << " fortran compiler: " << ATLAS_Fortran_COMPILER_ID << " " << ATLAS_Fortran_COMPILER_VERSION << '\n' + << " flags : " << ATLAS_Fortran_FLAGS << '\n' #endif - << " \n"; - - bool feature_fortran(false); - bool feature_OpenMP(false); - bool feature_Trans(false); - bool feature_Tesselation(false); - bool feature_BoundsChecking(false); - bool feature_MPI(false); + << " \n"; + + bool feature_fortran( false ); + bool feature_OpenMP( false ); + bool feature_Trans( false ); + bool feature_Tesselation( false ); + bool feature_BoundsChecking( false ); + bool feature_MPI( false ); #ifdef ATLAS_HAVE_FORTRAN - feature_fortran = true; + feature_fortran = true; #endif #ifdef ECKIT_HAVE_MPI - feature_MPI = true; + feature_MPI = true; #endif #ifdef ATLAS_HAVE_OMP - feature_OpenMP = true; + feature_OpenMP = true; #endif #ifdef ATLAS_HAVE_TRANS - feature_Trans = true; + feature_Trans = true; #endif #ifdef ATLAS_HAVE_TESSELATION - feature_Tesselation = true; + feature_Tesselation = true; #endif #ifdef ATLAS_HAVE_BOUNDSCHECKING - feature_BoundsChecking = true; + feature_BoundsChecking = true; #endif - std::string array_data_store = "Native"; + std::string array_data_store = "Native"; #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE - array_data_store = "Gridtools-host"; + array_data_store = "Gridtools-host"; #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array_data_store = "GridTools-CUDA"; + array_data_store = "GridTools-CUDA"; #endif #endif - out << " Features:" << '\n' - << " Fortran : " << str(feature_fortran) << '\n' - << " MPI : " << str(feature_MPI) << '\n' - << " OpenMP : " << str(feature_OpenMP) << '\n' - << " BoundsChecking : " << str(feature_BoundsChecking) << '\n' - << " Trans : " << str(feature_Trans) << '\n' - << " Tesselation : " << str(feature_Tesselation) << '\n' + out << " Features:" << '\n' + << " Fortran : " << str( feature_fortran ) << '\n' + << " MPI : " << str( feature_MPI ) << '\n' + << " OpenMP : " << str( feature_OpenMP ) << '\n' + << " BoundsChecking : " << str( feature_BoundsChecking ) << '\n' + << " Trans : " << str( feature_Trans ) << '\n' + << " Tesselation : " << str( feature_Tesselation ) << '\n' << " ArrayDataStore : " << array_data_store << '\n' << " gidx_t : " << ATLAS_BITS_GLOBAL << " bit integer" << '\n' << " \n"; - out << " Dependencies: " << "\n"; + 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'; } #ifdef ATLAS_HAVE_TRANS out << " transi version (" << transi_version() << "), " - << "git-sha1 "<< transi_git_sha1_abbrev(7) << '\n'; + << "git-sha1 " << transi_git_sha1_abbrev( 7 ) << '\n'; out << " trans version (" << trans_version() << "), " - << "git-sha1 "<< trans_git_sha1_abbrev(7) << '\n'; + << "git-sha1 " << trans_git_sha1_abbrev( 7 ) << '\n'; #endif - } -} // namespace atlas - +} // namespace atlas diff --git a/src/atlas/library/Library.h b/src/atlas/library/Library.h index 4f6eca2e9..53998860c 100644 --- a/src/atlas/library/Library.h +++ b/src/atlas/library/Library.h @@ -4,19 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include #include +#include #include "eckit/system/Library.h" namespace eckit { - class Parametrisation; +class Parametrisation; } namespace atlas { @@ -25,24 +26,26 @@ namespace atlas { class Library : public eckit::system::Library { public: - Library(); static Library& instance(); virtual std::string version() const override; - virtual std::string gitsha1(unsigned int count) const override; - std::string gitsha1() const { return gitsha1(7); } + virtual std::string gitsha1( unsigned int count ) const override; + std::string gitsha1() const { return gitsha1( 7 ); } - void initialise(int argc, char **argv); - void initialise(const eckit::Parametrisation&); + void initialise( int argc, char** argv ); + void initialise( const eckit::Parametrisation& ); void initialise(); void finalise(); struct Information { - friend std::ostream& operator<<(std::ostream& s, const Information& i) { i.print(s); return s; } - void print(std::ostream&) const; + friend std::ostream& operator<<( std::ostream& s, const Information& i ) { + i.print( s ); + return s; + } + void print( std::ostream& ) const; }; Information information() const { return Information(); } @@ -55,7 +58,6 @@ class Library : public eckit::system::Library { bool traceBarriers() const { return trace_barriers_; } protected: - virtual const void* addr() const override; bool info_{true}; @@ -72,5 +74,4 @@ typedef Library Atlas; //---------------------------------------------------------------------------------------------------------------------- -} // namespace atlas - +} // namespace atlas diff --git a/src/atlas/library/config.h b/src/atlas/library/config.h index 6bdcfbe63..6c2760023 100644 --- a/src/atlas/library/config.h +++ b/src/atlas/library/config.h @@ -1,7 +1,9 @@ #pragma once +#include #include "atlas/atlas_ecbuild_config.h" #include "atlas/library/defines.h" +#include "eckit/eckit_config.h" #define ATLAS_HAVE_TRACE 1 @@ -9,18 +11,17 @@ namespace atlas { /// @typedef gidx_t /// Integer type for global indices -#if ATLAS_BITS_GLOBAL==32 - typedef int gidx_t; +#if ATLAS_BITS_GLOBAL == 32 +typedef int gidx_t; #else - typedef long gidx_t; +typedef long gidx_t; #endif - /// @typedef idx_t - /// Integer type for indices in connectivity tables - typedef int idx_t; - - /// @typedef uidx_t - /// Integer type for unique indices - typedef long uidx_t; +/// @typedef idx_t +/// Integer type for indices in connectivity tables +typedef int idx_t; +/// @typedef uidx_t +/// Integer type for unique indices +typedef long uidx_t; } diff --git a/src/atlas/mesh.h b/src/atlas/mesh.h index 2c38711b2..1c706f083 100644 --- a/src/atlas/mesh.h +++ b/src/atlas/mesh.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,11 +13,11 @@ #pragma once -#include "atlas/mesh/Mesh.h" -#include "atlas/mesh/Nodes.h" -#include "atlas/mesh/Halo.h" +#include "atlas/mesh/Connectivity.h" #include "atlas/mesh/ElementType.h" -#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Elements.h" -#include "atlas/mesh/Connectivity.h" +#include "atlas/mesh/Halo.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/IsGhostNode.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index fd0b45d23..70bed2881 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -4,17 +4,18 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include "atlas/mesh/Connectivity.h" -#include "atlas/runtime/ErrorHandling.h" +#include #include "atlas/array.h" -#include "atlas/array/MakeView.h" #include "atlas/array/DataType.h" +#include "atlas/array/MakeView.h" #include "atlas/array/Vector.h" +#include "atlas/runtime/ErrorHandling.h" #ifdef ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 @@ -28,362 +29,339 @@ namespace atlas { namespace mesh { // ----------------------------------------------------------------------------- - -IrregularConnectivityImpl::IrregularConnectivityImpl(const std::string& name ) : - owns_(true), - data_{ - array::Array::create(0), // values - array::Array::create(1), // displs - array::Array::create(1)}, // counts - values_view_(array::make_host_view(*(data_[_values_]))), - displs_view_(array::make_host_view(*(data_[_displs_]))), - counts_view_(array::make_host_view(*(data_[_counts_]))), - missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), - rows_(0), - maxcols_(0), - mincols_(std::numeric_limits::max()), - ctxt_(0), - callback_update_(0), - callback_delete_(0), - gpu_clone_(this) -{ - rename(name); - displs_view_(0) = 0; - counts_view_(0) = 0; +IrregularConnectivityImpl::IrregularConnectivityImpl( const std::string& name ) : + owns_( true ), + data_{array::Array::create( 0 ), // values + array::Array::create( 1 ), // displs + array::Array::create( 1 )}, // counts + values_view_( array::make_host_view( *( data_[_values_] ) ) ), + displs_view_( array::make_host_view( *( data_[_displs_] ) ) ), + counts_view_( array::make_host_view( *( data_[_counts_] ) ) ), + missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), + rows_( 0 ), + maxcols_( 0 ), + mincols_( std::numeric_limits::max() ), + ctxt_( 0 ), + callback_update_( 0 ), + callback_delete_( 0 ), + gpu_clone_( this ) { + rename( name ); + displs_view_( 0 ) = 0; + counts_view_( 0 ) = 0; } // ----------------------------------------------------------------------------- -size_t get_total_size_counts(size_t rows, size_t counts[]) -{ +size_t get_total_size_counts( size_t rows, size_t counts[] ) { size_t total_size = 0; - for( size_t j=0; j(values, array::ArrayShape{get_total_size_counts(rows, counts)}), - array::Array::wrap(displs, array::ArrayShape{rows}), - array::Array::wrap(counts, array::ArrayShape{rows})}, - values_view_(array::make_view(*(data_[_values_]))), - displs_view_(array::make_view(*(data_[_displs_]))), - counts_view_(array::make_view(*(data_[_counts_]))), +IrregularConnectivityImpl::IrregularConnectivityImpl( idx_t values[], size_t rows, size_t displs[], size_t counts[] ) : + owns_( false ), + data_{array::Array::wrap( values, array::ArrayShape{get_total_size_counts( rows, counts )} ), + array::Array::wrap( displs, array::ArrayShape{rows} ), + array::Array::wrap( counts, array::ArrayShape{rows} )}, + values_view_( array::make_view( *( data_[_values_] ) ) ), + displs_view_( array::make_view( *( data_[_displs_] ) ) ), + counts_view_( array::make_view( *( data_[_counts_] ) ) ), missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), - rows_(rows), - ctxt_(0), - callback_update_(0), - callback_delete_(0), - gpu_clone_(this) -{ - maxcols_ = 0; - mincols_ = std::numeric_limits::max(); - for( size_t j=0; j::max(); + for ( size_t j = 0; j < rows; ++j ) { + maxcols_ = std::max( maxcols_, counts[j] ); + mincols_ = std::min( mincols_, counts[j] ); + } +} + +IrregularConnectivityImpl::IrregularConnectivityImpl( const IrregularConnectivityImpl& other ) : + owns_( false ), + data_{other.data_[0], other.data_[1], other.data_[2]}, + values_view_( other.values_view_ ), + displs_view_( other.displs_view_ ), + counts_view_( other.counts_view_ ), + missing_value_( other.missing_value_ ), + rows_( other.rows_ ), + maxcols_( other.maxcols_ ), + mincols_( other.mincols_ ), + ctxt_( 0 ), + gpu_clone_( this ) {} //------------------------------------------------------------------------------------------------------ -IrregularConnectivityImpl::~IrregularConnectivityImpl() -{ - on_delete(); +IrregularConnectivityImpl::~IrregularConnectivityImpl() { + on_delete(); - if(owns_) { - std::for_each(data_.begin(), data_.end(), [](array::Array* a){ - assert(a); - delete a; - a = 0; - }); - } + if ( owns_ ) { + std::for_each( data_.begin(), data_.end(), []( array::Array* a ) { + assert( a ); + delete a; + a = 0; + } ); + } } //------------------------------------------------------------------------------------------------------ -void IrregularConnectivityImpl::clear() -{ - if( owns() ) - { - data_[_values_]->resize(0); - data_[_displs_]->resize(1); - data_[_counts_]->resize(1); - displs_view_ = array::make_view(*(data_[_displs_])); - counts_view_ = array::make_view(*(data_[_counts_])); - displs_view_(0) = 0; - counts_view_(0) = 0; - } - else - { - data_[_values_] = nullptr; - data_[_displs_] = nullptr; - data_[_counts_] = nullptr; -//std::for_each(data_.begin(), data_.end(), [](array::Array* a){ a=0;}); - } - maxcols_ = 0; - mincols_ = std::numeric_limits::max(); - on_update(); +void IrregularConnectivityImpl::clear() { + if ( owns() ) { + data_[_values_]->resize( 0 ); + data_[_displs_]->resize( 1 ); + data_[_counts_]->resize( 1 ); + displs_view_ = array::make_view( *( data_[_displs_] ) ); + counts_view_ = array::make_view( *( data_[_counts_] ) ); + displs_view_( 0 ) = 0; + counts_view_( 0 ) = 0; + } + else { + data_[_values_] = nullptr; + data_[_displs_] = nullptr; + data_[_counts_] = nullptr; + // std::for_each(data_.begin(), data_.end(), [](array::Array* a){ a=0;}); + } + maxcols_ = 0; + mincols_ = std::numeric_limits::max(); + on_update(); } //------------------------------------------------------------------------------------------------------ -void IrregularConnectivityImpl::on_delete() -{ - if( ctxt_ && callback_delete_ ) callback_delete_(ctxt_); +void IrregularConnectivityImpl::on_delete() { + if ( ctxt_ && callback_delete_ ) callback_delete_( ctxt_ ); } //------------------------------------------------------------------------------------------------------ -void IrregularConnectivityImpl::on_update() -{ - if( ctxt_ && callback_update_ ) callback_update_(ctxt_); +void IrregularConnectivityImpl::on_update() { + if ( ctxt_ && callback_update_ ) callback_update_( ctxt_ ); } -void IrregularConnectivityImpl::resize( size_t old_size, size_t new_size, bool initialize, const idx_t values[], bool fortran_array) -{ - data_[_values_]->resize(new_size); - values_view_ = array::make_view(*(data_[_values_])); - //TODO WILLEM isnt this if the other way around? - idx_t add_base = fortran_array ? 0 : FORTRAN_BASE; - if (initialize) { - for (size_t j=0, c=old_size; cresize( new_size ); + values_view_ = array::make_view( *( data_[_values_] ) ); + // TODO WILLEM isnt this if the other way around? + idx_t add_base = fortran_array ? 0 : FORTRAN_BASE; + if ( initialize ) { + for ( size_t j = 0, c = old_size; c < new_size; ++c, ++j ) { + values_view_( c ) = values[j] + add_base; + } } - } else { - for (size_t j=old_size; jsize(); - - if(rows_ == 0) - old_size=0; +void IrregularConnectivityImpl::add( size_t rows, size_t cols, const idx_t values[], bool fortran_array ) { + if ( !owns_ ) throw eckit::AssertionFailed( "HybridConnectivity must be owned to be resized directly" ); + size_t old_size = data_[_values_]->size(); - size_t new_size = old_size + rows*cols; - size_t new_rows = rows_+rows; + if ( rows_ == 0 ) old_size = 0; - ASSERT( data_[_displs_] != 0 ); - ASSERT( data_[_counts_] != 0 ); - data_[_displs_]->resize(new_rows+1); - data_[_counts_]->resize(new_rows+1); - displs_view_ = array::make_view(*(data_[_displs_])); - counts_view_ = array::make_view(*(data_[_counts_])); + size_t new_size = old_size + rows * cols; + size_t new_rows = rows_ + rows; + ASSERT( data_[_displs_] != 0 ); + ASSERT( data_[_counts_] != 0 ); + data_[_displs_]->resize( new_rows + 1 ); + data_[_counts_]->resize( new_rows + 1 ); + displs_view_ = array::make_view( *( data_[_displs_] ) ); + counts_view_ = array::make_view( *( data_[_counts_] ) ); - for(size_t j=0; rows_ values_vector; - if( ! block.values_view_.contiguous() ) { - values_vector.resize(rows*cols); - values = values_vector.data(); - for( int i=0, c=0; i values_vector; + if ( !block.values_view_.contiguous() ) { + values_vector.resize( rows * cols ); + values = values_vector.data(); + for ( int i = 0, c = 0; i < rows; ++i ) { + for ( int j = 0; j < cols; ++j ) { + values_vector[c++] = block( i, j ); + } + } + fortran_array = false; + } + add( rows, cols, values, fortran_array ); } //------------------------------------------------------------------------------------------------------ -void IrregularConnectivityImpl::add( size_t rows, const size_t cols[] ) -{ - if( !owns_ ) throw eckit::AssertionFailed("HybridConnectivity must be owned to be resized directly"); - size_t old_size = data_[_values_]->size(); - size_t new_size = old_size; - for( size_t j=0; jresize(new_rows+1); - data_[_counts_]->resize(new_rows+1); - displs_view_ = array::make_view(*(data_[_displs_])); - counts_view_ = array::make_view(*(data_[_counts_])); - - for(size_t j=0; rows_size(); + size_t new_size = old_size; + for ( size_t j = 0; j < rows; ++j ) + new_size += cols[j]; + size_t new_rows = rows_ + rows; + data_[_displs_]->resize( new_rows + 1 ); + data_[_counts_]->resize( new_rows + 1 ); + displs_view_ = array::make_view( *( data_[_displs_] ) ); + counts_view_ = array::make_view( *( data_[_counts_] ) ); + + for ( size_t j = 0; rows_ < new_rows; ++rows_, ++j ) { + // TODO isnt this a bug ? I dont understand + displs_view_( rows_ + 1 ) = displs_view_( rows_ ) + cols[j]; + counts_view_( rows_ ) = cols[j]; + maxcols_ = std::max( maxcols_, cols[j] ); + mincols_ = std::min( mincols_, cols[j] ); + } + + resize( old_size, new_size, false, NULL, false ); + + on_update(); } //------------------------------------------------------------------------------------------------------ -void IrregularConnectivityImpl::add( size_t rows, size_t cols ) -{ - if( !owns_ ) throw eckit::AssertionFailed("HybridConnectivity must be owned to be resized directly"); - size_t old_size = data_[_values_]->size(); +void IrregularConnectivityImpl::add( size_t rows, size_t cols ) { + if ( !owns_ ) throw eckit::AssertionFailed( "HybridConnectivity must be owned to be resized directly" ); + size_t old_size = data_[_values_]->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; + size_t new_size = old_size + rows * cols; + size_t new_rows = rows_ + rows; - ASSERT( data_[_displs_] != 0 ); - ASSERT( data_[_counts_] != 0 ); - data_[_displs_]->resize(new_rows+1); - data_[_counts_]->resize(new_rows+1); - displs_view_ = array::make_view(*(data_[_displs_])); - counts_view_ = array::make_view(*(data_[_counts_])); + ASSERT( data_[_displs_] != 0 ); + ASSERT( data_[_counts_] != 0 ); + data_[_displs_]->resize( new_rows + 1 ); + data_[_counts_]->resize( new_rows + 1 ); + displs_view_ = array::make_view( *( data_[_displs_] ) ); + counts_view_ = array::make_view( *( data_[_counts_] ) ); + for ( size_t j = 0; rows_ < new_rows; ++rows_, ++j ) { + displs_view_( rows_ + 1 ) = displs_view_( rows_ ) + cols; + counts_view_( rows_ ) = cols; + } - for(size_t j=0; rows_insert( position, rows); - data_[_counts_]->insert( position, rows); - displs_view_ = array::make_view(*(data_[_displs_])); - counts_view_ = array::make_view(*(data_[_counts_])); - - displs_view_(position) = position_displs; - for( size_t jrow=position; jrowinsert(position_displs,rows*cols); - values_view_ = array::make_view(*(data_[_values_])); - - if(values == NULL) { - for(size_t c=position_displs; cinsert( position, rows ); + data_[_counts_]->insert( position, rows ); + displs_view_ = array::make_view( *( data_[_displs_] ) ); + counts_view_ = array::make_view( *( data_[_counts_] ) ); + + displs_view_( position ) = position_displs; + for ( size_t jrow = position; jrow < position + rows; ++jrow ) { + counts_view_( jrow ) = cols; + } + for ( size_t jrow = position; jrow < displs_view_.size() - 1; ++jrow ) { + displs_view_( jrow + 1 ) = displs_view_( jrow ) + counts_view_( jrow ); } - } - rows_ += rows; + maxcols_ = std::max( maxcols_, cols ); + mincols_ = std::min( mincols_, cols ); - on_update(); + data_[_values_]->insert( position_displs, rows * cols ); + values_view_ = array::make_view( *( data_[_values_] ) ); + + if ( values == NULL ) { + for ( size_t c = position_displs; c < position_displs + rows * cols; ++c ) { + values_view_( c ) = missing_value() TO_FORTRAN; + } + } + else { + idx_t add_base = fortran_array ? 0 : FORTRAN_BASE; + for ( size_t c = position_displs; c < position_displs + rows * cols; ++c ) { + values_view_( c ) = values[c - position_displs] + add_base; + } + } + rows_ += rows; + + on_update(); } //------------------------------------------------------------------------------------------------------ -void IrregularConnectivityImpl::insert( size_t position, size_t rows, size_t cols ) -{ - IrregularConnectivityImpl::insert(position, rows, cols, NULL, false); +void IrregularConnectivityImpl::insert( size_t position, size_t rows, size_t cols ) { + IrregularConnectivityImpl::insert( position, rows, cols, NULL, false ); } //------------------------------------------------------------------------------------------------------ -void IrregularConnectivityImpl::insert( size_t position, size_t rows, const size_t cols[] ) -{ - if( !owns_ ) throw eckit::AssertionFailed("HybridConnectivity must be owned to be resized directly"); - size_t position_displs = displs_view_(position); +void IrregularConnectivityImpl::insert( size_t position, size_t rows, const size_t cols[] ) { + if ( !owns_ ) throw eckit::AssertionFailed( "HybridConnectivity must be owned to be resized directly" ); + size_t position_displs = displs_view_( position ); - if(rows_==0) { - if(position>1) { - data_[_displs_]->insert( position-1, rows); - data_[_counts_]->insert( position-1, rows); + if ( rows_ == 0 ) { + if ( position > 1 ) { + data_[_displs_]->insert( position - 1, rows ); + data_[_counts_]->insert( position - 1, rows ); } - } else { - data_[_displs_]->insert( position, rows); - data_[_counts_]->insert( position, rows); } - displs_view_ = array::make_view(*(data_[_displs_])); - counts_view_ = array::make_view(*(data_[_counts_])); - - displs_view_(position) = position_displs; - for( size_t jrow=position; jrowinsert( position, rows ); + data_[_counts_]->insert( position, rows ); + } + displs_view_ = array::make_view( *( data_[_displs_] ) ); + counts_view_ = array::make_view( *( data_[_counts_] ) ); + + displs_view_( position ) = position_displs; + for ( size_t jrow = position; jrow < position + rows; ++jrow ) { + counts_view_( jrow ) = cols[jrow - position]; + maxcols_ = std::max( maxcols_, counts_view_( jrow ) ); + mincols_ = std::min( mincols_, counts_view_( jrow ) ); } - for( size_t jrow=position; jrowinsert(position_displs,insert_size); - values_view_ = array::make_view(*(data_[_values_])); + data_[_values_]->insert( position_displs, insert_size ); + values_view_ = array::make_view( *( data_[_values_] ) ); - for(size_t c=position_displs; ccloneToDevice();}); - values_view_ = array::make_device_view(*(data_[_values_])); - displs_view_ = array::make_device_view(*(data_[_displs_])); - counts_view_ = array::make_device_view(*(data_[_counts_])); + std::for_each( data_.begin(), data_.end(), []( array::Array* a ) { a->cloneToDevice(); } ); + values_view_ = array::make_device_view( *( data_[_values_] ) ); + displs_view_ = array::make_device_view( *( data_[_displs_] ) ); + counts_view_ = array::make_device_view( *( data_[_counts_] ) ); gpu_clone_.cloneToDevice(); } void IrregularConnectivityImpl::cloneFromDevice() { - std::for_each(data_.begin(), data_.end(), [](array::Array* a){ a->cloneFromDevice();}); - values_view_ = array::make_host_view(*(data_[_values_])); - displs_view_ = array::make_host_view(*(data_[_displs_])); - counts_view_ = array::make_host_view(*(data_[_counts_])); + std::for_each( data_.begin(), data_.end(), []( array::Array* a ) { a->cloneFromDevice(); } ); + values_view_ = array::make_host_view( *( data_[_values_] ) ); + displs_view_ = array::make_host_view( *( data_[_displs_] ) ); + counts_view_ = array::make_host_view( *( data_[_counts_] ) ); } void IrregularConnectivityImpl::syncHostDevice() const { - std::for_each(data_.begin(), data_.end(), [](array::Array* a){ a->syncHostDevice();}); + std::for_each( data_.begin(), data_.end(), []( array::Array* a ) { a->syncHostDevice(); } ); } bool IrregularConnectivityImpl::valid() const { bool res = true; - std::for_each(data_.begin(), data_.end(), [&](array::Array* a){ res &= a->valid();}); + std::for_each( data_.begin(), data_.end(), [&]( array::Array* a ) { res &= a->valid(); } ); return res; } bool IrregularConnectivityImpl::hostNeedsUpdate() const { - bool res=true; - std::for_each(data_.begin(), data_.end(), [&](array::Array* a){ res &= a->hostNeedsUpdate();}); + bool res = true; + std::for_each( data_.begin(), data_.end(), [&]( array::Array* a ) { res &= a->hostNeedsUpdate(); } ); return res; } bool IrregularConnectivityImpl::deviceNeedsUpdate() const { - bool res=true; - std::for_each(data_.begin(), data_.end(), [&](array::Array* a){ res &= a->deviceNeedsUpdate();}); + bool res = true; + std::for_each( data_.begin(), data_.end(), [&]( array::Array* a ) { res &= a->deviceNeedsUpdate(); } ); return res; } -size_t IrregularConnectivityImpl::footprint() const -{ - size_t size = sizeof(*this); - std::for_each(data_.begin(), data_.end(), [&](array::Array* a){ size += a->footprint();}); - return size; +size_t IrregularConnectivityImpl::footprint() const { + size_t size = sizeof( *this ); + std::for_each( data_.begin(), data_.end(), [&]( array::Array* a ) { size += a->footprint(); } ); + return size; } -void IrregularConnectivityImpl::dump(std::ostream& os) const { - array::make_host_view(*(data_[_values_])).dump(os); +void IrregularConnectivityImpl::dump( std::ostream& os ) const { + array::make_host_view( *( data_[_values_] ) ).dump( os ); } - //------------------------------------------------------------------------------------------------------ /* } //------------------------------------------------------------------------------------------------------ -MultiBlockConnectivity::MultiBlockConnectivity( idx_t values[], size_t rows, size_t displs[], size_t counts[], size_t blocks, size_t block_displs[], size_t block_cols[] ) +MultiBlockConnectivity::MultiBlockConnectivity( idx_t values[], size_t rows, +size_t displs[], size_t counts[], size_t blocks, size_t block_displs[], size_t +block_cols[] ) : IrregularConnectivity(values,rows,displs,counts), blocks_(blocks), - block_displs_(array::Array::wrap(block_displs, array::ArrayShape{blocks})), - block_cols_(array::Array::wrap(block_cols, array::ArrayShape{blocks})), + block_displs_(array::Array::wrap(block_displs, +array::ArrayShape{blocks})), + block_cols_(array::Array::wrap(block_cols, +array::ArrayShape{blocks})), block_(blocks), block_displs_view_(array::make_view(*block_displs_)), block_cols_view_(array::make_view(*block_cols_)) @@ -454,409 +434,373 @@ MultiBlockConnectivity::MultiBlockConnectivity( idx_t values[], size_t rows, siz */ //------------------------------------------------------------------------------------------------------ -MultiBlockConnectivityImpl::MultiBlockConnectivityImpl(const std::string& name) : - IrregularConnectivityImpl(name), - blocks_(0), - block_displs_(array::Array::create(1)), - block_cols_(array::Array::create(1)), - block_displs_view_(array::make_view(*block_displs_)), - block_cols_view_(array::make_view(*block_cols_)), - block_(0), - block_view_(make_host_vector_view(block_)), - gpu_clone_(this) -{ - block_displs_view_(0) = 0; +MultiBlockConnectivityImpl::MultiBlockConnectivityImpl( const std::string& name ) : + IrregularConnectivityImpl( name ), + blocks_( 0 ), + block_displs_( array::Array::create( 1 ) ), + block_cols_( array::Array::create( 1 ) ), + block_displs_view_( array::make_view( *block_displs_ ) ), + block_cols_view_( array::make_view( *block_cols_ ) ), + block_( 0 ), + block_view_( make_host_vector_view( block_ ) ), + gpu_clone_( this ) { + block_displs_view_( 0 ) = 0; } //------------------------------------------------------------------------------------------------------ MultiBlockConnectivityImpl::~MultiBlockConnectivityImpl() { - if (block_displs_) delete block_displs_; - if (block_cols_) delete block_cols_; + if ( block_displs_ ) delete block_displs_; + if ( block_cols_ ) delete block_cols_; } //------------------------------------------------------------------------------------------------------ -void MultiBlockConnectivityImpl::clear() -{ - //TODO -// IrregularConnectivity::clear(); -// if( owns() ) -// { -// block_displs_.resize(1); -// block_displs_[0]=0ul; -// block_cols_.clear(); -// } -// blocks_ = 0; -// block_displs_ = 0; -// block_cols_ = 0; -// block_.clear(); -} - -void MultiBlockConnectivityImpl::cloneToDevice() -{ - IrregularConnectivityImpl::cloneToDevice(); - block_displs_->cloneToDevice(); - block_cols_ ->cloneToDevice(); - block_displs_view_ = array::make_device_view(*(block_displs_)); - block_cols_view_ = array::make_device_view(*(block_cols_)); +void MultiBlockConnectivityImpl::clear() { + // TODO + // IrregularConnectivity::clear(); + // if( owns() ) + // { + // block_displs_.resize(1); + // block_displs_[0]=0ul; + // block_cols_.clear(); + // } + // blocks_ = 0; + // block_displs_ = 0; + // block_cols_ = 0; + // block_.clear(); +} + +void MultiBlockConnectivityImpl::cloneToDevice() { + IrregularConnectivityImpl::cloneToDevice(); + block_displs_->cloneToDevice(); + block_cols_->cloneToDevice(); + block_displs_view_ = array::make_device_view( *( block_displs_ ) ); + block_cols_view_ = array::make_device_view( *( block_cols_ ) ); - block_.cloneToDevice(); - block_view_ = make_device_vector_view(block_); + block_.cloneToDevice(); + block_view_ = make_device_vector_view( block_ ); - gpu_clone_.cloneToDevice(); + gpu_clone_.cloneToDevice(); } -void MultiBlockConnectivityImpl::cloneFromDevice() -{ - IrregularConnectivityImpl::cloneFromDevice(); - block_displs_->cloneFromDevice(); - block_cols_ ->cloneFromDevice(); - block_displs_view_ = array::make_host_view(*(block_displs_)); - block_cols_view_ = array::make_host_view(*(block_cols_)); +void MultiBlockConnectivityImpl::cloneFromDevice() { + IrregularConnectivityImpl::cloneFromDevice(); + block_displs_->cloneFromDevice(); + block_cols_->cloneFromDevice(); + block_displs_view_ = array::make_host_view( *( block_displs_ ) ); + block_cols_view_ = array::make_host_view( *( block_cols_ ) ); - block_.cloneFromDevice(); - block_view_ = make_host_vector_view(block_); + block_.cloneFromDevice(); + block_view_ = make_host_vector_view( block_ ); } -void MultiBlockConnectivityImpl::syncHostDevice() const -{ - IrregularConnectivityImpl::syncHostDevice(); - block_displs_->syncHostDevice(); - block_cols_ ->syncHostDevice(); +void MultiBlockConnectivityImpl::syncHostDevice() const { + IrregularConnectivityImpl::syncHostDevice(); + block_displs_->syncHostDevice(); + block_cols_->syncHostDevice(); } bool MultiBlockConnectivityImpl::valid() const { - return - IrregularConnectivityImpl::valid() && - block_displs_->valid() && - block_cols_->valid(); + return IrregularConnectivityImpl::valid() && block_displs_->valid() && block_cols_->valid(); } bool MultiBlockConnectivityImpl::hostNeedsUpdate() const { - return - IrregularConnectivityImpl::hostNeedsUpdate() && - block_displs_->hostNeedsUpdate() && - block_cols_->hostNeedsUpdate(); + return IrregularConnectivityImpl::hostNeedsUpdate() && block_displs_->hostNeedsUpdate() && + block_cols_->hostNeedsUpdate(); } bool MultiBlockConnectivityImpl::deviceNeedsUpdate() const { - return - IrregularConnectivityImpl::deviceNeedsUpdate() && - block_displs_->deviceNeedsUpdate() && - block_cols_->deviceNeedsUpdate(); + return IrregularConnectivityImpl::deviceNeedsUpdate() && block_displs_->deviceNeedsUpdate() && + block_cols_->deviceNeedsUpdate(); } //------------------------------------------------------------------------------------------------------ -void MultiBlockConnectivityImpl::add(size_t rows, size_t cols, const idx_t values[], bool fortran_array ) -{ - if( !owns() ) throw eckit::AssertionFailed("MultiBlockConnectivity must be owned to be resized directly"); - size_t old_rows = this->rows(); - IrregularConnectivityImpl::add(rows,cols,values,fortran_array); - - block_displs_->insert( block_displs_->size(), 1); - block_cols_ ->insert( block_cols_ ->size(), 1); - block_displs_view_ = array::make_view(*block_displs_); - block_cols_view_ = array::make_view(*block_cols_); - blocks_++; - block_displs_view_(block_displs_view_.size()-1) = old_rows+rows; - block_cols_view_ (block_cols_view_ .size()-2) = cols; +void MultiBlockConnectivityImpl::add( size_t rows, size_t cols, const idx_t values[], bool fortran_array ) { + if ( !owns() ) throw eckit::AssertionFailed( "MultiBlockConnectivity must be owned to be resized directly" ); + size_t old_rows = this->rows(); + IrregularConnectivityImpl::add( rows, cols, values, fortran_array ); - rebuild_block_connectivity(); + block_displs_->insert( block_displs_->size(), 1 ); + block_cols_->insert( block_cols_->size(), 1 ); + block_displs_view_ = array::make_view( *block_displs_ ); + block_cols_view_ = array::make_view( *block_cols_ ); + blocks_++; + block_displs_view_( block_displs_view_.size() - 1 ) = old_rows + rows; + block_cols_view_( block_cols_view_.size() - 2 ) = cols; + + rebuild_block_connectivity(); } //------------------------------------------------------------------------------------------------------ -void MultiBlockConnectivityImpl::add( const BlockConnectivityImpl& block ) -{ - if( !owns() ) throw eckit::AssertionFailed("MultiBlockConnectivity must be owned to be resized directly"); - IrregularConnectivityImpl::add(block); - - block_view_ = make_host_vector_view(block_); +void MultiBlockConnectivityImpl::add( const BlockConnectivityImpl& block ) { + if ( !owns() ) throw eckit::AssertionFailed( "MultiBlockConnectivity must be owned to be resized directly" ); + IrregularConnectivityImpl::add( block ); + block_view_ = make_host_vector_view( block_ ); } //------------------------------------------------------------------------------------------------------ -void MultiBlockConnectivityImpl::add( size_t rows, size_t cols ) -{ - if( !owns() ) throw eckit::AssertionFailed("MultiBlockConnectivity must be owned to be resized directly"); - size_t old_rows = this->rows(); - IrregularConnectivityImpl::add(rows,cols); - - block_displs_->insert( block_displs_->size(), 1); - block_cols_ ->insert( block_cols_ ->size(), 1); - block_displs_view_ = array::make_view(*block_displs_); - block_cols_view_ = array::make_view(*block_cols_); - blocks_++; - block_displs_view_(block_displs_view_.size()-1) = old_rows+rows; - block_cols_view_ (block_cols_view_ .size()-2) = cols; +void MultiBlockConnectivityImpl::add( size_t rows, size_t cols ) { + if ( !owns() ) throw eckit::AssertionFailed( "MultiBlockConnectivity must be owned to be resized directly" ); + size_t old_rows = this->rows(); + IrregularConnectivityImpl::add( rows, cols ); - rebuild_block_connectivity(); + block_displs_->insert( block_displs_->size(), 1 ); + block_cols_->insert( block_cols_->size(), 1 ); + block_displs_view_ = array::make_view( *block_displs_ ); + block_cols_view_ = array::make_view( *block_cols_ ); + blocks_++; + block_displs_view_( block_displs_view_.size() - 1 ) = old_rows + rows; + block_cols_view_( block_cols_view_.size() - 2 ) = cols; + + rebuild_block_connectivity(); } //------------------------------------------------------------------------------------------------------ -void MultiBlockConnectivityImpl::add( size_t rows, const size_t cols[] ) -{ - if( !owns() ) throw eckit::AssertionFailed("MultiBlockConnectivity must be owned to be resized directly"); - size_t min=std::numeric_limits::max(); - size_t max=0; - size_t old_rows = this->rows(); - - for( size_t j=0; jinsert( block_displs_->size(), 1); - block_cols_->insert( block_cols_->size(), 1); - block_displs_view_ = array::make_view(*block_displs_); - block_cols_view_ = array::make_view(*block_cols_); - blocks_++; - block_displs_view_(block_displs_view_.size()-1) = old_rows; - block_cols_view_(block_cols_view_.size()-2) = max; +void MultiBlockConnectivityImpl::add( size_t rows, const size_t cols[] ) { + if ( !owns() ) throw eckit::AssertionFailed( "MultiBlockConnectivity must be owned to be resized directly" ); + size_t min = std::numeric_limits::max(); + size_t max = 0; + size_t old_rows = this->rows(); - rebuild_block_connectivity(); + for ( size_t j = 0; j < rows; ++j ) { + min = std::min( min, cols[j] ); + max = std::min( max, cols[j] ); + } + if ( min != max ) + throw eckit::AssertionFailed( + "MultiBlockConnectivity::add(rows,cols[]): " + "all elements of cols[] must be identical" ); + IrregularConnectivityImpl::add( rows, cols ); + + block_displs_->insert( block_displs_->size(), 1 ); + block_cols_->insert( block_cols_->size(), 1 ); + block_displs_view_ = array::make_view( *block_displs_ ); + block_cols_view_ = array::make_view( *block_cols_ ); + blocks_++; + block_displs_view_( block_displs_view_.size() - 1 ) = old_rows; + block_cols_view_( block_cols_view_.size() - 2 ) = max; + + rebuild_block_connectivity(); } //------------------------------------------------------------------------------------------------------ -void MultiBlockConnectivityImpl::insert( size_t position, size_t rows, size_t cols, const idx_t values[], bool fortran_array ) -{ - if( !owns() ) throw eckit::AssertionFailed("MultiBlockConnectivity must be owned to be resized directly"); +void MultiBlockConnectivityImpl::insert( size_t position, size_t rows, size_t cols, const idx_t values[], + bool fortran_array ) { + if ( !owns() ) throw eckit::AssertionFailed( "MultiBlockConnectivity must be owned to be resized directly" ); - ASSERT(blocks_); + ASSERT( blocks_ ); - long blk_idx = blocks_; - do{ blk_idx--; } while( - blk_idx >= 0l && - block_displs_view_(blk_idx) >= position && - cols != block_cols_view_(blk_idx) - ); - ASSERT( blk_idx >= 0l ); - ASSERT( cols == block(blk_idx).cols() ); + long blk_idx = blocks_; + do { + blk_idx--; + } while ( blk_idx >= 0l && block_displs_view_( blk_idx ) >= position && cols != block_cols_view_( blk_idx ) ); + ASSERT( blk_idx >= 0l ); + ASSERT( cols == block( blk_idx ).cols() ); - for( size_t jblk=blk_idx; jblk= 0l && - block_displs_view_(blk_idx) >= position && - cols != block_cols_view_(blk_idx) - ); + long blk_idx = blocks_; + do { + blk_idx--; + } while ( blk_idx >= 0l && block_displs_view_( blk_idx ) >= position && cols != block_cols_view_( blk_idx ) ); - ASSERT( blk_idx >= 0l ); + ASSERT( blk_idx >= 0l ); - IrregularConnectivityImpl::insert(position,rows,cols); + IrregularConnectivityImpl::insert( position, rows, cols ); - for( size_t jblk=blk_idx; jblk::max(); - size_t max=0; - for( size_t j=0; j= 0l && - block_displs_view_(blk_idx) >= position && - max != block_cols_view_(blk_idx) - ); - - ASSERT( blk_idx >= 0l ); - - IrregularConnectivityImpl::insert(position,rows,cols); - - for( size_t jblk=blk_idx; jblk::max(); + size_t max = 0; + for ( size_t j = 0; j < rows; ++j ) { + min = std::min( min, cols[j] ); + max = std::min( max, cols[j] ); + } + if ( min != max ) + throw eckit::AssertionFailed( + "MultiBlockConnectivity::add(rows,cols[]): " + "all elements of cls[] must be identical" ); + + long blk_idx = blocks_; + do { + blk_idx--; + } while ( blk_idx >= 0l && block_displs_view_( blk_idx ) >= position && max != block_cols_view_( blk_idx ) ); + + ASSERT( blk_idx >= 0l ); + + IrregularConnectivityImpl::insert( position, rows, cols ); + + for ( size_t jblk = blk_idx; jblk < blocks_; ++jblk ) + block_displs_view_( jblk + 1 ) += rows; + rebuild_block_connectivity(); } //------------------------------------------------------------------------------------------------------ -void MultiBlockConnectivityImpl::rebuild_block_connectivity() -{ - block_.resize(blocks_,0); - block_view_ = make_host_vector_view(block_); - - for( size_t b=0; brebuild( - block_displs_view_(b+1)-block_displs_view_(b), // rows - block_cols_view_(b), // cols - data()+ displs(block_displs_view_(b))); - } - else { - block_view_[b] = - new BlockConnectivityImpl( - block_displs_view_(b+1)-block_displs_view_(b), // rows - block_cols_view_(b), // cols - data()+displs(block_displs_view_(b)), - /*own = */ false); +void MultiBlockConnectivityImpl::rebuild_block_connectivity() { + block_.resize( blocks_, 0 ); + block_view_ = make_host_vector_view( block_ ); + + for ( size_t b = 0; b < blocks_; ++b ) { + if ( block_view_[b] ) { + block_view_[b]->rebuild( block_displs_view_( b + 1 ) - block_displs_view_( b ), // rows + block_cols_view_( b ), // cols + data() + displs( block_displs_view_( b ) ) ); + } + else { + block_view_[b] = new BlockConnectivityImpl( block_displs_view_( b + 1 ) - block_displs_view_( b ), // rows + block_cols_view_( b ), // cols + data() + displs( block_displs_view_( b ) ), + /*own = */ false ); + } } - } } //------------------------------------------------------------------------------------------------------ -size_t MultiBlockConnectivityImpl::footprint() const -{ - size_t size = IrregularConnectivityImpl::footprint(); - size += block_displs_->footprint(); - size += block_cols_->footprint(); +size_t MultiBlockConnectivityImpl::footprint() const { + size_t size = IrregularConnectivityImpl::footprint(); + size += block_displs_->footprint(); + size += block_cols_->footprint(); - for( size_t j=0; jfootprint(); - } - return size; + for ( size_t j = 0; j < block_.size(); ++j ) { + size += block_view_[j]->footprint(); + } + return size; } //------------------------------------------------------------------------------------------------------ BlockConnectivityImpl::BlockConnectivityImpl() : - owns_(true), - values_(array::Array::create(1,1) ), - values_view_(array::make_view(*values_)), - rows_(0), - cols_(0), - missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), - gpu_clone_(this) -{ -} + owns_( true ), + values_( array::Array::create( 1, 1 ) ), + values_view_( array::make_view( *values_ ) ), + rows_( 0 ), + cols_( 0 ), + missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), + gpu_clone_( this ) {} //------------------------------------------------------------------------------------------------------ BlockConnectivityImpl::BlockConnectivityImpl( size_t rows, size_t cols, const std::initializer_list& values ) : - owns_(true), - values_(array::Array::create(1,1) ), - values_view_(array::make_view(*values_)), - rows_(rows), - cols_(cols), - missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), - gpu_clone_(this) -{ - delete values_; - values_ = array::Array::create(rows_,cols_); - values_view_ = array::make_view(*values_); - idx_t add_base = FORTRAN_BASE; - auto v = values.begin(); - for (size_t i=0; i( 1, 1 ) ), + values_view_( array::make_view( *values_ ) ), + rows_( rows ), + cols_( cols ), + missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), + gpu_clone_( this ) { + delete values_; + values_ = array::Array::create( rows_, cols_ ); + values_view_ = array::make_view( *values_ ); + idx_t add_base = FORTRAN_BASE; + auto v = values.begin(); + for ( size_t i = 0; i < rows_; ++i ) { + for ( size_t j = 0; j < cols_; ++j ) { + values_view_( i, j ) = *( v++ ) + add_base; + } + } + ASSERT( v == values.end() ); } //------------------------------------------------------------------------------------------------------ BlockConnectivityImpl::BlockConnectivityImpl( size_t rows, size_t cols, idx_t values[] ) : - owns_(true), - values_(array::Array::create(1,1) ), - values_view_(array::make_view(*values_)), - rows_(rows), - cols_(cols), - missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), - gpu_clone_(this) -{ - - delete values_; - values_ = array::Array::create(rows_,cols_); - values_view_ = array::make_view(*values_); - if( values_->size() ) { - idx_t add_base = FORTRAN_BASE; - idx_t *v = &values[0]; - for (size_t i=0; i( 1, 1 ) ), + values_view_( array::make_view( *values_ ) ), + rows_( rows ), + cols_( cols ), + missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), + gpu_clone_( this ) { + delete values_; + values_ = array::Array::create( rows_, cols_ ); + values_view_ = array::make_view( *values_ ); + if ( values_->size() ) { + idx_t add_base = FORTRAN_BASE; + idx_t* v = &values[0]; + for ( size_t i = 0; i < rows_; ++i ) { + for ( size_t j = 0; j < cols_; ++j ) { + values_view_( i, j ) = *( v++ ) + add_base; + } + } + } } - //------------------------------------------------------------------------------------------------------ -BlockConnectivityImpl::BlockConnectivityImpl( size_t rows, size_t cols, idx_t values[], bool dummy ) - : owns_(false), - values_(array::Array::wrap(values, array::ArrayShape{rows, cols})), - values_view_(array::make_view(*values_)), - rows_(rows), - cols_(cols), +BlockConnectivityImpl::BlockConnectivityImpl( size_t rows, size_t cols, idx_t values[], bool dummy ) : + owns_( false ), + values_( array::Array::wrap( values, array::ArrayShape{rows, cols} ) ), + values_view_( array::make_view( *values_ ) ), + rows_( rows ), + cols_( cols ), missing_value_( std::numeric_limits::is_signed ? -1 : std::numeric_limits::max() ), - gpu_clone_(this) -{ -} + gpu_clone_( this ) {} //------------------------------------------------------------------------------------------------------ BlockConnectivityImpl::~BlockConnectivityImpl() { - if(owns_) { - assert(values_); + if ( owns_ ) { + assert( values_ ); delete values_; } } //------------------------------------------------------------------------------------------------------ -void BlockConnectivityImpl::rebuild( size_t rows, size_t cols, idx_t values[] ) -{ - ASSERT( not owns_ ); - rows_ = rows; - cols_ = cols; - assert(values_); - delete values_; - values_ = array::Array::wrap(values, array::ArrayShape{rows, cols}); - values_view_ = array::make_view(*values_); +void BlockConnectivityImpl::rebuild( size_t rows, size_t cols, idx_t values[] ) { + ASSERT( not owns_ ); + rows_ = rows; + cols_ = cols; + assert( values_ ); + delete values_; + values_ = array::Array::wrap( values, array::ArrayShape{rows, cols} ); + values_view_ = array::make_view( *values_ ); } //------------------------------------------------------------------------------------------------------ -void BlockConnectivityImpl::add(size_t rows, size_t cols, const idx_t values[], bool fortran_array) -{ - if (!owns_) throw eckit::AssertionFailed("BlockConnectivity must be owned to be resized directly"); - if (cols_ != 0 && cols_ != cols) - throw eckit::AssertionFailed("Cannot add values with different cols than already existing in BlockConnectivity"); +void BlockConnectivityImpl::add( size_t rows, size_t cols, const idx_t values[], bool fortran_array ) { + if ( !owns_ ) throw eckit::AssertionFailed( "BlockConnectivity must be owned to be resized directly" ); + if ( cols_ != 0 && cols_ != cols ) + throw eckit::AssertionFailed( + "Cannot add values with different cols than " + "already existing in BlockConnectivity" ); - values_->resize(rows_+rows, cols); - values_view_ = array::make_view(*values_); + values_->resize( rows_ + rows, cols ); + values_view_ = array::make_view( *values_ ); idx_t add_base = fortran_array ? 0 : FORTRAN_BASE; - for (size_t i = 0, i_old=rows_; i < rows; ++i, ++i_old) { - for (size_t j = 0; j < cols; ++j) { - values_view_(i_old, j) = values[i*cols + j] + add_base; - } + for ( size_t i = 0, i_old = rows_; i < rows; ++i, ++i_old ) { + for ( size_t j = 0; j < cols; ++j ) { + values_view_( i_old, j ) = values[i * cols + j] + add_base; + } } rows_ += rows; @@ -865,22 +809,21 @@ void BlockConnectivityImpl::add(size_t rows, size_t cols, const idx_t values[], //------------------------------------------------------------------------------------------------------ -size_t BlockConnectivityImpl::footprint() const -{ - size_t size = sizeof(*this); - if( owns() ) size += values_->footprint(); - return size; +size_t BlockConnectivityImpl::footprint() const { + size_t size = sizeof( *this ); + if ( owns() ) size += values_->footprint(); + return size; } void BlockConnectivityImpl::cloneToDevice() { values_->cloneToDevice(); - values_view_ = array::make_device_view(*values_); + values_view_ = array::make_device_view( *values_ ); gpu_clone_.cloneToDevice(); } void BlockConnectivityImpl::cloneFromDevice() { values_->cloneFromDevice(); - values_view_ = array::make_host_view(*values_); + values_view_ = array::make_host_view( *values_ ); } bool BlockConnectivityImpl::valid() const { @@ -897,186 +840,148 @@ bool BlockConnectivityImpl::deviceNeedsUpdate() const { //------------------------------------------------------------------------------------------------------ -class ConnectivityPrivateAccess -{ +class ConnectivityPrivateAccess { private: - typedef Connectivity::ctxt_t ctxt_t; - typedef Connectivity::callback_t callback_t; + typedef Connectivity::ctxt_t ctxt_t; + typedef Connectivity::callback_t callback_t; + public: - ConnectivityPrivateAccess(Connectivity& connectivity) : connectivity_(connectivity) - { - } - ctxt_t &ctxt() { return connectivity_.ctxt_; } - callback_t &callback_update() { return connectivity_.callback_update_; } - callback_t &callback_delete() { return connectivity_.callback_delete_; } - -// TODO : For now return host-view raw data to Fortran, but this should be -// reviewed to also possibly return device-view data - int *values() { return array::make_view( *connectivity_.data_[Connectivity::_values_] ).data(); } - size_t *displs() { return array::make_view( *connectivity_.data_[Connectivity::_displs_] ).data(); } - size_t *counts() { return array::make_view( *connectivity_.data_[Connectivity::_counts_] ).data(); } - - const char* name() { return connectivity_.name_; } + ConnectivityPrivateAccess( Connectivity& connectivity ) : connectivity_( connectivity ) {} + ctxt_t& ctxt() { return connectivity_.ctxt_; } + callback_t& callback_update() { return connectivity_.callback_update_; } + callback_t& callback_delete() { return connectivity_.callback_delete_; } + + // TODO : For now return host-view raw data to Fortran, but this should be + // reviewed to also possibly return device-view data + int* values() { return array::make_view( *connectivity_.data_[Connectivity::_values_] ).data(); } + size_t* displs() { return array::make_view( *connectivity_.data_[Connectivity::_displs_] ).data(); } + size_t* counts() { return array::make_view( *connectivity_.data_[Connectivity::_counts_] ).data(); } + + const char* name() { return connectivity_.name_; } private: - Connectivity& connectivity_; + Connectivity& connectivity_; }; //------------------------------------------------------------------------------------------------------ -extern "C" -{ -Connectivity* atlas__Connectivity__create() -{ - Connectivity* connectivity = 0; - ATLAS_ERROR_HANDLING( - connectivity = new Connectivity(); - ); - return connectivity; +extern "C" { +Connectivity* atlas__Connectivity__create() { + Connectivity* connectivity = 0; + ATLAS_ERROR_HANDLING( connectivity = new Connectivity(); ); + return connectivity; } -void atlas__Connectivity__delete(Connectivity* This) -{ - ATLAS_ERROR_HANDLING(delete This); +void atlas__Connectivity__delete( Connectivity* This ) { + ATLAS_ERROR_HANDLING( delete This ); } -void atlas__connectivity__register_ctxt(Connectivity* This, Connectivity::ctxt_t ctxt ) -{ - ConnectivityPrivateAccess access(*This); - access.ctxt() = ctxt; +void atlas__connectivity__register_ctxt( Connectivity* This, Connectivity::ctxt_t ctxt ) { + ConnectivityPrivateAccess access( *This ); + access.ctxt() = ctxt; } -int atlas__connectivity__ctxt(Connectivity* This, Connectivity::ctxt_t* ctxt) -{ - ConnectivityPrivateAccess access(*This); - *ctxt = access.ctxt(); - return bool( access.ctxt() ); +int atlas__connectivity__ctxt( Connectivity* This, Connectivity::ctxt_t* ctxt ) { + ConnectivityPrivateAccess access( *This ); + *ctxt = access.ctxt(); + return bool( access.ctxt() ); } -void atlas__connectivity__register_update(Connectivity* This, Connectivity::callback_t callback ) -{ - ConnectivityPrivateAccess access(*This); - access.callback_update() = callback; +void atlas__connectivity__register_update( Connectivity* This, Connectivity::callback_t callback ) { + ConnectivityPrivateAccess access( *This ); + access.callback_update() = callback; } -void atlas__connectivity__register_delete(Connectivity* This, Connectivity::callback_t callback ) -{ - ConnectivityPrivateAccess access(*This); - access.callback_delete() = callback; +void atlas__connectivity__register_delete( Connectivity* This, Connectivity::callback_t callback ) { + ConnectivityPrivateAccess access( *This ); + access.callback_delete() = callback; } -void atlas__Connectivity__displs(Connectivity* This, size_t* &displs, size_t &size) -{ - ConnectivityPrivateAccess access(*This); - displs = access.displs(); - size = This->rows()+1; +void atlas__Connectivity__displs( Connectivity* This, size_t*& displs, size_t& size ) { + ConnectivityPrivateAccess access( *This ); + displs = access.displs(); + size = This->rows() + 1; } -void atlas__Connectivity__counts(Connectivity* This, size_t* &counts, size_t &size) -{ - ConnectivityPrivateAccess access(*This); - counts = access.counts(); - size = This->rows(); +void atlas__Connectivity__counts( Connectivity* This, size_t*& counts, size_t& size ) { + ConnectivityPrivateAccess access( *This ); + counts = access.counts(); + size = This->rows(); } -void atlas__Connectivity__values(Connectivity* This, int* &values, size_t &size) -{ - ConnectivityPrivateAccess access(*This); - values = access.values(); - size = This->rows() ? access.displs()[This->rows()]+1 : 0 ; +void atlas__Connectivity__values( Connectivity* This, int*& values, size_t& size ) { + ConnectivityPrivateAccess access( *This ); + values = access.values(); + size = This->rows() ? access.displs()[This->rows()] + 1 : 0; } -void atlas__Connectivity__add_values(Connectivity* This, size_t rows, size_t cols, int values[]) -{ - This->add(rows,cols,values,true); +void atlas__Connectivity__add_values( Connectivity* This, size_t rows, size_t cols, int values[] ) { + This->add( rows, cols, values, true ); } -void atlas__Connectivity__add_missing(Connectivity* This, size_t rows, size_t cols) -{ - This->add(rows,cols); +void atlas__Connectivity__add_missing( Connectivity* This, size_t rows, size_t cols ) { + This->add( rows, cols ); } -size_t atlas__Connectivity__rows(const Connectivity* This) -{ - return This->rows(); +size_t atlas__Connectivity__rows( const Connectivity* This ) { + return This->rows(); } -int atlas__Connectivity__missing_value(const Connectivity* This) -{ - return This->missing_value() TO_FORTRAN; +int atlas__Connectivity__missing_value( const Connectivity* This ) { + return This->missing_value() TO_FORTRAN; } -MultiBlockConnectivity* atlas__MultiBlockConnectivity__create() -{ - MultiBlockConnectivity* connectivity = 0; - ATLAS_ERROR_HANDLING( - connectivity = new MultiBlockConnectivity(); - ); - return connectivity; +MultiBlockConnectivity* atlas__MultiBlockConnectivity__create() { + MultiBlockConnectivity* connectivity = 0; + ATLAS_ERROR_HANDLING( connectivity = new MultiBlockConnectivity(); ); + return connectivity; } -size_t atlas__MultiBlockConnectivity__blocks(const MultiBlockConnectivity* This) -{ - return This->blocks(); +size_t atlas__MultiBlockConnectivity__blocks( const MultiBlockConnectivity* This ) { + return This->blocks(); } -BlockConnectivityImpl* atlas__MultiBlockConnectivity__block(MultiBlockConnectivity* This, size_t block_idx) -{ - ATLAS_ERROR_HANDLING( ASSERT(This != 0 ) ); - BlockConnectivityImpl* block = &This->block(block_idx); - ASSERT( block != 0 ); - return block; +BlockConnectivityImpl* atlas__MultiBlockConnectivity__block( MultiBlockConnectivity* This, size_t block_idx ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + BlockConnectivityImpl* block = &This->block( block_idx ); + ASSERT( block != 0 ); + return block; } -void atlas__BlockConnectivity__delete(BlockConnectivityImpl* This) -{ - ATLAS_ERROR_HANDLING( delete This ); +void atlas__BlockConnectivity__delete( BlockConnectivityImpl* This ) { + ATLAS_ERROR_HANDLING( delete This ); } -size_t atlas__BlockConnectivity__rows(const BlockConnectivityImpl* This) -{ - ATLAS_ERROR_HANDLING( ASSERT(This != 0 ) ); - return This->rows(); +size_t atlas__BlockConnectivity__rows( const BlockConnectivityImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->rows(); } -size_t atlas__BlockConnectivity__cols(const BlockConnectivityImpl* This) -{ - ATLAS_ERROR_HANDLING( ASSERT(This != 0 ) ); - return This->cols(); +size_t atlas__BlockConnectivity__cols( const BlockConnectivityImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->cols(); } -int atlas__BlockConnectivity__missing_value(const BlockConnectivityImpl* This) -{ - ATLAS_ERROR_HANDLING( ASSERT(This != 0 ) ); - return This->missing_value(); +int atlas__BlockConnectivity__missing_value( const BlockConnectivityImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->missing_value(); } -void atlas__BlockConnectivity__data(BlockConnectivityImpl* This, int* &data, size_t &rows, size_t &cols) -{ - ATLAS_ERROR_HANDLING( ASSERT(This != 0 ) ); - data = This->data(); - rows = This->rows(); - cols = This->cols(); +void atlas__BlockConnectivity__data( BlockConnectivityImpl* This, int*& data, size_t& rows, size_t& cols ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + data = This->data(); + rows = This->rows(); + cols = This->cols(); } -const char* atlas__Connectivity__name (Connectivity* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return ConnectivityPrivateAccess(*This).name(); - ); - return 0; +const char* atlas__Connectivity__name( Connectivity* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return ConnectivityPrivateAccess( *This ).name(); ); + return 0; } -void atlas__Connectivity__rename(Connectivity* This, const char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - This->rename( std::string(name) ); - ); +void atlas__Connectivity__rename( Connectivity* This, const char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); This->rename( std::string( name ) ); ); } - } -} // namespace mesh -} // namespace atlas - +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index dc5ff8eaa..736a33e6c 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -25,14 +26,14 @@ #include -#include "atlas/library/config.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" -#include "atlas/array/IndexView.h" #include "atlas/array/DataType.h" +#include "atlas/array/IndexView.h" #include "atlas/array/Vector.h" -#include "atlas/array_fwd.h" #include "atlas/array/gridtools/GPUClonable.h" +#include "atlas/array_fwd.h" +#include "atlas/library/config.h" #include "eckit/memory/Owned.h" @@ -42,13 +43,11 @@ namespace mesh { #define MAX_STRING_SIZE 60 template -class ConnectivityInterface : public eckit::Owned, public ConnectivityImpl -{ +class ConnectivityInterface : public eckit::Owned, public ConnectivityImpl { using ConnectivityImpl::ConnectivityImpl; using eckit::Owned::Owned; }; - // Classes defined in this file: class IrregularConnectivityImpl; class BlockConnectivityImpl; @@ -59,7 +58,7 @@ class MultiBlockConnectivityImpl; #ifdef ATLAS_HAVE_FORTRAN #define INDEX_REF Index #define FROM_FORTRAN -1 -#define TO_FORTRAN +1 +#define TO_FORTRAN +1 #else #define INDEX_REF * #define FROM_FORTRAN @@ -93,219 +92,238 @@ namespace detail { // FortranIndex: // Helper class that does +1 and -1 operations on stored values -class ConnectivityIndex -{ +class ConnectivityIndex { public: - enum { BASE = 1 }; + enum + { + BASE = 1 + }; + public: - ATLAS_HOST_DEVICE ConnectivityIndex(idx_t* idx): idx_(idx) {} - ATLAS_HOST_DEVICE void set(const idx_t& value) { *(idx_) = value+BASE; } - ATLAS_HOST_DEVICE idx_t get() const { return *(idx_)-BASE; } - ATLAS_HOST_DEVICE void operator=(const idx_t& value) { set(value); } - ATLAS_HOST_DEVICE ConnectivityIndex& operator=(const ConnectivityIndex& other) { set(other.get()); return *this; } - ATLAS_HOST_DEVICE ConnectivityIndex& operator+(const idx_t& value) { *(idx_)+=value; return *this; } - ATLAS_HOST_DEVICE ConnectivityIndex& operator-(const idx_t& value) { *(idx_)-=value; return *this; } - ATLAS_HOST_DEVICE ConnectivityIndex& operator--() { --(*(idx_)); return *this; } - ATLAS_HOST_DEVICE ConnectivityIndex& operator++() { ++(*(idx_)); return *this; } - - //implicit conversion - ATLAS_HOST_DEVICE operator idx_t() const { return get(); } + ATLAS_HOST_DEVICE ConnectivityIndex( idx_t* idx ) : idx_( idx ) {} + ATLAS_HOST_DEVICE void set( const idx_t& value ) { *( idx_ ) = value + BASE; } + ATLAS_HOST_DEVICE idx_t get() const { return *(idx_)-BASE; } + ATLAS_HOST_DEVICE void operator =( const idx_t& value ) { set( value ); } + ATLAS_HOST_DEVICE ConnectivityIndex& operator=( const ConnectivityIndex& other ) { + set( other.get() ); + return *this; + } + ATLAS_HOST_DEVICE ConnectivityIndex& operator+( const idx_t& value ) { + *( idx_ ) += value; + return *this; + } + ATLAS_HOST_DEVICE ConnectivityIndex& operator-( const idx_t& value ) { + *( idx_ ) -= value; + return *this; + } + ATLAS_HOST_DEVICE ConnectivityIndex& operator--() { + --( *( idx_ ) ); + return *this; + } + ATLAS_HOST_DEVICE ConnectivityIndex& operator++() { + ++( *( idx_ ) ); + return *this; + } + + // implicit conversion + ATLAS_HOST_DEVICE operator idx_t() const { return get(); } private: - idx_t* idx_; + idx_t* idx_; }; -} +} // namespace detail -class ConnectivityRow -{ - #ifdef ATLAS_HAVE_FORTRAN +class ConnectivityRow { +#ifdef ATLAS_HAVE_FORTRAN typedef detail::ConnectivityIndex Index; - #else +#else typedef idx_t Index; - #endif +#endif public: - ATLAS_HOST_DEVICE - ConnectivityRow(idx_t *data, size_t size) : data_(data), size_(size) {} + ConnectivityRow( idx_t* data, size_t size ) : data_( data ), size_( size ) {} ATLAS_HOST_DEVICE - idx_t operator()(size_t i) const { return data_[i] FROM_FORTRAN; } + idx_t operator()( size_t i ) const { return data_[i] FROM_FORTRAN; } ATLAS_HOST_DEVICE - Index operator()(size_t i) { return INDEX_REF(data_+i); } + Index operator()( size_t i ) { return INDEX_REF( data_ + i ); } ATLAS_HOST_DEVICE size_t size() const { return size_; } - private: - idx_t *data_; +private: + idx_t* data_; size_t size_; }; -class IrregularConnectivityImpl -{ +class IrregularConnectivityImpl { public: - typedef ConnectivityRow Row; + typedef ConnectivityRow Row; + + static constexpr unsigned short _values_ = 0; + static constexpr unsigned short _displs_ = 1; + static constexpr unsigned short _counts_ = 2; - static constexpr unsigned short _values_=0; - static constexpr unsigned short _displs_=1; - static constexpr unsigned short _counts_=2; public: -//-- Constructors + //-- Constructors - /// @brief Construct connectivity table that needs resizing a-posteriori - /// Data is owned - IrregularConnectivityImpl( const std::string& name = "" ); + /// @brief Construct connectivity table that needs resizing a-posteriori + /// Data is owned + IrregularConnectivityImpl( const std::string& name = "" ); - /// @brief Construct connectivity table wrapping existing raw data. - /// No resizing can be performed as data is not owned. - IrregularConnectivityImpl( idx_t values[], size_t rows, size_t displs[], size_t counts[] ); + /// @brief Construct connectivity table wrapping existing raw data. + /// No resizing can be performed as data is not owned. + IrregularConnectivityImpl( idx_t values[], size_t rows, size_t displs[], size_t counts[] ); - /// @brief Copy ctr (only to be used when calling a cuda kernel) - // This ctr has to be defined in the header, since __CUDACC__ will identify whether - // it is compiled it for a GPU kernel + /// @brief Copy ctr (only to be used when calling a cuda kernel) + // This ctr has to be defined in the header, since __CUDACC__ will identify + // whether + // it is compiled it for a GPU kernel - /// @brief Copy ctr (only to be used when calling a cuda kernel) - // This ctr has to be defined in the header, since __CUDACC__ will identify whether - // it is compiled it for a GPU kernel - IrregularConnectivityImpl(const IrregularConnectivityImpl &other); + /// @brief Copy ctr (only to be used when calling a cuda kernel) + // This ctr has to be defined in the header, since __CUDACC__ will identify + // whether + // it is compiled it for a GPU kernel + IrregularConnectivityImpl( const IrregularConnectivityImpl& other ); - virtual ~IrregularConnectivityImpl(); + virtual ~IrregularConnectivityImpl(); -//-- Accessors + //-- Accessors - /// @brief Name associated to this Connetivity - const std::string name() const { return std::string(name_); } + /// @brief Name associated to this Connetivity + const std::string name() const { return std::string( name_ ); } - /// @brief Rename this Connectivity - void rename(const std::string& name) { strncpy(name_, name.c_str(), std::max(name.size(), size_t(MAX_STRING_SIZE))); } + /// @brief Rename this Connectivity + void rename( const std::string& name ) { + strncpy( name_, name.c_str(), std::max( name.size(), size_t( MAX_STRING_SIZE ) ) ); + } - /// @brief Number of rows in the connectivity table - ATLAS_HOST_DEVICE - size_t rows() const { return rows_; } + /// @brief Number of rows in the connectivity table + ATLAS_HOST_DEVICE + size_t rows() const { return rows_; } - /// @brief Number of columns for specified row in the connectivity table - ATLAS_HOST_DEVICE - size_t cols( size_t row_idx ) const { return counts_view_(row_idx); } + /// @brief Number of columns for specified row in the connectivity table + ATLAS_HOST_DEVICE + size_t cols( size_t row_idx ) const { return counts_view_( row_idx ); } - /// @brief Maximum value for number of columns over all rows - ATLAS_HOST_DEVICE - size_t maxcols() const { return maxcols_; } + /// @brief Maximum value for number of columns over all rows + ATLAS_HOST_DEVICE + size_t maxcols() const { return maxcols_; } - /// @brief Minimum value for number of columns over all rows - ATLAS_HOST_DEVICE - size_t mincols() const { return mincols_; } + /// @brief Minimum value for number of columns over all rows + ATLAS_HOST_DEVICE + size_t mincols() const { return mincols_; } - /// @brief Access to connectivity table elements for given row and column - /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. - ATLAS_HOST_DEVICE - idx_t operator()( size_t row_idx, size_t col_idx ) const; + /// @brief Access to connectivity table elements for given row and column + /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. + ATLAS_HOST_DEVICE + idx_t operator()( size_t row_idx, size_t col_idx ) const; - /// @brief Access to raw data. - /// Note that the connectivity base is 1 in case ATLAS_HAVE_FORTRAN is defined. - const idx_t* data() const { return values_view_.data(); } - idx_t* data() { return values_view_.data(); } + /// @brief Access to raw data. + /// Note that the connectivity base is 1 in case ATLAS_HAVE_FORTRAN is + /// defined. + const idx_t* data() const { return values_view_.data(); } + idx_t* data() { return values_view_.data(); } - size_t size() const { return values_view_.size();} + size_t size() const { return values_view_.size(); } - ATLAS_HOST_DEVICE - idx_t missing_value() const { return missing_value_; } + ATLAS_HOST_DEVICE + idx_t missing_value() const { return missing_value_; } - ATLAS_HOST_DEVICE - Row row( size_t row_idx ) const; + ATLAS_HOST_DEVICE + Row row( size_t row_idx ) const; -///-- Modifiers + ///-- Modifiers - /// @brief Modify row with given values. Values must be given with base 0 - void set( size_t row_idx, const idx_t column_values[] ); + /// @brief Modify row with given values. Values must be given with base 0 + void set( size_t row_idx, const idx_t column_values[] ); - /// @brief Modify (row,col) with given value. Value must be given with base 0 - void set( size_t row_idx, size_t col_idx, const idx_t value ); + /// @brief Modify (row,col) with given value. Value must be given with base 0 + void set( size_t row_idx, size_t col_idx, const idx_t value ); - /// @brief Resize connectivity - /// @note Can only be used when data is owned. - virtual void resize(size_t old_size, size_t size, bool initialize, const idx_t values[], bool fortran_array); + /// @brief Resize connectivity + /// @note Can only be used when data is owned. + virtual void resize( size_t old_size, size_t size, bool initialize, const idx_t values[], bool fortran_array ); - /// @brief Resize connectivity, and add given rows - /// @note Can only be used when data is owned. - virtual void add( size_t rows, size_t cols, const idx_t values[], bool fortran_array=false ); + /// @brief Resize connectivity, and add given rows + /// @note Can only be used when data is owned. + virtual void add( size_t rows, size_t cols, const idx_t values[], bool fortran_array = false ); - /// @brief Resize connectivity, and add given rows with missing values - /// @note Can only be used when data is owned. - virtual void add( size_t rows, size_t cols ); + /// @brief Resize connectivity, and add given rows with missing values + /// @note Can only be used when data is owned. + virtual void add( size_t rows, size_t cols ); - /// @brief Resize connectivity, and add given rows with missing values - /// @note Can only be used when data is owned. - virtual void add( size_t rows, const size_t cols[] ); + /// @brief Resize connectivity, and add given rows with missing values + /// @note Can only be used when data is owned. + virtual void add( size_t rows, const size_t cols[] ); - /// @brief Resize connectivity, and copy from a BlockConnectivity - virtual void add( const BlockConnectivityImpl& block ); + /// @brief Resize connectivity, and copy from a BlockConnectivity + virtual void add( const BlockConnectivityImpl& block ); - /// @brief Resize connectivity, and insert given rows - /// @note Can only be used when data is owned. - virtual void insert( size_t position, size_t rows, size_t cols, const idx_t values[], bool fortran_array=false ); + /// @brief Resize connectivity, and insert given rows + /// @note Can only be used when data is owned. + virtual void insert( size_t position, size_t rows, size_t cols, const idx_t values[], bool fortran_array = false ); - /// @brief Resize connectivity, and insert given rows with missing values - /// @note Can only be used when data is owned. - virtual void insert( size_t position, size_t rows, size_t cols ); + /// @brief Resize connectivity, and insert given rows with missing values + /// @note Can only be used when data is owned. + virtual void insert( size_t position, size_t rows, size_t cols ); - /// @brief Resize connectivity, and insert given rows with missing values - /// @note Can only be used when data is owned. - virtual void insert( size_t position, size_t rows, const size_t cols[] ); + /// @brief Resize connectivity, and insert given rows with missing values + /// @note Can only be used when data is owned. + virtual void insert( size_t position, size_t rows, const size_t cols[] ); - virtual void clear(); + virtual void clear(); - virtual size_t footprint() const; + virtual size_t footprint() const; - size_t displs(const size_t row) const {return displs_view_(row); } + size_t displs( const size_t row ) const { return displs_view_( row ); } - virtual void cloneToDevice(); - virtual void cloneFromDevice(); - virtual void syncHostDevice() const; - virtual bool valid() const; - virtual bool hostNeedsUpdate() const; - virtual bool deviceNeedsUpdate() const; + virtual void cloneToDevice(); + virtual void cloneFromDevice(); + virtual void syncHostDevice() const; + virtual bool valid() const; + virtual bool hostNeedsUpdate() const; + virtual bool deviceNeedsUpdate() const; - IrregularConnectivityImpl* gpu_object_ptr() {return gpu_clone_.gpu_object_ptr();} - void dump(std::ostream& os) const; + IrregularConnectivityImpl* gpu_object_ptr() { return gpu_clone_.gpu_object_ptr(); } + void dump( std::ostream& os ) const; protected: - bool owns() { return owns_; } - const size_t *displs() const { return displs_view_.data(); } - const size_t *counts() const { return counts_view_.data(); } + bool owns() { return owns_; } + const size_t* displs() const { return displs_view_.data(); } + const size_t* counts() const { return counts_view_.data(); } private: - - void on_delete(); - void on_update(); + void on_delete(); + void on_update(); private: - char name_[MAX_STRING_SIZE]; + char name_[MAX_STRING_SIZE]; - bool owns_; - std::array data_; + bool owns_; + std::array data_; - array::ArrayView values_view_; - array::ArrayView displs_view_; - array::ArrayView counts_view_; + array::ArrayView values_view_; + array::ArrayView displs_view_; + array::ArrayView counts_view_; - idx_t missing_value_; - size_t rows_; - size_t maxcols_; - size_t mincols_; + idx_t missing_value_; + size_t rows_; + size_t maxcols_; + size_t mincols_; public: - typedef void* ctxt_t; - typedef void (*callback_t)(ctxt_t); + typedef void* ctxt_t; + typedef void ( *callback_t )( ctxt_t ); private: - friend class ConnectivityPrivateAccess; - ctxt_t ctxt_; - callback_t callback_update_; - callback_t callback_delete_; - array::gridtools::GPUClonable gpu_clone_; - + friend class ConnectivityPrivateAccess; + ctxt_t ctxt_; + callback_t callback_update_; + callback_t callback_delete_; + array::gridtools::GPUClonable gpu_clone_; }; // ---------------------------------------------------------------------------------------------- @@ -313,8 +331,10 @@ class IrregularConnectivityImpl /// @brief MultiBlockConnectivityImpl Table /// @author Willem Deconinck /// -/// Container for connectivity tables that are layed out in memory as multiple BlockConnectivities stitched together. -/// This is e.g. the case for a element-node connectivity, with element-types grouped together: +/// Container for connectivity tables that are layed out in memory as multiple +/// BlockConnectivities stitched together. +/// This is e.g. the case for a element-node connectivity, with element-types +/// grouped together: /// connectivity = [ /// # triangles (block 0) /// 1 2 3 @@ -327,7 +347,8 @@ class IrregularConnectivityImpl /// 21 22 23 24 /// ] /// -/// This class can also be interpreted as a atlas::IrregularConnectivity without distinction between blocks +/// This class can also be interpreted as a atlas::IrregularConnectivity without +/// distinction between blocks /// /// There are 2 modes of construction: /// - It wraps existing raw data @@ -339,122 +360,120 @@ class IrregularConnectivityImpl /// /// In the first mode of construction, the connectivity table cannot be resized. /// In the second mode of construction, resizing is possible -class MultiBlockConnectivityImpl : public IrregularConnectivityImpl -{ +class MultiBlockConnectivityImpl : public IrregularConnectivityImpl { public: - -//-- Constructors - - /// @brief Construct connectivity table that needs resizing a-posteriori - /// Data is owned - MultiBlockConnectivityImpl( const std::string& name = "" ); - -/* - /// @brief Construct connectivity table wrapping existing raw data. - /// No resizing can be performed as data is not owned. - MultiBlockConnectivity( - idx_t values[], - size_t rows, - size_t displs[], - size_t counts[], - size_t blocks, size_t block_displs[], - size_t block_cols[] ); + //-- Constructors + + /// @brief Construct connectivity table that needs resizing a-posteriori + /// Data is owned + MultiBlockConnectivityImpl( const std::string& name = "" ); + + /* +/// @brief Construct connectivity table wrapping existing raw data. +/// No resizing can be performed as data is not owned. +MultiBlockConnectivity( + idx_t values[], + size_t rows, + size_t displs[], + size_t counts[], + size_t blocks, size_t block_displs[], + size_t block_cols[] ); */ - virtual ~MultiBlockConnectivityImpl(); + virtual ~MultiBlockConnectivityImpl(); -//-- Accessors + //-- Accessors - /// @brief Number of blocks - ATLAS_HOST_DEVICE - size_t blocks() const { return blocks_; } + /// @brief Number of blocks + ATLAS_HOST_DEVICE + size_t blocks() const { return blocks_; } - /// @brief Access to a block connectivity - ATLAS_HOST_DEVICE - const BlockConnectivityImpl& block( size_t block_idx ) const { return *(block_view_[block_idx]); } - ATLAS_HOST_DEVICE - BlockConnectivityImpl& block( size_t block_idx ) { return *(block_view_[block_idx]); } + /// @brief Access to a block connectivity + ATLAS_HOST_DEVICE + const BlockConnectivityImpl& block( size_t block_idx ) const { return *( block_view_[block_idx] ); } + ATLAS_HOST_DEVICE + BlockConnectivityImpl& block( size_t block_idx ) { return *( block_view_[block_idx] ); } -// ATLAS_HOST_DEVICE -// BlockConnectivityImpl* base() { return block_.base();} + // ATLAS_HOST_DEVICE + // BlockConnectivityImpl* base() { return block_.base();} - /// @brief Access to connectivity table elements for given row and column - /// The row_idx counts up from 0, from block 0, as in IrregularConnectivity - /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. - ATLAS_HOST_DEVICE - idx_t operator()( size_t row_idx, size_t col_idx ) const; + /// @brief Access to connectivity table elements for given row and column + /// The row_idx counts up from 0, from block 0, as in IrregularConnectivity + /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. + ATLAS_HOST_DEVICE + idx_t operator()( size_t row_idx, size_t col_idx ) const; - /// @brief Access to connectivity table elements for given row and column - /// The block_row_idx counts up from zero for every block_idx. - /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. - ATLAS_HOST_DEVICE - idx_t operator()( size_t block_idx, size_t block_row_idx, size_t block_col_idx ) const; + /// @brief Access to connectivity table elements for given row and column + /// The block_row_idx counts up from zero for every block_idx. + /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. + ATLAS_HOST_DEVICE + idx_t operator()( size_t block_idx, size_t block_row_idx, size_t block_col_idx ) const; -///-- Modifiers + ///-- Modifiers - /// @brief Resize connectivity, and add given rows as a new block - /// @note Can only be used when data is owned. - virtual void add( size_t rows, size_t cols, const idx_t values[], bool fortran_array=false ); + /// @brief Resize connectivity, and add given rows as a new block + /// @note Can only be used when data is owned. + virtual void add( size_t rows, size_t cols, const idx_t values[], bool fortran_array = false ); - /// @brief Resize connectivity, and copy from a BlockConnectivity to a new block - /// @note Can only be used when data is owned. - virtual void add( const BlockConnectivityImpl& ); + /// @brief Resize connectivity, and copy from a BlockConnectivity to a new + /// block + /// @note Can only be used when data is owned. + virtual void add( const BlockConnectivityImpl& ); - /// @brief Resize connectivity, and add given rows with missing values - /// @note Can only be used when data is owned. - virtual void add( size_t rows, size_t cols ); + /// @brief Resize connectivity, and add given rows with missing values + /// @note Can only be used when data is owned. + virtual void add( size_t rows, size_t cols ); - /// @brief Resize connectivity, and add given rows with missing values - /// @note Can only be used when data is owned. - virtual void add( size_t rows, const size_t cols[] ); + /// @brief Resize connectivity, and add given rows with missing values + /// @note Can only be used when data is owned. + virtual void add( size_t rows, const size_t cols[] ); - /// @brief Resize connectivity, and insert given rows - /// @note Can only be used when data is owned. - virtual void insert( size_t position, size_t rows, size_t cols, const idx_t values[], bool fortran_array=false ); + /// @brief Resize connectivity, and insert given rows + /// @note Can only be used when data is owned. + virtual void insert( size_t position, size_t rows, size_t cols, const idx_t values[], bool fortran_array = false ); - /// @brief Resize connectivity, and insert given rows with missing values - /// @note Can only be used when data is owned. - virtual void insert( size_t position, size_t rows, size_t cols ); + /// @brief Resize connectivity, and insert given rows with missing values + /// @note Can only be used when data is owned. + virtual void insert( size_t position, size_t rows, size_t cols ); - /// @brief Resize connectivity, and insert given rows with missing values - /// @note Can only be used when data is owned. - virtual void insert( size_t position, size_t rows, const size_t cols[] ); + /// @brief Resize connectivity, and insert given rows with missing values + /// @note Can only be used when data is owned. + virtual void insert( size_t position, size_t rows, const size_t cols[] ); - virtual void clear(); + virtual void clear(); - virtual size_t footprint() const; + virtual size_t footprint() const; - virtual void cloneToDevice(); - virtual void cloneFromDevice(); - virtual void syncHostDevice() const; - virtual bool valid() const; - virtual bool hostNeedsUpdate() const; - virtual bool deviceNeedsUpdate() const; + virtual void cloneToDevice(); + virtual void cloneFromDevice(); + virtual void syncHostDevice() const; + virtual bool valid() const; + virtual bool hostNeedsUpdate() const; + virtual bool deviceNeedsUpdate() const; - MultiBlockConnectivityImpl* gpu_object_ptr() {return gpu_clone_.gpu_object_ptr();} + MultiBlockConnectivityImpl* gpu_object_ptr() { return gpu_clone_.gpu_object_ptr(); } private: - - void rebuild_block_connectivity(); + void rebuild_block_connectivity(); private: - size_t blocks_; - array::Array* block_displs_; - array::Array* block_cols_; - - array::ArrayView block_displs_view_; - array::ArrayView block_cols_view_; - array::Vector block_; - array::VectorView block_view_; + size_t blocks_; + array::Array* block_displs_; + array::Array* block_cols_; - array::gridtools::GPUClonable gpu_clone_; + array::ArrayView block_displs_view_; + array::ArrayView block_cols_view_; + array::Vector block_; + array::VectorView block_view_; + array::gridtools::GPUClonable gpu_clone_; }; // ----------------------------------------------------------------------------------------------------- /// @brief Block Connectivity table /// @author Willem Deconinck -/// Container for connectivity tables that are layed out in memory as a block. Every row has the same +/// Container for connectivity tables that are layed out in memory as a block. +/// Every row has the same /// number of columns. /// /// There are 2 modes of construction: @@ -468,105 +487,102 @@ class MultiBlockConnectivityImpl : public IrregularConnectivityImpl /// In the first mode of construction, the connectivity table cannot be resized. /// In the second mode of construction, resizing is possible class BlockConnectivityImpl { - private: - friend class IrregularConnectivityImpl; - friend class MultiBlockConnectivityImpl; - BlockConnectivityImpl( size_t rows, size_t cols, idx_t values[], bool dummy); + friend class IrregularConnectivityImpl; + friend class MultiBlockConnectivityImpl; + BlockConnectivityImpl( size_t rows, size_t cols, idx_t values[], bool dummy ); public: + //-- Constructors + + /// @brief Construct connectivity table that needs resizing a-posteriori + /// Data is owned + BlockConnectivityImpl(); + BlockConnectivityImpl( size_t rows, size_t cols, const std::initializer_list& ); + + /// @brief Construct connectivity table wrapping existing raw data. + /// No resizing can be performed as data is not owned. + BlockConnectivityImpl( size_t rows, size_t cols, idx_t values[] ); + + /// @brief Copy ctr (only to be used when calling a cuda kernel) + // This ctr has to be defined in the header, since __CUDACC__ will identify + // whether + // it is compiled it for a GPU kernel + BlockConnectivityImpl( const BlockConnectivityImpl& other ) : + owns_( false ), + values_( 0 ), + values_view_( other.values_view_ ), + rows_( other.rows_ ), + cols_( other.cols_ ), + missing_value_( other.missing_value_ ), + gpu_clone_( this ) {} + + /// @brief Destructor + ~BlockConnectivityImpl(); + + void rebuild( size_t rows, size_t cols, idx_t values[] ); + + //-- Accessors + + /// @brief Access to connectivity table elements for given row and column + /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. + ATLAS_HOST_DEVICE + idx_t operator()( size_t row_idx, size_t col_idx ) const; -//-- Constructors - - /// @brief Construct connectivity table that needs resizing a-posteriori - /// Data is owned - BlockConnectivityImpl(); - BlockConnectivityImpl( size_t rows, size_t cols, const std::initializer_list& ); - - /// @brief Construct connectivity table wrapping existing raw data. - /// No resizing can be performed as data is not owned. - BlockConnectivityImpl( size_t rows, size_t cols, idx_t values[]); - - /// @brief Copy ctr (only to be used when calling a cuda kernel) - // This ctr has to be defined in the header, since __CUDACC__ will identify whether - // it is compiled it for a GPU kernel - BlockConnectivityImpl(const BlockConnectivityImpl& other) - : owns_(false), - values_(0), - values_view_(other.values_view_), - rows_(other.rows_), - cols_(other.cols_), - missing_value_( other.missing_value_), - gpu_clone_(this) - {} - - - /// @brief Destructor - ~BlockConnectivityImpl(); - - void rebuild( size_t rows, size_t cols, idx_t values[] ); - -//-- Accessors - - /// @brief Access to connectivity table elements for given row and column - /// The returned index has base 0 regardless if ATLAS_HAVE_FORTRAN is defined. - ATLAS_HOST_DEVICE - idx_t operator()( size_t row_idx, size_t col_idx ) const; - - /// @brief Number of rows - ATLAS_HOST_DEVICE - size_t rows() const { return rows_; } + /// @brief Number of rows + ATLAS_HOST_DEVICE + size_t rows() const { return rows_; } - /// @brief Number of columns - ATLAS_HOST_DEVICE - size_t cols() const { return cols_; } + /// @brief Number of columns + ATLAS_HOST_DEVICE + size_t cols() const { return cols_; } - /// @brief Access to raw data. - /// Note that the connectivity base is 1 in case ATLAS_HAVE_FORTRAN is defined. - ATLAS_HOST_DEVICE - const idx_t* data() const { return values_view_.data(); } - ATLAS_HOST_DEVICE - idx_t* data() { return values_view_.data(); } + /// @brief Access to raw data. + /// Note that the connectivity base is 1 in case ATLAS_HAVE_FORTRAN is + /// defined. + ATLAS_HOST_DEVICE + const idx_t* data() const { return values_view_.data(); } + ATLAS_HOST_DEVICE + idx_t* data() { return values_view_.data(); } - ATLAS_HOST_DEVICE - idx_t missing_value() const { return missing_value_; } + ATLAS_HOST_DEVICE + idx_t missing_value() const { return missing_value_; } - size_t footprint() const; + size_t footprint() const; -//-- Modifiers + //-- Modifiers - /// @brief Modify row with given values. Values must be given with base 0 - ATLAS_HOST_DEVICE - void set( size_t row_idx, const idx_t column_values[] ); + /// @brief Modify row with given values. Values must be given with base 0 + ATLAS_HOST_DEVICE + void set( size_t row_idx, const idx_t column_values[] ); - /// @brief Modify (row,col) with given value. Value must be given with base 0 - ATLAS_HOST_DEVICE - void set( size_t row_idx, size_t col_idx, const idx_t value ); + /// @brief Modify (row,col) with given value. Value must be given with base 0 + ATLAS_HOST_DEVICE + void set( size_t row_idx, size_t col_idx, const idx_t value ); - /// @brief Resize connectivity, and add given rows - /// @note Can only be used when data is owned. - void add( size_t rows, size_t cols, const idx_t values[], bool fortran_array=false ); + /// @brief Resize connectivity, and add given rows + /// @note Can only be used when data is owned. + void add( size_t rows, size_t cols, const idx_t values[], bool fortran_array = false ); - void cloneToDevice(); - void cloneFromDevice(); - void syncHostDevice() const; - bool valid() const; - bool hostNeedsUpdate() const; - bool deviceNeedsUpdate() const; + void cloneToDevice(); + void cloneFromDevice(); + void syncHostDevice() const; + bool valid() const; + bool hostNeedsUpdate() const; + bool deviceNeedsUpdate() const; - bool owns() const { return owns_; } - BlockConnectivityImpl* gpu_object_ptr() {return gpu_clone_.gpu_object_ptr();} + bool owns() const { return owns_; } + BlockConnectivityImpl* gpu_object_ptr() { return gpu_clone_.gpu_object_ptr(); } private: - bool owns_; - array::Array* values_; - array::ArrayView values_view_; - - size_t rows_; - size_t cols_; - idx_t missing_value_; - array::gridtools::GPUClonable gpu_clone_; - + bool owns_; + array::Array* values_; + array::ArrayView values_view_; + + size_t rows_; + size_t cols_; + idx_t missing_value_; + array::gridtools::GPUClonable gpu_clone_; }; typedef ConnectivityInterface IrregularConnectivity; @@ -577,84 +593,79 @@ typedef IrregularConnectivity Connectivity; // ----------------------------------------------------------------------------------------------------- -inline idx_t IrregularConnectivityImpl::operator()( size_t row_idx, size_t col_idx ) const -{ - assert(counts_view_(row_idx) >( col_idx)); - return values_view_(displs_view_(row_idx) + col_idx) FROM_FORTRAN; +inline idx_t IrregularConnectivityImpl::operator()( size_t row_idx, size_t col_idx ) const { + assert( counts_view_( row_idx ) > ( col_idx ) ); + return values_view_( displs_view_( row_idx ) + col_idx ) FROM_FORTRAN; } inline void IrregularConnectivityImpl::set( size_t row_idx, const idx_t column_values[] ) { - const size_t N = counts_view_(row_idx); - for( size_t n=0; n(values_view_.data() ) +displs_view_(row_idx) , counts_view_(row_idx) ); +inline IrregularConnectivityImpl::Row IrregularConnectivityImpl::row( size_t row_idx ) const { + return IrregularConnectivityImpl::Row( const_cast( values_view_.data() ) + displs_view_( row_idx ), + counts_view_( row_idx ) ); } // ----------------------------------------------------------------------------------------------------- -inline idx_t MultiBlockConnectivityImpl::operator()( size_t row_idx, size_t col_idx ) const -{ - return IrregularConnectivityImpl::operator()(row_idx,col_idx); +inline idx_t MultiBlockConnectivityImpl::operator()( size_t row_idx, size_t col_idx ) const { + return IrregularConnectivityImpl::operator()( row_idx, col_idx ); } - -inline idx_t MultiBlockConnectivityImpl::operator()( size_t block_idx, size_t block_row_idx, size_t block_col_idx ) const -{ - return block(block_idx)(block_row_idx,block_col_idx); +inline idx_t MultiBlockConnectivityImpl::operator()( size_t block_idx, size_t block_row_idx, + size_t block_col_idx ) const { + return block( block_idx )( block_row_idx, block_col_idx ); } - // ----------------------------------------------------------------------------------------------------- inline idx_t BlockConnectivityImpl::operator()( size_t row_idx, size_t col_idx ) const { - return values_view_(row_idx, col_idx) FROM_FORTRAN; + return values_view_( row_idx, col_idx ) FROM_FORTRAN; } inline void BlockConnectivityImpl::set( size_t row_idx, const idx_t column_values[] ) { - for( size_t n=0; n inline DataType::kind_t DataType::kind() { return KIND_INT32; } - +// TODO HACK +// template<> inline DataType::kind_t +// DataType::kind() { return KIND_INT32; } } -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/mesh/ElementType.cc b/src/atlas/mesh/ElementType.cc index 8d86f8ea2..22292ac85 100644 --- a/src/atlas/mesh/ElementType.cc +++ b/src/atlas/mesh/ElementType.cc @@ -4,23 +4,23 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "atlas/mesh/ElementType.h" -#include "atlas/util/CoordinateEnums.h" #include "atlas/runtime/ErrorHandling.h" +#include "atlas/util/CoordinateEnums.h" namespace atlas { namespace mesh { //------------------------------------------------------------------------------ -ElementType* ElementType::create( const std::string& ) -{ - NOTIMP; - return 0; +ElementType* ElementType::create( const std::string& ) { + NOTIMP; + return 0; } ElementType::ElementType() {} @@ -29,53 +29,39 @@ ElementType::~ElementType() {} //----------------------------------------------------------------------------- extern "C" { -void atlas__mesh__ElementType__delete(ElementType* This) -{ - ATLAS_ERROR_HANDLING( delete This ); +void atlas__mesh__ElementType__delete( ElementType* This ) { + ATLAS_ERROR_HANDLING( delete This ); } -ElementType* atlas__mesh__Triangle__create() { return new temporary::Triangle(); } -ElementType* atlas__mesh__Quadrilateral__create() { return new temporary::Quadrilateral(); } -ElementType* atlas__mesh__Line__create() { return new temporary::Line(); } - -const char* atlas__mesh__ElementType__name (const ElementType* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->name().c_str(); - ); - return 0; +ElementType* atlas__mesh__Triangle__create() { + return new temporary::Triangle(); } - -size_t atlas__mesh__ElementType__nb_nodes(const ElementType* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->nb_nodes() - ); - return 0; +ElementType* atlas__mesh__Quadrilateral__create() { + return new temporary::Quadrilateral(); +} +ElementType* atlas__mesh__Line__create() { + return new temporary::Line(); } -size_t atlas__mesh__ElementType__nb_edges(const ElementType* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->nb_edges() - ); - return 0; +const char* atlas__mesh__ElementType__name( const ElementType* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->name().c_str(); ); + return 0; } -int atlas__mesh__ElementType__parametric(const ElementType *This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->parametric() - ); - return 0; +size_t atlas__mesh__ElementType__nb_nodes( const ElementType* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->nb_nodes() ); + return 0; } +size_t atlas__mesh__ElementType__nb_edges( const ElementType* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->nb_edges() ); + return 0; +} +int atlas__mesh__ElementType__parametric( const ElementType* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->parametric() ); + return 0; +} } } // namespace mesh } // namespace atlas - diff --git a/src/atlas/mesh/ElementType.h b/src/atlas/mesh/ElementType.h index aaa19d082..fec95f10a 100644 --- a/src/atlas/mesh/ElementType.h +++ b/src/atlas/mesh/ElementType.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -19,138 +20,198 @@ namespace atlas { namespace mesh { /** - * \brief ElementType class (abstract) that provides access to geometric information of an element + * \brief ElementType class (abstract) that provides access to geometric + * information of an element */ class ElementType : public eckit::Owned { +public: // methods + static ElementType* create( const std::string& ); -public: // methods + //-- Constructors - static ElementType* create( const std::string& ); + ElementType(); + ~ElementType() = 0; -//-- Constructors + //-- Accessors - ElementType(); - ~ElementType() = 0; + virtual const std::string& name() const = 0; + // virtual size_t dimensionality() const = 0; -//-- Accessors + // virtual size_t nb_vertices() const = 0; + virtual size_t nb_edges() const = 0; + // virtual size_t nb_faces() const = 0; - virtual const std::string& name() const = 0; - // virtual size_t dimensionality() const = 0; + virtual size_t nb_nodes() const = 0; - // virtual size_t nb_vertices() const = 0; - virtual size_t nb_edges() const = 0; - // virtual size_t nb_faces() const = 0; - - virtual size_t nb_nodes() const = 0; - - virtual bool parametric() const = 0; + virtual bool parametric() const = 0; }; namespace temporary { - - class Volume : public ElementType - { - public: - enum { DIMENSIONALITY=3 }; - }; - - class Face : public ElementType - { - public: - enum { DIMENSIONALITY=2 }; - enum { FACES=1 }; + +class Volume : public ElementType { +public: + enum + { + DIMENSIONALITY = 3 + }; +}; + +class Face : public ElementType { +public: + enum + { + DIMENSIONALITY = 2 + }; + enum + { + FACES = 1 + }; virtual size_t nb_faces() const { return FACES; } - }; - - class Edge: public ElementType - { - public: - enum { DIMENSIONALITY=1 }; - enum { FACES=0 }; - enum { EDGES=1 }; - virtual size_t nb_faces() const { return FACES; } - virtual size_t nb_edges() const { return EDGES; } - }; - - class Vertex: public ElementType - { - public: - enum { DIMENSIONALITY=0 }; - enum { FACES=0 }; - enum { EDGES=0 }; - enum { VERTICES=1 }; - virtual size_t nb_faces() const { return FACES; } - virtual size_t nb_edges() const { return EDGES; } - virtual size_t nb_vertices() const { return VERTICES; } - }; +}; -class Quadrilateral : public Face -{ +class Edge : public ElementType { public: - enum { EDGES=4 }; - enum { VERTICES=4 }; - enum { FACETS=EDGES }; - enum { RIDGES=VERTICES }; - virtual ~Quadrilateral() {} - virtual bool parametric() const { return true; } - virtual size_t nb_vertices() const { return VERTICES; } - virtual size_t nb_edges() const { return EDGES; } - virtual size_t nb_nodes() const { return VERTICES; } - virtual size_t nb_facets() const { return FACETS; } - virtual size_t nb_ridges() const { return RIDGES; } - virtual const std::string& name() const { static std::string s("Quadrilateral"); return s; } + enum + { + DIMENSIONALITY = 1 + }; + enum + { + FACES = 0 + }; + enum + { + EDGES = 1 + }; + virtual size_t nb_faces() const { return FACES; } + virtual size_t nb_edges() const { return EDGES; } }; -class Triangle : public Face -{ +class Vertex : public ElementType { public: - enum { EDGES=3 }; - enum { VERTICES=3 }; - enum { FACETS=EDGES }; - enum { RIDGES=VERTICES }; - virtual ~Triangle() {} - virtual bool parametric() const { return true; } - virtual size_t nb_vertices() const { return VERTICES; } - virtual size_t nb_edges() const { return EDGES; } - virtual size_t nb_nodes() const { return VERTICES; } - virtual size_t nb_facets() const { return FACETS; } - virtual size_t nb_ridges() const { return RIDGES; } - virtual const std::string& name() const { static std::string s("Triangle"); return s; } + enum + { + DIMENSIONALITY = 0 + }; + enum + { + FACES = 0 + }; + enum + { + EDGES = 0 + }; + enum + { + VERTICES = 1 + }; + virtual size_t nb_faces() const { return FACES; } + virtual size_t nb_edges() const { return EDGES; } + virtual size_t nb_vertices() const { return VERTICES; } }; -class Line : public Edge -{ +class Quadrilateral : public Face { public: - enum { VERTICES = 2 }; - enum { FACETS = VERTICES }; - enum { RIDGES = 0 }; - virtual ~Line() {} - virtual bool parametric() const { return true; } - virtual size_t nb_vertices() const { return VERTICES; } - virtual size_t nb_edges() const { return EDGES; } - virtual size_t nb_nodes() const { return VERTICES; } - virtual size_t nb_facets() const { return FACETS; } - virtual const std::string& name() const { static std::string s("Line"); return s; } + enum + { + EDGES = 4 + }; + enum + { + VERTICES = 4 + }; + enum + { + FACETS = EDGES + }; + enum + { + RIDGES = VERTICES + }; + virtual ~Quadrilateral() {} + virtual bool parametric() const { return true; } + virtual size_t nb_vertices() const { return VERTICES; } + virtual size_t nb_edges() const { return EDGES; } + virtual size_t nb_nodes() const { return VERTICES; } + virtual size_t nb_facets() const { return FACETS; } + virtual size_t nb_ridges() const { return RIDGES; } + virtual const std::string& name() const { + static std::string s( "Quadrilateral" ); + return s; + } }; -} +class Triangle : public Face { +public: + enum + { + EDGES = 3 + }; + enum + { + VERTICES = 3 + }; + enum + { + FACETS = EDGES + }; + enum + { + RIDGES = VERTICES + }; + virtual ~Triangle() {} + virtual bool parametric() const { return true; } + virtual size_t nb_vertices() const { return VERTICES; } + virtual size_t nb_edges() const { return EDGES; } + virtual size_t nb_nodes() const { return VERTICES; } + virtual size_t nb_facets() const { return FACETS; } + virtual size_t nb_ridges() const { return RIDGES; } + virtual const std::string& name() const { + static std::string s( "Triangle" ); + return s; + } +}; +class Line : public Edge { +public: + enum + { + VERTICES = 2 + }; + enum + { + FACETS = VERTICES + }; + enum + { + RIDGES = 0 + }; + virtual ~Line() {} + virtual bool parametric() const { return true; } + virtual size_t nb_vertices() const { return VERTICES; } + virtual size_t nb_edges() const { return EDGES; } + virtual size_t nb_nodes() const { return VERTICES; } + virtual size_t nb_facets() const { return FACETS; } + virtual const std::string& name() const { + static std::string s( "Line" ); + return s; + } +}; +} // namespace temporary -extern "C" -{ +extern "C" { ElementType* atlas__mesh__Triangle__create(); ElementType* atlas__mesh__Quadrilateral__create(); ElementType* atlas__mesh__Line__create(); -void atlas__mesh__ElementType__delete(ElementType* This); -size_t atlas__mesh__ElementType__nb_nodes(const ElementType* This); -size_t atlas__mesh__ElementType__nb_edges(const ElementType* This); -int atlas__mesh__ElementType__parametric(const ElementType* This); -const char* atlas__mesh__ElementType__name (const ElementType* This); - +void atlas__mesh__ElementType__delete( ElementType* This ); +size_t atlas__mesh__ElementType__nb_nodes( const ElementType* This ); +size_t atlas__mesh__ElementType__nb_edges( const ElementType* This ); +int atlas__mesh__ElementType__parametric( const ElementType* This ); +const char* atlas__mesh__ElementType__name( const ElementType* This ); } //------------------------------------------------------------------------------------------------------ -} // namespace mesh -} // namespace atlas +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/Elements.cc b/src/atlas/mesh/Elements.cc index 4b2f847f4..1b45018f7 100644 --- a/src/atlas/mesh/Elements.cc +++ b/src/atlas/mesh/Elements.cc @@ -4,313 +4,261 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/library/config.h" -#include "atlas/mesh/ElementType.h" #include "atlas/mesh/Elements.h" +#include "atlas/array/MakeView.h" #include "atlas/field/Field.h" +#include "atlas/library/config.h" +#include "atlas/mesh/ElementType.h" #include "atlas/runtime/ErrorHandling.h" -#include "atlas/array/MakeView.h" namespace atlas { namespace mesh { //----------------------------------------------------------------------------- -void Elements::rebuild() -{ - size_ = hybrid_elements_->elements_size_[type_idx_]; - nb_nodes_ = hybrid_elements_->element_type(type_idx_).nb_nodes(); - nb_edges_ = hybrid_elements_->element_type(type_idx_).nb_edges(); - begin_ = hybrid_elements_->elements_begin_[type_idx_]; - end_ = hybrid_elements_->elements_begin_[type_idx_+1]; +void Elements::rebuild() { + size_ = hybrid_elements_->elements_size_[type_idx_]; + nb_nodes_ = hybrid_elements_->element_type( type_idx_ ).nb_nodes(); + nb_edges_ = hybrid_elements_->element_type( type_idx_ ).nb_edges(); + begin_ = hybrid_elements_->elements_begin_[type_idx_]; + end_ = hybrid_elements_->elements_begin_[type_idx_ + 1]; } -Elements::Elements( HybridElements &elements, size_t type_idx ) - : owns_(false), hybrid_elements_(&elements), type_idx_(type_idx) -{ - rebuild(); +Elements::Elements( HybridElements& elements, size_t type_idx ) : + owns_( false ), + hybrid_elements_( &elements ), + type_idx_( type_idx ) { + rebuild(); } -Elements::Elements( ElementType* element_type, size_t nb_elements, const std::vector &node_connectivity ) - : owns_(true) -{ - hybrid_elements_ = new HybridElements(); - type_idx_ = hybrid_elements_->add(element_type,nb_elements,node_connectivity.data()); - rebuild(); +Elements::Elements( ElementType* element_type, size_t nb_elements, const std::vector& node_connectivity ) : + owns_( true ) { + hybrid_elements_ = new HybridElements(); + type_idx_ = hybrid_elements_->add( element_type, nb_elements, node_connectivity.data() ); + rebuild(); } -Elements::Elements( ElementType* element_type, size_t nb_elements, const idx_t node_connectivity[], bool fortran_array ) - : owns_(true) -{ - hybrid_elements_ = new HybridElements(); - type_idx_ = hybrid_elements_->add(element_type,nb_elements,node_connectivity,fortran_array); - rebuild(); +Elements::Elements( ElementType* element_type, size_t nb_elements, const idx_t node_connectivity[], + bool fortran_array ) : + owns_( true ) { + hybrid_elements_ = new HybridElements(); + type_idx_ = hybrid_elements_->add( element_type, nb_elements, node_connectivity, fortran_array ); + rebuild(); } - -Elements::~Elements() -{ - if( owns_ ) delete hybrid_elements_; +Elements::~Elements() { + if ( owns_ ) delete hybrid_elements_; } -const std::string& Elements::name() const -{ - return hybrid_elements_->element_type(type_idx_).name(); +const std::string& Elements::name() const { + return hybrid_elements_->element_type( type_idx_ ).name(); } -template<> array::LocalView Elements::view( const Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} ); +template <> +array::LocalView Elements::view( const Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()} ); } -template<> array::LocalView Elements::view( const Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} ); +template <> +array::LocalView Elements::view( const Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()} ); } -template<> array::LocalView Elements::view( const Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} ); +template <> +array::LocalView Elements::view( const Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()} ); } -template<> array::LocalView Elements::view( const Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} ); +template <> +array::LocalView Elements::view( const Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()} ); } - - -template<> array::LocalView Elements::view( const Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +template <> +array::LocalView Elements::view( const Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()}, array::Range::all() ); } -template<> array::LocalView Elements::view( const Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +template <> +array::LocalView Elements::view( const Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()}, array::Range::all() ); } -template<> array::LocalView Elements::view( const Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +template <> +array::LocalView Elements::view( const Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()}, array::Range::all() ); } -template<> array::LocalView Elements::view( const Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +template <> +array::LocalView Elements::view( const Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()}, array::Range::all() ); } // ---------------------------------------------------------------------------- -template<> array::LocalView Elements::view( Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} ); +template <> +array::LocalView Elements::view( Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()} ); } -template<> array::LocalView Elements::view( Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} ); +template <> +array::LocalView Elements::view( Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()} ); } -template<> array::LocalView Elements::view( Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} ); +template <> +array::LocalView Elements::view( Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()} ); } -template<> array::LocalView Elements::view( Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} ); +template <> +array::LocalView Elements::view( Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()} ); } - - -template<> array::LocalView Elements::view( Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +template <> +array::LocalView Elements::view( Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()}, array::Range::all() ); } -template<> array::LocalView Elements::view( Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +template <> +array::LocalView Elements::view( Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()}, array::Range::all() ); } -template<> array::LocalView Elements::view( Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +template <> +array::LocalView Elements::view( Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()}, array::Range::all() ); } -template<> array::LocalView Elements::view( Field& field ) const -{ - return array::make_host_view( field ) - .slice( array::Range{begin(),begin()+size()} , array::Range::all() ); +template <> +array::LocalView Elements::view( Field& field ) const { + return array::make_host_view( field ).slice( + array::Range{begin(), begin() + size()}, array::Range::all() ); } -size_t Elements::add(const size_t nb_elements) -{ - size_t position = size(); - hybrid_elements_->insert(type_idx_,end(),nb_elements); - return position; +size_t Elements::add( const size_t nb_elements ) { + size_t position = size(); + hybrid_elements_->insert( type_idx_, end(), nb_elements ); + return position; } //----------------------------------------------------------------------------- extern "C" { -void atlas__mesh__Elements__delete(Elements* This) -{ - ATLAS_ERROR_HANDLING( delete This ); +void atlas__mesh__Elements__delete( Elements* This ) { + ATLAS_ERROR_HANDLING( delete This ); } -size_t atlas__mesh__Elements__size(const Elements* This) -{ - ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); - return This->size(); +size_t atlas__mesh__Elements__size( const Elements* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->size(); } -size_t atlas__mesh__Elements__begin(const Elements* This) -{ - ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); - return This->begin(); +size_t atlas__mesh__Elements__begin( const Elements* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->begin(); } -size_t atlas__mesh__Elements__end(const Elements* This) -{ - ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); - return This->end(); +size_t atlas__mesh__Elements__end( const Elements* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->end(); } -BlockConnectivity* atlas__mesh__Elements__node_connectivity(Elements* This) -{ - BlockConnectivity* connectivity(0); - ATLAS_ERROR_HANDLING( connectivity = &This->node_connectivity() ); - return connectivity; +BlockConnectivity* atlas__mesh__Elements__node_connectivity( Elements* This ) { + BlockConnectivity* connectivity( 0 ); + ATLAS_ERROR_HANDLING( connectivity = &This->node_connectivity() ); + return connectivity; } -BlockConnectivity* atlas__mesh__Elements__edge_connectivity(Elements* This) -{ - BlockConnectivity* connectivity(0); - ATLAS_ERROR_HANDLING( connectivity = &This->edge_connectivity() ); - return connectivity; +BlockConnectivity* atlas__mesh__Elements__edge_connectivity( Elements* This ) { + BlockConnectivity* connectivity( 0 ); + ATLAS_ERROR_HANDLING( connectivity = &This->edge_connectivity() ); + return connectivity; } -BlockConnectivity* atlas__mesh__Elements__cell_connectivity(Elements* This) -{ - BlockConnectivity* connectivity(0); - ATLAS_ERROR_HANDLING( connectivity = &This->cell_connectivity() ); - return connectivity; +BlockConnectivity* atlas__mesh__Elements__cell_connectivity( Elements* This ) { + BlockConnectivity* connectivity( 0 ); + ATLAS_ERROR_HANDLING( connectivity = &This->cell_connectivity() ); + return connectivity; } - -int atlas__mesh__Elements__has_field(const Elements* This, char* name) -{ - ATLAS_ERROR_HANDLING( ASSERT(This!=0) ); - return This->has_field(std::string(name)); +int atlas__mesh__Elements__has_field( const Elements* This, char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->has_field( std::string( name ) ); } -int atlas__mesh__Elements__nb_fields(const Elements* This) -{ - ATLAS_ERROR_HANDLING( ASSERT(This!=0) ); - return This->nb_fields(); +int atlas__mesh__Elements__nb_fields( const Elements* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->nb_fields(); } -field::FieldImpl* atlas__mesh__Elements__field_by_idx(Elements* This, size_t idx) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->field(idx).get(); - ); - return field; +field::FieldImpl* atlas__mesh__Elements__field_by_idx( Elements* This, size_t idx ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->field( idx ).get(); ); + return field; } -field::FieldImpl* atlas__mesh__Elements__field_by_name(Elements* This, char* name) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->field(std::string(name)).get(); - ); - return field; +field::FieldImpl* atlas__mesh__Elements__field_by_name( Elements* This, char* name ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->field( std::string( name ) ).get(); ); + return field; } -field::FieldImpl* atlas__mesh__Elements__global_index(Elements* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->global_index().get(); - ); - return field; - +field::FieldImpl* atlas__mesh__Elements__global_index( Elements* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->global_index().get(); ); + return field; } -field::FieldImpl* atlas__mesh__Elements__remote_index(Elements* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->remote_index().get(); - ); - return field; +field::FieldImpl* atlas__mesh__Elements__remote_index( Elements* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->remote_index().get(); ); + return field; } -field::FieldImpl* atlas__mesh__Elements__partition(Elements* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->partition().get(); - ); - return field; +field::FieldImpl* atlas__mesh__Elements__partition( Elements* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->partition().get(); ); + return field; } -field::FieldImpl* atlas__mesh__Elements__halo(Elements* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->halo().get(); - ); - return field; +field::FieldImpl* atlas__mesh__Elements__halo( Elements* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->halo().get(); ); + return field; } -const ElementType* atlas__mesh__Elements__element_type(const Elements* This) -{ - const ElementType* element_type(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - element_type = &This->element_type(); - ); - return element_type; +const ElementType* atlas__mesh__Elements__element_type( const Elements* This ) { + const ElementType* element_type( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); element_type = &This->element_type(); ); + return element_type; } -void atlas__mesh__Elements__add(Elements* This, size_t nb_elements) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - This->add(nb_elements); - ); +void atlas__mesh__Elements__add( Elements* This, size_t nb_elements ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); This->add( nb_elements ); ); } - } //----------------------------------------------------------------------------- @@ -320,4 +268,3 @@ void atlas__mesh__Elements__add(Elements* This, size_t nb_elements) #undef FORTRAN_BASE #undef TO_FORTRAN - diff --git a/src/atlas/mesh/Elements.h b/src/atlas/mesh/Elements.h index ae4d1a645..aa4d53309 100644 --- a/src/atlas/mesh/Elements.h +++ b/src/atlas/mesh/Elements.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,12 +17,16 @@ #pragma once -#include "eckit/memory/Owned.h" +#include "atlas/array/ArrayView.h" #include "atlas/mesh/Connectivity.h" #include "atlas/mesh/HybridElements.h" -#include "atlas/array/ArrayView.h" +#include "eckit/memory/Owned.h" -namespace atlas { namespace mesh { class ElementType; } } +namespace atlas { +namespace mesh { +class ElementType; +} +} // namespace atlas namespace atlas { namespace mesh { @@ -31,250 +36,228 @@ namespace mesh { /// @brief Describe elements of a single type class Elements : public eckit::Owned { public: - // typedef atlas::mesh::BlockConnectivity Connectivity; + // typedef atlas::mesh::BlockConnectivity Connectivity; public: + //-- Constructors -//-- Constructors - - /// @brief Constructor that treats elements as sub-elements in HybridElements - Elements( HybridElements &elements, size_t type_idx ); - - /// @brief Constructor that internally creates a HybridElements that owns the data - Elements( ElementType*, size_t nb_elements, const std::vector &node_connectivity ); + /// @brief Constructor that treats elements as sub-elements in HybridElements + Elements( HybridElements& elements, size_t type_idx ); - /// @brief Constructor that internally creates a HybridElements that owns the data - Elements( ElementType*, size_t nb_elements, const idx_t node_connectivity[], bool fortran_array=false ); + /// @brief Constructor that internally creates a HybridElements that owns the + /// data + Elements( ElementType*, size_t nb_elements, const std::vector& node_connectivity ); - /// @brief Destructor - virtual ~Elements(); + /// @brief Constructor that internally creates a HybridElements that owns the + /// data + Elements( ElementType*, size_t nb_elements, const idx_t node_connectivity[], bool fortran_array = false ); -//-- Accessors + /// @brief Destructor + virtual ~Elements(); - /// @brief Number of elements - size_t size() const; + //-- Accessors - /// @brief Name of this element type - const std::string& name() const; + /// @brief Number of elements + size_t size() const; - /// @brief Number of nodes for each element type - size_t nb_nodes() const; + /// @brief Name of this element type + const std::string& name() const; - /// @brief Number of edges for each element type - size_t nb_edges() const; + /// @brief Number of nodes for each element type + size_t nb_nodes() const; - /// @brief Element to Node connectivity table - const BlockConnectivity &node_connectivity() const; - BlockConnectivity &node_connectivity(); + /// @brief Number of edges for each element type + size_t nb_edges() const; - /// @brief Element to Edge connectivity table - const BlockConnectivity &edge_connectivity() const; - BlockConnectivity &edge_connectivity(); + /// @brief Element to Node connectivity table + const BlockConnectivity& node_connectivity() const; + BlockConnectivity& node_connectivity(); - /// @brief Element to Cell connectivity table - const BlockConnectivity &cell_connectivity() const; - BlockConnectivity &cell_connectivity(); + /// @brief Element to Edge connectivity table + const BlockConnectivity& edge_connectivity() const; + BlockConnectivity& edge_connectivity(); - /// @brief Element type of these Elements - const ElementType& element_type() const; + /// @brief Element to Cell connectivity table + const BlockConnectivity& cell_connectivity() const; + BlockConnectivity& cell_connectivity(); - /// @brief Access hybrid_elements - /// HybridElements can contain more Elements, and holds the data. -// const HybridElements& hybrid_elements() const; + /// @brief Element type of these Elements + const ElementType& element_type() const; - /// @brief Index of Elements in hybrid_elements -// size_t type_idx() const; + /// @brief Access hybrid_elements + /// HybridElements can contain more Elements, and holds the data. + // const HybridElements& hybrid_elements() const; - /// @brief Begin of elements in hybrid_elements - size_t begin() const; + /// @brief Index of Elements in hybrid_elements + // size_t type_idx() const; - /// @brief End of elements in hybrid_elements - size_t end() const; + /// @brief Begin of elements in hybrid_elements + size_t begin() const; + /// @brief End of elements in hybrid_elements + size_t end() const; - const Field& field(const std::string& name) const { return hybrid_elements_->field(name); } - Field& field(const std::string& name) { return hybrid_elements_->field(name); } - bool has_field(const std::string& name) const { return hybrid_elements_->has_field(name); } + const Field& field( const std::string& name ) const { return hybrid_elements_->field( name ); } + Field& field( const std::string& name ) { return hybrid_elements_->field( name ); } + bool has_field( const std::string& name ) const { return hybrid_elements_->has_field( name ); } - const Field& field(size_t idx) const { return hybrid_elements_->field(idx); } - Field& field(size_t idx) { return hybrid_elements_->field(idx); } - size_t nb_fields() const { return hybrid_elements_->nb_fields(); } + const Field& field( size_t idx ) const { return hybrid_elements_->field( idx ); } + Field& field( size_t idx ) { return hybrid_elements_->field( idx ); } + size_t nb_fields() const { return hybrid_elements_->nb_fields(); } - const Field& global_index() const { return hybrid_elements_->global_index(); } - Field& global_index() { return hybrid_elements_->global_index(); } + const Field& global_index() const { return hybrid_elements_->global_index(); } + Field& global_index() { return hybrid_elements_->global_index(); } - const Field& remote_index() const { return hybrid_elements_->remote_index(); } - Field& remote_index() { return hybrid_elements_->remote_index(); } + const Field& remote_index() const { return hybrid_elements_->remote_index(); } + Field& remote_index() { return hybrid_elements_->remote_index(); } - const Field& partition() const { return hybrid_elements_->partition(); } - Field& partition() { return hybrid_elements_->partition(); } + const Field& partition() const { return hybrid_elements_->partition(); } + Field& partition() { return hybrid_elements_->partition(); } - const Field& halo() const { return hybrid_elements_->halo(); } - Field& halo() { return hybrid_elements_->halo(); } + const Field& halo() const { return hybrid_elements_->halo(); } + Field& halo() { return hybrid_elements_->halo(); } - template - array::LocalView view( const Field& ) const; + template + array::LocalView view( const Field& ) const; - template - array::LocalView view( Field& ) const; + template + array::LocalView view( Field& ) const; - size_t add(const size_t nb_elements); + size_t add( const size_t nb_elements ); private: - - friend class HybridElements; - void rebuild(); + friend class HybridElements; + void rebuild(); private: - bool owns_; - HybridElements* hybrid_elements_; - size_t size_; - size_t begin_; - size_t end_; - size_t type_idx_; - size_t nb_nodes_; - size_t nb_edges_; + bool owns_; + HybridElements* hybrid_elements_; + size_t size_; + size_t begin_; + size_t end_; + size_t type_idx_; + size_t nb_nodes_; + size_t nb_edges_; }; // ------------------------------------------------------------------------------------------------------ -inline size_t Elements::size() const -{ - return size_; +inline size_t Elements::size() const { + return size_; } -inline size_t Elements::nb_nodes() const -{ - return nb_nodes_; +inline size_t Elements::nb_nodes() const { + return nb_nodes_; } -inline size_t Elements::nb_edges() const -{ - return nb_edges_; +inline size_t Elements::nb_edges() const { + return nb_edges_; } -//inline size_t Elements::type_idx() const +// inline size_t Elements::type_idx() const //{ // return type_idx_; //} -//inline const HybridElements& Elements::hybrid_elements() const +// inline const HybridElements& Elements::hybrid_elements() const //{ // return *hybrid_elements_; //} -inline const BlockConnectivity& Elements::node_connectivity() const -{ - if( hybrid_elements_->node_connectivity().blocks() ) { - return hybrid_elements_->node_connectivity().block(type_idx_); - } - else - { - static BlockConnectivity dummy; - return dummy; - } +inline const BlockConnectivity& Elements::node_connectivity() const { + if ( hybrid_elements_->node_connectivity().blocks() ) { + return hybrid_elements_->node_connectivity().block( type_idx_ ); + } + else { + static BlockConnectivity dummy; + return dummy; + } } -inline BlockConnectivity& Elements::node_connectivity() -{ - if( hybrid_elements_->node_connectivity().blocks() ) { - return hybrid_elements_->node_connectivity().block(type_idx_); - } - else - { - static BlockConnectivity dummy; - return dummy; - } +inline BlockConnectivity& Elements::node_connectivity() { + if ( hybrid_elements_->node_connectivity().blocks() ) { + return hybrid_elements_->node_connectivity().block( type_idx_ ); + } + else { + static BlockConnectivity dummy; + return dummy; + } } -inline const BlockConnectivity& Elements::edge_connectivity() const -{ - if( hybrid_elements_->edge_connectivity().blocks() ) { - return hybrid_elements_->edge_connectivity().block(type_idx_); - } - else - { - static BlockConnectivity dummy; - return dummy; - } +inline const BlockConnectivity& Elements::edge_connectivity() const { + if ( hybrid_elements_->edge_connectivity().blocks() ) { + return hybrid_elements_->edge_connectivity().block( type_idx_ ); + } + else { + static BlockConnectivity dummy; + return dummy; + } } -inline BlockConnectivity& Elements::edge_connectivity() -{ - if( hybrid_elements_->edge_connectivity().blocks() ) { - return hybrid_elements_->edge_connectivity().block(type_idx_); - } - else - { - static BlockConnectivity dummy; - return dummy; - } +inline BlockConnectivity& Elements::edge_connectivity() { + if ( hybrid_elements_->edge_connectivity().blocks() ) { + return hybrid_elements_->edge_connectivity().block( type_idx_ ); + } + else { + static BlockConnectivity dummy; + return dummy; + } } - -inline const BlockConnectivity& Elements::cell_connectivity() const -{ - if( hybrid_elements_->cell_connectivity().blocks() ) { - return hybrid_elements_->cell_connectivity().block(type_idx_); - } - else - { - static BlockConnectivity dummy; - return dummy; - } +inline const BlockConnectivity& Elements::cell_connectivity() const { + if ( hybrid_elements_->cell_connectivity().blocks() ) { + return hybrid_elements_->cell_connectivity().block( type_idx_ ); + } + else { + static BlockConnectivity dummy; + return dummy; + } } -inline BlockConnectivity& Elements::cell_connectivity() -{ - if( hybrid_elements_->cell_connectivity().blocks() ) { - return hybrid_elements_->cell_connectivity().block(type_idx_); - } - else - { - static BlockConnectivity dummy; - return dummy; - } +inline BlockConnectivity& Elements::cell_connectivity() { + if ( hybrid_elements_->cell_connectivity().blocks() ) { + return hybrid_elements_->cell_connectivity().block( type_idx_ ); + } + else { + static BlockConnectivity dummy; + return dummy; + } } - -inline const ElementType& Elements::element_type() const -{ - return hybrid_elements_->element_type(type_idx_); +inline const ElementType& Elements::element_type() const { + return hybrid_elements_->element_type( type_idx_ ); } -inline size_t Elements::begin() const -{ - return begin_; +inline size_t Elements::begin() const { + return begin_; } -inline size_t Elements::end() const -{ - return end_; +inline size_t Elements::end() const { + return end_; } // ------------------------------------------------------------------------------------------------------ -extern "C" -{ -void atlas__mesh__Elements__delete(Elements* This); -size_t atlas__mesh__Elements__size(const Elements* This); -size_t atlas__mesh__Elements__begin(const Elements* This); -size_t atlas__mesh__Elements__end(const Elements* This); -BlockConnectivity* atlas__mesh__Elements__node_connectivity(Elements* This); -BlockConnectivity* atlas__mesh__Elements__edge_connectivity(Elements* This); -BlockConnectivity* atlas__mesh__Elements__cell_connectivity(Elements* This); -int atlas__mesh__Elements__has_field(const Elements* This, char* name); -int atlas__mesh__Elements__nb_fields(const Elements* This); -field::FieldImpl* atlas__mesh__Elements__field_by_idx(Elements* This, size_t idx); -field::FieldImpl* atlas__mesh__Elements__field_by_name(Elements* This, char* name); -field::FieldImpl* atlas__mesh__Elements__global_index(Elements* This); -field::FieldImpl* atlas__mesh__Elements__remote_index(Elements* This); -field::FieldImpl* atlas__mesh__Elements__partition(Elements* This); -field::FieldImpl* atlas__mesh__Elements__halo(Elements* This); -const ElementType* atlas__mesh__Elements__element_type(const Elements* This); -void atlas__mesh__Elements__add(Elements* This, size_t nb_elements); +extern "C" { +void atlas__mesh__Elements__delete( Elements* This ); +size_t atlas__mesh__Elements__size( const Elements* This ); +size_t atlas__mesh__Elements__begin( const Elements* This ); +size_t atlas__mesh__Elements__end( const Elements* This ); +BlockConnectivity* atlas__mesh__Elements__node_connectivity( Elements* This ); +BlockConnectivity* atlas__mesh__Elements__edge_connectivity( Elements* This ); +BlockConnectivity* atlas__mesh__Elements__cell_connectivity( Elements* This ); +int atlas__mesh__Elements__has_field( const Elements* This, char* name ); +int atlas__mesh__Elements__nb_fields( const Elements* This ); +field::FieldImpl* atlas__mesh__Elements__field_by_idx( Elements* This, size_t idx ); +field::FieldImpl* atlas__mesh__Elements__field_by_name( Elements* This, char* name ); +field::FieldImpl* atlas__mesh__Elements__global_index( Elements* This ); +field::FieldImpl* atlas__mesh__Elements__remote_index( Elements* This ); +field::FieldImpl* atlas__mesh__Elements__partition( Elements* This ); +field::FieldImpl* atlas__mesh__Elements__halo( Elements* This ); +const ElementType* atlas__mesh__Elements__element_type( const Elements* This ); +void atlas__mesh__Elements__add( Elements* This, size_t nb_elements ); } //------------------------------------------------------------------------------------------------------ -} // namespace mesh -} // namespace atlas +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/Halo.cc b/src/atlas/mesh/Halo.cc index 5eb39b204..a2a9d86aa 100644 --- a/src/atlas/mesh/Halo.cc +++ b/src/atlas/mesh/Halo.cc @@ -4,36 +4,33 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "eckit/exception/Exceptions.h" #include "atlas/mesh/Halo.h" #include "atlas/mesh/Mesh.h" #include "atlas/util/Metadata.h" +#include "eckit/exception/Exceptions.h" namespace atlas { namespace mesh { -Halo::Halo(const Mesh& mesh) -{ - size_=0; - mesh.metadata().get("halo",size_); +Halo::Halo( const Mesh& mesh ) { + size_ = 0; + mesh.metadata().get( "halo", size_ ); } -Halo::Halo(const detail::MeshImpl& mesh) -{ - size_=0; - mesh.metadata().get("halo",size_); +Halo::Halo( const detail::MeshImpl& mesh ) { + size_ = 0; + mesh.metadata().get( "halo", size_ ); } long Halo::size() const { - ASSERT( size_>=0 ); - return size_; + ASSERT( size_ >= 0 ); + return size_; } - -} // namespace mesh -} // namespace atlas - +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/Halo.h b/src/atlas/mesh/Halo.h index d9f982bb4..0bba40af4 100644 --- a/src/atlas/mesh/Halo.h +++ b/src/atlas/mesh/Halo.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,30 +14,30 @@ #include namespace atlas { - class Mesh; +class Mesh; namespace mesh { namespace detail { - class MeshImpl; -} -} +class MeshImpl; } +} // namespace mesh +} // namespace atlas namespace atlas { namespace mesh { // ------------------------------------------------------------------- -class Halo -{ +class Halo { public: - Halo() {} - Halo(const Mesh& mesh); - Halo(const detail::MeshImpl& mesh); - Halo(const long size) : size_(size) {} - long size() const; + Halo() {} + Halo( const Mesh& mesh ); + Halo( const detail::MeshImpl& mesh ); + Halo( const long size ) : size_( size ) {} + long size() const; + private: - long size_{-1}; + long size_{-1}; }; -} // namespace mesh -} // namespace atlas +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/HybridElements.cc b/src/atlas/mesh/HybridElements.cc index 376964c9b..34fbefd4f 100644 --- a/src/atlas/mesh/HybridElements.cc +++ b/src/atlas/mesh/HybridElements.cc @@ -4,24 +4,23 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/mesh/HybridElements.h" #include -#include "eckit/memory/SharedPtr.h" -#include "atlas/library/config.h" +#include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" #include "atlas/library/config.h" #include "atlas/mesh/ElementType.h" -#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Elements.h" #include "atlas/mesh/Mesh.h" -#include "atlas/mesh/ElementType.h" -#include "atlas/field/Field.h" #include "atlas/runtime/ErrorHandling.h" -#include "eckit/log/Bytes.h" -#include "atlas/array/MakeView.h" #include "atlas/runtime/Log.h" +#include "eckit/log/Bytes.h" +#include "eckit/memory/SharedPtr.h" #ifdef ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 @@ -32,10 +31,10 @@ using atlas::array::ArrayView; using atlas::array::IndexView; -using atlas::array::make_view; -using atlas::array::make_indexview; using atlas::array::make_datatype; +using atlas::array::make_indexview; using atlas::array::make_shape; +using atlas::array::make_view; namespace atlas { namespace mesh { @@ -44,454 +43,382 @@ namespace mesh { namespace { -static void set_uninitialized_fields_to_zero( HybridElements& elems, size_t begin ) -{ - ArrayView global_index = make_view( elems.global_index() ); - IndexView remote_index = make_indexview( elems.remote_index() ); - ArrayView partition = make_view( elems.partition() ); - ArrayView halo = make_view( elems.halo() ); - ArrayView patch = make_view( elems.field("patch") ); - - for( size_t j=begin; j global_index = make_view( elems.global_index() ); + IndexView remote_index = make_indexview( elems.remote_index() ); + ArrayView partition = make_view( elems.partition() ); + ArrayView halo = make_view( elems.halo() ); + ArrayView patch = make_view( elems.field( "patch" ) ); + + for ( size_t j = begin; j < elems.size(); ++j ) { + global_index( j ) = 0; + remote_index( j ) = 0; + partition( j ) = 0; + halo( j ) = 0; + patch( j ) = 0; + } } +} // namespace //------------------------------------------------------------------------------------------------------ -HybridElements::HybridElements() : - size_(0), - elements_size_(), - elements_begin_(1,0ul), - type_idx_() -{ - add( Field("glb_idx", make_datatype(), make_shape(size())) ); - add( Field("remote_idx", make_datatype(), make_shape(size())) ); - add( Field("partition", make_datatype(), make_shape(size())) ); - add( Field("halo", make_datatype(), make_shape(size())) ); - add( Field("patch", make_datatype(), make_shape(size())) ); - set_uninitialized_fields_to_zero(*this, 0); - - node_connectivity_ = &add( new Connectivity("node") ); - edge_connectivity_ = &add( new Connectivity("edge") ); - cell_connectivity_ = &add( new Connectivity("cell") ); -} - -HybridElements::~HybridElements() -{ -} - -Field HybridElements::add( const Field& field ) -{ - ASSERT( field ); - ASSERT( ! field.name().empty() ); - - if( has_field(field.name()) ) { - std::stringstream msg; - msg << "Trying to add field '"<second; - array::ArrayShape shape = field.shape(); - shape[0] = size_; - field.resize(shape); - } - - set_uninitialized_fields_to_zero( *this, old_size ); - -} - -void HybridElements::remove_field(const std::string& name) -{ - if( ! has_field(name) ) - { - std::stringstream msg; - msg << "Trying to remove field `"<second; -} - -Field& HybridElements::field(const std::string& name) -{ - return const_cast(static_cast(this)->field(name)); -} - -const Field& HybridElements::field(size_t idx) const -{ - ASSERT(idx < nb_fields()); - size_t c(0); - for( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) - { - if( idx == c ) - { - const Field& field = it->second; - return field; +HybridElements::HybridElements() : size_( 0 ), elements_size_(), elements_begin_( 1, 0ul ), type_idx_() { + add( Field( "glb_idx", make_datatype(), make_shape( size() ) ) ); + add( Field( "remote_idx", make_datatype(), make_shape( size() ) ) ); + add( Field( "partition", make_datatype(), make_shape( size() ) ) ); + add( Field( "halo", make_datatype(), make_shape( size() ) ) ); + add( Field( "patch", make_datatype(), make_shape( size() ) ) ); + set_uninitialized_fields_to_zero( *this, 0 ); + + node_connectivity_ = &add( new Connectivity( "node" ) ); + edge_connectivity_ = &add( new Connectivity( "edge" ) ); + cell_connectivity_ = &add( new Connectivity( "cell" ) ); +} + +HybridElements::~HybridElements() {} + +Field HybridElements::add( const Field& field ) { + ASSERT( field ); + ASSERT( !field.name().empty() ); + + if ( has_field( field.name() ) ) { + std::stringstream msg; + msg << "Trying to add field '" << field.name() + << "' to HybridElements, but HybridElements already has a field with " + "this name."; + throw eckit::Exception( msg.str(), Here() ); + } + fields_[field.name()] = field; + return field; +} + +void HybridElements::resize( size_t size ) { + size_t old_size = size_; + size_ = size; + for ( FieldMap::iterator it = fields_.begin(); it != fields_.end(); ++it ) { + Field& field = it->second; + array::ArrayShape shape = field.shape(); + shape[0] = size_; + field.resize( shape ); + } + + set_uninitialized_fields_to_zero( *this, old_size ); +} + +void HybridElements::remove_field( const std::string& name ) { + if ( !has_field( name ) ) { + std::stringstream msg; + msg << "Trying to remove field `" << name << "' in Nodes, but no field with this name is present in Nodes."; + throw eckit::Exception( msg.str(), Here() ); } - c++; - } - throw eckit::SeriousBug("Should not be here!",Here()); + fields_.erase( name ); } -Field& HybridElements::field(size_t idx) -{ - return const_cast(static_cast(this)->field(idx)); +const Field& HybridElements::field( const std::string& name ) const { + if ( !has_field( name ) ) { + std::stringstream msg; + msg << "Trying to access field `" << name << "' in Nodes, but no field with this name is present in Nodes."; + throw eckit::Exception( msg.str(), Here() ); + } + return fields_.find( name )->second; } +Field& HybridElements::field( const std::string& name ) { + return const_cast( static_cast( this )->field( name ) ); +} -HybridElements::Connectivity& HybridElements::add( Connectivity *connectivity ) -{ - connectivities_[connectivity->name()] = connectivity; - return *connectivity; +const Field& HybridElements::field( size_t idx ) const { + ASSERT( idx < nb_fields() ); + size_t c( 0 ); + for ( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) { + if ( idx == c ) { + const Field& field = it->second; + return field; + } + c++; + } + throw eckit::SeriousBug( "Should not be here!", Here() ); } +Field& HybridElements::field( size_t idx ) { + return const_cast( static_cast( this )->field( idx ) ); +} -size_t HybridElements::add( const ElementType* element_type, size_t nb_elements, const std::vector &connectivity ) -{ - return add(element_type,nb_elements,connectivity.data()); +HybridElements::Connectivity& HybridElements::add( Connectivity* connectivity ) { + connectivities_[connectivity->name()] = connectivity; + return *connectivity; } -size_t HybridElements::add( const ElementType* element_type, size_t nb_elements, const idx_t connectivity[] ) -{ - return add(element_type,nb_elements,connectivity,false); +size_t HybridElements::add( const ElementType* element_type, size_t nb_elements, + const std::vector& connectivity ) { + return add( element_type, nb_elements, connectivity.data() ); } -size_t HybridElements::add( const ElementType* element_type, size_t nb_elements, const idx_t connectivity[], bool fortran_array ) -{ - eckit::SharedPtr etype ( element_type ); +size_t HybridElements::add( const ElementType* element_type, size_t nb_elements, const idx_t connectivity[] ) { + return add( element_type, nb_elements, connectivity, false ); +} - size_t old_size=size(); - size_t new_size = old_size+nb_elements; +size_t HybridElements::add( const ElementType* element_type, size_t nb_elements, const idx_t connectivity[], + bool fortran_array ) { + eckit::SharedPtr etype( element_type ); - size_t nb_nodes = etype->nb_nodes(); + size_t old_size = size(); + size_t new_size = old_size + nb_elements; - type_idx_.resize(new_size); + size_t nb_nodes = etype->nb_nodes(); - for( size_t e=old_size; erebuild(); - else elements_[t].reset( new Elements(*this,t) ); - } + elements_begin_.push_back( new_size ); + elements_size_.push_back( nb_elements ); -// for( size_t t=0; trebuild(); -// } -// element_types_.push_back( etype ); -// elements_.push_back( eckit::SharedPtr(new Elements(*this,type_idx_.back())) ); + element_types_.push_back( etype ); + elements_.resize( element_types_.size() ); + for ( size_t t = 0; t < nb_types(); ++t ) { + if ( elements_[t] ) + elements_[t]->rebuild(); + else + elements_[t].reset( new Elements( *this, t ) ); + } + // for( size_t t=0; trebuild(); + // } + // element_types_.push_back( etype ); + // elements_.push_back( eckit::SharedPtr(new + // Elements(*this,type_idx_.back())) ); - node_connectivity_->add(nb_elements,nb_nodes,connectivity,fortran_array); + node_connectivity_->add( nb_elements, nb_nodes, connectivity, fortran_array ); - resize( new_size ); - return element_types_.size()-1; + resize( new_size ); + return element_types_.size() - 1; } -size_t HybridElements::add( const ElementType* element_type, size_t nb_elements ) -{ - eckit::SharedPtr etype ( element_type ); +size_t HybridElements::add( const ElementType* element_type, size_t nb_elements ) { + eckit::SharedPtr etype( element_type ); - size_t old_size=size(); - size_t new_size = old_size+nb_elements; + size_t old_size = size(); + size_t new_size = old_size + nb_elements; - size_t nb_nodes = etype->nb_nodes(); + size_t nb_nodes = etype->nb_nodes(); - type_idx_.resize(new_size); + type_idx_.resize( new_size ); - for( size_t e=old_size; eadd(nb_elements,nb_nodes); - resize( new_size ); - return element_types_.size()-1; + node_connectivity_->add( nb_elements, nb_nodes ); + resize( new_size ); + return element_types_.size() - 1; } -size_t HybridElements::add( const Elements& elems ) -{ - bool fortran_array = true; - return add( &elems.element_type(), elems.size(), elems.node_connectivity().data(), fortran_array ); +size_t HybridElements::add( const Elements& elems ) { + bool fortran_array = true; + return add( &elems.element_type(), elems.size(), elems.node_connectivity().data(), fortran_array ); } - -const std::string& HybridElements::name(size_t elem_idx) const { return element_types_[type_idx_[elem_idx]]->name(); } - -size_t HybridElements::elemtype_nb_nodes(size_t elem_idx) const -{ - return element_type( type_idx(elem_idx) ).nb_nodes(); +const std::string& HybridElements::name( size_t elem_idx ) const { + return element_types_[type_idx_[elem_idx]]->name(); } -size_t HybridElements::elemtype_nb_edges(size_t elem_idx) const -{ - return element_type( type_idx(elem_idx) ).nb_edges(); +size_t HybridElements::elemtype_nb_nodes( size_t elem_idx ) const { + return element_type( type_idx( elem_idx ) ).nb_nodes(); } -void HybridElements::insert( size_t type_idx, size_t position, size_t nb_elements ) -{ - type_idx_.insert(type_idx_.begin()+position,nb_elements,type_idx); - elements_size_[type_idx] += nb_elements; - for( size_t jtype=type_idx+1; jtyperebuild(); - } - node_connectivity_->insert(position,nb_elements,element_types_[type_idx]->nb_nodes()); +size_t HybridElements::elemtype_nb_edges( size_t elem_idx ) const { + return element_type( type_idx( elem_idx ) ).nb_edges(); +} - size_+=nb_elements; - for( FieldMap::iterator it = fields_.begin(); it != fields_.end(); ++it ) - { - Field& field = it->second; - field.insert(position,nb_elements); - } +void HybridElements::insert( size_t type_idx, size_t position, size_t nb_elements ) { + type_idx_.insert( type_idx_.begin() + position, nb_elements, type_idx ); + elements_size_[type_idx] += nb_elements; + for ( size_t jtype = type_idx + 1; jtype < nb_types() + 1; ++jtype ) + elements_begin_[jtype] += nb_elements; + for ( size_t t = 0; t < nb_types(); ++t ) { + elements_[t]->rebuild(); + } + node_connectivity_->insert( position, nb_elements, element_types_[type_idx]->nb_nodes() ); + size_ += nb_elements; + for ( FieldMap::iterator it = fields_.begin(); it != fields_.end(); ++it ) { + Field& field = it->second; + field.insert( position, nb_elements ); + } } - //----------------------------------------------------------------------------- -void HybridElements::clear() -{ - resize(0); - for( ConnectivityMap::iterator it = connectivities_.begin(); it!=connectivities_.end(); ++it ) - { - it->second->clear(); - } - size_=0; - elements_size_.clear(); - elements_begin_.resize(1); - elements_begin_[0]=0; - element_types_.clear(); - type_idx_.clear(); - elements_.clear(); +void HybridElements::clear() { + resize( 0 ); + for ( ConnectivityMap::iterator it = connectivities_.begin(); it != connectivities_.end(); ++it ) { + it->second->clear(); + } + size_ = 0; + elements_size_.clear(); + elements_begin_.resize( 1 ); + elements_begin_[0] = 0; + element_types_.clear(); + type_idx_.clear(); + elements_.clear(); } //----------------------------------------------------------------------------- void HybridElements::cloneToDevice() const { - std::for_each(fields_.begin(), fields_.end(), [](const FieldMap::value_type& v){ v.second.cloneToDevice();}); - std::for_each(connectivities_.begin(), connectivities_.end(), [](const ConnectivityMap::value_type& v){ v.second->cloneToDevice();}); + std::for_each( fields_.begin(), fields_.end(), []( const FieldMap::value_type& v ) { v.second.cloneToDevice(); } ); + std::for_each( connectivities_.begin(), connectivities_.end(), + []( const ConnectivityMap::value_type& v ) { v.second->cloneToDevice(); } ); } void HybridElements::cloneFromDevice() const { - std::for_each(fields_.begin(), fields_.end(), [](const FieldMap::value_type& v){ v.second.cloneFromDevice();}); - std::for_each(connectivities_.begin(), connectivities_.end(), [](const ConnectivityMap::value_type& v){ v.second->cloneFromDevice();}); + std::for_each( fields_.begin(), fields_.end(), + []( const FieldMap::value_type& v ) { v.second.cloneFromDevice(); } ); + std::for_each( connectivities_.begin(), connectivities_.end(), + []( const ConnectivityMap::value_type& v ) { v.second->cloneFromDevice(); } ); } void HybridElements::syncHostDevice() const { - std::for_each(fields_.begin(), fields_.end(), [](const FieldMap::value_type& v){ v.second.syncHostDevice();}); - std::for_each(connectivities_.begin(), connectivities_.end(), [](const ConnectivityMap::value_type& v){ v.second->syncHostDevice();}); + std::for_each( fields_.begin(), fields_.end(), []( const FieldMap::value_type& v ) { v.second.syncHostDevice(); } ); + std::for_each( connectivities_.begin(), connectivities_.end(), + []( const ConnectivityMap::value_type& v ) { v.second->syncHostDevice(); } ); } - size_t HybridElements::footprint() const { - size_t size = sizeof(*this); - for( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) { - size += (*it).second.footprint(); - } - for( ConnectivityMap::const_iterator it = connectivities_.begin(); it != connectivities_.end(); ++it ) { - size += (*it).second->footprint(); - } - size += elements_size_.capacity() * sizeof(size_t); - size += elements_begin_.capacity() * sizeof(size_t); + size_t size = sizeof( *this ); + for ( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) { + size += ( *it ).second.footprint(); + } + for ( ConnectivityMap::const_iterator it = connectivities_.begin(); it != connectivities_.end(); ++it ) { + size += ( *it ).second->footprint(); + } + size += elements_size_.capacity() * sizeof( size_t ); + size += elements_begin_.capacity() * sizeof( size_t ); - size += metadata_.footprint(); + size += metadata_.footprint(); - return size; + return size; } //----------------------------------------------------------------------------- extern "C" { -HybridElements* atlas__mesh__HybridElements__create() -{ - HybridElements* This = 0; - ATLAS_ERROR_HANDLING( This = new HybridElements() ); - return This; +HybridElements* atlas__mesh__HybridElements__create() { + HybridElements* This = 0; + ATLAS_ERROR_HANDLING( This = new HybridElements() ); + return This; } -void atlas__mesh__HybridElements__delete(HybridElements* This) -{ - ATLAS_ERROR_HANDLING( delete This ); +void atlas__mesh__HybridElements__delete( HybridElements* This ) { + ATLAS_ERROR_HANDLING( delete This ); } -MultiBlockConnectivity* atlas__mesh__HybridElements__node_connectivity(HybridElements* This) -{ - MultiBlockConnectivity* connectivity(0); - ATLAS_ERROR_HANDLING( connectivity = &This->node_connectivity() ); - return connectivity; +MultiBlockConnectivity* atlas__mesh__HybridElements__node_connectivity( HybridElements* This ) { + MultiBlockConnectivity* connectivity( 0 ); + ATLAS_ERROR_HANDLING( connectivity = &This->node_connectivity() ); + return connectivity; } -MultiBlockConnectivity* atlas__mesh__HybridElements__edge_connectivity(HybridElements* This) -{ - MultiBlockConnectivity* connectivity(0); - ATLAS_ERROR_HANDLING( connectivity = &This->edge_connectivity() ); - return connectivity; +MultiBlockConnectivity* atlas__mesh__HybridElements__edge_connectivity( HybridElements* This ) { + MultiBlockConnectivity* connectivity( 0 ); + ATLAS_ERROR_HANDLING( connectivity = &This->edge_connectivity() ); + return connectivity; } -MultiBlockConnectivity* atlas__mesh__HybridElements__cell_connectivity(HybridElements* This) -{ - MultiBlockConnectivity* connectivity(0); - ATLAS_ERROR_HANDLING( connectivity = &This->cell_connectivity() ); - return connectivity; +MultiBlockConnectivity* atlas__mesh__HybridElements__cell_connectivity( HybridElements* This ) { + MultiBlockConnectivity* connectivity( 0 ); + ATLAS_ERROR_HANDLING( connectivity = &This->cell_connectivity() ); + return connectivity; } -size_t atlas__mesh__HybridElements__size(const HybridElements* This) -{ - return This->size(); +size_t atlas__mesh__HybridElements__size( const HybridElements* This ) { + return This->size(); } -void atlas__mesh__HybridElements__add_elements(HybridElements* This, ElementType* elementtype, size_t nb_elements) -{ - This->add(elementtype,nb_elements); +void atlas__mesh__HybridElements__add_elements( HybridElements* This, ElementType* elementtype, size_t nb_elements ) { + This->add( elementtype, nb_elements ); } -void atlas__mesh__HybridElements__add_elements_with_nodes(HybridElements*This, ElementType* elementtype, size_t nb_elements, int node_connectivity[], int fortran_array) -{ - This->add(elementtype,nb_elements,node_connectivity,fortran_array); +void atlas__mesh__HybridElements__add_elements_with_nodes( HybridElements* This, ElementType* elementtype, + size_t nb_elements, int node_connectivity[], + int fortran_array ) { + This->add( elementtype, nb_elements, node_connectivity, fortran_array ); } -int atlas__mesh__HybridElements__has_field(const HybridElements* This, char* name) -{ - ATLAS_ERROR_HANDLING( ASSERT(This!=0) ); - return This->has_field(std::string(name)); +int atlas__mesh__HybridElements__has_field( const HybridElements* This, char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->has_field( std::string( name ) ); } -int atlas__mesh__HybridElements__nb_fields(const HybridElements* This) -{ - ATLAS_ERROR_HANDLING( ASSERT(This!=0) ); - return This->nb_fields(); +int atlas__mesh__HybridElements__nb_fields( const HybridElements* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->nb_fields(); } -int atlas__mesh__HybridElements__nb_types(const HybridElements* This) -{ - ATLAS_ERROR_HANDLING( ASSERT(This!=0) ); - return This->nb_types(); +int atlas__mesh__HybridElements__nb_types( const HybridElements* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ) ); + return This->nb_types(); } -field::FieldImpl* atlas__mesh__HybridElements__field_by_idx(HybridElements* This, size_t idx) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->field(idx).get(); - ); - return field; +field::FieldImpl* atlas__mesh__HybridElements__field_by_idx( HybridElements* This, size_t idx ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->field( idx ).get(); ); + return field; } -field::FieldImpl* atlas__mesh__HybridElements__field_by_name(HybridElements* This, char* name) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->field(std::string(name)).get(); - ); - return field; +field::FieldImpl* atlas__mesh__HybridElements__field_by_name( HybridElements* This, char* name ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->field( std::string( name ) ).get(); ); + return field; } -field::FieldImpl* atlas__mesh__HybridElements__global_index(HybridElements* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->global_index().get(); - ); - return field; - +field::FieldImpl* atlas__mesh__HybridElements__global_index( HybridElements* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->global_index().get(); ); + return field; } -field::FieldImpl* atlas__mesh__HybridElements__remote_index(HybridElements* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->remote_index().get(); - ); - return field; +field::FieldImpl* atlas__mesh__HybridElements__remote_index( HybridElements* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->remote_index().get(); ); + return field; } -field::FieldImpl* atlas__mesh__HybridElements__partition(HybridElements* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->partition().get(); - ); - return field; +field::FieldImpl* atlas__mesh__HybridElements__partition( HybridElements* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->partition().get(); ); + return field; } -field::FieldImpl* atlas__mesh__HybridElements__halo(HybridElements* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->halo().get(); - ); - return field; +field::FieldImpl* atlas__mesh__HybridElements__halo( HybridElements* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->halo().get(); ); + return field; } -Elements* atlas__mesh__HybridElements__elements(HybridElements* This, size_t idx) -{ - Elements* elements(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - elements = &This->elements(idx); - ); - return elements; +Elements* atlas__mesh__HybridElements__elements( HybridElements* This, size_t idx ) { + Elements* elements( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); elements = &This->elements( idx ); ); + return elements; } -void atlas__mesh__HybridElements__add_field(HybridElements*This, field::FieldImpl* field) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - This->add(field); - ); +void atlas__mesh__HybridElements__add_field( HybridElements* This, field::FieldImpl* field ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); This->add( field ); ); } - - } //----------------------------------------------------------------------------- @@ -500,6 +427,3 @@ void atlas__mesh__HybridElements__add_field(HybridElements*This, field::FieldImp } // namespace atlas #undef FORTRAN_BASE - - - diff --git a/src/atlas/mesh/HybridElements.h b/src/atlas/mesh/HybridElements.h index 75c1d8f24..7b4f91af0 100644 --- a/src/atlas/mesh/HybridElements.h +++ b/src/atlas/mesh/HybridElements.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,17 +17,27 @@ #pragma once -#include "eckit/memory/Owned.h" -#include "eckit/memory/SharedPtr.h" -#include "atlas/mesh/Connectivity.h" #include "atlas/field/Field.h" +#include "atlas/mesh/Connectivity.h" #include "atlas/util/Metadata.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" -#include "atlas/field/detail/FieldImpl.h" // only included for Fortran interface +#include "atlas/field/detail/FieldImpl.h" // only included for Fortran interface -namespace atlas { class Mesh; } -namespace atlas { namespace mesh { class ElementType; } } -namespace atlas { namespace mesh { class Elements; } } +namespace atlas { +class Mesh; +} +namespace atlas { +namespace mesh { +class ElementType; +} +} // namespace atlas +namespace atlas { +namespace mesh { +class Elements; +} +} // namespace atlas namespace atlas { namespace mesh { @@ -35,264 +46,247 @@ namespace mesh { /// @brief HybridElements class that describes elements of different types class HybridElements : public eckit::Owned { -friend class Elements; -public: - typedef MultiBlockConnectivity Connectivity; + friend class Elements; -public: // methods - -//-- Constructors - - HybridElements(); - virtual ~HybridElements(); - -//-- Accessors +public: + typedef MultiBlockConnectivity Connectivity; - /// @brief Number of elements - size_t size() const; +public: // methods + //-- Constructors + HybridElements(); + virtual ~HybridElements(); - /// @brief Number of nodes for given element - size_t nb_nodes( size_t elem_idx ) const; + //-- Accessors - /// @brief Number of edges for given element - size_t nb_edges( size_t elem_idx ) const; + /// @brief Number of elements + size_t size() const; - /// @brief Element type index for given element - size_t type_idx( size_t elem_idx ) const; + /// @brief Number of nodes for given element + size_t nb_nodes( size_t elem_idx ) const; - /// @brief Element type name for given element - const std::string& name( size_t elem_idx ) const; + /// @brief Number of edges for given element + size_t nb_edges( size_t elem_idx ) const; - /// @brief Element to Node connectivity table - const HybridElements::Connectivity& node_connectivity() const; - HybridElements::Connectivity& node_connectivity(); + /// @brief Element type index for given element + size_t type_idx( size_t elem_idx ) const; - /// @brief Element to Edge connectivity table - const HybridElements::Connectivity& edge_connectivity() const; - HybridElements::Connectivity& edge_connectivity(); + /// @brief Element type name for given element + const std::string& name( size_t elem_idx ) const; - /// @brief Element to Cell connectivity table - const HybridElements::Connectivity& cell_connectivity() const; - HybridElements::Connectivity& cell_connectivity(); + /// @brief Element to Node connectivity table + const HybridElements::Connectivity& node_connectivity() const; + HybridElements::Connectivity& node_connectivity(); - /// @brief Number of types present in HybridElements - size_t nb_types() const; + /// @brief Element to Edge connectivity table + const HybridElements::Connectivity& edge_connectivity() const; + HybridElements::Connectivity& edge_connectivity(); - /// @brief The element_type description for given type - const ElementType& element_type( size_t type_idx ) const; + /// @brief Element to Cell connectivity table + const HybridElements::Connectivity& cell_connectivity() const; + HybridElements::Connectivity& cell_connectivity(); - /// @brief Sub-elements convenience class for given type - /// This allows optimized access to connectivities and loops. - const Elements& elements( size_t type_idx ) const; - Elements& elements( size_t type_idx ); - - const Field& field(const std::string& name) const; - Field& field(const std::string& name); - bool has_field(const std::string& name) const { return (fields_.find(name) != fields_.end()); } + /// @brief Number of types present in HybridElements + size_t nb_types() const; - const Field& field(size_t) const; - Field& field(size_t); - size_t nb_fields() const { return fields_.size(); } + /// @brief The element_type description for given type + const ElementType& element_type( size_t type_idx ) const; - const util::Metadata& metadata() const { return metadata_; } - util::Metadata& metadata() { return metadata_; } + /// @brief Sub-elements convenience class for given type + /// This allows optimized access to connectivities and loops. + const Elements& elements( size_t type_idx ) const; + Elements& elements( size_t type_idx ); - const Field& global_index() const { return field("glb_idx"); } - Field& global_index() { return field("glb_idx"); } + const Field& field( const std::string& name ) const; + Field& field( const std::string& name ); + bool has_field( const std::string& name ) const { return ( fields_.find( name ) != fields_.end() ); } - const Field& remote_index() const { return field("remote_idx"); } - Field& remote_index() { return field("remote_idx"); } + const Field& field( size_t ) const; + Field& field( size_t ); + size_t nb_fields() const { return fields_.size(); } - const Field& partition() const { return field("partition"); } - Field& partition() { return field("partition"); } + const util::Metadata& metadata() const { return metadata_; } + util::Metadata& metadata() { return metadata_; } - const Field& halo() const { return field("halo"); } - Field& halo() { return field("halo"); } + const Field& global_index() const { return field( "glb_idx" ); } + Field& global_index() { return field( "glb_idx" ); } -// -- Modifiers + const Field& remote_index() const { return field( "remote_idx" ); } + Field& remote_index() { return field( "remote_idx" ); } - /// @brief Add a new element type with given number of elements - /// @return type_idx of the added element type - size_t add( const ElementType*, size_t nb_elements ); + const Field& partition() const { return field( "partition" ); } + Field& partition() { return field( "partition" ); } - /// @brief Add a new element type with given number of elements and node-connectivity - /// @return type_idx of the added element type - size_t add( const ElementType*, size_t nb_elements, const std::vector &node_connectivity ); + const Field& halo() const { return field( "halo" ); } + Field& halo() { return field( "halo" ); } - /// @brief Add a new element type with given number of elements and node-connectivity - /// @return type_idx of the added element type - size_t add( const ElementType*, size_t nb_elements, const idx_t node_connectivity[] ); + // -- Modifiers - /// @brief Add a new element type with given number of elements and node-connectivity - /// @return type_idx of the added element type - size_t add( const ElementType*, size_t nb_elements, const idx_t node_connectivity[], bool fortran_array ); + /// @brief Add a new element type with given number of elements + /// @return type_idx of the added element type + size_t add( const ElementType*, size_t nb_elements ); - /// @brief Add a new element type from existing Elements. - /// Data will be copied. - /// @return type_idx of the added element type - size_t add( const Elements& ); - - Field add( const Field& field ); + /// @brief Add a new element type with given number of elements and + /// node-connectivity + /// @return type_idx of the added element type + size_t add( const ElementType*, size_t nb_elements, const std::vector& node_connectivity ); - void remove_field(const std::string& name); + /// @brief Add a new element type with given number of elements and + /// node-connectivity + /// @return type_idx of the added element type + size_t add( const ElementType*, size_t nb_elements, const idx_t node_connectivity[] ); - void insert( size_t type_idx, size_t position, size_t nb_elements = 1 ); + /// @brief Add a new element type with given number of elements and + /// node-connectivity + /// @return type_idx of the added element type + size_t add( const ElementType*, size_t nb_elements, const idx_t node_connectivity[], bool fortran_array ); - void cloneToDevice() const; + /// @brief Add a new element type from existing Elements. + /// Data will be copied. + /// @return type_idx of the added element type + size_t add( const Elements& ); - void cloneFromDevice() const; + Field add( const Field& field ); - void syncHostDevice() const; + void remove_field( const std::string& name ); + void insert( size_t type_idx, size_t position, size_t nb_elements = 1 ); - void clear(); + void cloneToDevice() const; - /// @brief Return the memory footprint of the elements - size_t footprint() const; + void cloneFromDevice() const; -private: // -- types + void syncHostDevice() const; - typedef std::map< std::string, Field > FieldMap; - typedef std::map< std::string, eckit::SharedPtr > ConnectivityMap; + void clear(); -private: // -- methods + /// @brief Return the memory footprint of the elements + size_t footprint() const; - void resize( size_t size ); +private: // -- types + typedef std::map FieldMap; + typedef std::map> ConnectivityMap; - size_t elemtype_nb_nodes(size_t elem_idx) const ; - size_t elemtype_nb_edges(size_t elem_idx) const ; +private: // -- methods + void resize( size_t size ); - Connectivity& add( Connectivity* ); - -private: // -- Data + size_t elemtype_nb_nodes( size_t elem_idx ) const; + size_t elemtype_nb_edges( size_t elem_idx ) const; -// -- Total number of elements - size_t size_; + Connectivity& add( Connectivity* ); -// -- Data: one value per type - std::vector elements_size_; - std::vector elements_begin_; - std::vector< eckit::SharedPtr > element_types_; +private: // -- Data + // -- Total number of elements + size_t size_; -// -- Data: one value per element - std::vector type_idx_; + // -- Data: one value per type + std::vector elements_size_; + std::vector elements_begin_; + std::vector> element_types_; -// -- Sub elements - std::vector< eckit::SharedPtr > elements_; + // -- Data: one value per element + std::vector type_idx_; -// -- Fields and connectivities - FieldMap fields_; - ConnectivityMap connectivities_; + // -- Sub elements + std::vector> elements_; -// -- Metadata - util::Metadata metadata_; + // -- Fields and connectivities + FieldMap fields_; + ConnectivityMap connectivities_; -// -- Cached shortcuts to specific connectivities in connectivities_ - Connectivity* node_connectivity_; - Connectivity* edge_connectivity_; - Connectivity* cell_connectivity_; + // -- Metadata + util::Metadata metadata_; + // -- Cached shortcuts to specific connectivities in connectivities_ + Connectivity* node_connectivity_; + Connectivity* edge_connectivity_; + Connectivity* cell_connectivity_; }; // ----------------------------------------------------------------------------------------------------- -inline size_t HybridElements::size() const -{ - return size_; +inline size_t HybridElements::size() const { + return size_; } -inline size_t HybridElements::nb_types() const -{ - return element_types_.size(); +inline size_t HybridElements::nb_types() const { + return element_types_.size(); } -inline const ElementType& HybridElements::element_type( size_t type_idx ) const -{ - return *element_types_[type_idx].get(); +inline const ElementType& HybridElements::element_type( size_t type_idx ) const { + return *element_types_[type_idx].get(); } -inline const HybridElements::Connectivity& HybridElements::node_connectivity() const -{ - return *node_connectivity_; +inline const HybridElements::Connectivity& HybridElements::node_connectivity() const { + return *node_connectivity_; } -inline HybridElements::Connectivity& HybridElements::node_connectivity() -{ - return *node_connectivity_; +inline HybridElements::Connectivity& HybridElements::node_connectivity() { + return *node_connectivity_; } -inline const HybridElements::Connectivity& HybridElements::edge_connectivity() const -{ - return *edge_connectivity_; +inline const HybridElements::Connectivity& HybridElements::edge_connectivity() const { + return *edge_connectivity_; } -inline HybridElements::Connectivity& HybridElements::edge_connectivity() -{ - return *edge_connectivity_; +inline HybridElements::Connectivity& HybridElements::edge_connectivity() { + return *edge_connectivity_; } -inline const HybridElements::Connectivity& HybridElements::cell_connectivity() const -{ - return *cell_connectivity_; +inline const HybridElements::Connectivity& HybridElements::cell_connectivity() const { + return *cell_connectivity_; } -inline HybridElements::Connectivity& HybridElements::cell_connectivity() -{ - return *cell_connectivity_; +inline HybridElements::Connectivity& HybridElements::cell_connectivity() { + return *cell_connectivity_; } - -inline const Elements& HybridElements::elements( size_t type_idx ) const -{ - return *elements_[type_idx].get(); +inline const Elements& HybridElements::elements( size_t type_idx ) const { + return *elements_[type_idx].get(); } -inline Elements& HybridElements::elements( size_t type_idx ) -{ - return *elements_[type_idx].get(); +inline Elements& HybridElements::elements( size_t type_idx ) { + return *elements_[type_idx].get(); } -inline size_t HybridElements::nb_nodes( size_t elem_idx ) const -{ - return node_connectivity_->rows() ? node_connectivity_->cols(elem_idx) : elemtype_nb_nodes(elem_idx); +inline size_t HybridElements::nb_nodes( size_t elem_idx ) const { + return node_connectivity_->rows() ? node_connectivity_->cols( elem_idx ) : elemtype_nb_nodes( elem_idx ); } -inline size_t HybridElements::nb_edges( size_t elem_idx ) const -{ - return edge_connectivity_->rows() ? edge_connectivity_->cols(elem_idx) : elemtype_nb_edges(elem_idx); +inline size_t HybridElements::nb_edges( size_t elem_idx ) const { + return edge_connectivity_->rows() ? edge_connectivity_->cols( elem_idx ) : elemtype_nb_edges( elem_idx ); } -inline size_t HybridElements::type_idx( size_t elem_idx ) const -{ - return type_idx_[elem_idx]; +inline size_t HybridElements::type_idx( size_t elem_idx ) const { + return type_idx_[elem_idx]; } // ------------------------------------------------------------------------------------------------------ -extern "C" -{ +extern "C" { HybridElements* atlas__mesh__HybridElements__create(); -void atlas__mesh__HybridElements__delete(HybridElements* This); -MultiBlockConnectivity* atlas__mesh__HybridElements__node_connectivity(HybridElements* This); -MultiBlockConnectivity* atlas__mesh__HybridElements__edge_connectivity(HybridElements* This); -MultiBlockConnectivity* atlas__mesh__HybridElements__cell_connectivity(HybridElements* This); - -size_t atlas__mesh__HybridElements__size(const HybridElements* This); -void atlas__mesh__HybridElements__add_elements(HybridElements* This, ElementType* elementtype, size_t nb_elements); -void atlas__mesh__HybridElements__add_elements_with_nodes(HybridElements* This, ElementType* elementtype, size_t nb_elements, int node_connectivity[], int fortran_array); -void atlas__mesh__HybridElements__add_field(HybridElements* This, field::FieldImpl* field); -int atlas__mesh__HybridElements__has_field(const HybridElements* This, char* name); -int atlas__mesh__HybridElements__nb_fields(const HybridElements* This); -int atlas__mesh__HybridElements__nb_types(const HybridElements* This); -field::FieldImpl* atlas__mesh__HybridElements__field_by_name(HybridElements* This, char* name); -field::FieldImpl* atlas__mesh__HybridElements__field_by_idx(HybridElements* This, size_t idx); -field::FieldImpl* atlas__mesh__HybridElements__global_index(HybridElements* This); -field::FieldImpl* atlas__mesh__HybridElements__remote_index(HybridElements* This); -field::FieldImpl* atlas__mesh__HybridElements__partition(HybridElements* This); -field::FieldImpl* atlas__mesh__HybridElements__halo(HybridElements* This); - -Elements* atlas__mesh__HybridElements__elements(HybridElements* This, size_t idx); +void atlas__mesh__HybridElements__delete( HybridElements* This ); +MultiBlockConnectivity* atlas__mesh__HybridElements__node_connectivity( HybridElements* This ); +MultiBlockConnectivity* atlas__mesh__HybridElements__edge_connectivity( HybridElements* This ); +MultiBlockConnectivity* atlas__mesh__HybridElements__cell_connectivity( HybridElements* This ); + +size_t atlas__mesh__HybridElements__size( const HybridElements* This ); +void atlas__mesh__HybridElements__add_elements( HybridElements* This, ElementType* elementtype, size_t nb_elements ); +void atlas__mesh__HybridElements__add_elements_with_nodes( HybridElements* This, ElementType* elementtype, + size_t nb_elements, int node_connectivity[], + int fortran_array ); +void atlas__mesh__HybridElements__add_field( HybridElements* This, field::FieldImpl* field ); +int atlas__mesh__HybridElements__has_field( const HybridElements* This, char* name ); +int atlas__mesh__HybridElements__nb_fields( const HybridElements* This ); +int atlas__mesh__HybridElements__nb_types( const HybridElements* This ); +field::FieldImpl* atlas__mesh__HybridElements__field_by_name( HybridElements* This, char* name ); +field::FieldImpl* atlas__mesh__HybridElements__field_by_idx( HybridElements* This, size_t idx ); +field::FieldImpl* atlas__mesh__HybridElements__global_index( HybridElements* This ); +field::FieldImpl* atlas__mesh__HybridElements__remote_index( HybridElements* This ); +field::FieldImpl* atlas__mesh__HybridElements__partition( HybridElements* This ); +field::FieldImpl* atlas__mesh__HybridElements__halo( HybridElements* This ); + +Elements* atlas__mesh__HybridElements__elements( HybridElements* This, size_t idx ); } -} // namespace mesh -} // namespace atlas +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/IsGhostNode.h b/src/atlas/mesh/IsGhostNode.h index 34482eae3..2520e0003 100644 --- a/src/atlas/mesh/IsGhostNode.h +++ b/src/atlas/mesh/IsGhostNode.h @@ -4,38 +4,34 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "atlas/mesh/Nodes.h" -#include "atlas/field/Field.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" +#include "atlas/mesh/Nodes.h" #include "atlas/parallel/mpi/mpi.h" namespace atlas { namespace mesh { -class IsGhostNode -{ +class IsGhostNode { public: - IsGhostNode( const mesh::Nodes& nodes ) : - flags_( array::make_view (nodes.field("flags")) ), - ghost_( array::make_view (nodes.ghost()) ) - { - } + IsGhostNode( const mesh::Nodes& nodes ) : + flags_( array::make_view( nodes.field( "flags" ) ) ), + ghost_( array::make_view( nodes.ghost() ) ) {} + + bool operator()( size_t idx ) const { return Nodes::Topology::check( flags_( idx ), Nodes::Topology::GHOST ); } - bool operator()(size_t idx) const - { - return Nodes::Topology::check(flags_(idx),Nodes::Topology::GHOST); - } private: - array::ArrayView flags_; - array::ArrayView ghost_; + array::ArrayView flags_; + array::ArrayView ghost_; }; -} // namespace mesh -} // namespace atlas +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/Mesh.cc b/src/atlas/mesh/Mesh.cc index 4f4d33ab5..ba7394c1b 100644 --- a/src/atlas/mesh/Mesh.cc +++ b/src/atlas/mesh/Mesh.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,22 +15,14 @@ namespace atlas { //---------------------------------------------------------------------------------------------------------------------- -Mesh::Mesh() : - impl_( new Implementation() ) { -} +Mesh::Mesh() : impl_( new Implementation() ) {} -Mesh::Mesh( const Mesh& mesh ) : - impl_( mesh.impl_ ) { -} +Mesh::Mesh( const Mesh& mesh ) : impl_( mesh.impl_ ) {} -Mesh::Mesh( const Implementation* impl ) : - impl_( const_cast(impl) ) { -} +Mesh::Mesh( const Implementation* impl ) : impl_( const_cast( impl ) ) {} -Mesh::Mesh( eckit::Stream& stream ) : - impl_( new Implementation(stream) ) { -} +Mesh::Mesh( eckit::Stream& stream ) : impl_( new Implementation( stream ) ) {} //---------------------------------------------------------------------------------------------------------------------- -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/mesh/Mesh.h b/src/atlas/mesh/Mesh.h index f9cf12563..d47038073 100644 --- a/src/atlas/mesh/Mesh.h +++ b/src/atlas/mesh/Mesh.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,33 +13,36 @@ #include -#include "eckit/memory/SharedPtr.h" #include "atlas/mesh/detail/MeshImpl.h" +#include "eckit/memory/SharedPtr.h" //---------------------------------------------------------------------------------------------------------------------- // Forward declarations namespace atlas { - class Projection; +class Projection; } namespace atlas { namespace util { - class Metadata; -} } +class Metadata; +} +} // namespace atlas namespace atlas { namespace mesh { - class Nodes; - class HybridElements; - typedef HybridElements Edges; - typedef HybridElements Cells; -} } +class Nodes; +class HybridElements; +typedef HybridElements Edges; +typedef HybridElements Cells; +} // namespace mesh +} // namespace atlas namespace atlas { namespace meshgenerator { - class MeshGeneratorImpl; -} } +class MeshGeneratorImpl; +} +} // namespace atlas //---------------------------------------------------------------------------------------------------------------------- @@ -47,51 +51,51 @@ namespace atlas { //---------------------------------------------------------------------------------------------------------------------- class Mesh { - public: - using Implementation = mesh::detail::MeshImpl; - using Nodes = mesh::Nodes; - using Cells = mesh::Cells; - using Edges = mesh::Edges; + using Nodes = mesh::Nodes; + using Cells = mesh::Cells; + using Edges = mesh::Edges; using HybridElements = mesh::HybridElements; using PartitionGraph = mesh::detail::PartitionGraph; - using Polygon = mesh::PartitionPolygon; + using Polygon = mesh::PartitionPolygon; public: - Mesh(); Mesh( const Mesh& ); Mesh( const Implementation* ); /// @brief Construct a mesh from a Stream (serialization) - explicit Mesh(eckit::Stream&); + explicit Mesh( eckit::Stream& ); /// @brief Serialization to Stream - void encode(eckit::Stream& s) const { return impl_->encode(s); } + void encode( eckit::Stream& s ) const { return impl_->encode( s ); } - void print(std::ostream& out) const { impl_->print(out); } + void print( std::ostream& out ) const { impl_->print( out ); } const util::Metadata& metadata() const { return impl_->metadata(); } - util::Metadata& metadata() { return impl_->metadata(); } + util::Metadata& metadata() { return impl_->metadata(); } const Nodes& nodes() const { return impl_->nodes(); } - Nodes& nodes() { return impl_->nodes(); } + Nodes& nodes() { return impl_->nodes(); } const Cells& cells() const { return impl_->cells(); } - Cells& cells() { return impl_->cells();; } + Cells& cells() { + return impl_->cells(); + ; + } const Edges& edges() const { return impl_->edges(); } - Edges& edges() { return impl_->edges(); } + Edges& edges() { return impl_->edges(); } const HybridElements& facets() const { return impl_->facets(); } - HybridElements& facets() { return impl_->facets(); } + HybridElements& facets() { return impl_->facets(); } const HybridElements& ridges() const { return impl_->ridges(); } - HybridElements& ridges() { return impl_->ridges(); } + HybridElements& ridges() { return impl_->ridges(); } const HybridElements& peaks() const { return impl_->peaks(); } - HybridElements& peaks() { return impl_->peaks(); } + HybridElements& peaks() { return impl_->peaks(); } bool generated() const { return impl_->generated(); } @@ -115,31 +119,28 @@ class Mesh { PartitionGraph::Neighbours nearestNeighbourPartitions() const { return impl_->nearestNeighbourPartitions(); } const Implementation* get() const { return impl_.get(); } - Implementation* get() { return impl_.get(); } + Implementation* get() { return impl_.get(); } - const Polygon& polygon( size_t halo = 0) const { return impl_->polygon(halo); } + const Polygon& polygon( size_t halo = 0 ) const { return impl_->polygon( halo ); } const Grid& grid() const { return impl_->grid(); } operator bool() const { return impl_; } private: // methods - - friend std::ostream& operator<<(std::ostream& s, const Mesh& p) { - p.print(s); + friend std::ostream& operator<<( std::ostream& s, const Mesh& p ) { + p.print( s ); return s; } friend class meshgenerator::MeshGeneratorImpl; - void setProjection(const Projection& p) { impl_->setProjection(p); } - void setGrid(const Grid& p) { impl_->setGrid(p); } + void setProjection( const Projection& p ) { impl_->setProjection( p ); } + void setGrid( const Grid& p ) { impl_->setGrid( p ); } private: - eckit::SharedPtr impl_; - }; //---------------------------------------------------------------------------------------------------------------------- -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/mesh/Nodes.cc b/src/atlas/mesh/Nodes.cc index eb0792e1a..de4d67dea 100644 --- a/src/atlas/mesh/Nodes.cc +++ b/src/atlas/mesh/Nodes.cc @@ -4,17 +4,18 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/array/MakeView.h" #include "atlas/mesh/Nodes.h" +#include "atlas/array/MakeView.h" #include "atlas/field/Field.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/runtime/ErrorHandling.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" +#include "atlas/util/CoordinateEnums.h" using atlas::array::make_datatype; using atlas::array::make_shape; @@ -24,395 +25,293 @@ namespace mesh { //------------------------------------------------------------------------------------------------------ -Nodes::Nodes(): size_(0) -{ - global_index_ = add( Field("glb_idx", make_datatype(), make_shape(size())) ); - remote_index_ = add( Field("remote_idx", make_datatype(), make_shape(size())) ); - partition_ = add( Field("partition", make_datatype(), make_shape(size())) ); - xy_ = add( Field("xy", make_datatype(), make_shape(size(),2)) ); - xy_.set_variables(2); - lonlat_ = add( Field("lonlat", make_datatype(), make_shape(size(),2)) ); - lonlat_.set_variables(2); - ghost_ = add( Field("ghost", make_datatype(), make_shape(size())) ); - - edge_connectivity_ = &add( new Connectivity("edge") ); - cell_connectivity_ = &add( new Connectivity("cell") ); - - - add( Field("flags", make_datatype(), make_shape(size())) ); - - array::ArrayView glb_idx = array::make_view( global_index() ); - array::ArrayView part = array::make_view( partition() ); - array::ArrayView flags = array::make_view( field("flags") ); - - for(size_t n=0; nname()] = connectivity; - return *connectivity; -} - -Field Nodes::add( const Field& field ) -{ - ASSERT( field ); - ASSERT( ! field.name().empty() ); - - if( has_field(field.name()) ) { - std::stringstream msg; - msg << "Trying to add field '"<second; -} - -Field& Nodes::field(const std::string& name) -{ - return const_cast(static_cast(this)->field(name)); -} - -void Nodes::resize( size_t size ) -{ - size_t previous_size = size_; - size_ = size; - for( FieldMap::iterator it = fields_.begin(); it != fields_.end(); ++it ) - { - Field& field = it->second; - array::ArrayShape shape = field.shape(); - shape[0] = size_; - field.resize(shape); - } - - array::ArrayView glb_idx = array::make_view( global_index() ); - array::ArrayView part = array::make_view( partition() ); - array::ArrayView flags = array::make_view( field("flags") ); - - const int mpi_rank = mpi::comm().rank(); - for(size_t n=previous_size; nsecond; - return field; +Nodes::Nodes() : size_( 0 ) { + global_index_ = add( Field( "glb_idx", make_datatype(), make_shape( size() ) ) ); + remote_index_ = add( Field( "remote_idx", make_datatype(), make_shape( size() ) ) ); + partition_ = add( Field( "partition", make_datatype(), make_shape( size() ) ) ); + xy_ = add( Field( "xy", make_datatype(), make_shape( size(), 2 ) ) ); + xy_.set_variables( 2 ); + lonlat_ = add( Field( "lonlat", make_datatype(), make_shape( size(), 2 ) ) ); + lonlat_.set_variables( 2 ); + ghost_ = add( Field( "ghost", make_datatype(), make_shape( size() ) ) ); + + edge_connectivity_ = &add( new Connectivity( "edge" ) ); + cell_connectivity_ = &add( new Connectivity( "cell" ) ); + + add( Field( "flags", make_datatype(), make_shape( size() ) ) ); + + array::ArrayView glb_idx = array::make_view( global_index() ); + array::ArrayView part = array::make_view( partition() ); + array::ArrayView flags = array::make_view( field( "flags" ) ); + + for ( size_t n = 0; n < size(); ++n ) { + glb_idx( n ) = 1 + n; + part( n ) = mpi::comm().rank(); + flags( n ) = 0; + } +} + +Nodes::Connectivity& Nodes::add( Connectivity* connectivity ) { + connectivities_[connectivity->name()] = connectivity; + return *connectivity; +} + +Field Nodes::add( const Field& field ) { + ASSERT( field ); + ASSERT( !field.name().empty() ); + + if ( has_field( field.name() ) ) { + std::stringstream msg; + msg << "Trying to add field '" << field.name() << "' to Nodes, but Nodes already has a field with this name."; + throw eckit::Exception( msg.str(), Here() ); + } + fields_[field.name()] = field; + return field; +} + +void Nodes::remove_field( const std::string& name ) { + if ( !has_field( name ) ) { + std::stringstream msg; + msg << "Trying to remove field `" << name << "' in Nodes, but no field with this name is present in Nodes."; + throw eckit::Exception( msg.str(), Here() ); } - c++; - } - eckit::SeriousBug("Should not be here!",Here()); - static Field f; - return f; + fields_.erase( name ); } -Field& Nodes::field(size_t idx) -{ - return const_cast(static_cast(this)->field(idx)); + +const Field& Nodes::field( const std::string& name ) const { + if ( !has_field( name ) ) { + std::stringstream msg; + msg << "Trying to access field `" << name << "' in Nodes, but no field with this name is present in Nodes."; + throw eckit::Exception( msg.str(), Here() ); + } + return fields_.find( name )->second; } -void Nodes::print(std::ostream& os) const -{ +Field& Nodes::field( const std::string& name ) { + return const_cast( static_cast( this )->field( name ) ); +} + +void Nodes::resize( size_t size ) { + size_t previous_size = size_; + size_ = size; + for ( FieldMap::iterator it = fields_.begin(); it != fields_.end(); ++it ) { + Field& field = it->second; + array::ArrayShape shape = field.shape(); + shape[0] = size_; + field.resize( shape ); + } + + array::ArrayView glb_idx = array::make_view( global_index() ); + array::ArrayView part = array::make_view( partition() ); + array::ArrayView flags = array::make_view( field( "flags" ) ); + + const int mpi_rank = mpi::comm().rank(); + for ( size_t n = previous_size; n < size_; ++n ) { + glb_idx( n ) = 1 + n; + part( n ) = mpi_rank; + ; + flags( n ) = 0; + } +} + +const Field& Nodes::field( size_t idx ) const { + ASSERT( idx < nb_fields() ); + size_t c( 0 ); + for ( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) { + if ( idx == c ) { + const Field& field = it->second; + return field; + } + c++; + } + eckit::SeriousBug( "Should not be here!", Here() ); + static Field f; + return f; +} +Field& Nodes::field( size_t idx ) { + return const_cast( static_cast( this )->field( idx ) ); +} + +void Nodes::print( std::ostream& os ) const { os << "Nodes[\n"; os << "\t size=" << size() << ",\n"; os << "\t fields=\n"; - for(size_t i = 0; i < nb_fields(); ++i) - { - os << "\t\t" << field(i); - if( i != nb_fields()-1 ) - os << ","; + for ( size_t i = 0; i < nb_fields(); ++i ) { + os << "\t\t" << field( i ); + if ( i != nb_fields() - 1 ) os << ","; os << "\n"; } os << "]"; } - size_t Nodes::footprint() const { - size_t size = sizeof(*this); - for( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) { - size += (*it).second.footprint(); - } - for( ConnectivityMap::const_iterator it = connectivities_.begin(); it != connectivities_.end(); ++it ) { - size += (*it).second->footprint(); - } - size += metadata_.footprint(); - return size; -} - - -const IrregularConnectivity& Nodes::connectivity(const std::string& name) const -{ - if( (connectivities_.find(name) == connectivities_.end()) ) - { - std::stringstream msg; - msg << "Trying to access connectivity `"<second; -} -IrregularConnectivity& Nodes::connectivity(const std::string& name) -{ - if( (connectivities_.find(name) == connectivities_.end()) ) - { - std::stringstream msg; - msg << "Trying to access connectivity `"<second; + size_t size = sizeof( *this ); + for ( FieldMap::const_iterator it = fields_.begin(); it != fields_.end(); ++it ) { + size += ( *it ).second.footprint(); + } + for ( ConnectivityMap::const_iterator it = connectivities_.begin(); it != connectivities_.end(); ++it ) { + size += ( *it ).second->footprint(); + } + size += metadata_.footprint(); + return size; +} + +const IrregularConnectivity& Nodes::connectivity( const std::string& name ) const { + if ( ( connectivities_.find( name ) == connectivities_.end() ) ) { + std::stringstream msg; + msg << "Trying to access connectivity `" << name + << "' in Nodes, but no connectivity with this name is present in " + "Nodes."; + throw eckit::Exception( msg.str(), Here() ); + } + return *connectivities_.find( name )->second; +} +IrregularConnectivity& Nodes::connectivity( const std::string& name ) { + if ( ( connectivities_.find( name ) == connectivities_.end() ) ) { + std::stringstream msg; + msg << "Trying to access connectivity `" << name + << "' in Nodes, but no connectivity with this name is present in " + "Nodes."; + throw eckit::Exception( msg.str(), Here() ); + } + return *connectivities_.find( name )->second; } void Nodes::cloneToDevice() const { - std::for_each(fields_.begin(), fields_.end(), [](const FieldMap::value_type& v){ v.second.cloneToDevice();}); - std::for_each(connectivities_.begin(), connectivities_.end(), [](const ConnectivityMap::value_type& v){ v.second->cloneToDevice();}); + std::for_each( fields_.begin(), fields_.end(), []( const FieldMap::value_type& v ) { v.second.cloneToDevice(); } ); + std::for_each( connectivities_.begin(), connectivities_.end(), + []( const ConnectivityMap::value_type& v ) { v.second->cloneToDevice(); } ); } void Nodes::cloneFromDevice() const { - std::for_each(fields_.begin(), fields_.end(), [](const FieldMap::value_type& v){ v.second.cloneFromDevice();}); - std::for_each(connectivities_.begin(), connectivities_.end(), [](const ConnectivityMap::value_type& v){ v.second->cloneFromDevice();}); + std::for_each( fields_.begin(), fields_.end(), + []( const FieldMap::value_type& v ) { v.second.cloneFromDevice(); } ); + std::for_each( connectivities_.begin(), connectivities_.end(), + []( const ConnectivityMap::value_type& v ) { v.second->cloneFromDevice(); } ); } void Nodes::syncHostDevice() const { - std::for_each(fields_.begin(), fields_.end(), [](const FieldMap::value_type& v){ v.second.syncHostDevice();}); - std::for_each(connectivities_.begin(), connectivities_.end(), [](const ConnectivityMap::value_type& v){ v.second->syncHostDevice();}); + std::for_each( fields_.begin(), fields_.end(), []( const FieldMap::value_type& v ) { v.second.syncHostDevice(); } ); + std::for_each( connectivities_.begin(), connectivities_.end(), + []( const ConnectivityMap::value_type& v ) { v.second->syncHostDevice(); } ); } //----------------------------------------------------------------------------- extern "C" { -Nodes* atlas__mesh__Nodes__create() -{ - Nodes* nodes(0); - ATLAS_ERROR_HANDLING( nodes = new Nodes() ); - return nodes; -} - -void atlas__mesh__Nodes__delete (Nodes* This) -{ - ATLAS_ERROR_HANDLING( delete This ); -} - - -size_t atlas__mesh__Nodes__size (Nodes* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->size(); - ); - return 0; -} -void atlas__mesh__Nodes__resize (Nodes* This, size_t size) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - This->resize(size); - ); -} -size_t atlas__mesh__Nodes__nb_fields (Nodes* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->nb_fields(); - ); - return 0; -} - -void atlas__mesh__Nodes__add_field (Nodes* This, field::FieldImpl* field) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(field); - This->add(field); - ); -} - -void atlas__mesh__Nodes__remove_field (Nodes* This, char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - This->remove_field(std::string(name)); - ); -} - -int atlas__mesh__Nodes__has_field (Nodes* This, char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->has_field(std::string(name)); - ); - return 0; -} - -field::FieldImpl* atlas__mesh__Nodes__field_by_name (Nodes* This, char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->field(std::string(name)).get(); - ); - return 0; -} - -field::FieldImpl* atlas__mesh__Nodes__field_by_idx (Nodes* This, size_t idx) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return This->field(idx).get(); - ); - return 0; -} - -util::Metadata* atlas__mesh__Nodes__metadata(Nodes* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return &This->metadata(); - ); - return 0; -} - -void atlas__mesh__Nodes__str (Nodes* This, char* &str, int &size) -{ - ATLAS_ERROR_HANDLING( - std::stringstream ss; - ss << *This; - std::string s = ss.str(); - size = s.size(); - str = new char[size+1]; - strcpy(str,s.c_str()); - ); -} - -IrregularConnectivity* atlas__mesh__Nodes__edge_connectivity(Nodes* This) -{ - IrregularConnectivity* connectivity(0); - ATLAS_ERROR_HANDLING( connectivity = &This->edge_connectivity() ); - return connectivity; -} - -IrregularConnectivity* atlas__mesh__Nodes__cell_connectivity(Nodes* This) -{ - IrregularConnectivity* connectivity(0); - ATLAS_ERROR_HANDLING( connectivity = &This->cell_connectivity() ); - return connectivity; -} - -IrregularConnectivity* atlas__mesh__Nodes__connectivity (Nodes* This, char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return &This->connectivity(std::string(name)); - ); - return 0; -} - - -void atlas__mesh__Nodes__add_connectivity (Nodes* This, IrregularConnectivity* connectivity) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(connectivity); - This->add(connectivity); - ); -} - -field::FieldImpl* atlas__mesh__Nodes__xy(Nodes* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->xy().get(); - ); - return field; -} - -field::FieldImpl* atlas__mesh__Nodes__lonlat(Nodes* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->lonlat().get(); - ); - return field; -} - -field::FieldImpl* atlas__mesh__Nodes__global_index(Nodes* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->global_index().get(); - ); - return field; -} - -field::FieldImpl* atlas__mesh__Nodes__remote_index(Nodes* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->remote_index().get(); - ); - return field; -} - -field::FieldImpl* atlas__mesh__Nodes__partition(Nodes* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->partition().get(); - ); - return field; -} - -field::FieldImpl* atlas__mesh__Nodes__ghost(Nodes* This) -{ - field::FieldImpl* field(0); - ATLAS_ERROR_HANDLING( - ASSERT(This!=0); - field = This->ghost().get(); - ); - return field; +Nodes* atlas__mesh__Nodes__create() { + Nodes* nodes( 0 ); + ATLAS_ERROR_HANDLING( nodes = new Nodes() ); + return nodes; +} + +void atlas__mesh__Nodes__delete( Nodes* This ) { + ATLAS_ERROR_HANDLING( delete This ); +} + +size_t atlas__mesh__Nodes__size( Nodes* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->size(); ); + return 0; +} +void atlas__mesh__Nodes__resize( Nodes* This, size_t size ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); This->resize( size ); ); +} +size_t atlas__mesh__Nodes__nb_fields( Nodes* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->nb_fields(); ); + return 0; +} + +void atlas__mesh__Nodes__add_field( Nodes* This, field::FieldImpl* field ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( field ); This->add( field ); ); +} + +void atlas__mesh__Nodes__remove_field( Nodes* This, char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); This->remove_field( std::string( name ) ); ); +} + +int atlas__mesh__Nodes__has_field( Nodes* This, char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->has_field( std::string( name ) ); ); + return 0; +} + +field::FieldImpl* atlas__mesh__Nodes__field_by_name( Nodes* This, char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->field( std::string( name ) ).get(); ); + return 0; +} + +field::FieldImpl* atlas__mesh__Nodes__field_by_idx( Nodes* This, size_t idx ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->field( idx ).get(); ); + return 0; +} + +util::Metadata* atlas__mesh__Nodes__metadata( Nodes* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->metadata(); ); + return 0; +} + +void atlas__mesh__Nodes__str( Nodes* This, char*& str, int& size ) { + ATLAS_ERROR_HANDLING( std::stringstream ss; ss << *This; std::string s = ss.str(); size = s.size(); + str = new char[size + 1]; strcpy( str, s.c_str() ); ); +} + +IrregularConnectivity* atlas__mesh__Nodes__edge_connectivity( Nodes* This ) { + IrregularConnectivity* connectivity( 0 ); + ATLAS_ERROR_HANDLING( connectivity = &This->edge_connectivity() ); + return connectivity; +} + +IrregularConnectivity* atlas__mesh__Nodes__cell_connectivity( Nodes* This ) { + IrregularConnectivity* connectivity( 0 ); + ATLAS_ERROR_HANDLING( connectivity = &This->cell_connectivity() ); + return connectivity; +} + +IrregularConnectivity* atlas__mesh__Nodes__connectivity( Nodes* This, char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->connectivity( std::string( name ) ); ); + return 0; +} + +void atlas__mesh__Nodes__add_connectivity( Nodes* This, IrregularConnectivity* connectivity ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( connectivity ); This->add( connectivity ); ); +} + +field::FieldImpl* atlas__mesh__Nodes__xy( Nodes* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->xy().get(); ); + return field; +} + +field::FieldImpl* atlas__mesh__Nodes__lonlat( Nodes* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->lonlat().get(); ); + return field; +} + +field::FieldImpl* atlas__mesh__Nodes__global_index( Nodes* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->global_index().get(); ); + return field; +} + +field::FieldImpl* atlas__mesh__Nodes__remote_index( Nodes* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->remote_index().get(); ); + return field; +} + +field::FieldImpl* atlas__mesh__Nodes__partition( Nodes* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->partition().get(); ); + return field; +} + +field::FieldImpl* atlas__mesh__Nodes__ghost( Nodes* This ) { + field::FieldImpl* field( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This != 0 ); field = This->ghost().get(); ); + return field; } } } // namespace mesh } // namespace atlas - diff --git a/src/atlas/mesh/Nodes.h b/src/atlas/mesh/Nodes.h index 26ecb6655..4bfe2daa9 100644 --- a/src/atlas/mesh/Nodes.h +++ b/src/atlas/mesh/Nodes.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,196 +16,185 @@ #include #include +#include "atlas/field/Field.h" +#include "atlas/mesh/Connectivity.h" +#include "atlas/util/Bitflags.h" +#include "atlas/util/Metadata.h" #include "eckit/exception/Exceptions.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" -#include "atlas/mesh/Connectivity.h" -#include "atlas/field/Field.h" -#include "atlas/util/Metadata.h" -#include "atlas/util/Bitflags.h" namespace atlas { namespace mesh { /** - * \brief Nodes class that owns a collection of fields defined in nodes of the mesh + * \brief Nodes class that owns a collection of fields defined in nodes of the + * mesh */ class Nodes : public eckit::Owned { public: - typedef IrregularConnectivity Connectivity; - - class Topology : public util::Bitflags - { - public: - enum { - NONE = 0, - GHOST = (1<<1), - PERIODIC = (1<<2), - BC = (1<<3), - WEST = (1<<4), - EAST = (1<<5), - NORTH = (1<<6), - SOUTH = (1<<7) + typedef IrregularConnectivity Connectivity; + + class Topology : public util::Bitflags { + public: + enum + { + NONE = 0, + GHOST = ( 1 << 1 ), + PERIODIC = ( 1 << 2 ), + BC = ( 1 << 3 ), + WEST = ( 1 << 4 ), + EAST = ( 1 << 5 ), + NORTH = ( 1 << 6 ), + SOUTH = ( 1 << 7 ) + }; }; - }; - -public: // methods -//-- Constructors +public: // methods + //-- Constructors + /// @brief Construct "size" nodes + Nodes(); + // Nodes(size_t size); - /// @brief Construct "size" nodes - Nodes(); -// Nodes(size_t size); + //-- Accessors -//-- Accessors + const Field& field( const std::string& name ) const; + Field& field( const std::string& name ); + bool has_field( const std::string& name ) const { return ( fields_.find( name ) != fields_.end() ); } - const Field& field(const std::string& name) const; - Field& field(const std::string& name); - bool has_field(const std::string& name) const { return (fields_.find(name) != fields_.end()); } + const Field& field( size_t ) const; + Field& field( size_t ); + size_t nb_fields() const { return fields_.size(); } - const Field& field(size_t) const; - Field& field(size_t); - size_t nb_fields() const { return fields_.size(); } + const util::Metadata& metadata() const { return metadata_; } + util::Metadata& metadata() { return metadata_; } - const util::Metadata& metadata() const { return metadata_; } - util::Metadata& metadata() { return metadata_; } + const Field& global_index() const { return global_index_; } + Field& global_index() { return global_index_; } - const Field& global_index() const { return global_index_; } - Field& global_index() { return global_index_; } + const Field& remote_index() const { return remote_index_; } + Field& remote_index() { return remote_index_; } - const Field& remote_index() const { return remote_index_; } - Field& remote_index() { return remote_index_; } + const Field& partition() const { return partition_; } + Field& partition() { return partition_; } - const Field& partition() const { return partition_; } - Field& partition() { return partition_; } + const Field& xy() const { return xy_; } + Field& xy() { return xy_; } - const Field& xy() const { return xy_; } - Field& xy() { return xy_; } + const Field& lonlat() const { return lonlat_; } + Field& lonlat() { return lonlat_; } - const Field& lonlat() const { return lonlat_; } - Field& lonlat() { return lonlat_; } + const Field& ghost() const { return ghost_; } + Field& ghost() { return ghost_; } - const Field& ghost() const { return ghost_; } - Field& ghost() { return ghost_; } + /// @brief Node to Edge connectivity table + const Connectivity& edge_connectivity() const; + Connectivity& edge_connectivity(); - /// @brief Node to Edge connectivity table - const Connectivity& edge_connectivity() const; - Connectivity& edge_connectivity(); + /// @brief Node to Cell connectivity table + const Connectivity& cell_connectivity() const; + Connectivity& cell_connectivity(); - /// @brief Node to Cell connectivity table - const Connectivity& cell_connectivity() const; - Connectivity& cell_connectivity(); + const Connectivity& connectivity( const std::string& name ) const; + Connectivity& connectivity( const std::string& name ); - const Connectivity& connectivity(const std::string& name) const; - Connectivity& connectivity(const std::string& name); + bool has_connectivity( std::string name ) const { return connectivities_.count( name ); } - bool has_connectivity(std::string name) const { return connectivities_.count(name); } + size_t size() const { return size_; } - size_t size() const { return size_; } + // -- Modifiers -// -- Modifiers + Field add( const Field& ); - Field add( const Field& ); + void resize( size_t ); - void resize( size_t ); + void remove_field( const std::string& name ); - void remove_field(const std::string& name); + Connectivity& add( mesh::Connectivity* ); - Connectivity& add( mesh::Connectivity* ); + /// @brief Return the memory footprint of the Nodes + size_t footprint() const; + void cloneToDevice() const; - /// @brief Return the memory footprint of the Nodes - size_t footprint() const; + void cloneFromDevice() const; - void cloneToDevice() const; - - void cloneFromDevice() const; - - void syncHostDevice() const; + void syncHostDevice() const; private: + void print( std::ostream& ) const; - void print(std::ostream&) const; - - friend std::ostream& operator<<(std::ostream& s, const Nodes& p) { - p.print(s); - return s; - } + friend std::ostream& operator<<( std::ostream& s, const Nodes& p ) { + p.print( s ); + return s; + } private: - - typedef std::map< std::string, Field > FieldMap; - typedef std::map< std::string, eckit::SharedPtr > ConnectivityMap; + typedef std::map FieldMap; + typedef std::map> ConnectivityMap; private: - - size_t size_; - FieldMap fields_; - ConnectivityMap connectivities_; - - util::Metadata metadata_; - - // Cached shortcuts to specific fields in fields_ - Field global_index_; - Field remote_index_; - Field partition_; - Field xy_; - Field lonlat_; - Field ghost_; - -// Cached shortcuts to specific connectivities in connectivities_ - Connectivity* edge_connectivity_; - Connectivity* cell_connectivity_; - + size_t size_; + FieldMap fields_; + ConnectivityMap connectivities_; + + util::Metadata metadata_; + + // Cached shortcuts to specific fields in fields_ + Field global_index_; + Field remote_index_; + Field partition_; + Field xy_; + Field lonlat_; + Field ghost_; + + // Cached shortcuts to specific connectivities in connectivities_ + Connectivity* edge_connectivity_; + Connectivity* cell_connectivity_; }; -inline const Nodes::Connectivity& Nodes::edge_connectivity() const -{ - return *edge_connectivity_; +inline const Nodes::Connectivity& Nodes::edge_connectivity() const { + return *edge_connectivity_; } -inline Nodes::Connectivity& Nodes::edge_connectivity() -{ - return *edge_connectivity_; +inline Nodes::Connectivity& Nodes::edge_connectivity() { + return *edge_connectivity_; } -inline const Nodes::Connectivity& Nodes::cell_connectivity() const -{ - return *cell_connectivity_; +inline const Nodes::Connectivity& Nodes::cell_connectivity() const { + return *cell_connectivity_; } -inline Nodes::Connectivity& Nodes::cell_connectivity() -{ - return *cell_connectivity_; +inline Nodes::Connectivity& Nodes::cell_connectivity() { + return *cell_connectivity_; } -extern "C" -{ +extern "C" { Nodes* atlas__mesh__Nodes__create(); -void atlas__mesh__Nodes__delete (Nodes* This); -size_t atlas__mesh__Nodes__size (Nodes* This); -void atlas__mesh__Nodes__resize (Nodes* This, size_t size); -size_t atlas__mesh__Nodes__nb_fields (Nodes* This); -void atlas__mesh__Nodes__add_field (Nodes* This, field::FieldImpl* field); -void atlas__mesh__Nodes__remove_field (Nodes* This, char* name); -int atlas__mesh__Nodes__has_field (Nodes* This, char* name); -field::FieldImpl* atlas__mesh__Nodes__field_by_name (Nodes* This, char* name); -field::FieldImpl* atlas__mesh__Nodes__field_by_idx (Nodes* This, size_t idx); -util::Metadata* atlas__mesh__Nodes__metadata(Nodes* This); -void atlas__mesh__Nodes__str (Nodes* This, char* &str, int &size); -IrregularConnectivity* atlas__mesh__Nodes__edge_connectivity(Nodes* This); -IrregularConnectivity* atlas__mesh__Nodes__cell_connectivity(Nodes* This); -IrregularConnectivity* atlas__mesh__Nodes__connectivity (Nodes* This, char* name); -void atlas__mesh__Nodes__add_connectivity (Nodes* This, IrregularConnectivity* connectivity); -field::FieldImpl* atlas__mesh__Nodes__xy(Nodes* This); -field::FieldImpl* atlas__mesh__Nodes__lonlat(Nodes* This); -field::FieldImpl* atlas__mesh__Nodes__global_index(Nodes* This); -field::FieldImpl* atlas__mesh__Nodes__remote_index(Nodes* This); -field::FieldImpl* atlas__mesh__Nodes__partition(Nodes* This); -field::FieldImpl* atlas__mesh__Nodes__ghost(Nodes* This); +void atlas__mesh__Nodes__delete( Nodes* This ); +size_t atlas__mesh__Nodes__size( Nodes* This ); +void atlas__mesh__Nodes__resize( Nodes* This, size_t size ); +size_t atlas__mesh__Nodes__nb_fields( Nodes* This ); +void atlas__mesh__Nodes__add_field( Nodes* This, field::FieldImpl* field ); +void atlas__mesh__Nodes__remove_field( Nodes* This, char* name ); +int atlas__mesh__Nodes__has_field( Nodes* This, char* name ); +field::FieldImpl* atlas__mesh__Nodes__field_by_name( Nodes* This, char* name ); +field::FieldImpl* atlas__mesh__Nodes__field_by_idx( Nodes* This, size_t idx ); +util::Metadata* atlas__mesh__Nodes__metadata( Nodes* This ); +void atlas__mesh__Nodes__str( Nodes* This, char*& str, int& size ); +IrregularConnectivity* atlas__mesh__Nodes__edge_connectivity( Nodes* This ); +IrregularConnectivity* atlas__mesh__Nodes__cell_connectivity( Nodes* This ); +IrregularConnectivity* atlas__mesh__Nodes__connectivity( Nodes* This, char* name ); +void atlas__mesh__Nodes__add_connectivity( Nodes* This, IrregularConnectivity* connectivity ); +field::FieldImpl* atlas__mesh__Nodes__xy( Nodes* This ); +field::FieldImpl* atlas__mesh__Nodes__lonlat( Nodes* This ); +field::FieldImpl* atlas__mesh__Nodes__global_index( Nodes* This ); +field::FieldImpl* atlas__mesh__Nodes__remote_index( Nodes* This ); +field::FieldImpl* atlas__mesh__Nodes__partition( Nodes* This ); +field::FieldImpl* atlas__mesh__Nodes__ghost( Nodes* This ); } //------------------------------------------------------------------------------------------------------ -} // namespace mesh -} // namespace atlas +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/PartitionPolygon.cc b/src/atlas/mesh/PartitionPolygon.cc index 4a7b88940..c1ad79973 100644 --- a/src/atlas/mesh/PartitionPolygon.cc +++ b/src/atlas/mesh/PartitionPolygon.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -28,134 +29,172 @@ namespace atlas { namespace mesh { namespace { -util::Polygon::edge_set_t compute_edges(const detail::MeshImpl& mesh, size_t halo) { - // extract partition boundary edges by always attempting first to` - // remove a reversed edge from a neighbouring element, if any - util::Polygon::edge_set_t edges; - for (size_t t = 0; t < mesh.cells().nb_types(); ++t) { - const Elements& elements = mesh.cells().elements(t); - - const BlockConnectivity& conn = elements.node_connectivity(); - auto field_patch = elements.view< int, 1 >(elements.field("patch")); - auto field_halo = elements.view< int, 1 >(elements.field("halo")); - - const size_t nb_nodes = elements.nb_nodes(); - - for (size_t j = 0; j < elements.size(); ++j) { - if (field_patch(j) == 0 && field_halo(j) <= halo ) { - for (size_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); - } - } - } - } - } - return edges; -} -} - -PartitionPolygon::PartitionPolygon(const detail::MeshImpl& mesh, size_t halo) : - util::Polygon( compute_edges(mesh,halo) ), - mesh_(mesh), - halo_(halo) { +util::Polygon::edge_set_t compute_edges( const detail::MeshImpl& mesh, size_t halo ) { + // extract partition boundary edges by always attempting first to` + // remove a reversed edge from a neighbouring element, if any + util::Polygon::edge_set_t edges; + for ( size_t t = 0; t < mesh.cells().nb_types(); ++t ) { + const Elements& elements = mesh.cells().elements( t ); + + const BlockConnectivity& conn = elements.node_connectivity(); + auto field_patch = elements.view( elements.field( "patch" ) ); + auto field_halo = elements.view( elements.field( "halo" ) ); + + const size_t nb_nodes = elements.nb_nodes(); + + for ( size_t j = 0; j < elements.size(); ++j ) { + if ( field_patch( j ) == 0 && field_halo( j ) <= halo ) { + for ( size_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 ); } + } + } + } + } + return edges; } +} // namespace +PartitionPolygon::PartitionPolygon( const detail::MeshImpl& mesh, size_t halo ) : + util::Polygon( compute_edges( mesh, halo ) ), + mesh_( mesh ), + halo_( halo ) {} size_t PartitionPolygon::footprint() const { - size_t size = sizeof(*this); - size += capacity()*sizeof(idx_t); + size_t size = sizeof( *this ); + size += capacity() * sizeof( idx_t ); return size; } - -void PartitionPolygon::outputPythonScript(const eckit::PathName& filepath, const eckit::Configuration& config) const { - const eckit::mpi::Comm& comm = atlas::mpi::comm(); - int mpi_rank = int(comm.rank()); - int mpi_size = int(comm.size()); - - auto xy = array::make_view( mesh_.nodes().xy() ); - - double xmin = std::numeric_limits::max(); - double xmax = -std::numeric_limits::max(); - for (idx_t i : *this) { - xmin = std::min(xmin, xy(i, XX) ); - xmax = std::max(xmax, xy(i, XX) ); - } - comm.allReduceInPlace(xmin,eckit::mpi::min()); - comm.allReduceInPlace(xmax,eckit::mpi::max()); - - size_t count = mesh_.nodes().size(); - size_t count_all = count; - comm.allReduceInPlace(count_all, eckit::mpi::sum()); - - - for (int r = 0; r < mpi_size; ++r) { - if (mpi_rank == r) { - std::ofstream f(filepath.asString().c_str(), mpi_rank == 0? std::ios::trunc : std::ios::app); - - if (mpi_rank == 0) { - f << "\n" "# Configuration option to plot nodes" - "\n" "plot_nodes = " + std::string( ( config.getBool("nodes",false) ? "True" : "False" ) ) + - "\n" - "\n" "import matplotlib.pyplot as plt" - "\n" "from matplotlib.path import Path" - "\n" "import matplotlib.patches as patches" - "\n" "" - "\n" "from itertools import cycle" - "\n" "import matplotlib.cm as cm" - "\n" "import numpy as np" - "\n" "cycol = cycle([cm.Paired(i) for i in np.linspace(0,1,12,endpoint=True)]).next" - "\n" "" - "\n" "fig = plt.figure()" - "\n" "ax = fig.add_subplot(111,aspect='equal')" - "\n" ""; - } - f << "\n" "verts_" << r << " = ["; - for (idx_t i : static_cast(*this)) { - f << "\n (" << xy(i, XX) << ", " << xy(i, YY) << "), "; - } - f << "\n]" - "\n" "" - "\n" "codes_" << r << " = [Path.MOVETO]" - "\n" "codes_" << r << ".extend([Path.LINETO] * " << (size()-2) << ")" - "\n" "codes_" << r << ".extend([Path.CLOSEPOLY])" - "\n" "" - "\n" "count_" << r << " = " << count << - "\n" "count_all_" << r << " = " << count_all << - "\n" "" - //"\n" "x_" << r << " = ["; for (size_t i=0; i( mesh_.nodes().xy() ); + + double xmin = std::numeric_limits::max(); + double xmax = -std::numeric_limits::max(); + for ( idx_t i : *this ) { + xmin = std::min( xmin, xy( i, XX ) ); + xmax = std::max( xmax, xy( i, XX ) ); + } + comm.allReduceInPlace( xmin, eckit::mpi::min() ); + comm.allReduceInPlace( xmax, eckit::mpi::max() ); + + size_t count = mesh_.nodes().size(); + size_t count_all = count; + comm.allReduceInPlace( count_all, eckit::mpi::sum() ); + + for ( int r = 0; r < mpi_size; ++r ) { + if ( mpi_rank == r ) { + std::ofstream f( filepath.asString().c_str(), mpi_rank == 0 ? std::ios::trunc : std::ios::app ); + + if ( mpi_rank == 0 ) { + f << "\n" + "# Configuration option to plot nodes" + "\n" + "plot_nodes = " + + std::string( ( config.getBool( "nodes", false ) ? "True" : "False" ) ) + + "\n" + "\n" + "import matplotlib.pyplot as plt" + "\n" + "from matplotlib.path import Path" + "\n" + "import matplotlib.patches as patches" + "\n" + "" + "\n" + "from itertools import cycle" + "\n" + "import matplotlib.cm as cm" + "\n" + "import numpy as np" + "\n" + "cycol = cycle([cm.Paired(i) for i in " + "np.linspace(0,1,12,endpoint=True)]).next" + "\n" + "" + "\n" + "fig = plt.figure()" + "\n" + "ax = fig.add_subplot(111,aspect='equal')" + "\n" + ""; + } + f << "\n" + "verts_" + << r << " = ["; + for ( idx_t i : static_cast( *this ) ) { + f << "\n (" << xy( i, XX ) << ", " << xy( i, YY ) << "), "; + } + f << "\n]" + "\n" + "" + "\n" + "codes_" + << r + << " = [Path.MOVETO]" + "\n" + "codes_" + << r << ".extend([Path.LINETO] * " << ( size() - 2 ) + << ")" + "\n" + "codes_" + << r + << ".extend([Path.CLOSEPOLY])" + "\n" + "" + "\n" + "count_" + << r << " = " << count + << "\n" + "count_all_" + << r << " = " << count_all + << "\n" + "" + //"\n" "x_" << r << " = ["; for (size_t i=0; i(*this) - << "}"; + << "halo:" << halo_ << ",size:" << size() << ",nodes:" << static_cast( *this ) << "}"; } - } // namespace mesh } // namespace atlas - diff --git a/src/atlas/mesh/PartitionPolygon.h b/src/atlas/mesh/PartitionPolygon.h index 52bd485e5..0fd15d58e 100644 --- a/src/atlas/mesh/PartitionPolygon.h +++ b/src/atlas/mesh/PartitionPolygon.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,11 +16,18 @@ #pragma once #include -#include "eckit/memory/Owned.h" #include "atlas/library/config.h" -#include "atlas/mesh/detail/MeshImpl.h" #include "atlas/util/Config.h" #include "atlas/util/Polygon.h" +#include "eckit/memory/Owned.h" + +namespace atlas { +namespace mesh { +namespace detail { +class MeshImpl; +} +} // namespace mesh +} // namespace atlas namespace atlas { namespace mesh { @@ -28,42 +36,35 @@ namespace mesh { * @brief Polygon class that holds the boundary of a mesh partition */ class PartitionPolygon : public util::Polygon, public eckit::Owned { - -public: // methods - +public: // methods //-- Constructors /// @brief Construct "size" polygon - PartitionPolygon(const detail::MeshImpl& mesh, size_t halo); + PartitionPolygon( const detail::MeshImpl& mesh, size_t halo ); //-- Accessors - size_t halo() const { - return halo_; - } + size_t halo() const { return halo_; } /// @brief Return the memory footprint of the Polygon size_t footprint() const; - void outputPythonScript(const eckit::PathName&, const eckit::Configuration& = util::NoConfig() ) const; + void outputPythonScript( const eckit::PathName&, const eckit::Configuration& = util::NoConfig() ) const; private: + void print( std::ostream& ) const; - void print(std::ostream&) const; - - friend std::ostream& operator<<(std::ostream& s, const PartitionPolygon& p) { - p.print(s); + friend std::ostream& operator<<( std::ostream& s, const PartitionPolygon& p ) { + p.print( s ); return s; } private: - const detail::MeshImpl& mesh_; size_t halo_; - }; //------------------------------------------------------------------------------------------------------ -} // namespace mesh -} // namespace atlas +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/BuildCellCentres.cc b/src/atlas/mesh/actions/BuildCellCentres.cc index 2f6509db0..10c64eaf1 100644 --- a/src/atlas/mesh/actions/BuildCellCentres.cc +++ b/src/atlas/mesh/actions/BuildCellCentres.cc @@ -4,19 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/mesh/actions/BuildCellCentres.h" #include -#include "eckit/types/FloatCompare.h" +#include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/actions/BuildCellCentres.h" -#include "atlas/field/Field.h" #include "atlas/util/CoordinateEnums.h" -#include "atlas/array/MakeView.h" +#include "eckit/types/FloatCompare.h" namespace atlas { namespace mesh { @@ -24,81 +25,71 @@ namespace actions { //---------------------------------------------------------------------------------------------------------------------- -BuildCellCentres::BuildCellCentres( const std::string& field_name ) : - field_name_(field_name) { -} +BuildCellCentres::BuildCellCentres( const std::string& field_name ) : field_name_( field_name ) {} Field& BuildCellCentres::operator()( Mesh& mesh ) const { - if (!mesh.cells().has_field(field_name_)) { - - mesh::Nodes& nodes = mesh.nodes(); - array::ArrayView coords = array::make_view(nodes.field("xyz")); + if ( !mesh.cells().has_field( field_name_ ) ) { + mesh::Nodes& nodes = mesh.nodes(); + array::ArrayView coords = array::make_view( nodes.field( "xyz" ) ); size_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" ); } - size_t nb_cells = mesh.cells().size(); - array::ArrayView centroids = array::make_view( - mesh.cells().add( - Field(field_name_, array::make_datatype(), array::make_shape(nb_cells, 3)) )); + size_t nb_cells = mesh.cells().size(); + array::ArrayView centroids = array::make_view( mesh.cells().add( + Field( field_name_, array::make_datatype(), array::make_shape( nb_cells, 3 ) ) ) ); const mesh::HybridElements::Connectivity& cell_node_connectivity = mesh.cells().node_connectivity(); - for (size_t e = 0; e < nb_cells; ++e) { - centroids(e, XX) = 0.; - centroids(e, YY) = 0.; - centroids(e, ZZ) = 0.; + for ( size_t e = 0; e < nb_cells; ++e ) { + centroids( e, XX ) = 0.; + centroids( e, YY ) = 0.; + centroids( e, ZZ ) = 0.; - const size_t nb_cell_nodes = cell_node_connectivity.cols(e); + const size_t nb_cell_nodes = cell_node_connectivity.cols( e ); // check for degenerate elements (less than three unique nodes) // NOTE: this is not a proper check but it is very robust - eckit::types::CompareApproximatelyEqual approx(1.e-9); + eckit::types::CompareApproximatelyEqual approx( 1.e-9 ); int nb_equal_nodes = 0; - for (size_t ni = 0; ni < nb_cell_nodes - 1; ++ni) { - idx_t i = cell_node_connectivity(e, ni); - Point3 Pi(coords(i, XX), coords(i, YY), coords(i, ZZ)); - for (size_t nj = ni + 1; nj < nb_cell_nodes; ++nj) { - idx_t j = cell_node_connectivity(e, nj); - Point3 Pj(coords(j, XX), coords(j, YY), coords(j, ZZ)); - if (approx(Pi[XX], Pj[XX]) && - approx(Pi[YY], Pj[YY]) && - approx(Pi[ZZ], Pj[ZZ])) { + for ( size_t ni = 0; ni < nb_cell_nodes - 1; ++ni ) { + idx_t i = cell_node_connectivity( e, ni ); + Point3 Pi( coords( i, XX ), coords( i, YY ), coords( i, ZZ ) ); + for ( size_t nj = ni + 1; nj < nb_cell_nodes; ++nj ) { + idx_t j = cell_node_connectivity( e, nj ); + Point3 Pj( coords( j, XX ), coords( j, YY ), coords( j, ZZ ) ); + if ( approx( Pi[XX], Pj[XX] ) && approx( Pi[YY], Pj[YY] ) && approx( Pi[ZZ], Pj[ZZ] ) ) { ++nb_equal_nodes; } } } - int nb_unique_nodes = int(nb_cell_nodes) - nb_equal_nodes; - if (nb_unique_nodes < 3) { - continue; - } + int nb_unique_nodes = int( nb_cell_nodes ) - nb_equal_nodes; + if ( nb_unique_nodes < 3 ) { continue; } // calculate centroid by averaging coordinates (uses only "real" nodes) size_t nb_real_nodes = 0; - for (size_t n = 0; n < nb_cell_nodes; ++n) { - const size_t i = size_t(cell_node_connectivity(e, n)); - if (i < firstVirtualPoint) { + for ( size_t n = 0; n < nb_cell_nodes; ++n ) { + const size_t i = size_t( cell_node_connectivity( e, n ) ); + if ( i < firstVirtualPoint ) { ++nb_real_nodes; - centroids(e, XX) += coords(i, XX); - centroids(e, YY) += coords(i, YY); - centroids(e, ZZ) += coords(i, ZZ); + centroids( e, XX ) += coords( i, XX ); + centroids( e, YY ) += coords( i, YY ); + centroids( e, ZZ ) += coords( i, ZZ ); } } - if (nb_real_nodes > 1) { - const double average_coefficient = 1. / static_cast(nb_real_nodes); - centroids(e, XX) *= average_coefficient; - centroids(e, YY) *= average_coefficient; - centroids(e, ZZ) *= average_coefficient; + if ( nb_real_nodes > 1 ) { + const double average_coefficient = 1. / static_cast( nb_real_nodes ); + centroids( e, XX ) *= average_coefficient; + centroids( e, YY ) *= average_coefficient; + centroids( e, ZZ ) *= average_coefficient; } } } - return mesh.cells().field(field_name_); + return mesh.cells().field( field_name_ ); } -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/BuildCellCentres.h b/src/atlas/mesh/actions/BuildCellCentres.h index 5f5546202..66ec52964 100644 --- a/src/atlas/mesh/actions/BuildCellCentres.h +++ b/src/atlas/mesh/actions/BuildCellCentres.h @@ -4,12 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once +#include + namespace atlas { class Mesh; @@ -21,16 +24,15 @@ namespace actions { /// Generates the cell centres on each cell class BuildCellCentres { public: - BuildCellCentres( const std::string& field_name = "centre" ); /// @note Correct only for Linear Triangles and Quadrilaterals - Field& operator()(Mesh&) const; + Field& operator()( Mesh& ) const; private: std::string field_name_; }; -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.cc b/src/atlas/mesh/actions/BuildConvexHull3D.cc index 490d81a80..433785037 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.cc +++ b/src/atlas/mesh/actions/BuildConvexHull3D.cc @@ -4,14 +4,15 @@ * 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 + * 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 #include "eckit/log/BigNum.h" #include "eckit/memory/ScopedPtr.h" @@ -22,42 +23,42 @@ #define CGAL_NDEBUG #include -#include -#include #include -#include #include +#include +#include +#include -typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Polyhedron_3 Polyhedron_3; +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Polyhedron_3 Polyhedron_3; -typedef K::Vector_3 Vector_3; -typedef K::FT FT; -typedef K::Segment_3 Segment_3; -typedef K::Point_3 Point_3; +typedef K::Vector_3 Vector_3; +typedef K::FT FT; +typedef K::Segment_3 Segment_3; +typedef K::Point_3 Point_3; -const Point_3 origin = Point_3(CGAL::ORIGIN); +const Point_3 origin = Point_3( CGAL::ORIGIN ); #endif +#include "atlas/array/ArrayView.h" +#include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" #include "atlas/grid/Grid.h" -#include "atlas/runtime/Trace.h" +#include "atlas/interpolation/method/PointSet.h" +#include "atlas/mesh/ElementType.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/ElementType.h" #include "atlas/mesh/actions/BuildConvexHull3D.h" -#include "atlas/field/Field.h" +#include "atlas/runtime/Trace.h" #include "atlas/util/CoordinateEnums.h" -#include "atlas/interpolation/method/PointSet.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/MakeView.h" using namespace eckit; using namespace eckit::geometry; -using atlas::interpolation::method::PointSet; using atlas::interpolation::method::PointIndex3; +using atlas::interpolation::method::PointSet; namespace atlas { namespace mesh { @@ -67,8 +68,7 @@ namespace actions { #ifdef CGAL_FOUND -static Polyhedron_3* create_convex_hull_from_points( const std::vector< Point3 >& pts ) -{ +static Polyhedron_3* create_convex_hull_from_points( const std::vector& pts ) { ATLAS_TRACE(); Polyhedron_3* poly = new Polyhedron_3(); @@ -76,8 +76,8 @@ static Polyhedron_3* create_convex_hull_from_points( const std::vector< Point3 > // insertion from a vector : std::vector vertices( pts.size() ); - for( size_t i = 0; i < vertices.size(); ++i ) - vertices[i] = Point_3( pts[i](XX), pts[i](YY), pts[i](ZZ) ); + for ( size_t i = 0; i < vertices.size(); ++i ) + vertices[i] = Point_3( pts[i]( XX ), pts[i]( YY ), pts[i]( ZZ ) ); // compute convex hull of non-collinear points @@ -86,8 +86,7 @@ static Polyhedron_3* create_convex_hull_from_points( const std::vector< Point3 > return poly; } -static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, PointSet& points ) -{ +static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, PointSet& points ) { ATLAS_TRACE(); bool ensure_outward_normals = true; @@ -96,7 +95,7 @@ static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, Poin ASSERT( points.size() == nodes.size() ); - const idx_t nb_nodes = idx_t(points.size()); + const idx_t nb_nodes = idx_t( points.size() ); ASSERT( mesh.cells().size() == 0 ); @@ -105,29 +104,26 @@ static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, Poin const size_t nb_triags = poly.size_of_facets(); mesh.cells().add( new mesh::temporary::Triangle(), nb_triags ); mesh::HybridElements::Connectivity& triag_nodes = mesh.cells().node_connectivity(); - array::ArrayView triag_gidx = array::make_view( mesh.cells().global_index() ); - array::ArrayView triag_part = array::make_view( mesh.cells().partition() ); + array::ArrayView triag_gidx = array::make_view( mesh.cells().global_index() ); + array::ArrayView triag_part = array::make_view( mesh.cells().partition() ); Point3 pt; idx_t idx[3]; Polyhedron_3::Vertex_const_handle vts[3]; - Log::debug() << "Inserting triags (" << eckit::BigNum(nb_triags) << ")" << std::endl; + Log::debug() << "Inserting triags (" << eckit::BigNum( nb_triags ) << ")" << std::endl; size_t tidx = 0; - for( Polyhedron_3::Facet_const_iterator f = poly.facets_begin(); f != poly.facets_end(); ++f ) - { - + for ( Polyhedron_3::Facet_const_iterator f = poly.facets_begin(); f != poly.facets_end(); ++f ) { // loop over half-edges and take each vertex() - size_t iedge = 0; + size_t iedge = 0; Polyhedron_3::Halfedge_around_facet_const_circulator edge = f->facet_begin(); - do - { + do { Polyhedron_3::Vertex_const_handle vh = edge->vertex(); - const Polyhedron_3::Point_3& p = vh->point(); + const Polyhedron_3::Point_3& p = vh->point(); - pt.assign(p); + pt.assign( p ); idx[iedge] = points.unique( pt ); @@ -137,29 +133,28 @@ static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, Poin ++iedge; ++edge; - } - while ( edge != f->facet_begin() && iedge < 3 ); + } while ( edge != f->facet_begin() && iedge < 3 ); ASSERT( iedge == 3 ); - if( ensure_outward_normals ) /* ensure outward pointing normal */ + if ( ensure_outward_normals ) /* ensure outward pointing normal */ { - Vector_3 p0 ( origin, vts[0]->point() ); - Vector_3 n = CGAL::normal( vts[0]->point(), vts[1]->point(), vts[2]->point() ); + Vector_3 p0( origin, vts[0]->point() ); + Vector_3 n = CGAL::normal( vts[0]->point(), vts[1]->point(), vts[2]->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 */ - triag_nodes.set(tidx, idx ); + triag_nodes.set( tidx, idx ); - triag_gidx(tidx) = tidx+1; + triag_gidx( tidx ) = tidx + 1; - triag_part(tidx) = 0; + triag_part( tidx ) = 0; ++tidx; } @@ -170,28 +165,24 @@ static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, Poin #else struct Polyhedron_3 { - size_t size_of_vertices() const { return 0; } + size_t size_of_vertices() const { return 0; } }; -static Polyhedron_3* create_convex_hull_from_points( const std::vector< Point3 >& pts ) -{ - throw NotImplemented( "CGAL package not found -- Delaunay triangulation is disabled", Here() ); +static Polyhedron_3* create_convex_hull_from_points( const std::vector& pts ) { + throw NotImplemented( "CGAL package not found -- Delaunay triangulation is disabled", Here() ); } -static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, PointSet& points ) -{ - throw NotImplemented( "CGAL package not found -- Delaunay triangulation is disabled", Here() ); +static void cgal_polyhedron_to_atlas_mesh( Mesh& mesh, Polyhedron_3& poly, PointSet& points ) { + throw NotImplemented( "CGAL package not found -- Delaunay triangulation is disabled", Here() ); } #endif //---------------------------------------------------------------------------------------------------------------------- -void BuildConvexHull3D::operator()( Mesh& mesh ) const -{ +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(); @@ -199,30 +190,27 @@ void BuildConvexHull3D::operator()( Mesh& mesh ) const PointSet points( mesh ); - std::vector< Point3 > ipts; + std::vector ipts; points.list_unique_points( ipts ); -// std::cout << "unique pts " << ipts.size() << std::endl; -// std::cout << "duplicates " << points.duplicates().size() << std::endl; - + // std::cout << "unique pts " << ipts.size() << std::endl; + // std::cout << "duplicates " << points.duplicates().size() << std::endl; // define polyhedron to hold convex hull - eckit::ScopedPtr< Polyhedron_3 > poly( create_convex_hull_from_points( ipts ) ); + eckit::ScopedPtr poly( create_convex_hull_from_points( ipts ) ); -// std::cout << "convex hull " << poly->size_of_vertices() << " vertices" << std::endl; + // std::cout << "convex hull " << poly->size_of_vertices() << " vertices" + // << std::endl; ASSERT( poly->size_of_vertices() == ipts.size() ); cgal_polyhedron_to_atlas_mesh( mesh, *poly, points ); - } //---------------------------------------------------------------------------------------------------------------------- -} // namespace actions -} // namespace mesh -} // namespace atlas - - +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.h b/src/atlas/mesh/actions/BuildConvexHull3D.h index 39fcda85a..cbeb456f0 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.h +++ b/src/atlas/mesh/actions/BuildConvexHull3D.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -21,14 +22,11 @@ namespace actions { /// Creates a 3D convex-hull on the mesh points class BuildConvexHull3D { public: - - void operator()(Mesh&) const; - + void operator()( Mesh& ) const; }; -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas #endif - diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index 7520c3fbc..c5b111c19 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -4,33 +4,34 @@ * 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 + * 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 +#include +#include #include -#include "atlas/library/config.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/IndexView.h" +#include "atlas/field/Field.h" +#include "atlas/functionspace/EdgeColumns.h" +#include "atlas/functionspace/NodeColumns.h" #include "atlas/grid/Grid.h" +#include "atlas/library/config.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/actions/BuildDualMesh.h" -#include "atlas/field/Field.h" -#include "atlas/functionspace/NodeColumns.h" -#include "atlas/functionspace/EdgeColumns.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/util/Unique.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/IndexView.h" +#include "atlas/parallel/Checksum.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Trace.h" -#include "atlas/parallel/Checksum.h" +#include "atlas/util/CoordinateEnums.h" +#include "atlas/util/Unique.h" using atlas::functionspace::NodeColumns; using atlas::mesh::Halo; @@ -41,446 +42,386 @@ namespace actions { namespace { -void global_bounding_box( const mesh::Nodes& nodes, double min[2], double max[2] ) -{ - ATLAS_TRACE(); - - array::ArrayView xy = array::make_view( nodes.xy() ); - const int nb_nodes = nodes.size(); - min[XX] = std::numeric_limits::max(); - min[YY] = std::numeric_limits::max(); - max[XX] = -std::numeric_limits::max(); - max[YY] = -std::numeric_limits::max(); - - for (int node=0; node xy = array::make_view( nodes.xy() ); + const int nb_nodes = nodes.size(); + min[XX] = std::numeric_limits::max(); + min[YY] = std::numeric_limits::max(); + max[XX] = -std::numeric_limits::max(); + max[YY] = -std::numeric_limits::max(); + + for ( int node = 0; node < nb_nodes; ++node ) { + min[XX] = std::min( min[XX], xy( node, XX ) ); + min[YY] = std::min( min[YY], xy( node, YY ) ); + max[XX] = std::max( max[XX], xy( node, XX ) ); + max[YY] = std::max( max[YY], xy( node, YY ) ); + } + + ATLAS_TRACE_MPI( ALLREDUCE ) { + mpi::comm().allReduceInPlace( min, 2, eckit::mpi::min() ); + mpi::comm().allReduceInPlace( max, 2, eckit::mpi::max() ); + } } -struct Node -{ - Node() {} - Node(gidx_t gid, idx_t idx) - { - g = gid; - i = idx; - } - gidx_t g; - idx_t i; - - bool operator < (const Node& other) const - { - return ( g < other.g ); - } -}; +struct Node { + Node() {} + Node( gidx_t gid, idx_t idx ) { + g = gid; + i = idx; + } + gidx_t g; + idx_t i; -inline double sqr(double a) { return a*a; } + bool operator<( const Node& other ) const { return ( g < other.g ); } +}; +inline double sqr( double a ) { + return a * a; } -array::Array* build_centroids_xy( const mesh::HybridElements& , const Field& xy); - -void add_centroid_dual_volume_contribution( - Mesh& mesh, - array::ArrayView& dual_volumes ); -void add_median_dual_volume_contribution_cells( - const mesh::HybridElements& cells, - const mesh::HybridElements& edges, - const mesh::Nodes& nodes, - array::Array& array_dual_volumes ); -void add_median_dual_volume_contribution_poles( - const mesh::HybridElements& edges, - const mesh::Nodes& nodes, - array::Array& array_dual_volumes ); +} // namespace + +array::Array* build_centroids_xy( const mesh::HybridElements&, const Field& xy ); + +void add_centroid_dual_volume_contribution( Mesh& mesh, array::ArrayView& dual_volumes ); +void add_median_dual_volume_contribution_cells( const mesh::HybridElements& cells, const mesh::HybridElements& edges, + const mesh::Nodes& nodes, array::Array& array_dual_volumes ); +void add_median_dual_volume_contribution_poles( const mesh::HybridElements& edges, const mesh::Nodes& nodes, + array::Array& array_dual_volumes ); void build_dual_normals( Mesh& mesh ); void make_dual_normals_outward( Mesh& mesh ); -void build_median_dual_mesh( Mesh& mesh ) -{ - ATLAS_TRACE(); - - mesh::Nodes& nodes = mesh.nodes(); - mesh::HybridElements& edges = mesh.edges(); - Field dual_volumes = nodes.add( - Field( "dual_volumes", array::make_datatype(), array::make_shape(nodes.size()) ) ); - - 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") ) - mesh.edges().add( - Field("centroids_xy",build_centroids_xy(mesh.edges(),mesh.nodes().xy())) ); - - array::ArrayView v = array::make_view(dual_volumes); - v.assign(0.); - add_median_dual_volume_contribution_cells(mesh.cells(),mesh.edges(),mesh.nodes(),dual_volumes); - add_median_dual_volume_contribution_poles(mesh.edges(),mesh.nodes(),dual_volumes); - - build_dual_normals( mesh ); - - Field skewness = mesh.edges().add( - Field("skewness", array::make_datatype(), array::make_shape(mesh.edges().size()))); - Field alpha = mesh.edges().add( - Field("alpha", array::make_datatype(), array::make_shape(mesh.edges().size()))); - array::make_view(skewness).assign(0.); - array::make_view(alpha).assign(0.5); - - functionspace::NodeColumns nodes_fs(mesh); - { - ATLAS_TRACE("halo-exchange dual_volumes"); - nodes_fs.haloExchange(nodes.field( "dual_volumes" )); - } - - functionspace::EdgeColumns edges_fs(mesh, Halo(mesh)); - { - ATLAS_TRACE( "halo-exchange dual_normals" ); - edges_fs.haloExchange(edges.field( "dual_normals" )); - } - make_dual_normals_outward(mesh); -} +void build_median_dual_mesh( Mesh& mesh ) { + ATLAS_TRACE(); + + mesh::Nodes& nodes = mesh.nodes(); + mesh::HybridElements& edges = mesh.edges(); + Field dual_volumes = + nodes.add( Field( "dual_volumes", array::make_datatype(), array::make_shape( nodes.size() ) ) ); + + 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" ) ) + mesh.edges().add( Field( "centroids_xy", build_centroids_xy( mesh.edges(), mesh.nodes().xy() ) ) ); + array::ArrayView v = + array::make_view( dual_volumes ); + v.assign( 0. ); + add_median_dual_volume_contribution_cells( mesh.cells(), mesh.edges(), mesh.nodes(), dual_volumes ); + add_median_dual_volume_contribution_poles( mesh.edges(), mesh.nodes(), dual_volumes ); -array::Array* build_centroids_xy( const mesh::HybridElements& elements, const Field& field_xy ) -{ - const array::ArrayView xy = array::make_view( field_xy ); - array::Array* array_centroids = array::Array::create(array::make_shape(elements.size(),2)); - array::ArrayView centroids = array::make_view( *array_centroids ); - size_t nb_elems = elements.size(); - const mesh::HybridElements::Connectivity& elem_nodes = elements.node_connectivity(); - for (size_t e=0; e(nb_nodes_per_elem); - for (size_t n=0; n(), array::make_shape( mesh.edges().size() ) ) ); + Field alpha = + mesh.edges().add( Field( "alpha", array::make_datatype(), array::make_shape( mesh.edges().size() ) ) ); + array::make_view( skewness ).assign( 0. ); + array::make_view( alpha ).assign( 0.5 ); + + functionspace::NodeColumns nodes_fs( mesh ); { - centroids(e,XX) += xy( elem_nodes(e,n), XX ); - centroids(e,YY) += xy( elem_nodes(e,n), YY ); + ATLAS_TRACE( "halo-exchange dual_volumes" ); + nodes_fs.haloExchange( nodes.field( "dual_volumes" ) ); } - centroids(e,XX) *= average_coefficient; - centroids(e,YY) *= average_coefficient; - } - return array_centroids; -} -void add_median_dual_volume_contribution_cells( - const mesh::HybridElements& cells, - const mesh::HybridElements& edges, - const mesh::Nodes& nodes, - array::Array& array_dual_volumes ) -{ - ATLAS_TRACE(); - - array::ArrayView dual_volumes = array::make_view ( array_dual_volumes ); - - const array::ArrayView xy = array::make_view( nodes.xy() ); - const array::ArrayView cell_centroids = array::make_view( cells.field("centroids_xy") ); - const array::ArrayView edge_centroids = array::make_view( edges.field("centroids_xy") ); - const mesh::HybridElements::Connectivity& cell_edge_connectivity = cells.edge_connectivity(); - const mesh::HybridElements::Connectivity& edge_node_connectivity = edges.node_connectivity(); - auto patch = array::make_view(cells.field("patch")); - - // special ordering for bit-identical results - size_t nb_cells = cells.size(); - std::vector ordering(nb_cells); - for (size_t jcell=0; jcell dual_volumes = array::make_view( array_dual_volumes ); - const array::ArrayView xy = array::make_view( nodes.xy() ); - const array::ArrayView edge_centroids = array::make_view( edges.field("centroids_xy") ); - const mesh::HybridElements::Connectivity& edge_node_connectivity = edges.node_connectivity(); - const mesh::HybridElements::Connectivity& edge_cell_connectivity = edges.cell_connectivity(); - - const size_t nb_edges = edges.size(); - std::map > node_to_bdry_edge; - for(size_t jedge=0; jedge >::iterator it; - for( it=node_to_bdry_edge.begin(); it!=node_to_bdry_edge.end(); ++it) - { - const size_t jnode = (*it).first; - std::vector& bdry_edges = (*it).second; - const double x0 = xy(jnode,XX); - const double y0 = xy(jnode,YY); - double x1, y1, y2; - for (size_t jedge = 0; jedge < bdry_edges.size(); ++jedge) - { - const size_t iedge = bdry_edges[jedge]; - x1 = edge_centroids(iedge,XX); - y1 = edge_centroids(iedge,YY); - - y2 = 0.; - if ( std::abs(y1-max[YY]) xy = array::make_view( field_xy ); + array::Array* array_centroids = array::Array::create( array::make_shape( elements.size(), 2 ) ); + array::ArrayView centroids = array::make_view( *array_centroids ); + size_t nb_elems = elements.size(); + const mesh::HybridElements::Connectivity& elem_nodes = elements.node_connectivity(); + for ( size_t e = 0; e < nb_elems; ++e ) { + centroids( e, XX ) = 0.; + centroids( e, YY ) = 0.; + const size_t nb_nodes_per_elem = elem_nodes.cols( e ); + const double average_coefficient = 1. / static_cast( nb_nodes_per_elem ); + for ( size_t n = 0; n < nb_nodes_per_elem; ++n ) { + centroids( e, XX ) += xy( elem_nodes( e, n ), XX ); + centroids( e, YY ) += xy( elem_nodes( e, n ), YY ); + } + centroids( e, XX ) *= average_coefficient; + centroids( e, YY ) *= average_coefficient; } - } + return array_centroids; +} +void add_median_dual_volume_contribution_cells( const mesh::HybridElements& cells, const mesh::HybridElements& edges, + const mesh::Nodes& nodes, array::Array& array_dual_volumes ) { + ATLAS_TRACE(); + + array::ArrayView dual_volumes = array::make_view( array_dual_volumes ); + + const array::ArrayView xy = array::make_view( nodes.xy() ); + const array::ArrayView cell_centroids = array::make_view( cells.field( "centroids_xy" ) ); + const array::ArrayView edge_centroids = array::make_view( edges.field( "centroids_xy" ) ); + const mesh::HybridElements::Connectivity& cell_edge_connectivity = cells.edge_connectivity(); + const mesh::HybridElements::Connectivity& edge_node_connectivity = edges.node_connectivity(); + auto patch = array::make_view( cells.field( "patch" ) ); + + // special ordering for bit-identical results + size_t nb_cells = cells.size(); + std::vector ordering( nb_cells ); + for ( size_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 ( size_t jcell = 0; jcell < nb_cells; ++jcell ) { + idx_t icell = ordering[jcell].i; + if ( patch( icell ) ) continue; + double x0 = cell_centroids( icell, XX ); + double y0 = cell_centroids( icell, YY ); + + for ( size_t jedge = 0; jedge < cell_edge_connectivity.cols( icell ); ++jedge ) { + idx_t iedge = cell_edge_connectivity( icell, jedge ); + double x1 = edge_centroids( iedge, XX ); + double y1 = edge_centroids( iedge, YY ); + for ( size_t jnode = 0; jnode < 2; ++jnode ) { + idx_t inode = edge_node_connectivity( iedge, jnode ); + double x2 = xy( inode, XX ); + double y2 = xy( inode, YY ); + double triag_area = std::abs( x0 * ( y1 - y2 ) + x1 * ( y2 - y0 ) + x2 * ( y0 - y1 ) ) * 0.5; + dual_volumes( inode ) += triag_area; + } + } + } } +void add_median_dual_volume_contribution_poles( const mesh::HybridElements& edges, const mesh::Nodes& nodes, + array::Array& array_dual_volumes ) { + ATLAS_TRACE(); + + array::ArrayView dual_volumes = array::make_view( array_dual_volumes ); + const array::ArrayView xy = array::make_view( nodes.xy() ); + const array::ArrayView edge_centroids = array::make_view( edges.field( "centroids_xy" ) ); + const mesh::HybridElements::Connectivity& edge_node_connectivity = edges.node_connectivity(); + const mesh::HybridElements::Connectivity& edge_cell_connectivity = edges.cell_connectivity(); + + const size_t nb_edges = edges.size(); + std::map> node_to_bdry_edge; + for ( size_t jedge = 0; jedge < nb_edges; ++jedge ) { + if ( edge_cell_connectivity( jedge, 0 ) != edge_cell_connectivity.missing_value() && + edge_cell_connectivity( jedge, 1 ) == edge_cell_connectivity.missing_value() ) { + node_to_bdry_edge[edge_node_connectivity( jedge, 0 )].push_back( jedge ); + node_to_bdry_edge[edge_node_connectivity( jedge, 1 )].push_back( jedge ); + } + } -void build_dual_normals( Mesh& mesh ) -{ - ATLAS_TRACE(); + const double tol = 1.e-6; + double min[2], max[2]; + global_bounding_box( nodes, min, max ); + + std::map>::iterator it; + for ( it = node_to_bdry_edge.begin(); it != node_to_bdry_edge.end(); ++it ) { + const size_t jnode = ( *it ).first; + std::vector& bdry_edges = ( *it ).second; + const double x0 = xy( jnode, XX ); + const double y0 = xy( jnode, YY ); + double x1, y1, y2; + for ( size_t jedge = 0; jedge < bdry_edges.size(); ++jedge ) { + const size_t iedge = bdry_edges[jedge]; + x1 = edge_centroids( iedge, XX ); + y1 = edge_centroids( iedge, YY ); + + y2 = 0.; + if ( std::abs( y1 - max[YY] ) < tol ) + y2 = 90.; + else if ( std::abs( y1 - min[YY] ) < tol ) + y2 = -90.; + + if ( y2 != 0 ) { + const double quad_area = std::abs( ( x1 - x0 ) * ( y2 - y0 ) ); + dual_volumes( jnode ) += quad_area; + } + } + } +} - array::ArrayView elem_centroids = array::make_view( mesh.cells().field("centroids_xy") ); +void build_dual_normals( Mesh& mesh ) { + ATLAS_TRACE(); - mesh::Nodes& nodes = mesh.nodes(); - mesh::HybridElements& edges = mesh.edges(); - const size_t nb_edges = edges.size(); + array::ArrayView elem_centroids = array::make_view( mesh.cells().field( "centroids_xy" ) ); - array::ArrayView node_xy = array::make_view( nodes.xy() ); - double min[2], max[2]; - global_bounding_box( nodes, min, max ); - double tol = 1.e-6; + mesh::Nodes& nodes = mesh.nodes(); + mesh::HybridElements& edges = mesh.edges(); + const size_t nb_edges = edges.size(); - double xl, yl, xr, yr; - array::ArrayView edge_centroids = array::make_view( edges.field("centroids_xy") ); - array::ArrayView dual_normals = array::make_view( edges.add( - Field("dual_normals", array::make_datatype(), array::make_shape(nb_edges,2)) ) ); + array::ArrayView node_xy = array::make_view( nodes.xy() ); + double min[2], max[2]; + global_bounding_box( nodes, min, max ); + double tol = 1.e-6; - const mesh::HybridElements::Connectivity& edge_node_connectivity = edges.node_connectivity(); - const mesh::HybridElements::Connectivity& edge_cell_connectivity = edges.cell_connectivity(); + double xl, yl, xr, yr; + array::ArrayView edge_centroids = array::make_view( edges.field( "centroids_xy" ) ); + array::ArrayView dual_normals = array::make_view( + edges.add( Field( "dual_normals", array::make_datatype(), array::make_shape( nb_edges, 2 ) ) ) ); - std::map > node_to_bdry_edge; - for(size_t jedge=0; jedge> node_to_bdry_edge; + for ( size_t jedge = 0; jedge < nb_edges; ++jedge ) { + if ( edge_cell_connectivity( jedge, 0 ) != edge_cell_connectivity.missing_value() && + edge_cell_connectivity( jedge, 1 ) == edge_cell_connectivity.missing_value() ) { + node_to_bdry_edge[edge_node_connectivity( jedge, 0 )].push_back( jedge ); + node_to_bdry_edge[edge_node_connectivity( jedge, 1 )].push_back( jedge ); + } } - } - for (size_t edge=0; edge& bdry_edges = node_to_bdry_edge[node]; - double x[2]; - size_t cnt=0; - for (size_t jedge = 0; jedge < bdry_edges.size(); ++jedge) - { - idx_t bdry_edge = bdry_edges[jedge]; - if ( std::abs(edge_centroids(bdry_edge,YY)-max[YY])& bdry_edges = node_to_bdry_edge[node]; + double x[2]; + size_t cnt = 0; + for ( size_t jedge = 0; jedge < bdry_edges.size(); ++jedge ) { + idx_t bdry_edge = bdry_edges[jedge]; + if ( std::abs( edge_centroids( bdry_edge, YY ) - max[YY] ) < tol ) { + edge_centroids( edge, YY ) = 90.; + x[cnt] = edge_centroids( bdry_edge, XX ); + ++cnt; + } + else if ( std::abs( edge_centroids( bdry_edge, YY ) - min[YY] ) < tol ) { + edge_centroids( edge, YY ) = -90.; + x[cnt] = edge_centroids( bdry_edge, XX ); + ++cnt; + } + } + if ( cnt == 2 ) { + dual_normals( edge, XX ) = 0; + if ( node_xy( node, YY ) < 0. ) + dual_normals( edge, YY ) = -std::abs( x[1] - x[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; + break; + } + } } - if (cnt == 2 ) - { - dual_normals(edge,XX) = 0; - if (node_xy(node,YY) < 0.) - dual_normals(edge,YY) = -std::abs(x[1]-x[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; - break; + else { + idx_t left_elem = edge_cell_connectivity( edge, 0 ); + idx_t right_elem = edge_cell_connectivity( edge, 1 ); + xl = elem_centroids( left_elem, XX ); + yl = elem_centroids( left_elem, YY ); + if ( right_elem == edge_cell_connectivity.missing_value() ) { + xr = edge_centroids( edge, XX ); + yr = edge_centroids( edge, YY ); + ; + if ( std::abs( yr - max[YY] ) < tol ) + yr = 90.; + else if ( std::abs( yr - min[YY] ) < tol ) + yr = -90.; + } + else { + xr = elem_centroids( right_elem, XX ); + yr = elem_centroids( right_elem, YY ); + } + + dual_normals( edge, XX ) = yl - yr; + dual_normals( edge, YY ) = -xl + xr; } - } } - else - { - idx_t left_elem = edge_cell_connectivity(edge,0); - idx_t right_elem = edge_cell_connectivity(edge,1); - xl = elem_centroids(left_elem,XX); - yl = elem_centroids(left_elem,YY); - if( right_elem == edge_cell_connectivity.missing_value() ) - { - xr = edge_centroids(edge,XX); - yr = edge_centroids(edge,YY);; - if ( std::abs(yr-max[YY]) node_xy = array::make_view( nodes.xy() ); - - mesh::HybridElements& edges = mesh.edges(); - const mesh::HybridElements::Connectivity& edge_cell_connectivity = edges.cell_connectivity(); - const mesh::HybridElements::Connectivity& edge_node_connectivity = edges.node_connectivity(); - array::ArrayView dual_normals = array::make_view( edges.field("dual_normals") ); - const size_t nb_edges = edges.size(); - - for (size_t edge=0; edge node_xy = array::make_view( nodes.xy() ); + + mesh::HybridElements& edges = mesh.edges(); + const mesh::HybridElements::Connectivity& edge_cell_connectivity = edges.cell_connectivity(); + const mesh::HybridElements::Connectivity& edge_node_connectivity = edges.node_connectivity(); + array::ArrayView dual_normals = array::make_view( edges.field( "dual_normals" ) ); + const size_t nb_edges = edges.size(); + + for ( size_t edge = 0; edge < nb_edges; ++edge ) { + if ( edge_cell_connectivity( edge, 0 ) != edge_cell_connectivity.missing_value() ) { + // Make normal point from node 1 to node 2 + const size_t ip1 = edge_node_connectivity( edge, 0 ); + const size_t ip2 = edge_node_connectivity( edge, 1 ); + double dx = node_xy( ip2, XX ) - node_xy( ip1, XX ); + double dy = node_xy( ip2, YY ) - node_xy( ip1, YY ); + if ( dx * dual_normals( edge, XX ) + dy * dual_normals( edge, YY ) < 0 ) { + dual_normals( edge, XX ) = -dual_normals( edge, XX ); + dual_normals( edge, YY ) = -dual_normals( edge, YY ); + } + } } - } } +void build_brick_dual_mesh( const Grid& grid, Mesh& mesh ) { + auto g = grid::StructuredGrid( grid ); + if ( g ) { + if ( mpi::comm().size() != 1 ) + throw eckit::UserError( "Cannot build_brick_dual_mesh with more than 1 task", Here() ); + + mesh::Nodes& nodes = mesh.nodes(); + array::ArrayView xy = array::make_view( nodes.xy() ); + array::ArrayView dual_volumes = array::make_view( nodes.add( + Field( "dual_volumes", array::make_datatype(), array::make_shape( nodes.size(), 1 ) ) ) ); + array::ArrayView gidx = array::make_view( nodes.global_index() ); + + int c = 0; + int n = 0; + for ( size_t jlat = 0; jlat < g.ny(); ++jlat ) { + double lat = g.y( jlat ); + double latN = ( jlat == 0 ) ? 90. : 0.5 * ( lat + g.y( jlat - 1 ) ); + double latS = ( jlat == g.ny() - 1 ) ? -90. : 0.5 * ( lat + g.y( jlat + 1 ) ); + double dlat = ( latN - latS ); + double dlon = 360. / static_cast( g.nx( jlat ) ); + + for ( size_t jlon = 0; jlon < g.nx( jlat ); ++jlon ) { + while ( gidx( c ) != n + 1 ) + c++; + ASSERT( xy( c, XX ) == g.x( jlon, jlat ) ); + ASSERT( xy( c, YY ) == lat ); + dual_volumes( c ) = dlon * dlat; + ++n; + } + } -void build_brick_dual_mesh(const Grid& grid, Mesh& mesh) -{ - auto g = grid::StructuredGrid(grid); - if( g ) - { - if( mpi::comm().size() != 1 ) - throw eckit::UserError("Cannot build_brick_dual_mesh with more than 1 task",Here()); - - mesh::Nodes& nodes = mesh.nodes(); - array::ArrayView xy = array::make_view( nodes.xy() ); - array::ArrayView dual_volumes = array::make_view( nodes.add( - Field("dual_volumes", array::make_datatype(), array::make_shape(nodes.size(),1) ) ) ); - array::ArrayView gidx = array::make_view( nodes.global_index() ); - - int c=0; - int n=0; - for(size_t jlat = 0; jlat < g.ny(); ++jlat) - { - double lat = g.y(jlat); - double latN = (jlat==0) ? 90. : 0.5*(lat+g.y(jlat-1)); - double latS = (jlat==g.ny()-1) ? -90. : 0.5*(lat+g.y(jlat+1)); - double dlat = (latN-latS); - double dlon = 360./static_cast(g.nx(jlat)); - - for(size_t jlon = 0; jlon < g.nx(jlat); ++jlon) - { - while( gidx(c) != n+1 ) c++; - ASSERT( xy(c,XX) == g.x(jlon,jlat) ); - ASSERT( xy(c,YY) == lat ); - dual_volumes(c) = dlon*dlat; - ++n; - } - + functionspace::NodeColumns nodes_fs( mesh ); + nodes_fs.haloExchange( nodes.field( "dual_volumes" ) ); + } + else { + throw eckit::BadCast( "Cannot build_brick_dual_mesh with mesh provided grid type", Here() ); } - - functionspace::NodeColumns nodes_fs( mesh ); - nodes_fs.haloExchange(nodes.field("dual_volumes")); - } - else - { - throw eckit::BadCast("Cannot build_brick_dual_mesh with mesh provided grid type",Here()); - } } -void build_centroid_dual_mesh( Mesh& mesh ) -{ - NOTIMP; - // This requires code below which has not been ported yet +void build_centroid_dual_mesh( Mesh& mesh ) { + NOTIMP; + // This requires code below which has not been ported yet } // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -void atlas__build_median_dual_mesh ( Mesh::Implementation* mesh) { - ATLAS_ERROR_HANDLING( Mesh m(mesh); build_median_dual_mesh(m); ); +void atlas__build_median_dual_mesh( Mesh::Implementation* mesh ) { + ATLAS_ERROR_HANDLING( Mesh m( mesh ); build_median_dual_mesh( m ); ); } -void atlas__build_centroid_dual_mesh ( Mesh::Implementation* mesh) { - ATLAS_ERROR_HANDLING( Mesh m(mesh); build_centroid_dual_mesh(m); ); +void atlas__build_centroid_dual_mesh( Mesh::Implementation* mesh ) { + ATLAS_ERROR_HANDLING( Mesh m( mesh ); build_centroid_dual_mesh( m ); ); } // ------------------------------------------------------------------ -} // namespace actions -} // namespace mesh -} // namespace atlas - +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/BuildDualMesh.h b/src/atlas/mesh/actions/BuildDualMesh.h index 7d5c37c80..1e5fbbdca 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.h +++ b/src/atlas/mesh/actions/BuildDualMesh.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -52,17 +53,16 @@ void build_centroid_dual_mesh( Mesh& mesh ); * | | | | * | # | # | # | # */ -void build_brick_dual_mesh(const Grid& grid, Mesh& mesh ); +void build_brick_dual_mesh( const Grid& grid, Mesh& mesh ); // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -extern "C" -{ - void atlas__build_median_dual_mesh (Mesh::Implementation* mesh); - void atlas__build_centroid_dual_mesh (Mesh::Implementation* mesh); +extern "C" { +void atlas__build_median_dual_mesh( Mesh::Implementation* mesh ); +void atlas__build_centroid_dual_mesh( Mesh::Implementation* mesh ); } // ------------------------------------------------------------------ -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/BuildEdges.cc b/src/atlas/mesh/actions/BuildEdges.cc index 21ffe01a2..f299551bf 100644 --- a/src/atlas/mesh/actions/BuildEdges.cc +++ b/src/atlas/mesh/actions/BuildEdges.cc @@ -4,34 +4,35 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include +#include "atlas/mesh/actions/BuildEdges.h" #include -#include #include -#include +#include #include +#include +#include +#include "atlas/array.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/IndexView.h" +#include "atlas/field/Field.h" #include "atlas/library/config.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/mesh/actions/BuildEdges.h" -#include "atlas/mesh/Nodes.h" #include "atlas/mesh/ElementType.h" -#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Elements.h" -#include "atlas/field/Field.h" +#include "atlas/mesh/HybridElements.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" #include "atlas/mesh/detail/AccumulateFacets.h" -#include "atlas/util/Unique.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/ErrorHandling.h" +#include "atlas/util/CoordinateEnums.h" #include "atlas/util/LonLatMicroDeg.h" #include "atlas/util/MicroDeg.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array.h" -#include "atlas/array/IndexView.h" -#include "atlas/runtime/ErrorHandling.h" -#include "atlas/parallel/mpi/mpi.h" +#include "atlas/util/Unique.h" using atlas::mesh::detail::accumulate_facets; using Topology = atlas::mesh::Nodes::Topology; @@ -42,405 +43,359 @@ namespace atlas { namespace mesh { namespace actions { - //---------------------------------------------------------------------------------------------------------------------- -namespace { // anonymous -struct Sort -{ - Sort() {} - Sort(gidx_t gid, int idx) - { - g = gid; - i = idx; - } - gidx_t g; - int i; - bool operator < (const Sort& other) const - { - return ( g < other.g ); - } +namespace { // anonymous +struct Sort { + Sort() {} + Sort( gidx_t gid, int idx ) { + g = gid; + i = idx; + } + gidx_t g; + int i; + bool operator<( const Sort& other ) const { return ( g < other.g ); } }; -} // anonymous namespace - -void build_element_to_edge_connectivity( Mesh& mesh ) -{ - ATLAS_TRACE(); - mesh::HybridElements::Connectivity& cell_edge_connectivity = mesh.cells().edge_connectivity(); - cell_edge_connectivity.clear(); - - // Allocate cell_edge_connectivity - for( size_t t=0; t init(mesh.cells().elements(t).size()*nb_edges_per_elem,cell_edge_connectivity.missing_value()); - cell_edge_connectivity.add(nb_elements,nb_edges_per_elem,init.data()); - } - - size_t nb_edges = mesh.edges().size(); - mesh::HybridElements::Connectivity& edge_cell_connectivity = mesh.edges().cell_connectivity(); - mesh::HybridElements::Connectivity& edge_node_connectivity = mesh.edges().node_connectivity(); - - bool has_pole_edges(false); - std::shared_ptr< array::ArrayView > is_pole_edge; - if( mesh.edges().has_field("is_pole_edge") ) - { - has_pole_edges = true; - is_pole_edge = std::shared_ptr< array::ArrayView > - ( new array::ArrayView( array::make_view( mesh.edges().field("is_pole_edge") ) ) ) ; - } - - // Sort edges for bit-reproducibility - std::vector edge_sort; edge_sort.reserve(nb_edges); - { - UniqueLonLat compute_uid( mesh ); +} // anonymous namespace + +void build_element_to_edge_connectivity( Mesh& mesh ) { + ATLAS_TRACE(); + mesh::HybridElements::Connectivity& cell_edge_connectivity = mesh.cells().edge_connectivity(); + cell_edge_connectivity.clear(); + + // Allocate cell_edge_connectivity + for ( size_t t = 0; t < mesh.cells().nb_types(); ++t ) { + size_t nb_elements = mesh.cells().elements( t ).size(); + size_t nb_edges_per_elem = mesh.cells().element_type( t ).nb_edges(); + std::vector init( mesh.cells().elements( t ).size() * nb_edges_per_elem, + cell_edge_connectivity.missing_value() ); + cell_edge_connectivity.add( nb_elements, nb_edges_per_elem, init.data() ); + } - for( size_t jedge=0; jedge> is_pole_edge; + if ( mesh.edges().has_field( "is_pole_edge" ) ) { + has_pole_edges = true; + is_pole_edge = std::shared_ptr>( + new array::ArrayView( array::make_view( mesh.edges().field( "is_pole_edge" ) ) ) ); + } - // Fill in cell_edge_connectivity - std::vector edge_cnt( mesh.cells().size() ); - for( size_t jedge=0; jedge edge_sort; + edge_sort.reserve( nb_edges ); { - idx_t elem = edge_cell_connectivity(iedge,j); - - if ( elem != edge_cell_connectivity.missing_value() ) - { - cell_edge_connectivity.set(elem,edge_cnt[elem]++, iedge); - } - else - { - if( !( has_pole_edges && (*is_pole_edge)(iedge) ) ) - { - if( j==0 ) - throw eckit::SeriousBug("edge has no element connected",Here()); - } - } + UniqueLonLat compute_uid( mesh ); + + for ( size_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 ); } - } + // Fill in cell_edge_connectivity + std::vector edge_cnt( mesh.cells().size() ); + for ( size_t jedge = 0; jedge < nb_edges; ++jedge ) { + int iedge = edge_sort[jedge].i; + for ( size_t j = 0; j < 2; ++j ) { + idx_t elem = edge_cell_connectivity( iedge, j ); - // Verify that all edges have been found - for( size_t jcell=0; jcell(mesh.cells().field("patch")); - if( patch(jcell) ) continue; + if ( elem != edge_cell_connectivity.missing_value() ) { + cell_edge_connectivity.set( elem, edge_cnt[elem]++, iedge ); + } + else { + if ( !( has_pole_edges && ( *is_pole_edge )( iedge ) ) ) { + if ( j == 0 ) throw eckit::SeriousBug( "edge has no element connected", Here() ); + } + } + } + } - for( size_t jcol=0; jcol gidx = array::make_view(mesh.nodes().global_index() ); - std::stringstream msg; msg << "Could not find edge " << jcol << " for " << mesh.cells().name(jcell) << " elem " << jcell << " with nodes ( "; - for( size_t jnode=0; jnode( mesh.cells().field( "patch" ) ); + if ( patch( jcell ) ) continue; + + for ( size_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() ); + std::stringstream msg; + msg << "Could not find edge " << jcol << " for " << mesh.cells().name( jcell ) << " elem " << jcell + << " with nodes ( "; + for ( size_t jnode = 0; jnode < mesh.cells().node_connectivity().cols( jcell ); ++jnode ) { + msg << gidx( mesh.cells().node_connectivity()( jcell, jnode ) ) << " "; + } + msg << ")"; + throw eckit::SeriousBug( msg.str(), Here() ); + } } - msg << ")"; - throw eckit::SeriousBug(msg.str(),Here()); - } } - } } +void build_node_to_edge_connectivity( Mesh& mesh ) { + mesh::Nodes& nodes = mesh.nodes(); + const size_t nb_edges = mesh.edges().size(); + mesh::HybridElements::Connectivity& edge_node_connectivity = mesh.edges().node_connectivity(); -void build_node_to_edge_connectivity( Mesh& mesh ) -{ - mesh::Nodes& nodes = mesh.nodes(); - const size_t nb_edges = mesh.edges().size(); + std::vector to_edge_size( nodes.size(), 0 ); + for ( size_t jedge = 0; jedge < nb_edges; ++jedge ) { + for ( int j = 0; j < 2; ++j ) { + ++to_edge_size[edge_node_connectivity( jedge, j )]; + } + } - mesh::HybridElements::Connectivity& edge_node_connectivity = mesh.edges().node_connectivity(); + mesh::Nodes::Connectivity& node_to_edge = nodes.edge_connectivity(); + node_to_edge.add( nodes.size(), to_edge_size.data() ); + for ( size_t jnode = 0; jnode < nodes.size(); ++jnode ) + to_edge_size[jnode] = 0; - std::vector to_edge_size (nodes.size(),0); - for(size_t jedge = 0; jedge < nb_edges; ++jedge) - { - for( int j=0; j<2; ++j) - { - ++to_edge_size[ edge_node_connectivity(jedge,j) ]; - } - } - - mesh::Nodes::Connectivity& node_to_edge = nodes.edge_connectivity(); - node_to_edge.add( nodes.size(), to_edge_size.data() ); - for( size_t jnode=0; jnode edge_sort(nb_edges); - for( size_t jedge=0; jedge edge_sort( nb_edges ); + for ( size_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 ( size_t jedge = 0; jedge < nb_edges; ++jedge ) { + size_t iedge = edge_sort[jedge].i; + for ( size_t j = 0; j < 2; ++j ) { + idx_t node = edge_node_connectivity( iedge, j ); + node_to_edge.set( node, to_edge_size[node]++, iedge ); + } } - } } -void accumulate_pole_edges( mesh::Nodes& nodes, std::vector& pole_edge_nodes, size_t& nb_pole_edges ) -{ - enum { NORTH=0, SOUTH=1 }; - - array::ArrayView xy = array::make_view( nodes.xy() ); - array::ArrayView flags = array::make_view( nodes.field( "flags" ) ); - array::ArrayView part = array::make_view( nodes.partition() ); - const size_t nb_nodes = nodes.size(); - - double min[2], max[2]; - min[XX] = std::numeric_limits::max(); - min[YY] = std::numeric_limits::max(); - max[XX] = -std::numeric_limits::max(); - max[YY] = -std::numeric_limits::max(); - for (size_t node=0; node > pole_nodes(2); - for (size_t node=0; node& pole_edge_nodes, size_t& nb_pole_edges ) { + enum { - int npart=-1; - for( std::set::iterator it=pole_nodes[NS].begin(); it!=pole_nodes[NS].end(); ++it) - { - int node = *it; - if( npart == -1 ) npart = part(node); - else if ( part(node) != npart ) - { - // Not implemented yet, when pole-lattitude is split. - std::stringstream msg; - msg << "Split pole-latitude is not supported yet... node "< xy = array::make_view( nodes.xy() ); + array::ArrayView flags = array::make_view( nodes.field( "flags" ) ); + array::ArrayView part = array::make_view( nodes.partition() ); + const size_t nb_nodes = nodes.size(); + + double min[2], max[2]; + min[XX] = std::numeric_limits::max(); + min[YY] = std::numeric_limits::max(); + max[XX] = -std::numeric_limits::max(); + max[YY] = -std::numeric_limits::max(); + for ( size_t node = 0; node < nb_nodes; ++node ) { + min[XX] = std::min( min[XX], xy( node, XX ) ); + min[YY] = std::min( min[YY], xy( node, YY ) ); + max[XX] = std::max( max[XX], xy( node, XX ) ); + max[YY] = std::max( max[YY], xy( node, YY ) ); + } + + ATLAS_TRACE_MPI( ALLREDUCE ) { + mpi::comm().allReduceInPlace( min, 2, eckit::mpi::min() ); + mpi::comm().allReduceInPlace( max, 2, eckit::mpi::max() ); + } + + double tol = 1e-6; + + // Collect all nodes closest to poles + std::vector> pole_nodes( 2 ); + for ( size_t node = 0; node < nb_nodes; ++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 ); } - } } - } - // Create connections over the poles and store in pole_edge_nodes - nb_pole_edges = 0; - for( size_t NS = 0; NS<2; ++NS ) - { - for( std::set::iterator it=pole_nodes[NS].begin(); it!=pole_nodes[NS].end(); ++it) + // Sanity check { - int node = *it; - if( !Topology::check(flags(node),Topology::PERIODIC|Topology::GHOST) ) - { - int x2 = microdeg( xy(node,XX) + 180. ); - for( std::set::iterator itr=pole_nodes[NS].begin(); itr!=pole_nodes[NS].end(); ++itr) - { - int other_node = *itr; - if( microdeg( xy(other_node,XX) ) == x2 ) - { - if( !Topology::check(flags(other_node),Topology::PERIODIC) ) - { - pole_edge_nodes.push_back(node); - pole_edge_nodes.push_back(other_node); - ++nb_pole_edges; + for ( size_t NS = 0; NS < 2; ++NS ) { + int npart = -1; + for ( std::set::iterator it = pole_nodes[NS].begin(); it != pole_nodes[NS].end(); ++it ) { + int node = *it; + if ( npart == -1 ) + npart = part( node ); + else if ( part( node ) != npart ) { + // Not implemented yet, when pole-lattitude is split. + std::stringstream msg; + msg << "Split pole-latitude is not supported yet... node " << node << "[p" << part( node ) + << "] should belong to part " << npart; + throw eckit::NotImplemented( msg.str(), Here() ); + } } - } } - } } - } + // Create connections over the poles and store in pole_edge_nodes + nb_pole_edges = 0; + for ( size_t NS = 0; NS < 2; ++NS ) { + for ( std::set::iterator it = pole_nodes[NS].begin(); it != pole_nodes[NS].end(); ++it ) { + int node = *it; + if ( !Topology::check( flags( node ), Topology::PERIODIC | Topology::GHOST ) ) { + int x2 = microdeg( xy( node, XX ) + 180. ); + for ( std::set::iterator itr = pole_nodes[NS].begin(); itr != pole_nodes[NS].end(); ++itr ) { + int other_node = *itr; + if ( microdeg( xy( other_node, XX ) ) == x2 ) { + if ( !Topology::check( flags( other_node ), Topology::PERIODIC ) ) { + pole_edge_nodes.push_back( node ); + pole_edge_nodes.push_back( other_node ); + ++nb_pole_edges; + } + } + } + } + } + } } +struct ComputeUniquePoleEdgeIndex { + // Already assumes that the edges cross the pole -struct ComputeUniquePoleEdgeIndex -{ - // Already assumes that the edges cross the pole - - ComputeUniquePoleEdgeIndex( const mesh::Nodes& nodes ) : - xy( array::make_view ( nodes.xy() ) ) - { - } + ComputeUniquePoleEdgeIndex( const mesh::Nodes& nodes ) : xy( array::make_view( nodes.xy() ) ) {} - gidx_t operator()( const mesh::Connectivity::Row& edge_nodes ) const - { - double centroid[2]; - centroid[XX] = 0.; - centroid[YY] = 0.; - for( size_t jnode=0; jnode<2; ++jnode ) - { - centroid[XX] += xy( edge_nodes(jnode), XX ); - centroid[YY] += xy( edge_nodes(jnode), YY ); + gidx_t operator()( const mesh::Connectivity::Row& edge_nodes ) const { + double centroid[2]; + centroid[XX] = 0.; + centroid[YY] = 0.; + for ( size_t jnode = 0; jnode < 2; ++jnode ) { + centroid[XX] += xy( edge_nodes( jnode ), XX ); + centroid[YY] += xy( edge_nodes( jnode ), YY ); + } + centroid[XX] /= 2.; + centroid[YY] /= 2.; + if ( centroid[YY] > 0 ) + centroid[YY] = 90.; + 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] ) ); } - centroid[XX] /= 2.; - centroid[YY] /= 2.; - if( centroid[YY] > 0 ) - centroid[YY] = 90.; - 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]) ); - } - - array::ArrayView xy; + + array::ArrayView xy; }; +void build_edges( Mesh& mesh ) { + mesh::Nodes& nodes = mesh.nodes(); + array::ArrayView part = array::make_view( nodes.partition() ); -void build_edges( Mesh& mesh ) -{ - mesh::Nodes& nodes = mesh.nodes(); - array::ArrayView part = array::make_view( nodes.partition() ); + size_t nb_nodes = nodes.size(); - size_t nb_nodes = nodes.size(); + // storage for edge-to-node-connectivity shape=(nb_edges,2) + std::vector edge_nodes_data; + std::vector edge_to_elem_data; + size_t nb_edges; + size_t nb_inner_edges; + idx_t missing_value; - // storage for edge-to-node-connectivity shape=(nb_edges,2) - std::vector< idx_t > edge_nodes_data; - std::vector< idx_t > edge_to_elem_data; - size_t nb_edges; - size_t nb_inner_edges; - idx_t missing_value; + accumulate_facets( mesh.cells(), mesh.nodes(), edge_nodes_data, edge_to_elem_data, nb_edges, nb_inner_edges, + missing_value ); + // Build edges + mesh.edges().add( new mesh::temporary::Line(), nb_edges, edge_nodes_data.data() ); + mesh::HybridElements::Connectivity& edge_nodes = mesh.edges().node_connectivity(); + mesh::HybridElements::Connectivity& cell_nodes = mesh.cells().node_connectivity(); - accumulate_facets(mesh.cells(),mesh.nodes(),edge_nodes_data,edge_to_elem_data,nb_edges,nb_inner_edges,missing_value); - // Build edges - mesh.edges().add( new mesh::temporary::Line(), nb_edges, edge_nodes_data.data() ); - mesh::HybridElements::Connectivity& edge_nodes = mesh.edges().node_connectivity(); - mesh::HybridElements::Connectivity& cell_nodes = mesh.cells().node_connectivity(); + UniqueLonLat compute_uid( mesh ); - UniqueLonLat compute_uid( mesh ); + array::IndexView edge_ridx = array::make_indexview( mesh.edges().remote_index() ); + array::ArrayView edge_part = array::make_view( mesh.edges().partition() ); + array::ArrayView edge_glb_idx = array::make_view( mesh.edges().global_index() ); + + ASSERT( cell_nodes.missing_value() == missing_value ); + for ( size_t edge = 0; edge < nb_edges; ++edge ) { + const int ip1 = edge_nodes( edge, 0 ); + const int ip2 = edge_nodes( edge, 1 ); + if ( compute_uid( ip1 ) > compute_uid( ip2 ) ) { + idx_t swapped[2] = {ip2, ip1}; + edge_nodes.set( edge, swapped ); + } - array::IndexView edge_ridx = array::make_indexview ( mesh.edges().remote_index() ); - array::ArrayView edge_part = array::make_view ( mesh.edges().partition() ); - array::ArrayView edge_glb_idx = array::make_view ( mesh.edges().global_index() ); + ASSERT( size_t( edge_nodes( edge, 0 ) ) < nb_nodes ); + ASSERT( size_t( edge_nodes( edge, 1 ) ) < nb_nodes ); + edge_glb_idx( edge ) = compute_uid( edge_nodes.row( edge ) ); + edge_part( edge ) = std::min( part( edge_nodes( edge, 0 ) ), part( edge_nodes( edge, 1 ) ) ); + edge_ridx( edge ) = edge; - ASSERT( cell_nodes.missing_value() == missing_value ); - for( size_t edge=0; edge compute_uid(ip2) ) - { - idx_t swapped[2] = {ip2,ip1}; - edge_nodes.set(edge,swapped); + const idx_t e1 = edge_to_elem_data[2 * edge + 0]; + const idx_t e2 = edge_to_elem_data[2 * edge + 1]; + + ASSERT( e1 != cell_nodes.missing_value() ); + if ( e2 == cell_nodes.missing_value() ) { + // do nothing + } + else if ( compute_uid( cell_nodes.row( e1 ) ) > compute_uid( cell_nodes.row( e2 ) ) ) { + edge_to_elem_data[edge * 2 + 0] = e2; + edge_to_elem_data[edge * 2 + 1] = e1; + } } - ASSERT( size_t(edge_nodes(edge,0)) < nb_nodes ); - ASSERT( size_t(edge_nodes(edge,1)) < nb_nodes ); - edge_glb_idx(edge) = compute_uid(edge_nodes.row(edge)); - edge_part(edge) = std::min( part(edge_nodes(edge,0)), part(edge_nodes(edge,1) ) ); - edge_ridx(edge) = edge; + mesh.edges().cell_connectivity().add( nb_edges, 2, edge_to_elem_data.data() ); - const idx_t e1 = edge_to_elem_data[2*edge+0]; - const idx_t e2 = edge_to_elem_data[2*edge+1]; + build_element_to_edge_connectivity( mesh ); +} - ASSERT( e1 != cell_nodes.missing_value() ); - if( e2 == cell_nodes.missing_value() ) { - // do nothing - } - else if ( compute_uid(cell_nodes.row(e1)) > compute_uid(cell_nodes.row(e2)) ) { - edge_to_elem_data[edge*2+0] = e2; - edge_to_elem_data[edge*2+1] = e1; - } - } +void build_pole_edges( Mesh& mesh ) { + mesh::Nodes& nodes = mesh.nodes(); + mesh::HybridElements& edges = mesh.edges(); - mesh.edges().cell_connectivity().add( nb_edges, 2, edge_to_elem_data.data() ); + size_t nb_cell_edges = edges.size(); - build_element_to_edge_connectivity(mesh); -} + size_t nb_pole_edges; + std::vector pole_edge_nodes; + accumulate_pole_edges( nodes, pole_edge_nodes, nb_pole_edges ); + + edges.add( new mesh::temporary::Line(), nb_pole_edges, pole_edge_nodes.data() ); + + if ( !edges.has_field( "is_pole_edge" ) ) + edges.add( Field( "is_pole_edge", array::make_datatype(), array::make_shape( edges.size() ) ) ); + + array::ArrayView node_part = array::make_view( nodes.partition() ); + + array::ArrayView edge_glb_idx = array::make_view( edges.global_index() ); + array::ArrayView edge_part = array::make_view( edges.partition() ); + array::IndexView edge_ridx = array::make_indexview( edges.remote_index() ); + array::ArrayView is_pole_edge = array::make_view( edges.field( "is_pole_edge" ) ); -void build_pole_edges( Mesh& mesh ) -{ - mesh::Nodes& nodes = mesh.nodes(); - mesh::HybridElements& edges = mesh.edges(); - - size_t nb_cell_edges = edges.size(); - - size_t nb_pole_edges; - std::vector pole_edge_nodes; - accumulate_pole_edges( nodes, pole_edge_nodes, nb_pole_edges ); - - edges.add(new mesh::temporary::Line(), nb_pole_edges, pole_edge_nodes.data() ); - - if( ! edges.has_field("is_pole_edge") ) - edges.add( Field("is_pole_edge", array::make_datatype(), array::make_shape(edges.size()))); - - array::ArrayView node_part = array::make_view( nodes.partition() ); - - array::ArrayView edge_glb_idx = array::make_view( edges.global_index() ); - array::ArrayView edge_part = array::make_view( edges.partition() ); - array::IndexView edge_ridx = array::make_indexview( edges.remote_index() ); - array::ArrayView is_pole_edge = array::make_view( edges.field( "is_pole_edge" ) ); - - mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); - MultiBlockConnectivity& edge_to_elem = edges.cell_connectivity(); - edge_to_elem.add(nb_pole_edges,2); - - for(size_t edge=0; edge namespace atlas { class Mesh; +namespace mesh { +namespace detail { +class MeshImpl; +} +} // namespace mesh +} // namespace atlas +namespace atlas { namespace mesh { namespace actions { @@ -26,16 +33,13 @@ void build_node_to_edge_connectivity( Mesh& mesh ); // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -extern "C" -{ - void atlas__build_edges (Mesh::Implementation* mesh); - void atlas__build_pole_edges (Mesh::Implementation* mesh); - void atlas__build_node_to_edge_connectivity (Mesh::Implementation* mesh); +extern "C" { +void atlas__build_edges( mesh::detail::MeshImpl* mesh ); +void atlas__build_pole_edges( mesh::detail::MeshImpl* mesh ); +void atlas__build_node_to_edge_connectivity( mesh::detail::MeshImpl* mesh ); } // ------------------------------------------------------------------ -} // namespace actions -} // namespace mesh -} // namespace atlas - -#endif // BuildEdges_h +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 4374bd113..3f0fba3d9 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -4,13 +4,14 @@ * 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 + * 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 "atlas/array.h" @@ -29,7 +30,6 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/LonLatMicroDeg.h" @@ -38,18 +38,18 @@ //#define DEBUG_OUTPUT #ifdef DEBUG_OUTPUT -#include "atlas/output/Gmsh.h" #include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildXYZField.h" +#include "atlas/output/Gmsh.h" #endif // #define ATLAS_103 // #define ATLAS_103_SORT -using atlas::mesh::detail::accumulate_facets; using atlas::mesh::detail::PeriodicTransform; -using atlas::util::UniqueLonLat; +using atlas::mesh::detail::accumulate_facets; using atlas::util::LonLatMicroDeg; +using atlas::util::UniqueLonLat; using atlas::util::microdeg; using Topology = atlas::mesh::Nodes::Topology; @@ -57,230 +57,207 @@ namespace atlas { namespace mesh { namespace actions { -struct Entity -{ - Entity(gidx_t gid, int idx) - { - g = gid; - i = idx; - } - gidx_t g; - gidx_t i; - bool operator < (const Entity& other) const - { - return ( g Those specific periodic points at the EAST boundary are not checked for uid, -// and could receive different gidx for different tasks - - - // unused // int mypart = mpi::comm().rank(); - int nparts = mpi::comm().size(); - size_t root = 0; - - array::ArrayView nodes_glb_idx = array::make_view ( nodes.global_index() ); - //nodes_glb_idx.dump( Log::info() ); -// ATLAS_DEBUG( "min = " << nodes.global_index().metadata().getLong("min") ); -// ATLAS_DEBUG( "max = " << nodes.global_index().metadata().getLong("max") ); -// ATLAS_DEBUG( "human_readable = " << nodes.global_index().metadata().getBool("human_readable") ); - gidx_t glb_idx_max = 0; - - std::vector points_to_edit; - - if( do_all ) { - points_to_edit.resize(nodes_glb_idx.size()); - for( size_t i=0; i glb_idx(points_to_edit.size()); - int nb_nodes = glb_idx.size(); - for( size_t i=0; i recvcounts(mpi::comm().size()); - std::vector recvdispls(mpi::comm().size()); - - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gather(nb_nodes, recvcounts, root); - } - int glb_nb_nodes = std::accumulate(recvcounts.begin(),recvcounts.end(),0); - - recvdispls[0]=0; - for (int jpart=1; jpart glb_idx_gathered( glb_nb_nodes ); - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), - glb_idx_gathered.data(), - recvcounts.data(), recvdispls.data(), root); - } - - - // 2) Sort all global indices, and renumber from 1 to glb_nb_edges - std::vector node_sort; node_sort.reserve(glb_nb_nodes); - for( size_t jnode=0; jnode 0 && node_sort[jnode].g != node_sort[jnode-1].g ) { - ++gid; +void make_nodes_global_index_human_readable( const mesh::actions::BuildHalo& build_halo, mesh::Nodes& nodes, + bool do_all ) { + ATLAS_TRACE(); + // TODO: ATLAS-14: fix renumbering of EAST periodic boundary points + // --> Those specific periodic points at the EAST boundary are not checked for + // uid, + // and could receive different gidx for different tasks + + // unused // int mypart = mpi::comm().rank(); + int nparts = mpi::comm().size(); + size_t root = 0; + + array::ArrayView nodes_glb_idx = array::make_view( nodes.global_index() ); + // nodes_glb_idx.dump( Log::info() ); + // ATLAS_DEBUG( "min = " << nodes.global_index().metadata().getLong("min") ); + // ATLAS_DEBUG( "max = " << nodes.global_index().metadata().getLong("max") ); + // ATLAS_DEBUG( "human_readable = " << + // nodes.global_index().metadata().getBool("human_readable") ); + gidx_t glb_idx_max = 0; + + std::vector points_to_edit; + + if ( do_all ) { + points_to_edit.resize( nodes_glb_idx.size() ); + for ( size_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 ) + points_to_edit[i] = build_halo.periodic_points_local_index_[i]; } - int inode = node_sort[jnode].i; - glb_idx_gathered[inode] = gid; - } - // 3) Scatter renumbered back - ATLAS_TRACE_MPI( SCATTER ) { - mpi::comm().scatterv(glb_idx_gathered.data(), - recvcounts.data(), recvdispls.data(), - glb_idx.data(), glb_idx.size(), root); - } + std::vector glb_idx( points_to_edit.size() ); + int nb_nodes = glb_idx.size(); + for ( size_t i = 0; i < nb_nodes; ++i ) + glb_idx[i] = nodes_glb_idx( points_to_edit[i] ); - for( int jnode=0; jnode recvcounts( mpi::comm().size() ); + std::vector recvdispls( mpi::comm().size() ); + + ATLAS_TRACE_MPI( GATHER ) { mpi::comm().gather( nb_nodes, recvcounts, root ); } + int glb_nb_nodes = std::accumulate( recvcounts.begin(), recvcounts.end(), 0 ); + + recvdispls[0] = 0; + for ( int jpart = 1; jpart < nparts; ++jpart ) { // start at 1 + recvdispls[jpart] = recvcounts[jpart - 1] + recvdispls[jpart - 1]; + } + + std::vector glb_idx_gathered( glb_nb_nodes ); + ATLAS_TRACE_MPI( GATHER ) { + mpi::comm().gatherv( glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), + recvdispls.data(), root ); + } + + // 2) Sort all global indices, and renumber from 1 to glb_nb_edges + std::vector node_sort; + node_sort.reserve( glb_nb_nodes ); + for ( size_t jnode = 0; jnode < glb_idx_gathered.size(); ++jnode ) { + node_sort.push_back( Entity( glb_idx_gathered[jnode], jnode ) ); + } + + ATLAS_TRACE_SCOPE( "sort on rank 0" ) { std::sort( node_sort.begin(), node_sort.end() ); } + + gidx_t gid = glb_idx_max + 1; + for ( size_t jnode = 0; jnode < node_sort.size(); ++jnode ) { + if ( jnode > 0 && node_sort[jnode].g != node_sort[jnode - 1].g ) { ++gid; } + int inode = node_sort[jnode].i; + glb_idx_gathered[inode] = gid; + } + + // 3) Scatter renumbered back + ATLAS_TRACE_MPI( SCATTER ) { + mpi::comm().scatterv( glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), + glb_idx.size(), root ); + } + + for ( int jnode = 0; jnode < nb_nodes; ++jnode ) { + nodes_glb_idx( points_to_edit[jnode] ) = glb_idx[jnode]; + } + // nodes_glb_idx.dump( Log::info() ); + // Log::info() << std::endl; + nodes.global_index().metadata().set( "human_readable", true ); } // ------------------------------------------------------------------------------------- -void make_cells_global_index_human_readable( const mesh::actions::BuildHalo& build_halo, mesh::Cells& cells, bool do_all ) -{ - ATLAS_TRACE(); - - int nparts = mpi::comm().size(); - size_t root = 0; - - array::ArrayView cells_glb_idx = array::make_view ( cells.global_index() ); -// ATLAS_DEBUG( "min = " << cells.global_index().metadata().getLong("min") ); -// ATLAS_DEBUG( "max = " << cells.global_index().metadata().getLong("max") ); -// ATLAS_DEBUG( "human_readable = " << cells.global_index().metadata().getBool("human_readable") ); - gidx_t glb_idx_max = 0; - - std::vector cells_to_edit; - - if( do_all ) { - cells_to_edit.resize(cells_glb_idx.size()); - for( size_t i=0; i glb_idx(cells_to_edit.size()); - int nb_cells = glb_idx.size(); - for( size_t i=0; i recvcounts(mpi::comm().size()); - std::vector recvdispls(mpi::comm().size()); - - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gather(nb_cells, recvcounts, root); - } - int glb_nb_cells = std::accumulate(recvcounts.begin(),recvcounts.end(),0); - - recvdispls[0]=0; - for (int jpart=1; jpart glb_idx_gathered( glb_nb_cells ); - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), - glb_idx_gathered.data(), - recvcounts.data(), recvdispls.data(), root); - } - - - // 2) Sort all global indices, and renumber from 1 to glb_nb_edges - std::vector cell_sort; cell_sort.reserve(glb_nb_cells); - for( size_t jnode=0; jnode 0 && cell_sort[jcell].g != cell_sort[jcell-1].g ) { - ++gid; +void make_cells_global_index_human_readable( const mesh::actions::BuildHalo& build_halo, mesh::Cells& cells, + bool do_all ) { + ATLAS_TRACE(); + + int nparts = mpi::comm().size(); + size_t root = 0; + + array::ArrayView cells_glb_idx = array::make_view( cells.global_index() ); + // ATLAS_DEBUG( "min = " << cells.global_index().metadata().getLong("min") ); + // ATLAS_DEBUG( "max = " << cells.global_index().metadata().getLong("max") ); + // ATLAS_DEBUG( "human_readable = " << + // cells.global_index().metadata().getBool("human_readable") ); + gidx_t glb_idx_max = 0; + + std::vector cells_to_edit; + + if ( do_all ) { + cells_to_edit.resize( cells_glb_idx.size() ); + for ( size_t i = 0; i < cells_glb_idx.size(); ++i ) + cells_to_edit[i] = i; + } + else { + glb_idx_max = cells.global_index().metadata().getLong( "max", 0 ); + cells_to_edit.resize( build_halo.periodic_cells_local_index_.size() ); + for ( size_t i = 0; i < cells_to_edit.size(); ++i ) + cells_to_edit[i] = build_halo.periodic_cells_local_index_[i]; + } + + std::vector glb_idx( cells_to_edit.size() ); + int nb_cells = glb_idx.size(); + for ( size_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 + + std::vector recvcounts( mpi::comm().size() ); + std::vector recvdispls( mpi::comm().size() ); + + ATLAS_TRACE_MPI( GATHER ) { mpi::comm().gather( nb_cells, recvcounts, root ); } + int glb_nb_cells = std::accumulate( recvcounts.begin(), recvcounts.end(), 0 ); + + recvdispls[0] = 0; + for ( int jpart = 1; jpart < nparts; ++jpart ) { // start at 1 + recvdispls[jpart] = recvcounts[jpart - 1] + recvdispls[jpart - 1]; } - int icell = cell_sort[jcell].i; - glb_idx_gathered[icell] = gid; - } - // 3) Scatter renumbered back - ATLAS_TRACE_MPI( SCATTER ) { - mpi::comm().scatterv(glb_idx_gathered.data(), - recvcounts.data(), recvdispls.data(), - glb_idx.data(), glb_idx.size(), root); - } + std::vector glb_idx_gathered( glb_nb_cells ); + ATLAS_TRACE_MPI( GATHER ) { + mpi::comm().gatherv( glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), + recvdispls.data(), root ); + } + + // 2) Sort all global indices, and renumber from 1 to glb_nb_edges + std::vector cell_sort; + cell_sort.reserve( glb_nb_cells ); + for ( size_t jnode = 0; jnode < glb_idx_gathered.size(); ++jnode ) { + cell_sort.push_back( Entity( glb_idx_gathered[jnode], jnode ) ); + } + + ATLAS_TRACE_SCOPE( "sort on rank 0" ) { std::sort( cell_sort.begin(), cell_sort.end() ); } + + gidx_t gid = glb_idx_max + 1; + for ( size_t jcell = 0; jcell < cell_sort.size(); ++jcell ) { + if ( jcell > 0 && cell_sort[jcell].g != cell_sort[jcell - 1].g ) { ++gid; } + int icell = cell_sort[jcell].i; + glb_idx_gathered[icell] = gid; + } - for( int jcell=0; jcell > Node2Elem; +typedef std::vector> Node2Elem; -void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) -{ - ATLAS_TRACE(); +void build_lookup_node2elem( const Mesh& mesh, Node2Elem& node2elem ) { + ATLAS_TRACE(); - auto cell_gidx = array::make_view( mesh.cells().global_index() ); - auto node_gidx = array::make_view( mesh.nodes().global_index() ); + auto cell_gidx = array::make_view( mesh.cells().global_index() ); + auto node_gidx = array::make_view( mesh.nodes().global_index() ); - const mesh::Nodes& nodes = mesh.nodes(); + const mesh::Nodes& nodes = mesh.nodes(); - node2elem.resize(nodes.size()); - for( size_t jnode=0; jnode( mesh.cells().field("patch") ); + const mesh::HybridElements::Connectivity& elem_nodes = mesh.cells().node_connectivity(); + auto patched = array::make_view( mesh.cells().field( "patch" ) ); - size_t nb_elems = mesh.cells().size(); - for (size_t elem=0; elem& bdry_nodes ) { + ATLAS_TRACE(); -void accumulate_partition_bdry_nodes_old( Mesh& mesh, std::vector& bdry_nodes ) -{ - ATLAS_TRACE(); - - std::set bdry_nodes_set; - - std::vector< idx_t > facet_nodes; - std::vector< idx_t > connectivity_facet_to_elem; - - facet_nodes.reserve(mesh.nodes().size()*4); - connectivity_facet_to_elem.reserve(facet_nodes.capacity()*2); - - size_t nb_facets(0); - size_t nb_inner_facets(0); - idx_t missing_value; - accumulate_facets( - /*in*/ mesh.cells(), - /*in*/ mesh.nodes(), - /*out*/ facet_nodes, // shape(nb_facets,nb_nodes_per_facet) - /*out*/ connectivity_facet_to_elem, - /*out*/ nb_facets, - /*out*/ nb_inner_facets, - /*out*/ missing_value ); - - for( size_t jface=0; jface bdry_nodes_set; + + std::vector facet_nodes; + std::vector connectivity_facet_to_elem; + + facet_nodes.reserve( mesh.nodes().size() * 4 ); + connectivity_facet_to_elem.reserve( facet_nodes.capacity() * 2 ); + + size_t nb_facets( 0 ); + size_t nb_inner_facets( 0 ); + idx_t missing_value; + accumulate_facets( + /*in*/ mesh.cells(), + /*in*/ mesh.nodes(), + /*out*/ facet_nodes, // shape(nb_facets,nb_nodes_per_facet) + /*out*/ connectivity_facet_to_elem, + /*out*/ nb_facets, + /*out*/ nb_inner_facets, + /*out*/ missing_value ); + + for ( size_t jface = 0; jface < nb_facets; ++jface ) { + if ( connectivity_facet_to_elem[jface * 2 + 1] == missing_value ) { + for ( size_t jnode = 0; jnode < 2; ++jnode ) // 2 nodes per face + { + bdry_nodes_set.insert( facet_nodes[jface * 2 + jnode] ); + } + } } - } - bdry_nodes = std::vector( bdry_nodes_set.begin(), bdry_nodes_set.end()); + bdry_nodes = std::vector( bdry_nodes_set.begin(), bdry_nodes_set.end() ); } - -void accumulate_partition_bdry_nodes( Mesh& mesh, size_t halo, std::vector& bdry_nodes ) -{ +void accumulate_partition_bdry_nodes( Mesh& mesh, size_t halo, std::vector& bdry_nodes ) { #ifndef ATLAS_103 - /* deprecated */ - accumulate_partition_bdry_nodes_old(mesh,bdry_nodes); + /* deprecated */ + accumulate_partition_bdry_nodes_old( mesh, bdry_nodes ); #else - ATLAS_TRACE(); - const Mesh::Polygon& polygon = mesh.polygon(halo); - bdry_nodes = std::vector( polygon.begin(), polygon.end() ); + ATLAS_TRACE(); + const Mesh::Polygon& polygon = mesh.polygon( halo ); + bdry_nodes = std::vector( polygon.begin(), polygon.end() ); #endif #ifdef ATLAS_103_SORT - /* not required */ - std::sort(bdry_nodes.begin(),bdry_nodes.end()); + /* not required */ + std::sort( bdry_nodes.begin(), bdry_nodes.end() ); #endif } -template< typename Predicate > -std::vector filter_nodes(std::vector nodes, const Predicate& predicate ) -{ - std::vector filtered; filtered.reserve(nodes.size()); - for( int inode : nodes ) { - if( predicate(inode) ) - filtered.push_back(inode); - } - return filtered; +template +std::vector filter_nodes( std::vector nodes, const Predicate& predicate ) { + std::vector filtered; + filtered.reserve( nodes.size() ); + for ( int inode : nodes ) { + if ( predicate( inode ) ) filtered.push_back( inode ); + } + return filtered; } -class Notification -{ +class Notification { public: - void add_error(const std::string& note, const eckit::CodeLocation& loc ) - { - notes.push_back( note + " @ " + std::string(loc) ); - } - void add_error(const std::string& note ) - { - notes.push_back( note ); - } - - bool error() const { return notes.size() > 0; } - void reset() { notes.clear(); } - - std::string str() const - { - std::stringstream stream; - for(size_t jnote = 0; jnote < notes.size(); ++jnote) - { - if ( jnote > 0 ) stream << "\n"; - stream << notes[jnote]; + void add_error( const std::string& note, const eckit::CodeLocation& loc ) { + notes.push_back( note + " @ " + std::string( loc ) ); } - return stream.str(); - } + void add_error( const std::string& note ) { notes.push_back( note ); } - operator std::string() const { return str(); } + bool error() const { return notes.size() > 0; } + void reset() { notes.clear(); } + + std::string str() const { + std::stringstream stream; + for ( size_t jnote = 0; jnote < notes.size(); ++jnote ) { + if ( jnote > 0 ) stream << "\n"; + stream << notes[jnote]; + } + return stream.str(); + } + + operator std::string() const { return str(); } private: - friend std::ostream& operator<<(std::ostream& s, const Notification& notes) { s << notes.str(); return s; } + friend std::ostream& operator<<( std::ostream& s, const Notification& notes ) { + s << notes.str(); + return s; + } private: - std::vector notes; + std::vector notes; }; - -typedef std::map Uid2Node; -void build_lookup_uid2node( Mesh& mesh, Uid2Node& uid2node ) -{ - ATLAS_TRACE(); - Notification notes; - mesh::Nodes& nodes = mesh.nodes(); - array::ArrayView xy = array::make_view ( nodes.xy() ); - array::ArrayView glb_idx = array::make_view ( nodes.global_index() ); - size_t nb_nodes = nodes.size(); - - UniqueLonLat compute_uid(mesh); - - uid2node.clear(); - for( size_t jnode=0; jnode Uid2Node; +void build_lookup_uid2node( Mesh& mesh, Uid2Node& uid2node ) { + ATLAS_TRACE(); + Notification notes; + mesh::Nodes& nodes = mesh.nodes(); + array::ArrayView xy = array::make_view( nodes.xy() ); + array::ArrayView glb_idx = array::make_view( nodes.global_index() ); + size_t nb_nodes = nodes.size(); + + UniqueLonLat compute_uid( mesh ); + + uid2node.clear(); + for ( size_t jnode = 0; jnode < nb_nodes; ++jnode ) { + uid_t uid = compute_uid( jnode ); + bool inserted = uid2node.insert( std::make_pair( uid, jnode ) ).second; + if ( not inserted ) { + int other = uid2node[uid]; + std::stringstream msg; + msg << "Node uid: " << uid << " " << glb_idx( jnode ) << " (" << xy( jnode, XX ) << "," << xy( jnode, YY ) + << ") has already been added as node " << glb_idx( other ) << " (" << xy( other, XX ) << "," + << xy( other, YY ) << ")"; + notes.add_error( msg.str() ); + } } - } - if( notes.error() ) - throw eckit::SeriousBug(notes.str(),Here()); + if ( notes.error() ) throw eckit::SeriousBug( notes.str(), Here() ); } -void accumulate_elements( const Mesh& mesh, - const mpi::BufferView& request_node_uid, - const Uid2Node& uid2node, - const Node2Elem& node2elem, - std::vector& found_elements, - std::set< uid_t >& new_nodes_uid ) -{ - //ATLAS_TRACE(); - const mesh::HybridElements::Connectivity &elem_nodes = mesh.cells().node_connectivity(); - const auto elem_part = array::make_view( mesh.cells().partition() ); - - size_t nb_nodes = request_node_uid.size(); - const size_t mpi_rank = mpi::comm().rank(); - - std::set< idx_t > found_elements_set; - - for( size_t jnode=0; jnodesecond; - } - if( inode != -1 && size_t(inode) < node2elem.size() ) - { - for(size_t jelem = 0; jelem < node2elem[inode].size(); ++jelem) - { - idx_t e = node2elem[inode][jelem]; - if( size_t(elem_part(e)) == mpi_rank ) - { - found_elements_set.insert( e ); +void accumulate_elements( const Mesh& mesh, const mpi::BufferView& request_node_uid, const Uid2Node& uid2node, + const Node2Elem& node2elem, std::vector& found_elements, + std::set& new_nodes_uid ) { + // ATLAS_TRACE(); + const mesh::HybridElements::Connectivity& elem_nodes = mesh.cells().node_connectivity(); + const auto elem_part = array::make_view( mesh.cells().partition() ); + + size_t nb_nodes = request_node_uid.size(); + const size_t mpi_rank = mpi::comm().rank(); + + std::set found_elements_set; + + for ( size_t jnode = 0; jnode < nb_nodes; ++jnode ) { + uid_t uid = request_node_uid( jnode ); + + int inode = -1; + // search and get node index for uid + Uid2Node::const_iterator found = uid2node.find( uid ); + if ( found != uid2node.end() ) { inode = found->second; } + if ( inode != -1 && size_t( inode ) < node2elem.size() ) { + for ( size_t jelem = 0; jelem < node2elem[inode].size(); ++jelem ) { + idx_t e = node2elem[inode][jelem]; + if ( size_t( elem_part( e ) ) == mpi_rank ) { found_elements_set.insert( e ); } + } } - } } - } - // found_bdry_elements_set now contains elements for the nodes - found_elements = std::vector( found_elements_set.begin(), found_elements_set.end()); + // found_bdry_elements_set now contains elements for the nodes + found_elements = std::vector( found_elements_set.begin(), found_elements_set.end() ); - UniqueLonLat compute_uid( mesh ); + UniqueLonLat compute_uid( mesh ); - // Collect all nodes - new_nodes_uid.clear(); - for(size_t jelem = 0; jelem < found_elements.size(); ++jelem) - { - idx_t e = found_elements[jelem]; + // Collect all nodes + new_nodes_uid.clear(); + for ( size_t jelem = 0; jelem < found_elements.size(); ++jelem ) { + idx_t e = found_elements[jelem]; - size_t nb_elem_nodes = elem_nodes.cols(e); - for( size_t n=0; n > node_part; + struct Buffers { + std::vector> node_part; - std::vector< std::vector > node_ridx; + std::vector> node_ridx; - std::vector< std::vector > node_flags; + std::vector> node_flags; - std::vector< std::vector > node_glb_idx; + std::vector> node_glb_idx; - std::vector< std::vector > node_xy; + std::vector> node_xy; - std::vector< std::vector > elem_glb_idx; + std::vector> elem_glb_idx; - std::vector< std::vector > elem_nodes_id; + std::vector> elem_nodes_id; - std::vector< std::vector > elem_nodes_displs; + std::vector> elem_nodes_displs; - std::vector< std::vector > elem_part; + std::vector> elem_part; - std::vector< std::vector > elem_type; + std::vector> elem_type; - Buffers(Mesh& mesh) - { - const size_t mpi_size = mpi::comm().size(); - - node_part.resize(mpi_size); - node_ridx.resize(mpi_size); - node_flags.resize(mpi_size); - node_glb_idx.resize(mpi_size); - node_xy.resize(mpi_size); - elem_glb_idx.resize(mpi_size); - elem_nodes_id.resize(mpi_size); - elem_nodes_displs.resize(mpi_size); - elem_part.resize(mpi_size); - elem_type.resize(mpi_size); - } + Buffers( Mesh& mesh ) { + const size_t mpi_size = mpi::comm().size(); - void print( std::ostream& os ) const - { - const size_t mpi_size = mpi::comm().size(); - os << "Nodes\n" - << "-----\n"; - size_t n(0); - for( size_t jpart=0; jpart new_periodic_ghost_points; - std::vector< std::vector > new_periodic_ghost_cells; - } status; + friend std::ostream& operator<<( std::ostream& out, const Buffers& b ) { + b.print( out ); + return out; + } + }; -public: + static void all_to_all( Buffers& send, Buffers& recv ) { + ATLAS_TRACE(); + const eckit::mpi::Comm& comm = mpi::comm(); + + ATLAS_TRACE_MPI( ALLTOALL ) { + comm.allToAll( send.node_glb_idx, recv.node_glb_idx ); + comm.allToAll( send.node_part, recv.node_part ); + comm.allToAll( send.node_ridx, recv.node_ridx ); + comm.allToAll( send.node_flags, recv.node_flags ); + comm.allToAll( send.node_xy, recv.node_xy ); + comm.allToAll( send.elem_glb_idx, recv.elem_glb_idx ); + comm.allToAll( send.elem_nodes_id, recv.elem_nodes_id ); + comm.allToAll( send.elem_part, recv.elem_part ); + comm.allToAll( send.elem_type, recv.elem_type ); + comm.allToAll( send.elem_nodes_displs, recv.elem_nodes_displs ); + } + } - BuildHalo& builder_; - Mesh& mesh; - array::ArrayView xy; - array::ArrayView lonlat; - array::ArrayView glb_idx; - array::ArrayView part; - array::IndexView ridx; - array::ArrayView flags; - array::ArrayView ghost; - mesh::HybridElements::Connectivity* elem_nodes; - array::ArrayView elem_part; - array::ArrayView elem_glb_idx; - - std::vector bdry_nodes; - Node2Elem node_to_elem; - Uid2Node uid2node; - UniqueLonLat compute_uid; - size_t halo; + struct Status { + std::vector new_periodic_ghost_points; + std::vector> new_periodic_ghost_cells; + } status; +public: + BuildHalo& builder_; + Mesh& mesh; + array::ArrayView xy; + array::ArrayView lonlat; + array::ArrayView glb_idx; + array::ArrayView part; + array::IndexView ridx; + array::ArrayView flags; + array::ArrayView ghost; + mesh::HybridElements::Connectivity* elem_nodes; + array::ArrayView elem_part; + array::ArrayView elem_glb_idx; + + std::vector bdry_nodes; + Node2Elem node_to_elem; + Uid2Node uid2node; + UniqueLonLat compute_uid; + size_t halo; public: - BuildHaloHelper( BuildHalo& builder, Mesh& _mesh ): - builder_( builder ), - mesh(_mesh), - xy ( array::make_view ( mesh.nodes().xy() ) ), - lonlat ( array::make_view ( mesh.nodes().lonlat() ) ), - glb_idx ( array::make_view ( mesh.nodes().global_index() ) ), - part ( array::make_view ( mesh.nodes().partition() ) ), - ridx ( array::make_indexview ( mesh.nodes().remote_index() ) ), - flags ( array::make_view ( mesh.nodes().field("flags") ) ), - ghost ( array::make_view ( mesh.nodes().ghost() ) ), - elem_nodes ( &mesh.cells().node_connectivity() ), - elem_part ( array::make_view ( mesh.cells().partition() ) ), - elem_glb_idx ( array::make_view ( mesh.cells().global_index() ) ), - compute_uid(mesh) - { - halo = 0; - mesh.metadata().get("halo",halo); - // update(); - } - - void update() - { - compute_uid.update(); - mesh::Nodes& nodes = mesh.nodes(); - xy = array::make_view ( nodes.xy() ); - lonlat = array::make_view ( nodes.lonlat() ); - glb_idx = array::make_view ( nodes.global_index() ); - part = array::make_view ( nodes.partition() ); - ridx = array::make_indexview ( nodes.remote_index() ); - flags = array::make_view ( nodes.field("flags") ); - ghost = array::make_view ( nodes.ghost() ); - - elem_nodes = &mesh.cells().node_connectivity(); - elem_part = array::make_view ( mesh.cells().partition() ); - elem_glb_idx = array::make_view ( mesh.cells().global_index() ); - } - - template< typename NodeContainer, typename ElementContainer > - void fill_sendbuffer(Buffers& buf,const NodeContainer& nodes_uid, const ElementContainer& elems, const int p) - { - //ATLAS_TRACE(); - - int nb_nodes = nodes_uid.size(); - buf.node_glb_idx[p].resize(nb_nodes); - buf.node_part [p].resize(nb_nodes); - buf.node_ridx [p].resize(nb_nodes); - buf.node_flags [p].resize(nb_nodes,Topology::NONE); - buf.node_xy [p].resize(2*nb_nodes); - - int jnode=0; - typename NodeContainer::iterator it; - for( it=nodes_uid.begin(); it!=nodes_uid.end(); ++it, ++jnode ) - { - uid_t uid = *it; - - Uid2Node::iterator found = uid2node.find( uid ); - if( found != uid2node.end() ) // Point exists inside domain - { - int node = found->second; - buf.node_glb_idx[p][jnode] = glb_idx(node); - buf.node_part [p][jnode] = part (node); - buf.node_ridx [p][jnode] = ridx (node); - buf.node_xy [p][jnode*2+XX] = xy (node,XX); - buf.node_xy [p][jnode*2+YY] = xy (node,YY); - Topology::set(buf.node_flags[p][jnode],flags(node)|Topology::GHOST); - } - else - { - Log::warning() << "Node with uid " << uid << " needed by ["<( mesh.nodes().xy() ) ), + lonlat( array::make_view( mesh.nodes().lonlat() ) ), + glb_idx( array::make_view( mesh.nodes().global_index() ) ), + part( array::make_view( mesh.nodes().partition() ) ), + ridx( array::make_indexview( mesh.nodes().remote_index() ) ), + flags( array::make_view( mesh.nodes().field( "flags" ) ) ), + ghost( array::make_view( mesh.nodes().ghost() ) ), + elem_nodes( &mesh.cells().node_connectivity() ), + elem_part( array::make_view( mesh.cells().partition() ) ), + elem_glb_idx( array::make_view( mesh.cells().global_index() ) ), + compute_uid( mesh ) { + halo = 0; + mesh.metadata().get( "halo", halo ); + // update(); } - size_t nb_elems = elems.size(); - - size_t nb_elem_nodes(0); - for( size_t jelem=0; jelemcols(ielem); + void update() { + compute_uid.update(); + mesh::Nodes& nodes = mesh.nodes(); + xy = array::make_view( nodes.xy() ); + lonlat = array::make_view( nodes.lonlat() ); + glb_idx = array::make_view( nodes.global_index() ); + part = array::make_view( nodes.partition() ); + ridx = array::make_indexview( nodes.remote_index() ); + flags = array::make_view( nodes.field( "flags" ) ); + ghost = array::make_view( nodes.ghost() ); + + elem_nodes = &mesh.cells().node_connectivity(); + elem_part = array::make_view( mesh.cells().partition() ); + elem_glb_idx = array::make_view( mesh.cells().global_index() ); } - buf.elem_glb_idx [p].resize(nb_elems); - buf.elem_part [p].resize(nb_elems); - buf.elem_type [p].resize(nb_elems); - buf.elem_nodes_id[p].resize(nb_elem_nodes); - buf.elem_nodes_displs[p].resize(nb_elems); - size_t jelemnode(0); - for( size_t jelem=0; jelemcols(ielem); ++jnode ) - buf.elem_nodes_id[p][jelemnode++] = compute_uid( (*elem_nodes)(ielem,jnode) ); - } - } - - template< typename NodeContainer, typename ElementContainer > - void fill_sendbuffer(Buffers& buf,const NodeContainer& nodes_uid, const ElementContainer& elems, const PeriodicTransform& transform, int newflags, const int p) - { - //ATLAS_TRACE(); - - int nb_nodes = nodes_uid.size(); - buf.node_glb_idx[p].resize(nb_nodes); - buf.node_part [p].resize(nb_nodes); - buf.node_ridx [p].resize(nb_nodes); - buf.node_flags [p].resize(nb_nodes,Topology::NONE); - buf.node_xy [p].resize(2*nb_nodes); - - int jnode=0; - typename NodeContainer::iterator it; - for( it=nodes_uid.begin(); it!=nodes_uid.end(); ++it, ++jnode ) - { - uid_t uid = *it; - - Uid2Node::iterator found = uid2node.find( uid ); - if( found != uid2node.end() ) // Point exists inside domain - { - int node = found->second; - buf.node_part [p][jnode] = part (node); - buf.node_ridx [p][jnode] = ridx (node); - buf.node_xy [p][jnode*2+XX] = xy (node,XX); - buf.node_xy [p][jnode*2+YY] = xy (node,YY); - transform(&buf.node_xy[p][jnode*2],-1); - // Global index of node is based on UID of destination - buf.node_glb_idx[p][jnode] = util::unique_lonlat(&buf.node_xy [p][jnode*2]); - Topology::set(buf.node_flags[p][jnode],newflags); - } - else - { - Log::warning() << "Node with uid " << uid << " needed by ["< + void fill_sendbuffer( Buffers& buf, const NodeContainer& nodes_uid, const ElementContainer& elems, const int p ) { + // ATLAS_TRACE(); + + int nb_nodes = nodes_uid.size(); + buf.node_glb_idx[p].resize( nb_nodes ); + buf.node_part[p].resize( nb_nodes ); + buf.node_ridx[p].resize( nb_nodes ); + buf.node_flags[p].resize( nb_nodes, Topology::NONE ); + buf.node_xy[p].resize( 2 * nb_nodes ); + + int jnode = 0; + typename NodeContainer::iterator it; + for ( it = nodes_uid.begin(); it != nodes_uid.end(); ++it, ++jnode ) { + uid_t uid = *it; + + Uid2Node::iterator found = uid2node.find( uid ); + if ( found != uid2node.end() ) // Point exists inside domain + { + int node = found->second; + buf.node_glb_idx[p][jnode] = glb_idx( node ); + buf.node_part[p][jnode] = part( node ); + buf.node_ridx[p][jnode] = ridx( node ); + buf.node_xy[p][jnode * 2 + XX] = xy( node, XX ); + buf.node_xy[p][jnode * 2 + YY] = xy( node, YY ); + Topology::set( buf.node_flags[p][jnode], flags( node ) | Topology::GHOST ); + } + else { + Log::warning() << "Node with uid " << uid << " needed by [" << p << "] was not found in [" + << mpi::comm().rank() << "]." << std::endl; + ASSERT( false ); + } + } - size_t nb_elems = elems.size(); + size_t nb_elems = elems.size(); - size_t nb_elem_nodes(0); - for( size_t jelem=0; jelemcols(ielem); - } + size_t nb_elem_nodes( 0 ); + for ( size_t jelem = 0; jelem < nb_elems; ++jelem ) { + size_t ielem = elems[jelem]; + nb_elem_nodes += elem_nodes->cols( ielem ); + } - buf.elem_glb_idx [p].resize(nb_elems); - buf.elem_part [p].resize(nb_elems); - buf.elem_type [p].resize(nb_elems); - buf.elem_nodes_id[p].resize(nb_elem_nodes); - buf.elem_nodes_displs[p].resize(nb_elems); - size_t jelemnode(0); - for( size_t jelem=0; jelem crds(elem_nodes->cols(ielem)*2); - for(size_t jnode=0; jnodecols(ielem); ++jnode) - { - double crd[] = { xy( (*elem_nodes)(ielem,jnode),XX) , xy( (*elem_nodes)(ielem,jnode),YY) }; - transform(crd,-1); - buf.elem_nodes_id[p][jelemnode++] = util::unique_lonlat(crd); - crds[jnode*2+XX] = crd[XX]; - crds[jnode*2+YY] = crd[YY]; - } - // Global index of element is based on UID of destination - - buf.elem_glb_idx[p][jelem] = - util::unique_lonlat( crds.data(), elem_nodes->cols(ielem) ); + buf.elem_glb_idx[p].resize( nb_elems ); + buf.elem_part[p].resize( nb_elems ); + buf.elem_type[p].resize( nb_elems ); + buf.elem_nodes_id[p].resize( nb_elem_nodes ); + buf.elem_nodes_displs[p].resize( nb_elems ); + size_t jelemnode( 0 ); + for ( size_t jelem = 0; jelem < nb_elems; ++jelem ) { + buf.elem_nodes_displs[p][jelem] = jelemnode; + size_t ielem = elems[jelem]; + + buf.elem_glb_idx[p][jelem] = elem_glb_idx( ielem ); + buf.elem_part[p][jelem] = elem_part( ielem ); + buf.elem_type[p][jelem] = mesh.cells().type_idx( ielem ); + for ( size_t jnode = 0; jnode < elem_nodes->cols( ielem ); ++jnode ) + buf.elem_nodes_id[p][jelemnode++] = compute_uid( ( *elem_nodes )( ielem, jnode ) ); + } } - } - - - void add_nodes( Buffers& buf, bool periodic ) - { - ATLAS_TRACE(); + template + void fill_sendbuffer( Buffers& buf, const NodeContainer& nodes_uid, const ElementContainer& elems, + const PeriodicTransform& transform, int newflags, const int p ) { + // ATLAS_TRACE(); + + int nb_nodes = nodes_uid.size(); + buf.node_glb_idx[p].resize( nb_nodes ); + buf.node_part[p].resize( nb_nodes ); + buf.node_ridx[p].resize( nb_nodes ); + buf.node_flags[p].resize( nb_nodes, Topology::NONE ); + buf.node_xy[p].resize( 2 * nb_nodes ); + + int jnode = 0; + typename NodeContainer::iterator it; + for ( it = nodes_uid.begin(); it != nodes_uid.end(); ++it, ++jnode ) { + uid_t uid = *it; + + Uid2Node::iterator found = uid2node.find( uid ); + if ( found != uid2node.end() ) // Point exists inside domain + { + int node = found->second; + buf.node_part[p][jnode] = part( node ); + buf.node_ridx[p][jnode] = ridx( node ); + buf.node_xy[p][jnode * 2 + XX] = xy( node, XX ); + buf.node_xy[p][jnode * 2 + YY] = xy( node, YY ); + transform( &buf.node_xy[p][jnode * 2], -1 ); + // Global index of node is based on UID of destination + buf.node_glb_idx[p][jnode] = util::unique_lonlat( &buf.node_xy[p][jnode * 2] ); + Topology::set( buf.node_flags[p][jnode], newflags ); + } + else { + Log::warning() << "Node with uid " << uid << " needed by [" << p << "] was not found in [" + << mpi::comm().rank() << "]." << std::endl; + ASSERT( false ); + } + } - const size_t mpi_size = mpi::comm().size(); + size_t nb_elems = elems.size(); - mesh::Nodes& nodes = mesh.nodes(); - int nb_nodes = nodes.size(); + size_t nb_elem_nodes( 0 ); + for ( size_t jelem = 0; jelem < nb_elems; ++jelem ) { + size_t ielem = elems[jelem]; + nb_elem_nodes += elem_nodes->cols( ielem ); + } - // Nodes might be duplicated from different Tasks. We need to identify unique entries - std::vector node_uid(nb_nodes); - std::set new_node_uid; - { - ATLAS_TRACE( "compute node_uid" ); - for( int jnode=0; jnode crds( elem_nodes->cols( ielem ) * 2 ); + for ( size_t jnode = 0; jnode < elem_nodes->cols( ielem ); ++jnode ) { + double crd[] = {xy( ( *elem_nodes )( ielem, jnode ), XX ), xy( ( *elem_nodes )( ielem, jnode ), YY )}; + transform( crd, -1 ); + buf.elem_nodes_id[p][jelemnode++] = util::unique_lonlat( crd ); + crds[jnode * 2 + XX] = crd[XX]; + crds[jnode * 2 + YY] = crd[YY]; + } + // Global index of element is based on UID of destination + + buf.elem_glb_idx[p][jelem] = -util::unique_lonlat( crds.data(), elem_nodes->cols( ielem ) ); + } } - auto node_already_exists = [&node_uid,&new_node_uid]( uid_t uid ) { - std::vector::iterator it = std::lower_bound( node_uid.begin(), node_uid.end(), uid ); - bool not_found = ( it == node_uid.end() || uid < *it ); - if( not_found ) { - bool inserted = new_node_uid.insert( uid ).second; - return not inserted; - } else { - return true; - } - }; + void add_nodes( Buffers& buf, bool periodic ) { + ATLAS_TRACE(); - std::vector< std::vector > rfn_idx(mpi_size); - for(size_t jpart = 0; jpart < mpi_size; ++jpart) - { - rfn_idx[jpart].reserve(buf.node_glb_idx[jpart].size()); - } + const size_t mpi_size = mpi::comm().size(); - int nb_new_nodes=0; - for(size_t jpart = 0; jpart < mpi_size; ++jpart) - { - for(size_t n = 0; n < buf.node_glb_idx[jpart].size(); ++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); - } - } - nb_new_nodes += rfn_idx[jpart].size(); - } + mesh::Nodes& nodes = mesh.nodes(); + int nb_nodes = nodes.size(); - // Resize nodes - // ------------ - nodes.resize( nb_nodes+nb_new_nodes ); - flags = array::make_view( nodes.field("flags") ); - glb_idx = array::make_view( nodes.global_index() ); - part = array::make_view( nodes.partition() ); - ridx = array::make_indexview( nodes.remote_index() ); - xy = array::make_view( nodes.xy() ); - lonlat = array::make_view( nodes.lonlat() ); - ghost = array::make_view( nodes.ghost() ); - - compute_uid.update(); - - // Add new nodes - // ------------- - int new_node=0; - for(size_t jpart = 0; jpart < mpi_size; ++jpart) - { - for(size_t n = 0; n < rfn_idx[jpart].size(); ++n) - { - int loc_idx = nb_nodes+new_node; - Topology::reset(flags(loc_idx),buf.node_flags[jpart][rfn_idx[jpart][n]]); - ghost (loc_idx) = Topology::check(flags(loc_idx),Topology::GHOST); - glb_idx(loc_idx) = buf.node_glb_idx [jpart][rfn_idx[jpart][n]]; - part (loc_idx) = buf.node_part [jpart][rfn_idx[jpart][n]]; - ridx (loc_idx) = buf.node_ridx [jpart][rfn_idx[jpart][n]]; - PointXY pxy( &buf.node_xy [jpart][rfn_idx[jpart][n]*2] ); - xy (loc_idx,XX) = pxy.x(); - xy (loc_idx,YY) = pxy.y(); - PointLonLat pll = mesh.projection().lonlat(pxy); - lonlat (loc_idx,XX) = pll.lon(); - lonlat (loc_idx,YY) = pll.lat(); - - if( periodic ) - status.new_periodic_ghost_points.push_back( loc_idx ); - - // make sure new node was not already there + // Nodes might be duplicated from different Tasks. We need to identify + // unique entries + std::vector node_uid( nb_nodes ); + std::set new_node_uid; { - uid_t uid = compute_uid(loc_idx); - Uid2Node::iterator found = uid2node.find(uid); - if( found != uid2node.end() ) - { - int other = found->second; - std::stringstream msg; - msg << "New node with uid " << uid << ":\n" << glb_idx(loc_idx) - << "("<::iterator it = std::lower_bound( node_uid.begin(), node_uid.end(), uid ); + bool not_found = ( it == node_uid.end() || uid < *it ); + if ( not_found ) { + bool inserted = new_node_uid.insert( uid ).second; + return not inserted; + } + else { + return true; + } + }; + + std::vector> rfn_idx( mpi_size ); + for ( size_t jpart = 0; jpart < mpi_size; ++jpart ) { + rfn_idx[jpart].reserve( buf.node_glb_idx[jpart].size() ); } - ++new_node; - } - } - } - void add_elements( Buffers& buf, bool periodic ) - { - ATLAS_TRACE(); + int nb_new_nodes = 0; + for ( size_t jpart = 0; jpart < mpi_size; ++jpart ) { + for ( size_t n = 0; n < buf.node_glb_idx[jpart].size(); ++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 ); } + } + nb_new_nodes += rfn_idx[jpart].size(); + } - const size_t mpi_size = mpi::comm().size(); - auto cell_gidx = array::make_view(mesh.cells().global_index()); - // Elements might be duplicated from different Tasks. We need to identify unique entries - int nb_elems = mesh.cells().size(); -// std::set elem_uid; - std::vector elem_uid(2*nb_elems); - std::set new_elem_uid; - { - ATLAS_TRACE( "compute elem_uid" ); - for( int jelem=0; jelemrow(jelem)); - elem_uid[jelem*2+1] = cell_gidx(jelem); - } - std::sort( elem_uid.begin(), elem_uid.end() ); + // Resize nodes + // ------------ + nodes.resize( nb_nodes + nb_new_nodes ); + flags = array::make_view( nodes.field( "flags" ) ); + glb_idx = array::make_view( nodes.global_index() ); + part = array::make_view( nodes.partition() ); + ridx = array::make_indexview( nodes.remote_index() ); + xy = array::make_view( nodes.xy() ); + lonlat = array::make_view( nodes.lonlat() ); + ghost = array::make_view( nodes.ghost() ); + + compute_uid.update(); + + // Add new nodes + // ------------- + int new_node = 0; + for ( size_t jpart = 0; jpart < mpi_size; ++jpart ) { + for ( size_t n = 0; n < rfn_idx[jpart].size(); ++n ) { + int loc_idx = nb_nodes + new_node; + Topology::reset( flags( loc_idx ), buf.node_flags[jpart][rfn_idx[jpart][n]] ); + ghost( loc_idx ) = Topology::check( flags( loc_idx ), Topology::GHOST ); + glb_idx( loc_idx ) = buf.node_glb_idx[jpart][rfn_idx[jpart][n]]; + part( loc_idx ) = buf.node_part[jpart][rfn_idx[jpart][n]]; + ridx( loc_idx ) = buf.node_ridx[jpart][rfn_idx[jpart][n]]; + PointXY pxy( &buf.node_xy[jpart][rfn_idx[jpart][n] * 2] ); + xy( loc_idx, XX ) = pxy.x(); + xy( loc_idx, YY ) = pxy.y(); + PointLonLat pll = mesh.projection().lonlat( pxy ); + lonlat( loc_idx, XX ) = pll.lon(); + lonlat( loc_idx, YY ) = pll.lat(); + + if ( periodic ) status.new_periodic_ghost_points.push_back( loc_idx ); + + // make sure new node was not already there + { + uid_t uid = compute_uid( loc_idx ); + Uid2Node::iterator found = uid2node.find( uid ); + if ( found != uid2node.end() ) { + int other = found->second; + std::stringstream msg; + msg << "New node with uid " << uid << ":\n" + << glb_idx( loc_idx ) << "(" << xy( loc_idx, XX ) << "," << xy( loc_idx, YY ) << ")\n"; + msg << "Existing already loc " << other << " : " << glb_idx( other ) << "(" << xy( other, XX ) + << "," << xy( other, YY ) << ")\n"; + throw eckit::SeriousBug( msg.str(), Here() ); + } + uid2node[uid] = nb_nodes + new_node; + } + ++new_node; + } + } } - auto element_already_exists = [&elem_uid,&new_elem_uid]( uid_t uid ) -> bool { - std::vector::iterator it = std::lower_bound( elem_uid.begin(), elem_uid.end(), uid ); - bool not_found = ( it == elem_uid.end() || uid < *it ); - if( not_found ) { - bool inserted = new_elem_uid.insert( uid ).second; - return not inserted; - } else { - return true; - } - }; - - if( not status.new_periodic_ghost_cells.size() ) - status.new_periodic_ghost_cells.resize(mesh.cells().nb_types()); + void add_elements( Buffers& buf, bool periodic ) { + ATLAS_TRACE(); + + const size_t mpi_size = mpi::comm().size(); + auto cell_gidx = array::make_view( mesh.cells().global_index() ); + // Elements might be duplicated from different Tasks. We need to identify + // unique entries + int nb_elems = mesh.cells().size(); + // std::set elem_uid; + std::vector elem_uid( 2 * nb_elems ); + std::set new_elem_uid; + { + ATLAS_TRACE( "compute elem_uid" ); + for ( int jelem = 0; jelem < nb_elems; ++jelem ) { + elem_uid[jelem * 2 + 0] = -compute_uid( elem_nodes->row( jelem ) ); + elem_uid[jelem * 2 + 1] = cell_gidx( jelem ); + } + std::sort( elem_uid.begin(), elem_uid.end() ); + } + auto element_already_exists = [&elem_uid, &new_elem_uid]( uid_t uid ) -> bool { + std::vector::iterator it = std::lower_bound( elem_uid.begin(), elem_uid.end(), uid ); + bool not_found = ( it == elem_uid.end() || uid < *it ); + if ( not_found ) { + bool inserted = new_elem_uid.insert( uid ).second; + return not inserted; + } + else { + return true; + } + }; + + 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 ( size_t jpart = 0; jpart < mpi_size; ++jpart ) { + received_new_elems[jpart].reserve( buf.elem_glb_idx[jpart].size() ); + } - std::vector< std::vector > received_new_elems( mpi_size ); - for(size_t jpart = 0; jpart < mpi_size; ++jpart) - { - received_new_elems[jpart].reserve(buf.elem_glb_idx[jpart].size()); - } - - size_t nb_new_elems(0); - for(size_t jpart = 0; jpart < mpi_size; ++jpart) - { - for(size_t e = 0; e < buf.elem_glb_idx[jpart].size(); ++e) - { - if( element_already_exists( buf.elem_glb_idx[jpart][e]) == false ) { - received_new_elems[jpart].push_back(e); + size_t nb_new_elems( 0 ); + for ( size_t jpart = 0; jpart < mpi_size; ++jpart ) { + for ( size_t e = 0; e < buf.elem_glb_idx[jpart].size(); ++e ) { + if ( element_already_exists( buf.elem_glb_idx[jpart][e] ) == false ) { + received_new_elems[jpart].push_back( e ); + } + } + nb_new_elems += received_new_elems[jpart].size(); } - } - nb_new_elems += received_new_elems[jpart].size(); - } - std::vector< std::vector< std::vector > > - elements_of_type( mesh.cells().nb_types(), - std::vector< std::vector >( mpi_size ) ); - std::vector nb_elements_of_type( mesh.cells().nb_types(), 0 ); + std::vector>> elements_of_type( mesh.cells().nb_types(), + std::vector>( mpi_size ) ); + std::vector nb_elements_of_type( mesh.cells().nb_types(), 0 ); - for(size_t jpart = 0; jpart < mpi_size ; ++jpart) - { - for(size_t jelem = 0; jelem < received_new_elems[jpart].size(); ++jelem) - { - int ielem = received_new_elems[jpart][jelem]; - elements_of_type[buf.elem_type[jpart][ielem]][jpart] . push_back(ielem); - ++nb_elements_of_type[buf.elem_type[jpart][ielem]]; - } - } + for ( size_t jpart = 0; jpart < mpi_size; ++jpart ) { + for ( size_t jelem = 0; jelem < received_new_elems[jpart].size(); ++jelem ) { + int ielem = received_new_elems[jpart][jelem]; + elements_of_type[buf.elem_type[jpart][ielem]][jpart].push_back( ielem ); + ++nb_elements_of_type[buf.elem_type[jpart][ielem]]; + } + } - for( size_t t=0; t > &elems = elements_of_type[t]; - mesh::Elements& elements = mesh.cells().elements(t); - - // Add new elements - BlockConnectivity &node_connectivity = elements.node_connectivity(); - if( nb_elements_of_type[t] == 0 ) continue; - - size_t old_size = elements.size(); - size_t new_elems_pos = elements.add(nb_elements_of_type[t]); - - auto elem_type_glb_idx = elements.view( mesh.cells().global_index() ); - auto elem_type_part = elements.view( mesh.cells().partition() ); - auto elem_type_halo = elements.view( mesh.cells().halo() ); - auto elem_type_patch = elements.view( mesh.cells().field("patch") ); - - // Copy information in new elements - size_t new_elem(0); - for(size_t jpart = 0; jpart < mpi_size ; ++jpart) - { - for(size_t e = 0; e < elems[jpart].size(); ++e) - { - size_t jelem = elems[jpart][e]; - int loc_idx = new_elems_pos+new_elem; - elem_type_glb_idx(loc_idx) = std::abs(buf.elem_glb_idx[jpart][jelem]); - elem_type_part (loc_idx) = buf.elem_part[jpart][jelem]; - elem_type_halo (loc_idx) = halo+1; - elem_type_patch (loc_idx) = 0; - for( size_t n=0; n>& elems = elements_of_type[t]; + mesh::Elements& elements = mesh.cells().elements( t ); + + // Add new elements + BlockConnectivity& node_connectivity = elements.node_connectivity(); + if ( nb_elements_of_type[t] == 0 ) continue; + + size_t old_size = elements.size(); + size_t new_elems_pos = elements.add( nb_elements_of_type[t] ); + + auto elem_type_glb_idx = elements.view( mesh.cells().global_index() ); + auto elem_type_part = elements.view( mesh.cells().partition() ); + auto elem_type_halo = elements.view( mesh.cells().halo() ); + auto elem_type_patch = elements.view( mesh.cells().field( "patch" ) ); + + // Copy information in new elements + size_t new_elem( 0 ); + for ( size_t jpart = 0; jpart < mpi_size; ++jpart ) { + for ( size_t e = 0; e < elems[jpart].size(); ++e ) { + size_t jelem = elems[jpart][e]; + int loc_idx = new_elems_pos + new_elem; + elem_type_glb_idx( loc_idx ) = std::abs( buf.elem_glb_idx[jpart][jelem] ); + elem_type_part( loc_idx ) = buf.elem_part[jpart][jelem]; + elem_type_halo( loc_idx ) = halo + 1; + elem_type_patch( loc_idx ) = 0; + for ( size_t n = 0; n < node_connectivity.cols(); ++n ) + node_connectivity.set( + loc_idx, n, uid2node[buf.elem_nodes_id[jpart][buf.elem_nodes_displs[jpart][jelem] + n]] ); + + if ( periodic ) { status.new_periodic_ghost_cells[t].push_back( old_size + new_elem ); } + + ++new_elem; + } + } } - } } - } - - void add_buffers( Buffers& buf, bool periodic = false ) - { - add_nodes( buf, periodic ); - add_elements( buf, periodic ); - update(); - } + void add_buffers( Buffers& buf, bool periodic = false ) { + add_nodes( buf, periodic ); + add_elements( buf, periodic ); + update(); + } }; - - namespace { -void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, atlas::mpi::Buffer& recv, bool periodic = false ) { - auto& comm = mpi::comm(); +void gather_bdry_nodes( const BuildHaloHelper& helper, const std::vector& send, + atlas::mpi::Buffer& recv, bool periodic = false ) { + auto& comm = mpi::comm(); #ifndef ATLAS_103 - /* deprecated */ - ATLAS_TRACE( "gather_bdry_nodes old way" ); - { - ATLAS_TRACE_MPI( ALLGATHER ) { - comm.allGatherv(send.begin(), send.end(), recv); + /* deprecated */ + ATLAS_TRACE( "gather_bdry_nodes old way" ); + { + ATLAS_TRACE_MPI( ALLGATHER ) { comm.allGatherv( send.begin(), send.end(), recv ); } } - } #else - ATLAS_TRACE(); + ATLAS_TRACE(); - Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); - if( periodic ) { - // add own rank to neighbours to allow periodicity with self (pole caps) - size_t rank = comm.rank(); - neighbours.insert( std::upper_bound( neighbours.begin(), neighbours.end(), rank ), rank ); - } + Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); + if ( periodic ) { + // add own rank to neighbours to allow periodicity with self (pole caps) + size_t rank = comm.rank(); + neighbours.insert( std::upper_bound( neighbours.begin(), neighbours.end(), rank ), rank ); + } - const size_t mpi_size = comm.size(); - const int counts_tag = 0; - const int buffer_tag = 1; + const size_t mpi_size = comm.size(); + const int counts_tag = 0; + const int buffer_tag = 1; - std::vector counts_requests; counts_requests.reserve(neighbours.size()); - std::vector buffer_requests; buffer_requests.reserve(neighbours.size()); + std::vector counts_requests; + counts_requests.reserve( neighbours.size() ); + std::vector buffer_requests; + buffer_requests.reserve( neighbours.size() ); - int sendcnt = send.size(); - ATLAS_TRACE_MPI(ISEND) { - for( size_t to : neighbours ) { - counts_requests.push_back( comm.iSend( sendcnt, to, counts_tag ) ); + int sendcnt = send.size(); + ATLAS_TRACE_MPI( ISEND ) { + for ( size_t to : neighbours ) { + counts_requests.push_back( comm.iSend( sendcnt, to, counts_tag ) ); + } } - } - recv.counts.assign(0,mpi_size); + recv.counts.assign( 0, mpi_size ); + + ATLAS_TRACE_MPI( IRECEIVE ) { + for ( size_t from : neighbours ) { + counts_requests.push_back( comm.iReceive( recv.counts[from], from, counts_tag ) ); + } + } - ATLAS_TRACE_MPI(IRECEIVE) { - for( size_t from : neighbours ) { - counts_requests.push_back( comm.iReceive( recv.counts[from], from, counts_tag ) ); + ATLAS_TRACE_MPI( ISEND ) { + for ( size_t to : neighbours ) { + buffer_requests.push_back( comm.iSend( send.data(), send.size(), to, buffer_tag ) ); + } } - } - ATLAS_TRACE_MPI(ISEND) { - for( size_t to : neighbours ) { - buffer_requests.push_back( comm.iSend(send.data(),send.size(),to, buffer_tag ) ); + ATLAS_TRACE_MPI( WAIT ) { + for ( auto request : counts_requests ) { + comm.wait( request ); + } } - } - ATLAS_TRACE_MPI(WAIT) { - for( auto request : counts_requests ) { - comm.wait( request ); + recv.displs[0] = 0; + recv.cnt = recv.counts[0]; + for ( size_t jpart = 1; jpart < mpi_size; ++jpart ) { + recv.displs[jpart] = recv.displs[jpart - 1] + recv.counts[jpart - 1]; + recv.cnt += recv.counts[jpart]; } - } - - recv.displs[0] = 0; - recv.cnt = recv.counts[0]; - for(size_t jpart = 1; jpart < mpi_size; ++jpart) { - recv.displs[jpart] = recv.displs[jpart-1] + recv.counts[jpart-1]; - recv.cnt += recv.counts[jpart]; - } - recv.buffer.resize(recv.cnt); - - ATLAS_TRACE_MPI( IRECEIVE ) { - for( size_t from : neighbours ) { - buffer_requests.push_back( - comm.iReceive( recv.buffer.data()+recv.displs[from], - recv.counts[from], from, buffer_tag) ); + recv.buffer.resize( recv.cnt ); + + ATLAS_TRACE_MPI( IRECEIVE ) { + for ( size_t from : neighbours ) { + buffer_requests.push_back( + comm.iReceive( recv.buffer.data() + recv.displs[from], recv.counts[from], from, buffer_tag ) ); + } } - } - ATLAS_TRACE_MPI( WAIT ) { - for( auto request : buffer_requests ) { - comm.wait( request ); + ATLAS_TRACE_MPI( WAIT ) { + for ( auto request : buffer_requests ) { + comm.wait( request ); + } } - } #endif } -} - - - - -void increase_halo_interior( BuildHaloHelper& helper ) -{ - helper.update(); - if (helper.node_to_elem.size() == 0 ) - build_lookup_node2elem(helper.mesh,helper.node_to_elem); +} // namespace - if( helper.uid2node.size() == 0 ) - build_lookup_uid2node(helper.mesh,helper.uid2node); +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.uid2node.size() == 0 ) build_lookup_uid2node( helper.mesh, helper.uid2node ); - // All buffers needed to move elements and nodes - BuildHaloHelper::Buffers sendmesh(helper.mesh); - BuildHaloHelper::Buffers recvmesh(helper.mesh); + // All buffers needed to move elements and nodes + BuildHaloHelper::Buffers sendmesh( helper.mesh ); + BuildHaloHelper::Buffers recvmesh( helper.mesh ); - // 1) Find boundary nodes of this partition: + // 1) Find boundary nodes of this partition: - accumulate_partition_bdry_nodes(helper.mesh,helper.halo,helper.bdry_nodes); - const std::vector& bdry_nodes = helper.bdry_nodes; + accumulate_partition_bdry_nodes( helper.mesh, helper.halo, helper.bdry_nodes ); + const std::vector& bdry_nodes = helper.bdry_nodes; - // 2) Communicate uid of these boundary nodes to other partitions + // 2) Communicate uid of these boundary nodes to other partitions - std::vector send_bdry_nodes_uid(bdry_nodes.size()); - for(size_t jnode = 0; jnode < bdry_nodes.size(); ++jnode) - send_bdry_nodes_uid[jnode] = helper.compute_uid(bdry_nodes[jnode]); + std::vector send_bdry_nodes_uid( bdry_nodes.size() ); + for ( size_t jnode = 0; jnode < bdry_nodes.size(); ++jnode ) + send_bdry_nodes_uid[jnode] = helper.compute_uid( bdry_nodes[jnode] ); - size_t mpi_size = mpi::comm().size(); - atlas::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); - - gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts ); + size_t mpi_size = mpi::comm().size(); + atlas::mpi::Buffer recv_bdry_nodes_uid_from_parts( mpi_size ); + gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts ); #ifndef ATLAS_103 - /* deprecated */ - for (size_t jpart = 0; jpart < mpi_size; ++jpart) + /* deprecated */ + for ( size_t jpart = 0; jpart < mpi_size; ++jpart ) #else - const Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); - for (size_t jpart : neighbours) + const Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); + for ( size_t jpart : neighbours ) #endif - { + { - // 3) Find elements and nodes completing these elements in - // other tasks that have my nodes through its UID + // 3) Find elements and nodes completing these elements in + // other tasks that have my nodes through its UID - mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; + mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; - std::vector found_bdry_elems; - std::set< uid_t > found_bdry_nodes_uid; + std::vector found_bdry_elems; + std::set found_bdry_nodes_uid; - accumulate_elements(helper.mesh,recv_bdry_nodes_uid, - helper.uid2node, - helper.node_to_elem, - found_bdry_elems, - found_bdry_nodes_uid); + accumulate_elements( helper.mesh, recv_bdry_nodes_uid, helper.uid2node, helper.node_to_elem, found_bdry_elems, + found_bdry_nodes_uid ); - // 4) Fill node and element buffers to send back - helper.fill_sendbuffer(sendmesh, found_bdry_nodes_uid, found_bdry_elems, jpart); - } + // 4) Fill node and element buffers to send back + helper.fill_sendbuffer( sendmesh, found_bdry_nodes_uid, found_bdry_elems, jpart ); + } - // 5) Now communicate all buffers - helper.all_to_all(sendmesh, recvmesh); + // 5) Now communicate all buffers + helper.all_to_all( sendmesh, recvmesh ); - // 6) Adapt mesh +// 6) Adapt mesh #ifdef DEBUG_OUTPUT - Log::debug() << "recv: \n" << recvmesh << std::endl; + Log::debug() << "recv: \n" << recvmesh << std::endl; #endif - helper.add_buffers(recvmesh); + helper.add_buffers( recvmesh ); } class PeriodicPoints { public: - PeriodicPoints(Mesh& mesh, int flag, size_t N) : - flags_( array::make_view ( mesh.nodes().field("flags") ) ) - { - flag_ = flag; - N_ = N; - } - - bool operator()(int j) const - { - if( j>=N_ ) return false; - if( Topology::check(flags_(j),flag_) ) return true; - return false; - } -private: - int N_; - int flag_; - array::ArrayView flags_; - - friend std::ostream& operator<<(std::ostream& os, const PeriodicPoints& periodic_points) { - os << "["; - for( size_t j=0; j( mesh.nodes().field( "flags" ) ) ) { + flag_ = flag; + N_ = N; } - os << " ]"; - return os; - } -}; + bool operator()( int j ) const { + if ( j >= N_ ) return false; + if ( Topology::check( flags_( j ), flag_ ) ) return true; + return false; + } +private: + int N_; + int flag_; + array::ArrayView flags_; + + friend std::ostream& operator<<( std::ostream& os, const PeriodicPoints& periodic_points ) { + os << "["; + for ( size_t j = 0; j < periodic_points.flags_.shape( 0 ); ++j ) { + if ( periodic_points( j ) ) os << " " << j + 1; + } + os << " ]"; + return os; + } +}; -void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& periodic_points, const PeriodicTransform& transform, int newflags) -{ - helper.update(); - //if (helper.node_to_elem.size() == 0 ) !!! NOT ALLOWED !!! (atlas_test_halo will fail) - build_lookup_node2elem(helper.mesh,helper.node_to_elem); +void increase_halo_periodic( BuildHaloHelper& helper, const PeriodicPoints& periodic_points, + const PeriodicTransform& transform, int newflags ) { + helper.update(); + // if (helper.node_to_elem.size() == 0 ) !!! NOT ALLOWED !!! (atlas_test_halo + // will fail) + build_lookup_node2elem( helper.mesh, helper.node_to_elem ); - //if( helper.uid2node.size() == 0 ) !!! NOT ALLOWED !!! (atlas_test_halo will fail) - build_lookup_uid2node(helper.mesh,helper.uid2node); + // if( helper.uid2node.size() == 0 ) !!! NOT ALLOWED !!! (atlas_test_halo will + // fail) + build_lookup_uid2node( helper.mesh, helper.uid2node ); - // All buffers needed to move elements and nodes - BuildHaloHelper::Buffers sendmesh(helper.mesh); - BuildHaloHelper::Buffers recvmesh(helper.mesh); + // All buffers needed to move elements and nodes + BuildHaloHelper::Buffers sendmesh( helper.mesh ); + BuildHaloHelper::Buffers recvmesh( helper.mesh ); - // 1) Find boundary nodes of this partition: + // 1) Find boundary nodes of this partition: - if( ! helper.bdry_nodes.size() ) - accumulate_partition_bdry_nodes(helper.mesh,helper.halo,helper.bdry_nodes); + if ( !helper.bdry_nodes.size() ) accumulate_partition_bdry_nodes( helper.mesh, helper.halo, helper.bdry_nodes ); - std::vector bdry_nodes = filter_nodes(helper.bdry_nodes,periodic_points); + std::vector bdry_nodes = filter_nodes( helper.bdry_nodes, periodic_points ); - // 2) Compute transformed uid of these boundary nodes and send to other partitions + // 2) Compute transformed uid of these boundary nodes and send to other + // partitions - std::vector send_bdry_nodes_uid(bdry_nodes.size()); - for(size_t jnode = 0; jnode < bdry_nodes.size(); ++jnode) - { - double crd[] = { helper.xy(bdry_nodes[jnode],XX), helper.xy(bdry_nodes[jnode],YY) }; - transform(crd,+1); - // Log::info() << " crd " << crd[0] << " " << crd[1] << " uid " << util::unique_lonlat(crd) << std::endl; - send_bdry_nodes_uid[jnode] = util::unique_lonlat(crd); - } + std::vector send_bdry_nodes_uid( bdry_nodes.size() ); + for ( size_t jnode = 0; jnode < bdry_nodes.size(); ++jnode ) { + double crd[] = {helper.xy( bdry_nodes[jnode], XX ), helper.xy( bdry_nodes[jnode], YY )}; + transform( crd, +1 ); + // Log::info() << " crd " << crd[0] << " " << crd[1] << " uid " << + // util::unique_lonlat(crd) << std::endl; + send_bdry_nodes_uid[jnode] = util::unique_lonlat( crd ); + } - size_t mpi_size = mpi::comm().size(); - atlas::mpi::Buffer recv_bdry_nodes_uid_from_parts(mpi_size); + size_t mpi_size = mpi::comm().size(); + atlas::mpi::Buffer recv_bdry_nodes_uid_from_parts( mpi_size ); - gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts, /* periodic = */ true ); + gather_bdry_nodes( helper, send_bdry_nodes_uid, recv_bdry_nodes_uid_from_parts, + /* periodic = */ true ); #ifndef ATLAS_103 - /* deprecated */ - for (size_t jpart = 0; jpart < mpi_size; ++jpart) + /* deprecated */ + for ( size_t jpart = 0; jpart < mpi_size; ++jpart ) #else - Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); - // add own rank to neighbours to allow periodicity with self (pole caps) - size_t rank = mpi::comm().rank(); - neighbours.insert( std::upper_bound( neighbours.begin(), neighbours.end(), rank ), rank ); - for (size_t jpart : neighbours) + Mesh::PartitionGraph::Neighbours neighbours = helper.mesh.nearestNeighbourPartitions(); + // add own rank to neighbours to allow periodicity with self (pole caps) + size_t rank = mpi::comm().rank(); + neighbours.insert( std::upper_bound( neighbours.begin(), neighbours.end(), rank ), rank ); + for ( size_t jpart : neighbours ) #endif - { - // 3) Find elements and nodes completing these elements in - // other tasks that have my nodes through its UID + { + // 3) Find elements and nodes completing these elements in + // other tasks that have my nodes through its UID - atlas::mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; + atlas::mpi::BufferView recv_bdry_nodes_uid = recv_bdry_nodes_uid_from_parts[jpart]; - std::vector found_bdry_elems; - std::set< uid_t > found_bdry_nodes_uid; + std::vector found_bdry_elems; + std::set found_bdry_nodes_uid; - accumulate_elements(helper.mesh,recv_bdry_nodes_uid, - helper.uid2node, - helper.node_to_elem, - found_bdry_elems, - found_bdry_nodes_uid); + accumulate_elements( helper.mesh, recv_bdry_nodes_uid, helper.uid2node, helper.node_to_elem, found_bdry_elems, + found_bdry_nodes_uid ); - // 4) Fill node and element buffers to send back - helper.fill_sendbuffer(sendmesh, found_bdry_nodes_uid, found_bdry_elems, transform, newflags, jpart); - } + // 4) Fill node and element buffers to send back + helper.fill_sendbuffer( sendmesh, found_bdry_nodes_uid, found_bdry_elems, transform, newflags, jpart ); + } - // 5) Now communicate all buffers - helper.all_to_all(sendmesh, recvmesh); + // 5) Now communicate all buffers + helper.all_to_all( sendmesh, recvmesh ); - // 6) Adapt mesh +// 6) Adapt mesh #ifdef DEBUG_OUTPUT - Log::debug() << "recv: \n" << recvmesh << std::endl; + Log::debug() << "recv: \n" << recvmesh << std::endl; #endif - helper.add_buffers(recvmesh, /* periodic = */ true ); - + helper.add_buffers( recvmesh, /* periodic = */ true ); } -void BuildHalo::operator () ( int nb_elems ) -{ - ATLAS_TRACE( "BuildHalo" ); - - int halo = 0; - mesh_.metadata().get("halo",halo); +void BuildHalo::operator()( int nb_elems ) { + ATLAS_TRACE( "BuildHalo" ); - if( halo == nb_elems ) - return; + int halo = 0; + mesh_.metadata().get( "halo", halo ); + if ( halo == nb_elems ) return; - ATLAS_TRACE( "Increasing mesh halo" ); + ATLAS_TRACE( "Increasing mesh halo" ); - for(int jhalo=halo ; jhalo periodic_points_local_index_; - std::vector periodic_cells_local_index_; + std::vector periodic_points_local_index_; + std::vector periodic_cells_local_index_; private: - Mesh& mesh_; + Mesh& mesh_; }; - /// @brief Enlarge each partition of the mesh with a halo of elements /// @param [inout] mesh The mesh to enlarge /// @param [in] nb_elems Size of the halo /// @author Willem Deconinck /// @date June 2014 inline void build_halo( Mesh& mesh, int nb_elems ) { - BuildHalo f(mesh); - f( nb_elems ); + BuildHalo f( mesh ); + f( nb_elems ); } // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -extern "C" -{ - void atlas__build_halo (Mesh::Implementation* mesh, int nb_elems); +extern "C" { +void atlas__build_halo( Mesh::Implementation* mesh, int nb_elems ); } // ------------------------------------------------------------------ -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas -#endif // BuildHalo_h +#endif // BuildHalo_h diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 382967023..677c1c414 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -4,63 +4,69 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/mesh/actions/BuildParallelFields.h" #include #include #include -#include "eckit/exception/Exceptions.h" +#include "atlas/array.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/IndexView.h" +#include "atlas/field/Field.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/actions/BuildParallelFields.h" -#include "atlas/field/Field.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/util/Unique.h" #include "atlas/mesh/detail/PeriodicTransform.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/IndexView.h" -#include "atlas/array.h" -#include "atlas/runtime/Log.h" -#include "atlas/runtime/ErrorHandling.h" -#include "atlas/runtime/Trace.h" +#include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/mpi/Buffer.h" #include "atlas/parallel/mpi/mpi.h" -#include "atlas/parallel/GatherScatter.h" +#include "atlas/runtime/ErrorHandling.h" +#include "atlas/runtime/Log.h" +#include "atlas/runtime/Trace.h" +#include "atlas/util/CoordinateEnums.h" +#include "atlas/util/Unique.h" +#include "eckit/exception/Exceptions.h" -#define EDGE(jedge) "Edge("< glb_idx = array::make_view( nodes.global_index() ); + array::ArrayView glb_idx = array::make_view( nodes.global_index() ); - UniqueLonLat compute_uid(nodes); + UniqueLonLat compute_uid( nodes ); - for( size_t jnode=0; jnode Those specific periodic points at the EAST boundary are not checked for uid, -// and could receive different gidx for different tasks + // TODO: ATLAS-14: fix renumbering of EAST periodic boundary points + // --> Those specific periodic points at the EAST boundary are not checked for + // uid, + // and could receive different gidx for different tasks - UniqueLonLat compute_uid(nodes); + UniqueLonLat compute_uid( nodes ); - // unused // int mypart = mpi::comm().rank(); - int nparts = mpi::comm().size(); - size_t root = 0; + // unused // int mypart = mpi::comm().rank(); + int nparts = mpi::comm().size(); + size_t root = 0; - array::ArrayView glb_idx = array::make_view ( nodes.global_index() ); + array::ArrayView glb_idx = array::make_view( nodes.global_index() ); - /* - * Sorting following gidx will define global order of - * gathered fields. Special care needs to be taken for - * pole edges, as their centroid might coincide with - * other edges - */ - int nb_nodes = glb_idx.shape(0); - for( int jnode=0; jnode loc_id_arr( nb_nodes ); + array::ArrayView loc_id = array::make_view( loc_id_arr ); - // 1) Gather all global indices, together with location - array::ArrayT loc_id_arr( nb_nodes ); - array::ArrayView loc_id = array::make_view(loc_id_arr); + for ( int jnode = 0; jnode < nb_nodes; ++jnode ) { + loc_id( jnode ) = glb_idx( jnode ); + } - for( int jnode=0; jnode recvcounts( mpi::comm().size() ); + std::vector recvdispls( mpi::comm().size() ); - std::vector recvcounts(mpi::comm().size()); - std::vector recvdispls(mpi::comm().size()); + ATLAS_TRACE_MPI( GATHER ) { mpi::comm().gather( nb_nodes, recvcounts, root ); } - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gather(nb_nodes, recvcounts, root); - } + recvdispls[0] = 0; + for ( int jpart = 1; jpart < nparts; ++jpart ) { // start at 1 + recvdispls[jpart] = recvcounts[jpart - 1] + recvdispls[jpart - 1]; + } + int glb_nb_nodes = std::accumulate( recvcounts.begin(), recvcounts.end(), 0 ); - recvdispls[0]=0; - for (int jpart=1; jpart glb_id_arr( glb_nb_nodes ); + array::ArrayView glb_id = array::make_view( glb_id_arr ); - array::ArrayT glb_id_arr( glb_nb_nodes ); - array::ArrayView glb_id = array::make_view(glb_id_arr); + ATLAS_TRACE_MPI( GATHER ) { + mpi::comm().gatherv( loc_id.data(), loc_id.size(), glb_id.data(), recvcounts.data(), recvdispls.data(), root ); + } - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gatherv(loc_id.data(), loc_id.size(), glb_id.data(), recvcounts.data(), recvdispls.data(), root); - } + // 2) Sort all global indices, and renumber from 1 to glb_nb_edges + std::vector node_sort; + node_sort.reserve( glb_nb_nodes ); + ATLAS_TRACE_SCOPE( "sort global indices" ) { + for ( size_t jnode = 0; jnode < glb_id.shape( 0 ); ++jnode ) { + node_sort.push_back( Node( glb_id( jnode ), jnode ) ); + } + std::sort( node_sort.begin(), node_sort.end() ); + } - // 2) Sort all global indices, and renumber from 1 to glb_nb_edges - std::vector node_sort; node_sort.reserve(glb_nb_nodes); - ATLAS_TRACE_SCOPE("sort global indices") { - for( size_t jnode=0; jnode + std::vector proc( nparts ); + for ( size_t jpart = 0; jpart < nparts; ++jpart ) + proc[jpart] = jpart; + // <--------- + + auto ridx = array::make_indexview( nodes.remote_index() ); + auto part = array::make_view( nodes.partition() ); + auto gidx = array::make_view( nodes.global_index() ); + size_t nb_nodes = nodes.size(); + + int varsize = 2; + + std::vector> send_needed( mpi::comm().size() ); + std::vector> recv_needed( mpi::comm().size() ); + int sendcnt = 0; + std::map lookup; + for ( size_t jnode = 0; jnode < nb_nodes; ++jnode ) { + uid_t uid = compute_uid( jnode ); + + if ( size_t( part( jnode ) ) == mypart ) { + lookup[uid] = jnode; + ridx( jnode ) = jnode; + } + else { + ASSERT( jnode < part.shape( 0 ) ); + if ( part( jnode ) >= (int)proc.size() ) { + std::stringstream msg; + msg << "Assertion [part(" << jnode << ") < proc.size()] failed\n" + << "part(" << jnode << ") = " << part( jnode ) << "\n" + << "proc.size() = " << proc.size(); + eckit::AssertionFailed( msg.str(), Here() ); + } + ASSERT( part( jnode ) < (int)proc.size() ); + ASSERT( (size_t)proc[part( jnode )] < send_needed.size() ); + send_needed[proc[part( jnode )]].push_back( uid ); + send_needed[proc[part( jnode )]].push_back( jnode ); + sendcnt++; + } + } -} + ATLAS_TRACE_MPI( ALLTOALL ) { mpi::comm().allToAll( send_needed, recv_needed ); } + + std::vector> send_found( mpi::comm().size() ); + std::vector> recv_found( mpi::comm().size() ); + + for ( size_t jpart = 0; jpart < nparts; ++jpart ) { + const std::vector& recv_node = recv_needed[proc[jpart]]; + const size_t nb_recv_nodes = recv_node.size() / varsize; + // array::ArrayView recv_node( make_view( Array::wrap(shape, + // recv_needed[ proc[jpart] ].data()) ), + // array::make_shape(recv_needed[ proc[jpart] ].size()/varsize,varsize) + // ); + for ( size_t jnode = 0; jnode < nb_recv_nodes; ++jnode ) { + uid_t uid = recv_node[jnode * varsize + 0]; + int inode = recv_node[jnode * varsize + 1]; + if ( lookup.count( uid ) ) { + send_found[proc[jpart]].push_back( inode ); + send_found[proc[jpart]].push_back( lookup[uid] ); + } + else { + std::stringstream msg; + msg << "[" << mpi::comm().rank() << "] " + << "Node requested by rank [" << jpart << "] with uid [" << uid + << "] that should be owned is not found"; + throw eckit::SeriousBug( msg.str(), Here() ); + } + } + } -//---------------------------------------------------------------------------------------------------------------------- + ATLAS_TRACE_MPI( ALLTOALL ) { mpi::comm().allToAll( send_found, recv_found ); } -Field& build_nodes_remote_idx( mesh::Nodes& nodes ) -{ - ATLAS_TRACE(); - size_t mypart = mpi::comm().rank(); - size_t nparts = mpi::comm().size(); - - UniqueLonLat compute_uid(nodes); - - // This piece should be somewhere central ... could be NPROMA ? - // ----------> - std::vector< int > proc( nparts ); - for( size_t jpart=0; jpart( nodes.remote_index() ); - auto part = array::make_view( nodes.partition() ); - auto gidx = array::make_view( nodes.global_index() ); - size_t nb_nodes = nodes.size(); - - int varsize=2; - - std::vector< std::vector > send_needed( mpi::comm().size() ); - std::vector< std::vector > recv_needed( mpi::comm().size() ); - int sendcnt=0; - std::map lookup; - for( size_t jnode=0; jnode& recv_node = recv_found[proc[jpart]]; + const size_t nb_recv_nodes = recv_node.size() / 2; + // array::ArrayView recv_node( recv_found[ proc[jpart] ].data(), + // array::make_shape(recv_found[ proc[jpart] ].size()/2,2) ); + for ( size_t jnode = 0; jnode < nb_recv_nodes; ++jnode ) { + ridx( recv_node[jnode * 2 + 0] ) = recv_node[jnode * 2 + 1]; + } } - else - { - ASSERT( jnode < part.shape(0) ); - if( part(jnode) >= (int)proc.size() ) - { - std::stringstream msg; - msg << "Assertion [part("<& recv_node = recv_found[ proc[jpart] ]; - const size_t nb_recv_nodes = recv_node.size()/2; - // array::ArrayView recv_node( recv_found[ proc[jpart] ].data(), - // array::make_shape(recv_found[ proc[jpart] ].size()/2,2) ); - for( size_t jnode=0; jnode edge_part = array::make_view( edges.partition() ); - array::ArrayView edge_glb_idx = array::make_view( edges.global_index() ); - - const mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); - const mesh::HybridElements::Connectivity& edge_to_elem = edges.cell_connectivity(); - - array::ArrayView node_part = array::make_view( nodes.partition() ); - array::ArrayView xy = array::make_view( nodes.xy() ); - array::ArrayView flags = array::make_view( nodes.field("flags") ); - array::ArrayView node_gidx = array::make_view( nodes.global_index() ); - - array::ArrayView elem_part = array::make_view(mesh.cells().partition() ); - - auto check_flags = [&](idx_t jedge, int flag) { - idx_t ip1 = edge_nodes(jedge,0); - idx_t ip2 = edge_nodes(jedge,1); - 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; - } - return false; - }; - - PeriodicTransform transform; - - size_t nb_edges = edges.size(); - - std::vector periodic(nb_edges); - - std::vector bdry_edges; bdry_edges.reserve(nb_edges); - std::map global_to_local; - - for( size_t jedge=0; jedge y2) ? pn1 : pn2; - } - - idx_t elem1 = edge_to_elem(jedge,0); - idx_t elem2 = edge_to_elem(jedge,1); - if( elem1 == edge_to_elem.missing_value() ) { - bdry_edges.push_back( edge_glb_idx(jedge) ); - p = pn1; - // Log::error() << EDGE(jedge) << " is a pole edge with part " << p << std::endl; - } else if(elem2 == edge_to_elem.missing_value()) { - // if( not domain_bdry(jedge) ) { - bdry_edges.push_back( edge_glb_idx(jedge) ); - p = elem_part(elem1); - // } - } else if( p != elem_part(elem1) && p != elem_part(elem2) ) { - p = ( p == pn1 ) ? pn2 : pn1; - - if( p != elem_part(elem1) and p != elem_part(elem2) ) { - std::stringstream msg; - msg << "[" << eckit::mpi::comm().rank() << "] " << EDGE(jedge) << " has nodes and elements of different rank: elem1[p"<::iterator it = std::lower_bound( bdry_edges.begin(), bdry_edges.end(), gid ); - bool found = !( it == bdry_edges.end() || gid < *it ); - return found; - }; - - int mpi_size = eckit::mpi::comm().size(); - mpi::Buffer recv_bdry_edges_from_parts(mpi_size); - std::vector< std::vector > send_gidx(mpi_size); - std::vector< std::vector > send_part(mpi_size); - std::vector< std::vector > recv_gidx(mpi_size); - std::vector< std::vector > recv_part(mpi_size); - mpi::comm().allGatherv(bdry_edges.begin(),bdry_edges.end(),recv_bdry_edges_from_parts); - for( int p=0; p edge_part = array::make_view( edges.partition() ); + array::ArrayView edge_glb_idx = array::make_view( edges.global_index() ); + + const mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); + const mesh::HybridElements::Connectivity& edge_to_elem = edges.cell_connectivity(); + + array::ArrayView node_part = array::make_view( nodes.partition() ); + array::ArrayView xy = array::make_view( nodes.xy() ); + array::ArrayView flags = array::make_view( nodes.field( "flags" ) ); + array::ArrayView node_gidx = array::make_view( nodes.global_index() ); + + array::ArrayView elem_part = array::make_view( mesh.cells().partition() ); + + auto check_flags = [&]( idx_t jedge, int flag ) { + idx_t ip1 = edge_nodes( jedge, 0 ); + idx_t ip2 = edge_nodes( jedge, 1 ); + 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; } + return false; + }; + + PeriodicTransform transform; + + size_t nb_edges = edges.size(); + + std::vector periodic( nb_edges ); + + std::vector bdry_edges; + bdry_edges.reserve( nb_edges ); + std::map global_to_local; + + for ( size_t jedge = 0; jedge < nb_edges; ++jedge ) { + global_to_local[edge_glb_idx( jedge )] = jedge; + + periodic[jedge] = 0; + idx_t ip1 = edge_nodes( jedge, 0 ); + idx_t ip2 = edge_nodes( jedge, 1 ); + int pn1 = node_part( ip1 ); + int pn2 = node_part( ip2 ); + int y1 = util::microdeg( xy( ip1, YY ) ); + int y2 = util::microdeg( xy( ip2, YY ) ); + int p; + if ( y1 == y2 ) { + int x1 = util::microdeg( xy( ip1, XX ) ); + int x2 = util::microdeg( xy( ip2, XX ) ); + p = ( x1 < x2 ) ? pn1 : pn2; + } + else { + p = ( y1 > y2 ) ? pn1 : pn2; + } + + idx_t elem1 = edge_to_elem( jedge, 0 ); + idx_t elem2 = edge_to_elem( jedge, 1 ); + if ( elem1 == edge_to_elem.missing_value() ) { + bdry_edges.push_back( edge_glb_idx( jedge ) ); + p = pn1; + // Log::error() << EDGE(jedge) << " is a pole edge with part " << p << + // std::endl; + } + else if ( elem2 == edge_to_elem.missing_value() ) { + // if( not domain_bdry(jedge) ) { + bdry_edges.push_back( edge_glb_idx( jedge ) ); + p = elem_part( elem1 ); + // } + } + else if ( p != elem_part( elem1 ) && p != elem_part( elem2 ) ) { + p = ( p == pn1 ) ? pn2 : pn1; + + if ( p != elem_part( elem1 ) and p != elem_part( elem2 ) ) { + std::stringstream msg; + msg << "[" << eckit::mpi::comm().rank() << "] " << EDGE( jedge ) + << " has nodes and elements of different rank: elem1[p" << elem_part( elem1 ) << "] elem2[p" + << elem_part( elem2 ) << "]"; + throw eckit::SeriousBug( msg.str(), Here() ); + } + } + edge_part( jedge ) = p; + } + std::sort( bdry_edges.begin(), bdry_edges.end() ); + auto is_bdry_edge = [&bdry_edges]( gidx_t gid ) { + std::vector::iterator it = std::lower_bound( bdry_edges.begin(), bdry_edges.end(), gid ); + bool found = !( it == bdry_edges.end() || gid < *it ); + return found; + }; + + int mpi_size = eckit::mpi::comm().size(); + mpi::Buffer recv_bdry_edges_from_parts( mpi_size ); + std::vector> send_gidx( mpi_size ); + std::vector> send_part( mpi_size ); + std::vector> recv_gidx( mpi_size ); + std::vector> recv_part( mpi_size ); + mpi::comm().allGatherv( bdry_edges.begin(), bdry_edges.end(), recv_bdry_edges_from_parts ); + for ( int p = 0; p < mpi_size; ++p ) { + auto view = recv_bdry_edges_from_parts[p]; + for ( int j = 0; j < view.size(); ++j ) { + gidx_t gidx = view[j]; + if ( global_to_local.count( gidx ) ) { + if ( not is_bdry_edge( gidx ) ) { + int iedge = global_to_local[gidx]; + send_gidx[p].push_back( gidx ); + send_part[p].push_back( edge_part( iedge ) ); + } + } + } + } + mpi::comm().allToAll( send_gidx, recv_gidx ); + mpi::comm().allToAll( send_part, recv_part ); + for ( int p = 0; p < mpi_size; ++p ) { + const auto& recv_gidx_p = recv_gidx[p]; + const auto& recv_part_p = recv_part[p]; + for ( int j = 0; j < recv_gidx_p.size(); ++j ) { + idx_t iedge = global_to_local[recv_gidx_p[j]]; + int prev = edge_part( iedge ); + edge_part( iedge ) = recv_part_p[j]; + // if( edge_part(iedge) != prev ) + // Log::error() << EDGE(iedge) << " part " << prev << " --> " << + // edge_part(iedge) << std::endl; + } + } + + // Sanity check + std::shared_ptr> is_pole_edge; + bool has_pole_edges = false; + if ( edges.has_field( "is_pole_edge" ) ) { + has_pole_edges = true; + is_pole_edge = std::shared_ptr>( + new array::ArrayView( array::make_view( edges.field( "is_pole_edge" ) ) ) ); + } + int insane = 0; + for ( size_t jedge = 0; jedge < nb_edges; ++jedge ) { + idx_t ip1 = edge_nodes( jedge, 0 ); + idx_t ip2 = edge_nodes( jedge, 1 ); + idx_t elem1 = edge_to_elem( jedge, 0 ); + idx_t elem2 = edge_to_elem( jedge, 1 ); + int p = edge_part( jedge ); + int pn1 = node_part( ip1 ); + int pn2 = node_part( ip2 ); + if ( has_pole_edges && ( *is_pole_edge )( jedge ) ) { + if ( p != pn1 || p != pn2 ) { + Log::error() << "pole edge " << EDGE( jedge ) << " [p" << p << "] is not correct" << std::endl; + insane = 1; + } + } + else { + if ( elem1 == edge_to_elem.missing_value() && elem2 == edge_to_elem.missing_value() ) { + Log::error() << EDGE( jedge ) << " has no neighbouring elements" << std::endl; + insane = 1; + } } - } - } - } - mpi::comm().allToAll(send_gidx,recv_gidx); - mpi::comm().allToAll(send_part,recv_part); - for( int p=0; p " << edge_part(iedge) << std::endl; - } - } - - - // Sanity check - std::shared_ptr< array::ArrayView > is_pole_edge; - bool has_pole_edges = false; - if( edges.has_field("is_pole_edge") ) - { - has_pole_edges = true; - is_pole_edge = std::shared_ptr>( new array::ArrayView(array::make_view( edges.field("is_pole_edge") ) ) ); - } - int insane = 0; - for( size_t jedge=0; jedge part " << edge_part(jedge)); -//#endif - - -//#ifdef DEBUGGING_PARFIELDS_disable -// if( PERIODIC_EDGE(jedge) ) -// DEBUG_VAR( " the part is " << edge_part(jedge) ); -//#endif -// } -// /// TODO: Make sure that the edge-partition is at least one of the partition numbers of the -// /// neighbouring elements. -// /// Because of this problem, the size of the halo should be set to 2 instead of 1!!! -// /// This will be addressed with JIRA issue ATLAS-12 - - return edges.partition(); + else { + int pe1 = elem_part( elem1 ); + int pe2 = elem_part( elem2 ); + bool edge_partition_is_same_as_one_of_elems = ( p == pe1 || p == pe2 ); + if ( not edge_partition_is_same_as_one_of_elems and not edge_partition_is_same_as_one_of_nodes ) { + Log::error() << EDGE( jedge ) << " is not correct elem1[p" << pe1 << "] elem2[p" << pe2 << "]" + << std::endl; + insane = 1; + } + } + } + mpi::comm().allReduceInPlace( insane, eckit::mpi::max() ); + if ( insane && eckit::mpi::comm().rank() == 0 ) throw eckit::Exception( "Sanity check failed", Here() ); + + //#ifdef DEBUGGING_PARFIELDS + // if( OWNED_EDGE(jedge) ) + // DEBUG( EDGE(jedge) << " --> part " << edge_part(jedge)); + //#endif + + //#ifdef DEBUGGING_PARFIELDS_disable + // if( PERIODIC_EDGE(jedge) ) + // DEBUG_VAR( " the part is " << edge_part(jedge) ); + //#endif + // } + // /// TODO: Make sure that the edge-partition is at least one of the + // partition numbers of the + // /// neighbouring elements. + // /// Because of this problem, the size of the halo should be set to 2 + // instead of 1!!! + // /// This will be addressed with JIRA issue ATLAS-12 + + return edges.partition(); } -Field& build_edges_remote_idx( Mesh& mesh ) -{ - ATLAS_TRACE(); +Field& build_edges_remote_idx( Mesh& mesh ) { + ATLAS_TRACE(); - const mesh::Nodes& nodes = mesh.nodes(); - UniqueLonLat compute_uid(mesh); + const mesh::Nodes& nodes = mesh.nodes(); + UniqueLonLat compute_uid( mesh ); - size_t mypart = mpi::comm().rank(); - size_t nparts = mpi::comm().size(); + size_t mypart = mpi::comm().rank(); + size_t nparts = mpi::comm().size(); - mesh::HybridElements& edges = mesh.edges(); + mesh::HybridElements& edges = mesh.edges(); - array::IndexView edge_ridx = array::make_indexview ( edges.remote_index() ); + array::IndexView edge_ridx = array::make_indexview( edges.remote_index() ); - const array::ArrayView edge_part = array::make_view( edges.partition() ); - const mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); + const array::ArrayView edge_part = array::make_view( edges.partition() ); + const mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); - array::ArrayView xy = array::make_view( nodes.xy() ); - array::ArrayView flags = array::make_view( nodes.field("flags") ); + array::ArrayView xy = array::make_view( nodes.xy() ); + array::ArrayView flags = array::make_view( nodes.field( "flags" ) ); #ifdef DEBUGGING_PARFIELDS - array::ArrayView node_gidx = array::make_view( nodes.global_index() ); - array::ArrayView node_part = array::make_view( nodes.partition() ); + array::ArrayView node_gidx = array::make_view( nodes.global_index() ); + array::ArrayView node_part = array::make_view( nodes.partition() ); #endif - std::shared_ptr< array::ArrayView > is_pole_edge; - bool has_pole_edges = false; - if( edges.has_field("is_pole_edge") ) - { - has_pole_edges = true; - is_pole_edge = std::shared_ptr< array::ArrayView > ( - new array::ArrayView( array::make_view( edges.field("is_pole_edge") ) ) ); - } - - const int nb_edges = edges.size(); - - double centroid[2]; - std::vector< std::vector > send_needed( mpi::comm().size() ); - std::vector< std::vector > recv_needed( mpi::comm().size() ); - int sendcnt=0; - std::map lookup; - - PeriodicTransform transform; - - - for( int jedge=0; jedge 0 ? 90. : -90.; + std::shared_ptr> is_pole_edge; + bool has_pole_edges = false; + if ( edges.has_field( "is_pole_edge" ) ) { + has_pole_edges = true; + is_pole_edge = std::shared_ptr>( + new array::ArrayView( array::make_view( edges.field( "is_pole_edge" ) ) ) ); } - bool needed(false); - - if( (Topology::check(flags(ip1),Topology::PERIODIC) && !Topology::check(flags(ip1),Topology::BC|Topology::WEST) && - Topology::check(flags(ip2),Topology::PERIODIC) && !Topology::check(flags(ip2),Topology::BC|Topology::WEST)) || - (Topology::check(flags(ip1),Topology::PERIODIC) && !Topology::check(flags(ip1),Topology::BC|Topology::WEST) && - Topology::check(flags(ip2),Topology::BC|Topology::WEST)) || - (Topology::check(flags(ip1),Topology::BC|Topology::WEST) && - Topology::check(flags(ip2),Topology::PERIODIC) && !Topology::check(flags(ip2),Topology::BC|Topology::WEST)) ) - { - needed = true; - if( Topology::check(flags(ip1),Topology::EAST ) ) - transform(centroid,-1); - else - transform(centroid,+1); - } + const int nb_edges = edges.size(); + + double centroid[2]; + std::vector> send_needed( mpi::comm().size() ); + std::vector> recv_needed( mpi::comm().size() ); + int sendcnt = 0; + std::map lookup; + + PeriodicTransform transform; + + for ( int jedge = 0; jedge < nb_edges; ++jedge ) { + int ip1 = edge_nodes( jedge, 0 ); + 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.; } + + bool needed( false ); + + if ( ( Topology::check( flags( ip1 ), Topology::PERIODIC ) && + !Topology::check( flags( ip1 ), Topology::BC | Topology::WEST ) && + Topology::check( flags( ip2 ), Topology::PERIODIC ) && + !Topology::check( flags( ip2 ), Topology::BC | Topology::WEST ) ) || + ( Topology::check( flags( ip1 ), Topology::PERIODIC ) && + !Topology::check( flags( ip1 ), Topology::BC | Topology::WEST ) && + Topology::check( flags( ip2 ), Topology::BC | Topology::WEST ) ) || + ( Topology::check( flags( ip1 ), Topology::BC | Topology::WEST ) && + Topology::check( flags( ip2 ), Topology::PERIODIC ) && + !Topology::check( flags( ip2 ), Topology::BC | Topology::WEST ) ) ) { + needed = true; + if ( Topology::check( flags( ip1 ), Topology::EAST ) ) + transform( centroid, -1 ); + else + transform( centroid, +1 ); + } - uid_t uid = util::unique_lonlat(centroid); - if( size_t(edge_part(jedge)) == mypart && !needed ) // All interior edges fall here - { - lookup[ uid ] = jedge; - edge_ridx(jedge) = jedge; + uid_t uid = util::unique_lonlat( centroid ); + if ( size_t( edge_part( jedge ) ) == mypart && !needed ) // All interior edges fall here + { + lookup[uid] = jedge; + edge_ridx( jedge ) = jedge; #ifdef DEBUGGING_PARFIELDS - if( FIND_EDGE(jedge) ) - { - DEBUG( "Found "< > send_found( mpi::comm().size() ); - std::vector< std::vector > recv_found( mpi::comm().size() ); - - std::map::iterator found; - for( size_t jpart=0; jpart& recv_edge = recv_needed[jpart]; - const size_t nb_recv_edges = recv_edge.size()/varsize; - // array::ArrayView recv_edge( recv_needed[ jpart ].data(), - // array::make_shape(recv_needed[ jpart ].size()/varsize,varsize) ); - for( size_t jedge=0; jedgesecond ); - } - else - { - std::stringstream msg; + ATLAS_TRACE_MPI( ALLTOALL ) { mpi::comm().allToAll( send_needed, recv_needed ); } + + std::vector> send_found( mpi::comm().size() ); + std::vector> recv_found( mpi::comm().size() ); + + std::map::iterator found; + for ( size_t jpart = 0; jpart < nparts; ++jpart ) { + const std::vector& recv_edge = recv_needed[jpart]; + const size_t nb_recv_edges = recv_edge.size() / varsize; + // array::ArrayView recv_edge( recv_needed[ jpart ].data(), + // array::make_shape(recv_needed[ jpart ].size()/varsize,varsize) ); + for ( size_t jedge = 0; jedge < nb_recv_edges; ++jedge ) { + uid_t recv_uid = recv_edge[jedge * varsize + 0]; + int recv_idx = recv_edge[jedge * varsize + 1]; + found = lookup.find( recv_uid ); + if ( found != lookup.end() ) { + send_found[jpart].push_back( recv_idx ); + send_found[jpart].push_back( found->second ); + } + else { + std::stringstream msg; #ifdef DEBUGGING_PARFIELDS - msg << "Edge("<& recv_edge = recv_found[jpart]; - const size_t nb_recv_edges = recv_edge.size()/2; - // array::ArrayView recv_edge( recv_found[ jpart ].data(), - // array::make_shape(recv_found[ jpart ].size()/2,2) ); - for( size_t jedge=0; jedge& recv_edge = recv_found[jpart]; + const size_t nb_recv_edges = recv_edge.size() / 2; + // array::ArrayView recv_edge( recv_found[ jpart ].data(), + // array::make_shape(recv_found[ jpart ].size()/2,2) ); + for ( size_t jedge = 0; jedge < nb_recv_edges; ++jedge ) { + edge_ridx( recv_edge[jedge * 2 + 0] ) = recv_edge[jedge * 2 + 1]; + } + } + return edges.remote_index(); } -Field& build_edges_global_idx( Mesh& mesh ) -{ - ATLAS_TRACE(); - - UniqueLonLat compute_uid(mesh); - - int nparts = mpi::comm().size(); - size_t root = 0; - - mesh::HybridElements& edges = mesh.edges(); - - array::make_view(edges.global_index()).assign(-1); - array::ArrayView edge_gidx = array::make_view( edges.global_index() ); - - const mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); - array::ArrayView xy = array::make_view( mesh.nodes().xy() ); - std::shared_ptr< array::ArrayView > is_pole_edge; - bool has_pole_edges = false; - if( edges.has_field("is_pole_edge") ) - { - has_pole_edges = true; - is_pole_edge = std::shared_ptr< array::ArrayView > ( - new array::ArrayView( array::make_view( edges.field("is_pole_edge") ) ) ); - } - - /* - * Sorting following edge_gidx will define global order of - * gathered fields. Special care needs to be taken for - * pole edges, as their centroid might coincide with - * other edges - */ - double centroid[2]; - int nb_edges = edges.size(); - for( int jedge=0; jedge 0 ? 90. : -90.; - } - edge_gidx(jedge) = util::unique_lonlat(centroid); - } - } - - /* - * REMOTE INDEX BASE = 1 - */ - - // 1) Gather all global indices, together with location - array::ArrayT loc_edge_id_arr(nb_edges); - array::ArrayView loc_edge_id = array::make_view(loc_edge_id_arr); - - for( int jedge=0; jedge recvcounts(mpi::comm().size()); - std::vector recvdispls(mpi::comm().size()); - - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gather(nb_edges, recvcounts, root); - } - - recvdispls[0]=0; - for (int jpart=1; jpart glb_edge_id_arr(glb_nb_edges); - array::ArrayView glb_edge_id = array::make_view(glb_edge_id_arr); - - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gatherv(loc_edge_id.data(), loc_edge_id.size(), - glb_edge_id.data(), recvcounts.data(), recvdispls.data(), root); - } - - // 2) Sort all global indices, and renumber from 1 to glb_nb_edges - std::vector edge_sort; edge_sort.reserve(glb_nb_edges); - for( size_t jedge=0; jedge( edges.global_index() ).assign( -1 ); + array::ArrayView edge_gidx = array::make_view( edges.global_index() ); + + const mesh::HybridElements::Connectivity& edge_nodes = edges.node_connectivity(); + array::ArrayView xy = array::make_view( mesh.nodes().xy() ); + std::shared_ptr> is_pole_edge; + bool has_pole_edges = false; + if ( edges.has_field( "is_pole_edge" ) ) { + has_pole_edges = true; + is_pole_edge = std::shared_ptr>( + new array::ArrayView( array::make_view( edges.field( "is_pole_edge" ) ) ) ); + } + + /* + * Sorting following edge_gidx will define global order of + * gathered fields. Special care needs to be taken for + * pole edges, as their centroid might coincide with + * other edges + */ + double centroid[2]; + int nb_edges = edges.size(); + for ( int jedge = 0; jedge < nb_edges; ++jedge ) { + 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.; } + edge_gidx( jedge ) = util::unique_lonlat( centroid ); + } } - else if( edge_sort[jedge].g != edge_sort[jedge-1].g ) + + /* + * REMOTE INDEX BASE = 1 + */ + + // 1) Gather all global indices, together with location + array::ArrayT loc_edge_id_arr( nb_edges ); + array::ArrayView loc_edge_id = array::make_view( loc_edge_id_arr ); + + for ( int jedge = 0; jedge < nb_edges; ++jedge ) { + loc_edge_id( jedge ) = edge_gidx( jedge ); + } + + std::vector recvcounts( mpi::comm().size() ); + std::vector recvdispls( mpi::comm().size() ); + + ATLAS_TRACE_MPI( GATHER ) { mpi::comm().gather( nb_edges, recvcounts, root ); } + + recvdispls[0] = 0; + for ( int jpart = 1; jpart < nparts; ++jpart ) // start at 1 { - ++gid; + recvdispls[jpart] = recvcounts[jpart - 1] + recvdispls[jpart - 1]; + } + int glb_nb_edges = std::accumulate( recvcounts.begin(), recvcounts.end(), 0 ); + + array::ArrayT glb_edge_id_arr( glb_nb_edges ); + array::ArrayView glb_edge_id = array::make_view( glb_edge_id_arr ); + + ATLAS_TRACE_MPI( GATHER ) { + mpi::comm().gatherv( loc_edge_id.data(), loc_edge_id.size(), glb_edge_id.data(), recvcounts.data(), + recvdispls.data(), root ); + } + + // 2) Sort all global indices, and renumber from 1 to glb_nb_edges + std::vector edge_sort; + edge_sort.reserve( glb_nb_edges ); + for ( size_t jedge = 0; jedge < glb_edge_id.shape( 0 ); ++jedge ) { + edge_sort.emplace_back( Node( glb_edge_id( jedge ), jedge ) ); + } + std::sort( edge_sort.begin(), edge_sort.end() ); + + // Assume edge gid start + uid_t gid( 0 ); + for ( size_t jedge = 0; jedge < edge_sort.size(); ++jedge ) { + if ( jedge == 0 ) { ++gid; } + else if ( edge_sort[jedge].g != edge_sort[jedge - 1].g ) { + ++gid; + } + int iedge = edge_sort[jedge].i; + glb_edge_id( iedge ) = gid; } - int iedge = edge_sort[jedge].i; - glb_edge_id(iedge) = gid; - } - // 3) Scatter renumbered back - ATLAS_TRACE_MPI( SCATTER ) { - mpi::comm().scatterv(glb_edge_id.data(), recvcounts.data(), recvdispls.data(), - loc_edge_id.data(), loc_edge_id.size(), root); - } + // 3) Scatter renumbered back + ATLAS_TRACE_MPI( SCATTER ) { + mpi::comm().scatterv( glb_edge_id.data(), recvcounts.data(), recvdispls.data(), loc_edge_id.data(), + loc_edge_id.size(), root ); + } - for( int jedge=0; jedge #include +#include "atlas/array.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/IndexView.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildPeriodicBoundaries.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/util/LonLatMicroDeg.h" #include "atlas/mesh/detail/PeriodicTransform.h" -#include "atlas/array.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/IndexView.h" -#include "atlas/runtime/ErrorHandling.h" -#include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/mpi/Statistics.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/ErrorHandling.h" +#include "atlas/util/CoordinateEnums.h" +#include "atlas/util/LonLatMicroDeg.h" using Topology = atlas::mesh::Nodes::Topology; -using atlas::util::LonLatMicroDeg; using atlas::mesh::detail::PeriodicTransform; +using atlas::util::LonLatMicroDeg; namespace atlas { namespace mesh { @@ -34,197 +35,168 @@ namespace actions { typedef gidx_t uid_t; -void build_periodic_boundaries( Mesh& mesh ) -{ - bool periodic = false; - mesh.metadata().get("periodic",periodic); - if( ! periodic ) - { - - - - - - - - int mypart = mpi::comm().rank(); - - mesh::Nodes& nodes = mesh.nodes(); +void build_periodic_boundaries( Mesh& mesh ) { + bool periodic = false; + mesh.metadata().get( "periodic", periodic ); + if ( !periodic ) { + int mypart = mpi::comm().rank(); + + mesh::Nodes& nodes = mesh.nodes(); + + array::ArrayView flags = array::make_view( nodes.field( "flags" ) ); + array::IndexView ridx = array::make_indexview( nodes.remote_index() ); + array::ArrayView part = array::make_view( nodes.partition() ); + array::ArrayView ghost = array::make_view( nodes.ghost() ); + + int nb_nodes = nodes.size(); + + array::ArrayView xy = array::make_view( nodes.xy() ); + + // Identify my master and slave nodes on own partition + // master nodes are at x=0, slave nodes are at x=2pi + std::map master_lookup; + std::map slave_lookup; + std::vector master_nodes; + master_nodes.reserve( 3 * nb_nodes ); + std::vector slave_nodes; + slave_nodes.reserve( 3 * nb_nodes ); + + for ( size_t jnode = 0; jnode < nodes.size(); ++jnode ) { + if ( Topology::check_all( flags( jnode ), Topology::BC | Topology::WEST ) ) { + Topology::set( flags( jnode ), Topology::PERIODIC ); + if ( part( jnode ) == mypart ) { + LonLatMicroDeg ll( xy( jnode, XX ), xy( jnode, YY ) ); + master_lookup[ll.unique()] = jnode; + master_nodes.push_back( ll.lon() ); + master_nodes.push_back( ll.lat() ); + master_nodes.push_back( jnode ); + } + } + else if ( Topology::check( flags( jnode ), Topology::BC | Topology::EAST ) ) { + Topology::set( flags( jnode ), Topology::PERIODIC ); + Topology::set( flags( jnode ), Topology::GHOST ); + ghost( jnode ) = 1; + LonLatMicroDeg ll( xy( jnode, XX ), xy( jnode, YY ) ); + slave_lookup[ll.unique()] = jnode; + slave_nodes.push_back( ll.lon() ); + slave_nodes.push_back( ll.lat() ); + slave_nodes.push_back( jnode ); + ridx( jnode ) = -1; + } + } - array::ArrayView flags = array::make_view( nodes.field("flags") ); - array::IndexView ridx = array::make_indexview( nodes.remote_index() ); - array::ArrayView part = array::make_view( nodes.partition() ); - array::ArrayView ghost = array::make_view( nodes.ghost() ); + std::vector> found_master( mpi::comm().size() ); + std::vector> send_slave_idx( mpi::comm().size() ); - int nb_nodes = nodes.size(); + // Find masters on other tasks to send to me + { + int sendcnt = slave_nodes.size(); + std::vector recvcounts( mpi::comm().size() ); + + ATLAS_TRACE_MPI( ALLGATHER ) { mpi::comm().allGather( sendcnt, recvcounts.begin(), recvcounts.end() ); } + + std::vector recvdispls( mpi::comm().size() ); + recvdispls[0] = 0; + int recvcnt = recvcounts[0]; + for ( size_t jproc = 1; jproc < mpi::comm().size(); ++jproc ) { + recvdispls[jproc] = recvdispls[jproc - 1] + recvcounts[jproc - 1]; + recvcnt += recvcounts[jproc]; + } + std::vector recvbuf( recvcnt ); + + ATLAS_TRACE_MPI( ALLGATHER ) { + mpi::comm().allGatherv( slave_nodes.begin(), slave_nodes.end(), recvbuf.begin(), recvcounts.data(), + recvdispls.data() ); + } + + PeriodicTransform transform; + for ( size_t jproc = 0; jproc < mpi::comm().size(); ++jproc ) { + found_master.reserve( master_nodes.size() ); + send_slave_idx.reserve( master_nodes.size() ); + array::LocalView recv_slave( recvbuf.data() + recvdispls[jproc], + array::make_shape( recvcounts[jproc] / 3, 3 ) ); + for ( size_t jnode = 0; jnode < recv_slave.shape( 0 ); ++jnode ) { + LonLatMicroDeg slave( recv_slave( jnode, LON ), recv_slave( jnode, LAT ) ); + transform( slave, -1 ); + uid_t slave_uid = slave.unique(); + if ( master_lookup.count( slave_uid ) ) { + int master_idx = master_lookup[slave_uid]; + int slave_idx = recv_slave( jnode, 2 ); + found_master[jproc].push_back( master_idx ); + send_slave_idx[jproc].push_back( slave_idx ); + } + } + } + } - array::ArrayView xy = array::make_view( nodes.xy() ); + // Fill in data to communicate + std::vector> recv_slave_idx( mpi::comm().size() ); + std::vector> send_master_part( mpi::comm().size() ); + std::vector> recv_master_part( mpi::comm().size() ); + std::vector> send_master_ridx( mpi::comm().size() ); + std::vector> recv_master_ridx( mpi::comm().size() ); - // Identify my master and slave nodes on own partition - // master nodes are at x=0, slave nodes are at x=2pi - std::map master_lookup; - std::map slave_lookup; - std::vector master_nodes; master_nodes.reserve( 3*nb_nodes ); - std::vector slave_nodes; slave_nodes.reserve( 3*nb_nodes ); + // std::vector< std::vector > send_slave_part( mpi::comm().size() ); + // std::vector< std::vector > recv_slave_part( mpi::comm().size() ); + // std::vector< std::vector > send_slave_ridx( mpi::comm().size() ); + // std::vector< std::vector > recv_slave_ridx( mpi::comm().size() ); - for( size_t jnode=0; jnode > found_master(mpi::comm().size()); - std::vector< std::vector > send_slave_idx(mpi::comm().size()); - - // Find masters on other tasks to send to me - { - int sendcnt = slave_nodes.size(); - std::vector< int > recvcounts( mpi::comm().size() ); - - ATLAS_TRACE_MPI( ALLGATHER ) { - mpi::comm().allGather(sendcnt, recvcounts.begin(), recvcounts.end()); - } - - std::vector recvdispls( mpi::comm().size() ); - recvdispls[0] = 0; - int recvcnt = recvcounts[0]; - for( size_t jproc=1; jproc recvbuf(recvcnt); - - ATLAS_TRACE_MPI( ALLGATHER ) { - mpi::comm().allGatherv(slave_nodes.begin(), slave_nodes.end(), recvbuf.begin(), recvcounts.data(), recvdispls.data()); - } - - PeriodicTransform transform; - for( size_t jproc=0; jproc recv_slave(recvbuf.data()+recvdispls[jproc], array::make_shape(recvcounts[jproc]/3,3) ); - for( size_t jnode=0; jnode > recv_slave_idx( mpi::comm().size() ); - std::vector< std::vector > send_master_part( mpi::comm().size() ); - std::vector< std::vector > recv_master_part( mpi::comm().size() ); - std::vector< std::vector > send_master_ridx( mpi::comm().size() ); - std::vector< std::vector > recv_master_ridx( mpi::comm().size() ); - - // std::vector< std::vector > send_slave_part( mpi::comm().size() ); - // std::vector< std::vector > recv_slave_part( mpi::comm().size() ); - // std::vector< std::vector > send_slave_ridx( mpi::comm().size() ); - // std::vector< std::vector > recv_slave_ridx( mpi::comm().size() ); - - { - for( size_t jproc=0; jproc +#include #include -#include #include -#include +#include +#include #include -#include "eckit/filesystem/PathName.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" #include "atlas/library/config.h" +#include "atlas/mesh/ElementType.h" +#include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/Elements.h" -#include "atlas/mesh/ElementType.h" #include "atlas/mesh/actions/BuildDualMesh.h" -#include "atlas/field/Field.h" +#include "atlas/parallel/Checksum.h" +#include "atlas/runtime/ErrorHandling.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" #include "atlas/util/Point.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/MakeView.h" -#include "atlas/runtime/ErrorHandling.h" -#include "atlas/parallel/Checksum.h" +#include "eckit/filesystem/PathName.h" namespace atlas { namespace mesh { @@ -37,229 +38,199 @@ namespace actions { namespace { -void tri_quality(double& eta, double& rho, const PointLonLat& p1, const PointLonLat& p2, const PointLonLat& p3) -{ - // see http://www.gidhome.com/component/manual/referencemanual/preprocessing/mesh_menu/mesh_quality +void tri_quality( double& eta, double& rho, const PointLonLat& p1, const PointLonLat& p2, const PointLonLat& p3 ) { + // see + // http://www.gidhome.com/component/manual/referencemanual/preprocessing/mesh_menu/mesh_quality - double l12 = util::Constants::radiansToDegrees() * util::Earth::centralAngle(p1, p2); - double l23 = util::Constants::radiansToDegrees() * util::Earth::centralAngle(p2, p3); - double l31 = util::Constants::radiansToDegrees() * util::Earth::centralAngle(p3, p1); + double l12 = util::Constants::radiansToDegrees() * util::Earth::centralAngle( p1, p2 ); + double l23 = util::Constants::radiansToDegrees() * util::Earth::centralAngle( p2, p3 ); + double l31 = util::Constants::radiansToDegrees() * util::Earth::centralAngle( p3, p1 ); - double s = 0.5*(l12 + l23 + l31); - double area = std::sqrt(s * (s - l12) * (s - l23) * (s - l31)); + double s = 0.5 * ( l12 + l23 + l31 ); + double area = std::sqrt( s * ( s - l12 ) * ( s - l23 ) * ( s - l31 ) ); - eta = (4*area*std::sqrt(3.))/( std::pow(l12,2)+std::pow(l23,2)+std::pow(l31,2) ); + eta = ( 4 * area * std::sqrt( 3. ) ) / ( std::pow( l12, 2 ) + std::pow( l23, 2 ) + std::pow( l31, 2 ) ); - double min_length = std::min(std::min(l12,l23),l31); - double max_length = std::max(std::max(l12,l23),l31); + double min_length = std::min( std::min( l12, l23 ), l31 ); + double max_length = std::max( std::max( l12, l23 ), l31 ); - rho = min_length / max_length; + rho = min_length / max_length; } -void quad_quality(double& eta, double& rho, const PointLonLat& p1, const PointLonLat& p2, const PointLonLat& p3, const PointLonLat& p4) -{ - // see http://geuz.org/gmsh/doc/preprints/gmsh_quad_preprint.pdf - - const PointXYZ xyz[] { - util::Earth::convertGeodeticToGeocentric(p1, 1.), - util::Earth::convertGeodeticToGeocentric(p2, 1.), - util::Earth::convertGeodeticToGeocentric(p3, 1.), - util::Earth::convertGeodeticToGeocentric(p4, 1.) - }; +void quad_quality( double& eta, double& rho, const PointLonLat& p1, const PointLonLat& p2, const PointLonLat& p3, + const PointLonLat& p4 ) { + // see http://geuz.org/gmsh/doc/preprints/gmsh_quad_preprint.pdf - PointXYZ l2m1(PointXYZ::sub(xyz[1], xyz[0])); - PointXYZ l3m2(PointXYZ::sub(xyz[2], xyz[1])); - PointXYZ l4m3(PointXYZ::sub(xyz[3], xyz[2])); - PointXYZ l1m4(PointXYZ::sub(xyz[0], xyz[3])); + const PointXYZ xyz[]{ + util::Earth::convertGeodeticToGeocentric( p1, 1. ), util::Earth::convertGeodeticToGeocentric( p2, 1. ), + util::Earth::convertGeodeticToGeocentric( p3, 1. ), util::Earth::convertGeodeticToGeocentric( p4, 1. )}; - double norm_l2m1 = PointXYZ::norm(l2m1); - double norm_l3m2 = PointXYZ::norm(l3m2); - double norm_l4m3 = PointXYZ::norm(l4m3); - double norm_l1m4 = PointXYZ::norm(l1m4); + PointXYZ l2m1( PointXYZ::sub( xyz[1], xyz[0] ) ); + PointXYZ l3m2( PointXYZ::sub( xyz[2], xyz[1] ) ); + PointXYZ l4m3( PointXYZ::sub( xyz[3], xyz[2] ) ); + PointXYZ l1m4( PointXYZ::sub( xyz[0], xyz[3] ) ); - double dot_l4m1_l2m1 = - PointXYZ::dot(l1m4, l2m1); - double dot_l1m2_l3m2 = - PointXYZ::dot(l2m1, l3m2); - double dot_l2m3_l4m3 = - PointXYZ::dot(l3m2, l4m3); - double dot_l3m4_l1m4 = - PointXYZ::dot(l4m3, l1m4); + double norm_l2m1 = PointXYZ::norm( l2m1 ); + double norm_l3m2 = PointXYZ::norm( l3m2 ); + double norm_l4m3 = PointXYZ::norm( l4m3 ); + double norm_l1m4 = PointXYZ::norm( l1m4 ); - // Angles at each quad corner - double a1 = std::acos( dot_l4m1_l2m1 / ( norm_l1m4 * norm_l2m1 ) ); - double a2 = std::acos( dot_l1m2_l3m2 / ( norm_l2m1 * norm_l3m2 ) ); - double a3 = std::acos( dot_l2m3_l4m3 / ( norm_l3m2 * norm_l4m3 ) ); - double a4 = std::acos( dot_l3m4_l1m4 / ( norm_l4m3 * norm_l1m4 ) ); + double dot_l4m1_l2m1 = -PointXYZ::dot( l1m4, l2m1 ); + double dot_l1m2_l3m2 = -PointXYZ::dot( l2m1, l3m2 ); + double dot_l2m3_l4m3 = -PointXYZ::dot( l3m2, l4m3 ); + double dot_l3m4_l1m4 = -PointXYZ::dot( l4m3, l1m4 ); - double max_inner = std::max( std::max( std::max( - std::abs(M_PI_2-a1), std::abs(M_PI_2-a2) ), std::abs(M_PI_2-a3) ), std::abs(M_PI_2-a4)); + // Angles at each quad corner + double a1 = std::acos( dot_l4m1_l2m1 / ( norm_l1m4 * norm_l2m1 ) ); + double a2 = std::acos( dot_l1m2_l3m2 / ( norm_l2m1 * norm_l3m2 ) ); + double a3 = std::acos( dot_l2m3_l4m3 / ( norm_l3m2 * norm_l4m3 ) ); + double a4 = std::acos( dot_l3m4_l1m4 / ( norm_l4m3 * norm_l1m4 ) ); - eta = std::max(1. - M_2_PI*max_inner, 0.); + double max_inner = + std::max( std::max( std::max( std::abs( M_PI_2 - a1 ), std::abs( M_PI_2 - a2 ) ), std::abs( M_PI_2 - a3 ) ), + std::abs( M_PI_2 - a4 ) ); - double l12 = util::Earth::centralAngle(p1, p2); - double l23 = util::Earth::centralAngle(p2, p3); - double l34 = util::Earth::centralAngle(p3, p4); - double l41 = util::Earth::centralAngle(p4, p1); + eta = std::max( 1. - M_2_PI * max_inner, 0. ); - double min_length = std::min(std::min(std::min(l12,l23),l34),l41); - double max_length = std::max(std::max(std::max(l12,l23),l34),l41); + double l12 = util::Earth::centralAngle( p1, p2 ); + double l23 = util::Earth::centralAngle( p2, p3 ); + double l34 = util::Earth::centralAngle( p3, p4 ); + double l41 = util::Earth::centralAngle( p4, p1 ); - rho = min_length / max_length; -} + double min_length = std::min( std::min( std::min( l12, l23 ), l34 ), l41 ); + double max_length = std::max( std::max( std::max( l12, l23 ), l34 ), l41 ); + rho = min_length / max_length; } -void build_statistics( Mesh& mesh ) -{ - mesh::Nodes& nodes = mesh.nodes(); - array::ArrayView lonlat = array::make_view( nodes.lonlat() ); - - if( mesh.edges().size() ) - { - 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(); - - const int nb_edges = mesh.edges().size(); - for( int jedge=0; jedge rho = array::make_view( mesh.cells().add( - Field("stats_rho", array::make_datatype(), array::make_shape(mesh.cells().size()) ) ) ); - array::ArrayView eta = array::make_view( mesh.cells().add( - Field("stats_eta", array::make_datatype(), array::make_shape(mesh.cells().size()) ) ) ); - - for( size_t jtype=0; jtype lonlat = array::make_view( nodes.lonlat() ); + + if ( mesh.edges().size() ) { + 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(); + + const int nb_edges = mesh.edges().size(); + for ( int jedge = 0; jedge < nb_edges; ++jedge ) { + int ip1 = edge_nodes( jedge, 0 ); + int ip2 = edge_nodes( jedge, 1 ); + PointLonLat p1( lonlat( ip1, LON ), lonlat( ip1, LAT ) ); + PointLonLat p2( lonlat( ip2, LON ), lonlat( ip2, LAT ) ); + dist( jedge ) = util::Earth::distanceInMeters( p1, p2 ) * 1e-3; } + } - } + std::ofstream ofs; + eckit::PathName stats_path( "stats.txt" ); + int idt = 10; + if ( mpi::comm().size() == 1 ) { + ofs.open( stats_path.localPath(), std::ofstream::out ); + ofs << "# STATISTICS rho (min_length/max_length), eta (quality) \n"; + ofs << std::setw( idt ) << "# rho"; + ofs << std::setw( idt ) << "eta"; + ofs << "\n"; + ofs.close(); } - if( mpi::comm().size() == 1 ) - ofs.close(); - } - - eckit::PathName dual_stats_path("dual_stats.txt"); - if( mpi::comm().size() == 1 ) - { - ofs.open( dual_stats_path.localPath(), std::ofstream::out ); - ofs << "# STATISTICS dual_area \n"; - ofs << std::setw(idt) << "# area"; - ofs << "\n"; - } - - if( nodes.has_field("dual_volumes") ) - { - array::ArrayView dual_volumes = array::make_view( nodes.field("dual_volumes") ); - array::ArrayView dual_delta_sph = array::make_view( nodes.add( - Field( "dual_delta_sph", array::make_datatype(), array::make_shape(nodes.size(),1) ) ) ); - - for( size_t jnode=0; jnode rho = array::make_view( mesh.cells().add( + Field( "stats_rho", array::make_datatype(), array::make_shape( mesh.cells().size() ) ) ) ); + array::ArrayView eta = array::make_view( mesh.cells().add( + Field( "stats_eta", array::make_datatype(), array::make_shape( mesh.cells().size() ) ) ) ); + + for ( size_t jtype = 0; jtype < mesh.cells().nb_types(); ++jtype ) { + const mesh::Elements& elements = mesh.cells().elements( jtype ); + const BlockConnectivity& elem_nodes = elements.node_connectivity(); + const size_t nb_elems = elements.size(); + + if ( elements.element_type().name() == "Triangle" ) { + for ( size_t jelem = 0; jelem < nb_elems; ++jelem ) { + size_t ielem = elements.begin() + jelem; + size_t ip1 = elem_nodes( jelem, 0 ); + size_t ip2 = elem_nodes( jelem, 1 ); + size_t ip3 = elem_nodes( jelem, 2 ); + PointLonLat p1( lonlat( ip1, LON ), lonlat( ip1, LAT ) ); + PointLonLat p2( lonlat( ip2, LON ), lonlat( ip2, LAT ) ); + PointLonLat p3( lonlat( ip3, LON ), lonlat( ip3, LAT ) ); + + tri_quality( eta( ielem ), rho( ielem ), p1, p2, p3 ); + + if ( mpi::comm().size() == 1 ) { + ofs << std::setw( idt ) << rho( ielem ) << std::setw( idt ) << eta( ielem ) << "\n"; + } + } + } + if ( elements.element_type().name() == "Quadrilateral" ) { + for ( size_t jelem = 0; jelem < nb_elems; ++jelem ) { + size_t ielem = elements.begin() + jelem; + size_t ip1 = elem_nodes( jelem, 0 ); + size_t ip2 = elem_nodes( jelem, 1 ); + size_t ip3 = elem_nodes( jelem, 2 ); + size_t ip4 = elem_nodes( jelem, 3 ); + + PointLonLat p1( lonlat( ip1, LON ), lonlat( ip1, LAT ) ); + PointLonLat p2( lonlat( ip2, LON ), lonlat( ip2, LAT ) ); + PointLonLat p3( lonlat( ip3, LON ), lonlat( ip3, LAT ) ); + PointLonLat p4( lonlat( ip4, LON ), lonlat( ip4, LAT ) ); + + quad_quality( eta( ielem ), rho( ielem ), p1, p2, p3, p4 ); + + if ( mpi::comm().size() == 1 ) { + ofs << std::setw( idt ) << rho( ielem ) << std::setw( idt ) << eta( ielem ) << "\n"; + } + } + } + } + if ( mpi::comm().size() == 1 ) ofs.close(); } - if( mpi::comm().size() == 1 ) - { - for( size_t jnode=0; jnode dual_volumes = array::make_view( nodes.field( "dual_volumes" ) ); + array::ArrayView dual_delta_sph = array::make_view( nodes.add( + Field( "dual_delta_sph", array::make_datatype(), array::make_shape( nodes.size(), 1 ) ) ) ); + for ( size_t jnode = 0; jnode < nodes.size(); ++jnode ) { + const double lat = util::Constants::degreesToRadians() * lonlat( jnode, LAT ); + const double hx = util::Constants::degreesToRadians() * util::Earth::radiusInKm() * std::cos( lat ); + const double hy = util::Constants::degreesToRadians() * util::Earth::radiusInKm(); + dual_delta_sph( jnode ) = std::sqrt( dual_volumes( jnode ) * hx * hy ); + } + + if ( mpi::comm().size() == 1 ) { + for ( size_t jnode = 0; jnode < nodes.size(); ++jnode ) { + ofs << std::setw( idt ) << dual_delta_sph( jnode ) << "\n"; + } + } + } + if ( mpi::comm().size() == 1 ) ofs.close(); } // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -void atlas__build_statistics ( Mesh::Implementation* mesh) { - ATLAS_ERROR_HANDLING( Mesh m(mesh); build_statistics(m); ); +void atlas__build_statistics( Mesh::Implementation* mesh ) { + ATLAS_ERROR_HANDLING( Mesh m( mesh ); build_statistics( m ); ); } // ------------------------------------------------------------------ -} // namespace actions -} // namespace mesh -} // namespace atlas - +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/BuildStatistics.h b/src/atlas/mesh/actions/BuildStatistics.h index 5d3724f47..1899e5969 100644 --- a/src/atlas/mesh/actions/BuildStatistics.h +++ b/src/atlas/mesh/actions/BuildStatistics.h @@ -4,17 +4,16 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - - #ifndef BuildStatistics_h #define BuildStatistics_h namespace atlas { - class Mesh; +class Mesh; namespace mesh { namespace actions { @@ -23,14 +22,13 @@ void build_statistics( Mesh& mesh ); // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -extern "C" -{ - void atlas__build_statistics (Mesh::Implementation* mesh); +extern "C" { +void atlas__build_statistics( Mesh::Implementation* mesh ); } // ------------------------------------------------------------------ -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas -#endif // BuildStatistics_h +#endif // BuildStatistics_h diff --git a/src/atlas/mesh/actions/BuildTorusXYZField.cc b/src/atlas/mesh/actions/BuildTorusXYZField.cc index ce718b404..7db5891b9 100644 --- a/src/atlas/mesh/actions/BuildTorusXYZField.cc +++ b/src/atlas/mesh/actions/BuildTorusXYZField.cc @@ -4,19 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include +#include "atlas/array/ArrayView.h" +#include "atlas/domain/detail/GlobalDomain.h" +#include "atlas/domain/detail/RectangularDomain.h" +#include "atlas/field/Field.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildTorusXYZField.h" -#include "atlas/field/Field.h" -#include "atlas/array/ArrayView.h" -#include "atlas/domain/detail/RectangularDomain.h" -#include "atlas/domain/detail/GlobalDomain.h" namespace atlas { namespace mesh { @@ -24,52 +25,47 @@ namespace actions { //---------------------------------------------------------------------------------------------------------------------- -BuildTorusXYZField::BuildTorusXYZField(const std::string& name) - : name_(name) -{ -} +BuildTorusXYZField::BuildTorusXYZField( const std::string& name ) : name_( name ) {} -Field& BuildTorusXYZField::operator()(Mesh& mesh, const Domain& dom, double r0, double r1, int nx, int ny) const -{ - return operator()(mesh.nodes(),dom,r0,r1,nx,ny); +Field& BuildTorusXYZField::operator()( Mesh& mesh, const Domain& dom, double r0, double r1, int nx, int ny ) const { + return operator()( mesh.nodes(), dom, r0, r1, nx, ny ); } -Field& BuildTorusXYZField::operator()(mesh::Nodes& nodes, const Domain& dom, double r0, double r1, int nx, int ny) const -{ - // fill xyz with torus coordinates. r0 and r1 are large and small radii, respectively. +Field& BuildTorusXYZField::operator()( mesh::Nodes& nodes, const Domain& dom, double r0, double r1, int nx, + int ny ) const { + // fill xyz with torus coordinates. r0 and r1 are large and small radii, + // respectively. - auto domain = RectangularDomain( dom ); - ASSERT( domain ); - const double xmin = domain.xmin(); - const double xmax = domain.xmax(); - const double ymin = domain.ymin(); - const double ymax = domain.ymax(); + auto domain = RectangularDomain( dom ); + ASSERT( domain ); + const double xmin = domain.xmin(); + const double xmax = domain.xmax(); + const double ymin = domain.ymin(); + const double ymax = domain.ymax(); - if( !nodes.has_field(name_) ) - { - const size_t npts = nodes.size(); - const array::ArrayView lonlat = array::make_view( nodes.xy() ); - array::ArrayView xyz = array::make_view( nodes.add( - Field(name_,array::make_datatype(),array::make_shape(npts,3) ) ) ); + if ( !nodes.has_field( name_ ) ) { + const size_t npts = nodes.size(); + const array::ArrayView lonlat = array::make_view( nodes.xy() ); + array::ArrayView xyz = array::make_view( + nodes.add( Field( name_, array::make_datatype(), array::make_shape( npts, 3 ) ) ) ); - const double pi=M_PI; - const double c1 = 2.*pi/double(nx)*(nx-1)/(xmax-xmin); - const double c2 = 2.*pi/double(ny)*(ny-1)/(ymax-ymin); - for( size_t n=0; n(), array::make_shape(nodes.size(),3) ) ); - recompute = true; - } - if( recompute ) { - array::ArrayView lonlat = array::make_view( nodes.lonlat() ); - array::ArrayView xyz = array::make_view( nodes.field(name_) ); - - PointXYZ p2; - for( size_t n=0; n(), array::make_shape( nodes.size(), 3 ) ) ); + recompute = true; + } + if ( recompute ) { + array::ArrayView lonlat = array::make_view( nodes.lonlat() ); + array::ArrayView xyz = array::make_view( nodes.field( name_ ) ); + + PointXYZ p2; + for ( size_t n = 0; n < nodes.size(); ++n ) { + const PointLonLat p1( lonlat( n, 0 ), lonlat( n, 1 ) ); + p2 = util::Earth::convertGeodeticToGeocentric( p1 ); + xyz( n, 0 ) = p2.x(); + xyz( n, 1 ) = p2.y(); + xyz( n, 2 ) = p2.z(); + } } - } - return nodes.field(name_); + return nodes.field( name_ ); } //---------------------------------------------------------------------------------------------------------------------- -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/BuildXYZField.h b/src/atlas/mesh/actions/BuildXYZField.h index 341bd65ec..2a5999872 100644 --- a/src/atlas/mesh/actions/BuildXYZField.h +++ b/src/atlas/mesh/actions/BuildXYZField.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,14 +14,15 @@ #include namespace atlas { - class Field; - class Mesh; -} +class Field; +class Mesh; +} // namespace atlas namespace atlas { namespace mesh { - class Nodes; -} } +class Nodes; +} +} // namespace atlas namespace atlas { namespace mesh { @@ -31,21 +33,18 @@ namespace actions { /// Creates a XYZ field from the (lon,lat) field class BuildXYZField { public: + explicit BuildXYZField( const std::string& name = "xyz", bool force_recompute = false ); - explicit BuildXYZField(const std::string& name = "xyz", bool force_recompute=false); - - Field& operator()(Mesh&) const; - Field& operator()(mesh::Nodes&) const; + Field& operator()( Mesh& ) const; + Field& operator()( mesh::Nodes& ) const; private: - std::string name_; bool force_recompute_; - }; //---------------------------------------------------------------------------------------------------------------------- -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.cc b/src/atlas/mesh/actions/ExtendNodesGlobal.cc index a5cc6056d..1a24c05b8 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.cc +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.cc @@ -4,34 +4,29 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "atlas/mesh/actions/ExtendNodesGlobal.h" -#include "eckit/exception/Exceptions.h" #include "atlas/field/Field.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" - +#include "eckit/exception/Exceptions.h" namespace atlas { namespace mesh { namespace actions { -ExtendNodesGlobal::ExtendNodesGlobal( const std::string& gridname ) : - gridname_(gridname) { -} +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 +void ExtendNodesGlobal::operator()( const Grid& grid, Mesh& mesh ) const { + if ( grid.domain().global() ) return; // don't add virtual points to global domains Grid O16( "O16" ); @@ -41,51 +36,47 @@ void ExtendNodesGlobal::operator()(const Grid& grid, Mesh& mesh) const { // loop over the point and keep the ones that *don't* fall in the domain - for( const PointLonLat& lonlat : O16.lonlat() ) { - PointXY xy = grid.projection().xy(lonlat); - if( not grid.domain().contains( xy ) ) { - extended_pts.push_back(xy); - } + for ( const PointLonLat& lonlat : O16.lonlat() ) { + PointXY xy = grid.projection().xy( lonlat ); + if ( not grid.domain().contains( xy ) ) { extended_pts.push_back( xy ); } } mesh::Nodes& nodes = mesh.nodes(); - const size_t nb_real_pts = nodes.size(); + const size_t nb_real_pts = nodes.size(); const size_t nb_extension_pts = extended_pts.size(); size_t new_size = nodes.size() + extended_pts.size(); - nodes.resize(new_size); // resizes the fields + nodes.resize( new_size ); // resizes the fields const size_t nb_total_pts = nodes.size(); ASSERT( nb_total_pts == nb_real_pts + nb_extension_pts ); - nodes.metadata().set("NbRealPts",nb_real_pts); - nodes.metadata().set("NbVirtualPts",nb_extension_pts); - - array::ArrayView xyz = array::make_view( nodes.field("xyz") ); - array::ArrayView xy = array::make_view( nodes.xy() ); - array::ArrayView lonlat = array::make_view( nodes.lonlat() ); - array::ArrayView gidx = array::make_view( nodes.global_index() ); - - for(size_t i = 0; i < nb_extension_pts; ++i) { - const size_t n = nb_real_pts + i; - const PointLonLat pLL = grid.projection().lonlat(extended_pts[i]); - const PointXYZ pXYZ = util::Earth::convertGeodeticToGeocentric(pLL); - xyz(n,XX) = pXYZ.x(); - xyz(n,YY) = pXYZ.y(); - xyz(n,ZZ) = pXYZ.z(); - xy(n,XX) = extended_pts[i].x(); - xy(n,YY) = extended_pts[i].y(); - lonlat(n,LON) = pLL.lon(); - lonlat(n,LAT) = pLL.lat(); - gidx(n) = n+1; + nodes.metadata().set( "NbRealPts", nb_real_pts ); + nodes.metadata().set( "NbVirtualPts", nb_extension_pts ); + + array::ArrayView xyz = array::make_view( nodes.field( "xyz" ) ); + array::ArrayView xy = array::make_view( nodes.xy() ); + array::ArrayView lonlat = array::make_view( nodes.lonlat() ); + array::ArrayView gidx = array::make_view( nodes.global_index() ); + + for ( size_t i = 0; i < nb_extension_pts; ++i ) { + const size_t n = nb_real_pts + i; + const PointLonLat pLL = grid.projection().lonlat( extended_pts[i] ); + const PointXYZ pXYZ = util::Earth::convertGeodeticToGeocentric( pLL ); + xyz( n, XX ) = pXYZ.x(); + xyz( n, YY ) = pXYZ.y(); + xyz( n, ZZ ) = pXYZ.z(); + xy( n, XX ) = extended_pts[i].x(); + xy( n, YY ) = extended_pts[i].y(); + lonlat( n, LON ) = pLL.lon(); + lonlat( n, LAT ) = pLL.lat(); + gidx( n ) = n + 1; } - } - -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.h b/src/atlas/mesh/actions/ExtendNodesGlobal.h index ea37b878b..3a912f95d 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.h +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,30 +14,24 @@ #include namespace atlas { - class Mesh; - class Grid; -} - +class Mesh; +class Grid; +} // namespace atlas namespace atlas { namespace mesh { namespace actions { - /// Adds virtual nodes to the mesh that aren't contained in the Grid Domain class ExtendNodesGlobal { - public: - ExtendNodesGlobal( const std::string& gridname = "O16" ); - void operator()(const Grid&, Mesh&) const; + void operator()( const Grid&, Mesh& ) const; private: - std::string gridname_; }; - -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc index 24f97bcea..05e1e5f18 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc @@ -4,21 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include +#include -#include "eckit/filesystem/PathName.h" #include "atlas/parallel/mpi/mpi.h" +#include "eckit/filesystem/PathName.h" +#include "atlas/mesh/HybridElements.h" +#include "atlas/mesh/IsGhostNode.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/actions/WriteLoadBalanceReport.h" -#include "atlas/mesh/IsGhostNode.h" #include "atlas/runtime/ErrorHandling.h" using atlas::mesh::IsGhostNode; @@ -27,207 +28,192 @@ namespace atlas { namespace mesh { namespace actions { -void write_load_balance_report( const Mesh& mesh, const std::string& filename ) -{ - std::ofstream ofs; - if( mpi::comm().rank() == 0 ) - { - eckit::PathName path(filename); - ofs.open( path.localPath(), std::ofstream::out ); - } - - write_load_balance_report( mesh, ofs ); - - if( mpi::comm().rank() == 0 ) - { - ofs.close(); - } -} - - -void write_load_balance_report( const Mesh& mesh, std::ostream& ofs ) -{ - size_t npart = mpi::comm().size(); - size_t root = 0; - - std::vector nb_total_nodes(npart,0); - std::vector nb_owned_nodes(npart,0); - std::vector nb_ghost_nodes(npart,0); - std::vector ghost_ratio_nodes(npart,0); - - std::vector nb_total_edges(npart,0); - std::vector nb_owned_edges(npart,0); - std::vector nb_ghost_edges(npart,0); - std::vector nb_ghost_ratio_edges(npart,0); - - { - const mesh::Nodes& nodes = mesh.nodes(); - IsGhostNode is_ghost(nodes); - size_t nb_nodes = nodes.size(); - int nowned(0); - int nghost(0); - for(size_t n = 0; n < nb_nodes; ++n) - { - if( is_ghost(n) ) - ++nghost; - else - ++nowned; +void write_load_balance_report( const Mesh& mesh, const std::string& filename ) { + std::ofstream ofs; + if ( mpi::comm().rank() == 0 ) { + eckit::PathName path( filename ); + ofs.open( path.localPath(), std::ofstream::out ); } - /// @note this could be improved by packing the 3 integers in a vector, and doing only comm() call - - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gather(nb_nodes, nb_total_nodes, root); - mpi::comm().gather(nowned, nb_owned_nodes, root); - mpi::comm().gather(nghost, nb_ghost_nodes, root); - } - - for( size_t p=0; p(nb_ghost_nodes[p])/static_cast(nb_owned_nodes[p]); - } - else - { - ghost_ratio_nodes[p] = -1; - } - } - } - - bool has_edges = mesh.edges().size(); - - if( has_edges ) - { - const mesh::Nodes& nodes = mesh.nodes(); - IsGhostNode is_ghost(nodes); - const mesh::HybridElements::Connectivity& edge_nodes = mesh.edges().node_connectivity(); - size_t nb_edges = mesh.edges().size(); - int nowned(0); - int nghost(0); - for(size_t j = 0; j < nb_edges; ++j) - { - if( is_ghost(edge_nodes(j,0)) ) - ++nghost; - else - ++nowned; - } + write_load_balance_report( mesh, ofs ); + if ( mpi::comm().rank() == 0 ) { ofs.close(); } +} - /// @note this could be improved by packing the 3 integers in a vector, and doing only comm() call +void write_load_balance_report( const Mesh& mesh, std::ostream& ofs ) { + size_t npart = mpi::comm().size(); + size_t root = 0; - mpi::comm().gather(nb_edges, nb_total_edges, root); - mpi::comm().gather(nowned, nb_owned_edges, root); - mpi::comm().gather(nghost, nb_ghost_nodes, root); + std::vector nb_total_nodes( npart, 0 ); + std::vector nb_owned_nodes( npart, 0 ); + std::vector nb_ghost_nodes( npart, 0 ); + std::vector ghost_ratio_nodes( npart, 0 ); - } + std::vector nb_total_edges( npart, 0 ); + std::vector nb_owned_edges( npart, 0 ); + std::vector nb_ghost_edges( npart, 0 ); + std::vector nb_ghost_ratio_edges( npart, 0 ); - if( mpi::comm().rank() == 0 ) - { - int idt = 10; - ofs << "# STATISTICS\n"; - ofs << std::setw(1) << "#" << std::setw(5) << ""; - ofs << std::setw(idt) << "nodes"; - ofs << std::setw(idt) << "owned"; - ofs << std::setw(idt) << "ghost"; - ofs << std::setw(idt) << "ratio(%)"; - if( has_edges ) - { - ofs << std::setw(idt) << "edges"; - ofs << std::setw(idt) << "oedges"; - ofs << std::setw(idt) << "gedges"; - } - ofs << "\n"; - ofs << std::setw(6) << "# tot "; - ofs << std::setw(idt) << std::accumulate(nb_total_nodes.data(),nb_total_nodes.data()+npart,0); - ofs << std::setw(idt) << std::accumulate(nb_owned_nodes.data(),nb_owned_nodes.data()+npart,0); - ofs << std::setw(idt) << std::accumulate(nb_ghost_nodes.data(),nb_ghost_nodes.data()+npart,0); - ofs << std::setw(idt) << "/"; - if( has_edges ) - { - ofs << std::setw(idt) << std::accumulate(nb_total_edges.data(),nb_total_edges.data()+npart,0); - ofs << std::setw(idt) << std::accumulate(nb_owned_edges.data(),nb_owned_edges.data()+npart,0); - ofs << std::setw(idt) << std::accumulate(nb_ghost_edges.data(),nb_ghost_edges.data()+npart,0); - } - ofs << "\n"; - ofs << std::setw(6) << "# max "; - ofs << std::setw(idt) << *std::max_element(nb_total_nodes.data(),nb_total_nodes.data()+npart); - ofs << std::setw(idt) << *std::max_element(nb_owned_nodes.data(),nb_owned_nodes.data()+npart); - ofs << std::setw(idt) << *std::max_element(nb_ghost_nodes.data(),nb_ghost_nodes.data()+npart); - ofs << std::setw(idt) << std::setw(idt) << std::fixed << std::setprecision(2) << *std::max_element(ghost_ratio_nodes.data(),ghost_ratio_nodes.data()+npart) * 100.; - if( has_edges ) { - ofs << std::setw(idt) << *std::max_element(nb_total_edges.data(),nb_total_edges.data()+npart); - ofs << std::setw(idt) << *std::max_element(nb_owned_edges.data(),nb_owned_edges.data()+npart); - ofs << std::setw(idt) << *std::max_element(nb_ghost_edges.data(),nb_ghost_edges.data()+npart); + const mesh::Nodes& nodes = mesh.nodes(); + IsGhostNode is_ghost( nodes ); + size_t nb_nodes = nodes.size(); + int nowned( 0 ); + int nghost( 0 ); + for ( size_t n = 0; n < nb_nodes; ++n ) { + if ( is_ghost( n ) ) + ++nghost; + else + ++nowned; + } + + /// @note this could be improved by packing the 3 integers in a vector, and + /// doing only comm() call + + ATLAS_TRACE_MPI( GATHER ) { + mpi::comm().gather( nb_nodes, nb_total_nodes, root ); + mpi::comm().gather( nowned, nb_owned_nodes, root ); + mpi::comm().gather( nghost, nb_ghost_nodes, root ); + } + + for ( size_t p = 0; p < npart; ++p ) { + if ( nb_owned_nodes[p] ) { + ghost_ratio_nodes[p] = + static_cast( nb_ghost_nodes[p] ) / static_cast( nb_owned_nodes[p] ); + } + else { + ghost_ratio_nodes[p] = -1; + } + } } - ofs << "\n"; - ofs << std::setw(6) << "# min "; - ofs << std::setw(idt) << *std::min_element(nb_total_nodes.data(),nb_total_nodes.data()+npart); - ofs << std::setw(idt) << *std::min_element(nb_owned_nodes.data(),nb_owned_nodes.data()+npart); - ofs << std::setw(idt) << *std::min_element(nb_ghost_nodes.data(),nb_ghost_nodes.data()+npart); - ofs << std::setw(idt) << std::fixed << std::setprecision(2) << *std::min_element(ghost_ratio_nodes.data(),ghost_ratio_nodes.data()+npart) * 100.; - if( has_edges ) - { - ofs << std::setw(idt) << *std::min_element(nb_total_edges.data(),nb_total_edges.data()+npart); - ofs << std::setw(idt) << *std::min_element(nb_owned_edges.data(),nb_owned_edges.data()+npart); - ofs << std::setw(idt) << *std::min_element(nb_ghost_edges.data(),nb_ghost_edges.data()+npart); - } - ofs << "\n"; - ofs << std::setw(6) << "# avg "; - ofs << std::setw(idt) << std::accumulate(nb_total_nodes.data(),nb_total_nodes.data()+npart,0)/npart; - ofs << std::setw(idt) << std::accumulate(nb_owned_nodes.data(),nb_owned_nodes.data()+npart,0)/npart; - ofs << std::setw(idt) << std::accumulate(nb_ghost_nodes.data(),nb_ghost_nodes.data()+npart,0)/npart; - ofs << std::setw(idt) << std::fixed << std::setprecision(2) << std::accumulate(ghost_ratio_nodes.data(),ghost_ratio_nodes.data()+npart,0.)/static_cast(npart) *100.; - if( has_edges ) - { - ofs << std::setw(idt) << std::accumulate(nb_total_edges.data(),nb_total_edges.data()+npart,0)/npart; - ofs << std::setw(idt) << std::accumulate(nb_owned_edges.data(),nb_owned_edges.data()+npart,0)/npart; - ofs << std::setw(idt) << std::accumulate(nb_ghost_edges.data(),nb_ghost_edges.data()+npart,0)/npart; - } - ofs << "\n"; - ofs << "#----------------------------------------------------\n"; - ofs << "# PER TASK\n"; - ofs << std::setw(6) << "# part"; - ofs << std::setw(idt) << "nodes"; - ofs << std::setw(idt) << "owned"; - ofs << std::setw(idt) << "ghost"; - ofs << std::setw(idt) << "ratio(%)"; - if( has_edges ) - { - ofs << std::setw(idt) << "edges"; - ofs << std::setw(idt) << "oedges"; - ofs << std::setw(idt) << "gedges"; + + bool has_edges = mesh.edges().size(); + + if ( has_edges ) { + const mesh::Nodes& nodes = mesh.nodes(); + IsGhostNode is_ghost( nodes ); + const mesh::HybridElements::Connectivity& edge_nodes = mesh.edges().node_connectivity(); + size_t nb_edges = mesh.edges().size(); + int nowned( 0 ); + int nghost( 0 ); + for ( size_t j = 0; j < nb_edges; ++j ) { + if ( is_ghost( edge_nodes( j, 0 ) ) ) + ++nghost; + else + ++nowned; + } + + /// @note this could be improved by packing the 3 integers in a vector, and + /// doing only comm() call + + mpi::comm().gather( nb_edges, nb_total_edges, root ); + mpi::comm().gather( nowned, nb_owned_edges, root ); + mpi::comm().gather( nghost, nb_ghost_nodes, root ); } - ofs << "\n"; - for( size_t jpart=0; jpart( npart ) * 100.; + if ( has_edges ) { + ofs << std::setw( idt ) + << std::accumulate( nb_total_edges.data(), nb_total_edges.data() + npart, 0 ) / npart; + ofs << std::setw( idt ) + << std::accumulate( nb_owned_edges.data(), nb_owned_edges.data() + npart, 0 ) / npart; + ofs << std::setw( idt ) + << std::accumulate( nb_ghost_edges.data(), nb_ghost_edges.data() + npart, 0 ) / npart; + } + ofs << "\n"; + ofs << "#----------------------------------------------------\n"; + ofs << "# PER TASK\n"; + ofs << std::setw( 6 ) << "# part"; + ofs << std::setw( idt ) << "nodes"; + ofs << std::setw( idt ) << "owned"; + ofs << std::setw( idt ) << "ghost"; + ofs << std::setw( idt ) << "ratio(%)"; + if ( has_edges ) { + ofs << std::setw( idt ) << "edges"; + ofs << std::setw( idt ) << "oedges"; + ofs << std::setw( idt ) << "gedges"; + } + ofs << "\n"; + for ( size_t jpart = 0; jpart < npart; ++jpart ) { + ofs << std::setw( 6 ) << jpart; + ofs << std::setw( idt ) << nb_total_nodes[jpart]; + ofs << std::setw( idt ) << nb_owned_nodes[jpart]; + ofs << std::setw( idt ) << nb_ghost_nodes[jpart]; + ofs << std::setw( idt ) << std::fixed << std::setprecision( 2 ) << ghost_ratio_nodes[jpart] * 100.; + if ( has_edges ) { + ofs << std::setw( idt ) << nb_total_edges[jpart]; + ofs << std::setw( idt ) << nb_owned_edges[jpart]; + ofs << std::setw( idt ) << nb_ghost_edges[jpart]; + } + ofs << "\n"; + } } - } } // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -void atlas__write_load_balance_report (Mesh::Implementation* mesh, char* filename) -{ - ATLAS_ERROR_HANDLING( Mesh m(mesh); write_load_balance_report( m, std::string(filename) ); ); +void atlas__write_load_balance_report( Mesh::Implementation* mesh, char* filename ) { + ATLAS_ERROR_HANDLING( Mesh m( mesh ); write_load_balance_report( m, std::string( filename ) ); ); } // ------------------------------------------------------------------ -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.h b/src/atlas/mesh/actions/WriteLoadBalanceReport.h index c522d84b0..eaea20a07 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.h +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -22,15 +23,14 @@ void write_load_balance_report( const Mesh& mesh, const std::string& filename ); // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -extern "C" -{ - void atlas__write_load_balance_report (Mesh::Implementation* mesh, char* filename); +extern "C" { +void atlas__write_load_balance_report( Mesh::Implementation* mesh, char* filename ); } // ------------------------------------------------------------------ -} // namespace actions -} // namespace mesh -} // namespace atlas +} // namespace actions +} // namespace mesh +} // namespace atlas #endif diff --git a/src/atlas/mesh/detail/AccumulateFacets.cc b/src/atlas/mesh/detail/AccumulateFacets.cc index ab85397af..6519fe1f2 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.cc +++ b/src/atlas/mesh/detail/AccumulateFacets.cc @@ -4,143 +4,122 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "eckit/exception/Exceptions.h" -#include "atlas/mesh/HybridElements.h" +#include "atlas/mesh/detail/AccumulateFacets.h" #include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/detail/AccumulateFacets.h" #include "atlas/runtime/Trace.h" +#include "eckit/exception/Exceptions.h" namespace atlas { namespace mesh { namespace detail { -void accumulate_facets( - const mesh::HybridElements &cells, - const mesh::Nodes &nodes, - std::vector< idx_t > &facet_nodes_data, // shape(nb_facets,nb_nodes_per_facet) - std::vector< idx_t > &connectivity_facet_to_elem, - size_t &nb_facets, - size_t &nb_inner_facets, - idx_t &missing_value ) -{ - ATLAS_TRACE(); - missing_value = -1; - std::vector< std::vector > node_to_facet(nodes.size()); - for( size_t j=0; j(elements.field("patch")); +void accumulate_facets( const mesh::HybridElements& cells, const mesh::Nodes& nodes, + std::vector& facet_nodes_data, // shape(nb_facets,nb_nodes_per_facet) + std::vector& connectivity_facet_to_elem, size_t& nb_facets, size_t& nb_inner_facets, + idx_t& missing_value ) { + ATLAS_TRACE(); + missing_value = -1; + std::vector> node_to_facet( nodes.size() ); + for ( size_t j = 0; j < node_to_facet.size(); ++j ) { + node_to_facet[j].reserve( 6 ); + } + 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() ); } + for ( size_t t = 0; t < cells.nb_types(); ++t ) { + const mesh::Elements& elements = cells.elements( t ); + const mesh::BlockConnectivity& elem_nodes = elements.node_connectivity(); + auto patch = elements.view( elements.field( "patch" ) ); - size_t nb_elems = elements.size(); - size_t nb_nodes_in_facet = 2; + size_t nb_elems = elements.size(); + size_t nb_nodes_in_facet = 2; - std::vector< std::vector > facet_node_numbering; - size_t nb_facets_in_elem; - if (elements.name() == "Quadrilateral") - { - nb_facets_in_elem = 4; - facet_node_numbering.resize(nb_facets_in_elem, std::vector(nb_nodes_in_facet) ); - facet_node_numbering[0][0] = 0; - facet_node_numbering[0][1] = 1; - facet_node_numbering[1][0] = 1; - facet_node_numbering[1][1] = 2; - facet_node_numbering[2][0] = 2; - facet_node_numbering[2][1] = 3; - facet_node_numbering[3][0] = 3; - facet_node_numbering[3][1] = 0; - } - else if (elements.name() == "Triangle") - { - nb_facets_in_elem = 3; - facet_node_numbering.resize(nb_facets_in_elem, std::vector(nb_nodes_in_facet) ); - facet_node_numbering[0][0] = 0; - facet_node_numbering[0][1] = 1; - facet_node_numbering[1][0] = 1; - facet_node_numbering[1][1] = 2; - facet_node_numbering[2][0] = 2; - facet_node_numbering[2][1] = 0; - } - else - { - throw eckit::BadParameter(elements.name()+" is not \"Quadrilateral\" or \"Triangle\"",Here()); - } + std::vector> facet_node_numbering; + size_t nb_facets_in_elem; + if ( elements.name() == "Quadrilateral" ) { + nb_facets_in_elem = 4; + facet_node_numbering.resize( nb_facets_in_elem, std::vector( nb_nodes_in_facet ) ); + facet_node_numbering[0][0] = 0; + facet_node_numbering[0][1] = 1; + facet_node_numbering[1][0] = 1; + facet_node_numbering[1][1] = 2; + facet_node_numbering[2][0] = 2; + facet_node_numbering[2][1] = 3; + facet_node_numbering[3][0] = 3; + facet_node_numbering[3][1] = 0; + } + else if ( elements.name() == "Triangle" ) { + nb_facets_in_elem = 3; + facet_node_numbering.resize( nb_facets_in_elem, std::vector( nb_nodes_in_facet ) ); + facet_node_numbering[0][0] = 0; + facet_node_numbering[0][1] = 1; + facet_node_numbering[1][0] = 1; + facet_node_numbering[1][1] = 2; + facet_node_numbering[2][0] = 2; + facet_node_numbering[2][1] = 0; + } + else { + throw eckit::BadParameter( elements.name() + " is not \"Quadrilateral\" or \"Triangle\"", Here() ); + } - std::vector facet_nodes(nb_nodes_in_facet); + std::vector facet_nodes( nb_nodes_in_facet ); - for (size_t e = 0; e < nb_elems; ++e) - { - if( patch(e) ) continue; - for (size_t f=0; f1) // 2D or 3D - { - for(size_t jnode = 0; jnode < nb_nodes_in_facet; ++jnode) - { - size_t other_node = facet_nodes[jnode]; - for(size_t iface=0; iface 1 ) // 2D or 3D + { + for ( size_t jnode = 0; jnode < nb_nodes_in_facet; ++jnode ) { + size_t other_node = facet_nodes[jnode]; + for ( size_t iface = 0; iface < node_to_facet[other_node].size(); ++iface ) { + if ( node_to_facet[facet_nodes[jnode]][iface] == face ) { + ++nb_matched_nodes; + break; + } + } + } + if ( nb_matched_nodes == nb_nodes_in_facet ) { + connectivity_facet_to_elem[2 * face + 1] = e + elements.begin(); + ++nb_inner_facets; + found_face = true; + break; + } + } } - } - } - if (nb_matched_nodes == nb_nodes_in_facet) - { - connectivity_facet_to_elem[2*face+1] = e+elements.begin(); - ++nb_inner_facets; - found_face = true; - break; - } - } - } - if (found_face == false) - { - connectivity_facet_to_elem.emplace_back( elements.begin()+e ); - // if 2nd element stays missing_value, it is a bdry face - connectivity_facet_to_elem.emplace_back( missing_value ); - for (size_t n = 0; n < nb_nodes_in_facet; ++n) - { - node_to_facet[facet_nodes[n]].emplace_back(nb_facets); - facet_nodes_data.emplace_back(facet_nodes[n]); - } - ++nb_facets; + if ( found_face == false ) { + connectivity_facet_to_elem.emplace_back( elements.begin() + e ); + // if 2nd element stays missing_value, it is a bdry face + connectivity_facet_to_elem.emplace_back( missing_value ); + for ( size_t n = 0; n < nb_nodes_in_facet; ++n ) { + node_to_facet[facet_nodes[n]].emplace_back( nb_facets ); + facet_nodes_data.emplace_back( facet_nodes[n] ); + } + ++nb_facets; + } + } } - } - } } } -} // namespace detail -} // namespace mesh -} // namespace atlas +} // namespace detail +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/detail/AccumulateFacets.h b/src/atlas/mesh/detail/AccumulateFacets.h index 131964f74..3e94591c6 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.h +++ b/src/atlas/mesh/detail/AccumulateFacets.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,23 +14,27 @@ #include #include "atlas/library/config.h" -namespace atlas { namespace mesh { class HybridElements; } } -namespace atlas { namespace mesh { class Nodes; } } +namespace atlas { +namespace mesh { +class HybridElements; +} +} // namespace atlas +namespace atlas { +namespace mesh { +class Nodes; +} +} // namespace atlas namespace atlas { namespace mesh { namespace detail { // currently only supports 2D meshes. Little work needed for 3D. -void accumulate_facets( - const mesh::HybridElements &cells, - const mesh::Nodes &nodes, - std::vector< idx_t > &facet_nodes_data, // shape(nb_facets,nb_nodes_per_facet) - std::vector< idx_t > &connectivity_facet_to_elem, - size_t &nb_facets, - size_t &nb_inner_facets, - idx_t &missing_value ); +void accumulate_facets( const mesh::HybridElements& cells, const mesh::Nodes& nodes, + std::vector& facet_nodes_data, // shape(nb_facets,nb_nodes_per_facet) + std::vector& connectivity_facet_to_elem, size_t& nb_facets, size_t& nb_inner_facets, + idx_t& missing_value ); -} // namespace detail -} // namespace mesh -} // namespace atlas +} // namespace detail +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/detail/MeshImpl.cc b/src/atlas/mesh/detail/MeshImpl.cc index 1441a4020..775a25f67 100644 --- a/src/atlas/mesh/detail/MeshImpl.cc +++ b/src/atlas/mesh/detail/MeshImpl.cc @@ -4,21 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include "atlas/mesh/detail/MeshImpl.h" +#include #include "eckit/exception/Exceptions.h" #include "eckit/types/FloatCompare.h" #include "atlas/grid/Grid.h" +#include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/Elements.h" #include "atlas/parallel/mpi/mpi.h" using atlas::Grid; @@ -30,157 +31,140 @@ namespace detail { //---------------------------------------------------------------------------------------------------------------------- -MeshImpl::MeshImpl(eckit::Stream& s) -{ +MeshImpl::MeshImpl( eckit::Stream& s ) { NOTIMP; } -void MeshImpl::encode(eckit::Stream& s) const { +void MeshImpl::encode( eckit::Stream& s ) const { NOTIMP; } -MeshImpl::MeshImpl(): - dimensionality_(2) -{ - nodes_.reset( new mesh::Nodes() ); - createElements(); +MeshImpl::MeshImpl() : dimensionality_( 2 ) { + nodes_.reset( new mesh::Nodes() ); + createElements(); } - -MeshImpl::~MeshImpl() -{ - for( MeshObserver* o : mesh_observers_ ) { - o->onMeshDestruction(*this); - } +MeshImpl::~MeshImpl() { + for ( MeshObserver* o : mesh_observers_ ) { + o->onMeshDestruction( *this ); + } } -void MeshImpl::print(std::ostream& os) const -{ -} +void MeshImpl::print( std::ostream& os ) const {} 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(); - for( const auto& polygon : polygons_ ) { - if( polygon ) size += polygon->footprint(); - } + 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(); + for ( const auto& polygon : polygons_ ) { + if ( polygon ) size += polygon->footprint(); + } - return size; + return size; } +void MeshImpl::createElements() { + cells_.reset( new HybridElements() ); + facets_.reset( new HybridElements() ); + ridges_.reset( new HybridElements() ); + peaks_.reset( new HybridElements() ); + if ( dimensionality_ == 2 ) + edges_ = facets_; + else if ( dimensionality_ == 3 ) + edges_ = ridges_; + else + throw eckit::Exception( "Invalid Mesh dimensionality", Here() ); -void MeshImpl::createElements() -{ - cells_ .reset( new HybridElements() ); - facets_.reset( new HybridElements() ); - ridges_.reset( new HybridElements() ); - peaks_ .reset( new HybridElements() ); - if( dimensionality_ == 2 ) - edges_ = facets_; - else if( dimensionality_ == 3) - edges_ = ridges_; - else - throw eckit::Exception("Invalid Mesh dimensionality",Here()); - - ASSERT( edges_.owners() == 2 ); + ASSERT( edges_.owners() == 2 ); } bool MeshImpl::generated() const { - return ! (cells_->size() == 0 && facets_->size() == 0 && ridges_->size() == 0 && peaks_->size() == 0); + return !( cells_->size() == 0 && facets_->size() == 0 && ridges_->size() == 0 && peaks_->size() == 0 ); } -void MeshImpl::setProjection(const Projection& projection) { - projection_ = projection; +void MeshImpl::setProjection( const Projection& projection ) { + projection_ = projection; } -void MeshImpl::setGrid(const Grid& grid) { - grid_ = grid; - if( not projection_ ) - projection_ = grid_.projection(); +void MeshImpl::setGrid( const Grid& grid ) { + grid_.reset( new Grid( grid ) ); + if ( not projection_ ) projection_ = grid_->projection(); } size_t MeshImpl::nb_partitions() const { - return mpi::comm().size(); + return mpi::comm().size(); } size_t MeshImpl::partition() const { - return mpi::comm().rank(); + return mpi::comm().rank(); } 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) ); - } - return *partition_graph_; + if ( not partition_graph_ ) { partition_graph_.reset( build_partition_graph( *this ) ); } + return *partition_graph_; } PartitionGraph::Neighbours MeshImpl::nearestNeighbourPartitions() const { - return partitionGraph().nearestNeighbours(partition()); + return partitionGraph().nearestNeighbours( partition() ); } -const PartitionPolygon& MeshImpl::polygon(size_t halo) const { - if( halo >= polygons_.size() ) { - polygons_.resize(halo+1); - } - if( not polygons_[halo] ) { +const PartitionPolygon& MeshImpl::polygon( size_t halo ) const { + if ( halo >= polygons_.size() ) { polygons_.resize( halo + 1 ); } + if ( not polygons_[halo] ) { + int mesh_halo = 0; + metadata().get( "halo", mesh_halo ); + if ( halo > mesh_halo ) { + throw eckit::Exception( "Mesh does not contain a halo of size " + std::to_string( halo ) + ".", Here() ); + } - int mesh_halo = 0; - metadata().get("halo",mesh_halo); - if( halo > mesh_halo ) { - throw eckit::Exception("Mesh does not contain a halo of size "+std::to_string(halo)+".", Here()); + polygons_[halo].reset( new PartitionPolygon( *this, halo ) ); } - - polygons_[halo].reset( new PartitionPolygon(*this, halo) ); - } - return *polygons_[halo]; + return *polygons_[halo]; } void MeshImpl::attachObserver( MeshObserver& observer ) const { - if( std::find( mesh_observers_.begin(), mesh_observers_.end(), &observer ) == mesh_observers_.end() ) { - mesh_observers_.push_back( &observer ); - } + if ( std::find( mesh_observers_.begin(), mesh_observers_.end(), &observer ) == mesh_observers_.end() ) { + mesh_observers_.push_back( &observer ); + } } void MeshImpl::detachObserver( MeshObserver& observer ) const { - mesh_observers_.erase( - std::remove( mesh_observers_.begin(), mesh_observers_.end(), &observer ), - mesh_observers_.end() ); + mesh_observers_.erase( std::remove( mesh_observers_.begin(), mesh_observers_.end(), &observer ), + mesh_observers_.end() ); } //---------------------------------------------------------------------------------------------------------------------- - -} // namespace detail -} // namespace mesh -} // namespace atlas +} // namespace detail +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/detail/MeshImpl.h b/src/atlas/mesh/detail/MeshImpl.h index 2547ca021..11ffa0084 100644 --- a/src/atlas/mesh/detail/MeshImpl.h +++ b/src/atlas/mesh/detail/MeshImpl.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,24 +16,24 @@ #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" -#include "atlas/util/Metadata.h" -#include "atlas/grid/Grid.h" -#include "atlas/projection/Projection.h" -#include "atlas/mesh/detail/PartitionGraph.h" #include "atlas/mesh/PartitionPolygon.h" +#include "atlas/mesh/detail/PartitionGraph.h" +#include "atlas/projection/Projection.h" +#include "atlas/util/Metadata.h" //---------------------------------------------------------------------------------------------------------------------- namespace atlas { - class Grid; - class Mesh; +class Grid; +class Mesh; namespace mesh { - class PartitionPolygon; - class Nodes; - class HybridElements; - typedef HybridElements Edges; - typedef HybridElements Cells; -} } +class PartitionPolygon; +class Nodes; +class HybridElements; +typedef HybridElements Edges; +typedef HybridElements Cells; +} // namespace mesh +} // namespace atlas //---------------------------------------------------------------------------------------------------------------------- @@ -45,17 +46,15 @@ namespace detail { class MeshObserver; class MeshImpl : public eckit::Owned { - -public: // methods - +public: // methods /// @brief Construct a empty MeshImpl explicit MeshImpl(); /// @brief Construct a mesh from a Stream (serialization) - explicit MeshImpl(eckit::Stream&); + explicit MeshImpl( eckit::Stream& ); /// @brief Serialization to Stream - void encode(eckit::Stream& s) const; + void encode( eckit::Stream& s ) const; /// Destructor /// @note No need to be virtual since this is not a base class. @@ -64,25 +63,25 @@ class MeshImpl : public eckit::Owned { util::Metadata& metadata() { return metadata_; } const util::Metadata& metadata() const { return metadata_; } - void print(std::ostream&) const; + void print( std::ostream& ) const; const Nodes& nodes() const { return *nodes_; } - Nodes& nodes() { return *nodes_; } + Nodes& nodes() { return *nodes_; } const Cells& cells() const { return *cells_; } - Cells& cells() { return *cells_; } + Cells& cells() { return *cells_; } const Edges& edges() const { return *edges_; } - Edges& edges() { return *edges_; } + Edges& edges() { return *edges_; } const HybridElements& facets() const { return *facets_; } - HybridElements& facets() { return *facets_; } + HybridElements& facets() { return *facets_; } const HybridElements& ridges() const { return *ridges_; } - HybridElements& ridges() { return *ridges_; } + HybridElements& ridges() { return *ridges_; } const HybridElements& peaks() const { return *peaks_; } - HybridElements& peaks() { return *peaks_; } + HybridElements& peaks() { return *peaks_; } bool generated() const; @@ -104,38 +103,36 @@ class MeshImpl : public eckit::Owned { PartitionGraph::Neighbours nearestNeighbourPartitions() const; - const PartitionPolygon& polygon(size_t halo=0) const; + const PartitionPolygon& polygon( size_t halo = 0 ) const; - const Grid& grid() const { return grid_; } + const Grid& grid() const { return *grid_; } - void attachObserver(MeshObserver&) const; - void detachObserver(MeshObserver&) const; + void attachObserver( MeshObserver& ) const; + void detachObserver( MeshObserver& ) const; private: // methods - friend class ::atlas::Mesh; - friend std::ostream& operator<<(std::ostream& s, const MeshImpl& p) { - p.print(s); + friend std::ostream& operator<<( std::ostream& s, const MeshImpl& p ) { + p.print( s ); return s; } void createElements(); - void setProjection(const Projection&); - void setGrid(const Grid&); - -private: // members + void setProjection( const Projection& ); + void setGrid( const Grid& ); - util::Metadata metadata_; +private: // members + util::Metadata metadata_; eckit::SharedPtr nodes_; - // dimensionality : 2D | 3D - // -------- - eckit::SharedPtr cells_; // 2D | 3D - eckit::SharedPtr facets_; // 1D | 2D - eckit::SharedPtr ridges_; // 0D | 1D - eckit::SharedPtr peaks_; // NA | 0D + // dimensionality : 2D | 3D + // -------- + eckit::SharedPtr cells_; // 2D | 3D + eckit::SharedPtr facets_; // 1D | 2D + eckit::SharedPtr ridges_; // 0D | 1D + eckit::SharedPtr peaks_; // NA | 0D eckit::SharedPtr edges_; // alias to facets of 2D mesh, ridges of 3D mesh @@ -143,7 +140,7 @@ class MeshImpl : public eckit::Owned { Projection projection_; - Grid grid_; + std::unique_ptr grid_; mutable eckit::SharedPtr partition_graph_; @@ -156,11 +153,11 @@ class MeshImpl : public eckit::Owned { class MeshObserver { public: - virtual void onMeshDestruction(MeshImpl&) = 0; + virtual void onMeshDestruction( MeshImpl& ) = 0; }; //---------------------------------------------------------------------------------------------------------------------- -} // namespace detail -} // namespace mesh -} // namespace atlas +} // namespace detail +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/detail/MeshIntf.cc b/src/atlas/mesh/detail/MeshIntf.cc index 902571826..268f11de5 100644 --- a/src/atlas/mesh/detail/MeshIntf.cc +++ b/src/atlas/mesh/detail/MeshIntf.cc @@ -4,13 +4,14 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "atlas/mesh/detail/MeshIntf.h" -#include "atlas/runtime/ErrorHandling.h" #include "atlas/mesh/Nodes.h" +#include "atlas/runtime/ErrorHandling.h" namespace atlas { namespace mesh { @@ -18,63 +19,48 @@ namespace mesh { //---------------------------------------------------------------------------------------------------------------------- // C wrapper interfaces to C++ routines -Mesh::Implementation* atlas__Mesh__new () { - return new Mesh::Implementation(); +Mesh::Implementation* atlas__Mesh__new() { + return new Mesh::Implementation(); } -void atlas__Mesh__delete (Mesh::Implementation* This) { - delete This; +void atlas__Mesh__delete( Mesh::Implementation* This ) { + delete This; } -Nodes* atlas__Mesh__nodes (Mesh::Implementation* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return &This->nodes(); - ); - return nullptr; +Nodes* atlas__Mesh__nodes( Mesh::Implementation* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->nodes(); ); + return nullptr; } -Edges* atlas__Mesh__edges (Mesh::Implementation* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return &This->edges(); - ); - return nullptr; +Edges* atlas__Mesh__edges( Mesh::Implementation* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->edges(); ); + return nullptr; } -Cells* atlas__Mesh__cells (Mesh::Implementation* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return &This->cells(); - ); - return nullptr; +Cells* atlas__Mesh__cells( Mesh::Implementation* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return &This->cells(); ); + return nullptr; } -size_t atlas__Mesh__footprint (Mesh::Implementation* This) { - size_t size(0); - ATLAS_ERROR_HANDLING( - ASSERT( This ); - size = This->footprint(); - ); - return size; +size_t atlas__Mesh__footprint( Mesh::Implementation* This ) { + size_t size( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( This ); size = This->footprint(); ); + return size; } -void atlas__Mesh__clone_to_device(Mesh::Implementation* This) -{ - This->cloneToDevice(); +void atlas__Mesh__clone_to_device( Mesh::Implementation* This ) { + This->cloneToDevice(); } -void atlas__Mesh__clone_from_device(Mesh::Implementation* This) -{ - This->cloneFromDevice(); +void atlas__Mesh__clone_from_device( Mesh::Implementation* This ) { + This->cloneFromDevice(); } -void atlas__Mesh__sync_host_device(Mesh::Implementation* This) -{ - This->syncHostDevice(); +void atlas__Mesh__sync_host_device( Mesh::Implementation* This ) { + This->syncHostDevice(); } //---------------------------------------------------------------------------------------------------------------------- -} // namespace mesh -} // namespace atlas +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/detail/MeshIntf.h b/src/atlas/mesh/detail/MeshIntf.h index c3a026e04..71b6cd0ff 100644 --- a/src/atlas/mesh/detail/MeshIntf.h +++ b/src/atlas/mesh/detail/MeshIntf.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -18,20 +19,19 @@ namespace atlas { namespace mesh { // C wrapper interfaces to C++ routines -extern "C" -{ - Mesh::Implementation* atlas__Mesh__new (); - void atlas__Mesh__delete (Mesh::Implementation* This); - Nodes* atlas__Mesh__nodes (Mesh::Implementation* This); - Edges* atlas__Mesh__edges (Mesh::Implementation* This); - Cells* atlas__Mesh__cells (Mesh::Implementation* This); - size_t atlas__Mesh__footprint (Mesh::Implementation* This); - void atlas__Mesh__clone_to_device (Mesh::Implementation* This); - void atlas__Mesh__clone_from_device (Mesh::Implementation* This); - void atlas__Mesh__sync_host_device (Mesh::Implementation* This); +extern "C" { +Mesh::Implementation* atlas__Mesh__new(); +void atlas__Mesh__delete( Mesh::Implementation* This ); +Nodes* atlas__Mesh__nodes( Mesh::Implementation* This ); +Edges* atlas__Mesh__edges( Mesh::Implementation* This ); +Cells* atlas__Mesh__cells( Mesh::Implementation* This ); +size_t atlas__Mesh__footprint( Mesh::Implementation* This ); +void atlas__Mesh__clone_to_device( Mesh::Implementation* This ); +void atlas__Mesh__clone_from_device( Mesh::Implementation* This ); +void atlas__Mesh__sync_host_device( Mesh::Implementation* This ); } //---------------------------------------------------------------------------------------------------------------------- -} // namespace mesh -} // namespace atlas +} // namespace mesh +} // namespace atlas diff --git a/src/atlas/mesh/detail/PartitionGraph.cc b/src/atlas/mesh/detail/PartitionGraph.cc index b52367e26..182413fa9 100644 --- a/src/atlas/mesh/detail/PartitionGraph.cc +++ b/src/atlas/mesh/detail/PartitionGraph.cc @@ -4,24 +4,25 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include #include "eckit/exception/Exceptions.h" -#include "eckit/types/FloatCompare.h" #include "eckit/log/Bytes.h" +#include "eckit/types/FloatCompare.h" -#include "atlas/mesh/detail/MeshImpl.h" +#include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/Elements.h" +#include "atlas/mesh/detail/MeshImpl.h" #include "atlas/parallel/mpi/mpi.h" -#include "atlas/util/Unique.h" #include "atlas/runtime/Log.h" +#include "atlas/util/Unique.h" namespace atlas { namespace mesh { @@ -29,163 +30,149 @@ namespace detail { //---------------------------------------------------------------------------------------------------------------------- -PartitionGraph* build_partition_graph(const MeshImpl& mesh ) { - - const eckit::mpi::Comm& comm = mpi::comm(); - const int mpi_size = int(comm.size()); - - const util::Polygon& poly = mesh.polygon(); - - std::vector< double > polygon; - polygon.reserve(poly.size()*2); +PartitionGraph* build_partition_graph( const MeshImpl& mesh ) { + const eckit::mpi::Comm& comm = mpi::comm(); + const int mpi_size = int( comm.size() ); - auto xy = array::make_view< double, 2 >( mesh.nodes().xy() ); + const util::Polygon& poly = mesh.polygon(); - for( idx_t node : poly ) { - polygon.push_back( xy(node,XX) ); - polygon.push_back( xy(node,YY) ); - } - ASSERT(polygon.size() >= 4); + std::vector polygon; + polygon.reserve( poly.size() * 2 ); - eckit::mpi::Buffer recv_polygons(mpi_size); - comm.allGatherv(polygon.begin(),polygon.end(),recv_polygons); + auto xy = array::make_view( mesh.nodes().xy() ); - using PolygonXY = std::vector; - std::vector< PolygonXY > polygons(mpi_size); - for( size_t p=0; p > uid_2_parts; - size_t jpart=0; - 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.; - } - uidx_t uid = util::unique_lonlat( pll.data() ); - uid_2_parts[uid].insert( jpart ); + ASSERT( polygon.size() >= 4 ); + + eckit::mpi::Buffer recv_polygons( mpi_size ); + comm.allGatherv( polygon.begin(), polygon.end(), recv_polygons ); + + using PolygonXY = std::vector; + std::vector polygons( mpi_size ); + for ( size_t p = 0; p < mpi_size; ++p ) { + for ( size_t j = 0; j < recv_polygons.counts[p] / 2; ++j ) { + PointXY pxy( *( recv_polygons.begin() + recv_polygons.displs[p] + 2 * j + XX ), + *( recv_polygons.begin() + recv_polygons.displs[p] + 2 * j + YY ) ); + polygons[p].push_back( pxy ); + } } - ++jpart; - } - std::vector< std::set > graph(mpi_size); - for( const auto& u2p : uid_2_parts ){ - const std::set& parts = u2p.second; - for( size_t jpart : parts ) { - for( size_t ipart : parts ) { - if( jpart != ipart ) { - graph[jpart].insert(ipart); + + std::map> uid_2_parts; + size_t jpart = 0; + 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.; } + uidx_t uid = util::unique_lonlat( pll.data() ); + uid_2_parts[uid].insert( jpart ); } - } + ++jpart; } - } - - std::vector counts(mpi_size); - std::vector displs(mpi_size); - size_t values_size=0; - for( size_t jpart=0; jpart values; values.reserve(values_size); - for( const std::set& graph_node : graph ) { - for( size_t v : graph_node ) { - values.push_back(v); + std::vector> graph( mpi_size ); + for ( const auto& u2p : uid_2_parts ) { + const std::set& parts = u2p.second; + for ( size_t jpart : parts ) { + for ( size_t ipart : parts ) { + if ( jpart != ipart ) { graph[jpart].insert( ipart ); } + } + } } - } - return new PartitionGraph( values.data(), mpi_size, displs.data(), counts.data() ); -} + std::vector counts( mpi_size ); + std::vector displs( mpi_size ); + size_t values_size = 0; + for ( size_t jpart = 0; jpart < mpi_size; ++jpart ) { + counts[jpart] = graph[jpart].size(); + displs[jpart] = values_size; + values_size += counts[jpart]; + } + std::vector values; + values.reserve( values_size ); + for ( const std::set& graph_node : graph ) { + for ( size_t v : graph_node ) { + values.push_back( v ); + } + } + return new PartitionGraph( values.data(), mpi_size, displs.data(), counts.data() ); +} size_t PartitionGraph::footprint() const { - size_t size = sizeof(*this); - size += sizeof(size_t)*displs_.capacity(); - size += sizeof(size_t)*counts_.capacity(); - size += sizeof(size_t)*values_.capacity(); - return size; + size_t size = sizeof( *this ); + size += sizeof( size_t ) * displs_.capacity(); + size += sizeof( size_t ) * counts_.capacity(); + size += sizeof( size_t ) * values_.capacity(); + return size; } size_t PartitionGraph::size() const { - return displs_.size(); + return displs_.size(); } -PartitionGraph::Neighbours PartitionGraph::nearestNeighbours(const size_t partition) const { - return Neighbours(values_.data()+displs_[partition],values_.data()+displs_[partition]+counts_[partition]); +PartitionGraph::Neighbours PartitionGraph::nearestNeighbours( const size_t partition ) const { + return Neighbours( values_.data() + displs_[partition], values_.data() + displs_[partition] + counts_[partition] ); } -PartitionGraph::PartitionGraph() { -} +PartitionGraph::PartitionGraph() {} PartitionGraph::PartitionGraph( size_t values[], size_t rows, size_t displs[], size_t counts[] ) { - displs_.assign(displs,displs+rows); - counts_.assign(counts,counts+rows); - values_.assign(values,values+displs[rows-1]+counts[rows-1]); - - for( size_t jpart=0; jpart 1 ) - { - Log::warning() << "Delaunay triangulation does not support a GridDistribution" - "with more than 1 partition" - << std::endl; - NOTIMP; - /// TODO: Read mesh on 1 MPI task, and distribute according to GridDistribution - /// HINT: use atlas/actions/DistributeMesh - } - else - { - generate(grid, mesh); - } +void DelaunayMeshGenerator::generate( const Grid& grid, const grid::Distribution& dist, Mesh& mesh ) const { + if ( dist.nb_partitions() > 1 ) { + Log::warning() << "Delaunay triangulation does not support a GridDistribution" + "with more than 1 partition" + << std::endl; + NOTIMP; + /// TODO: Read mesh on 1 MPI task, and distribute according to + /// GridDistribution + /// HINT: use atlas/actions/DistributeMesh + } + else { + generate( grid, mesh ); + } } -void DelaunayMeshGenerator::generate(const Grid& g, Mesh& mesh) const -{ +void DelaunayMeshGenerator::generate( const Grid& g, Mesh& mesh ) const { + createNodes( g, mesh ); - createNodes(g,mesh); + array::ArrayView gidx = array::make_view( mesh.nodes().global_index() ); + for ( size_t jnode = 0; jnode < mesh.nodes().size(); ++jnode ) { + gidx( jnode ) = jnode + 1; + } - array::ArrayView gidx = array::make_view( mesh.nodes().global_index() ); - for( size_t jnode=0; jnode xy = array::make_view( mesh.nodes().xy() ); - array::ArrayView lonlat = array::make_view( mesh.nodes().lonlat() ); - size_t jnode(0); - Projection projection = grid.projection(); - PointLonLat Pll; - for( PointXY Pxy : grid.xy() ) { - xy(jnode,XX) = Pxy.x(); - xy(jnode,YY) = Pxy.y(); - Pll = projection.lonlat(Pxy); - lonlat(jnode,LON) = Pll.lon(); - lonlat(jnode,LAT) = Pll.lat(); - ++jnode; - } +void DelaunayMeshGenerator::createNodes( const Grid& grid, Mesh& mesh ) const { + size_t nb_nodes = grid.size(); + mesh.nodes().resize( nb_nodes ); + + array::ArrayView xy = array::make_view( mesh.nodes().xy() ); + array::ArrayView lonlat = array::make_view( mesh.nodes().lonlat() ); + size_t jnode( 0 ); + Projection projection = grid.projection(); + PointLonLat Pll; + for ( PointXY Pxy : grid.xy() ) { + xy( jnode, XX ) = Pxy.x(); + xy( jnode, YY ) = Pxy.y(); + Pll = projection.lonlat( Pxy ); + lonlat( jnode, LON ) = Pll.lon(); + lonlat( jnode, LAT ) = Pll.lat(); + ++jnode; + } } namespace { -static MeshGeneratorBuilder< DelaunayMeshGenerator > __delaunay("delaunay"); +static MeshGeneratorBuilder __delaunay( "delaunay" ); } //---------------------------------------------------------------------------------------------------------------------- -} // namespace meshgenerator -} // namespace atlas - +} // namespace meshgenerator +} // namespace atlas diff --git a/src/atlas/meshgenerator/DelaunayMeshGenerator.h b/src/atlas/meshgenerator/DelaunayMeshGenerator.h index 7b75aaaa8..420355f22 100644 --- a/src/atlas/meshgenerator/DelaunayMeshGenerator.h +++ b/src/atlas/meshgenerator/DelaunayMeshGenerator.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,9 +14,9 @@ #include "atlas/meshgenerator/MeshGenerator.h" namespace atlas { - class Mesh; - class Grid; -} +class Mesh; +class Grid; +} // namespace atlas namespace atlas { namespace meshgenerator { @@ -24,21 +25,18 @@ namespace meshgenerator { class DelaunayMeshGenerator : public MeshGenerator::Implementation { public: + DelaunayMeshGenerator(); + DelaunayMeshGenerator( const eckit::Parametrisation& p ); - DelaunayMeshGenerator(); - DelaunayMeshGenerator(const eckit::Parametrisation& p); - - virtual ~DelaunayMeshGenerator(); + virtual ~DelaunayMeshGenerator(); -private: // methods +private: // methods + virtual void hash( eckit::Hash& ) const override; - virtual void hash(eckit::Hash&) const override; + virtual void generate( const Grid&, const grid::Distribution&, Mesh& ) const override; + virtual void generate( const Grid&, Mesh& ) const override; - virtual void generate(const Grid&, const grid::Distribution&, Mesh&) const override; - virtual void generate(const Grid&, Mesh&) const override; - - void createNodes(const Grid&, Mesh&) const; - + void createNodes( const Grid&, Mesh& ) const; }; //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/meshgenerator/MeshGenerator.cc b/src/atlas/meshgenerator/MeshGenerator.cc index 6fcadf021..7ac6a445c 100644 --- a/src/atlas/meshgenerator/MeshGenerator.cc +++ b/src/atlas/meshgenerator/MeshGenerator.cc @@ -4,30 +4,31 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include -#include #include +#include +#include "eckit/exception/Exceptions.h" #include "eckit/thread/AutoLock.h" #include "eckit/thread/Mutex.h" -#include "eckit/exception/Exceptions.h" #include "eckit/utils/Hash.h" +#include "atlas/array/ArrayView.h" +#include "atlas/field/Field.h" #include "atlas/grid/Grid.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" +#include "atlas/meshgenerator/DelaunayMeshGenerator.h" #include "atlas/meshgenerator/MeshGenerator.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" -#include "atlas/meshgenerator/DelaunayMeshGenerator.h" -#include "atlas/mesh/HybridElements.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/array/ArrayView.h" -#include "atlas/field/Field.h" using atlas::Mesh; @@ -38,305 +39,261 @@ namespace meshgenerator { namespace { - static eckit::Mutex *local_mutex = 0; - static std::map *m = 0; - static pthread_once_t once = PTHREAD_ONCE_INIT; +static eckit::Mutex* local_mutex = 0; +static std::map* m = 0; +static pthread_once_t once = PTHREAD_ONCE_INIT; - static void init() { - local_mutex = new eckit::Mutex(); - m = new std::map(); - } +static void init() { + local_mutex = new eckit::Mutex(); + m = new std::map(); +} - template void load_builder() { MeshGeneratorBuilder("tmp"); } +template +void load_builder() { + MeshGeneratorBuilder( "tmp" ); +} - struct force_link { - force_link() - { - load_builder(); - load_builder(); - } - }; +struct force_link { + force_link() { + load_builder(); + load_builder(); + } +}; -} +} // namespace //---------------------------------------------------------------------------------------------------------------------- -MeshGeneratorImpl::MeshGeneratorImpl() -{ -} +MeshGeneratorImpl::MeshGeneratorImpl() {} -MeshGeneratorImpl::~MeshGeneratorImpl() { -} +MeshGeneratorImpl::~MeshGeneratorImpl() {} -Mesh MeshGeneratorImpl::operator()( const Grid& grid ) const -{ - Mesh mesh; - generate(grid,mesh); - return mesh; +Mesh MeshGeneratorImpl::operator()( const Grid& grid ) const { + Mesh mesh; + generate( grid, mesh ); + return mesh; } -Mesh MeshGeneratorImpl::operator()( const Grid& grid, const grid::Distribution& distribution ) const -{ - Mesh mesh; - generate(grid,distribution,mesh); - return mesh; +Mesh MeshGeneratorImpl::operator()( const Grid& grid, const grid::Distribution& distribution ) const { + Mesh mesh; + generate( grid, distribution, mesh ); + return mesh; } -Mesh MeshGeneratorImpl::generate( const Grid& grid ) const -{ - Mesh mesh; - generate(grid,mesh); - return mesh; +Mesh MeshGeneratorImpl::generate( const Grid& grid ) const { + Mesh mesh; + generate( grid, mesh ); + return mesh; } -Mesh MeshGeneratorImpl::generate( const Grid& grid, const grid::Distribution& distribution ) const -{ - Mesh mesh; - generate(grid,distribution,mesh); - return mesh; +Mesh MeshGeneratorImpl::generate( const Grid& grid, const grid::Distribution& distribution ) const { + Mesh mesh; + generate( grid, distribution, mesh ); + return mesh; } //---------------------------------------------------------------------------------------------------------------------- -void MeshGeneratorImpl::generateGlobalElementNumbering( Mesh& mesh ) const -{ - size_t loc_nb_elems = mesh.cells().size(); - std::vector elem_counts( mpi::comm().size() ); - std::vector elem_displs( mpi::comm().size() ); +void MeshGeneratorImpl::generateGlobalElementNumbering( Mesh& mesh ) const { + size_t loc_nb_elems = mesh.cells().size(); + std::vector elem_counts( mpi::comm().size() ); + std::vector elem_displs( mpi::comm().size() ); - ATLAS_TRACE_MPI( ALLGATHER ) { - mpi::comm().allGather(loc_nb_elems, elem_counts.begin(), elem_counts.end()); - } + ATLAS_TRACE_MPI( ALLGATHER ) { mpi::comm().allGather( loc_nb_elems, elem_counts.begin(), elem_counts.end() ); } - elem_displs.at(0) = 0; - for(size_t jpart = 1; jpart < mpi::comm().size(); ++jpart) - { - elem_displs.at(jpart) = elem_displs.at(jpart-1) + elem_counts.at(jpart-1); - } + elem_displs.at( 0 ) = 0; + for ( size_t jpart = 1; jpart < mpi::comm().size(); ++jpart ) { + elem_displs.at( jpart ) = elem_displs.at( jpart - 1 ) + elem_counts.at( jpart - 1 ); + } - gidx_t gid = 1+elem_displs.at( mpi::comm().rank() ); + gidx_t gid = 1 + elem_displs.at( mpi::comm().rank() ); - array::ArrayView glb_idx = array::make_view( mesh.cells().global_index() ); + array::ArrayView glb_idx = array::make_view( mesh.cells().global_index() ); - for( size_t jelem=0; jelem lock(local_mutex); + eckit::AutoLock lock( local_mutex ); - ASSERT(m->find(name) == m->end()); - (*m)[name] = this; + ASSERT( m->find( name ) == m->end() ); + ( *m )[name] = this; } - MeshGeneratorFactory::~MeshGeneratorFactory() { - eckit::AutoLock lock(local_mutex); - m->erase(name_); + eckit::AutoLock lock( local_mutex ); + m->erase( name_ ); } +void MeshGeneratorFactory::list( std::ostream& out ) { + pthread_once( &once, init ); -void MeshGeneratorFactory::list(std::ostream& out) { - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; const char* sep = ""; - for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { - out << sep << (*j).first; + for ( std::map::const_iterator j = m->begin(); j != m->end(); ++j ) { + out << sep << ( *j ).first; sep = ", "; } } +const MeshGenerator::Implementation* MeshGeneratorFactory::build( const std::string& name ) { + pthread_once( &once, init ); -const MeshGenerator::Implementation *MeshGeneratorFactory::build(const std::string &name) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::map::const_iterator j = m->find(name); + std::map::const_iterator j = m->find( name ); Log::debug() << "Looking for MeshGeneratorFactory [" << name << "]" << std::endl; - if (j == m->end()) { + if ( j == m->end() ) { Log::error() << "No MeshGeneratorFactory for [" << name << "]" << std::endl; Log::error() << "MeshGeneratorFactories are:" << std::endl; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No MeshGeneratorFactory called ") + name); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << std::endl; + throw eckit::SeriousBug( std::string( "No MeshGeneratorFactory called " ) + name ); } - return (*j).second->make(); + return ( *j ).second->make(); } -const MeshGenerator::Implementation *MeshGeneratorFactory::build(const std::string& name, const eckit::Parametrisation& param) { - - pthread_once(&once, init); +const MeshGenerator::Implementation* MeshGeneratorFactory::build( const std::string& name, + const eckit::Parametrisation& param ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::map::const_iterator j = m->find(name); + std::map::const_iterator j = m->find( name ); Log::debug() << "Looking for MeshGeneratorFactory [" << name << "]" << std::endl; - if (j == m->end()) { + if ( j == m->end() ) { Log::error() << "No MeshGeneratorFactory for [" << name << "]" << std::endl; Log::error() << "MeshGeneratorFactories are:" << std::endl; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No MeshGeneratorFactory called ") + name); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << std::endl; + throw eckit::SeriousBug( std::string( "No MeshGeneratorFactory called " ) + name ); } - return (*j).second->make(param); + return ( *j ).second->make( param ); } //---------------------------------------------------------------------------------------------------------------------- extern "C" { -void atlas__MeshGenerator__delete(MeshGenerator::Implementation* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - delete This; - ); +void atlas__MeshGenerator__delete( MeshGenerator::Implementation* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); delete This; ); } -const MeshGenerator::Implementation* atlas__MeshGenerator__create_noconfig(const char* name) -{ - const MeshGenerator::Implementation* meshgenerator(0); - ATLAS_ERROR_HANDLING ( - { - MeshGenerator m( std::string{name} ); - meshgenerator = m.get(); - meshgenerator->attach(); - } - meshgenerator->detach(); - ); - return meshgenerator; +const MeshGenerator::Implementation* atlas__MeshGenerator__create_noconfig( const char* name ) { + const MeshGenerator::Implementation* meshgenerator( 0 ); + ATLAS_ERROR_HANDLING( { + MeshGenerator m( std::string{name} ); + meshgenerator = m.get(); + meshgenerator->attach(); + } meshgenerator->detach(); ); + return meshgenerator; } -const MeshGenerator::Implementation* atlas__MeshGenerator__create(const char* name, const eckit::Parametrisation* params) -{ - const MeshGenerator::Implementation* meshgenerator(0); - ATLAS_ERROR_HANDLING ( - ASSERT(params); - { - MeshGenerator m( std::string(name), *params ); - meshgenerator = m.get(); - meshgenerator->attach(); - } - meshgenerator->detach(); - ); - return meshgenerator; +const MeshGenerator::Implementation* atlas__MeshGenerator__create( const char* name, + const eckit::Parametrisation* params ) { + const MeshGenerator::Implementation* meshgenerator( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( params ); { + MeshGenerator m( std::string( name ), *params ); + meshgenerator = m.get(); + meshgenerator->attach(); + } meshgenerator->detach(); ); + return meshgenerator; } -Mesh::Implementation* atlas__MeshGenerator__generate__grid_griddist (const MeshGenerator::Implementation* This, const Grid::Implementation* grid, const grid::Distribution::impl_t* distribution ) -{ - ATLAS_ERROR_HANDLING( - Mesh::Implementation* m; - { - Mesh mesh = This->generate(Grid(grid), grid::Distribution(distribution)); - mesh.get()->attach(); - m = mesh.get(); - } - m->detach(); - return m; - ); - return nullptr; +Mesh::Implementation* atlas__MeshGenerator__generate__grid_griddist( const MeshGenerator::Implementation* This, + const Grid::Implementation* grid, + const grid::Distribution::impl_t* distribution ) { + ATLAS_ERROR_HANDLING( Mesh::Implementation * m; { + Mesh mesh = This->generate( Grid( grid ), grid::Distribution( distribution ) ); + mesh.get()->attach(); + m = mesh.get(); + } m->detach(); + return m; ); + return nullptr; } -Mesh::Implementation* atlas__MeshGenerator__generate__grid (const MeshGenerator::Implementation* This, const Grid::Implementation* grid ) -{ - ATLAS_ERROR_HANDLING( - Mesh::Implementation* m; - { - Mesh mesh = This->generate(Grid(grid));; - mesh.get()->attach(); - m = mesh.get(); - } - m->detach(); - return m; - ); - return nullptr; +Mesh::Implementation* atlas__MeshGenerator__generate__grid( const MeshGenerator::Implementation* This, + const Grid::Implementation* grid ) { + ATLAS_ERROR_HANDLING( Mesh::Implementation * m; { + Mesh mesh = This->generate( Grid( grid ) ); + ; + mesh.get()->attach(); + m = mesh.get(); + } m->detach(); + return m; ); + return nullptr; } - } //---------------------------------------------------------------------------------------------------------------------- -} // namespace meshgenerator +} // namespace meshgenerator //---------------------------------------------------------------------------------------------------------------------- -MeshGenerator::MeshGenerator() : - meshgenerator_( nullptr ) { -} +MeshGenerator::MeshGenerator() : meshgenerator_( nullptr ) {} -MeshGenerator::MeshGenerator( const Implementation* meshgenerator ) : - meshgenerator_( meshgenerator ) { -} +MeshGenerator::MeshGenerator( const Implementation* meshgenerator ) : meshgenerator_( meshgenerator ) {} -MeshGenerator::MeshGenerator( const MeshGenerator& meshgenerator ) : - meshgenerator_( meshgenerator.meshgenerator_ ) { -} +MeshGenerator::MeshGenerator( const MeshGenerator& meshgenerator ) : meshgenerator_( meshgenerator.meshgenerator_ ) {} -MeshGenerator::MeshGenerator(const std::string &key, const eckit::Parametrisation ¶ms) : - meshgenerator_( meshgenerator::MeshGeneratorFactory::build(key,params) ) { -} +MeshGenerator::MeshGenerator( const std::string& key, const eckit::Parametrisation& params ) : + meshgenerator_( meshgenerator::MeshGeneratorFactory::build( key, params ) ) {} -void MeshGenerator::hash(eckit::Hash& h) const { - return meshgenerator_->hash(h); +void MeshGenerator::hash( eckit::Hash& h ) const { + return meshgenerator_->hash( h ); } -Mesh MeshGenerator::generate( const Grid& g, const grid::Distribution& d) const { - return meshgenerator_->generate(g,d); +Mesh MeshGenerator::generate( const Grid& g, const grid::Distribution& d ) const { + return meshgenerator_->generate( g, d ); } -Mesh MeshGenerator::generate( const Grid& g) const { - return meshgenerator_->generate(g); +Mesh MeshGenerator::generate( const Grid& g ) const { + return meshgenerator_->generate( g ); } Mesh MeshGenerator::operator()( const Grid& g, const grid::Distribution& d ) const { - return meshgenerator_->operator()(g,d); + return meshgenerator_->operator()( g, d ); } Mesh MeshGenerator::operator()( const Grid& g ) const { - return meshgenerator_->operator()(g); + return meshgenerator_->operator()( g ); } //---------------------------------------------------------------------------------------------------------------------- -} // namespace atlas - +} // namespace atlas diff --git a/src/atlas/meshgenerator/MeshGenerator.h b/src/atlas/meshgenerator/MeshGenerator.h index a7d3ba6e3..3c0f26dbe 100644 --- a/src/atlas/meshgenerator/MeshGenerator.h +++ b/src/atlas/meshgenerator/MeshGenerator.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,25 +14,28 @@ #include #include +#include "eckit/config/Parametrisation.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" -#include "eckit/config/Parametrisation.h" -#include "atlas/grid/Grid.h" #include "atlas/grid/Distribution.h" +#include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" #include "atlas/util/Config.h" -namespace eckit { class Hash; } +namespace eckit { +class Hash; +} namespace atlas { - class Mesh; +class Mesh; } namespace atlas { namespace grid { - class Distribution; -} } +class Distribution; +} +} // namespace atlas namespace atlas { namespace meshgenerator { @@ -39,17 +43,15 @@ namespace meshgenerator { //---------------------------------------------------------------------------------------------------------------------- class MeshGeneratorImpl : public eckit::Owned { - public: - MeshGeneratorImpl(); virtual ~MeshGeneratorImpl(); - virtual void hash(eckit::Hash&) const = 0; + virtual void hash( eckit::Hash& ) const = 0; - virtual void generate( const Grid&, const grid::Distribution&, Mesh& ) const =0; - virtual void generate( const Grid&, Mesh& ) const =0; + virtual void generate( const Grid&, const grid::Distribution&, Mesh& ) const = 0; + virtual void generate( const Grid&, Mesh& ) const = 0; Mesh generate( const Grid&, const grid::Distribution& ) const; Mesh generate( const Grid& ) const; @@ -58,7 +60,6 @@ class MeshGeneratorImpl : public eckit::Owned { Mesh operator()( const Grid& ) const; protected: - void generateGlobalElementNumbering( Mesh& mesh ) const; void setProjection( Mesh&, const Projection& ) const; void setGrid( Mesh&, const Grid&, const grid::Distribution& ) const; @@ -68,87 +69,79 @@ class MeshGeneratorImpl : public eckit::Owned { class MeshGeneratorFactory { public: - /*! - * \brief build MeshGenerator with factory key, and default options - * \return mesh generator - */ - static const MeshGeneratorImpl* build(const std::string&); + * \brief build MeshGenerator with factory key, and default options + * \return mesh generator + */ + static const MeshGeneratorImpl* build( const std::string& ); /*! - * \brief build MeshGenerator with factory key inside parametrisation, - * and options specified in parametrisation as well - * \return mesh generator - */ - static const MeshGeneratorImpl* build(const std::string&, const eckit::Parametrisation&); + * \brief build MeshGenerator with factory key inside parametrisation, + * and options specified in parametrisation as well + * \return mesh generator + */ + static const MeshGeneratorImpl* build( const std::string&, const eckit::Parametrisation& ); /*! - * \brief list all registered mesh generators - */ - static void list(std::ostream &); + * \brief list all registered mesh generators + */ + static void list( std::ostream& ); private: - std::string name_; - virtual const MeshGeneratorImpl* make() = 0 ; - virtual const MeshGeneratorImpl* make(const eckit::Parametrisation&) = 0 ; + virtual const MeshGeneratorImpl* make() = 0; + virtual const MeshGeneratorImpl* make( const eckit::Parametrisation& ) = 0; protected: - - MeshGeneratorFactory(const std::string&); + MeshGeneratorFactory( const std::string& ); virtual ~MeshGeneratorFactory(); - }; //---------------------------------------------------------------------------------------------------------------------- -template +template class MeshGeneratorBuilder : public MeshGeneratorFactory { - virtual const MeshGeneratorImpl* make() { - return new T(); - } - virtual const MeshGeneratorImpl* make(const eckit::Parametrisation& param) { - return new T(param); - } - public: - MeshGeneratorBuilder(const std::string& name) : MeshGeneratorFactory(name) {} + virtual const MeshGeneratorImpl* make() { return new T(); } + virtual const MeshGeneratorImpl* make( const eckit::Parametrisation& param ) { return new T( param ); } + +public: + MeshGeneratorBuilder( const std::string& name ) : MeshGeneratorFactory( name ) {} }; //---------------------------------------------------------------------------------------------------------------------- extern "C" { -void atlas__MeshGenerator__delete(MeshGeneratorImpl* This); -const MeshGeneratorImpl* atlas__MeshGenerator__create_noconfig(const char* name); -const MeshGeneratorImpl* atlas__MeshGenerator__create(const char* name, const eckit::Parametrisation* params); -Mesh::Implementation* atlas__MeshGenerator__generate__grid_griddist(const MeshGeneratorImpl* This, const Grid::Implementation* grid, const grid::Distribution::impl_t* distribution); -Mesh::Implementation* atlas__MeshGenerator__generate__grid(const MeshGeneratorImpl* This, const Grid::Implementation* grid); +void atlas__MeshGenerator__delete( MeshGeneratorImpl* This ); +const MeshGeneratorImpl* atlas__MeshGenerator__create_noconfig( const char* name ); +const MeshGeneratorImpl* atlas__MeshGenerator__create( const char* name, const eckit::Parametrisation* params ); +Mesh::Implementation* atlas__MeshGenerator__generate__grid_griddist( const MeshGeneratorImpl* This, + const Grid::Implementation* grid, + const grid::Distribution::impl_t* distribution ); +Mesh::Implementation* atlas__MeshGenerator__generate__grid( const MeshGeneratorImpl* This, + const Grid::Implementation* grid ); } //---------------------------------------------------------------------------------------------------------------------- -} // namespace meshgenerator +} // namespace meshgenerator //---------------------------------------------------------------------------------------------------------------------- class MeshGenerator { - public: - - using Implementation = meshgenerator::MeshGeneratorImpl; - typedef atlas::util::Config Parameters; + using Implementation = meshgenerator::MeshGeneratorImpl; + typedef atlas::util::Config Parameters; private: - - eckit::SharedPtr< const Implementation > meshgenerator_; + eckit::SharedPtr meshgenerator_; public: - MeshGenerator(); MeshGenerator( const Implementation* ); MeshGenerator( const MeshGenerator& ); - MeshGenerator(const std::string &, const eckit::Parametrisation & = util::NoConfig()); + MeshGenerator( const std::string&, const eckit::Parametrisation& = util::NoConfig() ); - void hash(eckit::Hash&) const; + void hash( eckit::Hash& ) const; Mesh generate( const Grid&, const grid::Distribution& ) const; Mesh generate( const Grid& ) const; @@ -157,9 +150,8 @@ class MeshGenerator { Mesh operator()( const Grid& ) const; const Implementation* get() const { return meshgenerator_.get(); } - }; //---------------------------------------------------------------------------------------------------------------------- -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/meshgenerator/RegularMeshGenerator.cc b/src/atlas/meshgenerator/RegularMeshGenerator.cc index 6c1eb983c..26b4d80f1 100644 --- a/src/atlas/meshgenerator/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/RegularMeshGenerator.cc @@ -1,28 +1,27 @@ -#include +#include "atlas/meshgenerator/RegularMeshGenerator.h" #include #include #include +#include #include -#include "eckit/utils/Hash.h" -#include "atlas/library/config.h" -#include "atlas/grid/Partitioner.h" -#include "atlas/grid/Grid.h" -#include "atlas/grid/Distribution.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/ElementType.h" -#include "atlas/mesh/Elements.h" -#include "atlas/meshgenerator/RegularMeshGenerator.h" -#include "atlas/field/Field.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/runtime/Log.h" #include "atlas/array/Array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" +#include "atlas/field/Field.h" +#include "atlas/grid/Distribution.h" +#include "atlas/grid/Grid.h" +#include "atlas/grid/Partitioner.h" +#include "atlas/library/config.h" +#include "atlas/mesh/ElementType.h" +#include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" +#include "atlas/util/CoordinateEnums.h" +#include "eckit/utils/Hash.h" #define DEBUG_OUTPUT 0 #define DEBUG_OUTPUT_DETAIL 0 @@ -32,477 +31,506 @@ using Topology = atlas::mesh::Nodes::Topology; namespace atlas { namespace meshgenerator { -RegularMeshGenerator::RegularMeshGenerator(const eckit::Parametrisation& p) -{ - configure_defaults(); - - // options copied from Structured MeshGenerator - size_t 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); - - std::string partitioner; - if( p.get("partitioner",partitioner) ) - { - if( not grid::Partitioner::exists(partitioner) ) { - Log::warning() << "Atlas does not have support for partitioner " << partitioner << ". " - << "Defaulting to use partitioner EqualRegions" << std::endl; - partitioner = "equal_regions"; +RegularMeshGenerator::RegularMeshGenerator( const eckit::Parametrisation& p ) { + configure_defaults(); + + // options copied from Structured MeshGenerator + size_t 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 ); + + std::string partitioner; + if ( p.get( "partitioner", partitioner ) ) { + if ( not grid::Partitioner::exists( partitioner ) ) { + Log::warning() << "Atlas does not have support for partitioner " << partitioner << ". " + << "Defaulting to use partitioner EqualRegions" << std::endl; + partitioner = "equal_regions"; + } + options.set( "partitioner", partitioner ); } - options.set("partitioner",partitioner); - } - - // options specifically for this MeshGenerator - bool 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); - - bool biperiodic; - if( p.get("biperiodic",biperiodic) ) { - options.set("periodic_x",biperiodic); - options.set("periodic_y",biperiodic); - } -} + // options specifically for this MeshGenerator + bool periodic_x; + if ( p.get( "periodic_x", periodic_x ) ) options.set( "periodic_x", periodic_x ); -void RegularMeshGenerator::configure_defaults() -{ + bool periodic_y; + if ( p.get( "periodic_y", periodic_y ) ) options.set( "periodic_y", periodic_y ); - // This option sets number of parts the mesh will be split in - options.set( "nb_parts", mpi::comm().size() ); + bool biperiodic; + if ( p.get( "biperiodic", biperiodic ) ) { + options.set( "periodic_x", biperiodic ); + options.set( "periodic_y", biperiodic ); + } +} - // This option sets the part that will be generated - options.set( "part", mpi::comm().rank() ); +void RegularMeshGenerator::configure_defaults() { + // This option sets number of parts the mesh will be split in + options.set( "nb_parts", mpi::comm().size() ); - // This options sets the default partitioner - std::string partitioner; - if( grid::Partitioner::exists("trans") && mpi::comm().size() > 1 ) - partitioner = "trans"; - else - partitioner = "checkerboard"; - options.set("partitioner",partitioner); + // This option sets the part that will be generated + options.set( "part", mpi::comm().rank() ); - // Options for for periodic grids - options.set("periodic_x",false); - options.set("periodic_y",false); + // This options sets the default partitioner + std::string partitioner; + if ( grid::Partitioner::exists( "trans" ) && mpi::comm().size() > 1 ) + partitioner = "trans"; + else + partitioner = "checkerboard"; + options.set( "partitioner", partitioner ); + // Options for for periodic grids + options.set( "periodic_x", false ); + options.set( "periodic_y", false ); } -void RegularMeshGenerator::generate(const Grid& grid, Mesh& mesh ) const -{ - ASSERT(!mesh.generated()); +void RegularMeshGenerator::generate( const Grid& grid, Mesh& mesh ) const { + ASSERT( !mesh.generated() ); - const grid::RegularGrid rg = grid::RegularGrid(grid); - if( !rg ) - throw eckit::BadCast("RegularMeshGenerator can only work with a Regular grid",Here()); + const grid::RegularGrid rg = grid::RegularGrid( grid ); + if ( !rg ) throw eckit::BadCast( "RegularMeshGenerator can only work with a Regular grid", Here() ); - size_t nb_parts = options.get("nb_parts"); + size_t nb_parts = options.get( "nb_parts" ); - std::string partitioner_type = "checkerboard"; - options.get("checkerboard",partitioner_type); + std::string partitioner_type = "checkerboard"; + options.get( "checkerboard", partitioner_type ); - //if ( rg->nlat()%2 == 1 ) partitioner_factory = "equal_regions"; // Odd number of latitudes - //if ( nb_parts == 1 || eckit::mpi::size() == 1 ) partitioner_factory = "equal_regions"; // Only one part --> Trans is slower + // if ( rg->nlat()%2 == 1 ) partitioner_factory = "equal_regions"; // Odd + // number of latitudes + // if ( nb_parts == 1 || eckit::mpi::size() == 1 ) partitioner_factory = + // "equal_regions"; // Only one part --> Trans is slower - grid::Partitioner partitioner( partitioner_type, nb_parts ); - grid::Distribution distribution( partitioner.partition(grid) ); - generate( grid, distribution, mesh ); + grid::Partitioner partitioner( partitioner_type, nb_parts ); + grid::Distribution distribution( partitioner.partition( grid ) ); + generate( grid, distribution, mesh ); } -void RegularMeshGenerator::hash(eckit::Hash& h) const -{ - h.add("RegularMeshGenerator"); - options.hash(h); +void RegularMeshGenerator::hash( eckit::Hash& h ) const { + h.add( "RegularMeshGenerator" ); + options.hash( h ); } -void RegularMeshGenerator::generate(const Grid& grid, const grid::Distribution& distribution, Mesh& mesh ) const -{ - const grid::RegularGrid rg = grid::RegularGrid(grid); - if( !rg ) - throw eckit::BadCast("Grid could not be cast to a Regular",Here()); +void RegularMeshGenerator::generate( const Grid& grid, const grid::Distribution& distribution, Mesh& mesh ) const { + const grid::RegularGrid rg = grid::RegularGrid( grid ); + if ( !rg ) throw eckit::BadCast( "Grid could not be cast to a Regular", Here() ); - ASSERT(!mesh.generated()); + ASSERT( !mesh.generated() ); - if( grid.size() != distribution.partition().size() ) - { - std::stringstream msg; - msg << "Number of points in grid ("<& parts, - //const Region& region, - Mesh& mesh ) const -{ - int mypart = options.get("part"); - int nparts = options.get("nb_parts"); - int nx=rg.nx(); - int ny=rg.ny(); +void RegularMeshGenerator::generate_mesh( const grid::RegularGrid& rg, const std::vector& parts, + // const Region& region, + Mesh& mesh ) const { + int mypart = options.get( "part" ); + int nparts = options.get( "nb_parts" ); + int nx = rg.nx(); + int ny = rg.ny(); - bool periodic_x = options.get("periodic_x") or rg.periodic() ; - bool periodic_y = options.get("periodic_y"); + bool periodic_x = options.get( "periodic_x" ) or rg.periodic(); + bool periodic_y = options.get( "periodic_y" ); - Log::debug() << Here() << " periodic_x = " << periodic_x << std::endl; - Log::debug() << Here() << " periodic_y = " << periodic_y << std::endl; + Log::debug() << Here() << " periodic_x = " << periodic_x << std::endl; + Log::debug() << Here() << " periodic_y = " << periodic_y << std::endl; - // for asynchronous output +// for asynchronous output #if DEBUG_OUTPUT - sleep( mypart ); + sleep( mypart ); #endif - // this function should do the following: - // - define nodes with - // mesh.nodes().resize(nnodes); - // mesh::Nodes& nodes = mesh.nodes(); - // following properties should be defined: - // array::ArrayView xy ( nodes.xy() ); - // array::ArrayView glb_idx ( nodes.global_index() ); - // array::ArrayView part ( nodes.partition() ); - // array::ArrayView ghost ( nodes.ghost() ); - // array::ArrayView flags ( nodes.field("flags") ); - // - define cells (only quadrilaterals for now) with - // mesh.cells().add( new mesh::temporary::Quadrilateral(), nquads ); - // further define cells with - // array::ArrayView cells_glb_idx( mesh.cells().global_index() ); - // array::ArrayView cells_part( mesh.cells().partition() ); - // - define connectivity with - // mesh::HybridElements::Connectivity& node_connectivity = mesh.cells().node_connectivity(); - // node_connectivity.set( jcell, quad_nodes ); - // where quad_nodes is a 4-element integer array containing the LOCAL indices of the nodes - - // Start with calculating number of quadrilaterals - // The rule do determine if a cell belongs to a proc is the following: if the lowerleft corner of the cell belongs to that proc. - // so we loop over all gridpoints, select those that belong to the proc, and determine the number of cells - int ii_glb; // global index - int ncells; - - // vector of local indices: necessary for remote indices of ghost nodes - std::vector local_idx(rg.size(),-1); - std::vector current_idx(nparts,0); // index counter for each proc - - // determine rectangle (ix_min:ix_max) x (iy_min:iy_max) surrounding the nodes on this processor - int ix_min, ix_max, iy_min, iy_max, ix_glb, iy_glb, ix, iy; - int nnodes_nonghost, nnodes; // number of nodes: non-ghost; total; inside surrounding rectangle - int nnodes_SR, ii; - - // loop over all points to determine local indices and surroundig rectangle - ix_min=nx+1;ix_max=0;iy_min=ny+1;iy_max=0; - nnodes_nonghost=0; - - ii_glb=0; - for (iy=0;iy xy ( nodes.xy() ); + // array::ArrayView glb_idx ( nodes.global_index() ); + // array::ArrayView part ( nodes.partition() ); + // array::ArrayView ghost ( nodes.ghost() ); + // array::ArrayView flags ( nodes.field("flags") ); + // - define cells (only quadrilaterals for now) with + // mesh.cells().add( new mesh::temporary::Quadrilateral(), nquads ); + // further define cells with + // array::ArrayView cells_glb_idx( mesh.cells().global_index() + // ); + // array::ArrayView cells_part( mesh.cells().partition() ); + // - define connectivity with + // mesh::HybridElements::Connectivity& node_connectivity = + // mesh.cells().node_connectivity(); + // node_connectivity.set( jcell, quad_nodes ); + // where quad_nodes is a 4-element integer array containing the LOCAL + // indices of the nodes + + // Start with calculating number of quadrilaterals + // The rule do determine if a cell belongs to a proc is the following: if the + // lowerleft corner of the cell belongs to that proc. + // so we loop over all gridpoints, select those that belong to the proc, and + // determine the number of cells + int ii_glb; // global index + int ncells; + + // vector of local indices: necessary for remote indices of ghost nodes + std::vector local_idx( rg.size(), -1 ); + std::vector current_idx( nparts, 0 ); // index counter for each proc + + // determine rectangle (ix_min:ix_max) x (iy_min:iy_max) surrounding the nodes + // on this processor + int ix_min, ix_max, iy_min, iy_max, ix_glb, iy_glb, ix, iy; + int nnodes_nonghost, nnodes; // number of nodes: non-ghost; total; inside + // surrounding rectangle + int nnodes_SR, ii; + + // loop over all points to determine local indices and surroundig rectangle + ix_min = nx + 1; + ix_max = 0; + iy_min = ny + 1; + iy_max = 0; + nnodes_nonghost = 0; + + ii_glb = 0; + for ( iy = 0; iy < ny; iy++ ) { + for ( ix = 0; ix < nx; ix++ ) { + local_idx[ii_glb] = current_idx[parts[ii_glb]]++; // store local index on + // the local proc of + // this point + if ( parts[ii_glb] == mypart ) { + ++nnodes_nonghost; // non-ghost node: belongs to this part + ix_min = std::min( ix_min, ix ); + ix_max = std::max( ix_max, ix ); + iy_min = std::min( iy_min, iy ); + iy_max = std::max( iy_max, iy ); + } + ++ii_glb; // global index + } } - } - // add one row/column for ghost nodes (which include periodicity points) - ix_max=ix_max+1; - iy_max=iy_max+1; + // add one row/column for ghost nodes (which include periodicity points) + ix_max = ix_max + 1; + iy_max = iy_max + 1; #if DEBUG_OUTPUT_DETAIL - std::cout << "[" << mypart << "] : " << "SR = " << ix_min << ":" << ix_max << " x " << iy_min << ":" << iy_max << std::endl; + std::cout << "[" << mypart << "] : " + << "SR = " << ix_min << ":" << ix_max << " x " << iy_min << ":" << iy_max << std::endl; #endif - // dimensions of surrounding rectangle (SR) - int nxl=ix_max-ix_min+1; - int nyl=iy_max-iy_min+1; - - // upper estimate for number of nodes - nnodes_SR=nxl*nyl; - - // partitions and local indices in SR - std::vector parts_SR(nnodes_SR,-1); - std::vector local_idx_SR(nnodes_SR,-1); - std::vector is_ghost_SR(nnodes_SR,true); - ii=0; // index inside SR - for (iy=0; iy parts_SR( nnodes_SR, -1 ); + std::vector local_idx_SR( nnodes_SR, -1 ); + std::vector is_ghost_SR( nnodes_SR, true ); + ii = 0; // index inside SR + for ( iy = 0; iy < nyl; iy++ ) { + iy_glb = ( iy_min + iy ); // global y-index + for ( ix = 0; ix < nxl; ix++ ) { + ix_glb = ( ix_min + ix ); // global x-index + is_ghost_SR[ii] = !( ( parts_SR[ii] == mypart ) && ix < nxl - 1 && iy < nyl - 1 ); + if ( ix_glb < nx && iy_glb < ny ) { + ii_glb = (iy_glb)*nx + ix_glb; // global index + parts_SR[ii] = parts[ii_glb]; + local_idx_SR[ii] = local_idx[ii_glb]; + is_ghost_SR[ii] = !( ( parts_SR[ii] == mypart ) && ix < nxl - 1 && iy < nyl - 1 ); + } + else if ( ix_glb == nx && iy_glb < ny ) { + // take properties from the point to the left + parts_SR[ii] = parts[iy_glb * nx + ix_glb - 1]; + local_idx_SR[ii] = -1; + is_ghost_SR[ii] = true; + } + else if ( iy_glb == ny && ix_glb < nx ) { + // take properties from the point below + parts_SR[ii] = parts[( iy_glb - 1 ) * nx + ix_glb]; + local_idx_SR[ii] = -1; + is_ghost_SR[ii] = true; + } + else { + // take properties from the point belowleft + parts_SR[ii] = parts[( iy_glb - 1 ) * nx + ix_glb - 1]; + local_idx_SR[ii] = -1; + is_ghost_SR[ii] = true; + } + ++ii; + } } - } #if DEBUG_OUTPUT_DETAIL - std::cout << "[" << mypart << "] : " << "parts_SR = "; for (ii=0;ii is_node_SR(nnodes_SR,false); - - // determine number of cells and number of nodes - nnodes=0; - ncells=0; - for (iy=0; iy is_node_SR( nnodes_SR, false ); + + // determine number of cells and number of nodes + nnodes = 0; + ncells = 0; + for ( iy = 0; iy < nyl - 1; iy++ ) { // don't loop into ghost/periodicity row + for ( ix = 0; ix < nxl - 1; ix++ ) { // don't loop into ghost/periodicity column + ii = iy * nxl + ix; + if ( !is_ghost_SR[ii] ) { + // mark this node as being used + if ( !is_node_SR[ii] ) { + ++nnodes; + is_node_SR[ii] = true; + } + // check if this node is the lowerleft corner of a new cell + if ( ( ix_min + ix < nx - 1 || periodic_x ) && ( iy_min + iy < ny - 1 || periodic_y ) ) { + ++ncells; + // mark lowerright corner + ii = iy * nxl + ix + 1; + if ( !is_node_SR[ii] ) { + ++nnodes; + is_node_SR[ii] = true; + } + // mark upperleft corner + ii = ( iy + 1 ) * nxl + ix; + if ( !is_node_SR[ii] ) { + ++nnodes; + is_node_SR[ii] = true; + } + // mark upperright corner + ii = ( iy + 1 ) * nxl + ix + 1; + if ( !is_node_SR[ii] ) { + ++nnodes; + is_node_SR[ii] = true; + } + } + // periodic points are always needed, even if they don't belong to a + // cell + ii = iy * nxl + ix + 1; + if ( periodic_x && ix_min + ix == nx - 1 && !is_node_SR[ii] ) { + ++nnodes; + is_node_SR[ii] = true; + } + ii = ( iy + 1 ) * nxl + ix; + if ( periodic_y && iy_min + iy == ny - 1 && !is_node_SR[ii] ) { + ++nnodes; + is_node_SR[ii] = true; + } + ii = ( iy + 1 ) * nxl + ix + 1; + if ( periodic_x && periodic_y && ix_min + ix == nx - 1 && iy_min + iy == ny - 1 && !is_node_SR[ii] ) { + ++nnodes; + is_node_SR[ii] = true; + } + } } - - } } - } #if DEBUG_OUTPUT_DETAIL - std::cout << "[" << mypart << "] : " << "nnodes = " << nnodes << std::endl; - std::cout << "[" << mypart << "] : " << "is_node_SR = "; for (ii=0;ii xy = array::make_view( nodes.xy() ); - array::ArrayView lonlat = array::make_view( nodes.lonlat() ); - array::ArrayView glb_idx = array::make_view( nodes.global_index() ); - array::IndexView remote_idx = array::make_indexview( nodes.remote_index() ); - array::ArrayView part = array::make_view( nodes.partition() ); - array::ArrayView ghost = array::make_view( nodes.ghost() ); - array::ArrayView flags = array::make_view( nodes.field("flags") ); - - // define cells and associated properties - mesh.cells().add( new mesh::temporary::Quadrilateral(), ncells ); - int quad_begin = mesh.cells().elements(0).begin(); - array::ArrayView cells_part = array::make_view( mesh.cells().partition() ); - mesh::HybridElements::Connectivity& node_connectivity = mesh.cells().node_connectivity(); - - int quad_nodes[4]; - int jcell=quad_begin; - int inode, inode_nonghost, inode_ghost; - - // global indices for periodicity points - inode=nx*ny; - std::vector glb_idx_px(ny+1,-1); - std::vector glb_idx_py(nx+1,-1); - if (periodic_x) { - for (iy=0;iy xy = array::make_view( nodes.xy() ); + array::ArrayView lonlat = array::make_view( nodes.lonlat() ); + array::ArrayView glb_idx = array::make_view( nodes.global_index() ); + array::IndexView remote_idx = array::make_indexview( nodes.remote_index() ); + array::ArrayView part = array::make_view( nodes.partition() ); + array::ArrayView ghost = array::make_view( nodes.ghost() ); + array::ArrayView flags = array::make_view( nodes.field( "flags" ) ); + + // define cells and associated properties + mesh.cells().add( new mesh::temporary::Quadrilateral(), ncells ); + int quad_begin = mesh.cells().elements( 0 ).begin(); + array::ArrayView cells_part = array::make_view( mesh.cells().partition() ); + mesh::HybridElements::Connectivity& node_connectivity = mesh.cells().node_connectivity(); + + int quad_nodes[4]; + int jcell = quad_begin; + int inode, inode_nonghost, inode_ghost; + + // global indices for periodicity points + inode = nx * ny; + std::vector glb_idx_px( ny + 1, -1 ); + std::vector glb_idx_py( nx + 1, -1 ); + if ( periodic_x ) { + for ( iy = 0; iy < ny + ( periodic_y ? 1 : 0 ); iy++ ) { + glb_idx_px[iy] = inode++; } - glb_idx(inode) = ii_glb+1; // starting from 1 - // grid coordinates - double _xy[2]; - if (iy_glb __RegularMeshGenerator("regular"); +static MeshGeneratorBuilder __RegularMeshGenerator( "regular" ); } -} // namespace meshgenerator -} // namespace atlas +} // namespace meshgenerator +} // namespace atlas diff --git a/src/atlas/meshgenerator/RegularMeshGenerator.h b/src/atlas/meshgenerator/RegularMeshGenerator.h index ab2a84cb0..cdc3530ae 100644 --- a/src/atlas/meshgenerator/RegularMeshGenerator.h +++ b/src/atlas/meshgenerator/RegularMeshGenerator.h @@ -2,20 +2,23 @@ #pragma once #include "atlas/meshgenerator/MeshGenerator.h" -#include "atlas/util/Metadata.h" #include "atlas/util/Config.h" +#include "atlas/util/Metadata.h" -namespace eckit { class Parametrisation; } +namespace eckit { +class Parametrisation; +} namespace atlas { - class Mesh; +class Mesh; } namespace atlas { namespace grid { - class RegularGrid; - class Distribution; -} } +class RegularGrid; +class Distribution; +} // namespace grid +} // namespace atlas namespace atlas { namespace meshgenerator { @@ -23,34 +26,26 @@ namespace meshgenerator { //---------------------------------------------------------------------------------------------------------------------- class RegularMeshGenerator : public MeshGenerator::Implementation { - public: + RegularMeshGenerator( const eckit::Parametrisation& = util::NoConfig() ); - RegularMeshGenerator(const eckit::Parametrisation& = util::NoConfig() ); - - virtual void generate(const Grid&, const grid::Distribution&, Mesh&) const override; - virtual void generate(const Grid&, Mesh&) const override; + virtual void generate( const Grid&, const grid::Distribution&, Mesh& ) const override; + virtual void generate( const Grid&, Mesh& ) const override; using MeshGenerator::Implementation::generate; private: - - virtual void hash(eckit::Hash&) const override; + virtual void hash( eckit::Hash& ) const override; void configure_defaults(); - void generate_mesh( - const atlas::grid::RegularGrid&, - const std::vector& parts, - Mesh& m ) const; + void generate_mesh( const atlas::grid::RegularGrid&, const std::vector& parts, Mesh& m ) const; private: - util::Metadata options; - }; //---------------------------------------------------------------------------------------------------------------------- -} // namespace meshgenerator -} // namespace atlas +} // namespace meshgenerator +} // namespace atlas diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index 7333e88d8..f052bc8f8 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -4,38 +4,39 @@ * 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 + * 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 -#include "eckit/runtime/Main.h" #include "eckit/memory/SharedPtr.h" +#include "eckit/runtime/Main.h" #include "eckit/utils/Hash.h" -#include "atlas/library/config.h" -#include "atlas/grid/Partitioner.h" -#include "atlas/grid/Grid.h" +#include "atlas/array.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" #include "atlas/grid/Distribution.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" +#include "atlas/grid/Grid.h" +#include "atlas/grid/Partitioner.h" +#include "atlas/library/config.h" #include "atlas/mesh/ElementType.h" #include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" -#include "atlas/field/Field.h" -#include "atlas/util/CoordinateEnums.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "atlas/array.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/MakeView.h" -#include "atlas/parallel/mpi/mpi.h" +#include "atlas/util/CoordinateEnums.h" #define DEBUG_OUTPUT 0 @@ -49,1239 +50,1165 @@ namespace meshgenerator { namespace detail { namespace { -static double to_rad = M_PI/180.; -static double to_deg = 180.*M_1_PI; -} - -struct Region -{ - int north; - int south; - eckit::SharedPtr elems; - int ntriags; - int nquads; - int nnodes; - std::vector lat_begin; - std::vector lat_end; - std::vector nb_lat_elems; +static double to_rad = M_PI / 180.; +static double to_deg = 180. * M_1_PI; +} // namespace + +struct Region { + int north; + int south; + eckit::SharedPtr elems; + int ntriags; + int nquads; + int nnodes; + std::vector lat_begin; + std::vector lat_end; + std::vector nb_lat_elems; }; -StructuredMeshGenerator::StructuredMeshGenerator(const eckit::Parametrisation& p) -{ - configure_defaults(); - - bool 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); - - bool unique_pole; - if( p.get("unique_pole",unique_pole) ) - options.set("unique_pole",unique_pole); - - bool 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) ) - options.set("nb_parts",nb_parts); - - size_t part; - if( p.get("part",part) ) - options.set("part",part); - - double angle; - if( p.get("angle",angle) ) - options.set("angle",angle); - - bool 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); - - std::string partitioner; - if( grid::Partitioner::exists("trans") ) - partitioner = "trans"; - else - partitioner = "equal_regions"; - options.set("partitioner",partitioner); - - if( p.get("partitioner",partitioner) ) - { - if( not grid::Partitioner::exists(partitioner) ) { - Log::warning() << "Atlas does not have support for partitioner " << partitioner << ". " - << "Defaulting to use partitioner EqualRegions" << std::endl; - partitioner = "equal_regions"; - } - options.set("partitioner",partitioner); - } -} - +StructuredMeshGenerator::StructuredMeshGenerator( const eckit::Parametrisation& p ) { + configure_defaults(); -void StructuredMeshGenerator::configure_defaults() -{ - // This option creates a point at the pole when true - options.set( "include_pole", false ); + bool include_pole; + if ( p.get( "include_pole", include_pole ) ) options.set( "include_pole", include_pole ); - // This option sets the part that will be generated - options.set( "patch_pole", true ); + bool patch_pole; + if ( p.get( "patch_pole", patch_pole ) ) options.set( "patch_pole", patch_pole ); - // This option disregards multiple poles in grid (e.g. lonlat up to poles) and connects elements - // to the first node only. Note this option will only be looked at in case other option - // "3d"==true - options.set( "unique_pole", true ); + bool unique_pole; + if ( p.get( "unique_pole", unique_pole ) ) options.set( "unique_pole", unique_pole ); - // This option creates elements that connect east to west at greenwich meridian - // when true, instead of creating periodic ghost-points at east boundary when false - options.set( "3d", false ); + bool three_dimensional; + if ( p.get( "three_dimensional", three_dimensional ) || p.get( "3d", three_dimensional ) ) + options.set( "3d", three_dimensional ); - // This option sets number of parts the mesh will be split in - options.set( "nb_parts", mpi::comm().size() ); + size_t nb_parts; + if ( p.get( "nb_parts", nb_parts ) ) options.set( "nb_parts", nb_parts ); - // This option sets the part that will be generated - options.set( "part", mpi::comm().rank() ); + size_t part; + if ( p.get( "part", part ) ) options.set( "part", part ); - // Experimental option. The result is a non-standard Reduced Gaussian Grid, with a ragged Greenwich line - options.set("stagger", false ); + double angle; + if ( p.get( "angle", angle ) ) options.set( "angle", angle ); - // This option sets the maximum angle deviation for a quadrilateral element - // angle = 30 --> minimises number of triangles - // angle = 0 --> maximises number of triangles - options.set("angle", 0. ); + bool triangulate; + if ( p.get( "triangulate", triangulate ) ) options.set( "triangulate", triangulate ); - options.set("triangulate", false ); + bool ghost_at_end; + if ( p.get( "ghost_at_end", ghost_at_end ) ) options.set( "ghost_at_end", ghost_at_end ); - options.set("ghost_at_end", true ); + std::string partitioner; + if ( grid::Partitioner::exists( "trans" ) ) + partitioner = "trans"; + else + partitioner = "equal_regions"; + options.set( "partitioner", partitioner ); + if ( p.get( "partitioner", partitioner ) ) { + if ( not grid::Partitioner::exists( partitioner ) ) { + Log::warning() << "Atlas does not have support for partitioner " << partitioner << ". " + << "Defaulting to use partitioner EqualRegions" << std::endl; + partitioner = "equal_regions"; + } + options.set( "partitioner", partitioner ); + } } -void StructuredMeshGenerator::generate(const Grid& grid, Mesh& mesh ) const -{ - ASSERT(!mesh.generated()); +void StructuredMeshGenerator::configure_defaults() { + // This option creates a point at the pole when true + options.set( "include_pole", false ); + + // This option sets the part that will be generated + options.set( "patch_pole", true ); + + // This option disregards multiple poles in grid (e.g. lonlat up to poles) and + // connects elements + // to the first node only. Note this option will only be looked at in case + // other option + // "3d"==true + options.set( "unique_pole", true ); - const grid::StructuredGrid rg = grid::StructuredGrid(grid); - if( !rg ) - throw eckit::BadCast("Structured can only work with a Structured",Here()); + // This option creates elements that connect east to west at greenwich + // meridian + // when true, instead of creating periodic ghost-points at east boundary when + // false + options.set( "3d", false ); - size_t nb_parts = options.get("nb_parts"); + // This option sets number of parts the mesh will be split in + options.set( "nb_parts", mpi::comm().size() ); - std::string partitioner_type = "trans"; - options.get("partitioner",partitioner_type); + // This option sets the part that will be generated + options.set( "part", mpi::comm().rank() ); - if ( rg.ny()%2 == 1 ) partitioner_type = "equal_regions"; // Odd number of latitudes - if ( nb_parts == 1 || mpi::comm().size() == 1 ) partitioner_type = "equal_regions"; // Only one part --> Trans is slower + // Experimental option. The result is a non-standard Reduced Gaussian Grid, + // with a ragged Greenwich line + options.set( "stagger", false ); - grid::Partitioner partitioner( partitioner_type, nb_parts ); - grid::Distribution distribution( partitioner.partition(grid) ); - generate( grid, distribution, mesh ); + // This option sets the maximum angle deviation for a quadrilateral element + // angle = 30 --> minimises number of triangles + // angle = 0 --> maximises number of triangles + options.set( "angle", 0. ); + + options.set( "triangulate", false ); + + options.set( "ghost_at_end", true ); } -void StructuredMeshGenerator::hash(Hash& h) const -{ - h.add("Structured"); - options.hash(h); +void StructuredMeshGenerator::generate( const Grid& grid, Mesh& mesh ) const { + ASSERT( !mesh.generated() ); + + const grid::StructuredGrid rg = grid::StructuredGrid( grid ); + if ( !rg ) throw eckit::BadCast( "Structured can only work with a Structured", Here() ); + + size_t nb_parts = options.get( "nb_parts" ); + + std::string partitioner_type = "trans"; + options.get( "partitioner", partitioner_type ); + + if ( rg.ny() % 2 == 1 ) partitioner_type = "equal_regions"; // Odd number of latitudes + 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 ) ); + generate( grid, distribution, mesh ); } -void StructuredMeshGenerator::generate(const Grid& grid, const grid::Distribution& distribution, Mesh& mesh ) const -{ - ATLAS_TRACE(); +void StructuredMeshGenerator::hash( Hash& h ) const { + h.add( "Structured" ); + options.hash( h ); +} - const grid::StructuredGrid rg = grid::StructuredGrid(grid); - if( !rg ) - throw eckit::BadCast("Grid could not be cast to a Structured",Here()); +void StructuredMeshGenerator::generate( const Grid& grid, const grid::Distribution& distribution, Mesh& mesh ) const { + ATLAS_TRACE(); - ASSERT(!mesh.generated()); + const grid::StructuredGrid rg = grid::StructuredGrid( grid ); + if ( !rg ) throw eckit::BadCast( "Grid could not be cast to a Structured", Here() ); - if( grid.size() != distribution.partition().size() ) - { - std::stringstream msg; - msg << "Number of points in grid ("<("part"); + if ( grid.size() != distribution.partition().size() ) { + std::stringstream msg; + msg << "Number of points in grid (" << grid.size() + << ") different from " + "number of points in grid distribution (" + << distribution.partition().size() << ")"; + throw eckit::AssertionFailed( msg.str(), Here() ); + } + int mypart = options.get( "part" ); - // show distribution +// show distribution #if DEBUG_OUTPUT - int inode=0; - std::vector parts=distribution; + int inode = 0; + std::vector parts = distribution; Log::info() << "Partition : " << std::endl; - for (size_t ilat=0; ilat& parts, int mypart, Region& region) const -{ - ATLAS_TRACE(); - - double max_angle = options.get("angle"); - bool triangulate_quads = options.get("triangulate"); - bool three_dimensional = options.get("3d"); - bool has_north_pole = rg.y().front() == 90; - bool has_south_pole = rg.y().back() == -90; - bool unique_pole = options.get("unique_pole") && three_dimensional && has_north_pole && has_south_pole; - bool periodic_east_west = rg.periodic(); - - - int n; - /* - Find min and max latitudes used by this part. - */ - n=0; - int lat_north=-1; - for(size_t jlat = 0; jlat < rg.ny(); ++jlat) { - for(size_t jlon = 0; jlon < rg.nx(jlat); ++jlon) { - if( parts.at(n) == mypart ) { - lat_north=jlat; - goto end_north; - } - ++n; +void StructuredMeshGenerator::generate_region( const grid::StructuredGrid& rg, const std::vector& parts, + int mypart, Region& region ) const { + ATLAS_TRACE(); + + double max_angle = options.get( "angle" ); + bool triangulate_quads = options.get( "triangulate" ); + bool three_dimensional = options.get( "3d" ); + bool has_north_pole = rg.y().front() == 90; + bool has_south_pole = rg.y().back() == -90; + bool unique_pole = options.get( "unique_pole" ) && three_dimensional && has_north_pole && has_south_pole; + bool periodic_east_west = rg.periodic(); + + int n; + /* +Find min and max latitudes used by this part. +*/ + n = 0; + int lat_north = -1; + for ( size_t jlat = 0; jlat < rg.ny(); ++jlat ) { + for ( size_t jlon = 0; jlon < rg.nx( jlat ); ++jlon ) { + if ( parts.at( n ) == mypart ) { + lat_north = jlat; + goto end_north; + } + ++n; + } } - } end_north: - - n=rg.size()-1; - int lat_south=-1; - for( int jlat=rg.ny()-1; jlat>=0; --jlat) { - for( int jlon=rg.nx(jlat)-1; jlon>=0; --jlon) { - if( parts.at(n) == mypart ) { - lat_south=jlat; - goto end_south; - } - --n; +end_north: + + n = rg.size() - 1; + int lat_south = -1; + for ( int jlat = rg.ny() - 1; jlat >= 0; --jlat ) { + for ( int jlon = rg.nx( jlat ) - 1; jlon >= 0; --jlon ) { + if ( parts.at( n ) == mypart ) { + lat_south = jlat; + goto end_south; + } + --n; + } } - } end_south: - - - std::vector offset(rg.ny(),0); - - n=0; - for(size_t jlat = 0; jlat < rg.ny(); ++jlat) - { - offset.at(jlat)=n; - n+=rg.nx(jlat); - }; +end_south: - /* - We need to connect to next region - */ - if( lat_north-1 >=0 && rg.nx(lat_north-1) > 0 ) - --lat_north; - if(size_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); - region.north = lat_north; - region.south = lat_south; + std::vector offset( rg.ny(), 0 ); - array::ArrayShape shape = array::make_shape(region.south-region.north, 4*rg.nxmax(), 4); + n = 0; + for ( size_t jlat = 0; jlat < rg.ny(); ++jlat ) { + offset.at( jlat ) = n; + n += rg.nx( jlat ); + }; - region.elems.reset( array::Array::create(shape) ); + /* +We need to connect to next region +*/ + if ( lat_north - 1 >= 0 && rg.nx( lat_north - 1 ) > 0 ) --lat_north; + if ( size_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 ); + region.north = lat_north; + region.south = lat_south; - int nelems=0; - region.nquads=0; - region.ntriags=0; + array::ArrayShape shape = array::make_shape( region.south - region.north, 4 * rg.nxmax(), 4 ); - array::ArrayView elemview = array::make_view(*region.elems); - elemview.assign(-1); + region.elems.reset( array::Array::create( shape ) ); - bool stagger = options.get("stagger"); - for (int jlat=lat_north; jlat elemview = array::make_view( *region.elems ); + elemview.assign( -1 ); - ilat = jlat-region.north; + bool stagger = options.get( "stagger" ); + for ( int jlat = lat_north; jlat < lat_south; ++jlat ) { + // std::stringstream filename; filename << "/tmp/debug/"<(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"; + Log::info() << "-------\n"; #endif - // Log::info() << " access " << region.elems.stride(0)*(jlat-region.north) + region.elems.stride(1)*jelem + 5 << std::endl; -// Log::info() << ipN1 << "("<< xN1 << ") " << ipN2 << "("<< xN2 << ") " << std::endl; -// Log::info() << ipS1 << "("<< xS1 << ") " << ipS2 << "("<< xS2 << ") " << std::endl; - try_make_triangle_up = false; - try_make_triangle_down = false; - try_make_quad = false; - - -// ------------------------------------------------ -// START RULES -// ------------------------------------------------ - - const double dxN = std::abs(xN2-xN1); - const double dxS = std::abs(xS2-xS1); - const double dx = std::min(dxN,dxS); - const double alpha1 = ( dx==0. ? 0. : std::atan2((xN1-xS1),dx) * to_deg ); - const double alpha2 = ( dx==0. ? 0. : std::atan2((xN2-xS2),dx) * to_deg ); - if( std::abs(alpha1) <= max_angle && std::abs(alpha2) <= max_angle ) - { - if( triangulate_quads ) - { - if( false ) //std::abs(alpha1) < 1 && std::abs(alpha2) < 1) - { - try_make_triangle_up = (jlat+ipN1) % 2; - try_make_triangle_down = (jlat+ipN1+1) % 2; - } - else - { - dN1S2 = std::abs(xN1-xS2); - dS1N2 = std::abs(xS1-xN2); - // dN2S2 = std::abs(xN2-xS2); - // Log::info() << " dN1S2 " << dN1S2 << " dS1N2 " << dS1N2 << " dN2S2 " << dN2S2 << std::endl; - if (dN1S2 == dS1N2) - { - try_make_triangle_up = (jlat+ipN1) % 2; - try_make_triangle_down = (jlat+ipN1+1) % 2; - } - else if (dN1S2 < dS1N2) - { - 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;} - else { try_make_triangle_up = true; } + // Log::info() << " access " << + // region.elems.stride(0)*(jlat-region.north) + + // region.elems.stride(1)*jelem + 5 << std::endl; + // Log::info() << ipN1 << "("<< xN1 << ") " << ipN2 << "("<< xN2 + // << ") " << std::endl; + // Log::info() << ipS1 << "("<< xS1 << ") " << ipS2 << "("<< xS2 + // << ") " << std::endl; + try_make_triangle_up = false; + try_make_triangle_down = false; + try_make_quad = false; + + // ------------------------------------------------ + // START RULES + // ------------------------------------------------ + + const double dxN = std::abs( xN2 - xN1 ); + const double dxS = std::abs( xS2 - xS1 ); + const double dx = std::min( dxN, dxS ); + const double alpha1 = ( dx == 0. ? 0. : std::atan2( ( xN1 - xS1 ), dx ) * to_deg ); + const double alpha2 = ( dx == 0. ? 0. : std::atan2( ( xN2 - xS2 ), dx ) * to_deg ); + if ( std::abs( alpha1 ) <= max_angle && std::abs( alpha2 ) <= max_angle ) { + if ( triangulate_quads ) { + if ( false ) // std::abs(alpha1) < 1 && std::abs(alpha2) < 1) + { + try_make_triangle_up = ( jlat + ipN1 ) % 2; + try_make_triangle_down = ( jlat + ipN1 + 1 ) % 2; + } + else { + dN1S2 = std::abs( xN1 - xS2 ); + dS1N2 = std::abs( xS1 - xN2 ); + // dN2S2 = std::abs(xN2-xS2); + // Log::info() << " dN1S2 " << dN1S2 << " dS1N2 " << dS1N2 << " + // dN2S2 " << dN2S2 << std::endl; + if ( dN1S2 == dS1N2 ) { + try_make_triangle_up = ( jlat + ipN1 ) % 2; + try_make_triangle_down = ( jlat + ipN1 + 1 ) % 2; + } + else if ( dN1S2 < dS1N2 ) { + 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; } + else { + try_make_triangle_up = true; + } + } + else { + throw eckit::Exception( "Should not be here", Here() ); + } + } + } + else { + if ( ipN1 == ipN2 ) + try_make_triangle_up = true; + else if ( ipS1 == ipS2 ) + try_make_triangle_down = true; + else + try_make_quad = true; + + // try_make_quad = true; + } } - else - { - throw eckit::Exception("Should not be here", Here()); + else { + dN1S2 = std::abs( xN1 - xS2 ); + dS1N2 = std::abs( xS1 - xN2 ); + // 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; } + else if ( ( dN1S2 >= dS1N2 ) && ( ipN1 != ipN2 ) ) { + try_make_triangle_down = true; + } + else + throw Exception( "Should not try to make a quadrilateral!", Here() ); } - } - - } - else - { - if ( ipN1 == ipN2 ) try_make_triangle_up = true; - else if( ipS1 == ipS2 ) try_make_triangle_down = true; - else try_make_quad = true; - -// try_make_quad = true; - } - } - else - { - dN1S2 = std::abs(xN1-xS2); - dS1N2 = std::abs(xS1-xN2); - // 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;} - else if( (dN1S2 >= dS1N2) && (ipN1 != ipN2) ) { try_make_triangle_down = true;} - else throw Exception("Should not try to make a quadrilateral!",Here()); - } -// ------------------------------------------------ -// END RULES -// ------------------------------------------------ - + // ------------------------------------------------ + // END RULES + // ------------------------------------------------ #if DEBUG_OUTPUT - ATLAS_DEBUG_VAR(jelem); + ATLAS_DEBUG_VAR( jelem ); #endif - auto elem = lat_elems_view.slice(jelem,Range::all()); + auto elem = lat_elems_view.slice( jelem, Range::all() ); - if( try_make_quad ) - { - // add quadrilateral + if ( try_make_quad ) { +// add quadrilateral #if DEBUG_OUTPUT - Log::info() << " " << ipN1 << " " << ipN2 << '\n'; - Log::info() << " " << ipS1 << " " << ipS2 << '\n'; + Log::info() << " " << ipN1 << " " << ipN2 << '\n'; + Log::info() << " " << ipS1 << " " << ipS2 << '\n'; #endif - elem(0) = ipN1; - elem(1) = ipS1; - elem(2) = ipS2; - elem(3) = ipN2; - add_quad = false; - std::array np {pN1, pN2, pS1, pS2}; - std::array pcnts; - 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 ) pE = pS1; - } else if ( pcnts[2] > 2 ) { // 3 or more of pS1 - pE = pS1; - if( latN == 0 ) pE = pN1; - } - else { - std::array::iterator p_max = std::max_element(pcnts.begin(),pcnts.end()); - if( *p_max > 2 ) { // 3 or 4 points belong to same part - pE = np[ std::distance(np.begin(),p_max) ]; - } - else { // 3 or 4 points don't belong to mypart - pE = pN1; - if( latS == rg.ny()-1 ) pE = pS1; - } - } - add_quad = ( pE == mypart ); - if (add_quad) - { - ++region.nquads; - ++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; - 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); - region.lat_end.at(latS) = std::max(region.lat_end.at(latS), ipS2); - } - else - { + elem( 0 ) = ipN1; + elem( 1 ) = ipS1; + elem( 2 ) = ipS2; + elem( 3 ) = ipN2; + add_quad = false; + std::array np{pN1, pN2, pS1, pS2}; + std::array pcnts; + 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 ) pE = pS1; + } + else if ( pcnts[2] > 2 ) { // 3 or more of pS1 + pE = pS1; + if ( latN == 0 ) pE = pN1; + } + else { + std::array::iterator p_max = std::max_element( pcnts.begin(), pcnts.end() ); + if ( *p_max > 2 ) { // 3 or 4 points belong to same part + pE = np[std::distance( np.begin(), p_max )]; + } + else { // 3 or 4 points don't belong to mypart + pE = pN1; + if ( latS == rg.ny() - 1 ) pE = pS1; + } + } + add_quad = ( pE == mypart ); + if ( add_quad ) { + ++region.nquads; + ++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; + 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 ); + region.lat_end.at( latS ) = std::max( region.lat_end.at( latS ), ipS2 ); + } + else { #if DEBUG_OUTPUT - Log::info() << "Quad belongs to other partition" << std::endl; + Log::info() << "Quad belongs to other partition" << std::endl; #endif - } - ipN1=ipN2; - ipS1=ipS2; - } - else if( try_make_triangle_down ) // make triangle down - { - // triangle without ip3 + } + ipN1 = ipN2; + ipS1 = ipS2; + } + else if ( try_make_triangle_down ) // make triangle down + { +// triangle without ip3 #if DEBUG_OUTPUT - Log::info() << " " << ipN1 << " " << ipN2 << '\n'; - Log::info() << " " << ipS1 << '\n'; + Log::info() << " " << ipN1 << " " << ipN2 << '\n'; + Log::info() << " " << ipS1 << '\n'; #endif - elem(0) = ipN1; - elem(1) = ipS1; - elem(2) = -1; - elem(3) = ipN2; - - pE = pN1; - if( latS == rg.ny()-1 ) pE = pS1; - add_triag = (mypart == pE); - - if (add_triag) - { - ++region.ntriags; - ++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; - 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); - region.lat_end.at(latS) = std::max(region.lat_end.at(latS), ipS1); - } - else - { + elem( 0 ) = ipN1; + elem( 1 ) = ipS1; + elem( 2 ) = -1; + elem( 3 ) = ipN2; + + pE = pN1; + if ( latS == rg.ny() - 1 ) pE = pS1; + add_triag = ( mypart == pE ); + + if ( add_triag ) { + ++region.ntriags; + ++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; + 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 ); + region.lat_end.at( latS ) = std::max( region.lat_end.at( latS ), ipS1 ); + } + else { #if DEBUG_OUTPUT - Log::info() << "Downward Triag belongs to other partition" << std::endl; + Log::info() << "Downward Triag belongs to other partition" << std::endl; #endif - } - ipN1=ipN2; - // and ipS1=ipS1; - - } - else if( try_make_triangle_up ) // make triangle up - { - // triangle without ip4 + } + ipN1 = ipN2; + // and ipS1=ipS1; + } + else if ( try_make_triangle_up ) // make triangle up + { +// triangle without ip4 #if DEBUG_OUTPUT - Log::info() << " " << ipN1 << " ("<(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); - region.lat_end.at(latS) = std::max(region.lat_end.at(latS), ipS2); - } - else - { + elem( 0 ) = ipN1; + elem( 1 ) = ipS1; + elem( 2 ) = ipS2; + elem( 3 ) = -1; + + if ( pS1 == pE && pN1 != pE ) { + 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; + + add_triag = ( mypart == pE ); + + if ( add_triag ) { + ++region.ntriags; + ++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; + 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 ); + region.lat_end.at( latS ) = std::max( region.lat_end.at( latS ), ipS2 ); + } + else { #if DEBUG_OUTPUT - Log::info() << "Upward Triag belongs to other partition" << std::endl; + Log::info() << "Upward Triag belongs to other partition" << std::endl; #endif + } + ipS1 = ipS2; + // and ipN1=ipN1; + } + else { + throw eckit::SeriousBug( "Could not detect which element to create", Here() ); + } + ipN2 = std::min( endN, ipN1 + 1 ); + ipS2 = std::min( endS, ipS1 + 1 ); } - ipS1=ipS2; - // and ipN1=ipN1; - - } - else - { - throw eckit::SeriousBug("Could not detect which element to create", Here()); - } - ipN2 = std::min(endN,ipN1+1); - ipS2 = std::min(endS,ipS1+1); - } - region.nb_lat_elems.at(jlat) = jelem; + region.nb_lat_elems.at( jlat ) = jelem; #if DEBUG_OUTPUT - ATLAS_DEBUG_VAR(region.nb_lat_elems.at(jlat)); + ATLAS_DEBUG_VAR( region.nb_lat_elems.at( jlat ) ); #endif - if( region.nb_lat_elems.at(jlat) == 0 && latN == size_t(region.north) ) { - ++region.north; - } - if( region.nb_lat_elems.at(jlat) == 0 && latS == size_t(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( region.nb_lat_elems.at(jlat) > 0 ) - { - region.lat_end.at(latN) = std::max(region.lat_end.at(latN), region.lat_begin.at(latN)); - region.lat_end.at(latS) = std::max(region.lat_end.at(latS), region.lat_begin.at(latS)); - } - } // for jlat - -// Log::info() << "nb_triags = " << region.ntriags << std::endl; -// Log::info() << "nb_quads = " << region.nquads << std::endl; -// Log::info() << "nb_elems = " << nelems << std::endl; - - int nb_region_nodes = 0; - for(int jlat = region.north; jlat <= region.south; ++jlat) { - n = offset.at(jlat); - region.lat_begin.at(jlat) = std::max( 0, region.lat_begin.at(jlat) ); - for(size_t jlon = 0; jlon < rg.nx(jlat); ++jlon) { - if( parts.at(n) == mypart ) { - region.lat_begin.at(jlat) = std::min( region.lat_begin.at(jlat), int(jlon) ); - region.lat_end. at(jlat) = std::max( region.lat_end .at(jlat), int(jlon) ); - } - ++n; - } - nb_region_nodes += region.lat_end.at(jlat)-region.lat_begin.at(jlat)+1; + if ( region.nb_lat_elems.at( jlat ) == 0 && latN == size_t( region.north ) ) { ++region.north; } + if ( region.nb_lat_elems.at( jlat ) == 0 && latS == size_t( 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 ( region.nb_lat_elems.at( jlat ) > 0 ) { + region.lat_end.at( latN ) = std::max( region.lat_end.at( latN ), region.lat_begin.at( latN ) ); + region.lat_end.at( latS ) = std::max( region.lat_end.at( latS ), region.lat_begin.at( latS ) ); + } + } // for jlat + + // Log::info() << "nb_triags = " << region.ntriags << std::endl; + // Log::info() << "nb_quads = " << region.nquads << std::endl; + // Log::info() << "nb_elems = " << nelems << std::endl; + + int nb_region_nodes = 0; + for ( int jlat = region.north; jlat <= region.south; ++jlat ) { + n = offset.at( jlat ); + region.lat_begin.at( jlat ) = std::max( 0, region.lat_begin.at( jlat ) ); + for ( size_t jlon = 0; jlon < rg.nx( jlat ); ++jlon ) { + if ( parts.at( n ) == mypart ) { + region.lat_begin.at( jlat ) = std::min( region.lat_begin.at( jlat ), int( jlon ) ); + region.lat_end.at( jlat ) = std::max( region.lat_end.at( jlat ), int( jlon ) ); + } + ++n; + } + nb_region_nodes += region.lat_end.at( jlat ) - region.lat_begin.at( jlat ) + 1; - // Count extra periodic node - //if( periodic_east_west && size_t(region.lat_end.at(jlat)) == rg.nx(jlat) - 1) ++nb_region_nodes; - } + // Count extra periodic node + // if( periodic_east_west && size_t(region.lat_end.at(jlat)) == rg.nx(jlat) + // - 1) ++nb_region_nodes; + } - region.nnodes = nb_region_nodes; - if (region.nnodes == 0) - { - throw Exception("Trying to generate mesh with too many partitions. Reduce the number of partitions.",Here()); - } + region.nnodes = nb_region_nodes; + if ( region.nnodes == 0 ) { + throw Exception( + "Trying to generate mesh with too many partitions. Reduce " + "the number of partitions.", + Here() ); + } #if DEBUG_OUTPUT - ATLAS_DEBUG("End of generate_region()"); + ATLAS_DEBUG( "End of generate_region()" ); #endif } - namespace { struct GhostNode { - GhostNode(int _jlat, int _jlon, int _jnode) { jlat = _jlat; jlon=_jlon; jnode=_jnode; } - int jlat; - int jlon; - int jnode; + GhostNode( int _jlat, int _jlon, int _jnode ) { + jlat = _jlat; + jlon = _jlon; + jnode = _jnode; + } + int jlat; + int jlon; + int jnode; }; -} +} // namespace -void StructuredMeshGenerator::generate_mesh(const grid::StructuredGrid& rg, const std::vector& parts, const Region& region, Mesh& mesh) const -{ - ATLAS_TRACE(); - - ASSERT(!mesh.generated()); - - int mypart = options.get("part"); - int nparts = options.get("nb_parts"); - int n, l; - - bool has_point_at_north_pole = rg.y().front() == 90 && rg.nx().front() > 0; - bool has_point_at_south_pole = rg.y().back() == -90 && rg.nx().back() > 0; - bool three_dimensional = options.get("3d"); - bool periodic_east_west = rg.periodic(); - bool include_periodic_ghost_points = periodic_east_west && !three_dimensional; - bool remove_periodic_ghost_points = periodic_east_west && three_dimensional; - - bool include_north_pole = (mypart == 0 ) - && options.get("include_pole") - && !has_point_at_north_pole - && rg.domain().containsNorthPole(); - - bool include_south_pole = (mypart == nparts-1) - && options.get("include_pole") - && !has_point_at_south_pole - && rg.domain().containsSouthPole(); - - bool patch_north_pole = (mypart == 0) - && options.get("patch_pole") - && !has_point_at_north_pole - && rg.domain().containsNorthPole() - && rg.nx(1) > 0; - - bool patch_south_pole = (mypart == nparts-1) - && options.get("patch_pole") - && !has_point_at_south_pole - && rg.domain().containsSouthPole() - && rg.nx(rg.ny()-2) > 0; - - if( three_dimensional && nparts != 1 ) - throw BadParameter("Cannot generate three_dimensional mesh in parallel",Here()); - int nnodes = region.nnodes; - int ntriags = region.ntriags; - int nquads = region.nquads; - - if (include_north_pole) { - ++nnodes; - ntriags += rg.nx(0) - (periodic_east_west ? 0 : 1); - } - else if (patch_north_pole) { - ntriags += rg.nx(0)-2; - } - if (include_south_pole) { - ++nnodes; - ntriags += rg.nx(rg.ny()-1) - (periodic_east_west ? 0 : 1); - } - else if (patch_south_pole) { - ntriags += rg.nx(rg.ny()-1)-2; - } - - size_t node_numbering_size = nnodes; - if ( remove_periodic_ghost_points ) { - for(size_t jlat = 0; jlat < rg.ny(); ++jlat) - { - if( region.lat_end[jlat] >= rg.nx(jlat) ) - --nnodes; +void StructuredMeshGenerator::generate_mesh( const grid::StructuredGrid& rg, const std::vector& parts, + const Region& region, Mesh& mesh ) const { + ATLAS_TRACE(); + + ASSERT( !mesh.generated() ); + + int mypart = options.get( "part" ); + int nparts = options.get( "nb_parts" ); + int n, l; + + bool has_point_at_north_pole = rg.y().front() == 90 && rg.nx().front() > 0; + bool has_point_at_south_pole = rg.y().back() == -90 && rg.nx().back() > 0; + bool three_dimensional = options.get( "3d" ); + bool periodic_east_west = rg.periodic(); + bool include_periodic_ghost_points = periodic_east_west && !three_dimensional; + bool remove_periodic_ghost_points = periodic_east_west && three_dimensional; + + bool include_north_pole = ( mypart == 0 ) && options.get( "include_pole" ) && !has_point_at_north_pole && + rg.domain().containsNorthPole(); + + bool include_south_pole = ( mypart == nparts - 1 ) && options.get( "include_pole" ) && + !has_point_at_south_pole && rg.domain().containsSouthPole(); + + bool patch_north_pole = ( mypart == 0 ) && options.get( "patch_pole" ) && !has_point_at_north_pole && + rg.domain().containsNorthPole() && rg.nx( 1 ) > 0; + + bool patch_south_pole = ( mypart == nparts - 1 ) && options.get( "patch_pole" ) && !has_point_at_south_pole && + rg.domain().containsSouthPole() && rg.nx( rg.ny() - 2 ) > 0; + + if ( three_dimensional && nparts != 1 ) + throw BadParameter( "Cannot generate three_dimensional mesh in parallel", Here() ); + int nnodes = region.nnodes; + int ntriags = region.ntriags; + int nquads = region.nquads; + + if ( include_north_pole ) { + ++nnodes; + ntriags += rg.nx( 0 ) - ( periodic_east_west ? 0 : 1 ); + } + else if ( patch_north_pole ) { + ntriags += rg.nx( 0 ) - 2; + } + if ( include_south_pole ) { + ++nnodes; + ntriags += rg.nx( rg.ny() - 1 ) - ( periodic_east_west ? 0 : 1 ); + } + else if ( patch_south_pole ) { + ntriags += rg.nx( rg.ny() - 1 ) - 2; + } + + size_t node_numbering_size = nnodes; + if ( remove_periodic_ghost_points ) { + for ( size_t jlat = 0; jlat < rg.ny(); ++jlat ) { + if ( region.lat_end[jlat] >= rg.nx( jlat ) ) --nnodes; + } } - } #if DEBUG_OUTPUT - ATLAS_DEBUG_VAR(include_periodic_ghost_points); - ATLAS_DEBUG_VAR(include_north_pole); - ATLAS_DEBUG_VAR(include_south_pole); - ATLAS_DEBUG_VAR(three_dimensional); - ATLAS_DEBUG_VAR(patch_north_pole); - ATLAS_DEBUG_VAR(patch_south_pole); - ATLAS_DEBUG_VAR(rg.size()); - ATLAS_DEBUG_VAR(nnodes); - ATLAS_DEBUG_VAR(ntriags); - ATLAS_DEBUG_VAR(nquads); - ATLAS_DEBUG_VAR(options.get("ghost_at_end")); + ATLAS_DEBUG_VAR( include_periodic_ghost_points ); + ATLAS_DEBUG_VAR( include_north_pole ); + ATLAS_DEBUG_VAR( include_south_pole ); + ATLAS_DEBUG_VAR( three_dimensional ); + ATLAS_DEBUG_VAR( patch_north_pole ); + ATLAS_DEBUG_VAR( patch_south_pole ); + ATLAS_DEBUG_VAR( rg.size() ); + ATLAS_DEBUG_VAR( nnodes ); + ATLAS_DEBUG_VAR( ntriags ); + ATLAS_DEBUG_VAR( nquads ); + ATLAS_DEBUG_VAR( options.get( "ghost_at_end" ) ); #endif + std::vector offset_glb( rg.ny() ); + std::vector offset_loc( region.south - region.north + 1, 0 ); - std::vector offset_glb(rg.ny()); - std::vector offset_loc(region.south-region.north+1,0); - - n=0; - for(size_t jlat = 0; jlat < rg.ny(); ++jlat) - { - offset_glb.at(jlat)=n; - n+=rg.nx(jlat); - }; + n = 0; + for ( size_t jlat = 0; jlat < rg.ny(); ++jlat ) { + offset_glb.at( jlat ) = n; + n += rg.nx( jlat ); + }; - std::vector periodic_glb(rg.ny()); + std::vector periodic_glb( rg.ny() ); - if( include_periodic_ghost_points ) - { - for(size_t jlat = 0; jlat < rg.ny(); ++jlat) - { - if( rg.nx(jlat) > 0 ) - { - periodic_glb.at(jlat) = n; - ++n; - } + if ( include_periodic_ghost_points ) { + for ( size_t jlat = 0; jlat < rg.ny(); ++jlat ) { + if ( rg.nx( jlat ) > 0 ) { + periodic_glb.at( jlat ) = n; + ++n; + } + } } - } - else - { - for(size_t jlat = 0; jlat < rg.ny(); ++jlat) - { - if( rg.nx(jlat) > 0 ) - { - periodic_glb.at(jlat) = offset_glb.at(jlat) + rg.nx(jlat)-1; - } + else { + for ( size_t jlat = 0; jlat < rg.ny(); ++jlat ) { + if ( rg.nx( jlat ) > 0 ) { periodic_glb.at( jlat ) = offset_glb.at( jlat ) + rg.nx( jlat ) - 1; } + } } - } - int max_glb_idx = n; - - - mesh.nodes().resize(nnodes); - mesh::Nodes& nodes = mesh.nodes(); - - array::ArrayView xy = array::make_view( nodes.xy() ); - array::ArrayView lonlat = array::make_view( nodes.lonlat() ); - array::ArrayView glb_idx = array::make_view( nodes.global_index() ); - array::ArrayView part = array::make_view( nodes.partition() ); - array::ArrayView ghost = array::make_view( nodes.ghost() ); - array::ArrayView flags = array::make_view( nodes.field("flags") ); - - bool stagger = options.get("stagger"); - - std::vector node_numbering(node_numbering_size,-1); - if( options.get("ghost_at_end") ) - { - std::vector< GhostNode > ghost_nodes; - ghost_nodes.reserve( nnodes ); - int node_number=0; - int jnode=0; - l=0; - ASSERT( region.south >= region.north ); - for( int jlat = region.north; jlat <= region.south; ++jlat ) - { - int ilat=jlat-region.north; - offset_loc.at(ilat)=l; - l+=region.lat_end.at(jlat)-region.lat_begin.at(jlat)+1; - - - if( region.lat_end.at(jlat) < region.lat_begin.at(jlat) ) - { - ATLAS_DEBUG_VAR(jlat); - ATLAS_DEBUG_VAR(region.lat_begin[jlat]); - ATLAS_DEBUG_VAR(region.lat_end[jlat]); - } - for( int jlon=region.lat_begin.at(jlat); jlon<=region.lat_end.at(jlat); ++jlon ) - { - if( jlon < rg.nx(jlat) ) { - n = offset_glb.at(jlat) + jlon; - if( parts.at(n) == mypart ) { - node_numbering.at(jnode) = node_number; + int max_glb_idx = n; + + mesh.nodes().resize( nnodes ); + mesh::Nodes& nodes = mesh.nodes(); + + array::ArrayView xy = array::make_view( nodes.xy() ); + array::ArrayView lonlat = array::make_view( nodes.lonlat() ); + array::ArrayView glb_idx = array::make_view( nodes.global_index() ); + array::ArrayView part = array::make_view( nodes.partition() ); + array::ArrayView ghost = array::make_view( nodes.ghost() ); + array::ArrayView flags = array::make_view( nodes.field( "flags" ) ); + + bool stagger = options.get( "stagger" ); + + std::vector node_numbering( node_numbering_size, -1 ); + if ( options.get( "ghost_at_end" ) ) { + std::vector ghost_nodes; + ghost_nodes.reserve( nnodes ); + int node_number = 0; + int jnode = 0; + l = 0; + ASSERT( region.south >= region.north ); + for ( int jlat = region.north; jlat <= region.south; ++jlat ) { + int ilat = jlat - region.north; + offset_loc.at( ilat ) = l; + l += region.lat_end.at( jlat ) - region.lat_begin.at( jlat ) + 1; + + if ( region.lat_end.at( jlat ) < region.lat_begin.at( jlat ) ) { + ATLAS_DEBUG_VAR( jlat ); + ATLAS_DEBUG_VAR( region.lat_begin[jlat] ); + ATLAS_DEBUG_VAR( region.lat_end[jlat] ); + } + for ( int jlon = region.lat_begin.at( jlat ); jlon <= region.lat_end.at( jlat ); ++jlon ) { + if ( jlon < rg.nx( jlat ) ) { + n = offset_glb.at( jlat ) + jlon; + if ( parts.at( n ) == mypart ) { + node_numbering.at( jnode ) = node_number; + ++node_number; + } + else { + ghost_nodes.push_back( GhostNode( jlat, jlon, jnode ) ); + } + ++jnode; + } + else if ( include_periodic_ghost_points ) // add periodic point + { +#warning TODO: use second approach + part( jnode ) = mypart; + // part(jnode) = parts.at( offset_glb.at(jlat) ); + ghost( jnode ) = 1; + ghost_nodes.push_back( GhostNode( jlat, rg.nx( jlat ), jnode ) ); + ++jnode; + } + else { + --l; + } + } + } + for ( size_t jghost = 0; jghost < ghost_nodes.size(); ++jghost ) { + node_numbering.at( ghost_nodes.at( jghost ).jnode ) = node_number; ++node_number; - } - else { - ghost_nodes.push_back( GhostNode(jlat,jlon,jnode)); - } - ++jnode; } - else if ( include_periodic_ghost_points ) // add periodic point - { -#warning TODO: use second approach - part(jnode) = mypart; - //part(jnode) = parts.at( offset_glb.at(jlat) ); - ghost(jnode) = 1; - ghost_nodes.push_back( GhostNode(jlat,rg.nx(jlat),jnode) ); - ++jnode; - } else { - --l; + if ( include_north_pole ) { + node_numbering.at( jnode ) = jnode; + ++jnode; } - } - } - for( size_t jghost=0; jghost cells_glb_idx = array::make_view( mesh.cells().global_index() ); - array::ArrayView cells_part = array::make_view( mesh.cells().partition() ); - array::ArrayView cells_patch = array::make_view( mesh.cells().field("patch") ); - - /* - * label all patch cells a non-patch - */ - cells_patch.assign(0); - - /* - Fill in connectivity tables with global node indices first - */ - int jcell; - int jquad=0; - int jtriag=0; - int quad_begin = mesh.cells().elements(0).begin(); - int triag_begin = mesh.cells().elements(1).begin(); - int quad_nodes[4]; - int triag_nodes[3]; - - for (int jlat=region.north; jlat(*region.elems).slice(ilat,jelem,Range::all()); - - if(elem(2)>=0 && elem(3)>=0) // This is a quad - { - quad_nodes[0] = node_numbering.at( offset_loc.at(ilatN) + elem(0) - region.lat_begin.at(jlatN) ); - quad_nodes[1] = node_numbering.at( offset_loc.at(ilatS) + elem(1) - region.lat_begin.at(jlatS) ); - quad_nodes[2] = node_numbering.at( offset_loc.at(ilatS) + elem(2) - region.lat_begin.at(jlatS) ); - quad_nodes[3] = node_numbering.at( offset_loc.at(ilatN) + elem(3) - region.lat_begin.at(jlatN) ); - - if( three_dimensional && periodic_east_west ) - { - if (size_t(elem(2)) == rg.nx(jlatS)) quad_nodes[2] = node_numbering.at( offset_loc.at(ilatS) ); - if (size_t(elem(3)) == rg.nx(jlatN)) quad_nodes[3] = node_numbering.at( offset_loc.at(ilatN) ); - } - jcell = quad_begin + jquad++; - node_connectivity.set( jcell, quad_nodes ); - cells_glb_idx(jcell) = jcell+1; - cells_part(jcell) = mypart; - cells_patch(jcell) = 0; - } - else // This is a triag - { - if(elem(3)<0) // This is a triangle pointing up - { - triag_nodes[0] = node_numbering.at( offset_loc.at(ilatN) + elem(0) - region.lat_begin.at(jlatN) ); - triag_nodes[1] = node_numbering.at( offset_loc.at(ilatS) + elem(1) - region.lat_begin.at(jlatS) ); - triag_nodes[2] = node_numbering.at( offset_loc.at(ilatS) + elem(2) - region.lat_begin.at(jlatS) ); - if( three_dimensional && periodic_east_west ) - { - if (size_t(elem(0)) == rg.nx(jlatN)) triag_nodes[0] = node_numbering.at( offset_loc.at(ilatN) ); - if (size_t(elem(2)) == rg.nx(jlatS)) triag_nodes[2] = node_numbering.at( offset_loc.at(ilatS) ); - } - } - else // This is a triangle pointing down - { - triag_nodes[0] = node_numbering.at( offset_loc.at(ilatN) + elem(0) - region.lat_begin.at(jlatN) ); - triag_nodes[1] = node_numbering.at( offset_loc.at(ilatS) + elem(1) - region.lat_begin.at(jlatS) ); - triag_nodes[2] = node_numbering.at( offset_loc.at(ilatN) + elem(3) - region.lat_begin.at(jlatN) ); - if( three_dimensional && periodic_east_west ) - { - if (size_t(elem(1)) == rg.nx(jlatS)) triag_nodes[1] = node_numbering.at( offset_loc.at(ilatS) ); - if (size_t(elem(3)) == rg.nx(jlatN)) triag_nodes[2] = node_numbering.at( offset_loc.at(ilatN) ); - } + nodes.global_index().metadata().set( "human_readable", true ); + nodes.global_index().metadata().set( "min", 1 ); + nodes.global_index().metadata().set( "max", max_glb_idx ); + + // Now handle elements + // ------------------- + + mesh.cells().add( new mesh::temporary::Quadrilateral(), nquads ); + mesh.cells().add( new mesh::temporary::Triangle(), ntriags ); + + mesh::HybridElements::Connectivity& node_connectivity = mesh.cells().node_connectivity(); + array::ArrayView cells_glb_idx = array::make_view( mesh.cells().global_index() ); + array::ArrayView cells_part = array::make_view( mesh.cells().partition() ); + array::ArrayView cells_patch = array::make_view( mesh.cells().field( "patch" ) ); + + /* + * label all patch cells a non-patch + */ + cells_patch.assign( 0 ); + + /* +Fill in connectivity tables with global node indices first +*/ + int jcell; + int jquad = 0; + int jtriag = 0; + int quad_begin = mesh.cells().elements( 0 ).begin(); + int triag_begin = mesh.cells().elements( 1 ).begin(); + int quad_nodes[4]; + int triag_nodes[3]; + + for ( int jlat = region.north; jlat < region.south; ++jlat ) { + int ilat = jlat - region.north; + int jlatN = jlat; + int jlatS = jlat + 1; + int ilatN = ilat; + int ilatS = ilat + 1; + for ( int jelem = 0; jelem < region.nb_lat_elems.at( jlat ); ++jelem ) { + const auto elem = array::make_view( *region.elems ).slice( ilat, jelem, Range::all() ); + + if ( elem( 2 ) >= 0 && elem( 3 ) >= 0 ) // This is a quad + { + quad_nodes[0] = node_numbering.at( offset_loc.at( ilatN ) + elem( 0 ) - region.lat_begin.at( jlatN ) ); + quad_nodes[1] = node_numbering.at( offset_loc.at( ilatS ) + elem( 1 ) - region.lat_begin.at( jlatS ) ); + quad_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) + elem( 2 ) - region.lat_begin.at( jlatS ) ); + quad_nodes[3] = node_numbering.at( offset_loc.at( ilatN ) + elem( 3 ) - region.lat_begin.at( jlatN ) ); + + if ( three_dimensional && periodic_east_west ) { + if ( size_t( elem( 2 ) ) == rg.nx( jlatS ) ) + quad_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) ); + if ( size_t( elem( 3 ) ) == rg.nx( jlatN ) ) + quad_nodes[3] = node_numbering.at( offset_loc.at( ilatN ) ); + } + + jcell = quad_begin + jquad++; + node_connectivity.set( jcell, quad_nodes ); + cells_glb_idx( jcell ) = jcell + 1; + cells_part( jcell ) = mypart; + cells_patch( jcell ) = 0; + } + else // This is a triag + { + if ( elem( 3 ) < 0 ) // This is a triangle pointing up + { + triag_nodes[0] = + node_numbering.at( offset_loc.at( ilatN ) + elem( 0 ) - region.lat_begin.at( jlatN ) ); + triag_nodes[1] = + node_numbering.at( offset_loc.at( ilatS ) + elem( 1 ) - region.lat_begin.at( jlatS ) ); + triag_nodes[2] = + node_numbering.at( offset_loc.at( ilatS ) + elem( 2 ) - region.lat_begin.at( jlatS ) ); + if ( three_dimensional && periodic_east_west ) { + if ( size_t( elem( 0 ) ) == rg.nx( jlatN ) ) + triag_nodes[0] = node_numbering.at( offset_loc.at( ilatN ) ); + if ( size_t( elem( 2 ) ) == rg.nx( jlatS ) ) + triag_nodes[2] = node_numbering.at( offset_loc.at( ilatS ) ); + } + } + else // This is a triangle pointing down + { + triag_nodes[0] = + node_numbering.at( offset_loc.at( ilatN ) + elem( 0 ) - region.lat_begin.at( jlatN ) ); + triag_nodes[1] = + node_numbering.at( offset_loc.at( ilatS ) + elem( 1 ) - region.lat_begin.at( jlatS ) ); + triag_nodes[2] = + node_numbering.at( offset_loc.at( ilatN ) + elem( 3 ) - region.lat_begin.at( jlatN ) ); + if ( three_dimensional && periodic_east_west ) { + if ( size_t( elem( 1 ) ) == rg.nx( jlatS ) ) + triag_nodes[1] = node_numbering.at( offset_loc.at( ilatS ) ); + if ( size_t( elem( 3 ) ) == rg.nx( jlatN ) ) + triag_nodes[2] = node_numbering.at( offset_loc.at( ilatN ) ); + } + } + jcell = triag_begin + jtriag++; + node_connectivity.set( jcell, triag_nodes ); + cells_glb_idx( jcell ) = jcell + 1; + cells_part( jcell ) = mypart; + cells_patch( jcell ) = 0; + } } - jcell = triag_begin + jtriag++; - node_connectivity.set( jcell, triag_nodes ); - cells_glb_idx(jcell) = jcell+1; - cells_part(jcell) = mypart; - cells_patch(jcell) = 0; - } } - } - - if (include_north_pole) - { - int ilat = 0; - int ip1 = 0; - size_t nlon = rg.nx(0) - (periodic_east_west ? 0 : 1); - for (size_t ip2 = 0; ip2 < nlon; ++ip2) - { - jcell = triag_begin + jtriag++; - size_t ip3 = ip2+1; - 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 ); - node_connectivity.set( jcell, triag_nodes ); - cells_glb_idx(jcell) = jcell+1; - cells_part(jcell) = mypart; - cells_patch(jcell) = 0; + + if ( include_north_pole ) { + int ilat = 0; + int ip1 = 0; + size_t nlon = rg.nx( 0 ) - ( periodic_east_west ? 0 : 1 ); + for ( size_t ip2 = 0; ip2 < nlon; ++ip2 ) { + jcell = triag_begin + jtriag++; + size_t ip3 = ip2 + 1; + 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 ); + node_connectivity.set( jcell, triag_nodes ); + cells_glb_idx( jcell ) = jcell + 1; + cells_part( jcell ) = mypart; + cells_patch( jcell ) = 0; + } } - } - else if (patch_north_pole ) - { - int jlat = 0; - int ilat = 0; - int ip1, ip2, ip3; - - int jforward = 0; - int jbackward = rg.nx(jlat) - 1; - bool forward = true; - - while( true ) - { - if( forward ) - { - ip1 = jforward; - ip2 = jforward+1; - ip3 = jbackward; - } - else - { - ip1 = jforward; - ip2 = jbackward-1; - ip3 = jbackward; - } - - triag_nodes[0] = node_numbering.at( offset_loc.at(ilat) + ip1 ); - triag_nodes[1] = node_numbering.at( offset_loc.at(ilat) + ip2 ); - triag_nodes[2] = node_numbering.at( offset_loc.at(ilat) + ip3 ); - - jcell = triag_begin + jtriag++; - node_connectivity.set( jcell, triag_nodes ); - - cells_glb_idx (jcell) = jcell+1; - cells_part (jcell) = mypart; - cells_patch (jcell) = 1; // mark cell as "patch" - - if (jbackward == jforward+2 ) break; - - if( forward ) - { - ++jforward; - forward = false; - } - else - { - --jbackward; - forward = true; - } + else if ( patch_north_pole ) { + int jlat = 0; + int ilat = 0; + int ip1, ip2, ip3; + + int jforward = 0; + int jbackward = rg.nx( jlat ) - 1; + bool forward = true; + + while ( true ) { + if ( forward ) { + ip1 = jforward; + ip2 = jforward + 1; + ip3 = jbackward; + } + else { + ip1 = jforward; + ip2 = jbackward - 1; + ip3 = jbackward; + } + + triag_nodes[0] = node_numbering.at( offset_loc.at( ilat ) + ip1 ); + triag_nodes[1] = node_numbering.at( offset_loc.at( ilat ) + ip2 ); + triag_nodes[2] = node_numbering.at( offset_loc.at( ilat ) + ip3 ); + + jcell = triag_begin + jtriag++; + node_connectivity.set( jcell, triag_nodes ); + + cells_glb_idx( jcell ) = jcell + 1; + cells_part( jcell ) = mypart; + cells_patch( jcell ) = 1; // mark cell as "patch" + + if ( jbackward == jforward + 2 ) break; + + if ( forward ) { + ++jforward; + forward = false; + } + else { + --jbackward; + forward = true; + } + } } - } - - if (include_south_pole) - { - int jlat = rg.ny()-1; - int ilat = region.south-region.north; - int ip1 = 0; - size_t nlon = rg.nx(jlat)+1 - (periodic_east_west ? 0 : 1); - for (size_t ip2 = 1; ip2 < nlon; ++ip2) - { - jcell = triag_begin + jtriag++; - int ip3 = ip2-1; - 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) ) - 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; + + if ( include_south_pole ) { + int jlat = rg.ny() - 1; + int ilat = region.south - region.north; + int ip1 = 0; + size_t nlon = rg.nx( jlat ) + 1 - ( periodic_east_west ? 0 : 1 ); + for ( size_t ip2 = 1; ip2 < nlon; ++ip2 ) { + jcell = triag_begin + jtriag++; + int ip3 = ip2 - 1; + 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 ) ) + 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; + } } - } - else if (patch_south_pole) - { - int jlat = rg.ny()-1; - int ilat = region.south-region.north; - int ip1, ip2, ip3; - - int jforward = 0; - int jbackward = rg.nx(jlat) - 1; - bool forward = true; - - while( true ) - { - if( forward ) - { - ip1 = jforward; - ip2 = jforward+1; - ip3 = jbackward; - } - else - { - ip1 = jforward; - ip2 = jbackward-1; - ip3 = jbackward; - } - - triag_nodes[0] = node_numbering.at( offset_loc.at(ilat) + ip1 ); - triag_nodes[1] = node_numbering.at( offset_loc.at(ilat) + ip2 ); - triag_nodes[2] = node_numbering.at( offset_loc.at(ilat) + ip3 ); - - jcell = triag_begin + jtriag++; - node_connectivity.set( jcell, triag_nodes ); - - cells_glb_idx (jcell) = jcell+1; - cells_part (jcell) = mypart; - cells_patch (jcell) = 1; // mark cell as "patch" - - if (jbackward == jforward+2 ) break; - - if( forward ) - { - ++jforward; - forward = false; - } - else - { - --jbackward; - forward = true; - } + else if ( patch_south_pole ) { + int jlat = rg.ny() - 1; + int ilat = region.south - region.north; + int ip1, ip2, ip3; + + int jforward = 0; + int jbackward = rg.nx( jlat ) - 1; + bool forward = true; + + while ( true ) { + if ( forward ) { + ip1 = jforward; + ip2 = jforward + 1; + ip3 = jbackward; + } + else { + ip1 = jforward; + ip2 = jbackward - 1; + ip3 = jbackward; + } + + triag_nodes[0] = node_numbering.at( offset_loc.at( ilat ) + ip1 ); + triag_nodes[1] = node_numbering.at( offset_loc.at( ilat ) + ip2 ); + triag_nodes[2] = node_numbering.at( offset_loc.at( ilat ) + ip3 ); + + jcell = triag_begin + jtriag++; + node_connectivity.set( jcell, triag_nodes ); + + cells_glb_idx( jcell ) = jcell + 1; + cells_part( jcell ) = mypart; + cells_patch( jcell ) = 1; // mark cell as "patch" + + if ( jbackward == jforward + 2 ) break; + + if ( forward ) { + ++jforward; + forward = false; + } + else { + --jbackward; + forward = true; + } + } } - } - generateGlobalElementNumbering( mesh ); + generateGlobalElementNumbering( mesh ); } namespace { -static MeshGeneratorBuilder< StructuredMeshGenerator > __Structured("structured"); +static MeshGeneratorBuilder __Structured( "structured" ); } -} // namespace detail -} // namespace meshgenerator -} // namespace atlas +} // namespace detail +} // namespace meshgenerator +} // namespace atlas diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.h b/src/atlas/meshgenerator/StructuredMeshGenerator.h index fa3d63639..1fb3479f0 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.h +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.h @@ -4,35 +4,35 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include "atlas/meshgenerator/MeshGenerator.h" -#include "atlas/util/Metadata.h" #include "atlas/util/Config.h" +#include "atlas/util/Metadata.h" namespace eckit { - class Parametrisation; +class Parametrisation; } namespace atlas { - class Mesh; +class Mesh; } namespace atlas { namespace grid { - class StructuredGrid; - class Distribution; -} } - +class StructuredGrid; +class Distribution; +} // namespace grid +} // namespace atlas namespace atlas { namespace meshgenerator { - namespace detail { struct Region; @@ -40,59 +40,42 @@ struct Region; //---------------------------------------------------------------------------------------------------------------------- class StructuredMeshGenerator : public MeshGenerator::Implementation { - public: + StructuredMeshGenerator( const eckit::Parametrisation& = util::NoConfig() ); - StructuredMeshGenerator(const eckit::Parametrisation& = util::NoConfig() ); + virtual void generate( const Grid&, const grid::Distribution&, Mesh& ) const override; + virtual void generate( const Grid&, Mesh& ) const override; - virtual void generate(const Grid&, const grid::Distribution&, Mesh&) const override; - virtual void generate(const Grid&, Mesh&) const override; - - using MeshGenerator::Implementation::generate; + using MeshGenerator::Implementation::generate; private: + virtual void hash( eckit::Hash& ) const override; - virtual void hash(eckit::Hash&) const override; - - void configure_defaults(); + void configure_defaults(); - void generate_region( - const grid::StructuredGrid&, - const std::vector& parts, - int mypart, - Region& region) const; + void generate_region( const grid::StructuredGrid&, const std::vector& parts, int mypart, + Region& region ) const; - void generate_mesh_new( - const grid::StructuredGrid&, - const std::vector& parts, - const Region& region, - Mesh& m) const; + void generate_mesh_new( const grid::StructuredGrid&, const std::vector& parts, const Region& region, + Mesh& m ) const; - void generate_mesh( - const grid::StructuredGrid&, - const std::vector& parts, - const Region& region, - Mesh& m ) const; + void generate_mesh( const grid::StructuredGrid&, const std::vector& parts, const Region& region, + Mesh& m ) const; private: - - util::Metadata options; - + util::Metadata options; }; -} +} // namespace detail class StructuredMeshGenerator : public MeshGenerator { public: - StructuredMeshGenerator(const eckit::Parametrisation& config = util::NoConfig()) : - MeshGenerator("structured",config) { - } - StructuredMeshGenerator(const MeshGenerator& m ) : - MeshGenerator(m) { - } + StructuredMeshGenerator( const eckit::Parametrisation& config = util::NoConfig() ) : + MeshGenerator( "structured", config ) {} + StructuredMeshGenerator( const MeshGenerator& m ) : MeshGenerator( m ) {} }; //---------------------------------------------------------------------------------------------------------------------- -} // namespace meshgenerator -} // namespace atlas +} // namespace meshgenerator +} // namespace atlas diff --git a/src/atlas/numerics/Method.cc b/src/atlas/numerics/Method.cc index b14ae9c0d..2dc5d46f5 100644 --- a/src/atlas/numerics/Method.cc +++ b/src/atlas/numerics/Method.cc @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "eckit/exception/Exceptions.h" -#include "atlas/library/config.h" #include "atlas/numerics/Method.h" +#include "atlas/library/config.h" #include "atlas/runtime/ErrorHandling.h" +#include "eckit/exception/Exceptions.h" namespace atlas { namespace numerics { @@ -20,26 +21,17 @@ namespace numerics { // C wrapper interfaces to C++ routines extern "C" { - void atlas__Method__delete (Method* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - delete This; - This = 0; - ); +void atlas__Method__delete( Method* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); delete This; This = 0; ); } -const char* atlas__Method__name (Method* This) { - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->name().c_str(); - ); - return 0; +const char* atlas__Method__name( Method* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->name().c_str(); ); + return 0; } } // ------------------------------------------------------------------ -} // namespace numerics -} // namespace atlas - +} // namespace numerics +} // namespace atlas diff --git a/src/atlas/numerics/Method.h b/src/atlas/numerics/Method.h index 646e74641..210b7158f 100644 --- a/src/atlas/numerics/Method.h +++ b/src/atlas/numerics/Method.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -18,21 +19,19 @@ namespace numerics { /// @brief Method class /// @note Abstract base class -class Method : public eckit::Owned -{ +class Method : public eckit::Owned { public: Method() {} - virtual ~Method() = 0; + virtual ~Method() = 0; virtual std::string name() const = 0; }; inline Method::~Method() {} -extern "C" -{ - void atlas__Method__delete (Method* This); - const char* atlas__Method__name (Method* This); +extern "C" { +void atlas__Method__delete( Method* This ); +const char* atlas__Method__name( Method* This ); } -} // namespace numerics -} // namespace atlas +} // namespace numerics +} // namespace atlas diff --git a/src/atlas/numerics/Nabla.cc b/src/atlas/numerics/Nabla.cc index f957cf730..d896ccf30 100644 --- a/src/atlas/numerics/Nabla.cc +++ b/src/atlas/numerics/Nabla.cc @@ -4,241 +4,180 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/numerics/Nabla.h" #include #include -#include "eckit/thread/AutoLock.h" -#include "eckit/thread/Mutex.h" -#include "eckit/exception/Exceptions.h" -#include "atlas/library/config.h" #include "atlas/library/config.h" -#include "atlas/numerics/Nabla.h" #include "atlas/numerics/Method.h" -#include "atlas/numerics/fvm/Nabla.h" #include "atlas/numerics/fvm/Method.h" -#include "atlas/util/Config.h" +#include "atlas/numerics/fvm/Nabla.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" +#include "atlas/util/Config.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" namespace { - static eckit::Mutex *local_mutex = 0; - static std::map *m = 0; - static pthread_once_t once = PTHREAD_ONCE_INIT; +static eckit::Mutex* local_mutex = 0; +static std::map* m = 0; +static pthread_once_t once = PTHREAD_ONCE_INIT; - static void init() { - local_mutex = new eckit::Mutex(); - m = new std::map(); - } +static void init() { + local_mutex = new eckit::Mutex(); + m = new std::map(); } - +} // namespace namespace atlas { namespace numerics { -NablaImpl::NablaImpl(const Method &method, const eckit::Parametrisation &p) { -} +NablaImpl::NablaImpl( const Method& method, const eckit::Parametrisation& p ) {} -NablaImpl::~NablaImpl() { -} +NablaImpl::~NablaImpl() {} -Nabla::Nabla() : - nabla_(nullptr) { -} +Nabla::Nabla() : nabla_( nullptr ) {} -Nabla::Nabla( const Nabla::nabla_t* nabla ) : - nabla_(nabla) { -} +Nabla::Nabla( const Nabla::nabla_t* nabla ) : nabla_( nabla ) {} -Nabla::Nabla( const Nabla& nabla ) : - nabla_(nabla.nabla_) { -} +Nabla::Nabla( const Nabla& nabla ) : nabla_( nabla.nabla_ ) {} -Nabla::Nabla( const Method& method, const eckit::Parametrisation& p ) : - nabla_( NablaFactory::build(method,p) ) { -} +Nabla::Nabla( const Method& method, const eckit::Parametrisation& p ) : nabla_( NablaFactory::build( method, p ) ) {} -Nabla::Nabla( const Method& method ) : - Nabla( method, util::NoConfig() ) { -} +Nabla::Nabla( const Method& method ) : Nabla( method, util::NoConfig() ) {} -void Nabla::gradient(const Field &scalar, Field &grad) const { - nabla_->gradient(scalar,grad); +void Nabla::gradient( const Field& scalar, Field& grad ) const { + nabla_->gradient( scalar, grad ); } -void Nabla::divergence(const Field &vector, Field &div) const { - nabla_->divergence(vector,div); +void Nabla::divergence( const Field& vector, Field& div ) const { + nabla_->divergence( vector, div ); } -void Nabla::curl(const Field &vector, Field &curl) const { - nabla_->curl(vector,curl); +void Nabla::curl( const Field& vector, Field& curl ) const { + nabla_->curl( vector, curl ); } -void Nabla::laplacian(const Field &scalar, Field &laplacian) const { - nabla_->laplacian(scalar,laplacian); +void Nabla::laplacian( const Field& scalar, Field& laplacian ) const { + nabla_->laplacian( scalar, laplacian ); } - - namespace { -template void load_builder() { NablaBuilder("tmp"); } +template +void load_builder() { + NablaBuilder( "tmp" ); +} struct force_link { - force_link() - { - load_builder< fvm::Nabla >(); - } + force_link() { load_builder(); } }; -} - - -NablaFactory::NablaFactory(const std::string &name): - name_(name) { - - pthread_once(&once, init); +} // namespace - eckit::AutoLock lock(local_mutex); +NablaFactory::NablaFactory( const std::string& name ) : name_( name ) { + pthread_once( &once, init ); - ASSERT(m->find(name) == m->end()); - (*m)[name] = this; + eckit::AutoLock lock( local_mutex ); + ASSERT( m->find( name ) == m->end() ); + ( *m )[name] = this; } - NablaFactory::~NablaFactory() { - eckit::AutoLock lock(local_mutex); - m->erase(name_); + eckit::AutoLock lock( local_mutex ); + m->erase( name_ ); } +void NablaFactory::list( std::ostream& out ) { + pthread_once( &once, init ); -void NablaFactory::list(std::ostream& out) { - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; const char* sep = ""; - for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { - out << sep << (*j).first; + for ( std::map::const_iterator j = m->begin(); j != m->end(); ++j ) { + out << sep << ( *j ).first; sep = ", "; } } -bool NablaFactory::has(const std::string& name) -{ - pthread_once(&once, init); +bool NablaFactory::has( const std::string& name ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); - static force_link static_linking; + static force_link static_linking; - return ( m->find(name) != m->end() ); + return ( m->find( name ) != m->end() ); } +const NablaImpl* NablaFactory::build( const Method& method, const eckit::Parametrisation& p ) { + pthread_once( &once, init ); - -const NablaImpl* NablaFactory::build(const Method& method, const eckit::Parametrisation& p) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::map::const_iterator j = m->find(method.name()); + std::map::const_iterator j = m->find( method.name() ); Log::debug() << "Looking for NablaFactory [" << method.name() << "]" << '\n'; - if (j == m->end()) { + 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) - Log::error() << " " << (*j).first << '\n'; - throw eckit::SeriousBug(std::string("No NablaFactory called ") + method.name()); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << '\n'; + throw eckit::SeriousBug( std::string( "No NablaFactory called " ) + method.name() ); } - return (*j).second->make(method,p); + return ( *j ).second->make( method, p ); } extern "C" { -void atlas__Nabla__delete(Nabla::nabla_t* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - delete This; - ); -} - -const Nabla::nabla_t* atlas__Nabla__create (const Method* method, const eckit::Parametrisation* params) -{ - const Nabla::nabla_t* nabla(0); - ATLAS_ERROR_HANDLING( - ASSERT(method); - ASSERT(params); - { - Nabla n(*method,*params); - nabla = n.get(); - nabla->attach(); - } - nabla->detach(); - ); - return nabla; +void atlas__Nabla__delete( Nabla::nabla_t* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); delete This; ); } -void atlas__Nabla__gradient (const Nabla::nabla_t* This, const field::FieldImpl* scalar, field::FieldImpl* grad) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(scalar); - ASSERT(grad); - Field fgrad(grad); - This->gradient(scalar,fgrad); - ); +const Nabla::nabla_t* atlas__Nabla__create( const Method* method, const eckit::Parametrisation* params ) { + const Nabla::nabla_t* nabla( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( method ); ASSERT( params ); { + Nabla n( *method, *params ); + nabla = n.get(); + nabla->attach(); + } nabla->detach(); ); + return nabla; } -void atlas__Nabla__divergence (const Nabla::nabla_t* This, const field::FieldImpl* vector, field::FieldImpl* div) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(vector); - ASSERT(div); - Field fdiv(div); - This->divergence(vector,fdiv); - ); +void atlas__Nabla__gradient( const Nabla::nabla_t* This, const field::FieldImpl* scalar, field::FieldImpl* grad ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( scalar ); ASSERT( grad ); Field fgrad( grad ); + This->gradient( scalar, fgrad ); ); } -void atlas__Nabla__curl (const Nabla::nabla_t* This, const field::FieldImpl* vector, field::FieldImpl* curl) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(vector); - ASSERT(curl); - Field fcurl(curl); - This->curl(vector,fcurl); - ); +void atlas__Nabla__divergence( const Nabla::nabla_t* This, const field::FieldImpl* vector, field::FieldImpl* div ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( vector ); ASSERT( div ); Field fdiv( div ); + This->divergence( vector, fdiv ); ); } -void atlas__Nabla__laplacian (const Nabla::nabla_t* This, const field::FieldImpl* scalar, field::FieldImpl* laplacian) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(scalar); - ASSERT(laplacian); - Field flaplacian(laplacian); - This->laplacian(scalar,flaplacian); - ); +void atlas__Nabla__curl( const Nabla::nabla_t* This, const field::FieldImpl* vector, field::FieldImpl* curl ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( vector ); ASSERT( curl ); Field fcurl( curl ); + This->curl( vector, fcurl ); ); } - +void atlas__Nabla__laplacian( const Nabla::nabla_t* This, const field::FieldImpl* scalar, + field::FieldImpl* laplacian ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( scalar ); ASSERT( laplacian ); Field flaplacian( laplacian ); + This->laplacian( scalar, flaplacian ); ); +} } - -} // namespace numerics -} // namespace atlas +} // namespace numerics +} // namespace atlas diff --git a/src/atlas/numerics/Nabla.h b/src/atlas/numerics/Nabla.h index 88eff110f..05971d53b 100644 --- a/src/atlas/numerics/Nabla.h +++ b/src/atlas/numerics/Nabla.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,94 +14,98 @@ #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" -namespace eckit { class Parametrisation; } -namespace atlas { namespace numerics { class Method; } } -namespace atlas { namespace field { class FieldImpl; } } -namespace atlas { class Field; } +namespace eckit { +class Parametrisation; +} +namespace atlas { +namespace numerics { +class Method; +} +} // namespace atlas +namespace atlas { +namespace field { +class FieldImpl; +} +} // namespace atlas +namespace atlas { +class Field; +} namespace atlas { namespace numerics { class NablaImpl : public eckit::Owned { - public: - NablaImpl(const Method &, const eckit::Parametrisation &); - virtual ~NablaImpl(); - - virtual void gradient(const Field &scalar, Field &grad) const = 0; - virtual void divergence(const Field &vector, Field &div) const = 0; - virtual void curl(const Field &vector, Field &curl) const = 0; - virtual void laplacian(const Field &scalar, Field &laplacian) const = 0; + NablaImpl( const Method&, const eckit::Parametrisation& ); + virtual ~NablaImpl(); + virtual void gradient( const Field& scalar, Field& grad ) const = 0; + virtual void divergence( const Field& vector, Field& div ) const = 0; + virtual void curl( const Field& vector, Field& curl ) const = 0; + virtual void laplacian( const Field& scalar, Field& laplacian ) const = 0; }; // ------------------------------------------------------------------ class Nabla { - public: - - using nabla_t = NablaImpl; + using nabla_t = NablaImpl; private: - - eckit::SharedPtr nabla_; + eckit::SharedPtr nabla_; public: - - Nabla(); - Nabla( const nabla_t* ); - Nabla( const Nabla& nabla ); - Nabla(const Method &); - Nabla(const Method &, const eckit::Parametrisation &); - - void gradient(const Field &scalar, Field &grad) const; - void divergence(const Field &vector, Field &div) const; - void curl(const Field &vector, Field &curl) const; - void laplacian(const Field &scalar, Field &laplacian) const; - - const nabla_t* get() const { return nabla_.get(); } + Nabla(); + Nabla( const nabla_t* ); + Nabla( const Nabla& nabla ); + Nabla( const Method& ); + Nabla( const Method&, const eckit::Parametrisation& ); + + void gradient( const Field& scalar, Field& grad ) const; + void divergence( const Field& vector, Field& div ) const; + void curl( const Field& vector, Field& curl ) const; + void laplacian( const Field& scalar, Field& laplacian ) const; + + const nabla_t* get() const { return nabla_.get(); } }; - // ------------------------------------------------------------------ class NablaFactory { public: /*! - * \brief build Nabla with factory key, constructor arguments - * \return Nabla - */ - static const Nabla::nabla_t* build(const Method &, const eckit::Parametrisation &); + * \brief build Nabla with factory key, constructor arguments + * \return Nabla + */ + static const Nabla::nabla_t* build( const Method&, const eckit::Parametrisation& ); /*! - * \brief list all registered field creators - */ - static void list(std::ostream &); - static bool has(const std::string& name); + * \brief list all registered field creators + */ + static void list( std::ostream& ); + static bool has( const std::string& name ); private: - virtual const Nabla::nabla_t* make(const Method &, const eckit::Parametrisation &) = 0 ; + virtual const Nabla::nabla_t* make( const Method&, const eckit::Parametrisation& ) = 0; protected: - NablaFactory(const std::string&); + NablaFactory( const std::string& ); virtual ~NablaFactory(); private: - std::string name_; + std::string name_; }; // ------------------------------------------------------------------ -template +template class NablaBuilder : public NablaFactory { - public: - NablaBuilder(const std::string& name) : NablaFactory(name) {} + NablaBuilder( const std::string& name ) : NablaFactory( name ) {} private: - virtual const Nabla::nabla_t* make(const Method &method, const eckit::Parametrisation &p) { - return new T(method,p); + virtual const Nabla::nabla_t* make( const Method& method, const eckit::Parametrisation& p ) { + return new T( method, p ); } }; @@ -108,14 +113,13 @@ class NablaBuilder : public NablaFactory { extern "C" { -void atlas__Nabla__delete (Nabla::nabla_t* This); -const Nabla::nabla_t* atlas__Nabla__create (const Method* method, const eckit::Parametrisation* params); -void atlas__Nabla__gradient (const Nabla::nabla_t* This, const field::FieldImpl* scalar, field::FieldImpl* grad); -void atlas__Nabla__divergence (const Nabla::nabla_t* This, const field::FieldImpl* vector, field::FieldImpl* div); -void atlas__Nabla__curl (const Nabla::nabla_t* This, const field::FieldImpl* vector, field::FieldImpl* curl); -void atlas__Nabla__laplacian (const Nabla::nabla_t* This, const field::FieldImpl* scalar, field::FieldImpl* laplacian); - +void atlas__Nabla__delete( Nabla::nabla_t* This ); +const Nabla::nabla_t* atlas__Nabla__create( const Method* method, const eckit::Parametrisation* params ); +void atlas__Nabla__gradient( const Nabla::nabla_t* This, const field::FieldImpl* scalar, field::FieldImpl* grad ); +void atlas__Nabla__divergence( const Nabla::nabla_t* This, const field::FieldImpl* vector, field::FieldImpl* div ); +void atlas__Nabla__curl( const Nabla::nabla_t* This, const field::FieldImpl* vector, field::FieldImpl* curl ); +void atlas__Nabla__laplacian( const Nabla::nabla_t* This, const field::FieldImpl* scalar, field::FieldImpl* laplacian ); } -} // namespace numerics -} // namespace atlas +} // namespace numerics +} // namespace atlas diff --git a/src/atlas/numerics/fvm/Method.cc b/src/atlas/numerics/fvm/Method.cc index 3b7e945ff..f6f2f2d54 100644 --- a/src/atlas/numerics/fvm/Method.cc +++ b/src/atlas/numerics/fvm/Method.cc @@ -4,27 +4,28 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/numerics/fvm/Method.h" #include -#include "eckit/exception/Exceptions.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/MakeView.h" +#include "atlas/functionspace/EdgeColumns.h" +#include "atlas/functionspace/NodeColumns.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" +#include "atlas/mesh/actions/BuildDualMesh.h" #include "atlas/mesh/actions/BuildEdges.h" #include "atlas/mesh/actions/BuildParallelFields.h" -#include "atlas/mesh/actions/BuildDualMesh.h" -#include "atlas/functionspace/NodeColumns.h" -#include "atlas/functionspace/EdgeColumns.h" -#include "atlas/numerics/fvm/Method.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/util/Earth.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/MakeView.h" #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/ErrorHandling.h" +#include "atlas/util/CoordinateEnums.h" +#include "atlas/util/Earth.h" +#include "eckit/exception/Exceptions.h" // ======================================================= @@ -36,161 +37,132 @@ namespace fvm { namespace { - mesh::Halo get_halo(const eckit::Parametrisation ¶ms) - { - size_t halo_size(1); - params.get("halo",halo_size); - return mesh::Halo(halo_size); - } - - size_t get_levels(const eckit::Parametrisation ¶ms) - { - size_t levels(0); - params.get("levels",levels); +mesh::Halo get_halo( const eckit::Parametrisation& params ) { + size_t halo_size( 1 ); + params.get( "halo", halo_size ); + return mesh::Halo( halo_size ); +} + +size_t get_levels( const eckit::Parametrisation& params ) { + size_t levels( 0 ); + params.get( "levels", levels ); return levels; - } +} - double get_radius(const eckit::Parametrisation ¶ms) - { +double get_radius( const eckit::Parametrisation& params ) { double radius = util::Earth::radiusInMeters(); - params.get("radius",radius); + params.get( "radius", radius ); return radius; - } - } -Method::Method( Mesh &mesh ) : - Method::Method(mesh,util::NoConfig()) { - setup(); +} // namespace + +Method::Method( Mesh& mesh ) : Method::Method( mesh, util::NoConfig() ) { + setup(); } -Method::Method( Mesh &mesh, const mesh::Halo &halo ) : - Method::Method( mesh, util::Config("halo",halo.size()) ) { - setup(); +Method::Method( Mesh& mesh, const mesh::Halo& halo ) : Method::Method( mesh, util::Config( "halo", halo.size() ) ) { + setup(); } -Method::Method( Mesh &mesh, const eckit::Configuration ¶ms ) : - mesh_(mesh), - levels_(get_levels(params)), - halo_(get_halo(params)), - nodes_(mesh.nodes()), - edges_(mesh.edges()), - radius_(get_radius(params)) { - setup(); +Method::Method( Mesh& mesh, const eckit::Configuration& params ) : + mesh_( mesh ), + levels_( get_levels( params ) ), + halo_( get_halo( params ) ), + nodes_( mesh.nodes() ), + edges_( mesh.edges() ), + radius_( get_radius( params ) ) { + setup(); } -void Method::setup() -{ - util::Config node_columns_config; - node_columns_config.set("halo",halo_.size()); - if( levels_ ) node_columns_config.set("levels",levels_); - node_columns_ = functionspace::NodeColumns(mesh(), node_columns_config ); - if( edges_.size() == 0 ) - { - build_edges(mesh()); - build_pole_edges(mesh()); - build_edges_parallel_fields( mesh() ); - build_median_dual_mesh(mesh()); - build_node_to_edge_connectivity(mesh()); - - const size_t nnodes = nodes_.size(); - - // Compute sign - { - const array::ArrayView is_pole_edge = array::make_view( edges_.field("is_pole_edge") ); - - const mesh::Connectivity &node_edge_connectivity = nodes_.edge_connectivity(); - const mesh::MultiBlockConnectivity &edge_node_connectivity = edges_.node_connectivity(); - if( ! nodes_.has_field("node2edge_sign") ) - { - nodes_.add( - Field("node2edge_sign", - array::make_datatype(), - array::make_shape(nnodes,node_edge_connectivity.maxcols()) ) ); - } - array::ArrayView node2edge_sign = array::make_view( nodes_.field("node2edge_sign") ); - - atlas_omp_parallel_for( size_t jnode=0; jnode is_pole_edge = array::make_view( edges_.field( "is_pole_edge" ) ); + + const mesh::Connectivity& node_edge_connectivity = nodes_.edge_connectivity(); + const mesh::MultiBlockConnectivity& edge_node_connectivity = edges_.node_connectivity(); + if ( !nodes_.has_field( "node2edge_sign" ) ) { + nodes_.add( Field( "node2edge_sign", array::make_datatype(), + array::make_shape( nnodes, node_edge_connectivity.maxcols() ) ) ); + } + array::ArrayView node2edge_sign = + array::make_view( nodes_.field( "node2edge_sign" ) ); + + atlas_omp_parallel_for( size_t jnode = 0; jnode < nnodes; ++jnode ) { + for ( size_t jedge = 0; jedge < node_edge_connectivity.cols( jnode ); ++jedge ) { + size_t iedge = node_edge_connectivity( jnode, jedge ); + size_t ip1 = edge_node_connectivity( iedge, 0 ); + if ( jnode == ip1 ) + node2edge_sign( jnode, jedge ) = 1.; + else { + node2edge_sign( jnode, jedge ) = -1.; + if ( is_pole_edge( iedge ) ) node2edge_sign( jnode, jedge ) = 1.; + } + } + } } - } - } - // Metrics - if (0) { - const size_t nedges = edges_.size(); - const array::ArrayView lonlat_deg = array::make_view( nodes_.lonlat() ); - array::ArrayView dual_volumes = array::make_view( nodes_.field("dual_volumes") ); - array::ArrayView dual_normals = array::make_view( edges_.field("dual_normals") ); - - const double deg2rad = M_PI/180.; - atlas_omp_parallel_for( size_t jnode=0; jnode lonlat_deg = array::make_view( nodes_.lonlat() ); + array::ArrayView dual_volumes = array::make_view( nodes_.field( "dual_volumes" ) ); + array::ArrayView dual_normals = array::make_view( edges_.field( "dual_normals" ) ); + + const double deg2rad = M_PI / 180.; + atlas_omp_parallel_for( size_t jnode = 0; jnode < nnodes; ++jnode ) { + double y = lonlat_deg( jnode, LAT ) * deg2rad; + double hx = radius_ * std::cos( y ); + double hy = radius_; + double G = hx * hy; + dual_volumes( jnode ) *= std::pow( deg2rad, 2 ) * G; + } + + atlas_omp_parallel_for( size_t jedge = 0; jedge < nedges; ++jedge ) { + dual_normals( jedge, LON ) *= deg2rad; + dual_normals( jedge, LAT ) *= deg2rad; + } + } } - } - edge_columns_ = functionspace::EdgeColumns(mesh()); + edge_columns_ = functionspace::EdgeColumns( mesh() ); } // ------------------------------------------------------------------------------------------ extern "C" { -Method* atlas__numerics__fvm__Method__new (Mesh::Implementation* mesh, const eckit::Configuration* params) -{ - Method* method(0); - ATLAS_ERROR_HANDLING( - ASSERT(mesh); - Mesh m(mesh); - method = new Method(m,*params); - ); - return method; +Method* atlas__numerics__fvm__Method__new( Mesh::Implementation* mesh, const eckit::Configuration* params ) { + Method* method( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( mesh ); Mesh m( mesh ); method = new Method( m, *params ); ); + return method; } -const functionspace::detail::NodeColumns* atlas__numerics__fvm__Method__functionspace_nodes (Method* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return dynamic_cast(This->node_columns().get()); - ); - return 0; +const functionspace::detail::NodeColumns* atlas__numerics__fvm__Method__functionspace_nodes( Method* This ) { + ATLAS_ERROR_HANDLING( + ASSERT( This ); return dynamic_cast( This->node_columns().get() ); ); + return 0; } -const functionspace::detail::EdgeColumns* atlas__numerics__fvm__Method__functionspace_edges (Method* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - return dynamic_cast(This->edge_columns().get()); - ); - return 0; +const functionspace::detail::EdgeColumns* atlas__numerics__fvm__Method__functionspace_edges( Method* This ) { + ATLAS_ERROR_HANDLING( + ASSERT( This ); return dynamic_cast( This->edge_columns().get() ); ); + return 0; } - - - } // ------------------------------------------------------------------------------------------ -} // namepace fvm -} // namespace numerics -} // namespace atlas +} // namespace fvm +} // namespace numerics +} // namespace atlas diff --git a/src/atlas/numerics/fvm/Method.h b/src/atlas/numerics/fvm/Method.h index fb139d5fa..67873321a 100644 --- a/src/atlas/numerics/fvm/Method.h +++ b/src/atlas/numerics/fvm/Method.h @@ -4,80 +4,84 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #pragma once #include -#include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/EdgeColumns.h" +#include "atlas/functionspace/NodeColumns.h" #include "atlas/numerics/Method.h" -namespace eckit { class Parametrisation; } -namespace atlas { class Mesh; } -namespace atlas { namespace mesh { class HybridElements; } } -namespace atlas { namespace mesh { class Nodes; } } +namespace eckit { +class Parametrisation; +} +namespace atlas { +class Mesh; +} +namespace atlas { +namespace mesh { +class HybridElements; +} +} // namespace atlas +namespace atlas { +namespace mesh { +class Nodes; +} +} // namespace atlas namespace atlas { namespace numerics { namespace fvm { class Method : public numerics::Method { - public: + Method( Mesh&, const eckit::Configuration& ); + Method( Mesh&, const mesh::Halo& ); + Method( Mesh& ); - Method(Mesh &, const eckit::Configuration &); - Method(Mesh &, const mesh::Halo &); - Method(Mesh &); + virtual std::string name() const { return "fvm"; } - virtual std::string name() const { return "fvm"; } + const atlas::Mesh& mesh() const { return mesh_; } + atlas::Mesh& mesh() { return mesh_; } - const atlas::Mesh& mesh() const { return mesh_; } - atlas::Mesh& mesh() { return mesh_; } - - size_t levels() const { return levels_; } + size_t levels() const { return levels_; } - const functionspace::NodeColumns& node_columns() const { return node_columns_; } - functionspace::NodeColumns& node_columns() { return node_columns_; } + const functionspace::NodeColumns& node_columns() const { return node_columns_; } + functionspace::NodeColumns& node_columns() { return node_columns_; } - const functionspace::EdgeColumns& edge_columns() const { return edge_columns_; } - functionspace::EdgeColumns& edge_columns() { return edge_columns_; } + const functionspace::EdgeColumns& edge_columns() const { return edge_columns_; } + functionspace::EdgeColumns& edge_columns() { return edge_columns_; } - const double& radius() const { return radius_; } + const double& radius() const { return radius_; } private: - - void setup(); - -private: // data - - Mesh mesh_; // non-const because functionspace may modify mesh - size_t levels_; - mesh::Halo halo_; - mesh::Nodes &nodes_; - mesh::HybridElements &edges_; + void setup(); + +private: // data + Mesh mesh_; // non-const because functionspace may modify mesh + size_t levels_; + mesh::Halo halo_; + mesh::Nodes& nodes_; + mesh::HybridElements& edges_; functionspace::NodeColumns node_columns_; functionspace::EdgeColumns edge_columns_; double radius_; - - }; - // ------------------------------------------------------------------- // C wrapper interfaces to C++ routines -extern "C" -{ - Method* atlas__numerics__fvm__Method__new (Mesh::Implementation* mesh, const eckit::Configuration* params); - const functionspace::detail::NodeColumns* atlas__numerics__fvm__Method__functionspace_nodes (Method* This); - const functionspace::detail::EdgeColumns* atlas__numerics__fvm__Method__functionspace_edges (Method* This); +extern "C" { +Method* atlas__numerics__fvm__Method__new( Mesh::Implementation* mesh, const eckit::Configuration* params ); +const functionspace::detail::NodeColumns* atlas__numerics__fvm__Method__functionspace_nodes( Method* This ); +const functionspace::detail::EdgeColumns* atlas__numerics__fvm__Method__functionspace_edges( Method* This ); } -} // namespace fvm -} // namespace numerics -} // namespace atlas +} // namespace fvm +} // namespace numerics +} // namespace atlas diff --git a/src/atlas/numerics/fvm/Nabla.cc b/src/atlas/numerics/fvm/Nabla.cc index 7bc7c36a0..ef8d78a92 100644 --- a/src/atlas/numerics/fvm/Nabla.cc +++ b/src/atlas/numerics/fvm/Nabla.cc @@ -4,464 +4,420 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "eckit/exception/Exceptions.h" -#include "eckit/config/Parametrisation.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/field/Field.h" #include "atlas/numerics/fvm/Nabla.h" -#include "atlas/numerics/fvm/Method.h" -#include "atlas/util/CoordinateEnums.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" +#include "atlas/mesh/HybridElements.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" +#include "atlas/numerics/fvm/Method.h" #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/Log.h" +#include "atlas/util/CoordinateEnums.h" +#include "eckit/config/Parametrisation.h" +#include "eckit/exception/Exceptions.h" // ======================================================= using Topology = atlas::mesh::Nodes::Topology; -using Range = atlas::array::Range; +using Range = atlas::array::Range; namespace atlas { namespace numerics { namespace fvm { namespace { -static NablaBuilder< Nabla > __fvm_nabla("fvm"); - -} - -Nabla::Nabla(const numerics::Method &method, const eckit::Parametrisation &p) : - atlas::numerics::Nabla::nabla_t(method,p) -{ - fvm_ = dynamic_cast(&method); - if( ! fvm_ ) - throw eckit::BadCast("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; - - setup(); - +static NablaBuilder __fvm_nabla( "fvm" ); } -Nabla::~Nabla() -{ -} +Nabla::Nabla( const numerics::Method& method, const eckit::Parametrisation& p ) : + atlas::numerics::Nabla::nabla_t( method, p ) { + fvm_ = dynamic_cast( &method ); + if ( !fvm_ ) throw eckit::BadCast( "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; -void Nabla::setup() -{ - const mesh::Edges &edges = fvm_->mesh().edges(); - - const size_t nedges = edges.size(); - - const array::ArrayView edge_is_pole = array::make_view( edges.field("is_pole_edge") ); - - // Filter pole_edges out of all edges - std::vector tmp(nedges); - size_t c(0); - for(size_t jedge = 0; jedge < nedges; ++jedge) - { - if( edge_is_pole(jedge) ) - tmp[c++] = jedge; - } - pole_edges_.clear(); - pole_edges_.reserve(c); - for( size_t jedge=0; jedge 1 ) { - return gradient_of_vector(field,grad_field); - } else { - return gradient_of_scalar(field,grad_field); - } - throw eckit::SeriousBug("Cannot figure out if field is a scalar or vector field",Here()); -} +Nabla::~Nabla() {} -void Nabla::gradient_of_scalar(const Field& scalar_field, Field& grad_field) const -{ - Log::debug() << "Compute gradient of scalar field " << scalar_field.name() << " with fvm method" << std::endl; - const double radius = fvm_->radius(); - const double deg2rad = M_PI/180.; +void Nabla::setup() { + const mesh::Edges& edges = fvm_->mesh().edges(); - const mesh::Edges &edges = fvm_->mesh().edges(); - const mesh::Nodes &nodes = fvm_->mesh().nodes(); + const size_t nedges = edges.size(); - const size_t nnodes = nodes.size(); - const size_t nedges = edges.size(); - const size_t nlev = scalar_field.levels() ? scalar_field.levels() : 1; - if( (grad_field.levels() ? grad_field.levels() : 1) != nlev ) - throw eckit::AssertionFailed("gradient field should have same number of levels",Here()); + const array::ArrayView edge_is_pole = array::make_view( edges.field( "is_pole_edge" ) ); - const auto scalar = scalar_field.levels() ? array::make_view( scalar_field ).slice(Range::all(),Range::all()) - : array::make_view( scalar_field ).slice(Range::all(),Range::dummy()); - auto grad = grad_field.levels() ? array::make_view( grad_field ).slice(Range::all(),Range::all(),Range::all()) - : array::make_view( grad_field ).slice(Range::all(),Range::dummy(),Range::all()); - - const auto lonlat_deg = array::make_view( nodes.lonlat() ); - const auto dual_volumes = array::make_view( nodes.field("dual_volumes") ); - const auto dual_normals = array::make_view( edges.field("dual_normals") ); - const auto node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); - - const mesh::Connectivity& node2edge = nodes.edge_connectivity(); - const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); - - array::ArrayT avgS_arr( nedges,nlev,2ul ); - auto avgS = array::make_view(avgS_arr); - - const double scale = deg2rad*deg2rad*radius; + // Filter pole_edges out of all edges + std::vector tmp( nedges ); + size_t c( 0 ); + for ( size_t jedge = 0; jedge < nedges; ++jedge ) { + if ( edge_is_pole( jedge ) ) tmp[c++] = jedge; + } + pole_edges_.clear(); + pole_edges_.reserve( c ); + for ( size_t jedge = 0; jedge < c; ++jedge ) + pole_edges_.push_back( tmp[jedge] ); +} - atlas_omp_parallel - { - atlas_omp_for( size_t jedge=0; jedge 1 ) { return gradient_of_vector( field, grad_field ); } + else { + return gradient_of_scalar( field, grad_field ); } + throw eckit::SeriousBug( "Cannot figure out if field is a scalar or vector field", Here() ); +} - atlas_omp_for( size_t jnode=0; jnoderadius(); + const double deg2rad = M_PI / 180.; + + const mesh::Edges& edges = fvm_->mesh().edges(); + const mesh::Nodes& nodes = fvm_->mesh().nodes(); + + const size_t nnodes = nodes.size(); + const size_t nedges = edges.size(); + const size_t nlev = scalar_field.levels() ? scalar_field.levels() : 1; + if ( ( grad_field.levels() ? grad_field.levels() : 1 ) != nlev ) + throw eckit::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() ) + : array::make_view( scalar_field ).slice( Range::all(), Range::dummy() ); + auto grad = grad_field.levels() + ? array::make_view( grad_field ).slice( Range::all(), Range::all(), Range::all() ) + : array::make_view( grad_field ).slice( Range::all(), Range::dummy(), Range::all() ); + + const auto lonlat_deg = array::make_view( nodes.lonlat() ); + const auto dual_volumes = array::make_view( nodes.field( "dual_volumes" ) ); + const auto dual_normals = array::make_view( edges.field( "dual_normals" ) ); + const auto node2edge_sign = array::make_view( nodes.field( "node2edge_sign" ) ); + + const mesh::Connectivity& node2edge = nodes.edge_connectivity(); + const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); + + array::ArrayT avgS_arr( nedges, nlev, 2ul ); + auto avgS = array::make_view( avgS_arr ); + + const double scale = deg2rad * deg2rad * radius; + + atlas_omp_parallel { + atlas_omp_for( size_t jedge = 0; jedge < nedges; ++jedge ) { + int ip1 = edge2node( jedge, 0 ); + int ip2 = edge2node( jedge, 1 ); + + for ( size_t jlev = 0; jlev < nlev; ++jlev ) { + double avg = ( scalar( ip1, jlev ) + scalar( ip2, jlev ) ) * 0.5; + avgS( jedge, jlev, LON ) = dual_normals( jedge, LON ) * deg2rad * avg; + avgS( jedge, jlev, LAT ) = dual_normals( jedge, LAT ) * deg2rad * avg; + } + } + + atlas_omp_for( size_t jnode = 0; jnode < nnodes; ++jnode ) { + for ( size_t jlev = 0; jlev < nlev; ++jlev ) { + grad( jnode, jlev, LON ) = 0.; + grad( jnode, jlev, LAT ) = 0.; + } + for ( size_t jedge = 0; jedge < node2edge.cols( jnode ); ++jedge ) { + const int iedge = node2edge( jnode, jedge ); + const double add = node2edge_sign( jnode, jedge ); + for ( size_t jlev = 0; jlev < nlev; ++jlev ) { + grad( jnode, jlev, LON ) += add * avgS( iedge, jlev, LON ); + grad( jnode, jlev, LAT ) += add * avgS( iedge, jlev, LAT ); + } + } + const double y = lonlat_deg( jnode, LAT ) * deg2rad; + const double metric_y = 1. / ( dual_volumes( jnode ) * scale ); + const double metric_x = metric_y / std::cos( y ); + for ( size_t jlev = 0; jlev < nlev; ++jlev ) { + grad( jnode, jlev, LON ) *= metric_x; + grad( jnode, jlev, LAT ) *= metric_y; + } } - } - const double y = lonlat_deg(jnode,LAT) * deg2rad; - const double metric_y = 1./(dual_volumes(jnode)*scale); - const double metric_x = metric_y/std::cos(y); - for(size_t jlev = 0; jlev < nlev; ++jlev) - { - grad(jnode,jlev,LON) *= metric_x; - grad(jnode,jlev,LAT) *= metric_y; - } } - } } // ================================================================================ -void Nabla::gradient_of_vector(const Field &vector_field, Field &grad_field) const -{ - Log::debug() << "Compute gradient of vector field " << vector_field.name() << " with fvm method" << std::endl; - const double radius = fvm_->radius(); - const double deg2rad = M_PI/180.; +void Nabla::gradient_of_vector( const Field& vector_field, Field& grad_field ) const { + Log::debug() << "Compute gradient of vector field " << vector_field.name() << " with fvm method" << std::endl; + const double radius = fvm_->radius(); + const double deg2rad = M_PI / 180.; - const mesh::Edges &edges = fvm_->mesh().edges(); - const mesh::Nodes &nodes = fvm_->mesh().nodes(); + const mesh::Edges& edges = fvm_->mesh().edges(); + const mesh::Nodes& nodes = fvm_->mesh().nodes(); - const size_t nnodes = nodes.size(); - const size_t nedges = edges.size(); - const size_t nlev = vector_field.levels(); - if( vector_field.levels() != nlev ) - throw eckit::AssertionFailed("gradient field should have same number of levels",Here()); + const size_t nnodes = nodes.size(); + const size_t nedges = edges.size(); + const size_t nlev = vector_field.levels(); + if ( vector_field.levels() != nlev ) + throw eckit::AssertionFailed( "gradient field should have same number of levels", Here() ); - const auto vector = vector_field.levels() ? array::make_view( vector_field ).slice(Range::all(),Range::all(),Range::all()) - : array::make_view( vector_field ).slice(Range::all(),Range::dummy(),Range::all()); - auto grad = grad_field.levels() ? array::make_view( grad_field ).slice(Range::all(),Range::all(),Range::all()) - : array::make_view( grad_field ).slice(Range::all(),Range::dummy(),Range::all()); + const auto vector = + vector_field.levels() + ? array::make_view( vector_field ).slice( Range::all(), Range::all(), Range::all() ) + : array::make_view( vector_field ).slice( Range::all(), Range::dummy(), Range::all() ); + auto grad = grad_field.levels() + ? array::make_view( grad_field ).slice( Range::all(), Range::all(), Range::all() ) + : array::make_view( grad_field ).slice( Range::all(), Range::dummy(), Range::all() ); - const array::ArrayView lonlat_deg = array::make_view( nodes.lonlat() ); - const array::ArrayView dual_volumes = array::make_view( nodes.field("dual_volumes") ); - const array::ArrayView dual_normals = array::make_view( edges.field("dual_normals") ); - const array::ArrayView edge_is_pole = array::make_view( edges.field("is_pole_edge") ); - const array::ArrayView node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); + const array::ArrayView lonlat_deg = array::make_view( nodes.lonlat() ); + const array::ArrayView dual_volumes = array::make_view( nodes.field( "dual_volumes" ) ); + const array::ArrayView dual_normals = array::make_view( edges.field( "dual_normals" ) ); + const array::ArrayView edge_is_pole = array::make_view( edges.field( "is_pole_edge" ) ); + const array::ArrayView node2edge_sign = array::make_view( nodes.field( "node2edge_sign" ) ); - const mesh::Connectivity& node2edge = nodes.edge_connectivity(); - const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); + const mesh::Connectivity& node2edge = nodes.edge_connectivity(); + const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); - array::ArrayT avgS_arr( nedges,nlev,4ul ); - array::ArrayView avgS = array::make_view(avgS_arr); + array::ArrayT avgS_arr( nedges, nlev, 4ul ); + array::ArrayView avgS = array::make_view( avgS_arr ); - const double scale = deg2rad*deg2rad*radius; + const double scale = deg2rad * deg2rad * radius; - enum { LONdLON = 0, LONdLAT = 1, LATdLON = 2, LATdLAT = 3 }; - - atlas_omp_parallel - { - atlas_omp_for( size_t jedge=0; jedgeradius(); - const double deg2rad = M_PI/180.; - - const mesh::Edges &edges = fvm_->mesh().edges(); - const mesh::Nodes &nodes = fvm_->mesh().nodes(); - - const size_t nnodes = nodes.size(); - const size_t nedges = edges.size(); - const size_t nlev = vector_field.levels(); - if( div_field.levels() != nlev ) - throw eckit::AssertionFailed("divergence field should have same number of levels",Here()); - - const auto vector = vector_field.levels() ? array::make_view( vector_field ).slice(Range::all(),Range::all(),Range::all()) - : array::make_view( vector_field ).slice(Range::all(),Range::dummy(),Range::all()); - auto div = div_field.levels() ? array::make_view( div_field ).slice(Range::all(),Range::all()) - : array::make_view( div_field ).slice(Range::all(),Range::dummy()); - - const auto lonlat_deg = array::make_view( nodes.lonlat() ); - const auto dual_volumes = array::make_view( nodes.field("dual_volumes") ); - const auto dual_normals = array::make_view( edges.field("dual_normals") ); - const auto edge_is_pole = array::make_view( edges.field("is_pole_edge") ); - const auto node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); - const mesh::Connectivity& node2edge = nodes.edge_connectivity(); - const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); - - array::ArrayT avgS_arr(nedges,nlev,2ul); - array::ArrayView avgS = array::make_view(avgS_arr); - - const double scale = deg2rad*deg2rad*radius; - - atlas_omp_parallel - { - atlas_omp_for( size_t jedge=0; jedgeradius(); + const double deg2rad = M_PI / 180.; + + const mesh::Edges& edges = fvm_->mesh().edges(); + const mesh::Nodes& nodes = fvm_->mesh().nodes(); + + const size_t nnodes = nodes.size(); + const size_t nedges = edges.size(); + const size_t nlev = vector_field.levels(); + if ( div_field.levels() != nlev ) + throw eckit::AssertionFailed( "divergence field should have same number of levels", Here() ); + + const auto vector = + vector_field.levels() + ? array::make_view( vector_field ).slice( Range::all(), Range::all(), Range::all() ) + : array::make_view( vector_field ).slice( Range::all(), Range::dummy(), Range::all() ); + auto div = div_field.levels() ? array::make_view( div_field ).slice( Range::all(), Range::all() ) + : array::make_view( div_field ).slice( Range::all(), Range::dummy() ); + + const auto lonlat_deg = array::make_view( nodes.lonlat() ); + const auto dual_volumes = array::make_view( nodes.field( "dual_volumes" ) ); + const auto dual_normals = array::make_view( edges.field( "dual_normals" ) ); + const auto edge_is_pole = array::make_view( edges.field( "is_pole_edge" ) ); + const auto node2edge_sign = array::make_view( nodes.field( "node2edge_sign" ) ); + const mesh::Connectivity& node2edge = nodes.edge_connectivity(); + const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); + + array::ArrayT avgS_arr( nedges, nlev, 2ul ); + array::ArrayView avgS = array::make_view( avgS_arr ); + + const double scale = deg2rad * deg2rad * radius; + + atlas_omp_parallel { + atlas_omp_for( size_t jedge = 0; jedge < nedges; ++jedge ) { + size_t ip1 = edge2node( jedge, 0 ); + size_t ip2 = edge2node( jedge, 1 ); + double y1 = lonlat_deg( ip1, LAT ) * deg2rad; + double y2 = lonlat_deg( ip2, LAT ) * deg2rad; + double cosy1 = std::cos( y1 ); + double cosy2 = std::cos( y2 ); + + double pbc = 1. - edge_is_pole( jedge ); + + for ( size_t jlev = 0; jlev < nlev; ++jlev ) { + double avg[2] = { + ( vector( ip1, jlev, LON ) + vector( ip2, jlev, LON ) ) * 0.5, + ( cosy1 * vector( ip1, jlev, LAT ) + cosy2 * vector( ip2, jlev, LAT ) ) * 0.5 * + pbc // (force cos(y)=0 at pole) + }; + avgS( jedge, jlev, LON ) = dual_normals( jedge, LON ) * deg2rad * avg[LON]; + // above = 0 at pole by construction of S + avgS( jedge, jlev, LAT ) = dual_normals( jedge, LAT ) * deg2rad * avg[LAT]; + // above = 0 at pole by construction of pbc + // We don't need the cross terms for divergence, + // i.e. dual_normals(jedge,LON)*deg2rad*avg[LAT] + // and dual_normals(jedge,LAT)*deg2rad*avg[LON] + } + } - atlas_omp_for( size_t jnode=0; jnoderadius(); + const double deg2rad = M_PI / 180.; + + const mesh::Edges& edges = fvm_->mesh().edges(); + const mesh::Nodes& nodes = fvm_->mesh().nodes(); + + const size_t nnodes = nodes.size(); + const size_t nedges = edges.size(); + const size_t nlev = vector_field.levels(); + if ( curl_field.levels() != nlev ) + throw eckit::AssertionFailed( "curl field should have same number of levels", Here() ); + + const auto vector = + vector_field.levels() + ? array::make_view( vector_field ).slice( Range::all(), Range::all(), Range::all() ) + : array::make_view( vector_field ).slice( Range::all(), Range::dummy(), Range::all() ); + auto curl = curl_field.levels() ? array::make_view( curl_field ).slice( Range::all(), Range::all() ) + : array::make_view( curl_field ).slice( Range::all(), Range::dummy() ); + + const auto lonlat_deg = array::make_view( nodes.lonlat() ); + const auto dual_volumes = array::make_view( nodes.field( "dual_volumes" ) ); + const auto dual_normals = array::make_view( edges.field( "dual_normals" ) ); + const auto edge_is_pole = array::make_view( edges.field( "is_pole_edge" ) ); + const auto node2edge_sign = array::make_view( nodes.field( "node2edge_sign" ) ); + + const mesh::Connectivity& node2edge = nodes.edge_connectivity(); + const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); + + array::ArrayT avgS_arr( nedges, nlev, 2ul ); + array::ArrayView avgS = array::make_view( avgS_arr ); + + const double scale = deg2rad * deg2rad * radius * radius; + + atlas_omp_parallel { + atlas_omp_for( size_t jedge = 0; jedge < nedges; ++jedge ) { + size_t ip1 = edge2node( jedge, 0 ); + size_t ip2 = edge2node( jedge, 1 ); + double y1 = lonlat_deg( ip1, LAT ) * deg2rad; + double y2 = lonlat_deg( ip2, LAT ) * deg2rad; + double rcosy1 = radius * std::cos( y1 ); + double rcosy2 = radius * std::cos( y2 ); + + double pbc = 1 - edge_is_pole( jedge ); + + for ( size_t jlev = 0; jlev < nlev; ++jlev ) { + double avg[2] = {( rcosy1 * vector( ip1, jlev, LON ) + rcosy2 * vector( ip2, jlev, LON ) ) * 0.5 * + pbc, // (force R*cos(y)=0 at pole) + ( radius * vector( ip1, jlev, LAT ) + radius * vector( ip2, jlev, LAT ) ) * 0.5}; + avgS( jedge, jlev, LON ) = dual_normals( jedge, LAT ) * deg2rad * avg[LON]; + // above = 0 at pole by construction of pbc + avgS( jedge, jlev, LAT ) = dual_normals( jedge, LON ) * deg2rad * avg[LAT]; + // above = 0 at pole by construction of S + // We don't need the non-cross terms for curl, i.e. + // dual_normals(jedge,LON)*deg2rad*avg[LON] + // and dual_normals(jedge,LAT)*deg2rad*avg[LAT] + } + } -void Nabla::curl(const Field& vector_field, Field& curl_field) const -{ - const double radius = fvm_->radius(); - const double deg2rad = M_PI/180.; - - const mesh::Edges &edges = fvm_->mesh().edges(); - const mesh::Nodes &nodes = fvm_->mesh().nodes(); - - const size_t nnodes = nodes.size(); - const size_t nedges = edges.size(); - const size_t nlev = vector_field.levels(); - if( curl_field.levels() != nlev ) - throw eckit::AssertionFailed("curl field should have same number of levels",Here()); - - - const auto vector = vector_field.levels() ? array::make_view( vector_field ).slice(Range::all(),Range::all(),Range::all()) - : array::make_view( vector_field ).slice(Range::all(),Range::dummy(),Range::all()); - auto curl = curl_field.levels() ? array::make_view( curl_field ).slice(Range::all(),Range::all()) - : array::make_view( curl_field ).slice(Range::all(),Range::dummy()); - - const auto lonlat_deg = array::make_view( nodes.lonlat() ); - const auto dual_volumes = array::make_view( nodes.field("dual_volumes") ); - const auto dual_normals = array::make_view( edges.field("dual_normals") ); - const auto edge_is_pole = array::make_view( edges.field("is_pole_edge") ); - const auto node2edge_sign = array::make_view( nodes.field("node2edge_sign") ); - - const mesh::Connectivity& node2edge = nodes.edge_connectivity(); - const mesh::MultiBlockConnectivity& edge2node = edges.node_connectivity(); - - array::ArrayT avgS_arr(nedges,nlev,2ul); - array::ArrayView avgS = array::make_view(avgS_arr); - - const double scale = deg2rad*deg2rad*radius*radius; - - atlas_omp_parallel - { - atlas_omp_for( size_t jedge=0; jedgenode_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); - divergence(grad,lapl); +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 ); + divergence( grad, lapl ); } - - -} // namespace fvm -} // namespace numerics -} // namespace atlas +} // namespace fvm +} // namespace numerics +} // namespace atlas diff --git a/src/atlas/numerics/fvm/Nabla.h b/src/atlas/numerics/fvm/Nabla.h index 8388a48ce..3cea90661 100644 --- a/src/atlas/numerics/fvm/Nabla.h +++ b/src/atlas/numerics/fvm/Nabla.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,41 +16,43 @@ namespace atlas { namespace numerics { -namespace fvm { - class Method; -} } } +namespace fvm { +class Method; +} +} // namespace numerics +} // namespace atlas -namespace atlas { class Field; } +namespace atlas { +class Field; +} namespace atlas { namespace numerics { namespace fvm { class Nabla : public atlas::numerics::Nabla::nabla_t { - public: - Nabla(const atlas::numerics::Method &, const eckit::Parametrisation &); - virtual ~Nabla(); + Nabla( const atlas::numerics::Method&, const eckit::Parametrisation& ); + virtual ~Nabla(); - void gradient(const Field &scalar, Field &grad) const; - void divergence(const Field &vector, Field &div) const; - void curl(const Field &vector, Field &curl) const; - void laplacian(const Field &scalar, Field &laplacian) const; + void gradient( const Field& scalar, Field& grad ) const; + void divergence( const Field& vector, Field& div ) const; + void curl( const Field& vector, Field& curl ) const; + void laplacian( const Field& scalar, Field& laplacian ) const; private: - void setup(); + void setup(); - void gradient_of_scalar(const Field &scalar, Field &grad) const; - void gradient_of_vector(const Field &vector, Field &grad) const; + void gradient_of_scalar( const Field& scalar, Field& grad ) const; + void gradient_of_vector( const Field& vector, Field& grad ) const; private: - - fvm::Method const *fvm_; - std::vector pole_edges_; + fvm::Method const* fvm_; + std::vector pole_edges_; }; // ------------------------------------------------------------------ -} // namespace fvm -} // namespace numerics -} // namespace atlas +} // namespace fvm +} // namespace numerics +} // namespace atlas diff --git a/src/atlas/option.h b/src/atlas/option.h index 3c94f25e6..d17ae05ca 100644 --- a/src/atlas/option.h +++ b/src/atlas/option.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ diff --git a/src/atlas/option/Options.cc b/src/atlas/option/Options.cc index abf6070ad..0183c32ea 100644 --- a/src/atlas/option/Options.cc +++ b/src/atlas/option/Options.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,68 +17,55 @@ namespace atlas { namespace option { -type::type(const std::string &_type) -{ - set("type",_type); +type::type( const std::string& _type ) { + set( "type", _type ); } -halo::halo(size_t size) -{ - set("halo",size); +halo::halo( size_t size ) { + set( "halo", size ); } -datatype::datatype(array::DataType::kind_t kind) -{ - set("datatype",kind); +datatype::datatype( array::DataType::kind_t kind ) { + set( "datatype", kind ); } -datatype::datatype(const std::string &str ) -{ - set("datatype",array::DataType::str_to_kind(str)); +datatype::datatype( const std::string& str ) { + set( "datatype", array::DataType::str_to_kind( str ) ); } -datatype::datatype(array::DataType dtype) -{ - set("datatype",dtype.kind()); +datatype::datatype( array::DataType dtype ) { + set( "datatype", dtype.kind() ); } -name::name(const std::string &_name) -{ - set("name",_name); +name::name( const std::string& _name ) { + set( "name", _name ); } -global::global(size_t _owner) -{ - set("global",true); - set("owner",_owner); +global::global( size_t _owner ) { + set( "global", true ); + set( "owner", _owner ); } -levels::levels(size_t _levels) -{ - set("levels",_levels); +levels::levels( size_t _levels ) { + set( "levels", _levels ); } -variables::variables(size_t _variables) -{ - set("variables",_variables); +variables::variables( size_t _variables ) { + set( "variables", _variables ); } - -radius::radius(double _radius) -{ - set("radius",_radius); +radius::radius( double _radius ) { + set( "radius", _radius ); } -radius::radius(const std::string &key) -{ - if( key == "Earth" ) { - set("radius",util::Earth::radiusInMeters()); - } else { - NOTIMP; - } +radius::radius( const std::string& key ) { + if ( key == "Earth" ) { set( "radius", util::Earth::radiusInMeters() ); } + else { + NOTIMP; + } } // ---------------------------------------------------------------------------- -} // namespace option -} // namespace atlas +} // namespace option +} // namespace atlas diff --git a/src/atlas/option/Options.h b/src/atlas/option/Options.h index 6728b455f..d9537eb00 100644 --- a/src/atlas/option/Options.h +++ b/src/atlas/option/Options.h @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "atlas/util/Config.h" #include "atlas/array/DataType.h" +#include "atlas/util/Config.h" // ---------------------------------------------------------------------------- @@ -22,79 +23,77 @@ namespace option { class type : public util::Config { public: - type( const std::string& ); + type( const std::string& ); }; // ---------------------------------------------------------------------------- class global : public util::Config { public: - global( size_t owner = 0 ); + global( size_t owner = 0 ); }; // ---------------------------------------------------------------------------- class levels : public util::Config { public: - levels( size_t ); + levels( size_t ); }; // ---------------------------------------------------------------------------- class variables : public util::Config { public: - variables( size_t ); + variables( size_t ); }; // ---------------------------------------------------------------------------- class name : public util::Config { public: - name( const std::string& ); + name( const std::string& ); }; // ---------------------------------------------------------------------------- -template< typename T > +template class datatypeT : public util::Config { public: - datatypeT(); + datatypeT(); }; // ---------------------------------------------------------------------------- class datatype : public util::Config { public: - datatype( array::DataType::kind_t ); - datatype( const std::string& ); - datatype( array::DataType ); + datatype( array::DataType::kind_t ); + datatype( const std::string& ); + datatype( array::DataType ); }; // ---------------------------------------------------------------------------- class halo : public util::Config { public: - halo(size_t size); + halo( size_t size ); }; // ---------------------------------------------------------------------------- class radius : public util::Config { public: - radius( double ); - radius( const std::string& = "Earth" ); + radius( double ); + radius( const std::string& = "Earth" ); }; // ---------------------------------------------------------------------------- // Definitions // ---------------------------------------------------------------------------- -template +template datatypeT::datatypeT() { - set("datatype",array::DataType::kind()); + set( "datatype", array::DataType::kind() ); } - - -} // namespace option -} // namespace atlas +} // namespace option +} // namespace atlas diff --git a/src/atlas/option/TransOptions.cc b/src/atlas/option/TransOptions.cc index 5265051ad..3fec20074 100644 --- a/src/atlas/option/TransOptions.cc +++ b/src/atlas/option/TransOptions.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,62 +16,48 @@ namespace atlas { namespace option { -vorticity_divergence_fields::vorticity_divergence_fields(bool v) -{ - set("vorticity_divergence_fields",v); +vorticity_divergence_fields::vorticity_divergence_fields( bool v ) { + set( "vorticity_divergence_fields", v ); } -wind_EW_derivatives::wind_EW_derivatives(bool v) -{ - set("wind_EW_derivatives",v); +wind_EW_derivatives::wind_EW_derivatives( bool v ) { + set( "wind_EW_derivatives", v ); } -scalar_derivatives::scalar_derivatives(bool v) -{ - set("scalar_derivatives",v); +scalar_derivatives::scalar_derivatives( bool v ) { + set( "scalar_derivatives", v ); } -flt::flt(bool flt) -{ - set("flt",flt); +flt::flt( bool flt ) { + set( "flt", flt ); } -fft::fft( FFT fft ) -{ - static const std::map FFT_to_string = - { - {FFT::FFT992, "FFT992"}, - {FFT::FFTW, "FFTW" } - }; - set("fft",FFT_to_string.at(fft)); +fft::fft( FFT fft ) { + static const std::map FFT_to_string = {{FFT::FFT992, "FFT992"}, {FFT::FFTW, "FFTW"}}; + set( "fft", FFT_to_string.at( fft ) ); } -fft::fft( const std::string& fft ) -{ - set("fft",fft); +fft::fft( const std::string& fft ) { + set( "fft", fft ); } -split_latitudes::split_latitudes(bool split_latitudes) -{ - set("split_latitudes",split_latitudes); +split_latitudes::split_latitudes( bool split_latitudes ) { + set( "split_latitudes", split_latitudes ); } -write_legendre::write_legendre( const eckit::PathName& filepath ) -{ - set("write_legendre",filepath); +write_legendre::write_legendre( const eckit::PathName& filepath ) { + set( "write_legendre", filepath ); } -read_legendre::read_legendre( const eckit::PathName& filepath ) -{ - set("read_legendre",filepath); +read_legendre::read_legendre( const eckit::PathName& filepath ) { + set( "read_legendre", filepath ); } -nproma::nproma( int nproma ) -{ - set("nproma",nproma); +nproma::nproma( int nproma ) { + set( "nproma", nproma ); } // ---------------------------------------------------------------------------- -} // namespace option -} // namespace atlas +} // namespace option +} // namespace atlas diff --git a/src/atlas/option/TransOptions.h b/src/atlas/option/TransOptions.h index 899b76903..0aa990cd6 100644 --- a/src/atlas/option/TransOptions.h +++ b/src/atlas/option/TransOptions.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -19,72 +20,76 @@ namespace option { // ---------------------------------------------------------------------------- -enum class FFT { FFT992=1, FFTW=2 }; +enum class FFT +{ + FFT992 = 1, + FFTW = 2 +}; // ---------------------------------------------------------------------------- class scalar_derivatives : public util::Config { public: - scalar_derivatives( bool ); + scalar_derivatives( bool ); }; // ---------------------------------------------------------------------------- class wind_EW_derivatives : public util::Config { public: - wind_EW_derivatives( bool ); + wind_EW_derivatives( bool ); }; // ---------------------------------------------------------------------------- class vorticity_divergence_fields : public util::Config { public: - vorticity_divergence_fields( bool ); + vorticity_divergence_fields( bool ); }; // ---------------------------------------------------------------------------- class flt : public util::Config { public: - flt( bool ); + flt( bool ); }; // ---------------------------------------------------------------------------- class fft : public util::Config { public: - fft( FFT ); - fft( const std::string& ); + fft( FFT ); + fft( const std::string& ); }; // ---------------------------------------------------------------------------- class split_latitudes : public util::Config { public: - split_latitudes( bool ); + split_latitudes( bool ); }; // ---------------------------------------------------------------------------- class write_legendre : public util::Config { public: - write_legendre( const eckit::PathName& ); + write_legendre( const eckit::PathName& ); }; // ---------------------------------------------------------------------------- class read_legendre : public util::Config { public: - read_legendre( const eckit::PathName& ); + read_legendre( const eckit::PathName& ); }; // ---------------------------------------------------------------------------- class nproma : public util::Config { - nproma( int ); + nproma( int ); }; // ---------------------------------------------------------------------------- -} // namespace option -} // namespace atlas +} // namespace option +} // namespace atlas diff --git a/src/atlas/output/Gmsh.cc b/src/atlas/output/Gmsh.cc index 854580344..bdc6d97c5 100644 --- a/src/atlas/output/Gmsh.cc +++ b/src/atlas/output/Gmsh.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,19 +15,19 @@ #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" -#include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/output/Gmsh.h" +#include "atlas/output/detail/GmshIO.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "atlas/output/detail/GmshIO.h" #include "eckit/exception/Exceptions.h" using atlas::Field; using atlas::FieldSet; -using atlas::Mesh; using atlas::FunctionSpace; +using atlas::Mesh; using eckit::Parametrisation; namespace atlas { @@ -34,42 +35,37 @@ namespace output { // ----------------------------------------------------------------------------- -std::string GmshFileStream::parallelPathName(const PathName& path,int part) -{ - std::stringstream s; - // s << path.dirName() << "/" << path.baseName(false) << "_p" << part << ".msh"; - s << path.asString() << ".p"<(mesh)); - } - - writer(c).write(mesh,c.file); - config_.openmode = "a"; +void Gmsh::write( const Mesh& mesh, const eckit::Parametrisation& config ) const { + Gmsh::Configuration c = config_; + merge( c, config ); + + if ( c.coordinates == "xyz" and not mesh.nodes().has_field( "xyz" ) ) { + Log::debug() << "Building xyz representation for nodes" << std::endl; + mesh::actions::BuildXYZField( "xyz" )( const_cast( mesh ) ); + } + + writer( c ).write( mesh, c.file ); + config_.openmode = "a"; } // ----------------------------------------------------------------------------- -void Gmsh::write( - const Field& field, - const eckit::Parametrisation& config ) const -{ - Gmsh::Configuration c = config_; - merge(c,config); - writer(c).write(field,c.file,openmode(c)); - config_.openmode = "a"; +void Gmsh::write( const Field& field, const eckit::Parametrisation& config ) const { + Gmsh::Configuration c = config_; + merge( c, config ); + writer( c ).write( field, c.file, openmode( c ) ); + config_.openmode = "a"; } // ----------------------------------------------------------------------------- -void Gmsh::write( - const FieldSet& fields, - const eckit::Parametrisation& config) const -{ - Gmsh::Configuration c = config_; - merge(c,config); - writer(c).write(fields,fields.field(0).functionspace(),c.file,openmode(c)); - config_.openmode = "a"; +void Gmsh::write( const FieldSet& fields, const eckit::Parametrisation& config ) const { + Gmsh::Configuration c = config_; + merge( c, config ); + writer( c ).write( fields, fields.field( 0 ).functionspace(), c.file, openmode( c ) ); + config_.openmode = "a"; } // ----------------------------------------------------------------------------- -void Gmsh::write( - const Field& field, - const FunctionSpace& functionspace, - const eckit::Parametrisation& config) const -{ - Gmsh::Configuration c = config_; - merge(c,config); - writer(c).write(field,functionspace,c.file,openmode(c)); - config_.openmode = "a"; +void Gmsh::write( const Field& field, const FunctionSpace& functionspace, const eckit::Parametrisation& config ) const { + Gmsh::Configuration c = config_; + merge( c, config ); + writer( c ).write( field, functionspace, c.file, openmode( c ) ); + config_.openmode = "a"; } // ----------------------------------------------------------------------------- -void Gmsh::write( - const FieldSet& fields, - const FunctionSpace& functionspace, - const eckit::Parametrisation& config) const -{ - Gmsh::Configuration c = config_; - merge(c,config); - writer(c).write(fields,functionspace,c.file,openmode(c)); - config_.openmode = "a"; +void Gmsh::write( const FieldSet& fields, const FunctionSpace& functionspace, + const eckit::Parametrisation& config ) const { + Gmsh::Configuration c = config_; + merge( c, config ); + writer( c ).write( fields, functionspace, c.file, openmode( c ) ); + config_.openmode = "a"; } // ----------------------------------------------------------------------------- extern "C" { -Gmsh* atlas__output__Gmsh__create_pathname_mode(const char* pathname, const char* mode) -{ - Gmsh* gmsh(0); - ATLAS_ERROR_HANDLING( gmsh = new Gmsh(std::string(pathname),std::string(mode) ) ); - return gmsh; +Gmsh* atlas__output__Gmsh__create_pathname_mode( const char* pathname, const char* mode ) { + Gmsh* gmsh( 0 ); + ATLAS_ERROR_HANDLING( gmsh = new Gmsh( std::string( pathname ), std::string( mode ) ) ); + return gmsh; } -Gmsh* atlas__output__Gmsh__create_pathname_mode_config(const char* pathname, const char* mode, const Parametrisation* params) -{ - Gmsh* gmsh(0); - ATLAS_ERROR_HANDLING( gmsh = new Gmsh(std::string(pathname),std::string(mode), *params ) ); - return gmsh; +Gmsh* atlas__output__Gmsh__create_pathname_mode_config( const char* pathname, const char* mode, + const Parametrisation* params ) { + Gmsh* gmsh( 0 ); + ATLAS_ERROR_HANDLING( gmsh = new Gmsh( std::string( pathname ), std::string( mode ), *params ) ); + return gmsh; } -} // extern C +} // extern C -static OutputBuilder< detail::Gmsh > __gmsh("gmsh"); +static OutputBuilder __gmsh( "gmsh" ); -void force_link_atlas_output_detail_gmsh(void*) { - force_link_atlas_output_detail_gmsh(&__gmsh); +void force_link_atlas_output_detail_gmsh( void* ) { + force_link_atlas_output_detail_gmsh( &__gmsh ); } -} // namespace detail +} // namespace detail //---------------------------------------------------------------------------------------------------------------------- +Gmsh::Gmsh( const Output& output ) : Output( output ) {} -Gmsh::Gmsh( const Output& output ) : - Output(output) { -} +Gmsh::Gmsh( Stream& s ) : Output( new detail::Gmsh( s ) ) {} -Gmsh::Gmsh(Stream& s) : - Output( new detail::Gmsh(s) ) { -} - -Gmsh::Gmsh(Stream& s, const eckit::Parametrisation& c) : - Output( new detail::Gmsh(s,c) ) { -} - -Gmsh::Gmsh(const PathName& p, const std::string& mode) : - Output( new detail::Gmsh(p,mode) ) { -} +Gmsh::Gmsh( Stream& s, const eckit::Parametrisation& c ) : Output( new detail::Gmsh( s, c ) ) {} +Gmsh::Gmsh( const PathName& p, const std::string& mode ) : Output( new detail::Gmsh( p, mode ) ) {} -Gmsh::Gmsh(const PathName& p, const std::string& mode, const eckit::Parametrisation& c) : - Output( new detail::Gmsh(p,mode,c) ) { -} - -Gmsh::Gmsh(const PathName& p) : - Output( new detail::Gmsh(p) ) { -} - -Gmsh::Gmsh(const PathName& p, const eckit::Parametrisation& c) : - Output( new detail::Gmsh(p,c) ) { -} +Gmsh::Gmsh( const PathName& p, const std::string& mode, const eckit::Parametrisation& c ) : + Output( new detail::Gmsh( p, mode, c ) ) {} +Gmsh::Gmsh( const PathName& p ) : Output( new detail::Gmsh( p ) ) {} -} // namespace output -} // namespace atlas +Gmsh::Gmsh( const PathName& p, const eckit::Parametrisation& c ) : Output( new detail::Gmsh( p, c ) ) {} +} // namespace output +} // namespace atlas diff --git a/src/atlas/output/Gmsh.h b/src/atlas/output/Gmsh.h index 34f04d048..899dc3e11 100644 --- a/src/atlas/output/Gmsh.h +++ b/src/atlas/output/Gmsh.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -19,8 +20,8 @@ namespace output { namespace detail { class GmshIO; } -} -} +} // namespace output +} // namespace atlas namespace atlas { namespace output { @@ -29,108 +30,90 @@ namespace output { class GmshFileStream : public std::ofstream { public: - static std::string parallelPathName(const PathName& path,int part = mpi::comm().rank()); - GmshFileStream(const PathName& file_path, const char* mode, int part = mpi::comm().rank()); - + static std::string parallelPathName( const PathName& path, int part = mpi::comm().rank() ); + GmshFileStream( const PathName& file_path, const char* mode, int part = mpi::comm().rank() ); }; // ----------------------------------------------------------------------------- namespace detail { class Gmsh : public Output::output_t { - public: + Gmsh( Stream& ); + Gmsh( Stream&, const eckit::Parametrisation& ); - Gmsh(Stream&); - Gmsh(Stream&, const eckit::Parametrisation&); - - Gmsh(const PathName&, const std::string& mode); - Gmsh(const PathName&, const std::string& mode, const eckit::Parametrisation&); + Gmsh( const PathName&, const std::string& mode ); + Gmsh( const PathName&, const std::string& mode, const eckit::Parametrisation& ); - Gmsh(const PathName&); - Gmsh(const PathName&, const eckit::Parametrisation&); + Gmsh( const PathName& ); + Gmsh( const PathName&, const eckit::Parametrisation& ); virtual ~Gmsh(); /// Write mesh file - virtual void write( - const Mesh&, - const eckit::Parametrisation& = util::NoConfig() ) const; + virtual void write( const Mesh&, const eckit::Parametrisation& = util::NoConfig() ) const; /// Write field to file - virtual void write( - const Field&, - const eckit::Parametrisation& = util::NoConfig() ) const; + virtual void write( const Field&, const eckit::Parametrisation& = util::NoConfig() ) const; /// Write fieldset to file using FunctionSpace - virtual void write( - const FieldSet&, - const eckit::Parametrisation& = util::NoConfig() ) const; + virtual void write( const FieldSet&, const eckit::Parametrisation& = util::NoConfig() ) const; /// Write field to file using Functionspace - virtual void write( - const Field&, - const FunctionSpace&, - const eckit::Parametrisation& = util::NoConfig() ) const; + virtual void write( const Field&, const FunctionSpace&, const eckit::Parametrisation& = util::NoConfig() ) const; /// Write fieldset to file using FunctionSpace - virtual void write( - const FieldSet&, - const FunctionSpace&, - const eckit::Parametrisation& = util::NoConfig() ) const; + virtual void write( const FieldSet&, const FunctionSpace&, const eckit::Parametrisation& = util::NoConfig() ) const; public: - - struct Configuration { - bool binary; - bool edges; - bool elements; - bool gather; - bool ghost; - bool info; - std::vector levels; - std::string nodes; - std::string file; - std::string openmode; - std::string coordinates; - }; - - static void setGmshConfiguration(detail::GmshIO&, const Configuration& ); + struct Configuration { + bool binary; + bool edges; + bool elements; + bool gather; + bool ghost; + bool info; + std::vector levels; + std::string nodes; + std::string file; + std::string openmode; + std::string coordinates; + }; + + static void setGmshConfiguration( detail::GmshIO&, const Configuration& ); private: + mutable Configuration config_; - - mutable Configuration config_; - - void defaults(); + void defaults(); }; -} +} // namespace detail // ----------------------------------------------------------------------------- class Gmsh : public Output { public: - Gmsh( const Output& output ); - Gmsh(Stream&); - Gmsh(Stream&, const eckit::Parametrisation&); + Gmsh( const Output& output ); + Gmsh( Stream& ); + Gmsh( Stream&, const eckit::Parametrisation& ); - Gmsh(const PathName&, const std::string& mode); - Gmsh(const PathName&, const std::string& mode, const eckit::Parametrisation&); + Gmsh( const PathName&, const std::string& mode ); + Gmsh( const PathName&, const std::string& mode, const eckit::Parametrisation& ); - Gmsh(const PathName&); - Gmsh(const PathName&, const eckit::Parametrisation&); + Gmsh( const PathName& ); + Gmsh( const PathName&, const eckit::Parametrisation& ); }; // ----------------------------------------------------------------------------- extern "C" { -detail::Gmsh* atlas__output__Gmsh__create_pathname_mode(const char* pathname, const char* mode); -detail::Gmsh* atlas__output__Gmsh__create_pathname_mode_config(const char* pathname, const char* mode, const eckit::Parametrisation* params); - +detail::Gmsh* atlas__output__Gmsh__create_pathname_mode( const char* pathname, const char* mode ); +detail::Gmsh* atlas__output__Gmsh__create_pathname_mode_config( const char* pathname, const char* mode, + const eckit::Parametrisation* params ); } // ----------------------------------------------------------------------------- -} // namespace output -} // namespace atlas +} // namespace output +} // namespace atlas diff --git a/src/atlas/output/Output.cc b/src/atlas/output/Output.cc index 2f465a55f..823d25e38 100644 --- a/src/atlas/output/Output.cc +++ b/src/atlas/output/Output.cc @@ -4,258 +4,190 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include #include -#include "eckit/thread/AutoLock.h" -#include "eckit/thread/Mutex.h" -#include "eckit/exception/Exceptions.h" -#include "atlas/mesh/Mesh.h" #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" -#include "atlas/output/Output.h" +#include "atlas/mesh/Mesh.h" #include "atlas/output/Gmsh.h" +#include "atlas/output/Output.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" -using atlas::field::FieldImpl; using atlas::FieldSet; -using atlas::field::FieldSetImpl; -using atlas::Mesh; using atlas::FunctionSpace; +using atlas::Mesh; +using atlas::field::FieldImpl; +using atlas::field::FieldSetImpl; using eckit::Parametrisation; namespace atlas { namespace output { -static eckit::Mutex *local_mutex = 0; -static std::map *m = 0; -static pthread_once_t once = PTHREAD_ONCE_INIT; +static eckit::Mutex* local_mutex = 0; +static std::map* m = 0; +static pthread_once_t once = PTHREAD_ONCE_INIT; static void init() { local_mutex = new eckit::Mutex(); - m = new std::map(); + m = new std::map(); } -OutputImpl::OutputImpl() { -} +OutputImpl::OutputImpl() {} -OutputImpl::~OutputImpl() { -} +OutputImpl::~OutputImpl() {} -Output::Output() : - output_( nullptr ) { -} +Output::Output() : output_( nullptr ) {} -Output::Output( const output_t* output ) : - output_( output ) { -} - -Output::Output( const Output& output ) : - output_( output.output_ ) { -} +Output::Output( const output_t* output ) : output_( output ) {} +Output::Output( const Output& output ) : output_( output.output_ ) {} -Output::Output(const std::string &key, Stream& stream, const eckit::Parametrisation ¶ms) : - output_( OutputFactory::build(key,stream,params) ) { -} - +Output::Output( const std::string& key, Stream& stream, const eckit::Parametrisation& params ) : + output_( OutputFactory::build( key, stream, params ) ) {} /// Write mesh file -void Output::write( - const Mesh& m, - const eckit::Parametrisation& c ) const { - return output_->write(m,c); +void Output::write( const Mesh& m, const eckit::Parametrisation& c ) const { + return output_->write( m, c ); } /// Write field to file -void Output::write( - const Field& f, - const eckit::Parametrisation& c ) const { - return output_->write(f,c); +void Output::write( const Field& f, const eckit::Parametrisation& c ) const { + return output_->write( f, c ); } /// Write fieldset to file using FunctionSpace -void Output::write( - const FieldSet& f, - const eckit::Parametrisation& c ) const { - return output_->write(f,c); +void Output::write( const FieldSet& f, const eckit::Parametrisation& c ) const { + return output_->write( f, c ); } /// Write field to file using Functionspace -void Output::write( - const Field& f, - const FunctionSpace& fs, - const eckit::Parametrisation& c ) const { - return output_->write(f,fs,c); +void Output::write( const Field& f, const FunctionSpace& fs, const eckit::Parametrisation& c ) const { + return output_->write( f, fs, c ); } /// Write fieldset to file using FunctionSpace -void Output::write( - const FieldSet& f, - const FunctionSpace& fs, - const eckit::Parametrisation& c ) const { - return output_->write(f,fs,c); +void Output::write( const FieldSet& f, const FunctionSpace& fs, const eckit::Parametrisation& c ) const { + return output_->write( f, fs, c ); } +OutputFactory::OutputFactory( const std::string& name ) : name_( name ) { + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); + if ( m->find( name ) != m->end() ) { throw eckit::SeriousBug( "Duplicate OutputFactory entry " + name ); } -OutputFactory::OutputFactory(const std::string &name): - name_(name) { - - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); - - if(m->find(name) != m->end()) { - throw eckit::SeriousBug("Duplicate OutputFactory entry " + name); - } - - (*m)[name] = this; + ( *m )[name] = this; } - OutputFactory::~OutputFactory() { - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); - m->erase(name_); + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); + m->erase( name_ ); } - -void OutputFactory::list(std::ostream& out) { - - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); +void OutputFactory::list( std::ostream& out ) { + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); const char* sep = ""; - for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { - out << sep << (*j).first; + for ( std::map::const_iterator j = m->begin(); j != m->end(); ++j ) { + out << sep << ( *j ).first; sep = ", "; } } +const OutputImpl* OutputFactory::build( const std::string& name, Stream& stream ) { + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); -const OutputImpl *OutputFactory::build(const std::string &name, Stream& stream) { - - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); - - std::map::const_iterator j = m->find(name); + std::map::const_iterator j = m->find( name ); Log::debug() << "Looking for OutputFactory [" << name << "]" << std::endl; - if (j == m->end()) { + 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) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No OutputFactory called ") + name); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << std::endl; + throw eckit::SeriousBug( std::string( "No OutputFactory called " ) + name ); } - return (*j).second->make(stream); + return ( *j ).second->make( stream ); } -const OutputImpl *OutputFactory::build(const std::string& name, Stream& stream, const eckit::Parametrisation& param) { +const OutputImpl* OutputFactory::build( const std::string& name, Stream& stream, const eckit::Parametrisation& param ) { + pthread_once( &once, init ); + eckit::AutoLock lock( local_mutex ); - pthread_once(&once, init); - eckit::AutoLock lock(local_mutex); - - std::map::const_iterator j = m->find(name); + std::map::const_iterator j = m->find( name ); Log::debug() << "Looking for OutputFactory [" << name << "]" << std::endl; - if (j == m->end()) { + 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) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No OutputFactory called ") + name); + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << std::endl; + throw eckit::SeriousBug( std::string( "No OutputFactory called " ) + name ); } - return (*j).second->make(stream,param); + return ( *j ).second->make( stream, param ); } extern "C" { -void atlas__Output__delete(OutputImpl* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - delete This; - ); +void atlas__Output__delete( OutputImpl* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); delete This; ); } -const OutputImpl* atlas__Output__create(const char* factory_key, Stream* stream, const eckit::Parametrisation* params) -{ - const OutputImpl* output(0); - ATLAS_ERROR_HANDLING ( - // ASSERT(stream); - ASSERT(params); - { - Output o( std::string{factory_key}, *stream, *params ); - output = o.get(); - output->attach(); - } - output->detach(); - ); - return output; +const OutputImpl* atlas__Output__create( const char* factory_key, Stream* stream, + const eckit::Parametrisation* params ) { + const OutputImpl* output( 0 ); + ATLAS_ERROR_HANDLING( + // ASSERT(stream); + ASSERT( params ); { + Output o( std::string{factory_key}, *stream, *params ); + output = o.get(); + output->attach(); + } output->detach(); ); + return output; } -void atlas__Output__write_mesh(const OutputImpl* This, Mesh::Implementation* mesh, const Parametrisation* params) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(mesh); - ASSERT(params); - Mesh m(mesh); - This->write(m,*params); - ); +void atlas__Output__write_mesh( const OutputImpl* This, Mesh::Implementation* mesh, const Parametrisation* params ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( mesh ); ASSERT( params ); Mesh m( mesh ); + This->write( m, *params ); ); } -void atlas__Output__write_fieldset(const OutputImpl* This, const FieldSetImpl* fieldset, const Parametrisation* params) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(fieldset); - ASSERT(params); - This->write(fieldset,*params); - ); +void atlas__Output__write_fieldset( const OutputImpl* This, const FieldSetImpl* fieldset, + const Parametrisation* params ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( fieldset ); ASSERT( params ); This->write( fieldset, *params ); ); } -void atlas__Output__write_field(const OutputImpl* This, const FieldImpl* field, const Parametrisation* params) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(field); - ASSERT(params); - This->write(field,*params); - ); +void atlas__Output__write_field( const OutputImpl* This, const FieldImpl* field, const Parametrisation* params ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( field ); ASSERT( params ); This->write( field, *params ); ); } -void atlas__Output__write_fieldset_fs(const OutputImpl* This, const FieldSetImpl* fieldset, const functionspace::FunctionSpaceImpl* functionspace, const Parametrisation* params) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(fieldset); - ASSERT(functionspace); - ASSERT(params); - This->write(fieldset,functionspace,*params); - ); +void atlas__Output__write_fieldset_fs( const OutputImpl* This, const FieldSetImpl* fieldset, + const functionspace::FunctionSpaceImpl* functionspace, + const Parametrisation* params ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( fieldset ); ASSERT( functionspace ); ASSERT( params ); + This->write( fieldset, functionspace, *params ); ); } -void atlas__Output__write_field_fs(const OutputImpl* This, const FieldImpl* field, const functionspace::FunctionSpaceImpl* functionspace, const Parametrisation* params) -{ - ATLAS_ERROR_HANDLING( - ASSERT(This); - ASSERT(field); - ASSERT(functionspace); - ASSERT(params); - This->write(field,functionspace,*params); - ); +void atlas__Output__write_field_fs( const OutputImpl* This, const FieldImpl* field, + const functionspace::FunctionSpaceImpl* functionspace, + const Parametrisation* params ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( field ); ASSERT( functionspace ); ASSERT( params ); + This->write( field, functionspace, *params ); ); } - } -} // namespace output -} // namespace atlas - +} // namespace output +} // namespace atlas diff --git a/src/atlas/output/Output.h b/src/atlas/output/Output.h index 9bc4779ed..85919a6a3 100644 --- a/src/atlas/output/Output.h +++ b/src/atlas/output/Output.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,34 +13,36 @@ #include #include +#include "atlas/util/Config.h" +#include "eckit/config/Parametrisation.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" #include "eckit/serialisation/FileStream.h" -#include "eckit/config/Parametrisation.h" -#include "atlas/util/Config.h" namespace eckit { - class Parametrisation; - class PathName; -} +class Parametrisation; +class PathName; +} // namespace eckit namespace atlas { - class Mesh; +class Mesh; } namespace atlas { - class Field; - class FieldSet; +class Field; +class FieldSet; namespace field { - class FieldImpl; - class FieldSetImpl; -} } +class FieldImpl; +class FieldSetImpl; +} // namespace field +} // namespace atlas namespace atlas { - class FunctionSpace; +class FunctionSpace; namespace functionspace { - class FunctionSpaceImpl; -} } +class FunctionSpaceImpl; +} +} // namespace atlas namespace atlas { namespace output { @@ -50,153 +53,123 @@ typedef eckit::PathName PathName; // ----------------------------------------------------------------------------- class OutputImpl : public eckit::Owned { - public: - - typedef atlas::util::Config Parameters; + typedef atlas::util::Config Parameters; public: - OutputImpl(); virtual ~OutputImpl(); /// Write mesh file - virtual void write( - const Mesh&, - const eckit::Parametrisation& = util::NoConfig() ) const = 0; + virtual void write( const Mesh&, const eckit::Parametrisation& = util::NoConfig() ) const = 0; /// Write field to file - virtual void write( - const Field&, - const eckit::Parametrisation& = util::NoConfig() ) const = 0; + virtual void write( const Field&, const eckit::Parametrisation& = util::NoConfig() ) const = 0; /// Write fieldset to file using FunctionSpace - virtual void write( - const FieldSet&, - const eckit::Parametrisation& = util::NoConfig() ) const = 0; + virtual void write( const FieldSet&, const eckit::Parametrisation& = util::NoConfig() ) const = 0; /// Write field to file using Functionspace - virtual void write( - const Field&, - const FunctionSpace&, - const eckit::Parametrisation& = util::NoConfig() ) const = 0; + virtual void write( const Field&, const FunctionSpace&, + const eckit::Parametrisation& = util::NoConfig() ) const = 0; /// Write fieldset to file using FunctionSpace - virtual void write( - const FieldSet&, - const FunctionSpace&, - const eckit::Parametrisation& = util::NoConfig() ) const = 0; - + virtual void write( const FieldSet&, const FunctionSpace&, + const eckit::Parametrisation& = util::NoConfig() ) const = 0; }; class Output { - public: - - using output_t = OutputImpl; + using output_t = OutputImpl; private: - - eckit::SharedPtr output_; + eckit::SharedPtr output_; public: - Output(); - Output(const output_t*); - Output(const Output&); - Output(const std::string&, Stream&, const eckit::Parametrisation & = util::NoConfig() ); + Output( const output_t* ); + Output( const Output& ); + Output( const std::string&, Stream&, const eckit::Parametrisation& = util::NoConfig() ); /// Write mesh file - void write( - const Mesh&, - const eckit::Parametrisation& = util::NoConfig() ) const; + void write( const Mesh&, const eckit::Parametrisation& = util::NoConfig() ) const; /// Write field to file - void write( - const Field&, - const eckit::Parametrisation& = util::NoConfig() ) const; + void write( const Field&, const eckit::Parametrisation& = util::NoConfig() ) const; /// Write fieldset to file using FunctionSpace - void write( - const FieldSet&, - const eckit::Parametrisation& = util::NoConfig() ) const; + void write( const FieldSet&, const eckit::Parametrisation& = util::NoConfig() ) const; /// Write field to file using Functionspace - void write( - const Field&, - const FunctionSpace&, - const eckit::Parametrisation& = util::NoConfig() ) const; + void write( const Field&, const FunctionSpace&, const eckit::Parametrisation& = util::NoConfig() ) const; /// Write fieldset to file using FunctionSpace - void write( - const FieldSet&, - const FunctionSpace&, - const eckit::Parametrisation& = util::NoConfig() ) const; + void write( const FieldSet&, const FunctionSpace&, const eckit::Parametrisation& = util::NoConfig() ) const; const output_t* get() const { return output_.get(); } }; - - - - class OutputFactory { - public: +public: /*! - * \brief build Output with factory key, and default options - * \return mesh generator - */ - static const OutputImpl* build(const std::string&, Stream&); + * \brief build Output with factory key, and default options + * \return mesh generator + */ + static const OutputImpl* build( const std::string&, Stream& ); /*! - * \brief build Output with factory key inside parametrisation, - * and options specified in parametrisation as well - * \return mesh generator - */ - static const OutputImpl* build(const std::string&, Stream&, const eckit::Parametrisation&); + * \brief build Output with factory key inside parametrisation, + * and options specified in parametrisation as well + * \return mesh generator + */ + static const OutputImpl* build( const std::string&, Stream&, const eckit::Parametrisation& ); /*! - * \brief list all registered mesh generators - */ - static void list(std::ostream &); + * \brief list all registered mesh generators + */ + static void list( std::ostream& ); - private: +private: std::string name_; - virtual const OutputImpl* make(Stream&) = 0 ; - virtual const OutputImpl* make(Stream&, const eckit::Parametrisation&) = 0 ; - - protected: + virtual const OutputImpl* make( Stream& ) = 0; + virtual const OutputImpl* make( Stream&, const eckit::Parametrisation& ) = 0; - OutputFactory(const std::string&); +protected: + OutputFactory( const std::string& ); virtual ~OutputFactory(); - }; - -template +template class OutputBuilder : public OutputFactory { - virtual const OutputImpl* make(Stream& stream) { - return new T(stream); - } - virtual const OutputImpl* make(Stream& stream, const eckit::Parametrisation& param) { - return new T(stream,param); - } - public: - OutputBuilder(const std::string& name) : OutputFactory(name) {} + virtual const OutputImpl* make( Stream& stream ) { return new T( stream ); } + virtual const OutputImpl* make( Stream& stream, const eckit::Parametrisation& param ) { + return new T( stream, param ); + } + +public: + OutputBuilder( const std::string& name ) : OutputFactory( name ) {} }; // ----------------------------------------------------------------------------- extern "C" { -void atlas__Output__delete(OutputImpl* This); -const OutputImpl* atlas__Output__create(const char* factory_key, Stream* stream, const eckit::Parametrisation* params); -void atlas__Output__write_mesh(const OutputImpl* This, Mesh::Implementation* mesh, const eckit::Parametrisation* params); -void atlas__Output__write_fieldset(const OutputImpl* This, const field::FieldSetImpl* fieldset, const eckit::Parametrisation* params); -void atlas__Output__write_field(const OutputImpl* This, const field::FieldImpl* field, const eckit::Parametrisation* params); -void atlas__Output__write_fieldset_fs(const OutputImpl* This, const field::FieldSetImpl* fieldset, const functionspace::FunctionSpaceImpl* functionspace, const eckit::Parametrisation* params); -void atlas__Output__write_field_fs(const OutputImpl* This, const field::FieldImpl* field, const functionspace::FunctionSpaceImpl* functionspace, const eckit::Parametrisation* params); +void atlas__Output__delete( OutputImpl* This ); +const OutputImpl* atlas__Output__create( const char* factory_key, Stream* stream, + const eckit::Parametrisation* params ); +void atlas__Output__write_mesh( const OutputImpl* This, Mesh::Implementation* mesh, + const eckit::Parametrisation* params ); +void atlas__Output__write_fieldset( const OutputImpl* This, const field::FieldSetImpl* fieldset, + const eckit::Parametrisation* params ); +void atlas__Output__write_field( const OutputImpl* This, const field::FieldImpl* field, + const eckit::Parametrisation* params ); +void atlas__Output__write_fieldset_fs( const OutputImpl* This, const field::FieldSetImpl* fieldset, + const functionspace::FunctionSpaceImpl* functionspace, + const eckit::Parametrisation* params ); +void atlas__Output__write_field_fs( const OutputImpl* This, const field::FieldImpl* field, + const functionspace::FunctionSpaceImpl* functionspace, + const eckit::Parametrisation* params ); } -} // namespace output -} // namespace atlas +} // namespace output +} // namespace atlas diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index 01e133a01..967d8a412 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -4,36 +4,37 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include -#include -#include +#include "atlas/output/detail/GmshIO.h" #include +#include +#include #include -#include "eckit/filesystem/PathName.h" -#include "eckit/exception/Exceptions.h" -#include "eckit/utils/Translator.h" -#include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/ElementType.h" -#include "atlas/mesh/Elements.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/field/Field.h" -#include "atlas/field/FieldSet.h" -#include "atlas/functionspace/FunctionSpace.h" -#include "atlas/util/Constants.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/output/detail/GmshIO.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/parallel/GatherScatter.h" +#include #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" #include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" +#include "atlas/field/FieldSet.h" +#include "atlas/functionspace/FunctionSpace.h" +#include "atlas/mesh/ElementType.h" +#include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" +#include "atlas/parallel/GatherScatter.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" +#include "atlas/util/Constants.h" +#include "atlas/util/CoordinateEnums.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/filesystem/PathName.h" +#include "eckit/utils/Translator.h" using namespace eckit; using atlas::functionspace::NodeColumns; @@ -49,311 +50,283 @@ static double rad2deg = util::Constants::radiansToDegrees(); class GmshFile : public std::ofstream { public: - GmshFile(const PathName& file_path, std::ios_base::openmode mode, int part = atlas::mpi::comm().rank()) - { - PathName par_path(file_path); - if (atlas::mpi::comm().size() == 1 || part == -1) { - std::ofstream::open(par_path.localPath(), mode); - } else { - Translator to_str; - if (atlas::mpi::comm().rank() == 0) { - PathName par_path(file_path); - std::ofstream par_file(par_path.localPath(), std::ios_base::out); - for(size_t p = 0; p < atlas::mpi::comm().size(); ++p) { - PathName loc_path(file_path); - // loc_path = loc_path.baseName(false) + "_p" + to_str(p) + ".msh"; - loc_path = loc_path.baseName(false) + ".msh.p" + to_str(p); - par_file << "Merge \"" << loc_path << "\";" << std::endl; + GmshFile( const PathName& file_path, std::ios_base::openmode mode, int part = atlas::mpi::comm().rank() ) { + PathName par_path( file_path ); + if ( atlas::mpi::comm().size() == 1 || part == -1 ) { std::ofstream::open( par_path.localPath(), mode ); } + else { + Translator to_str; + if ( atlas::mpi::comm().rank() == 0 ) { + PathName par_path( file_path ); + std::ofstream par_file( par_path.localPath(), std::ios_base::out ); + for ( size_t p = 0; p < atlas::mpi::comm().size(); ++p ) { + PathName loc_path( file_path ); + // loc_path = loc_path.baseName(false) + "_p" + to_str(p) + ".msh"; + loc_path = loc_path.baseName( false ) + ".msh.p" + to_str( p ); + par_file << "Merge \"" << loc_path << "\";" << std::endl; + } + par_file.close(); + } + PathName path( file_path ); + // path = path.dirName() + "/" + path.baseName(false) + "_p" + + // to_str(part) + ".msh"; + path = path.dirName() + "/" + path.baseName( false ) + ".msh.p" + to_str( part ); + std::ofstream::open( path.localPath(), mode ); } - par_file.close(); - } - PathName path(file_path); - // path = path.dirName() + "/" + path.baseName(false) + "_p" + to_str(part) + ".msh"; - path = path.dirName() + "/" + path.baseName(false) + ".msh.p"+to_str(part); - std::ofstream::open(path.localPath(), mode); } - } }; -enum GmshElementTypes { LINE=1, TRIAG=2, QUAD=3, POINT=15 }; - - +enum GmshElementTypes +{ + LINE = 1, + TRIAG = 2, + QUAD = 3, + POINT = 15 +}; // ---------------------------------------------------------------------------- -void write_header_ascii(std::ostream& out) -{ - out << "$MeshFormat\n"; - out << "2.2 0 "<(&one),sizeof(int)); - out << "\n$EndMeshFormat\n"; +void write_header_binary( std::ostream& out ) { + out << "$MeshFormat\n"; + out << "2.2 1 " << sizeof( double ) << "\n"; + int one = 1; + out.write( reinterpret_cast( &one ), sizeof( int ) ); + out << "\n$EndMeshFormat\n"; } // ---------------------------------------------------------------------------- -namespace { // anonymous +namespace { // anonymous 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() ); - } else { - return make_view( field ).slice( Range::to(ndata), jlev, Range::dummy() ); +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() ); } + 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() ); - } else { - return make_view( field ).slice( Range::to(ndata), Range::dummy() ); + else { + if ( field.variables() ) { return make_view( field ).slice( Range::to( ndata ), Range::all() ); } + else { + return make_view( field ).slice( Range::to( ndata ), Range::dummy() ); + } } - } } -template< typename DATATYPE > -void write_level( std::ostream& out, const array::ArrayView gidx, const array::LocalView data ) { - int ndata = data.shape(0); - int nvars = data.shape(1); - if( nvars == 1) - { - for( size_t n = 0; n < ndata; ++n ) - { - out << gidx(n) << " " << data(n,0) << "\n"; - } - } - else if( nvars <= 3 ) - { - std::vector data_vec(3,0.); - for( size_t n = 0; n < ndata; ++n ) - { - out << gidx(n); - for(size_t v=0; v < nvars; ++v) - data_vec[v] = data(n,v); - for( int v=0; v<3; ++v) - out << " " << data_vec[v]; - out << "\n"; +template +void write_level( std::ostream& out, const array::ArrayView gidx, + const array::LocalView data ) { + int ndata = data.shape( 0 ); + int nvars = data.shape( 1 ); + if ( nvars == 1 ) { + for ( size_t n = 0; n < ndata; ++n ) { + out << gidx( n ) << " " << data( n, 0 ) << "\n"; + } } - } - else if( nvars <= 9 ) - { - std::vector data_vec(9,0.); - if( nvars == 4 ) - { - for( size_t n = 0; n < ndata; ++n ) { - for( int i=0; i<2; ++i ) { - for( int j=0; j<2; ++j ) { - data_vec[i*3+j] = data(n,i*2+j); - } + else if ( nvars <= 3 ) { + std::vector data_vec( 3, 0. ); + for ( size_t n = 0; n < ndata; ++n ) { + out << gidx( n ); + for ( size_t v = 0; v < nvars; ++v ) + data_vec[v] = data( n, v ); + for ( int v = 0; v < 3; ++v ) + out << " " << data_vec[v]; + out << "\n"; } - out << gidx(n); - for( int v=0; v<9; ++v) - out << " " << data_vec[v]; - out << "\n"; - } } - else if( nvars == 9 ) - { - for( size_t n = 0; n < ndata; ++n ) { - for( int i=0; i<3; ++i ) { - for( int j=0; j<3; ++j ) { - data_vec[i*3+j] = data(n,i*2+j); - } + else if ( nvars <= 9 ) { + std::vector data_vec( 9, 0. ); + if ( nvars == 4 ) { + for ( size_t n = 0; n < ndata; ++n ) { + for ( int i = 0; i < 2; ++i ) { + for ( int j = 0; j < 2; ++j ) { + data_vec[i * 3 + j] = data( n, i * 2 + j ); + } + } + out << gidx( n ); + for ( int v = 0; v < 9; ++v ) + out << " " << data_vec[v]; + out << "\n"; + } + } + else if ( nvars == 9 ) { + for ( size_t n = 0; n < ndata; ++n ) { + for ( int i = 0; i < 3; ++i ) { + for ( int j = 0; j < 3; ++j ) { + data_vec[i * 3 + j] = data( n, i * 2 + j ); + } + } + out << gidx( n ); + for ( int v = 0; v < 9; ++v ) + out << " " << data_vec[v]; + out << "\n"; + } + } + else { + NOTIMP; } - out << gidx(n); - for( int v=0; v<9; ++v) - out << " " << data_vec[v]; - out << "\n"; - } } - else - { - NOTIMP; + else { + NOTIMP; } - } - else - { - NOTIMP; - } } std::vector get_levels( int nlev, const Metadata& gmsh_options ) { - std::vector lev; - std::vector gmsh_levels; - gmsh_options.get("levels",gmsh_levels); - if( gmsh_levels.empty() || nlev == 1 ) - { - lev.resize(nlev); - for (size_t ilev=0; ilev < nlev; ++ilev) - lev[ilev] = ilev; - } - else - { - lev = gmsh_levels; - } - return lev; + std::vector lev; + std::vector gmsh_levels; + gmsh_options.get( "levels", gmsh_levels ); + if ( gmsh_levels.empty() || nlev == 1 ) { + lev.resize( nlev ); + for ( size_t ilev = 0; ilev < nlev; ++ilev ) + lev[ilev] = ilev; + } + else { + lev = gmsh_levels; + } + return lev; } std::string field_lev( const Field& field, int jlev ) { - if( field.levels() ) { - char str[6] = {0, 0, 0, 0, 0, 0}; - std::sprintf(str, "[%03lu]",jlev); - return std::string(str); - } else { - return std::string(); - } + if ( field.levels() ) { + char str[6] = {0, 0, 0, 0, 0, 0}; + std::sprintf( str, "[%03lu]", jlev ); + return std::string( str ); + } + else { + return std::string(); + } } double field_time( const Field& field ) { - return field.metadata().has("time") ? field.metadata().get("time") : 0.; + return field.metadata().has( "time" ) ? field.metadata().get( "time" ) : 0.; } int field_step( const Field& field ) { - return field.metadata().has("step") ? field.metadata().get("step") : 0 ; + return field.metadata().has( "step" ) ? field.metadata().get( "step" ) : 0; } int field_vars( int nvars ) { - if ( nvars == 1 ) return nvars; - else if( nvars <= 3 ) return 3; - else if( nvars <= 9 ) return 9; - else return nvars; + if ( nvars == 1 ) + return nvars; + else if ( nvars <= 3 ) + return 3; + else if ( nvars <= 9 ) + return 9; + else + return nvars; } -} // namespace anonymous +} // namespace // ---------------------------------------------------------------------------- -template< typename DATATYPE > -void write_field_nodes( - const Metadata& gmsh_options, - const functionspace::NodeColumns& function_space, - const Field& field, - std::ostream& out) -{ - Log::debug() << "writing NodeColumns field " << field.name() << " defined in NodeColumns..." << std::endl; - - bool gather( gmsh_options.get("gather") && atlas::mpi::comm().size() > 1 ); - bool binary( !gmsh_options.get("ascii") ); - size_t nlev = std::max(1,field.levels()); - size_t ndata = std::min(function_space.nb_nodes(),field.shape(0)); - size_t nvars = std::max(1,field.variables()); - array::ArrayView gidx = array::make_view( function_space.nodes().global_index() ); - Field gidx_glb; - Field field_glb; - if( gather ) - { - gidx_glb = function_space.createField( option::name("gidx_glb") | option::levels(false) | option::global() ); - function_space.gather(function_space.nodes().global_index(),gidx_glb); - gidx = array::make_view( gidx_glb ); - - field_glb = function_space.createField( field, option::global() ); - function_space.gather(field,field_glb); - ndata = std::min(function_space.nb_nodes_global(),field_glb.shape(0)); - } +template +void write_field_nodes( const Metadata& gmsh_options, const functionspace::NodeColumns& function_space, + const Field& field, std::ostream& out ) { + Log::debug() << "writing NodeColumns field " << field.name() << " defined in NodeColumns..." << std::endl; + + bool gather( gmsh_options.get( "gather" ) && atlas::mpi::comm().size() > 1 ); + bool binary( !gmsh_options.get( "ascii" ) ); + size_t nlev = std::max( 1, field.levels() ); + size_t ndata = std::min( function_space.nb_nodes(), field.shape( 0 ) ); + size_t nvars = std::max( 1, field.variables() ); + array::ArrayView gidx = array::make_view( function_space.nodes().global_index() ); + Field gidx_glb; + Field field_glb; + if ( gather ) { + gidx_glb = function_space.createField( option::name( "gidx_glb" ) | option::levels( false ) | + option::global() ); + function_space.gather( function_space.nodes().global_index(), gidx_glb ); + gidx = array::make_view( gidx_glb ); + + field_glb = function_space.createField( field, option::global() ); + function_space.gather( field, field_glb ); + ndata = std::min( function_space.nb_nodes_global(), field_glb.shape( 0 ) ); + } - std::vector lev = get_levels( nlev, gmsh_options ); - for (size_t ilev=0; ilev < lev.size(); ++ilev) - { - size_t jlev = lev[ilev]; - if( ( gather && atlas::mpi::comm().rank() == 0 ) || !gather ) - { - out << "$NodeData\n"; - out << "1\n"; - out << "\"" << field.name() << field_lev(field,jlev) << "\"\n"; - out << "1\n"; - out << field_time(field) << "\n"; - out << "4\n"; - out << field_step(field) << "\n"; - out << field_vars(nvars) << "\n"; - out << ndata << "\n"; - out << atlas::mpi::comm().rank() << "\n"; - auto data = gather ? make_level_view( field_glb, ndata, jlev ) : make_level_view( field, ndata, jlev ); - write_level( out, gidx, data ); - out << "$EndNodeData\n"; + std::vector lev = get_levels( nlev, gmsh_options ); + for ( size_t ilev = 0; ilev < lev.size(); ++ilev ) { + size_t jlev = lev[ilev]; + if ( ( gather && atlas::mpi::comm().rank() == 0 ) || !gather ) { + out << "$NodeData\n"; + out << "1\n"; + out << "\"" << field.name() << field_lev( field, jlev ) << "\"\n"; + out << "1\n"; + out << field_time( field ) << "\n"; + out << "4\n"; + out << field_step( field ) << "\n"; + out << field_vars( nvars ) << "\n"; + out << ndata << "\n"; + out << atlas::mpi::comm().rank() << "\n"; + auto data = gather ? make_level_view( field_glb, ndata, jlev ) + : make_level_view( field, ndata, jlev ); + write_level( out, gidx, data ); + out << "$EndNodeData\n"; + } } - } } // ---------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------- -template< typename DATATYPE > -void write_field_nodes( - const Metadata& gmsh_options, - const functionspace::StructuredColumns& function_space, - const Field& field, - std::ostream& out) -{ - Log::debug() << "writing StructuredColumns field " << field.name() << "..." << std::endl; - - bool gather( gmsh_options.get("gather") && atlas::mpi::comm().size() > 1 ); - bool binary( !gmsh_options.get("ascii") ); - size_t nlev = std::max(1,field.levels()); - size_t ndata = std::min(function_space.sizeOwned(),field.shape(0)); - size_t nvars = std::max(1,field.variables()); - auto gidx = array::make_view( function_space.global_index() ); - Field gidx_glb; - Field field_glb; - if( gather ) - { - gidx_glb = function_space.createField( function_space.global_index(), option::name("gidx_glb") | option::global() ); - function_space.gather(function_space.global_index(),gidx_glb); - gidx = array::make_view( gidx_glb ); - - field_glb = function_space.createField( field, option::global() ); - function_space.gather(field,field_glb); - ndata = field_glb.shape(0); - } - - - std::vector lev = get_levels(nlev,gmsh_options); - for (size_t ilev = 0; ilev < lev.size(); ++ilev) - { - size_t jlev = lev[ilev]; - char field_lev[6] = {0, 0, 0, 0, 0, 0}; - - if (field.levels()) - { - std::sprintf(field_lev, "[%03lu]", jlev); - } +template +void write_field_nodes( const Metadata& gmsh_options, const functionspace::StructuredColumns& function_space, + const Field& field, std::ostream& out ) { + Log::debug() << "writing StructuredColumns field " << field.name() << "..." << std::endl; + + bool gather( gmsh_options.get( "gather" ) && atlas::mpi::comm().size() > 1 ); + bool binary( !gmsh_options.get( "ascii" ) ); + size_t nlev = std::max( 1, field.levels() ); + size_t ndata = std::min( function_space.sizeOwned(), field.shape( 0 ) ); + size_t nvars = std::max( 1, field.variables() ); + auto gidx = array::make_view( function_space.global_index() ); + Field gidx_glb; + Field field_glb; + if ( gather ) { + gidx_glb = + function_space.createField( function_space.global_index(), option::name( "gidx_glb" ) | option::global() ); + function_space.gather( function_space.global_index(), gidx_glb ); + gidx = array::make_view( gidx_glb ); + + field_glb = function_space.createField( field, option::global() ); + function_space.gather( field, field_glb ); + ndata = field_glb.shape( 0 ); + } - double time = field.metadata().has("time") ? - field.metadata().get("time") : 0.; - - int step = field.metadata().has("step") ? - field.metadata().get("step") : 0 ; - - out << "$NodeData\n"; - out << "1\n"; - out << "\"" << field.name() << field_lev << "\"\n"; - out << "1\n"; - out << field_time(field) << "\n"; - out << "4\n"; - out << field_step(field) << "\n"; - out << field_vars(nvars) << "\n"; - out << ndata << "\n"; - out << atlas::mpi::comm().rank() << "\n"; - auto data = gather ? make_level_view( field_glb, ndata, jlev ) : make_level_view( field, ndata, jlev ); - write_level( out, gidx, data ); - out << "$EndNodeData\n"; - } + std::vector lev = get_levels( nlev, gmsh_options ); + for ( size_t ilev = 0; ilev < lev.size(); ++ilev ) { + size_t jlev = lev[ilev]; + char field_lev[6] = {0, 0, 0, 0, 0, 0}; + + if ( field.levels() ) { std::sprintf( field_lev, "[%03lu]", jlev ); } + + double time = field.metadata().has( "time" ) ? field.metadata().get( "time" ) : 0.; + + int step = field.metadata().has( "step" ) ? field.metadata().get( "step" ) : 0; + + out << "$NodeData\n"; + out << "1\n"; + out << "\"" << field.name() << field_lev << "\"\n"; + out << "1\n"; + out << field_time( field ) << "\n"; + out << "4\n"; + out << field_step( field ) << "\n"; + out << field_vars( nvars ) << "\n"; + out << ndata << "\n"; + out << atlas::mpi::comm().rank() << "\n"; + auto data = gather ? make_level_view( field_glb, ndata, jlev ) + : make_level_view( field, ndata, jlev ); + write_level( out, gidx, data ); + out << "$EndNodeData\n"; + } } // ---------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------- #if 0 template< typename DATA_TYPE > @@ -473,8 +446,6 @@ void write_field_elems(const Metadata& gmsh_options, const FunctionSpace& functi #endif // ---------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------- // Unused private function, in case for big-endian // ---------------------------------------------------------------------------- @@ -492,597 +463,521 @@ void swap_bytes(char *array, int size, int n) } #endif // ---------------------------------------------------------------------------- -} // end anonymous namespace - - +} // end anonymous namespace // ---------------------------------------------------------------------------- -GmshIO::GmshIO() -{ - // which field holds the Nodes - options.set("nodes", "xy"); +GmshIO::GmshIO() { + // which field holds the Nodes + options.set( "nodes", "xy" ); - // Gather fields to one proc before writing - options.set("gather", false); + // Gather fields to one proc before writing + options.set( "gather", false ); - // Output of ghost nodes / elements - options.set("ghost", false); + // Output of ghost nodes / elements + options.set( "ghost", false ); - // ASCII format (true) or binary (false) - options.set("ascii", true ); + // ASCII format (true) or binary (false) + options.set( "ascii", true ); - // Output of elements - options.set("elements", true); + // Output of elements + options.set( "elements", true ); - // Output of edges - options.set("edges", true ); + // Output of edges + options.set( "edges", true ); - // Levels of fields to use - options.set< std::vector >("levels", std::vector() ); + // Levels of fields to use + options.set>( "levels", std::vector() ); } -GmshIO::~GmshIO() -{ -} +GmshIO::~GmshIO() {} -Mesh GmshIO::read(const PathName& file_path) const -{ - Mesh mesh; - GmshIO::read(file_path,mesh); - return mesh; +Mesh GmshIO::read( const PathName& file_path ) const { + Mesh mesh; + GmshIO::read( file_path, mesh ); + return mesh; } 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(); - throw eckit::SeriousBug("Element type not supported", Here()); - return 0; -} +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(); + throw eckit::SeriousBug( "Element type not supported", Here() ); + return 0; } +} // namespace -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); +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 ); - std::string line; + std::string line; - while(line != "$MeshFormat") - std::getline(file,line); - double version; - int binary; - int size_of_real; - file >> version >> binary >> size_of_real; + while ( line != "$MeshFormat" ) + std::getline( file, line ); + double version; + int binary; + int size_of_real; + file >> version >> binary >> size_of_real; - while(line != "$Nodes") - std::getline(file,line); + while ( line != "$Nodes" ) + std::getline( file, line ); - // Create nodes + // Create nodes size_t nb_nodes; - file >> nb_nodes; - - mesh.nodes().resize(nb_nodes); - - mesh::Nodes& nodes = mesh.nodes(); - - nodes.add( Field("xyz",array::make_datatype(),array::make_shape(nb_nodes,3) ) ); - - array::ArrayView coords = array::make_view( nodes.field("xyz") ); - array::ArrayView glb_idx = array::make_view( nodes.global_index() ); - array::ArrayView part = array::make_view( nodes.partition() ); - - std::map glb_to_loc; - int g; - double x,y,z; - double xyz[3]; - double xmax = -std::numeric_limits::max(); - double zmax = -std::numeric_limits::max(); - gidx_t max_glb_idx=0; - while(binary && file.peek()=='\n') file.get(); - for( size_t n = 0; n < nb_nodes; ++n ) - { - if( binary ) - { - file.read(reinterpret_cast(&g), sizeof(int)); - file.read(reinterpret_cast(&xyz), sizeof(double)*3); - x = xyz[XX]; - y = xyz[YY]; - z = xyz[ZZ]; - } - else - { - file >> g >> x >> y >> z; + file >> nb_nodes; + + mesh.nodes().resize( nb_nodes ); + + mesh::Nodes& nodes = mesh.nodes(); + + nodes.add( Field( "xyz", array::make_datatype(), array::make_shape( nb_nodes, 3 ) ) ); + + array::ArrayView coords = array::make_view( nodes.field( "xyz" ) ); + array::ArrayView glb_idx = array::make_view( nodes.global_index() ); + array::ArrayView part = array::make_view( nodes.partition() ); + + std::map glb_to_loc; + int g; + double x, y, z; + double xyz[3]; + double xmax = -std::numeric_limits::max(); + double zmax = -std::numeric_limits::max(); + gidx_t max_glb_idx = 0; + while ( binary && file.peek() == '\n' ) + file.get(); + for ( size_t n = 0; n < nb_nodes; ++n ) { + if ( binary ) { + file.read( reinterpret_cast( &g ), sizeof( int ) ); + file.read( reinterpret_cast( &xyz ), sizeof( double ) * 3 ); + x = xyz[XX]; + y = xyz[YY]; + z = xyz[ZZ]; + } + else { + file >> g >> x >> y >> z; + } + glb_idx( n ) = g; + coords( n, XX ) = x; + coords( n, YY ) = y; + coords( n, ZZ ) = z; + glb_to_loc[g] = n; + part( n ) = 0; + max_glb_idx = std::max( max_glb_idx, static_cast( g ) ); + xmax = std::max( x, xmax ); + zmax = std::max( z, zmax ); } - glb_idx(n) = g; - coords(n,XX) = x; - coords(n,YY) = y; - coords(n,ZZ) = z; - glb_to_loc[ g ] = n; - part(n) = 0; - max_glb_idx = std::max(max_glb_idx, static_cast(g)); - xmax = std::max(x,xmax); - zmax = std::max(z,zmax); - } - if( xmax < 4*M_PI && zmax == 0. ) - { - for( size_t n = 0; n < nb_nodes; ++n ) - { - coords(n,XX) *= rad2deg; - coords(n,YY) *= rad2deg; + if ( xmax < 4 * M_PI && zmax == 0. ) { + for ( size_t n = 0; n < nb_nodes; ++n ) { + coords( n, XX ) *= rad2deg; + coords( n, YY ) *= rad2deg; + } } - } - for (int i=0; i<3; ++i) - std::getline(file,line); - - int nb_elements=0; - - while(line != "$Elements") - std::getline(file,line); - - file >> nb_elements; - - if( binary ) - { - while(file.peek()=='\n') file.get(); - int accounted_elems = 0; - while( accounted_elems < nb_elements ) - { - int header[3]; - int data[100]; - file.read(reinterpret_cast(&header),sizeof(int)*3); - - int etype = header[0]; - size_t netype = header[1]; - size_t ntags = header[2]; - accounted_elems += netype; - mesh::Elements* elements; - if( etype == LINE ) { - size_t jtype = mesh.edges().add(make_element_type(etype),netype); - elements = &mesh.edges().elements(jtype); - } else { - size_t jtype = mesh.cells().add(make_element_type(etype),netype); - elements = &mesh.edges().elements(jtype); - } - - size_t nnodes_per_elem = elements->element_type().nb_nodes(); - mesh::BlockConnectivity& conn = elements->node_connectivity(); - array::ArrayView egidx = array::make_view( elements->global_index() ); - array::ArrayView epart = array::make_view( elements->partition() ); + for ( int i = 0; i < 3; ++i ) + std::getline( file, line ); + + int nb_elements = 0; + + while ( line != "$Elements" ) + std::getline( file, line ); + + file >> nb_elements; + + if ( binary ) { + while ( file.peek() == '\n' ) + file.get(); + int accounted_elems = 0; + while ( accounted_elems < nb_elements ) { + int header[3]; + int data[100]; + file.read( reinterpret_cast( &header ), sizeof( int ) * 3 ); + + int etype = header[0]; + size_t netype = header[1]; + size_t ntags = header[2]; + accounted_elems += netype; + mesh::Elements* elements; + if ( etype == LINE ) { + size_t jtype = mesh.edges().add( make_element_type( etype ), netype ); + elements = &mesh.edges().elements( jtype ); + } + else { + size_t jtype = mesh.cells().add( make_element_type( etype ), netype ); + elements = &mesh.edges().elements( jtype ); + } - size_t dsize = 1+ntags+nnodes_per_elem; - int part; - for (size_t e=0; e(&data),sizeof(int)*dsize); - part = 0; - egidx(e) = data[0]; - epart(e) = part; - for(size_t n=0; n nb_etype(20,0); - int elements_max_glb_idx(0); - int etype; - for (int e=0; e> g >> etype; std::getline(file,line); // finish line - ++nb_etype[etype]; - elements_max_glb_idx = std::max(elements_max_glb_idx,g); + size_t nnodes_per_elem = elements->element_type().nb_nodes(); + mesh::BlockConnectivity& conn = elements->node_connectivity(); + array::ArrayView egidx = array::make_view( elements->global_index() ); + array::ArrayView epart = array::make_view( elements->partition() ); + + size_t dsize = 1 + ntags + nnodes_per_elem; + int part; + for ( size_t e = 0; e < netype; ++e ) { + file.read( reinterpret_cast( &data ), sizeof( int ) * dsize ); + part = 0; + egidx( e ) = data[0]; + epart( e ) = part; + for ( size_t n = 0; n < nnodes_per_elem; ++n ) + conn.set( e, n, glb_to_loc[data[1 + ntags + n]] ); + } + } } + else { + // Find out which element types are inside + int position = file.tellg(); + std::vector nb_etype( 20, 0 ); + int elements_max_glb_idx( 0 ); + int etype; + for ( int e = 0; e < nb_elements; ++e ) { + file >> g >> etype; + std::getline( file, line ); // finish line + ++nb_etype[etype]; + elements_max_glb_idx = std::max( elements_max_glb_idx, g ); + } - // Allocate data structures for quads, triags, edges - - int nb_quads = nb_etype[QUAD]; - int nb_triags = nb_etype[TRIAG]; - int nb_edges = nb_etype[LINE]; - - - mesh::Elements& quads = mesh.cells().elements( mesh.cells().add( make_element_type(QUAD), nb_quads ) ); - mesh::Elements& triags = mesh.cells().elements( mesh.cells().add( make_element_type(TRIAG), nb_triags ) ); - mesh::Elements& edges = mesh.edges().elements( mesh.edges().add( make_element_type(LINE), nb_edges ) ); - - mesh::BlockConnectivity& quad_nodes = quads.node_connectivity(); - mesh::BlockConnectivity& triag_nodes = triags.node_connectivity(); - mesh::BlockConnectivity& edge_nodes = edges.node_connectivity(); - - array::ArrayView quad_glb_idx = array::make_view ( quads.global_index() ); - array::ArrayView quad_part = array::make_view ( quads.partition() ); - - array::ArrayView triag_glb_idx = array::make_view( triags.global_index() ); - array::ArrayView triag_part = array::make_view( triags.partition() ); - - array::ArrayView edge_glb_idx = array::make_view( edges.global_index() ); - array::ArrayView edge_part = array::make_view( edges.partition() ); - - // Now read all elements - file.seekg(position,std::ios::beg); - int gn0, gn1, gn2, gn3; - int quad=0, triag=0, edge=0; - int ntags, tags[100]; - for (int e=0; e> g >> etype >> ntags; - for( int t=0; t> tags[t]; - int part=0; - if( ntags > 3 ) part = std::max( part, *std::max_element(tags+3,tags+ntags-1) ); // one positive, others negative - - int enodes[4]; - - switch( etype ) - { - case(QUAD): - file >> gn0 >> gn1 >> gn2 >> gn3; - quad_glb_idx(quad) = g; - quad_part(quad) = part; - enodes[0] = glb_to_loc[gn0]; - enodes[1] = glb_to_loc[gn1]; - enodes[2] = glb_to_loc[gn2]; - enodes[3] = glb_to_loc[gn3]; - quad_nodes.set(quad,enodes); - ++quad; - break; - case(TRIAG): - file >> gn0 >> gn1 >> gn2; - triag_glb_idx(triag) = g; - triag_part(triag) = part; - enodes[0] = glb_to_loc[gn0]; - enodes[1] = glb_to_loc[gn1]; - enodes[2] = glb_to_loc[gn2]; - triag_nodes.set(triag,enodes); - ++triag; - break; - case(LINE): - file >> gn0 >> gn1; - edge_glb_idx(edge) = g; - edge_part(edge) = part; - enodes[0] = glb_to_loc[gn0]; - enodes[1] = glb_to_loc[gn1]; - edge_nodes.set(edge,enodes); - ++edge; - break; - case(POINT): - file >> gn0; - break; - default: - std::cout << "etype " << etype << std::endl; - throw Exception("ERROR: element type not supported",Here()); - } + // Allocate data structures for quads, triags, edges + + int nb_quads = nb_etype[QUAD]; + int nb_triags = nb_etype[TRIAG]; + int nb_edges = nb_etype[LINE]; + + mesh::Elements& quads = mesh.cells().elements( mesh.cells().add( make_element_type( QUAD ), nb_quads ) ); + mesh::Elements& triags = mesh.cells().elements( mesh.cells().add( make_element_type( TRIAG ), nb_triags ) ); + mesh::Elements& edges = mesh.edges().elements( mesh.edges().add( make_element_type( LINE ), nb_edges ) ); + + mesh::BlockConnectivity& quad_nodes = quads.node_connectivity(); + mesh::BlockConnectivity& triag_nodes = triags.node_connectivity(); + mesh::BlockConnectivity& edge_nodes = edges.node_connectivity(); + + array::ArrayView quad_glb_idx = array::make_view( quads.global_index() ); + array::ArrayView quad_part = array::make_view( quads.partition() ); + + array::ArrayView triag_glb_idx = array::make_view( triags.global_index() ); + array::ArrayView triag_part = array::make_view( triags.partition() ); + + array::ArrayView edge_glb_idx = array::make_view( edges.global_index() ); + array::ArrayView edge_part = array::make_view( edges.partition() ); + + // Now read all elements + file.seekg( position, std::ios::beg ); + int gn0, gn1, gn2, gn3; + int quad = 0, triag = 0, edge = 0; + int ntags, tags[100]; + for ( int e = 0; e < nb_elements; ++e ) { + file >> g >> etype >> ntags; + for ( int t = 0; t < ntags; ++t ) + file >> tags[t]; + int part = 0; + if ( ntags > 3 ) + part = + std::max( part, *std::max_element( tags + 3, tags + ntags - 1 ) ); // one positive, others negative + + int enodes[4]; + + switch ( etype ) { + case ( QUAD ): + file >> gn0 >> gn1 >> gn2 >> gn3; + quad_glb_idx( quad ) = g; + quad_part( quad ) = part; + enodes[0] = glb_to_loc[gn0]; + enodes[1] = glb_to_loc[gn1]; + enodes[2] = glb_to_loc[gn2]; + enodes[3] = glb_to_loc[gn3]; + quad_nodes.set( quad, enodes ); + ++quad; + break; + case ( TRIAG ): + file >> gn0 >> gn1 >> gn2; + triag_glb_idx( triag ) = g; + triag_part( triag ) = part; + enodes[0] = glb_to_loc[gn0]; + enodes[1] = glb_to_loc[gn1]; + enodes[2] = glb_to_loc[gn2]; + triag_nodes.set( triag, enodes ); + ++triag; + break; + case ( LINE ): + file >> gn0 >> gn1; + edge_glb_idx( edge ) = g; + edge_part( edge ) = part; + enodes[0] = glb_to_loc[gn0]; + enodes[1] = glb_to_loc[gn1]; + edge_nodes.set( edge, enodes ); + ++edge; + break; + case ( POINT ): + file >> gn0; + break; + default: + std::cout << "etype " << etype << std::endl; + throw Exception( "ERROR: element type not supported", Here() ); + } + } } - } - file.close(); + file.close(); } +void GmshIO::write( const Mesh& mesh, const PathName& file_path ) const { + int part = mesh.metadata().has( "part" ) ? mesh.metadata().get( "part" ) : atlas::mpi::comm().rank(); + bool include_ghost = options.get( "ghost" ) && options.get( "elements" ); -void GmshIO::write(const Mesh& mesh, const PathName& file_path) const -{ - int part = mesh.metadata().has("part") ? mesh.metadata().get("part") : atlas::mpi::comm().rank(); - bool include_ghost = options.get("ghost") && options.get("elements"); - - std::string nodes_field = options.get("nodes"); - - const mesh::Nodes& nodes = mesh.nodes(); - array::ArrayView coords = array::make_view( nodes.field( nodes_field ) ); - array::ArrayView glb_idx = array::make_view( nodes.global_index() ); + std::string nodes_field = options.get( "nodes" ); - const size_t surfdim = coords.shape(1); // nb of variables in coords + const mesh::Nodes& nodes = mesh.nodes(); + array::ArrayView coords = array::make_view( nodes.field( nodes_field ) ); + array::ArrayView glb_idx = array::make_view( nodes.global_index() ); - ASSERT(surfdim == 2 || surfdim == 3); + const size_t surfdim = coords.shape( 1 ); // nb of variables in coords - Log::debug() << "writing mesh to gmsh file " << file_path << std::endl; + ASSERT( surfdim == 2 || surfdim == 3 ); - bool binary = !options.get("ascii"); + Log::debug() << "writing mesh to gmsh file " << file_path << std::endl; - openmode mode = std::ios::out; - if( binary ) - mode = std::ios::out | std::ios::binary; - GmshFile file(file_path,mode,part); + bool binary = !options.get( "ascii" ); - // Header - if( binary ) - write_header_binary(file); - else - write_header_ascii(file); - - // Nodes - const size_t nb_nodes = nodes.size(); - file << "$Nodes\n"; - file << nb_nodes << "\n"; - double xyz[3] = {0.,0.,0.}; - for( size_t n = 0; n < nb_nodes; ++n ) - { - int g = glb_idx(n); + openmode mode = std::ios::out; + if ( binary ) mode = std::ios::out | std::ios::binary; + GmshFile file( file_path, mode, part ); - for(size_t d = 0; d < surfdim; ++d) - xyz[d] = coords(n,d); - - if( binary ) - { - file.write(reinterpret_cast(&g), sizeof(int)); - file.write(reinterpret_cast(&xyz), sizeof(double)*3 ); - } + // Header + if ( binary ) + write_header_binary( file ); else - { - file << g << " " << xyz[XX] << " " << xyz[YY] << " " << xyz[ZZ] << "\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()); - - size_t nb_elements(0); - for( size_t jgroup=0; jgroup hybrid_halo = array::make_view( hybrid.halo() ); - for( size_t e=0; e( &g ), sizeof( int ) ); + file.write( reinterpret_cast( &xyz ), sizeof( double ) * 3 ); + } + else { + file << g << " " << xyz[XX] << " " << xyz[YY] << " " << xyz[ZZ] << "\n"; } - } } + if ( binary ) file << "\n"; + file << "$EndNodes\n"; - file << nb_elements << "\n"; - - for( size_t jgroup=0; jgroup( elements.global_index() ); - auto elems_partition = elements.view( elements.partition() ); - auto elems_halo = elements.view( elements.halo() ); - - if( binary ) - { - size_t nb_elems=elements.size(); - if( !include_ghost ) - { - for(size_t elem=0; elem grouped_elements; + if ( options.get( "elements" ) ) grouped_elements.push_back( &mesh.cells() ); + if ( options.get( "edges" ) ) grouped_elements.push_back( &mesh.edges() ); + + size_t nb_elements( 0 ); + for ( size_t jgroup = 0; jgroup < grouped_elements.size(); ++jgroup ) { + const mesh::HybridElements& hybrid = *grouped_elements[jgroup]; + nb_elements += hybrid.size(); + if ( !include_ghost ) { + const array::ArrayView hybrid_halo = array::make_view( hybrid.halo() ); + for ( size_t e = 0; e < hybrid.size(); ++e ) { + if ( hybrid_halo( e ) ) --nb_elements; + } } - } - - int header[3]; - int data[9]; - header[0] = gmsh_elem_type; - header[1] = nb_elems; - header[2] = 4; // nb_tags - file.write(reinterpret_cast(&header), sizeof(int)*3 ); - data[1]=1; - data[2]=1; - data[3]=1; - size_t datasize = sizeof(int)*(5+node_connectivity.cols()); - for(size_t elem=0; elem(&data), datasize ); - } - } } - else - { - std::stringstream ss_elem_info; ss_elem_info << " " << gmsh_elem_type << " 4 1 1 1 "; - std::string elem_info = ss_elem_info.str(); - for(size_t elem=0; elem( elements.global_index() ); + auto elems_partition = elements.view( elements.partition() ); + auto elems_halo = elements.view( elements.halo() ); + + if ( binary ) { + size_t nb_elems = elements.size(); + if ( !include_ghost ) { + for ( size_t elem = 0; elem < elements.size(); ++elem ) { + if ( elems_halo( elem ) ) --nb_elems; + } + } + + int header[3]; + int data[9]; + header[0] = gmsh_elem_type; + header[1] = nb_elems; + header[2] = 4; // nb_tags + file.write( reinterpret_cast( &header ), sizeof( int ) * 3 ); + data[1] = 1; + data[2] = 1; + data[3] = 1; + size_t datasize = sizeof( int ) * ( 5 + node_connectivity.cols() ); + for ( size_t elem = 0; elem < elements.size(); ++elem ) { + if ( include_ghost || !elems_halo( elem ) ) { + data[0] = elems_glb_idx( elem ); + data[4] = elems_partition( elem ); + for ( size_t n = 0; n < node_connectivity.cols(); ++n ) + data[5 + n] = glb_idx( node_connectivity( elem, n ) ); + file.write( reinterpret_cast( &data ), datasize ); + } + } + } + else { + std::stringstream ss_elem_info; + ss_elem_info << " " << gmsh_elem_type << " 4 1 1 1 "; + std::string elem_info = ss_elem_info.str(); + for ( size_t elem = 0; elem < elements.size(); ++elem ) { + if ( include_ghost || !elems_halo( elem ) ) { + file << elems_glb_idx( elem ) << elem_info << elems_partition( elem ); + for ( size_t n = 0; n < node_connectivity.cols(); ++n ) { + file << " " << glb_idx( node_connectivity( elem, n ) ); + } + file << "\n"; + } + } + } } - } } - } } - } - if( binary ) file << "\n"; - file << "$EndElements\n"; - file << std::flush; + if ( binary ) file << "\n"; + file << "$EndElements\n"; + file << std::flush; - // Optional mesh information file - if( options.has("info") && options.get("info") ) - { - PathName mesh_info(file_path); - mesh_info = mesh_info.dirName()+"/"+mesh_info.baseName(false)+"_info.msh"; + // Optional mesh information file + if ( options.has( "info" ) && options.get( "info" ) ) { + PathName mesh_info( file_path ); + mesh_info = mesh_info.dirName() + "/" + mesh_info.baseName( false ) + "_info.msh"; - //[next] make NodesFunctionSpace accept const mesh - functionspace::NodeColumns function_space( const_cast(mesh) ); + //[next] make NodesFunctionSpace accept const mesh + functionspace::NodeColumns function_space( const_cast( mesh ) ); - write(nodes.partition(),function_space,mesh_info,std::ios_base::out); + write( nodes.partition(), function_space, mesh_info, std::ios_base::out ); - if (nodes.has_field("dual_volumes")) - { - write(nodes.field("dual_volumes"),function_space,mesh_info,std::ios_base::app); - } - - if (nodes.has_field("dual_delta_sph")) - { - write(nodes.field("dual_delta_sph"),function_space,mesh_info,std::ios_base::app); - } + if ( nodes.has_field( "dual_volumes" ) ) { + write( nodes.field( "dual_volumes" ), function_space, mesh_info, std::ios_base::app ); + } - //[next] if( mesh.has_function_space("edges") ) - //[next] { - //[next] FunctionSpace& edges = mesh.function_space( "edges" ); - - //[next] if (edges.has_field("dual_normals")) - //[next] { - //[next] write(edges.field("dual_normals"),mesh_info,std::ios_base::app); - //[next] } - - //[next] if (edges.has_field("skewness")) - //[next] { - //[next] write(edges.field("skewness"),mesh_info,std::ios_base::app); - //[next] } - - //[next] if (edges.has_field("arc_length")) - //[next] { - //[next] write(edges.field("arc_length"),mesh_info,std::ios_base::app); - //[next] } - //[next] } - } - file.close(); + if ( nodes.has_field( "dual_delta_sph" ) ) { + write( nodes.field( "dual_delta_sph" ), function_space, mesh_info, std::ios_base::app ); + } + //[next] if( mesh.has_function_space("edges") ) + //[next] { + //[next] FunctionSpace& edges = mesh.function_space( "edges" ); + + //[next] if (edges.has_field("dual_normals")) + //[next] { + //[next] write(edges.field("dual_normals"),mesh_info,std::ios_base::app); + //[next] } + + //[next] if (edges.has_field("skewness")) + //[next] { + //[next] write(edges.field("skewness"),mesh_info,std::ios_base::app); + //[next] } + + //[next] if (edges.has_field("arc_length")) + //[next] { + //[next] write(edges.field("arc_length"),mesh_info,std::ios_base::app); + //[next] } + //[next] } + } + file.close(); } // ---------------------------------------------------------------------------- -void GmshIO::write( - const Field& field, - const PathName& file_path, - openmode mode) const -{ - if (!field.functionspace()) - { +void GmshIO::write( const Field& field, const PathName& file_path, openmode mode ) const { + if ( !field.functionspace() ) { std::stringstream msg; - msg << "Field ["<("ascii") ); +void GmshIO::write_delegate( const FieldSet& fieldset, const functionspace::NodeColumns& functionspace, + 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; - bool gather = options.has("gather") ? options.get("gather") : false; - GmshFile file(file_path,mode,gather?-1:atlas::mpi::comm().rank()); + bool gather = options.has( "gather" ) ? options.get( "gather" ) : false; + GmshFile file( file_path, mode, gather ? -1 : atlas::mpi::comm().rank() ); // Header - if (is_new_file) - { - write_header_ascii(file); - } + if ( is_new_file ) { write_header_ascii( file ); } // field::Fields - for(size_t field_idx = 0; field_idx < fieldset.size(); ++field_idx) - { + for ( size_t field_idx = 0; field_idx < fieldset.size(); ++field_idx ) { const Field& field = fieldset[field_idx]; - Log::debug() << "writing field " << field.name() - << " to gmsh file " << file_path << std::endl; + Log::debug() << "writing field " << field.name() << " to gmsh file " << file_path << std::endl; - if (field.datatype() == array::DataType::int32()) - { - write_field_nodes(options,functionspace,field,file); + if ( field.datatype() == array::DataType::int32() ) { + write_field_nodes( options, functionspace, field, file ); } - else if (field.datatype() == array::DataType::int64()) - { - write_field_nodes(options,functionspace,field,file); + else if ( field.datatype() == array::DataType::int64() ) { + write_field_nodes( options, functionspace, field, file ); } - else if (field.datatype() == array::DataType::real32()) - { - write_field_nodes(options,functionspace,field,file); + else if ( field.datatype() == array::DataType::real32() ) { + write_field_nodes( options, functionspace, field, file ); } - else if (field.datatype() == array::DataType::real64()) - { - write_field_nodes(options,functionspace,field,file); + else if ( field.datatype() == array::DataType::real64() ) { + write_field_nodes( options, functionspace, field, file ); } file << std::flush; @@ -1091,49 +986,37 @@ void GmshIO::write_delegate( } // ---------------------------------------------------------------------------- - - // ---------------------------------------------------------------------------- -void GmshIO::write_delegate( - const FieldSet& fieldset, - const functionspace::StructuredColumns& functionspace, - const PathName& file_path, openmode mode) const -{ - bool is_new_file = (mode != std::ios_base::app || !file_path.exists()); - bool binary(!options.get("ascii")); +void GmshIO::write_delegate( const FieldSet& fieldset, const functionspace::StructuredColumns& functionspace, + 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; + bool gather = options.has( "gather" ) ? options.get( "gather" ) : false; - GmshFile file(file_path,mode,gather?-1:atlas::mpi::comm().rank()); + GmshFile file( file_path, mode, gather ? -1 : atlas::mpi::comm().rank() ); // Header - if (is_new_file) - write_header_ascii(file); + if ( is_new_file ) write_header_ascii( file ); // field::Fields - for (size_t field_idx = 0; field_idx < fieldset.size(); ++field_idx) - { + for ( size_t field_idx = 0; field_idx < fieldset.size(); ++field_idx ) { const Field& field = fieldset[field_idx]; - Log::debug() << "writing field " << field.name() - << " to gmsh file " << file_path << std::endl; + Log::debug() << "writing field " << field.name() << " to gmsh file " << file_path << std::endl; - if (field.datatype() == array::DataType::int32()) - { - write_field_nodes(options, functionspace, field, file); + if ( field.datatype() == array::DataType::int32() ) { + write_field_nodes( options, functionspace, field, file ); } - else if (field.datatype() == array::DataType::int64()) - { - write_field_nodes(options, functionspace, field, file); + else if ( field.datatype() == array::DataType::int64() ) { + write_field_nodes( options, functionspace, field, file ); } - else if (field.datatype() == array::DataType::real32()) - { - write_field_nodes(options, functionspace, field, file); + else if ( field.datatype() == array::DataType::real32() ) { + write_field_nodes( options, functionspace, field, file ); } - else if (field.datatype() == array::DataType::real64()) - { - write_field_nodes(options, functionspace, field, file); + else if ( field.datatype() == array::DataType::real64() ) { + write_field_nodes( options, functionspace, field, file ); } file << std::flush; @@ -1143,108 +1026,87 @@ void GmshIO::write_delegate( } // ---------------------------------------------------------------------------- - // ---------------------------------------------------------------------------- -void GmshIO::write( - const FieldSet& fieldset, - const FunctionSpace& funcspace, - const eckit::PathName& file_path, - openmode mode) const -{ - if( functionspace::NodeColumns(funcspace) ) - write_delegate( - fieldset, - functionspace::NodeColumns(funcspace), - file_path, - mode); - else if( functionspace::StructuredColumns(funcspace) ) - write_delegate( - fieldset, - functionspace::StructuredColumns(funcspace), - file_path, - mode); - else - NOTIMP; +void GmshIO::write( const FieldSet& fieldset, const FunctionSpace& funcspace, const eckit::PathName& file_path, + openmode mode ) const { + if ( functionspace::NodeColumns( funcspace ) ) + write_delegate( fieldset, functionspace::NodeColumns( funcspace ), file_path, mode ); + else if ( functionspace::StructuredColumns( funcspace ) ) + write_delegate( fieldset, functionspace::StructuredColumns( funcspace ), file_path, mode ); + else + NOTIMP; } // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- -void GmshIO::write( - const Field& field, - const FunctionSpace& funcspace, - const eckit::PathName& file_path, - openmode mode) const -{ - if( functionspace::NodeColumns(funcspace) ) - write_delegate( - field, - functionspace::NodeColumns(funcspace), - file_path, - mode); - else if( functionspace::StructuredColumns(funcspace) ) - write_delegate( - field, - functionspace::StructuredColumns(funcspace), - file_path, - mode); - else - NOTIMP; +void GmshIO::write( const Field& field, const FunctionSpace& funcspace, const eckit::PathName& file_path, + openmode mode ) const { + if ( functionspace::NodeColumns( funcspace ) ) + write_delegate( field, functionspace::NodeColumns( funcspace ), file_path, mode ); + else if ( functionspace::StructuredColumns( funcspace ) ) + write_delegate( field, functionspace::StructuredColumns( funcspace ), file_path, mode ); + else + NOTIMP; } // ---------------------------------------------------------------------------- - -class GmshFortranInterface -{ +class GmshFortranInterface { public: - static Mesh::Implementation* atlas__Gmsh__read(GmshIO* This, char* file_path); - static void atlas__Gmsh__write(GmshIO* This, Mesh::Implementation* mesh, char* file_path); - static Mesh::Implementation* atlas__read_gmsh(char* file_path); - static void atlas__write_gmsh_mesh(const Mesh::Implementation* mesh, char* file_path); - static void atlas__write_gmsh_fieldset(const field::FieldSetImpl* fieldset, functionspace::FunctionSpaceImpl* functionspace, char* file_path, int mode); - static void atlas__write_gmsh_field(const field::FieldImpl* field, functionspace::FunctionSpaceImpl* functionspace, char* file_path, int mode); + static Mesh::Implementation* atlas__Gmsh__read( GmshIO* This, char* file_path ); + static void atlas__Gmsh__write( GmshIO* This, Mesh::Implementation* mesh, char* file_path ); + static Mesh::Implementation* atlas__read_gmsh( char* file_path ); + static void atlas__write_gmsh_mesh( const Mesh::Implementation* mesh, char* file_path ); + static void atlas__write_gmsh_fieldset( const field::FieldSetImpl* fieldset, + functionspace::FunctionSpaceImpl* functionspace, char* file_path, + int mode ); + static void atlas__write_gmsh_field( const field::FieldImpl* field, functionspace::FunctionSpaceImpl* functionspace, + char* file_path, int mode ); }; -Mesh::Implementation* GmshFortranInterface::atlas__Gmsh__read (GmshIO* This, char* file_path) { - Mesh::Implementation* m; - { - Mesh mesh = This->read( PathName(file_path) ); - mesh.get()->attach(); - m = mesh.get(); - } - m->detach(); - return m; +Mesh::Implementation* GmshFortranInterface::atlas__Gmsh__read( GmshIO* This, char* file_path ) { + Mesh::Implementation* m; + { + Mesh mesh = This->read( PathName( file_path ) ); + mesh.get()->attach(); + m = mesh.get(); + } + m->detach(); + return m; } -void GmshFortranInterface::atlas__Gmsh__write (GmshIO* This, Mesh::Implementation* mesh, char* file_path) { - Mesh m(mesh); - This->write( m, PathName(file_path) ); +void GmshFortranInterface::atlas__Gmsh__write( GmshIO* This, Mesh::Implementation* mesh, char* file_path ) { + Mesh m( mesh ); + This->write( m, PathName( file_path ) ); } -Mesh::Implementation* GmshFortranInterface::atlas__read_gmsh (char* file_path) -{ - Mesh::Implementation* m; - { - Mesh mesh = GmshIO().read(PathName(file_path)); - mesh.get()->attach(); - m = mesh.get(); - } - m->detach(); - return m; +Mesh::Implementation* GmshFortranInterface::atlas__read_gmsh( char* file_path ) { + Mesh::Implementation* m; + { + Mesh mesh = GmshIO().read( PathName( file_path ) ); + mesh.get()->attach(); + m = mesh.get(); + } + m->detach(); + return m; } -void GmshFortranInterface::atlas__write_gmsh_mesh (const Mesh::Implementation* mesh, char* file_path) { - GmshIO writer; - writer.write( mesh, PathName(file_path) ); +void GmshFortranInterface::atlas__write_gmsh_mesh( const Mesh::Implementation* mesh, char* file_path ) { + GmshIO writer; + writer.write( mesh, PathName( file_path ) ); } -void GmshFortranInterface::atlas__write_gmsh_fieldset (const field::FieldSetImpl* fieldset, functionspace::FunctionSpaceImpl* functionspace, char* file_path, int mode) { - GmshIO writer; - writer.write( fieldset, functionspace, PathName(file_path) ); +void GmshFortranInterface::atlas__write_gmsh_fieldset( const field::FieldSetImpl* fieldset, + functionspace::FunctionSpaceImpl* functionspace, char* file_path, + int mode ) { + GmshIO writer; + writer.write( fieldset, functionspace, PathName( file_path ) ); } -void GmshFortranInterface::atlas__write_gmsh_field (const field::FieldImpl* field, functionspace::FunctionSpaceImpl* functionspace, char* file_path, int mode) { - GmshIO writer; - writer.write( field, functionspace, PathName(file_path) ); +void GmshFortranInterface::atlas__write_gmsh_field( const field::FieldImpl* field, + functionspace::FunctionSpaceImpl* functionspace, char* file_path, + int mode ) { + GmshIO writer; + writer.write( field, functionspace, PathName( file_path ) ); } extern "C" { @@ -1252,42 +1114,42 @@ extern "C" { // ---------------------------------------------------------------------------- // C wrapper interfaces to C++ routines // ---------------------------------------------------------------------------- -GmshIO* atlas__Gmsh__new () { - return new GmshIO(); +GmshIO* atlas__Gmsh__new() { + return new GmshIO(); } -void atlas__Gmsh__delete (GmshIO* This) { - delete This; +void atlas__Gmsh__delete( GmshIO* This ) { + delete This; } -Mesh::Implementation* atlas__Gmsh__read (GmshIO* This, char* file_path) { - return GmshFortranInterface::atlas__Gmsh__read(This,file_path); +Mesh::Implementation* atlas__Gmsh__read( GmshIO* This, char* file_path ) { + return GmshFortranInterface::atlas__Gmsh__read( This, file_path ); } -void atlas__Gmsh__write (GmshIO* This, Mesh::Implementation* mesh, char* file_path) { - return GmshFortranInterface::atlas__Gmsh__write(This,mesh,file_path); +void atlas__Gmsh__write( GmshIO* This, Mesh::Implementation* mesh, char* file_path ) { + return GmshFortranInterface::atlas__Gmsh__write( This, mesh, file_path ); } -Mesh::Implementation* atlas__read_gmsh (char* file_path) { - return GmshFortranInterface::atlas__read_gmsh(file_path); +Mesh::Implementation* atlas__read_gmsh( char* file_path ) { + return GmshFortranInterface::atlas__read_gmsh( file_path ); } -void atlas__write_gmsh_mesh (const Mesh::Implementation* mesh, char* file_path) { - return GmshFortranInterface::atlas__write_gmsh_mesh(mesh,file_path); +void atlas__write_gmsh_mesh( const Mesh::Implementation* mesh, char* file_path ) { + return GmshFortranInterface::atlas__write_gmsh_mesh( mesh, file_path ); } -void atlas__write_gmsh_fieldset (const field::FieldSetImpl* fieldset, functionspace::FunctionSpaceImpl* functionspace, char* file_path, int mode) { - return GmshFortranInterface::atlas__write_gmsh_fieldset(fieldset,functionspace,file_path,mode); +void atlas__write_gmsh_fieldset( const field::FieldSetImpl* fieldset, functionspace::FunctionSpaceImpl* functionspace, + char* file_path, int mode ) { + return GmshFortranInterface::atlas__write_gmsh_fieldset( fieldset, functionspace, file_path, mode ); } -void atlas__write_gmsh_field (const field::FieldImpl* field, functionspace::FunctionSpaceImpl* functionspace, char* file_path, int mode) { - return GmshFortranInterface::atlas__write_gmsh_field(field,functionspace,file_path,mode); +void atlas__write_gmsh_field( const field::FieldImpl* field, functionspace::FunctionSpaceImpl* functionspace, + char* file_path, int mode ) { + return GmshFortranInterface::atlas__write_gmsh_field( field, functionspace, file_path, mode ); } - } // ---------------------------------------------------------------------------- -} // namespace detail -} // namespace output -} // namespace atlas - +} // namespace detail +} // namespace output +} // namespace atlas diff --git a/src/atlas/output/detail/GmshIO.h b/src/atlas/output/detail/GmshIO.h index 859b25649..6e414bd01 100644 --- a/src/atlas/output/detail/GmshIO.h +++ b/src/atlas/output/detail/GmshIO.h @@ -4,29 +4,44 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include #include +#include #include #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/StructuredColumns.h" #include "atlas/util/Metadata.h" namespace atlas { - class Field; - class FieldSet; - class Mesh; -} +class Field; +class FieldSet; +class Mesh; +} // namespace atlas -namespace atlas { namespace array { class Array; } } +namespace atlas { +namespace array { +class Array; +} +} // namespace atlas -namespace atlas { namespace util { namespace io { class GmshFortranInterface; } } } -namespace atlas { namespace output { class Gmsh; } } +namespace atlas { +namespace util { +namespace io { +class GmshFortranInterface; +} +} // namespace util +} // namespace atlas +namespace atlas { +namespace output { +class Gmsh; +} +} // namespace atlas namespace atlas { namespace output { @@ -35,96 +50,69 @@ namespace detail { //---------------------------------------------------------------------------------------------------------------------- class GmshIO { +public: // members + using Metadata = util::Metadata; + Metadata options; -public: // members - - using Metadata = util::Metadata; - Metadata options; +private: // types + typedef std::ios_base::openmode openmode; -private: // types +public: // methods + GmshIO(); - typedef std::ios_base::openmode openmode; - -public: // methods - - GmshIO(); - - ~GmshIO(); + ~GmshIO(); public: + Mesh read( const eckit::PathName& file_path ) const; - Mesh read(const eckit::PathName& file_path) const; - - void read(const eckit::PathName& file_path, Mesh& mesh) const; - - /// Write mesh file - /// Extra file with available mesh information is written to: - /// - filename_info.msh - void write(const Mesh& mesh, - const eckit::PathName& file_path) const; - - /// Write field to file - /// Depending on argument "mode", the fields will be appended, - /// or existing file will be overwritten - void write(const Field& field, - const eckit::PathName& file_path, - openmode mode = std::ios::out) const; - - /// Write fieldset to file using FunctionSpace - /// Depending on argument "mode", the fields will be appended, - /// or existing file will be overwritten - void write(const FieldSet& fieldset, - const FunctionSpace&, - const eckit::PathName& file_path, - openmode mode = std::ios::out) const; - - /// Write field to file using Functionspace - /// Depending on argument "mode", the fields will be appended, - /// or existing file will be overwritten - void write(const Field& field, - const FunctionSpace&, - const eckit::PathName& file_path, - openmode mode = std::ios::out) const; - + void read( const eckit::PathName& file_path, Mesh& mesh ) const; + /// Write mesh file + /// Extra file with available mesh information is written to: + /// - filename_info.msh + void write( const Mesh& mesh, const eckit::PathName& file_path ) const; + /// Write field to file + /// Depending on argument "mode", the fields will be appended, + /// or existing file will be overwritten + void write( const Field& field, const eckit::PathName& file_path, openmode mode = std::ios::out ) const; + /// Write fieldset to file using FunctionSpace + /// Depending on argument "mode", the fields will be appended, + /// or existing file will be overwritten + void write( const FieldSet& fieldset, const FunctionSpace&, const eckit::PathName& file_path, + openmode mode = std::ios::out ) const; + /// Write field to file using Functionspace + /// Depending on argument "mode", the fields will be appended, + /// or existing file will be overwritten + void write( const Field& field, const FunctionSpace&, const eckit::PathName& file_path, + openmode mode = std::ios::out ) const; private: - - /// Write fieldset to file using Nodes functionspace - /// Depending on argument "mode", the fields will be appended, - /// or existing file will be overwritten - void write_delegate(const FieldSet& fieldset, - const functionspace::NodeColumns&, - const eckit::PathName& file_path, - openmode mode = std::ios::out) const; - - /// Write fieldset to file using StructuredColumns functionspace - /// Depending on argument "mode", the fields will be appended, - /// or existing file will be overwritten - void write_delegate(const FieldSet& fieldset, - const functionspace::StructuredColumns&, - const eckit::PathName& file_path, - openmode mode = std::ios::out) const; - - /// Write field to file using Nodes functionspace - /// Depending on argument "mode", the fields will be appended, - /// or existing file will be overwritten - void write_delegate(const Field& field, - const functionspace::NodeColumns&, - const eckit::PathName& file_path, - openmode mode = std::ios::out) const; - - /// Write field to file using StructuredColumns functionspace - /// Depending on argument "mode", the fields will be appended, - /// or existing file will be overwritten - void write_delegate(const Field& field, - const functionspace::StructuredColumns&, - const eckit::PathName& file_path, - openmode mode = std::ios::out) const; - + /// Write fieldset to file using Nodes functionspace + /// Depending on argument "mode", the fields will be appended, + /// or existing file will be overwritten + void write_delegate( const FieldSet& fieldset, const functionspace::NodeColumns&, const eckit::PathName& file_path, + openmode mode = std::ios::out ) const; + + /// Write fieldset to file using StructuredColumns functionspace + /// Depending on argument "mode", the fields will be appended, + /// or existing file will be overwritten + void write_delegate( const FieldSet& fieldset, const functionspace::StructuredColumns&, + const eckit::PathName& file_path, openmode mode = std::ios::out ) const; + + /// Write field to file using Nodes functionspace + /// Depending on argument "mode", the fields will be appended, + /// or existing file will be overwritten + void write_delegate( const Field& field, const functionspace::NodeColumns&, const eckit::PathName& file_path, + openmode mode = std::ios::out ) const; + + /// Write field to file using StructuredColumns functionspace + /// Depending on argument "mode", the fields will be appended, + /// or existing file will be overwritten + void write_delegate( const Field& field, const functionspace::StructuredColumns&, const eckit::PathName& file_path, + openmode mode = std::ios::out ) const; }; //---------------------------------------------------------------------------------------------------------------------- @@ -133,17 +121,19 @@ class GmshIO { extern "C" { GmshIO* atlas__Gmsh__new(); -void atlas__Gmsh__delete(GmshIO* This); -Mesh::Implementation* atlas__Gmsh__read(GmshIO* This, char* file_path); -void atlas__Gmsh__write(GmshIO* This, Mesh::Implementation* mesh, char* file_path); -Mesh::Implementation* atlas__read_gmsh(char* file_path); -void atlas__write_gmsh_mesh(const Mesh::Implementation* mesh, char* file_path); -void atlas__write_gmsh_fieldset(const field::FieldSetImpl* fieldset, functionspace::FunctionSpaceImpl* function_space, char* file_path, int mode); -void atlas__write_gmsh_field(const field::FieldImpl* field, functionspace::FunctionSpaceImpl* function_space, char* file_path, int mode); +void atlas__Gmsh__delete( GmshIO* This ); +Mesh::Implementation* atlas__Gmsh__read( GmshIO* This, char* file_path ); +void atlas__Gmsh__write( GmshIO* This, Mesh::Implementation* mesh, char* file_path ); +Mesh::Implementation* atlas__read_gmsh( char* file_path ); +void atlas__write_gmsh_mesh( const Mesh::Implementation* mesh, char* file_path ); +void atlas__write_gmsh_fieldset( const field::FieldSetImpl* fieldset, functionspace::FunctionSpaceImpl* function_space, + char* file_path, int mode ); +void atlas__write_gmsh_field( const field::FieldImpl* field, functionspace::FunctionSpaceImpl* function_space, + char* file_path, int mode ); } //---------------------------------------------------------------------------------------------------------------------- -} // namespace detail -} // namespace output -} // namespace atlas +} // namespace detail +} // namespace output +} // namespace atlas diff --git a/src/atlas/output/detail/PointCloudIO.cc b/src/atlas/output/detail/PointCloudIO.cc index 99c9ec93d..9603f910e 100644 --- a/src/atlas/output/detail/PointCloudIO.cc +++ b/src/atlas/output/detail/PointCloudIO.cc @@ -4,27 +4,28 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/output/detail/PointCloudIO.h" #include -#include #include #include -#include "eckit/exception/Exceptions.h" -#include "eckit/filesystem/PathName.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/mesh/Nodes.h" +#include +#include "atlas/array/ArrayView.h" +#include "atlas/array/DataType.h" +#include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" #include "atlas/functionspace/NodeColumns.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/mesh/Nodes.h" #include "atlas/util/CoordinateEnums.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/MakeView.h" -#include "atlas/array/DataType.h" -#include "atlas/output/detail/PointCloudIO.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/filesystem/PathName.h" namespace atlas { namespace output { @@ -34,334 +35,295 @@ namespace detail { namespace { -std::string sanitize_field_name(const std::string& s) -{ - // replace non-printable characters, then trim right & left - std::string r(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 = "_"; - return r; +std::string sanitize_field_name( const std::string& s ) { + // replace non-printable characters, then trim right & left + std::string r( 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 = "_"; + return r; } - -} // end anonymous namespace - +} // end anonymous namespace // ------------------------------------------------------------------ +Mesh PointCloudIO::read( const eckit::PathName& path, std::vector& vfnames ) { + const std::string msg( "PointCloudIO::read: " ); -Mesh PointCloudIO::read(const eckit::PathName& path, std::vector& vfnames ) -{ - const std::string msg("PointCloudIO::read: "); - - Mesh mesh; - - vfnames.clear(); - - { - std::string line; - std::istringstream iss; - std::ostringstream oss; - size_t nb_pts; // # points/nodes - size_t nb_columns; // # data columns (lon,lat,field1,field2,...) - size_t nb_fld; // # fields (nb_fld := nb_columns-2) + Mesh mesh; - // open file and read all of header & data - std::ifstream f(path.asString().c_str()); - if (!f.is_open()) - throw eckit::CantOpenFile(path.asString()); + vfnames.clear(); - // header, part 1: - // determine number of rows/columns - // (read all of line, look for "PointCloudIO" signature, nb_pts, nb_columns, ...) - std::getline(f,line); - iss.str(line); - iss >> line >> nb_pts >> nb_columns; - if (line!="PointCloudIO") { - std::stringstream errmsg; errmsg << msg << "beginning of file `"<> line >> nb_pts >> nb_columns; + if ( line != "PointCloudIO" ) { + std::stringstream errmsg; + errmsg << msg << "beginning of file `" << path << "` not found (expected: PointCloudIO, got: " << line + << ")"; + throw eckit::BadParameter( errmsg.str(), Here() ); + } + if ( nb_pts == 0 ) throw eckit::BadValue( msg + "invalid number of points (failed: nb_pts>0)" ); + if ( nb_columns < 2 ) throw eckit::BadValue( msg + "invalid number of columns (failed: nb_columns>=2)" ); + + mesh.nodes().resize( nb_pts ); + + mesh::Nodes& nodes = mesh.nodes(); + array::ArrayView xy = array::make_view( nodes.xy() ); + + // header, part 2: + // determine columns' labels + // (check end of first line for possible column labels, starting from + // defaults) + + vfnames.resize( nb_columns ); + for ( size_t j = 0; j < nb_columns; ++j ) { + oss.str( "column_" ); + oss << ( j + 1 ); + vfnames[j] = ( iss && iss >> line ) ? sanitize_field_name( line ) : oss.str(); + } + + // (preallocate data, and define fields without the first two columns + // (lon,lat) because they are treated differently) + vfnames.erase( vfnames.begin(), vfnames.begin() + 2 ); + nb_fld = nb_columns - 2; // always >= 0, considering previous check + + std::vector> fields; + for ( size_t j = 0; j < nb_fld; ++j ) { + fields.push_back( array::make_view( + nodes.add( Field( vfnames[j], array::make_datatype(), array::make_shape( nb_pts ) ) ) ) ); + } + + size_t i, j; // (index for node/row and field/column, out of scope to check + // at end of loops) + for ( i = 0; f && i < nb_pts; ++i ) { + std::getline( f, line ); + iss.clear(); + iss.str( line ); + + // NOTE always expects (lon,lat) order, maybe make it configurable? + iss >> xy( i, XX ) >> xy( i, YY ); + ; + 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 << "."; + throw eckit::BadValue( msg + oss.str() ); + } + } + if ( i < nb_pts ) { + oss << "invalid number of lines in data section, read " << ( i ) << " lines, expected " << nb_pts << "."; + throw eckit::BadValue( msg + oss.str() ); + } + + f.close(); } - if (nb_pts==0) - throw eckit::BadValue(msg+"invalid number of points (failed: nb_pts>0)"); - if (nb_columns<2) - throw eckit::BadValue(msg+"invalid number of columns (failed: nb_columns>=2)"); - mesh.nodes().resize(nb_pts); - - mesh::Nodes& nodes = mesh.nodes(); - array::ArrayView< double, 2 > xy = array::make_view( nodes.xy() ); + return mesh; +} - // header, part 2: - // determine columns' labels - // (check end of first line for possible column labels, starting from defaults) +Mesh PointCloudIO::read( const eckit::PathName& path ) { + std::vector vfnames; + return read( path, vfnames ); +} - vfnames.resize(nb_columns); - for (size_t j=0; j>line)? sanitize_field_name(line) : oss.str(); +void PointCloudIO::write( const eckit::PathName& path, const Mesh& mesh ) { + const std::string msg( "PointCloudIO::write: " ); + + // operate in mesh function space, creating transversing data structures + // @warning: several copy operations here + + const mesh::Nodes& nodes = mesh.nodes(); + + const array::ArrayView lonlat = array::make_view( nodes.lonlat() ); + if ( !lonlat.size() ) throw eckit::BadParameter( msg + "invalid number of points (failed: nb_pts>0)" ); + + // get the fields (sanitized) names and values + // (bypasses fields ("lonlat"|"lonlat") as shape(1)!=1) + std::vector vfnames; + std::vector> vfvalues; + for ( size_t i = 0; i < nodes.nb_fields(); ++i ) { + const Field& field = nodes.field( i ); + if ( field.shape( 0 ) == lonlat.shape( 0 ) && field.shape( 1 ) == 1 && + field.datatype() == array::DataType::real64() ) // FIXME: no support for + // non-double types! + { + vfnames.push_back( sanitize_field_name( field.name() ) ); + vfvalues.push_back( array::make_view( field ) ); + } } - // (preallocate data, and define fields without the first two columns (lon,lat) because they are treated differently) - vfnames.erase(vfnames.begin(),vfnames.begin()+2); - nb_fld = nb_columns-2; // always >= 0, considering previous check + std::ofstream f( path.asString().c_str() ); + if ( !f.is_open() ) throw eckit::CantOpenFile( path.asString() ); - std::vector< array::ArrayView > fields; - for (size_t j=0; j ( nodes.add( Field(vfnames[j],array::make_datatype(),array::make_shape(nb_pts)) ) ) ); - } + const size_t Npts = lonlat.shape( 0 ); + const size_t Nfld = vfvalues.size(); - size_t i,j; // (index for node/row and field/column, out of scope to check at end of loops) - for (i=0; f && i> xy(i,XX) >> xy(i,YY);; - for (j=0; iss && j> fields[j](i); - if (j vfnames; - return read(path,vfnames); } -void PointCloudIO::write(const eckit::PathName& path, const Mesh& mesh) -{ - const std::string msg("PointCloudIO::write: "); - - // operate in mesh function space, creating transversing data structures - // @warning: several copy operations here - - const mesh::Nodes& nodes = mesh.nodes(); - - const array::ArrayView< double, 2 > lonlat = array::make_view(nodes.lonlat()); - if (!lonlat.size()) - throw eckit::BadParameter(msg+"invalid number of points (failed: nb_pts>0)"); - - // get the fields (sanitized) names and values - // (bypasses fields ("lonlat"|"lonlat") as shape(1)!=1) - std::vector< std::string > vfnames; - std::vector< array::ArrayView< double, 1 > > vfvalues; - for(size_t i=0; i(field)); +void PointCloudIO::write( const eckit::PathName& path, const FieldSet& fieldset, + const functionspace::NodeColumns& function_space ) { + const std::string msg( "PointCloudIO::write: " ); + + // operate in field sets with same grid and consistent size(s), creating + // transversing data structures + // @warning: several copy operations here + + ASSERT( fieldset.size() ); + + array::ArrayView lonlat = array::make_view( function_space.nodes().lonlat() ); + if ( !lonlat.size() ) throw eckit::BadParameter( msg + "invalid number of points (failed: nb_pts>0)" ); + + // get the fields (sanitized) names and values + // (bypasses fields ("lonlat"|"lonlat") as shape(1)!=1) + std::vector vfnames; + std::vector> vfvalues; + for ( size_t i = 0; i < fieldset.size(); ++i ) { + const Field& field = fieldset[i]; + if ( field.shape( 0 ) == lonlat.shape( 0 ) && field.rank() == 1 && + field.name() != "glb_idx" ) // FIXME: no support for non-int types! + { + vfnames.push_back( sanitize_field_name( field.name() ) ); + vfvalues.push_back( array::make_view( field ) ); + } } - } - - std::ofstream f( path.asString().c_str() ); - if (!f.is_open()) - throw eckit::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 lonlat = array::make_view( function_space.nodes().lonlat() ); - if (!lonlat.size()) - throw eckit::BadParameter(msg+"invalid number of points (failed: nb_pts>0)"); + f.precision( std::numeric_limits::digits10 ); - // get the fields (sanitized) names and values - // (bypasses fields ("lonlat"|"lonlat") as shape(1)!=1) - std::vector< std::string > vfnames; - std::vector< array::ArrayView< double, 1 > > vfvalues; - for (size_t i=0; i(field)); + // 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 ) + f << '\t' << vfvalues[j]( i ); + f << '\n'; } - } - - std::ofstream f(path.asString().c_str()); - if (!f.is_open()) - throw eckit::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::digits10 ); - - // data - for (size_t i=0; i& pts ) { + std::ofstream f( path.asString().c_str() ); + if ( !f.is_open() ) throw eckit::CantOpenFile( path.asString() ); -void PointCloudIO::write( - const eckit::PathName& path, - const std::vector< PointLonLat >& pts ) -{ - std::ofstream f(path.asString().c_str()); - if (!f.is_open()) - throw eckit::CantOpenFile(path.asString()); - - // header - f << "PointCloudIO\t" << pts.size() << '\t' << 2 << "\tlon\tlat\n"; + // header + f << "PointCloudIO\t" << pts.size() << '\t' << 2 << "\tlon\tlat\n"; - // data - for (size_t i=0; i& lon, const std::vector< double >& lat, - const std::vector< std::vector< double >* >& vfvalues, - const std::vector< std::string >& vfnames ) -{ - const std::string msg("PointCloudIO::write: "); - const size_t - Npts (lon.size()), - Nfld (vfvalues.size()); - if (Npts!=lat.size()) - throw eckit::BadParameter(msg+"number of points inconsistent (failed: #lon == #lat)"); - if (Nfld!=vfnames.size()) - throw eckit::BadParameter(msg+"number of fields inconsistent (failed: #vfvalues == #vfnames)"); - for (size_t j=0; jsize()) - throw eckit::BadParameter(msg+"number of points inconsistent (failed: #lon == #lat == #*vfvalues[])"); - - std::ofstream f(path.asString().c_str()); - if (!f.is_open()) - throw eckit::CantOpenFile(path.asString()); - - // header - f << "PointCloudIO\t" << Npts << '\t' << (2+Nfld) << "\tlon\tlat"; - for (size_t j=0; joperator[](i); +void PointCloudIO::write( const eckit::PathName& path, const std::vector& lon, const std::vector& lat, + const std::vector*>& vfvalues, const std::vector& vfnames ) { + const std::string msg( "PointCloudIO::write: " ); + const size_t Npts( lon.size() ), Nfld( vfvalues.size() ); + if ( Npts != lat.size() ) throw eckit::BadParameter( msg + "number of points inconsistent (failed: #lon == #lat)" ); + if ( Nfld != vfnames.size() ) + throw eckit::BadParameter( msg + "number of fields inconsistent (failed: #vfvalues == #vfnames)" ); + for ( size_t j = 0; j < Nfld; ++j ) + if ( Npts != vfvalues[j]->size() ) + throw eckit::BadParameter( msg + + "number of points inconsistent (failed: " + "#lon == #lat == #*vfvalues[])" ); + + std::ofstream f( path.asString().c_str() ); + if ( !f.is_open() ) throw eckit::CantOpenFile( path.asString() ); + + // header + f << "PointCloudIO\t" << Npts << '\t' << ( 2 + Nfld ) << "\tlon\tlat"; + for ( size_t j = 0; j < Nfld; ++j ) + f << '\t' << sanitize_field_name( vfnames[j] ); f << '\n'; - } - f.close(); + // data + for ( size_t i = 0; i < Npts; ++i ) { + f << lon[i] << '\t' << lat[i]; + for ( size_t j = 0; j < Nfld; ++j ) + f << '\t' << vfvalues[j]->operator[]( i ); + f << '\n'; + } + + f.close(); } +void PointCloudIO::write( const eckit::PathName& path, const int& nb_pts, const double* lon, const double* lat, + const int& nb_fld, const double** afvalues, const char** afnames ) { + 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 eckit::BadParameter( msg + "invalid number of points (nb_nodes)" ); + if ( !lon ) throw eckit::BadParameter( msg + "invalid array describing longitude (lon)" ); + if ( !lat ) throw eckit::BadParameter( msg + "invalid array describing latitude (lat)" ); -void PointCloudIO::write( - const eckit::PathName& path, - const int& nb_pts, const double* lon, const double* lat, - const int& nb_fld, const double** afvalues, const char** afnames ) -{ - 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 eckit::BadParameter(msg+"invalid number of points (nb_nodes)"); - if (!lon) - throw eckit::BadParameter(msg+"invalid array describing longitude (lon)"); - if (!lat) - throw eckit::BadParameter(msg+"invalid array describing latitude (lat)"); - - std::ofstream f(path.asString().c_str()); - if (!f.is_open()) - throw eckit::CantOpenFile(path.asString()); - - // header - f << "PointCloudIO\t" << Npts << '\t' << (2+Nfld) << "\tlon\tlat"; - for (size_t j=0; j #include +#include "atlas/util/Point.h" // forward declarations namespace eckit { - class PathName; +class PathName; } namespace atlas { - class Field; - class FieldSet; -} +class Field; +class FieldSet; +} // namespace atlas namespace atlas { namespace grid { - class Grid; - class Unstructured; -} } +class Grid; +class Unstructured; +} // namespace grid +} // namespace atlas -namespace atlas { class Mesh; } -namespace atlas { namespace functionspace { class NodeColumns; } } +namespace atlas { +class Mesh; +} +namespace atlas { +namespace functionspace { +class NodeColumns; +} +} // namespace atlas namespace atlas { namespace output { @@ -42,95 +51,95 @@ namespace detail { * - writing of Mesh * @warning only supports reading/writing doubles scalar fields */ - class PointCloudIO { - public: - - /** - * @brief Read PointCloudIO file into a Mesh - * @param path input file path - * @param Grid data structure pointer to use - * @return Grid data structure pointer - */ - static Mesh read( const eckit::PathName& path ); - - /** - * @brief Read PointCloudIO file into a Mesh - * @param path input file path - * @param vfnames names of fields to read - * @return Mesh pointer - */ - static Mesh read(const eckit::PathName& path, std::vector& vfnames ); - - /** - * @brief Write Grid to PointCloudIO file (overwrites possibly existing file) - * @param path output file path - * @param grid Grid data structure - */ - static void write(const eckit::PathName& path, const Mesh& mesh); - - /** - * @brief Write FieldSet to PointCloudIO file (overwrites possibly existing file) - * @param path output file path - * @param fieldset FieldSet data structure - */ - static void write(const eckit::PathName& path, const FieldSet& fieldset, const functionspace::NodeColumns &function_space); - - /** - * @brief Write lan/lon to PointCloudIO file (overwrites possibly existing file) - * @note length of vectors lat and lon should be the same - * @param path output file path - * @param lon vector containing longitude values - * @param lat vector containing latitude values - */ - static void write( - const eckit::PathName& path, - const std::vector< PointLonLat >& pts ); - - /** - * @brief Write lan/lon and fields to PointCloudIO file (overwrites possibly existing file) - * @param path output file path - * @param nb_pts number of points in unstructured grid - * @param lon array (of length nb_pts) pointer containing longitude - * @param lat array (of length nb_pts) pointer containing latitude - * @param nb_fld number of fields (default none) - * @param afvalues array (of length nb_fld) of arrays (of length nb_pts), containing field values - * @param afnames array (of length nb_fld) of field names - */ - static void write( - const eckit::PathName& path, - const int& nb_pts, const double* lon, const double* lat, - const int& nb_fld=0, const double** afvalues=NULL , const char** afnames=NULL ); - - /** - * @brief Write lan/lon and fields to PointCloudIO file (overwrites possibly existing file) - * @note length of vectors lat, lon and *vfvalues[] (each pointee) should be the same - * @note length of vectors vfvalues and vfnames should be the same - * @param path output file path - * @param lon vector containing longitude values - * @param lat vector containing latitude values - * @param vfvalues vector of vector pointers, each pointing to field values vectors - * @param vfnames vector of field names - */ - static void write( - const eckit::PathName& path, - const std::vector< double >& lon, const std::vector< double >& lat, - const std::vector< std::vector< double >* >& vfvalues=std::vector< std::vector< double >* >(), - const std::vector< std::string >& vfnames=std::vector< std::string >() ); +class PointCloudIO { +public: + /** + * @brief Read PointCloudIO file into a Mesh + * @param path input file path + * @param Grid data structure pointer to use + * @return Grid data structure pointer + */ + static Mesh read( const eckit::PathName& path ); + + /** + * @brief Read PointCloudIO file into a Mesh + * @param path input file path + * @param vfnames names of fields to read + * @return Mesh pointer + */ + static Mesh read( const eckit::PathName& path, std::vector& vfnames ); + + /** + * @brief Write Grid to PointCloudIO file (overwrites possibly existing file) + * @param path output file path + * @param grid Grid data structure + */ + static void write( const eckit::PathName& path, const Mesh& mesh ); + /** + * @brief Write FieldSet to PointCloudIO file (overwrites possibly existing + * file) + * @param path output file path + * @param fieldset FieldSet data structure + */ + static void write( const eckit::PathName& path, const FieldSet& fieldset, + const functionspace::NodeColumns& function_space ); + + /** + * @brief Write lan/lon to PointCloudIO file (overwrites possibly existing file) + * @note length of vectors lat and lon should be the same + * @param path output file path + * @param lon vector containing longitude values + * @param lat vector containing latitude values + */ + static void write( const eckit::PathName& path, const std::vector& pts ); + + /** + * @brief Write lan/lon and fields to PointCloudIO file (overwrites possibly + * existing file) + * @param path output file path + * @param nb_pts number of points in unstructured grid + * @param lon array (of length nb_pts) pointer containing longitude + * @param lat array (of length nb_pts) pointer containing latitude + * @param nb_fld number of fields (default none) + * @param afvalues array (of length nb_fld) of arrays (of length nb_pts), + * containing field values + * @param afnames array (of length nb_fld) of field names + */ + static void write( const eckit::PathName& path, const int& nb_pts, const double* lon, const double* lat, + const int& nb_fld = 0, const double** afvalues = NULL, const char** afnames = NULL ); + + /** + * @brief Write lan/lon and fields to PointCloudIO file (overwrites possibly + * existing file) + * @note length of vectors lat, lon and *vfvalues[] (each pointee) should be the + * same + * @note length of vectors vfvalues and vfnames should be the same + * @param path output file path + * @param lon vector containing longitude values + * @param lat vector containing latitude values + * @param vfvalues vector of vector pointers, each pointing to field values + * vectors + * @param vfnames vector of field names + */ + static void write( const eckit::PathName& path, const std::vector& lon, const std::vector& lat, + const std::vector*>& vfvalues = std::vector*>(), + const std::vector& vfnames = std::vector() ); }; - // C wrapper interfaces to C++ routines -extern "C" -{ - // PointCloudIO* atlas__pointcloud__new (); - // void atlas__pointcloud__delete(PointCloudIO* This); - // mesh::Mesh* atlas__pointcloud__read(PointCloudIO* This, char* file_path); - // mesh::Mesh* atlas__read_pointcloud(char* file_path); - // void atlas__write_pointcloud_fieldset(char* file_path, const field::FieldImpl* fieldset, const functionspace::FunctionSpaceImpl* functionspace); - // void atlas__write_pointcloud_field(char* file_path, const field::FieldImpl* field, const functionspace::FunctionSpaceImpl* functionspace); +extern "C" { +// PointCloudIO* atlas__pointcloud__new (); +// void atlas__pointcloud__delete(PointCloudIO* This); +// mesh::Mesh* atlas__pointcloud__read(PointCloudIO* This, char* file_path); +// mesh::Mesh* atlas__read_pointcloud(char* file_path); +// void atlas__write_pointcloud_fieldset(char* file_path, const +// field::FieldImpl* fieldset, const functionspace::FunctionSpaceImpl* +// functionspace); +// void atlas__write_pointcloud_field(char* file_path, const field::FieldImpl* +// field, const functionspace::FunctionSpaceImpl* functionspace); } -} // namespace detail -} // namespace output -} // namespace atlas +} // namespace detail +} // namespace output +} // namespace atlas diff --git a/src/atlas/parallel/Checksum.cc b/src/atlas/parallel/Checksum.cc index ebe9ebf46..b005a4880 100644 --- a/src/atlas/parallel/Checksum.cc +++ b/src/atlas/parallel/Checksum.cc @@ -4,135 +4,107 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include "atlas/parallel/Checksum.h" +#include namespace atlas { namespace parallel { -Checksum::Checksum() : - name_() -{ - is_setup_ = false; +Checksum::Checksum() : name_() { + is_setup_ = false; } -Checksum::Checksum(const std::string& name) : - name_(name) -{ - is_setup_ = false; +Checksum::Checksum( const std::string& name ) : name_( name ) { + is_setup_ = false; } -void Checksum::setup( const int part[], - const int remote_idx[], const int base, - const gidx_t glb_idx[], - const int parsize ) -{ - parsize_ = parsize; - gather_.reset( new GatherScatter() ); - gather_->setup(part,remote_idx,base,glb_idx,parsize); - is_setup_ = true; +void Checksum::setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], + const int parsize ) { + parsize_ = parsize; + gather_.reset( new GatherScatter() ); + gather_->setup( part, remote_idx, base, glb_idx, parsize ); + is_setup_ = true; } - -void Checksum::setup( const int part[], - const int remote_idx[], const int base, - const gidx_t glb_idx[], const int mask[], const int parsize ) -{ - parsize_ = parsize; - gather_.reset( new GatherScatter() ); - gather_->setup(part,remote_idx,base,glb_idx,mask,parsize); - is_setup_ = true; +void Checksum::setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], + const int mask[], const int parsize ) { + parsize_ = parsize; + gather_.reset( new GatherScatter() ); + gather_->setup( part, remote_idx, base, glb_idx, mask, parsize ); + is_setup_ = true; } void Checksum::setup( const eckit::SharedPtr& gather ) { - gather_ = gather; - parsize_ = gather->parsize_; - is_setup_ = true; + gather_ = gather; + parsize_ = gather->parsize_; + is_setup_ = true; } - ///////////////////// - -Checksum* atlas__Checksum__new () { - return new Checksum(); +Checksum* atlas__Checksum__new() { + return new Checksum(); } -void atlas__Checksum__delete (Checksum* This) { - delete This; +void atlas__Checksum__delete( Checksum* This ) { + delete This; } -void atlas__Checksum__setup32 ( Checksum* This, int part[], - int remote_idx[], int base, - int glb_idx[], - int parsize ) -{ -#if ATLAS_BITS_GLOBAL==32 - This->setup(part,remote_idx,base,glb_idx,parsize); +void atlas__Checksum__setup32( Checksum* This, int part[], int remote_idx[], int base, int glb_idx[], int parsize ) { +#if ATLAS_BITS_GLOBAL == 32 + This->setup( part, remote_idx, base, glb_idx, parsize ); #else - std::vector glb_idx_convert(parsize); - for( int j=0; jsetup(part,remote_idx,base,glb_idx_convert.data(),parsize); + std::vector glb_idx_convert( parsize ); + for ( int j = 0; j < parsize; ++j ) { + glb_idx_convert[j] = glb_idx[j]; + } + This->setup( part, remote_idx, base, glb_idx_convert.data(), parsize ); #endif } -void atlas__Checksum__setup64 ( Checksum* This, int part[], - int remote_idx[], int base, - long glb_idx[], - int parsize ) -{ -#if ATLAS_BITS_GLOBAL==64 - This->setup(part,remote_idx,base,glb_idx,parsize); +void atlas__Checksum__setup64( Checksum* This, int part[], int remote_idx[], int base, long glb_idx[], int parsize ) { +#if ATLAS_BITS_GLOBAL == 64 + This->setup( part, remote_idx, base, glb_idx, parsize ); #else - std::vector glb_idx_convert(parsize); - for( int j=0; jsetup(part,remote_idx,base,glb_idx_convert.data(),parsize); + std::vector glb_idx_convert( parsize ); + for ( int j = 0; j < parsize; ++j ) { + glb_idx_convert[j] = glb_idx[j]; + } + This->setup( part, remote_idx, base, glb_idx_convert.data(), parsize ); #endif } -void atlas__Checksum__execute_strided_int ( Checksum* This, - int lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, - char* checksum ) -{ - std::strcpy( checksum, This->execute(lfield,lvar_strides,lvar_extents,lvar_rank).c_str() ); +void atlas__Checksum__execute_strided_int( Checksum* This, int lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, char* checksum ) { + std::strcpy( checksum, This->execute( lfield, lvar_strides, lvar_extents, lvar_rank ).c_str() ); } -void atlas__Checksum__execute_strided_float ( Checksum* This, - float lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, - char* checksum ) -{ - std::strcpy( checksum, This->execute(lfield,lvar_strides,lvar_extents,lvar_rank).c_str() ); +void atlas__Checksum__execute_strided_float( Checksum* This, float lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, char* checksum ) { + std::strcpy( checksum, This->execute( lfield, lvar_strides, lvar_extents, lvar_rank ).c_str() ); } - -void atlas__Checksum__execute_strided_double ( Checksum* This, - double lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, - char* checksum ) -{ - std::strcpy( checksum, This->execute(lfield,lvar_strides,lvar_extents,lvar_rank).c_str() ); +void atlas__Checksum__execute_strided_double( Checksum* This, double lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, char* checksum ) { + std::strcpy( checksum, This->execute( lfield, lvar_strides, lvar_extents, lvar_rank ).c_str() ); } - -//const char* atlas__Checksum__execute_strided_double (Checksum* This, -// double lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank) +// const char* atlas__Checksum__execute_strided_double (Checksum* This, +// double lfield[], int +// lvar_strides[], int +// lvar_extents[], int lvar_rank) //{ // std::string checksum = // This->execute(lfield,lvar_strides,lvar_extents,lvar_rank); // return checksum.c_str(); //} - ///////////////////// -} // namespace parallel -} // namespace atlas +} // namespace parallel +} // namespace atlas diff --git a/src/atlas/parallel/Checksum.h b/src/atlas/parallel/Checksum.h index 04f85f40d..637ba537d 100644 --- a/src/atlas/parallel/Checksum.h +++ b/src/atlas/parallel/Checksum.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,188 +13,162 @@ #define Checksum_h #include -#include "eckit/memory/SharedPtr.h" -#include "eckit/memory/Owned.h" -#include "eckit/utils/Translator.h" -#include "atlas/util/Checksum.h" #include "atlas/array/ArrayView.h" -#include "atlas/runtime/Log.h" -#include "atlas/parallel/mpi/mpi.h" #include "atlas/parallel/GatherScatter.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Log.h" +#include "atlas/util/Checksum.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" +#include "eckit/utils/Translator.h" namespace atlas { namespace parallel { -class Checksum: public eckit::Owned { - -public: // types +class Checksum : public eckit::Owned { +public: // types typedef eckit::SharedPtr Ptr; public: - Checksum(); - Checksum(const std::string& name); - virtual ~Checksum() {} - -public: // methods - - std::string name() const { return name_; } - - /// @brief Setup - /// @param [in] part List of partitions - /// @param [in] remote_idx List of local indices on remote partitions - /// @param [in] base values of remote_idx start at "base" - /// @param [in] glb_idx List of global indices - /// @param [in] max_glb_idx maximum glb index we want to Checksum. - /// To Checksum everything, set to val > max value in domain - /// @param [in] parsize size of given lists - void setup( const int part[], - const int remote_idx[], const int base, - const gidx_t glb_idx[], - const int parsize ); - - /// @brief Setup - /// @param [in] part List of partitions - /// @param [in] remote_idx List of local indices on remote partitions - /// @param [in] base values of remote_idx start at "base" - /// @param [in] glb_idx List of global indices - /// @param [in] mask Mask indices not to include in the communication - /// pattern (0=include,1=exclude) - /// @param [in] parsize size of given lists - void setup( const int part[], - const int remote_idx[], const int base, - const gidx_t glb_idx[], const int mask[], const int parsize ); - - /// @brief Setup - void setup( const eckit::SharedPtr& ); - - template - std::string execute( const DATA_TYPE lfield[], - const int lvar_strides[], - const int lvar_extents[], - const int lvar_rank ) const; - - template - std::string execute( DATA_TYPE lfield[], const int nb_vars ) const; - - template - std::string execute( const array::ArrayView& lfield ) const; - - template - void var_info( const array::ArrayView& arr, - std::vector& varstrides, - std::vector& varextents ) const; - -private: // data - std::string name_; - eckit::SharedPtr gather_; - bool is_setup_; - size_t parsize_; + Checksum(); + Checksum( const std::string& name ); + virtual ~Checksum() {} + +public: // methods + std::string name() const { return name_; } + + /// @brief Setup + /// @param [in] part List of partitions + /// @param [in] remote_idx List of local indices on remote partitions + /// @param [in] base values of remote_idx start at "base" + /// @param [in] glb_idx List of global indices + /// @param [in] max_glb_idx maximum glb index we want to Checksum. + /// To Checksum everything, set to val > max value in + /// domain + /// @param [in] parsize size of given lists + void setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], const int parsize ); + + /// @brief Setup + /// @param [in] part List of partitions + /// @param [in] remote_idx List of local indices on remote partitions + /// @param [in] base values of remote_idx start at "base" + /// @param [in] glb_idx List of global indices + /// @param [in] mask Mask indices not to include in the communication + /// pattern (0=include,1=exclude) + /// @param [in] parsize size of given lists + void setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], const int mask[], + const int parsize ); + + /// @brief Setup + void setup( const eckit::SharedPtr& ); + + template + std::string execute( const DATA_TYPE lfield[], const int lvar_strides[], const int lvar_extents[], + const int lvar_rank ) const; + + template + std::string execute( DATA_TYPE lfield[], const int nb_vars ) const; + + template + std::string execute( const array::ArrayView& lfield ) const; + + template + void var_info( const array::ArrayView& arr, std::vector& varstrides, + std::vector& varextents ) const; + +private: // data + std::string name_; + eckit::SharedPtr gather_; + bool is_setup_; + size_t parsize_; }; -template -std::string Checksum::execute( const DATA_TYPE data[], - const int var_strides[], - const int var_extents[], - const int var_rank ) const -{ - size_t root = 0; - - if( ! is_setup_ ) - { - throw eckit::SeriousBug("Checksum was not setup",Here()); - } - std::vector local_checksums(parsize_); - int var_size = var_extents[0]*var_strides[0]; - - for( size_t pp=0; pp global_checksums( mpi::comm().rank() == root ? gather_->glb_dof() : 0 ); - parallel::Field loc(local_checksums.data(),1); - parallel::Field glb(global_checksums.data(),1); - gather_->gather(&loc,&glb,1); - - util::checksum_t glb_checksum = util::checksum( - global_checksums.data(), - global_checksums.size()); - - mpi::comm().broadcast(glb_checksum, root); - - return eckit::Translator()(glb_checksum); -} +template +std::string Checksum::execute( const DATA_TYPE data[], const int var_strides[], const int var_extents[], + const int var_rank ) const { + size_t root = 0; + if ( !is_setup_ ) { throw eckit::SeriousBug( "Checksum was not setup", Here() ); } + std::vector local_checksums( parsize_ ); + int var_size = var_extents[0] * var_strides[0]; -template -std::string Checksum::execute( DATA_TYPE lfield[], const int nb_vars ) const -{ - int strides[] = {1}; - int extents[] = {nb_vars}; - return execute( lfield, strides, extents, 1 ); + for ( size_t pp = 0; pp < parsize_; ++pp ) { + local_checksums[pp] = util::checksum( data + pp * var_size, var_size ); + } + + std::vector global_checksums( mpi::comm().rank() == root ? gather_->glb_dof() : 0 ); + parallel::Field loc( local_checksums.data(), 1 ); + parallel::Field glb( global_checksums.data(), 1 ); + gather_->gather( &loc, &glb, 1 ); + + util::checksum_t glb_checksum = util::checksum( global_checksums.data(), global_checksums.size() ); + + mpi::comm().broadcast( glb_checksum, root ); + + return eckit::Translator()( glb_checksum ); } +template +std::string Checksum::execute( DATA_TYPE lfield[], const int nb_vars ) const { + int strides[] = {1}; + int extents[] = {nb_vars}; + return execute( lfield, strides, extents, 1 ); +} -template -void Checksum::var_info( const array::ArrayView& arr, - std::vector& varstrides, - std::vector& varshape ) const -{ - int rank = std::max(1,RANK-1) ; - varstrides.resize(rank); - varshape.resize(rank); - - if( RANK>1 ) - { - size_t stride=1; - for( int j=RANK-1; j>0; --j ) { - varstrides[j-1] = stride; - varshape[j-1] = arr.shape(j); - stride *= varshape[j-1]; +template +void Checksum::var_info( const array::ArrayView& arr, std::vector& varstrides, + std::vector& varshape ) const { + int rank = std::max( 1, RANK - 1 ); + varstrides.resize( rank ); + varshape.resize( rank ); + + if ( RANK > 1 ) { + size_t stride = 1; + for ( int j = RANK - 1; j > 0; --j ) { + varstrides[j - 1] = stride; + varshape[j - 1] = arr.shape( j ); + stride *= varshape[j - 1]; + } + // varstrides.assign(arr.strides()+1,arr.strides()+RANK); + // varshape.assign(arr.shape()+1,arr.shape()+RANK); + } + else { + varstrides[0] = 1; + varshape[0] = 1; } -// varstrides.assign(arr.strides()+1,arr.strides()+RANK); -// varshape.assign(arr.shape()+1,arr.shape()+RANK); - } - else - { - varstrides[0] = 1; - varshape[0] = 1; - } } template -std::string Checksum::execute( const array::ArrayView& lfield ) const -{ - if( lfield.shape(0) == parsize_ ) - { - std::vector lvarstrides, lvarextents; - var_info(lfield, lvarstrides, lvarextents); - return execute( lfield.data(), lvarstrides.data(), lvarextents.data(), lvarstrides.size() ); - } - else - { - Log::error() << "lfield.shape(0) = " << lfield.shape(0); - NOTIMP; // Need to implement with parallel ranks > 1 - } - return std::string(""); +std::string Checksum::execute( const array::ArrayView& lfield ) const { + if ( lfield.shape( 0 ) == parsize_ ) { + std::vector lvarstrides, lvarextents; + var_info( lfield, lvarstrides, lvarextents ); + return execute( lfield.data(), lvarstrides.data(), lvarextents.data(), lvarstrides.size() ); + } + else { + Log::error() << "lfield.shape(0) = " << lfield.shape( 0 ); + NOTIMP; // Need to implement with parallel ranks > 1 + } + return std::string( "" ); } - // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -extern "C" -{ - Checksum* atlas__Checksum__new (); - void atlas__Checksum__delete (Checksum* This); - void atlas__Checksum__setup32 (Checksum* This, int part[], int remote_idx[], int base, int glb_idx[], int parsize); - void atlas__Checksum__setup64 (Checksum* This, int part[], int remote_idx[], int base, long glb_idx[], int parsize); - void atlas__Checksum__execute_strided_int (Checksum* This, int lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, char* checksum); - void atlas__Checksum__execute_strided_float (Checksum* This, float lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, char* checksum); - void atlas__Checksum__execute_strided_double (Checksum* This, double lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, char* checksum); +extern "C" { +Checksum* atlas__Checksum__new(); +void atlas__Checksum__delete( Checksum* This ); +void atlas__Checksum__setup32( Checksum* This, int part[], int remote_idx[], int base, int glb_idx[], int parsize ); +void atlas__Checksum__setup64( Checksum* This, int part[], int remote_idx[], int base, long glb_idx[], int parsize ); +void atlas__Checksum__execute_strided_int( Checksum* This, int lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, char* checksum ); +void atlas__Checksum__execute_strided_float( Checksum* This, float lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, char* checksum ); +void atlas__Checksum__execute_strided_double( Checksum* This, double lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, char* checksum ); } // ------------------------------------------------------------------ -} // namespace parallel -} // namespace atlas +} // namespace parallel +} // namespace atlas -#endif // Checksum_h +#endif // Checksum_h diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index d8c690cb0..0a8fa7205 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -4,412 +4,366 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include -#include +#include "atlas/parallel/GatherScatter.h" #include +#include #include +#include #include "atlas/array.h" #include "atlas/array/ArrayView.h" +#include "atlas/parallel/mpi/Statistics.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "atlas/parallel/GatherScatter.h" -#include "atlas/parallel/mpi/Statistics.h" namespace atlas { namespace parallel { namespace { -struct IsGhostPoint -{ - IsGhostPoint( const int part[], const int ridx[], const int base, const int N ) - { - part_ = part; - ridx_ = ridx; - base_ = base; - mypart_ = mpi::comm().rank(); - } - - bool operator()(int idx) - { - if( part_[idx] != mypart_ ) return true; - if( ridx_[idx] != base_+idx ) return true; - return false; - } - int mypart_; - const int* part_; - const int* ridx_; - int base_; -}; +struct IsGhostPoint { + IsGhostPoint( const int part[], const int ridx[], const int base, const int N ) { + part_ = part; + ridx_ = ridx; + base_ = base; + mypart_ = mpi::comm().rank(); + } -struct Node -{ - gidx_t p,i; - gidx_t g; - - Node() {} - Node(gidx_t gid, int part, int idx) - { - g = gid; - p = part; - i = idx; - } - - bool operator < (const Node& other) const - { - return ( g < other.g ); - } - - bool operator == (const Node& other) const - { - return ( g == other.g ); - } + bool operator()( int idx ) { + if ( part_[idx] != mypart_ ) return true; + if ( ridx_[idx] != base_ + idx ) return true; + return false; + } + int mypart_; + const int* part_; + const int* ridx_; + int base_; }; +struct Node { + gidx_t p, i; + gidx_t g; -bool operator < (const gidx_t g, const Node& n) -{ - return ( g < n.g ); -} + Node() {} + Node( gidx_t gid, int part, int idx ) { + g = gid; + p = part; + i = idx; + } + + bool operator<( const Node& other ) const { return ( g < other.g ); } + + bool operator==( const Node& other ) const { return ( g == other.g ); } +}; +bool operator<( const gidx_t g, const Node& n ) { + return ( g < n.g ); } -GatherScatter::GatherScatter() : - name_(), - is_setup_(false) -{ - myproc = mpi::comm().rank(); - nproc = mpi::comm().size(); +} // namespace + +GatherScatter::GatherScatter() : name_(), is_setup_( false ) { + myproc = mpi::comm().rank(); + nproc = mpi::comm().size(); } -GatherScatter::GatherScatter(const std::string& name) : - name_(name), - is_setup_(false) -{ - myproc = mpi::comm().rank(); - nproc = mpi::comm().size(); +GatherScatter::GatherScatter( const std::string& name ) : name_( name ), is_setup_( false ) { + myproc = mpi::comm().rank(); + nproc = mpi::comm().size(); } +void GatherScatter::setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], + const int mask[], const size_t parsize ) { + ATLAS_TRACE( "GatherScatter::setup" ); + + parsize_ = parsize; -void GatherScatter::setup( const int part[], - const int remote_idx[], const int base, - const gidx_t glb_idx[], const int mask[], const size_t parsize ) -{ - ATLAS_TRACE("GatherScatter::setup"); + glbcounts_.resize( nproc ); + glbcounts_.assign( nproc, 0 ); + glbdispls_.resize( nproc ); + glbdispls_.assign( nproc, 0 ); + const size_t nvar = 3; - parsize_ = parsize; + std::vector sendnodes( parsize_ * nvar ); + + loccnt_ = 0; + for ( size_t n = 0; n < parsize_; ++n ) { + if ( !mask[n] ) { + sendnodes[loccnt_++] = glb_idx[n]; + sendnodes[loccnt_++] = part[n]; + sendnodes[loccnt_++] = remote_idx[n] - base; + } + } - glbcounts_.resize(nproc); glbcounts_.assign(nproc,0); - glbdispls_.resize(nproc); glbdispls_.assign(nproc,0); - const size_t nvar = 3; + ATLAS_TRACE_MPI( ALLGATHER ) { mpi::comm().allGather( loccnt_, glbcounts_.begin(), glbcounts_.end() ); } - std::vector sendnodes(parsize_*nvar); + glbcnt_ = std::accumulate( glbcounts_.begin(), glbcounts_.end(), 0 ); - loccnt_ = 0; - for( size_t n=0; n recvnodes(glbcnt_); - - ATLAS_TRACE_MPI( ALLGATHER ) { - mpi::comm().allGatherv(sendnodes.begin(), sendnodes.begin() + loccnt_, - recvnodes.data(), glbcounts_.data(), glbdispls_.data()); - } - - // Load recvnodes in sorting structure - size_t nb_recv_nodes = glbcnt_/nvar; - std::vector node_sort(nb_recv_nodes); - for( size_t n=0; n idx(nproc,0); - for( size_t n=0; n recvnodes( glbcnt_ ); + + ATLAS_TRACE_MPI( ALLGATHER ) { + mpi::comm().allGatherv( sendnodes.begin(), sendnodes.begin() + loccnt_, recvnodes.data(), glbcounts_.data(), + glbdispls_.data() ); + } + + // Load recvnodes in sorting structure + size_t nb_recv_nodes = glbcnt_ / nvar; + std::vector node_sort( nb_recv_nodes ); + for ( size_t n = 0; n < nb_recv_nodes; ++n ) { + node_sort[n].g = recvnodes[n * nvar + 0]; + node_sort[n].p = recvnodes[n * nvar + 1]; + node_sort[n].i = recvnodes[n * nvar + 2]; + } + + recvnodes.clear(); + + // Sort on "g" member, and remove duplicates + ATLAS_TRACE_SCOPE( "sorting" ) { + std::sort( node_sort.begin(), node_sort.end() ); + node_sort.erase( std::unique( node_sort.begin(), node_sort.end() ), node_sort.end() ); + } + glbcounts_.assign( nproc, 0 ); + glbdispls_.assign( nproc, 0 ); + for ( size_t n = 0; n < node_sort.size(); ++n ) { + ++glbcounts_[node_sort[n].p]; + } + glbdispls_[0] = 0; + + for ( size_t jproc = 1; jproc < nproc; ++jproc ) // start at 1 + { + glbdispls_[jproc] = glbcounts_[jproc - 1] + glbdispls_[jproc - 1]; + } + glbcnt_ = std::accumulate( glbcounts_.begin(), glbcounts_.end(), 0 ); + loccnt_ = glbcounts_[myproc]; + glbmap_.clear(); + glbmap_.resize( glbcnt_ ); + locmap_.clear(); + locmap_.resize( loccnt_ ); + std::vector idx( nproc, 0 ); + for ( size_t n = 0; n < node_sort.size(); ++n ) { + size_t jproc = node_sort[n].p; + glbmap_[glbdispls_[jproc] + idx[jproc]] = n; + if ( jproc == myproc ) locmap_[idx[jproc]] = node_sort[n].i; -void GatherScatter::setup( const int part[], - const int remote_idx[], const int base, - const gidx_t glb_idx[], - const size_t parsize ) -{ - std::vector mask(parsize); - IsGhostPoint is_ghost(part,remote_idx,base,parsize); - for (size_t jj = 0; jj < parsize; ++jj) - { - mask[jj] = is_ghost(jj) ? 1 : 0; - } - setup( part, remote_idx, base, glb_idx, mask.data(), parsize ); + ++idx[jproc]; + } + + is_setup_ = true; +} + +void GatherScatter::setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], + const size_t parsize ) { + std::vector mask( parsize ); + IsGhostPoint is_ghost( part, remote_idx, base, parsize ); + for ( size_t jj = 0; jj < parsize; ++jj ) { + mask[jj] = is_ghost( jj ) ? 1 : 0; + } + setup( part, remote_idx, base, glb_idx, mask.data(), parsize ); } ///////////////////// -GatherScatter* atlas__GatherScatter__new () { - return new GatherScatter(); +GatherScatter* atlas__GatherScatter__new() { + return new GatherScatter(); } -void atlas__GatherScatter__delete ( GatherScatter* This) { - delete This; +void atlas__GatherScatter__delete( GatherScatter* This ) { + delete This; } -void atlas__GatherScatter__setup32 ( GatherScatter* This, int part[], - int remote_idx[], int base, - int glb_idx[], - int parsize ) -{ -#if ATLAS_BITS_GLOBAL==32 - This->setup(part,remote_idx,base,glb_idx,parsize); +void atlas__GatherScatter__setup32( GatherScatter* This, int part[], int remote_idx[], int base, int glb_idx[], + int parsize ) { +#if ATLAS_BITS_GLOBAL == 32 + This->setup( part, remote_idx, base, glb_idx, parsize ); #else - std::vector glb_idx_convert(parsize); - for(int j = 0; j < parsize; ++j) - { - glb_idx_convert[j] = glb_idx[j]; - } - This->setup(part,remote_idx,base,glb_idx_convert.data(),parsize); + std::vector glb_idx_convert( parsize ); + for ( int j = 0; j < parsize; ++j ) { + glb_idx_convert[j] = glb_idx[j]; + } + This->setup( part, remote_idx, base, glb_idx_convert.data(), parsize ); #endif } -void atlas__GatherScatter__setup64 ( GatherScatter* This, int part[], - int remote_idx[], int base, - long glb_idx[], - int parsize ) -{ -#if ATLAS_BITS_GLOBAL==64 - This->setup(part,remote_idx,base,glb_idx,parsize); +void atlas__GatherScatter__setup64( GatherScatter* This, int part[], int remote_idx[], int base, long glb_idx[], + int parsize ) { +#if ATLAS_BITS_GLOBAL == 64 + This->setup( part, remote_idx, base, glb_idx, parsize ); #else - std::vector glb_idx_convert(parsize); - for( size_t j=0; jsetup(part,remote_idx,base,glb_idx_convert.data(),parsize); + std::vector glb_idx_convert( parsize ); + for ( size_t j = 0; j < parsize; ++j ) { + glb_idx_convert[j] = glb_idx[j]; + } + This->setup( part, remote_idx, base, glb_idx_convert.data(), parsize ); #endif } -int atlas__GatherScatter__glb_dof ( GatherScatter* This ) -{ - return This->glb_dof(); +int atlas__GatherScatter__glb_dof( GatherScatter* This ) { + return This->glb_dof(); +} + +void atlas__GatherScatter__gather_int( GatherScatter* This, int lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, int gfield[], int gvar_strides[], int gvar_extents[], + int gvar_rank ) { + std::vector lvstrides( lvar_rank ); + std::vector lvextents( lvar_rank ); + std::vector gvstrides( gvar_rank ); + std::vector gvextents( gvar_rank ); + for ( int n = 0; n < lvar_rank; ++n ) { + lvstrides[n] = lvar_strides[n]; + lvextents[n] = lvar_extents[n]; + } + for ( int n = 0; n < gvar_rank; ++n ) { + gvstrides[n] = gvar_strides[n]; + gvextents[n] = gvar_extents[n]; + } + This->gather( lfield, lvstrides.data(), lvextents.data(), lvar_rank, gfield, gvstrides.data(), gvextents.data(), + gvar_rank ); +} + +void atlas__GatherScatter__gather_long( GatherScatter* This, long lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, long gfield[], int gvar_strides[], int gvar_extents[], + int gvar_rank ) { + std::vector lvstrides( lvar_rank ); + std::vector lvextents( lvar_rank ); + std::vector gvstrides( gvar_rank ); + std::vector gvextents( gvar_rank ); + for ( int n = 0; n < lvar_rank; ++n ) { + lvstrides[n] = lvar_strides[n]; + lvextents[n] = lvar_extents[n]; + } + for ( int n = 0; n < gvar_rank; ++n ) { + gvstrides[n] = gvar_strides[n]; + gvextents[n] = gvar_extents[n]; + } + This->gather( lfield, lvstrides.data(), lvextents.data(), lvar_rank, gfield, gvstrides.data(), gvextents.data(), + gvar_rank ); +} + +void atlas__GatherScatter__gather_float( GatherScatter* This, float lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, float gfield[], int gvar_strides[], int gvar_extents[], + int gvar_rank ) { + std::vector lvstrides( lvar_rank ); + std::vector lvextents( lvar_rank ); + std::vector gvstrides( gvar_rank ); + std::vector gvextents( gvar_rank ); + for ( int n = 0; n < lvar_rank; ++n ) { + lvstrides[n] = lvar_strides[n]; + lvextents[n] = lvar_extents[n]; + } + for ( int n = 0; n < gvar_rank; ++n ) { + gvstrides[n] = gvar_strides[n]; + gvextents[n] = gvar_extents[n]; + } + This->gather( lfield, lvstrides.data(), lvextents.data(), lvar_rank, gfield, gvstrides.data(), gvextents.data(), + gvar_rank ); +} + +void atlas__GatherScatter__gather_double( GatherScatter* This, double lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank, double gfield[], int gvar_strides[], int gvar_extents[], + int gvar_rank ) { + std::vector lvstrides( lvar_rank ); + std::vector lvextents( lvar_rank ); + std::vector gvstrides( gvar_rank ); + std::vector gvextents( gvar_rank ); + for ( int n = 0; n < lvar_rank; ++n ) { + lvstrides[n] = lvar_strides[n]; + lvextents[n] = lvar_extents[n]; + } + for ( int n = 0; n < gvar_rank; ++n ) { + gvstrides[n] = gvar_strides[n]; + gvextents[n] = gvar_extents[n]; + } + This->gather( lfield, lvstrides.data(), lvextents.data(), lvar_rank, gfield, gvstrides.data(), gvextents.data(), + gvar_rank ); } -void atlas__GatherScatter__gather_int ( GatherScatter* This, - int lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, - int gfield[], int gvar_strides[], int gvar_extents[], int gvar_rank) -{ - std::vector lvstrides(lvar_rank); - std::vector lvextents(lvar_rank); - std::vector gvstrides(gvar_rank); - std::vector gvextents(gvar_rank); - for(int n = 0; n < lvar_rank; ++n) { - lvstrides[n] = lvar_strides[n]; - lvextents[n] = lvar_extents[n]; - } - for(int n = 0; n < gvar_rank; ++n) { - gvstrides[n] = gvar_strides[n]; - gvextents[n] = gvar_extents[n]; - } - This->gather(lfield,lvstrides.data(),lvextents.data(),lvar_rank, - gfield,gvstrides.data(),gvextents.data(),gvar_rank); +void atlas__GatherScatter__scatter_int( GatherScatter* This, int gfield[], int gvar_strides[], int gvar_extents[], + int gvar_rank, int lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank ) { + std::vector lvstrides( lvar_rank ); + std::vector lvextents( lvar_rank ); + std::vector gvstrides( gvar_rank ); + std::vector gvextents( gvar_rank ); + for ( int n = 0; n < lvar_rank; ++n ) { + lvstrides[n] = lvar_strides[n]; + lvextents[n] = lvar_extents[n]; + } + for ( int n = 0; n < gvar_rank; ++n ) { + gvstrides[n] = gvar_strides[n]; + gvextents[n] = gvar_extents[n]; + } + This->scatter( gfield, gvstrides.data(), gvextents.data(), gvar_rank, lfield, lvstrides.data(), lvextents.data(), + lvar_rank ); } -void atlas__GatherScatter__gather_long ( GatherScatter* This, - long lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, - long gfield[], int gvar_strides[], int gvar_extents[], int gvar_rank) -{ - std::vector lvstrides(lvar_rank); - std::vector lvextents(lvar_rank); - std::vector gvstrides(gvar_rank); - std::vector gvextents(gvar_rank); - for(int n = 0; n < lvar_rank; ++n) { - lvstrides[n] = lvar_strides[n]; - lvextents[n] = lvar_extents[n]; - } - for(int n = 0; n < gvar_rank; ++n) { - gvstrides[n] = gvar_strides[n]; - gvextents[n] = gvar_extents[n]; - } - This->gather(lfield,lvstrides.data(),lvextents.data(),lvar_rank, - gfield,gvstrides.data(),gvextents.data(),gvar_rank);} - -void atlas__GatherScatter__gather_float ( GatherScatter* This, - float lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, - float gfield[], int gvar_strides[], int gvar_extents[], int gvar_rank) -{ - std::vector lvstrides(lvar_rank); - std::vector lvextents(lvar_rank); - std::vector gvstrides(gvar_rank); - std::vector gvextents(gvar_rank); - for(int n = 0; n < lvar_rank; ++n) { - lvstrides[n] = lvar_strides[n]; - lvextents[n] = lvar_extents[n]; - } - for(int n = 0; n < gvar_rank; ++n) { - gvstrides[n] = gvar_strides[n]; - gvextents[n] = gvar_extents[n]; - } - This->gather(lfield,lvstrides.data(),lvextents.data(),lvar_rank, - gfield,gvstrides.data(),gvextents.data(),gvar_rank);} - -void atlas__GatherScatter__gather_double ( GatherScatter* This, - double lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank, - double gfield[], int gvar_strides[], int gvar_extents[], int gvar_rank) -{ - std::vector lvstrides(lvar_rank); - std::vector lvextents(lvar_rank); - std::vector gvstrides(gvar_rank); - std::vector gvextents(gvar_rank); - for(int n = 0; n < lvar_rank; ++n) { - lvstrides[n] = lvar_strides[n]; - lvextents[n] = lvar_extents[n]; - } - for(int n = 0; n < gvar_rank; ++n) { - gvstrides[n] = gvar_strides[n]; - gvextents[n] = gvar_extents[n]; - } - This->gather(lfield,lvstrides.data(),lvextents.data(),lvar_rank, - gfield,gvstrides.data(),gvextents.data(),gvar_rank);} - -void atlas__GatherScatter__scatter_int ( GatherScatter* This, - int gfield[], int gvar_strides[], int gvar_extents[], int gvar_rank, - int lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank ) -{ - std::vector lvstrides(lvar_rank); - std::vector lvextents(lvar_rank); - std::vector gvstrides(gvar_rank); - std::vector gvextents(gvar_rank); - for(int n = 0; n < lvar_rank; ++n) { - lvstrides[n] = lvar_strides[n]; - lvextents[n] = lvar_extents[n]; - } - for(int n = 0; n < gvar_rank; ++n) { - gvstrides[n] = gvar_strides[n]; - gvextents[n] = gvar_extents[n]; - } - This->scatter( gfield, gvstrides.data(), gvextents.data(), gvar_rank, - lfield, lvstrides.data(), lvextents.data(), lvar_rank ); +void atlas__GatherScatter__scatter_long( GatherScatter* This, long gfield[], int gvar_strides[], int gvar_extents[], + int gvar_rank, long lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank ) { + std::vector lvstrides( lvar_rank ); + std::vector lvextents( lvar_rank ); + std::vector gvstrides( gvar_rank ); + std::vector gvextents( gvar_rank ); + for ( int n = 0; n < lvar_rank; ++n ) { + lvstrides[n] = lvar_strides[n]; + lvextents[n] = lvar_extents[n]; + } + for ( int n = 0; n < gvar_rank; ++n ) { + gvstrides[n] = gvar_strides[n]; + gvextents[n] = gvar_extents[n]; + } + This->scatter( gfield, gvstrides.data(), gvextents.data(), gvar_rank, lfield, lvstrides.data(), lvextents.data(), + lvar_rank ); } -void atlas__GatherScatter__scatter_long ( GatherScatter* This, - long gfield[], int gvar_strides[], int gvar_extents[], int gvar_rank, - long lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank ) -{ - std::vector lvstrides(lvar_rank); - std::vector lvextents(lvar_rank); - std::vector gvstrides(gvar_rank); - std::vector gvextents(gvar_rank); - for(int n = 0; n < lvar_rank; ++n) { - lvstrides[n] = lvar_strides[n]; - lvextents[n] = lvar_extents[n]; - } - for(int n = 0; n < gvar_rank; ++n) { - gvstrides[n] = gvar_strides[n]; - gvextents[n] = gvar_extents[n]; - } - This->scatter( gfield, gvstrides.data(), gvextents.data(), gvar_rank, - lfield, lvstrides.data(), lvextents.data(), lvar_rank );} - -void atlas__GatherScatter__scatter_float ( GatherScatter* This, - float gfield[], int gvar_strides[], int gvar_extents[], int gvar_rank, - float lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank ) -{ - std::vector lvstrides(lvar_rank); - std::vector lvextents(lvar_rank); - std::vector gvstrides(gvar_rank); - std::vector gvextents(gvar_rank); - for(int n = 0; n < lvar_rank; ++n) { - lvstrides[n] = lvar_strides[n]; - lvextents[n] = lvar_extents[n]; - } - for(int n = 0; n < gvar_rank; ++n) { - gvstrides[n] = gvar_strides[n]; - gvextents[n] = gvar_extents[n]; - } - This->scatter( gfield, gvstrides.data(), gvextents.data(), gvar_rank, - lfield, lvstrides.data(), lvextents.data(), lvar_rank );} - -void atlas__GatherScatter__scatter_double ( GatherScatter* This, - double gfield[], int gvar_strides[], int gvar_extents[], int gvar_rank, - double lfield[], int lvar_strides[], int lvar_extents[], int lvar_rank ) -{ - std::vector lvstrides(lvar_rank); - std::vector lvextents(lvar_rank); - std::vector gvstrides(gvar_rank); - std::vector gvextents(gvar_rank); - for(int n = 0; n < lvar_rank; ++n) { - lvstrides[n] = lvar_strides[n]; - lvextents[n] = lvar_extents[n]; - } - for(int n = 0; n < gvar_rank; ++n) { - gvstrides[n] = gvar_strides[n]; - gvextents[n] = gvar_extents[n]; - } - This->scatter( gfield, gvstrides.data(), gvextents.data(), gvar_rank, - lfield, lvstrides.data(), lvextents.data(), lvar_rank ); +void atlas__GatherScatter__scatter_float( GatherScatter* This, float gfield[], int gvar_strides[], int gvar_extents[], + int gvar_rank, float lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank ) { + std::vector lvstrides( lvar_rank ); + std::vector lvextents( lvar_rank ); + std::vector gvstrides( gvar_rank ); + std::vector gvextents( gvar_rank ); + for ( int n = 0; n < lvar_rank; ++n ) { + lvstrides[n] = lvar_strides[n]; + lvextents[n] = lvar_extents[n]; + } + for ( int n = 0; n < gvar_rank; ++n ) { + gvstrides[n] = gvar_strides[n]; + gvextents[n] = gvar_extents[n]; + } + This->scatter( gfield, gvstrides.data(), gvextents.data(), gvar_rank, lfield, lvstrides.data(), lvextents.data(), + lvar_rank ); } +void atlas__GatherScatter__scatter_double( GatherScatter* This, double gfield[], int gvar_strides[], int gvar_extents[], + int gvar_rank, double lfield[], int lvar_strides[], int lvar_extents[], + int lvar_rank ) { + std::vector lvstrides( lvar_rank ); + std::vector lvextents( lvar_rank ); + std::vector gvstrides( gvar_rank ); + std::vector gvextents( gvar_rank ); + for ( int n = 0; n < lvar_rank; ++n ) { + lvstrides[n] = lvar_strides[n]; + lvextents[n] = lvar_extents[n]; + } + for ( int n = 0; n < gvar_rank; ++n ) { + gvstrides[n] = gvar_strides[n]; + gvextents[n] = gvar_extents[n]; + } + This->scatter( gfield, gvstrides.data(), gvextents.data(), gvar_rank, lfield, lvstrides.data(), lvextents.data(), + lvar_rank ); +} ///////////////////// -} // namespace parallel -} // namespace atlas +} // namespace parallel +} // namespace atlas diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index 808fa1aad..b9528a2e6 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -4,606 +4,513 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #ifndef Gather_h #define Gather_h -#include #include +#include -#include "eckit/memory/SharedPtr.h" -#include "eckit/memory/Owned.h" #include "atlas/parallel/mpi/mpi.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" +#include "atlas/array/ArrayView.h" #include "atlas/library/config.h" #include "atlas/runtime/Log.h" -#include "atlas/array/ArrayView.h" namespace atlas { namespace parallel { //---------------------------------------------------------------------------------------------------------------------- -template struct remove_const { typedef T type; }; -template struct remove_const { typedef T type; }; +template +struct remove_const { + typedef T type; +}; +template +struct remove_const { + typedef T type; +}; -template struct add_const { typedef const typename remove_const::type type; }; -template struct add_const { typedef const T type; }; +template +struct add_const { + typedef const typename remove_const::type type; +}; +template +struct add_const { + typedef const T type; +}; template -class Field -{ +class Field { private: - typedef typename remove_const::type NON_CONST_DATA_TYPE; - typedef typename add_const::type CONST_DATA_TYPE; + typedef typename remove_const::type NON_CONST_DATA_TYPE; + typedef typename add_const::type CONST_DATA_TYPE; public: - Field() {} - - Field( DATA_TYPE data_[], const size_t var_strides_[], const size_t var_shape_[], const size_t var_rank_ ) : - data(const_cast(data_)), var_rank(var_rank_) - { - var_strides.assign(var_strides_,var_strides_+var_rank_); - var_shape.assign(var_shape_,var_shape_+var_rank_); - } - - Field( DATA_TYPE data_[], const size_t nb_vars ) : - data(const_cast(data_)), var_rank(1) - { - var_strides.assign(1,1); - var_shape.assign(1,nb_vars); - } - - template - Field( const array::ArrayView& arr ) - { - data = const_cast(arr.data()); - - var_rank = RANK; - var_strides.resize(var_rank); - var_shape.resize(var_rank); - - if( arr.rank()>1 ) - { - var_strides[0] = arr.stride(0); - var_shape[0] = 1; - for( int j=1; j( data_ ) ), + var_rank( var_rank_ ) { + var_strides.assign( var_strides_, var_strides_ + var_rank_ ); + var_shape.assign( var_shape_, var_shape_ + var_rank_ ); } - else - { - var_strides[0] = arr.stride(0); - var_shape[0] = 1; + + Field( DATA_TYPE data_[], const size_t nb_vars ) : data( const_cast( data_ ) ), var_rank( 1 ) { + var_strides.assign( 1, 1 ); + var_shape.assign( 1, nb_vars ); } - } - - template - Field( const array::LocalView& arr ) - { - data = const_cast(arr.data()); - - var_rank = RANK; - var_strides.resize(var_rank); - var_shape.resize(var_rank); - - if( arr.rank()>1 ) - { - var_strides[0] = arr.stride(0); - var_shape[0] = 1; - for( int j=1; j + Field( const array::ArrayView& arr ) { + data = const_cast( arr.data() ); + + var_rank = RANK; + var_strides.resize( var_rank ); + var_shape.resize( var_rank ); + + if ( arr.rank() > 1 ) { + var_strides[0] = arr.stride( 0 ); + var_shape[0] = 1; + for ( int j = 1; j < RANK; ++j ) { + var_strides[j] = arr.stride( j ); + var_shape[j] = arr.shape( j ); + } + } + else { + var_strides[0] = arr.stride( 0 ); + var_shape[0] = 1; + } } - else - { - var_strides[0] = arr.stride(0); - var_shape[0] = 1; + + template + Field( const array::LocalView& arr ) { + data = const_cast( arr.data() ); + + var_rank = RANK; + var_strides.resize( var_rank ); + var_shape.resize( var_rank ); + + if ( arr.rank() > 1 ) { + var_strides[0] = arr.stride( 0 ); + var_shape[0] = 1; + for ( int j = 1; j < RANK; ++j ) { + var_strides[j] = arr.stride( j ); + var_shape[j] = arr.shape( j ); + } + } + else { + var_strides[0] = arr.stride( 0 ); + var_shape[0] = 1; + } } - } public: - DATA_TYPE* data; - std::vector var_strides; - std::vector var_shape; - size_t var_rank; + DATA_TYPE* data; + std::vector var_strides; + std::vector var_shape; + size_t var_rank; }; -class GatherScatter: public eckit::Owned { - +class GatherScatter : public eckit::Owned { public: - GatherScatter(); - GatherScatter(const std::string& name); - virtual ~GatherScatter() {} - -public: // methods - - std::string name() const { return name_; } - - /// @brief Setup - /// @param [in] part List of partitions - /// @param [in] remote_idx List of local indices on remote partitions - /// @param [in] base values of remote_idx start at "base" - /// @param [in] glb_idx List of global indices - /// @param [in] parsize size of given lists - void setup( const int part[], - const int remote_idx[], const int base, - const gidx_t glb_idx[], - const size_t parsize ); - - - /// @brief Setup - /// @param [in] part List of partitions - /// @param [in] remote_idx List of local indices on remote partitions - /// @param [in] base values of remote_idx start at "base" - /// @param [in] glb_idx List of global indices - /// @param [in] parsize size of given lists - /// @param [in] mask Mask indices not to include in the communication - /// pattern (0=include,1=exclude) - void setup( const int part[], - const int remote_idx[], const int base, - const gidx_t glb_idx[], const int mask[], const size_t parsize ); - - template - void gather( const DATA_TYPE ldata[], - const size_t lstrides[], - const size_t lshape[], - const size_t lrank, - const size_t lmpl_idxpos[], - const size_t lmpl_rank, - DATA_TYPE gdata[], - const size_t gstrides[], - const size_t gshape[], - const size_t grank, - const size_t gmpl_idxpos[], - const size_t gmpl_rank, - const size_t root ) const; - - template - void gather( const DATA_TYPE ldata[], - const size_t lvar_strides[], - const size_t lvar_shape[], - const size_t lvar_rank, - DATA_TYPE gdata[], - const size_t gvar_strides[], - const size_t gvar_shape[], - const size_t gvar_rank, - const size_t root = 0 ) const; - - template - void gather( parallel::Field lfields[], - parallel::Field gfields[], - const size_t nb_fields, - const size_t root = 0 ) const; - - template - void gather( const array::ArrayView& ldata, - array::ArrayView& gdata, - const size_t root = 0 ) const; - - template - void scatter( parallel::Field gfields[], - parallel::Field lfields[], - const size_t nb_fields, - const size_t root = 0 ) const; - - template - void scatter( const DATA_TYPE gdata[], - const size_t gstrides[], - const size_t gshape[], - const size_t grank, - const size_t gmpl_idxpos[], - const size_t gmpl_rank, - DATA_TYPE ldata[], - const size_t lstrides[], - const size_t lshape[], - const size_t lrank, - const size_t lmpl_idxpos[], - const size_t lmpl_rank, - const size_t root ) const; - - template - void scatter( const DATA_TYPE gdata[], - const size_t gvar_strides[], - const size_t gvar_shape[], - const size_t gvar_rank, - DATA_TYPE ldata[], - const size_t lvar_strides[], - const size_t lvar_shape[], - const size_t lvar_rank, - const size_t root = 0 ) const; - - template - void scatter( const array::ArrayView& gdata, - array::ArrayView& ldata, - const size_t root = 0 ) const; - - int glb_dof() const { return glbcnt_; } - - int loc_dof() const { return loccnt_; } - -private: // methods - template< typename DATA_TYPE> - void pack_send_buffer( const parallel::Field& field, - const std::vector& sendmap, - DATA_TYPE send_buffer[] ) const; - - template< typename DATA_TYPE> - void unpack_recv_buffer( const std::vector& recvmap, - const DATA_TYPE recv_buffer[], - const parallel::Field& field ) const; - - template - void var_info( const array::ArrayView& arr, - std::vector& varstrides, - std::vector& varshape ) const; - -private: // data - - std::string name_; - int loccnt_; - int glbcnt_; - std::vector glbcounts_; - std::vector glbdispls_; - std::vector locmap_; - std::vector glbmap_; - - size_t nproc; - size_t myproc; - - bool is_setup_; - - size_t parsize_; friend class Checksum; - - - int glb_cnt(size_t root) const { return myproc==root ? glbcnt_ : 0 ; } + GatherScatter(); + GatherScatter( const std::string& name ); + virtual ~GatherScatter() {} + +public: // methods + std::string name() const { return name_; } + + /// @brief Setup + /// @param [in] part List of partitions + /// @param [in] remote_idx List of local indices on remote partitions + /// @param [in] base values of remote_idx start at "base" + /// @param [in] glb_idx List of global indices + /// @param [in] parsize size of given lists + void setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], + const size_t parsize ); + + /// @brief Setup + /// @param [in] part List of partitions + /// @param [in] remote_idx List of local indices on remote partitions + /// @param [in] base values of remote_idx start at "base" + /// @param [in] glb_idx List of global indices + /// @param [in] parsize size of given lists + /// @param [in] mask Mask indices not to include in the communication + /// pattern (0=include,1=exclude) + void setup( const int part[], const int remote_idx[], const int base, const gidx_t glb_idx[], const int mask[], + const size_t parsize ); + + template + void gather( const DATA_TYPE ldata[], const size_t lstrides[], const size_t lshape[], const size_t lrank, + const size_t lmpl_idxpos[], const size_t lmpl_rank, DATA_TYPE gdata[], const size_t gstrides[], + const size_t gshape[], const size_t grank, const size_t gmpl_idxpos[], const size_t gmpl_rank, + const size_t root ) const; + + template + void gather( const DATA_TYPE ldata[], const size_t lvar_strides[], const size_t lvar_shape[], + const size_t lvar_rank, DATA_TYPE gdata[], const size_t gvar_strides[], const size_t gvar_shape[], + const size_t gvar_rank, const size_t root = 0 ) const; + + template + void gather( parallel::Field lfields[], parallel::Field gfields[], + const size_t nb_fields, const size_t root = 0 ) const; + + template + void gather( const array::ArrayView& ldata, array::ArrayView& gdata, + const size_t root = 0 ) const; + + template + void scatter( parallel::Field gfields[], parallel::Field lfields[], + const size_t nb_fields, const size_t root = 0 ) const; + + template + void scatter( const DATA_TYPE gdata[], const size_t gstrides[], const size_t gshape[], const size_t grank, + const size_t gmpl_idxpos[], const size_t gmpl_rank, DATA_TYPE ldata[], const size_t lstrides[], + const size_t lshape[], const size_t lrank, const size_t lmpl_idxpos[], const size_t lmpl_rank, + const size_t root ) const; + + template + void scatter( const DATA_TYPE gdata[], const size_t gvar_strides[], const size_t gvar_shape[], + const size_t gvar_rank, DATA_TYPE ldata[], const size_t lvar_strides[], const size_t lvar_shape[], + const size_t lvar_rank, const size_t root = 0 ) const; + + template + void scatter( const array::ArrayView& gdata, array::ArrayView& ldata, + const size_t root = 0 ) const; + + int glb_dof() const { return glbcnt_; } + + int loc_dof() const { return loccnt_; } + +private: // methods + template + void pack_send_buffer( const parallel::Field& field, const std::vector& sendmap, + DATA_TYPE send_buffer[] ) const; + + template + void unpack_recv_buffer( const std::vector& recvmap, const DATA_TYPE recv_buffer[], + const parallel::Field& field ) const; + + template + void var_info( const array::ArrayView& arr, std::vector& varstrides, + std::vector& varshape ) const; + +private: // data + std::string name_; + int loccnt_; + int glbcnt_; + std::vector glbcounts_; + std::vector glbdispls_; + std::vector locmap_; + std::vector glbmap_; + + size_t nproc; + size_t myproc; + + bool is_setup_; + + size_t parsize_; + friend class Checksum; + + int glb_cnt( size_t root ) const { return myproc == root ? glbcnt_ : 0; } }; - //////////////////////////////////////////////////////////////////////////////// template -void GatherScatter::gather( parallel::Field lfields[], - parallel::Field gfields[], - size_t nb_fields, - const size_t root ) const -{ - if( ! is_setup_ ) - { - throw eckit::SeriousBug("GatherScatter was not setup",Here()); - } - - for( size_t jfield=0; jfield()); - const size_t gvar_size = std::accumulate(gfields[jfield].var_shape.data(),gfields[jfield].var_shape.data()+gfields[jfield].var_rank,1,std::multiplies()); - const int loc_size = loccnt_ * lvar_size; - const int glb_size = glb_cnt(root) * gvar_size; - std::vector loc_buffer(loc_size); - std::vector glb_buffer(glb_size); - std::vector glb_displs(nproc); - std::vector glb_counts(nproc); - - for (size_t jproc=0; jproc lfields[], parallel::Field gfields[], + size_t nb_fields, const size_t root ) const { + if ( !is_setup_ ) { throw eckit::SeriousBug( "GatherScatter was not setup", Here() ); } + + for ( size_t jfield = 0; jfield < nb_fields; ++jfield ) { + const size_t lvar_size = std::accumulate( lfields[jfield].var_shape.data(), + lfields[jfield].var_shape.data() + lfields[jfield].var_rank, 1, + std::multiplies() ); + const size_t gvar_size = std::accumulate( gfields[jfield].var_shape.data(), + gfields[jfield].var_shape.data() + gfields[jfield].var_rank, 1, + std::multiplies() ); + const int loc_size = loccnt_ * lvar_size; + const int glb_size = glb_cnt( root ) * gvar_size; + std::vector loc_buffer( loc_size ); + std::vector glb_buffer( glb_size ); + std::vector glb_displs( nproc ); + std::vector glb_counts( nproc ); + + for ( size_t jproc = 0; jproc < nproc; ++jproc ) { + glb_counts[jproc] = glbcounts_[jproc] * gvar_size; + glb_displs[jproc] = glbdispls_[jproc] * gvar_size; + } - /// Pack + /// Pack - pack_send_buffer(lfields[jfield],locmap_,loc_buffer.data()); + pack_send_buffer( lfields[jfield], locmap_, loc_buffer.data() ); - /// Gather + /// Gather - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gatherv(loc_buffer, glb_buffer, glb_counts, glb_displs, root); - } + 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]); - } + /// Unpack + if ( myproc == root ) unpack_recv_buffer( glbmap_, glb_buffer.data(), gfields[jfield] ); + } } -template -void GatherScatter::gather( const DATA_TYPE ldata[], - const size_t lvar_strides[], - const size_t lvar_shape[], - const size_t lvar_rank, - DATA_TYPE gdata[], - const size_t gvar_strides[], - const size_t gvar_shape[], - const size_t gvar_rank, - const size_t root ) const -{ - parallel::Field lfield(ldata,lvar_strides,lvar_shape,lvar_rank); - parallel::Field gfield(gdata,gvar_strides,gvar_shape,gvar_rank); - gather( &lfield, &gfield, 1, root ); +template +void GatherScatter::gather( const DATA_TYPE ldata[], const size_t lvar_strides[], const size_t lvar_shape[], + const size_t lvar_rank, DATA_TYPE gdata[], const size_t gvar_strides[], + const size_t gvar_shape[], const size_t gvar_rank, const size_t root ) const { + parallel::Field lfield( ldata, lvar_strides, lvar_shape, lvar_rank ); + parallel::Field gfield( gdata, gvar_strides, gvar_shape, gvar_rank ); + gather( &lfield, &gfield, 1, root ); } - template -void GatherScatter::scatter( parallel::Field gfields[], - parallel::Field lfields[], - const size_t nb_fields, - const size_t root ) const -{ - if( ! is_setup_ ) - { - throw eckit::SeriousBug("GatherScatter was not setup",Here()); - } - - for(size_t jfield=0; jfield < nb_fields; ++jfield) - { - const int lvar_size = std::accumulate(lfields[jfield].var_shape.data(),lfields[jfield].var_shape.data()+lfields[jfield].var_rank,1,std::multiplies()); - const int gvar_size = std::accumulate(gfields[jfield].var_shape.data(),gfields[jfield].var_shape.data()+gfields[jfield].var_rank,1,std::multiplies()); - const int loc_size = loccnt_ * lvar_size; - const int glb_size = glb_cnt(root) * gvar_size; - std::vector loc_buffer(loc_size); - std::vector glb_buffer(glb_size); - std::vector glb_displs(nproc); - std::vector glb_counts(nproc); - - for (size_t jproc=0; jproc < nproc; ++jproc) - { - glb_counts[jproc] = glbcounts_[jproc]*gvar_size; - glb_displs[jproc] = glbdispls_[jproc]*gvar_size; - } +void GatherScatter::scatter( parallel::Field gfields[], parallel::Field lfields[], + const size_t nb_fields, const size_t root ) const { + if ( !is_setup_ ) { throw eckit::SeriousBug( "GatherScatter was not setup", Here() ); } + + for ( size_t jfield = 0; jfield < nb_fields; ++jfield ) { + const int lvar_size = + std::accumulate( lfields[jfield].var_shape.data(), + lfields[jfield].var_shape.data() + lfields[jfield].var_rank, 1, std::multiplies() ); + const int gvar_size = + std::accumulate( gfields[jfield].var_shape.data(), + gfields[jfield].var_shape.data() + gfields[jfield].var_rank, 1, std::multiplies() ); + const int loc_size = loccnt_ * lvar_size; + const int glb_size = glb_cnt( root ) * gvar_size; + std::vector loc_buffer( loc_size ); + std::vector glb_buffer( glb_size ); + std::vector glb_displs( nproc ); + std::vector glb_counts( nproc ); + + for ( size_t jproc = 0; jproc < nproc; ++jproc ) { + glb_counts[jproc] = glbcounts_[jproc] * gvar_size; + glb_displs[jproc] = glbdispls_[jproc] * gvar_size; + } - /// Pack - if( myproc == root ) - pack_send_buffer(gfields[jfield],glbmap_,glb_buffer.data()); + /// Pack + if ( myproc == root ) pack_send_buffer( gfields[jfield], glbmap_, glb_buffer.data() ); - /// Scatter + /// Scatter - ATLAS_TRACE_MPI( SCATTER ) { - mpi::comm().scatterv(glb_buffer.begin(), glb_buffer.end(), glb_counts, glb_displs, loc_buffer.begin(), loc_buffer.end(), root); - } + ATLAS_TRACE_MPI( SCATTER ) { + mpi::comm().scatterv( glb_buffer.begin(), glb_buffer.end(), glb_counts, glb_displs, loc_buffer.begin(), + loc_buffer.end(), root ); + } - /// Unpack - unpack_recv_buffer(locmap_,loc_buffer.data(),lfields[jfield]); - } + /// Unpack + unpack_recv_buffer( locmap_, loc_buffer.data(), lfields[jfield] ); + } } -template -void GatherScatter::scatter( const DATA_TYPE gdata[], - const size_t gvar_strides[], - const size_t gvar_shape[], - const size_t gvar_rank, - DATA_TYPE ldata[], - const size_t lvar_strides[], - const size_t lvar_shape[], - const size_t lvar_rank, - const size_t root ) const -{ - parallel::Field gfield(gdata,gvar_strides,gvar_shape,gvar_rank); - parallel::Field lfield(ldata,lvar_strides,lvar_shape,lvar_rank); - scatter( &gfield, &lfield, 1, root ); +template +void GatherScatter::scatter( const DATA_TYPE gdata[], const size_t gvar_strides[], const size_t gvar_shape[], + const size_t gvar_rank, DATA_TYPE ldata[], const size_t lvar_strides[], + const size_t lvar_shape[], const size_t lvar_rank, const size_t root ) const { + parallel::Field gfield( gdata, gvar_strides, gvar_shape, gvar_rank ); + parallel::Field lfield( ldata, lvar_strides, lvar_shape, lvar_rank ); + scatter( &gfield, &lfield, 1, root ); } -template -void GatherScatter::pack_send_buffer( const parallel::Field& field, - const std::vector& sendmap, - DATA_TYPE send_buffer[] ) const -{ - const size_t sendcnt = sendmap.size(); - - size_t ibuf = 0; - const size_t send_stride = field.var_strides[0]*field.var_shape[0]; - - switch( field.var_rank ) - { - case 1: - for(size_t p=0; p < sendcnt; ++p) - { - const size_t pp = send_stride*sendmap[p]; - for( size_t i=0; i +void GatherScatter::pack_send_buffer( const parallel::Field& field, const std::vector& sendmap, + DATA_TYPE send_buffer[] ) const { + const size_t sendcnt = sendmap.size(); + + size_t ibuf = 0; + const size_t send_stride = field.var_strides[0] * field.var_shape[0]; + + switch ( field.var_rank ) { + case 1: + for ( size_t p = 0; p < sendcnt; ++p ) { + const size_t pp = send_stride * sendmap[p]; + for ( size_t i = 0; i < field.var_shape[0]; ++i ) { + DATA_TYPE tmp = field.data[pp + i * field.var_strides[0]]; + send_buffer[ibuf++] = tmp; + } + } + break; + case 2: + for ( size_t p = 0; p < sendcnt; ++p ) { + const size_t pp = send_stride * sendmap[p]; + for ( size_t i = 0; i < field.var_shape[0]; ++i ) { + const size_t ii = pp + i * field.var_strides[0]; + for ( size_t j = 0; j < field.var_shape[1]; ++j ) { + send_buffer[ibuf++] = field.data[ii + j * field.var_strides[1]]; + } + } + } + break; + case 3: + for ( size_t p = 0; p < sendcnt; ++p ) { + const size_t pp = send_stride * sendmap[p]; + for ( size_t i = 0; i < field.var_shape[0]; ++i ) { + const size_t ii = pp + i * field.var_strides[0]; + for ( size_t j = 0; j < field.var_shape[1]; ++j ) { + const size_t jj = ii + j * field.var_strides[1]; + for ( size_t k = 0; k < field.var_shape[2]; ++k ) { + send_buffer[ibuf++] = field.data[jj + k * field.var_strides[2]]; + } + } + } + } + break; + default: + NOTIMP; } - break; - default: - NOTIMP; - } } - - -template -void GatherScatter::unpack_recv_buffer( const std::vector& recvmap, - const DATA_TYPE recv_buffer[], - const parallel::Field& field ) const -{ - const size_t recvcnt = recvmap.size(); - - int ibuf = 0; - const size_t recv_stride = field.var_strides[0]*field.var_shape[0]; - - switch( field.var_rank ) - { - case 1: - for( size_t p=0; p +void GatherScatter::unpack_recv_buffer( const std::vector& recvmap, const DATA_TYPE recv_buffer[], + const parallel::Field& field ) const { + const size_t recvcnt = recvmap.size(); + + int ibuf = 0; + const size_t recv_stride = field.var_strides[0] * field.var_shape[0]; + + switch ( field.var_rank ) { + case 1: + for ( size_t p = 0; p < recvcnt; ++p ) { + const size_t pp = recv_stride * recvmap[p]; + for ( size_t i = 0; i < field.var_shape[0]; ++i ) { + field.data[pp + i * field.var_strides[0]] = recv_buffer[ibuf++]; + } + } + break; + case 2: + for ( size_t p = 0; p < recvcnt; ++p ) { + const size_t pp = recv_stride * recvmap[p]; + for ( size_t i = 0; i < field.var_shape[0]; ++i ) { + const size_t ii = pp + i * field.var_strides[0]; + for ( size_t j = 0; j < field.var_shape[1]; ++j ) { + field.data[ii + j * field.var_strides[1]] = recv_buffer[ibuf++]; + } + } + } + break; + case 3: + for ( size_t p = 0; p < recvcnt; ++p ) { + const size_t pp = recv_stride * recvmap[p]; + for ( size_t i = 0; i < field.var_shape[0]; ++i ) { + const size_t ii = pp + i * field.var_strides[0]; + for ( size_t j = 0; j < field.var_shape[1]; ++j ) { + const size_t jj = ii + j * field.var_strides[1]; + for ( size_t k = 0; k < field.var_shape[2]; ++k ) { + field.data[jj + k * field.var_strides[2]] = recv_buffer[ibuf++]; + } + } + } + } + break; + default: + NOTIMP; } - break; - default: - NOTIMP; - } } - - -template -void GatherScatter::var_info( const array::ArrayView& arr, - std::vector& varstrides, - std::vector& varshape ) const -{ - int rank = std::max(1,RANK-1) ; - varstrides.resize(rank); - varshape.resize(rank); - - if( RANK>1 ) - { - size_t stride=1; - for( int j=RANK-1; j>0; --j ) { - varstrides[j-1] = stride; - varshape[j-1] = arr.shape(j); - stride *= varshape[j-1]; +template +void GatherScatter::var_info( const array::ArrayView& arr, std::vector& varstrides, + std::vector& varshape ) const { + int rank = std::max( 1, RANK - 1 ); + varstrides.resize( rank ); + varshape.resize( rank ); + + if ( RANK > 1 ) { + size_t stride = 1; + for ( int j = RANK - 1; j > 0; --j ) { + varstrides[j - 1] = stride; + varshape[j - 1] = arr.shape( j ); + stride *= varshape[j - 1]; + } + // varstrides.assign(arr.strides()+1,arr.strides()+RANK); + // varshape.assign(arr.shape()+1,arr.shape()+RANK); + } + else { + varstrides[0] = 1; + varshape[0] = 1; } -// varstrides.assign(arr.strides()+1,arr.strides()+RANK); -// varshape.assign(arr.shape()+1,arr.shape()+RANK); - } - else - { - varstrides[0] = 1; - varshape[0] = 1; - } } template -void GatherScatter::gather( const array::ArrayView& ldata, - array::ArrayView& gdata, - const size_t root ) const -{ - if( ldata.shape(0) == parsize_ && gdata.shape(0) == size_t(glb_cnt(root)) ) - { - std::vector< parallel::Field > lfields(1, parallel::Field(ldata) ); - std::vector< parallel::Field > gfields(1, parallel::Field(gdata) ); - gather( lfields.data(), gfields.data(), 1, root ); - } - else - { - ATLAS_DEBUG_VAR(parsize_); - ATLAS_DEBUG_VAR(ldata.shape(0)); - ATLAS_DEBUG_VAR(glb_cnt(root)); - ATLAS_DEBUG_VAR(gdata.shape(0)); - NOTIMP; // Need to implement with parallel ranks > 1 - } +void GatherScatter::gather( const array::ArrayView& ldata, array::ArrayView& gdata, + const size_t root ) const { + if ( ldata.shape( 0 ) == parsize_ && gdata.shape( 0 ) == size_t( glb_cnt( root ) ) ) { + std::vector> lfields( 1, parallel::Field( ldata ) ); + std::vector> gfields( 1, parallel::Field( gdata ) ); + gather( lfields.data(), gfields.data(), 1, root ); + } + else { + ATLAS_DEBUG_VAR( parsize_ ); + ATLAS_DEBUG_VAR( ldata.shape( 0 ) ); + ATLAS_DEBUG_VAR( glb_cnt( root ) ); + ATLAS_DEBUG_VAR( gdata.shape( 0 ) ); + NOTIMP; // Need to implement with parallel ranks > 1 + } } template -void GatherScatter::scatter( const array::ArrayView& gdata, - array::ArrayView& ldata, - const size_t root ) const -{ - if( ldata.shape(0) == parsize_ && gdata.shape(0) == size_t(glb_cnt(root)) ) - { - std::vector< parallel::Field > gfields(1, parallel::Field(gdata) ); - std::vector< parallel::Field > lfields(1, parallel::Field(ldata) ); - scatter( gfields.data(), lfields.data(), 1, root ); - } - else - { - ATLAS_DEBUG_VAR(parsize_); - ATLAS_DEBUG_VAR(ldata.shape(0)); - ATLAS_DEBUG_VAR(glb_cnt(root)); - ATLAS_DEBUG_VAR(gdata.shape(0)); - NOTIMP; // Need to implement with parallel ranks > 1 - } +void GatherScatter::scatter( const array::ArrayView& gdata, array::ArrayView& ldata, + const size_t root ) const { + if ( ldata.shape( 0 ) == parsize_ && gdata.shape( 0 ) == size_t( glb_cnt( root ) ) ) { + std::vector> gfields( 1, parallel::Field( gdata ) ); + std::vector> lfields( 1, parallel::Field( ldata ) ); + scatter( gfields.data(), lfields.data(), 1, root ); + } + else { + ATLAS_DEBUG_VAR( parsize_ ); + ATLAS_DEBUG_VAR( ldata.shape( 0 ) ); + ATLAS_DEBUG_VAR( glb_cnt( root ) ); + ATLAS_DEBUG_VAR( gdata.shape( 0 ) ); + NOTIMP; // Need to implement with parallel ranks > 1 + } } - // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -extern "C" -{ - GatherScatter* atlas__GatherScatter__new (); - void atlas__GatherScatter__delete (GatherScatter* This); - void atlas__GatherScatter__setup32 (GatherScatter* This, int part[], int remote_idx[], int base, int glb_idx[], int parsize); - void atlas__GatherScatter__setup64 (GatherScatter* This, int part[], int remote_idx[], int base, long glb_idx[], int parsize); - int atlas__GatherScatter__glb_dof (GatherScatter* This); - void atlas__GatherScatter__gather_int (GatherScatter* This, int ldata[], int lvar_strides[], int lvar_shape[], int lvar_rank, int gdata[], int gvar_strides[], int gvar_shape[], int gvar_rank); - void atlas__GatherScatter__gather_long (GatherScatter* This, long ldata[], int lvar_strides[], int lvar_shape[], int lvar_rank, long gdata[], int gvar_strides[], int gvar_shape[], int gvar_rank); - void atlas__GatherScatter__gather_float (GatherScatter* This, float ldata[], int lvar_strides[], int lvar_shape[], int lvar_rank, float gdata[], int gvar_strides[], int gvar_shape[], int gvar_rank); - void atlas__GatherScatter__gather_double (GatherScatter* This, double ldata[], int lvar_strides[], int lvar_shape[], int lvar_rank, double gdata[], int gvar_strides[], int gvar_shape[], int gvar_rank); - void atlas__GatherScatter__scatter_int (GatherScatter* This, int gdata[], int gvar_strides[], int gvar_shape[], int gvar_rank, int ldata[], int lvar_strides[], int lvar_shape[], int lvar_rank); - void atlas__GatherScatter__scatter_long (GatherScatter* This, long gdata[], int gvar_strides[], int gvar_shape[], int gvar_rank, long ldata[], int lvar_strides[], int lvar_shape[], int lvar_rank); - void atlas__GatherScatter__scatter_float (GatherScatter* This, float gdata[], int gvar_strides[], int gvar_shape[], int gvar_rank, float ldata[], int lvar_strides[], int lvar_shape[], int lvar_rank); - void atlas__GatherScatter__scatter_double (GatherScatter* This, double gdata[], int gvar_strides[], int gvar_shape[], int gvar_rank, double ldata[], int lvar_strides[], int lvar_shape[], int lvar_rank); +extern "C" { +GatherScatter* atlas__GatherScatter__new(); +void atlas__GatherScatter__delete( GatherScatter* This ); +void atlas__GatherScatter__setup32( GatherScatter* This, int part[], int remote_idx[], int base, int glb_idx[], + int parsize ); +void atlas__GatherScatter__setup64( GatherScatter* This, int part[], int remote_idx[], int base, long glb_idx[], + int parsize ); +int atlas__GatherScatter__glb_dof( GatherScatter* This ); +void atlas__GatherScatter__gather_int( GatherScatter* This, int ldata[], int lvar_strides[], int lvar_shape[], + int lvar_rank, int gdata[], int gvar_strides[], int gvar_shape[], + int gvar_rank ); +void atlas__GatherScatter__gather_long( GatherScatter* This, long ldata[], int lvar_strides[], int lvar_shape[], + int lvar_rank, long gdata[], int gvar_strides[], int gvar_shape[], + int gvar_rank ); +void atlas__GatherScatter__gather_float( GatherScatter* This, float ldata[], int lvar_strides[], int lvar_shape[], + int lvar_rank, float gdata[], int gvar_strides[], int gvar_shape[], + int gvar_rank ); +void atlas__GatherScatter__gather_double( GatherScatter* This, double ldata[], int lvar_strides[], int lvar_shape[], + int lvar_rank, double gdata[], int gvar_strides[], int gvar_shape[], + int gvar_rank ); +void atlas__GatherScatter__scatter_int( GatherScatter* This, int gdata[], int gvar_strides[], int gvar_shape[], + int gvar_rank, int ldata[], int lvar_strides[], int lvar_shape[], + int lvar_rank ); +void atlas__GatherScatter__scatter_long( GatherScatter* This, long gdata[], int gvar_strides[], int gvar_shape[], + int gvar_rank, long ldata[], int lvar_strides[], int lvar_shape[], + int lvar_rank ); +void atlas__GatherScatter__scatter_float( GatherScatter* This, float gdata[], int gvar_strides[], int gvar_shape[], + int gvar_rank, float ldata[], int lvar_strides[], int lvar_shape[], + int lvar_rank ); +void atlas__GatherScatter__scatter_double( GatherScatter* This, double gdata[], int gvar_strides[], int gvar_shape[], + int gvar_rank, double ldata[], int lvar_strides[], int lvar_shape[], + int lvar_rank ); } // ------------------------------------------------------------------ -//typedef GatherScatter Gather; +// typedef GatherScatter Gather; -} // namespace parallel -} // namespace atlas +} // namespace parallel +} // namespace atlas -#endif // Gather_h +#endif // Gather_h diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index d76ae9e52..c220cb744 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -4,147 +4,134 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - /// @author Willem Deconinck /// @date Nov 2013 -#include +#include "atlas/parallel/HaloExchange.h" #include #include -#include "atlas/parallel/HaloExchange.h" -#include "atlas/parallel/mpi/Statistics.h" +#include #include "atlas/array/Array.h" +#include "atlas/parallel/mpi/Statistics.h" namespace atlas { namespace parallel { namespace { -struct IsGhostPoint -{ - IsGhostPoint( const int part[], const int ridx[], const int base, const int N ) - { - part_ = part; - ridx_ = ridx; - base_ = base; - mypart_ = mpi::comm().rank(); - } - - bool operator()(size_t idx) - { - if( part_[idx] != mypart_ ) return true; - if( size_t(ridx_[idx]) != base_+idx ) return true; - return false; - } - int mypart_; - const int* part_; - const int* ridx_; - int base_; +struct IsGhostPoint { + IsGhostPoint( const int part[], const int ridx[], const int base, const int N ) { + part_ = part; + ridx_ = ridx; + base_ = base; + mypart_ = mpi::comm().rank(); + } + + bool operator()( size_t idx ) { + if ( part_[idx] != mypart_ ) return true; + if ( size_t( ridx_[idx] ) != base_ + idx ) return true; + return false; + } + int mypart_; + const int* part_; + const int* ridx_; + int base_; }; -} +} // namespace -HaloExchange::HaloExchange() : - name_(), - is_setup_(false) -{ - myproc = mpi::comm().rank(); - nproc = mpi::comm().size(); +HaloExchange::HaloExchange() : name_(), is_setup_( false ) { + myproc = mpi::comm().rank(); + nproc = mpi::comm().size(); } -HaloExchange::HaloExchange(const std::string& name) : - name_(name), - is_setup_(false) -{ - myproc = mpi::comm().rank(); - nproc = mpi::comm().size(); +HaloExchange::HaloExchange( const std::string& name ) : name_( name ), is_setup_( false ) { + myproc = mpi::comm().rank(); + nproc = mpi::comm().size(); } -void HaloExchange::setup( const int part[], - const int remote_idx[], const int base, - const size_t parsize ) -{ - ATLAS_TRACE("HaloExchange::setup"); - - parsize_ = parsize; - sendcounts_.resize(nproc); sendcounts_.assign(nproc,0); - recvcounts_.resize(nproc); recvcounts_.assign(nproc,0); - senddispls_.resize(nproc); senddispls_.assign(nproc,0); - recvdispls_.resize(nproc); recvdispls_.assign(nproc,0); - - /* - Find the amount of nodes this proc has to receive from each other proc - */ - - IsGhostPoint is_ghost(part,remote_idx,base,parsize_); - - for (int jj = 0; jj < parsize_; ++jj) - { - if ( is_ghost(jj) ) - ++recvcounts_[part[jj]]; - } - recvcnt_ = std::accumulate(recvcounts_.begin(),recvcounts_.end(),0); - - - /* - Find the amount of nodes this proc has to send to each other proc - */ - ATLAS_TRACE_MPI( ALLTOALL ) { - mpi::comm().allToAll(recvcounts_, sendcounts_); - } - - sendcnt_ = std::accumulate(sendcounts_.begin(),sendcounts_.end(),0); - - recvdispls_[0]=0; - senddispls_[0]=0; - for (int jproc = 1; jproc < nproc; ++jproc) // start at 1 - { - recvdispls_[jproc]=recvcounts_[jproc-1]+recvdispls_[jproc-1]; - senddispls_[jproc]=sendcounts_[jproc-1]+senddispls_[jproc-1]; - } - /* - Fill vector "send_requests" with remote index of nodes needed, but are on other procs - We can also fill in the vector "recvmap_" which holds local indices of requested nodes - */ - - std::vector send_requests(recvcnt_); - - recvmap_.resize(recvcnt_); - std::vector cnt(nproc,0); - for (int jj = 0; jj < parsize_; ++jj) - { - if ( is_ghost(jj) ) +void HaloExchange::setup( const int part[], const int remote_idx[], const int base, const size_t parsize ) { + ATLAS_TRACE( "HaloExchange::setup" ); + + parsize_ = parsize; + sendcounts_.resize( nproc ); + sendcounts_.assign( nproc, 0 ); + recvcounts_.resize( nproc ); + recvcounts_.assign( nproc, 0 ); + senddispls_.resize( nproc ); + senddispls_.assign( nproc, 0 ); + recvdispls_.resize( nproc ); + recvdispls_.assign( nproc, 0 ); + + /* + Find the amount of nodes this proc has to receive from each other proc +*/ + + IsGhostPoint is_ghost( part, remote_idx, base, parsize_ ); + + for ( int jj = 0; jj < parsize_; ++jj ) { + if ( is_ghost( jj ) ) ++recvcounts_[part[jj]]; + } + recvcnt_ = std::accumulate( recvcounts_.begin(), recvcounts_.end(), 0 ); + + /* + Find the amount of nodes this proc has to send to each other proc +*/ + ATLAS_TRACE_MPI( ALLTOALL ) { mpi::comm().allToAll( recvcounts_, sendcounts_ ); } + + sendcnt_ = std::accumulate( sendcounts_.begin(), sendcounts_.end(), 0 ); + + recvdispls_[0] = 0; + senddispls_[0] = 0; + for ( int jproc = 1; jproc < nproc; ++jproc ) // start at 1 { - const int req_idx = recvdispls_[part[jj]] + cnt[part[jj]]; - send_requests[req_idx] = remote_idx[jj]-base; - recvmap_[req_idx] = jj; - ++cnt[part[jj]]; + recvdispls_[jproc] = recvcounts_[jproc - 1] + recvdispls_[jproc - 1]; + senddispls_[jproc] = sendcounts_[jproc - 1] + senddispls_[jproc - 1]; + } + /* + Fill vector "send_requests" with remote index of nodes needed, but are on + other procs + We can also fill in the vector "recvmap_" which holds local indices of + requested nodes +*/ + + std::vector send_requests( recvcnt_ ); + + recvmap_.resize( recvcnt_ ); + std::vector cnt( nproc, 0 ); + for ( int jj = 0; jj < parsize_; ++jj ) { + if ( is_ghost( jj ) ) { + const int req_idx = recvdispls_[part[jj]] + cnt[part[jj]]; + send_requests[req_idx] = remote_idx[jj] - base; + recvmap_[req_idx] = jj; + ++cnt[part[jj]]; + } + } + + /* + Fill vector "recv_requests" with what is needed by other procs +*/ + + std::vector recv_requests( sendcnt_ ); + ATLAS_TRACE_MPI( ALLTOALL ) { + mpi::comm().allToAllv( send_requests.data(), recvcounts_.data(), recvdispls_.data(), recv_requests.data(), + sendcounts_.data(), senddispls_.data() ); } - } - - /* - Fill vector "recv_requests" with what is needed by other procs - */ - - std::vector recv_requests(sendcnt_); - ATLAS_TRACE_MPI( ALLTOALL ) { - mpi::comm().allToAllv(send_requests.data(), recvcounts_.data(), recvdispls_.data(), - recv_requests.data(), sendcounts_.data(), senddispls_.data()); - } - - /* - What needs to be sent to other procs is asked by remote_idx, which is local here - */ - sendmap_.resize(sendcnt_); - for( int jj=0; jj void execute_halo_exchange( HaloExchange* This, Value field[], int var_strides[], int var_extents[], int var_rank ) { - // WARNING: Only works if there is only one parallel dimension AND being slowest moving - - array::ArrayShape shape{size_t(This->backdoor.parsize)}; - for( size_t j=0; j arr ( array::Array::wrap(field, - array::ArraySpec{shape,strides} ) ); - - switch(arr->rank()) { - case 1: {This->execute(*arr); break;} - case 2: {This->execute(*arr); break;} - case 3: {This->execute(*arr); break;} - case 4: {This->execute(*arr); break;} - default: throw eckit::AssertionFailed("Rank not supported in halo exchange"); + // WARNING: Only works if there is only one parallel dimension AND being + // slowest moving + + array::ArrayShape shape{size_t( This->backdoor.parsize )}; + for ( size_t j = 0; j < var_rank; ++j ) + shape.push_back( var_extents[j] ); + + array::ArrayStrides strides{size_t( var_extents[0] * var_strides[0] )}; + for ( size_t j = 0; j < var_rank; ++j ) + strides.push_back( var_strides[j] ); + + eckit::SharedPtr arr( array::Array::wrap( field, array::ArraySpec{shape, strides} ) ); + + switch ( arr->rank() ) { + case 1: { + This->execute( *arr ); + break; + } + case 2: { + This->execute( *arr ); + break; + } + case 3: { + This->execute( *arr ); + break; + } + case 4: { + This->execute( *arr ); + break; + } + default: + throw eckit::AssertionFailed( "Rank not supported in halo exchange" ); } } -} +} // namespace extern "C" { -HaloExchange* atlas__HaloExchange__new () { +HaloExchange* atlas__HaloExchange__new() { return new HaloExchange(); } -void atlas__HaloExchange__delete (HaloExchange* This) { +void atlas__HaloExchange__delete( HaloExchange* This ) { delete This; } -void atlas__HaloExchange__setup (HaloExchange* This, int part[], int remote_idx[], int base, int size) -{ - This->setup(part,remote_idx,base,size); +void atlas__HaloExchange__setup( HaloExchange* This, int part[], int remote_idx[], int base, int size ) { + This->setup( part, remote_idx, base, size ); } -void atlas__HaloExchange__execute_strided_int (HaloExchange* This, int field[], int var_strides[], int var_extents[], int var_rank) { - execute_halo_exchange(This,field,var_strides,var_extents,var_rank); +void atlas__HaloExchange__execute_strided_int( HaloExchange* This, int field[], int var_strides[], int var_extents[], + int var_rank ) { + execute_halo_exchange( This, field, var_strides, var_extents, var_rank ); } -void atlas__HaloExchange__execute_strided_long (HaloExchange* This, long field[], int var_strides[], int var_extents[], int var_rank) { - execute_halo_exchange(This,field,var_strides,var_extents,var_rank); +void atlas__HaloExchange__execute_strided_long( HaloExchange* This, long field[], int var_strides[], int var_extents[], + int var_rank ) { + execute_halo_exchange( This, field, var_strides, var_extents, var_rank ); } -void atlas__HaloExchange__execute_strided_float (HaloExchange* This, float field[], int var_strides[], int var_extents[], int var_rank) { - execute_halo_exchange(This,field,var_strides,var_extents,var_rank); +void atlas__HaloExchange__execute_strided_float( HaloExchange* This, float field[], int var_strides[], + int var_extents[], int var_rank ) { + execute_halo_exchange( This, field, var_strides, var_extents, var_rank ); } -void atlas__HaloExchange__execute_strided_double (HaloExchange* This, double field[], int var_strides[], int var_extents[], int var_rank) { - execute_halo_exchange(This,field,var_strides,var_extents,var_rank); +void atlas__HaloExchange__execute_strided_double( HaloExchange* This, double field[], int var_strides[], + int var_extents[], int var_rank ) { + execute_halo_exchange( This, field, var_strides, var_extents, var_rank ); } - } ///////////////////// -} // namespace parallel -} // namespace atlas +} // namespace parallel +} // namespace atlas diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index ae4f3fdf3..dacffa929 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,260 +15,228 @@ #ifndef HaloExchange_h #define HaloExchange_h +#include #include #include -#include -#include "eckit/memory/SharedPtr.h" -#include "eckit/memory/Owned.h" -#include "eckit/exception/Exceptions.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/parallel/mpi/Statistics.h" #include "atlas/parallel/HaloExchangeImpl.h" +#include "atlas/parallel/mpi/Statistics.h" +#include "atlas/parallel/mpi/mpi.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" -#include "atlas/array_fwd.h" #include "atlas/array/ArrayView.h" -#include "atlas/array/SVector.h" -#include "atlas/runtime/Log.h" #include "atlas/array/ArrayViewDefs.h" #include "atlas/array/ArrayViewUtil.h" +#include "atlas/array/SVector.h" +#include "atlas/array_fwd.h" +#include "atlas/runtime/Log.h" #ifdef ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA #include "atlas/parallel/HaloExchangeCUDA.h" #endif - namespace atlas { namespace parallel { -class HaloExchange: public eckit::Owned { - -public: // types +class HaloExchange : public eckit::Owned { +public: // types typedef eckit::SharedPtr Ptr; + public: - HaloExchange(); - HaloExchange(const std::string& name); - virtual ~HaloExchange() {} + HaloExchange(); + HaloExchange( const std::string& name ); + virtual ~HaloExchange() {} + +public: // methods + const std::string& name() const { return name_; } -public: // methods + void setup( const int part[], const int remote_idx[], const int base, size_t size ); - const std::string& name() const { return name_; } + // template + // void execute( DATA_TYPE field[], size_t nb_vars ) const; - void setup( const int part[], - const int remote_idx[], const int base, - size_t size ); + template + void execute( array::Array& field, bool on_device = false ) const; -// template -// void execute( DATA_TYPE field[], size_t nb_vars ) const; +private: // methods + void create_mappings( std::vector& send_map, std::vector& recv_map, size_t nb_vars ) const; - template - void execute( array::Array& field, bool on_device = false) const; + template + void create_mappings_impl( std::vector& send_map, std::vector& recv_map, size_t nb_vars ) const; + + size_t index( size_t i, size_t j, size_t k, size_t ni, size_t nj, size_t nk ) const { + return ( i + ni * ( j + nj * k ) ); + } -private: // methods + size_t index( size_t i, size_t j, size_t ni, size_t nj ) const { return ( i + ni * j ); } - void create_mappings( std::vector& send_map, std::vector& recv_map, size_t nb_vars ) const; + template + void pack_send_buffer( const array::ArrayView& hfield, + const array::ArrayView& dfield, array::SVector& send_buffer, + const bool on_device ) const; - template - void create_mappings_impl( std::vector& send_map, std::vector& recv_map, size_t nb_vars ) const; + template + void unpack_recv_buffer( const array::SVector& recv_buffer, + const array::ArrayView& hfield, + array::ArrayView& dfield, const bool on_device ) const; - size_t index(size_t i, size_t j, size_t k, size_t ni, size_t nj, size_t nk) const { return( i + ni*( j + nj*k) ); } + template + void var_info( const array::ArrayView& arr, std::vector& varstrides, + std::vector& varshape ) const; - size_t index(size_t i, size_t j, size_t ni, size_t nj) const { return( i + ni*j ); } +private: // data + std::string name_; + bool is_setup_; + int sendcnt_; + int recvcnt_; + std::vector sendcounts_; + std::vector senddispls_; + std::vector recvcounts_; + std::vector recvdispls_; + array::SVector sendmap_; + array::SVector recvmap_; + int parsize_; - template< int ParallelDim, typename DATA_TYPE, int RANK> - void pack_send_buffer( const array::ArrayView& hfield, - const array::ArrayView& dfield, - array::SVector& send_buffer, const bool on_device ) const; + int nproc; + int myproc; - template< int ParallelDim, typename DATA_TYPE, int RANK> - void unpack_recv_buffer(const array::SVector& recv_buffer, - const array::ArrayView& hfield, - array::ArrayView& dfield, const bool on_device) const; +public: + struct Backdoor { + int parsize; + } backdoor; +}; - template - void var_info( const array::ArrayView& arr, - std::vector& varstrides, - std::vector& varshape ) const; +template +void HaloExchange::execute( array::Array& field, bool on_device ) const { + if ( !is_setup_ ) { throw eckit::SeriousBug( "HaloExchange was not setup", Here() ); } -private: // data - std::string name_; - bool is_setup_; + ATLAS_TRACE( "HaloExchange", {"halo-exchange"} ); - int sendcnt_; - int recvcnt_; - std::vector sendcounts_; - std::vector senddispls_; - std::vector recvcounts_; - std::vector recvdispls_; - array::SVector sendmap_; - array::SVector recvmap_; - int parsize_; + auto field_hv = array::make_host_view( field ); - int nproc; - int myproc; + int tag = 1; + constexpr int parallelDim = array::get_parallel_dim( field_hv ); + size_t var_size = array::get_var_size( field_hv ); + int send_size = sendcnt_ * var_size; + int recv_size = recvcnt_ * var_size; -public: - struct Backdoor { - int parsize; - } backdoor ; + array::SVector send_buffer( send_size ); + array::SVector recv_buffer( recv_size ); + std::vector send_displs( nproc ); + std::vector recv_displs( nproc ); + std::vector send_counts( nproc ); + std::vector recv_counts( nproc ); -}; + std::vector send_req( nproc ); + std::vector recv_req( nproc ); -template -void HaloExchange::execute(array::Array& field, bool on_device) const -{ - if( ! is_setup_ ) - { - throw eckit::SeriousBug("HaloExchange was not setup",Here()); - } - - ATLAS_TRACE("HaloExchange",{"halo-exchange"}); - - auto field_hv = array::make_host_view(field); - - int tag=1; - constexpr int parallelDim = array::get_parallel_dim(field_hv); - size_t var_size = array::get_var_size< parallelDim >(field_hv); - int send_size = sendcnt_ * var_size; - int recv_size = recvcnt_ * var_size; - - array::SVector send_buffer(send_size); - array::SVector recv_buffer(recv_size); - std::vector send_displs(nproc ); - std::vector recv_displs(nproc ); - std::vector send_counts(nproc ); - std::vector recv_counts(nproc ); - - std::vector send_req(nproc ); - std::vector recv_req(nproc ); - - for (int jproc=0; jproc < nproc; ++jproc) - { - send_counts[jproc] = sendcounts_[jproc]*var_size; - recv_counts[jproc] = recvcounts_[jproc]*var_size; - send_displs[jproc] = senddispls_[jproc]*var_size; - recv_displs[jproc] = recvdispls_[jproc]*var_size; - } - - auto field_dv = on_device ? array::make_device_view(field) : - array::make_host_view(field); - - ATLAS_TRACE_MPI( IRECEIVE ) { - /// Let MPI know what we like to receive - for(int jproc=0; jproc < nproc; ++jproc) - { - if(recv_counts[jproc] > 0) - { - recv_req[jproc] = mpi::comm().iReceive(&recv_buffer[recv_displs[jproc]], recv_counts[jproc], jproc, tag); - } + for ( int jproc = 0; jproc < nproc; ++jproc ) { + send_counts[jproc] = sendcounts_[jproc] * var_size; + recv_counts[jproc] = recvcounts_[jproc] * var_size; + send_displs[jproc] = senddispls_[jproc] * var_size; + recv_displs[jproc] = recvdispls_[jproc] * var_size; } - } - - /// Pack - pack_send_buffer(field_hv, field_dv,send_buffer, on_device); - - /// Send - ATLAS_TRACE_MPI( ISEND ) { - for(int jproc=0; jproc < nproc; ++jproc) - { - if(send_counts[jproc] > 0) - { - send_req[jproc] = mpi::comm().iSend( - &send_buffer[send_displs[jproc]], - send_counts[jproc], jproc, tag); - } + + auto field_dv = + on_device ? array::make_device_view( field ) : array::make_host_view( field ); + + ATLAS_TRACE_MPI( IRECEIVE ) { + /// Let MPI know what we like to receive + for ( int jproc = 0; jproc < nproc; ++jproc ) { + if ( recv_counts[jproc] > 0 ) { + recv_req[jproc] = + mpi::comm().iReceive( &recv_buffer[recv_displs[jproc]], recv_counts[jproc], jproc, tag ); + } + } } - } - - /// 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]); - } + + /// Pack + pack_send_buffer( field_hv, field_dv, send_buffer, on_device ); + + /// Send + ATLAS_TRACE_MPI( ISEND ) { + for ( int jproc = 0; jproc < nproc; ++jproc ) { + if ( send_counts[jproc] > 0 ) { + send_req[jproc] = mpi::comm().iSend( &send_buffer[send_displs[jproc]], send_counts[jproc], jproc, tag ); + } + } } - } - - /// Unpack - unpack_recv_buffer(recv_buffer, field_hv, field_dv, on_device); - - /// 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]); - } + + /// 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] ); } + } } - } + /// Unpack + unpack_recv_buffer( recv_buffer, field_hv, field_dv, on_device ); + + /// 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] ); } + } + } } -template +template struct halo_packer { - template - static void pack(const unsigned int sendcnt, array::SVector const & sendmap, - const array::ArrayView& field, array::SVector& send_buffer ) - { - size_t ibuf = 0; - for(int node_cnt=0; node_cnt < sendcnt; ++node_cnt) - { - const size_t node_idx = sendmap[node_cnt]; - halo_packer_impl::apply(ibuf, node_idx, field, send_buffer); - } + template + static void pack( const unsigned int sendcnt, array::SVector const& sendmap, + const array::ArrayView& field, + array::SVector& send_buffer ) { + size_t ibuf = 0; + for ( int node_cnt = 0; node_cnt < sendcnt; ++node_cnt ) { + const size_t node_idx = sendmap[node_cnt]; + halo_packer_impl::apply( ibuf, node_idx, field, send_buffer ); + } } - template - static void unpack(const unsigned int recvcnt, array::SVector const & recvmap, - array::SVector const & recv_buffer, array::ArrayView& field ) - { - size_t ibuf = 0; - for(int node_cnt=0; node_cnt < recvcnt; ++node_cnt) - { - const size_t node_idx = recvmap[node_cnt]; - halo_unpacker_impl::apply(ibuf, node_idx, recv_buffer, field); - } + template + static void unpack( const unsigned int recvcnt, array::SVector const& recvmap, + array::SVector const& recv_buffer, array::ArrayView& field ) { + size_t ibuf = 0; + for ( int node_cnt = 0; node_cnt < recvcnt; ++node_cnt ) { + const size_t node_idx = recvmap[node_cnt]; + halo_unpacker_impl::apply( ibuf, node_idx, recv_buffer, field ); + } } - }; -template +template void HaloExchange::pack_send_buffer( const array::ArrayView& hfield, const array::ArrayView& dfield, - array::SVector& send_buffer, const bool on_device ) const -{ - ATLAS_TRACE(); + array::SVector& send_buffer, const bool on_device ) const { + ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - if(on_device) { - halo_packer_cuda::pack(sendcnt_, sendmap_, hfield, dfield, send_buffer); + if ( on_device ) { + halo_packer_cuda::pack( sendcnt_, sendmap_, hfield, dfield, send_buffer ); } else #endif - halo_packer::pack(sendcnt_, sendmap_, dfield, send_buffer); + halo_packer::pack( sendcnt_, sendmap_, dfield, send_buffer ); } -template +template void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buffer, const array::ArrayView& hfield, - array::ArrayView& dfield, const bool on_device) const -{ - ATLAS_TRACE(); + array::ArrayView& dfield, const bool on_device ) const { + ATLAS_TRACE(); #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - if(on_device) { - halo_packer_cuda::unpack(recvcnt_, recvmap_, recv_buffer, hfield, dfield); + if ( on_device ) { + halo_packer_cuda::unpack( recvcnt_, recvmap_, recv_buffer, hfield, dfield ); } else #endif - halo_packer::unpack(recvcnt_, recvmap_, recv_buffer, dfield); - + halo_packer::unpack( recvcnt_, recvmap_, recv_buffer, dfield ); } -//template -//void HaloExchange::execute( DATA_TYPE field[], size_t nb_vars ) const +// template +// void HaloExchange::execute( DATA_TYPE field[], size_t nb_vars ) const //{ // throw eckit::AssertionFailed("Call not supported"); @@ -276,33 +245,34 @@ void HaloExchange::unpack_recv_buffer( const array::SVector& recv_buf // execute( field, strides, shape, 1); //} - -//template -//void HaloExchange::execute( array::ArrayView&& field ) const +// template +// void HaloExchange::execute( array::ArrayView&& field ) const //{ // execute(field); //} //---------------------------------------------------------------------------------------------------------------------- // C wrapper interfaces to C++ routines -extern "C" -{ - HaloExchange* atlas__HaloExchange__new (); - void atlas__HaloExchange__delete (HaloExchange* This); - void atlas__HaloExchange__setup (HaloExchange* This, int part[], int remote_idx[], int base, int size); - void atlas__HaloExchange__execute_strided_int (HaloExchange* This, int field[], int var_strides[], int var_shape[], int var_rank); - void atlas__HaloExchange__execute_strided_long (HaloExchange* This, long field[], int var_strides[], int var_shape[], int var_rank); - void atlas__HaloExchange__execute_strided_float (HaloExchange* This, float field[], int var_strides[], int var_shape[], int var_rank); - void atlas__HaloExchange__execute_strided_double (HaloExchange* This, double field[], int var_strides[], int var_shape[], int var_rank); - void atlas__HaloExchange__execute_int (HaloExchange* This, int field[], int var_rank); - void atlas__HaloExchange__execute_float (HaloExchange* This, float field[], int var_rank); - void atlas__HaloExchange__execute_double (HaloExchange* This, double field[], int var_rank); - +extern "C" { +HaloExchange* atlas__HaloExchange__new(); +void atlas__HaloExchange__delete( HaloExchange* This ); +void atlas__HaloExchange__setup( HaloExchange* This, int part[], int remote_idx[], int base, int size ); +void atlas__HaloExchange__execute_strided_int( HaloExchange* This, int field[], int var_strides[], int var_shape[], + int var_rank ); +void atlas__HaloExchange__execute_strided_long( HaloExchange* This, long field[], int var_strides[], int var_shape[], + int var_rank ); +void atlas__HaloExchange__execute_strided_float( HaloExchange* This, float field[], int var_strides[], int var_shape[], + int var_rank ); +void atlas__HaloExchange__execute_strided_double( HaloExchange* This, double field[], int var_strides[], + int var_shape[], int var_rank ); +void atlas__HaloExchange__execute_int( HaloExchange* This, int field[], int var_rank ); +void atlas__HaloExchange__execute_float( HaloExchange* This, float field[], int var_rank ); +void atlas__HaloExchange__execute_double( HaloExchange* This, double field[], int var_rank ); } //---------------------------------------------------------------------------------------------------------------------- -} // namespace parallel -} // namespace atlas +} // namespace parallel +} // namespace atlas -#endif // HaloExchange_h +#endif // HaloExchange_h diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index d5d6c4877..6c12fafc9 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -6,27 +6,28 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "atlas/array/ArrayView.h" -#include "atlas/array/SVector.h" #include "atlas/array/ArrayViewDefs.h" +#include "atlas/array/SVector.h" namespace atlas { namespace parallel { -template +template struct halo_packer_cuda { - static void pack( const int sendcnt, array::SVector const & sendmap, - const array::ArrayView& hfield, const array::ArrayView& dfield, - array::SVector& send_buffer ); + static void pack( const int sendcnt, array::SVector const& sendmap, + const array::ArrayView& hfield, + const array::ArrayView& dfield, array::SVector& send_buffer ); - static void unpack( const int sendcnt, array::SVector const & recvmap, - const array::SVector& recv_buffer, const array::ArrayView& hfield, - array::ArrayView& dhfield ); + static void unpack( const int sendcnt, array::SVector const& recvmap, + const array::SVector& recv_buffer, + const array::ArrayView& hfield, + array::ArrayView& dhfield ); }; -} // namespace paralllel -} // namespace atlas - +} // namespace parallel +} // namespace atlas diff --git a/src/atlas/parallel/HaloExchangeImpl.h b/src/atlas/parallel/HaloExchangeImpl.h index b84508f63..3fec5c3a2 100644 --- a/src/atlas/parallel/HaloExchangeImpl.h +++ b/src/atlas/parallel/HaloExchangeImpl.h @@ -6,108 +6,103 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/array/SVector.h" #include "atlas/array/ArrayView.h" - +#include "atlas/array/SVector.h" namespace atlas { namespace parallel { -template +template struct halo_packer_impl { - template - ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, - array::SVector& send_buffer, Idx... idxs) { - for( size_t i=0; i< field.template shape(); ++i ) { - halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs..., i); - } + template + ATLAS_HOST_DEVICE static void apply( size_t& buf_idx, const size_t node_idx, + const array::ArrayView& field, + array::SVector& send_buffer, Idx... idxs ) { + for ( size_t i = 0; i < field.template shape(); ++i ) { + halo_packer_impl::apply( buf_idx, node_idx, field, send_buffer, + idxs..., i ); + } } }; -template +template struct halo_packer_impl { - template - ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, - array::SVector& send_buffer, Idx...idxs) - { - send_buffer[buf_idx++] = field(idxs...); + template + ATLAS_HOST_DEVICE static void apply( size_t& buf_idx, const size_t node_idx, + const array::ArrayView& field, + array::SVector& send_buffer, Idx... idxs ) { + send_buffer[buf_idx++] = field( idxs... ); } }; -template -struct halo_packer_impl -{ - template - ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, - array::SVector& send_buffer, Idx... idxs) { - halo_packer_impl::apply(buf_idx, node_idx, field, send_buffer, idxs...,node_idx); +template +struct halo_packer_impl { + template + ATLAS_HOST_DEVICE static void apply( size_t& buf_idx, const size_t node_idx, + const array::ArrayView& field, + array::SVector& send_buffer, Idx... idxs ) { + halo_packer_impl::apply( buf_idx, node_idx, field, send_buffer, idxs..., + node_idx ); } }; -template +template struct halo_packer_impl { - template - ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, const array::ArrayView& field, - array::SVector& send_buffer, Idx...idxs) - { - send_buffer[buf_idx++] = field(idxs...); + template + ATLAS_HOST_DEVICE static void apply( size_t& buf_idx, const size_t node_idx, + const array::ArrayView& field, + array::SVector& send_buffer, Idx... idxs ) { + send_buffer[buf_idx++] = field( idxs... ); } }; -template +template struct halo_unpacker_impl { - template - ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, - array::ArrayView& field, Idx... idxs) { - for( size_t i=0; i< field.template shape(); ++i ) { - halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs..., i); + template + ATLAS_HOST_DEVICE static void apply( size_t& buf_idx, const size_t node_idx, + array::SVector const& recv_buffer, + array::ArrayView& field, Idx... idxs ) { + for ( size_t i = 0; i < field.template shape(); ++i ) { + halo_unpacker_impl::apply( buf_idx, node_idx, recv_buffer, field, + idxs..., i ); } } }; -template +template struct halo_unpacker_impl { - - template - ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, - array::ArrayView& field, Idx...idxs) - { - field(idxs...) = recv_buffer[buf_idx++]; + template + ATLAS_HOST_DEVICE static void apply( size_t& buf_idx, const size_t node_idx, + array::SVector const& recv_buffer, + array::ArrayView& field, Idx... idxs ) { + field( idxs... ) = recv_buffer[buf_idx++]; } }; -template +template struct halo_unpacker_impl { - template - ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, - array::ArrayView& field, Idx... idxs) { - halo_unpacker_impl::apply(buf_idx, node_idx, recv_buffer, field, idxs...,node_idx); + template + ATLAS_HOST_DEVICE static void apply( size_t& buf_idx, const size_t node_idx, + array::SVector const& recv_buffer, + array::ArrayView& field, Idx... idxs ) { + halo_unpacker_impl::apply( buf_idx, node_idx, recv_buffer, field, + idxs..., node_idx ); } }; -template +template struct halo_unpacker_impl { - - template - ATLAS_HOST_DEVICE - static void apply(size_t& buf_idx, const size_t node_idx, array::SVector const & recv_buffer, - array::ArrayView& field, Idx...idxs) - { - field(idxs...) = recv_buffer[buf_idx++]; + template + ATLAS_HOST_DEVICE static void apply( size_t& buf_idx, const size_t node_idx, + array::SVector const& recv_buffer, + array::ArrayView& field, Idx... idxs ) { + field( idxs... ) = recv_buffer[buf_idx++]; } }; - -} //namespace parallel -} //namespace atlas - +} // namespace parallel +} // namespace atlas diff --git a/src/atlas/parallel/mpi/Buffer.h b/src/atlas/parallel/mpi/Buffer.h index 75249e2ce..d5ba9ce8d 100644 --- a/src/atlas/parallel/mpi/Buffer.h +++ b/src/atlas/parallel/mpi/Buffer.h @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "atlas/parallel/mpi/mpi.h" #include "atlas/array/LocalView.h" +#include "atlas/parallel/mpi/mpi.h" namespace atlas { namespace mpi { @@ -22,46 +23,43 @@ namespace mpi { /// counts and displacements, but with added index operator[] /// that returns an array::ArrayView of the part /// of the buffer for a processor index. -template struct Buffer; +template +struct Buffer; // ---------------------------------------------------------------------------------- -template -struct Buffer : eckit::mpi::Buffer -{ -}; +template +struct Buffer : eckit::mpi::Buffer {}; -template -class BufferView -{ +template +class BufferView { public: - BufferView(DATA_TYPE *data, size_t size) : data_(data), size_(size) {} + BufferView( DATA_TYPE* data, size_t size ) : data_( data ), size_( size ) {} size_t size() const { return size_; } - const DATA_TYPE& operator()(const size_t i) const { return data_[i]; } - const DATA_TYPE& operator[](const size_t i) const { return data_[i]; } + const DATA_TYPE& operator()( const size_t i ) const { return data_[i]; } + const DATA_TYPE& operator[]( const size_t i ) const { return data_[i]; } + private: - DATA_TYPE *data_; + DATA_TYPE* data_; size_t size_; }; template -struct Buffer : public eckit::mpi::Buffer -{ - - Buffer(size_t size) : eckit::mpi::Buffer(size) {} - - // array::make_shape( eckit::mpi::Buffer::counts[p] ) ); - // } - BufferView operator[](int p) - { - return BufferView( - eckit::mpi::Buffer::buffer.data() + eckit::mpi::Buffer::displs[p], - eckit::mpi::Buffer::counts[p] ); - } +struct Buffer : public eckit::mpi::Buffer { + Buffer( size_t size ) : eckit::mpi::Buffer( size ) {} + // array::make_shape( + // eckit::mpi::Buffer::counts[p] + // ) ); + // } + BufferView operator[]( int p ) { + return BufferView( + eckit::mpi::Buffer::buffer.data() + eckit::mpi::Buffer::displs[p], + eckit::mpi::Buffer::counts[p] ); + } }; // ---------------------------------------------------------------------------------- -} // namespace mpi -} // namespace atlas +} // namespace mpi +} // namespace atlas diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 471b754ad..aefc2e30f 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,22 +15,21 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Trace.h" -#define ATLAS_TRACE_MPI(...) +#define ATLAS_TRACE_MPI( ... ) #if ATLAS_HAVE_TRACE #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_( Type, location, operation, ... ) __ATLAS_TYPE_SCOPE( \ - Type, location, __ATLAS_TRACE_MPI_ENUM(operation) __ATLAS_COMMA_ARGS(__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__ ) ) -#define __ATLAS_TRACE_MPI_ENUM(operation) ::atlas::mpi::Operation::__ATLAS_STRINGIFY(operation) +#define __ATLAS_TRACE_MPI_ENUM( operation ) ::atlas::mpi::Operation::__ATLAS_STRINGIFY( operation ) #endif - namespace atlas { namespace mpi { @@ -38,55 +38,41 @@ struct StatisticsTimerTraits { using Tracing = runtime::trace::NoLogging; }; - -enum class Operation { - BROADCAST, - ALLREDUCE, - ALLGATHER, - ALLTOALL, - REDUCE, - GATHER, - SCATTER, - BARRIER, - SENDRECEIVE, - ISEND, - IRECEIVE, - WAIT, - _COUNT_ +enum class Operation +{ + BROADCAST, + ALLREDUCE, + ALLGATHER, + ALLTOALL, + REDUCE, + GATHER, + SCATTER, + BARRIER, + SENDRECEIVE, + ISEND, + IRECEIVE, + WAIT, + _COUNT_ }; -static const std::string& name(Operation c) { - static std::array(Operation::_COUNT_)> names { - "mpi.broadcast", - "mpi.allreduce", - "mpi.allgather", - "mpi.alltoall", - "mpi.reduce", - "mpi.gather", - "mpi.scatter", - "mpi.barrier", - "mpi.sendreceive", - "mpi.isend", - "mpi.ireceive", - "mpi.wait" - }; - return names[ static_cast(c) ]; +static const std::string& name( Operation c ) { + static std::array( Operation::_COUNT_ )> names{ + "mpi.broadcast", "mpi.allreduce", "mpi.allgather", "mpi.alltoall", "mpi.reduce", "mpi.gather", + "mpi.scatter", "mpi.barrier", "mpi.sendreceive", "mpi.isend", "mpi.ireceive", "mpi.wait"}; + return names[static_cast( c )]; } -class Trace : public runtime::trace::TraceT< StatisticsTimerTraits > { - using Base = runtime::trace::TraceT< StatisticsTimerTraits >; +class Trace : public runtime::trace::TraceT { + using Base = runtime::trace::TraceT; + public: - Trace( const eckit::CodeLocation& loc, Operation c ) : - Base( loc, name(c), make_labels(c) ) { - } + Trace( const eckit::CodeLocation& loc, Operation c ) : Base( loc, name( c ), make_labels( c ) ) {} Trace( const eckit::CodeLocation& loc, Operation c, const std::string& title ) : - Base( loc, title, make_labels(c) ) { - } + Base( loc, title, make_labels( c ) ) {} + private: - static std::vector make_labels( Operation c) { - return {"mpi", name(c)}; - } + static std::vector make_labels( Operation c ) { return {"mpi", name( c )}; } }; -} // namespace mpi -} // namespace atlas +} // namespace mpi +} // namespace atlas diff --git a/src/atlas/parallel/mpi/mpi.cc b/src/atlas/parallel/mpi/mpi.cc index 106383db5..78d44b180 100644 --- a/src/atlas/parallel/mpi/mpi.cc +++ b/src/atlas/parallel/mpi/mpi.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,10 +14,9 @@ namespace atlas { namespace mpi { -const eckit::mpi::Comm& comm() -{ - return eckit::mpi::comm(); +const eckit::mpi::Comm& comm() { + return eckit::mpi::comm(); } -} // namespace mpi -} // namespace atlas +} // namespace mpi +} // namespace atlas diff --git a/src/atlas/parallel/mpi/mpi.h b/src/atlas/parallel/mpi/mpi.h index a73062f27..abc10c4ea 100644 --- a/src/atlas/parallel/mpi/mpi.h +++ b/src/atlas/parallel/mpi/mpi.h @@ -4,19 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "eckit/mpi/Comm.h" #include "atlas/parallel/mpi/Statistics.h" +#include "eckit/mpi/Comm.h" namespace atlas { namespace mpi { const eckit::mpi::Comm& comm(); -} // namespace mpi -} // namespace atlas +} // namespace mpi +} // namespace atlas diff --git a/src/atlas/parallel/omp/omp.cc b/src/atlas/parallel/omp/omp.cc index 0272164ec..7e946f052 100644 --- a/src/atlas/parallel/omp/omp.cc +++ b/src/atlas/parallel/omp/omp.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,16 +14,16 @@ #ifdef _OPENMP #include #else -extern "C" void omp_set_num_threads(int num_threads); -extern "C" int omp_get_num_threads(void); -extern "C" int omp_get_max_threads(void); -extern "C" int omp_get_thread_num(void); -extern "C" int omp_get_num_procs(void); -extern "C" int omp_in_parallel(void); -extern "C" int omp_set_dynamic(int dynamic_threads); -extern "C" int omp_get_dynamic(void); -extern "C" void omp_set_nested(int nested); -extern "C" int omp_get_nested(void); +extern "C" void omp_set_num_threads( int num_threads ); +extern "C" int omp_get_num_threads( void ); +extern "C" int omp_get_max_threads( void ); +extern "C" int omp_get_thread_num( void ); +extern "C" int omp_get_num_procs( void ); +extern "C" int omp_in_parallel( void ); +extern "C" int omp_set_dynamic( int dynamic_threads ); +extern "C" int omp_get_dynamic( void ); +extern "C" void omp_set_nested( int nested ); +extern "C" int omp_get_nested( void ); #endif #ifdef ATLAS_HAVE_OMP @@ -40,80 +41,69 @@ extern "C" { } #endif -void atlas_omp_set_num_threads(int num_threads) -{ +void atlas_omp_set_num_threads( int num_threads ) { #ifdef 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) -{ +int atlas_omp_get_num_threads( void ) { #ifdef 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; + return 1; } -int atlas_omp_get_max_threads(void) -{ +int atlas_omp_get_max_threads( void ) { #ifdef 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; + return 1; } -int atlas_omp_get_thread_num(void) -{ +int atlas_omp_get_thread_num( void ) { #ifdef 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; + return 0; } -int atlas_omp_get_num_procs(void) -{ +int atlas_omp_get_num_procs( void ) { #ifdef 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; + return 1; } -int atlas_omp_in_parallel(void) -{ +int atlas_omp_in_parallel( void ) { #ifdef ATLAS_HAVE_OMP - if( omp_in_parallel ) return omp_in_parallel(); + if ( omp_in_parallel ) return omp_in_parallel(); #endif - return 0; + return 0; } -void atlas_omp_set_dynamic(int dynamic_threads) -{ +void atlas_omp_set_dynamic( int dynamic_threads ) { #ifdef 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) -{ +int atlas_omp_get_dynamic( void ) { #ifdef ATLAS_HAVE_OMP - if( omp_get_dynamic ) return omp_get_dynamic(); + if ( omp_get_dynamic ) return omp_get_dynamic(); #endif - return 0; + return 0; } -void atlas_omp_set_nested(int nested) -{ +void atlas_omp_set_nested( int nested ) { #ifdef 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) -{ +int atlas_omp_get_nested( void ) { #ifdef ATLAS_HAVE_OMP - if( omp_get_nested ) return omp_get_nested(); + if ( omp_get_nested ) return omp_get_nested(); #endif - return 0; + return 0; } - diff --git a/src/atlas/parallel/omp/omp.h b/src/atlas/parallel/omp/omp.h index de7f7a069..1785aea70 100644 --- a/src/atlas/parallel/omp/omp.h +++ b/src/atlas/parallel/omp/omp.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,48 +13,45 @@ #include "atlas/library/config.h" -void atlas_omp_set_num_threads(int num_threads); -int atlas_omp_get_num_threads(void); -int atlas_omp_get_max_threads(void); -int atlas_omp_get_thread_num(void); -int atlas_omp_get_num_procs(void); -int atlas_omp_in_parallel(void); -void atlas_omp_set_dynamic(int dynamic_threads); -int atlas_omp_get_dynamic(void); -void atlas_omp_set_nested(int nested); -int atlas_omp_get_nested(void); - +void atlas_omp_set_num_threads( int num_threads ); +int atlas_omp_get_num_threads( void ); +int atlas_omp_get_max_threads( void ); +int atlas_omp_get_thread_num( void ); +int atlas_omp_get_num_procs( void ); +int atlas_omp_in_parallel( void ); +void atlas_omp_set_dynamic( int dynamic_threads ); +int atlas_omp_get_dynamic( void ); +void atlas_omp_set_nested( int nested ); +int atlas_omp_get_nested( void ); #ifdef ATLAS_HAVE_OMP -#define __ATLAS_OMP_STR(x) #x -#define __ATLAS_OMP_STRINGIFY(x) __ATLAS_OMP_STR(x) -#define atlas_omp_pragma(x) \ - _Pragma( __ATLAS_OMP_STRINGIFY( x ) ) +#define __ATLAS_OMP_STR( x ) #x +#define __ATLAS_OMP_STRINGIFY( x ) __ATLAS_OMP_STR( x ) +#define atlas_omp_pragma( x ) _Pragma( __ATLAS_OMP_STRINGIFY( x ) ) #else -#define atlas_omp_pragma(x) +#define atlas_omp_pragma( x ) #endif #define atlas_omp_parallel_for atlas_omp_pragma(omp parallel for) for #define atlas_omp_for atlas_omp_pragma(omp for) for -#define atlas_omp_parallel atlas_omp_pragma(omp parallel) -#define atlas_omp_critical atlas_omp_pragma(omp critical) +#define atlas_omp_parallel atlas_omp_pragma( omp parallel ) +#define atlas_omp_critical atlas_omp_pragma( omp critical ) template -class atlas_omp_scoped_helper -{ +class atlas_omp_scoped_helper { public: - atlas_omp_scoped_helper(T p): value(p), once_(true) {} - bool once() const { return once_; } - void done() { once_=false; } - T value; + atlas_omp_scoped_helper( T p ) : value( p ), once_( true ) {} + bool once() const { return once_; } + void done() { once_ = false; } + T value; + private: - bool once_; + bool once_; }; -#define __atlas_omp_scoped(T,VAR,VAL) \ - for( atlas_omp_scoped_helper VAR(VAL); VAR.once(); VAR.done() ) +#define __atlas_omp_scoped( T, VAR, VAL ) for ( atlas_omp_scoped_helper VAR( VAL ); VAR.once(); VAR.done() ) -#define atlas_omp_critical_ordered \ +#define atlas_omp_critical_ordered \ __atlas_omp_scoped(const size_t, _nthreads, atlas_omp_get_num_threads()) \ atlas_omp_pragma( omp for ordered schedule(static,1) )\ for( size_t _thread=0; _thread<_nthreads.value; ++_thread )\ diff --git a/src/atlas/projection.h b/src/atlas/projection.h index a68b5a891..018b92ece 100644 --- a/src/atlas/projection.h +++ b/src/atlas/projection.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ diff --git a/src/atlas/projection/Projection.cc b/src/atlas/projection/Projection.cc index c5cade179..c46090c9f 100644 --- a/src/atlas/projection/Projection.cc +++ b/src/atlas/projection/Projection.cc @@ -2,24 +2,16 @@ namespace atlas { -Projection::Projection(): - projection_( Implementation::create() ) { -} +Projection::Projection() : projection_( Implementation::create() ) {} -Projection::Projection(const Projection& projection): - projection_( projection.projection_ ) { -} +Projection::Projection( const Projection& projection ) : projection_( projection.projection_ ) {} -Projection::Projection( const Implementation* projection ): - projection_( const_cast(projection) ) { -} +Projection::Projection( const Implementation* projection ) : projection_( const_cast( projection ) ) {} -Projection::Projection( const eckit::Parametrisation& p ): - projection_( Implementation::create(p) ) { -} +Projection::Projection( const eckit::Parametrisation& p ) : projection_( Implementation::create( p ) ) {} void Projection::hash( eckit::Hash& h ) const { - return projection_->hash(h); + return projection_->hash( h ); } -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/projection/Projection.h b/src/atlas/projection/Projection.h index 38dc869bf..931d35810 100644 --- a/src/atlas/projection/Projection.h +++ b/src/atlas/projection/Projection.h @@ -5,8 +5,8 @@ #include "eckit/memory/SharedPtr.h" #include "eckit/utils/Hash.h" -#include "atlas/util/Point.h" #include "atlas/projection/detail/ProjectionImpl.h" +#include "atlas/util/Point.h" //--------------------------------------------------------------------------------------------------------------------- @@ -22,53 +22,65 @@ namespace atlas { //--------------------------------------------------------------------------------------------------------------------- class Projection { - public: - - using Implementation = projection::detail::ProjectionImpl; - using Spec = Implementation::Spec; + using Implementation = projection::detail::ProjectionImpl; + using Spec = Implementation::Spec; public: + Projection(); + Projection( const Projection& ); + Projection( const Implementation* ); + Projection( const eckit::Parametrisation& ); - Projection(); - Projection( const Projection& ); - Projection( const Implementation* ); - Projection( const eckit::Parametrisation& ); + void xy2lonlat( double crd[] ) const; + void lonlat2xy( double crd[] ) const; - void xy2lonlat(double crd[]) const; - void lonlat2xy(double crd[]) const; + PointLonLat lonlat( const PointXY& ) const; + PointXY xy( const PointLonLat& ) const; - PointLonLat lonlat( const PointXY& ) const; - PointXY xy( const PointLonLat& ) const; + bool strictlyRegional() const; - bool strictlyRegional() const; + Spec spec() const; - Spec spec() const; + std::string units() const; - std::string units() const; + operator bool() const; - operator bool() const; + std::string type() const { return projection_->type(); } - std::string type() const { return projection_->type(); } - - void hash( eckit::Hash& ) const; + void hash( eckit::Hash& ) const; private: - - eckit::SharedPtr projection_; + eckit::SharedPtr projection_; }; //--------------------------------------------------------------------------------------------------------------------- -inline void Projection::xy2lonlat(double crd[]) const { return projection_->xy2lonlat(crd); } -inline void Projection::lonlat2xy(double crd[]) const { return projection_->lonlat2xy(crd); } -inline PointLonLat Projection::lonlat( const PointXY& xy) const { return projection_->lonlat(xy); } -inline PointXY Projection::xy( const PointLonLat& lonlat) const { return projection_->xy(lonlat); } -inline bool Projection::strictlyRegional() const { return projection_->strictlyRegional(); } -inline Projection::Spec Projection::spec() const { return projection_->spec(); } -inline std::string Projection::units() const { return projection_->units(); } -inline Projection::operator bool() const { return projection_->operator bool(); } +inline void Projection::xy2lonlat( double crd[] ) const { + return projection_->xy2lonlat( crd ); +} +inline void Projection::lonlat2xy( double crd[] ) const { + return projection_->lonlat2xy( crd ); +} +inline PointLonLat Projection::lonlat( const PointXY& xy ) const { + return projection_->lonlat( xy ); +} +inline PointXY Projection::xy( const PointLonLat& lonlat ) const { + return projection_->xy( lonlat ); +} +inline bool Projection::strictlyRegional() const { + return projection_->strictlyRegional(); +} +inline Projection::Spec Projection::spec() const { + return projection_->spec(); +} +inline std::string Projection::units() const { + return projection_->units(); +} +inline Projection::operator bool() const { + return projection_->operator bool(); +} //--------------------------------------------------------------------------------------------------------------------- -} +} // namespace atlas diff --git a/src/atlas/projection/detail/LambertProjection.cc b/src/atlas/projection/detail/LambertProjection.cc index b005692dc..e32f536c9 100644 --- a/src/atlas/projection/detail/LambertProjection.cc +++ b/src/atlas/projection/detail/LambertProjection.cc @@ -1,110 +1,102 @@ -#include #include "atlas/projection/detail/LambertProjection.h" +#include #include "atlas/util/Constants.h" #include "atlas/util/Earth.h" /* -Projection formula's for Lambert projection from "Map Projections: A Working Manual" +Projection formula's for Lambert projection from "Map Projections: A Working +Manual" The origin of the xy-system is at (lon0,0) */ namespace { - static double D2R(const double x) { - return atlas::util::Constants::degreesToRadians()*x; - } - static double R2D(const double x) { - return atlas::util::Constants::radiansToDegrees()*x; - } +static double D2R( const double x ) { + return atlas::util::Constants::degreesToRadians() * x; +} +static double R2D( const double x ) { + return atlas::util::Constants::radiansToDegrees() * x; } +} // namespace namespace atlas { namespace projection { namespace detail { - // constructors -LambertProjection::LambertProjection(const eckit::Parametrisation& params) { - // check presence of radius - if( ! params.get("radius",radius_) ) - radius_=util::Earth::radiusInMeters(); - // check presence of lat1 and lat2 - if( ! params.get("latitude1",lat1_) ) - throw eckit::BadParameter("latitude1 missing in Params",Here()); - if( ! params.get("latitude2",lat2_) ) - lat2_=lat1_; - // check presence of lon0 - if( ! params.get("longitude0",lon0_) ) - throw eckit::BadParameter("longitude0 missing in Params",Here()); - - setup(); +LambertProjection::LambertProjection( const eckit::Parametrisation& params ) { + // check presence of radius + if ( !params.get( "radius", radius_ ) ) radius_ = util::Earth::radiusInMeters(); + // check presence of lat1 and lat2 + if ( !params.get( "latitude1", lat1_ ) ) throw eckit::BadParameter( "latitude1 missing in Params", Here() ); + if ( !params.get( "latitude2", lat2_ ) ) lat2_ = lat1_; + // check presence of lon0 + if ( !params.get( "longitude0", lon0_ ) ) throw eckit::BadParameter( "longitude0 missing in Params", Here() ); + + setup(); } - void LambertProjection::setup() { - // setup (derived) constants - is_tangent_ = (lat1_==lat2_); - 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))); - } - F_ = std::cos(D2R(lat1_))*std::pow(std::tan(D2R(45.+lat1_*0.5)),n_)/n_; - rho0_ = radius_*F_; - inv_n_ = 1./n_; - sign_ = ( n_<0. ? -1. : 1. ); + // setup (derived) constants + is_tangent_ = ( lat1_ == lat2_ ); + 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 ) ) ); + } + F_ = std::cos( D2R( lat1_ ) ) * std::pow( std::tan( D2R( 45. + lat1_ * 0.5 ) ), n_ ) / n_; + rho0_ = radius_ * F_; + inv_n_ = 1. / n_; + sign_ = ( n_ < 0. ? -1. : 1. ); } -void LambertProjection::lonlat2xy(double crd[]) const { - - const double rho = radius_*F_/std::pow(std::tan(D2R(45+crd[1]*0.5)),n_); - const double theta = D2R( n_*(crd[0]-lon0_) ); - //eckit::geometry::reduceTo2Pi(theta); // bracket between 0 and 360 - // theta*=n_; - crd[0] = rho*std::sin(theta); - crd[1] = rho0_-rho*std::cos(theta); +void LambertProjection::lonlat2xy( double crd[] ) const { + const double rho = radius_ * F_ / std::pow( std::tan( D2R( 45 + crd[1] * 0.5 ) ), n_ ); + const double theta = D2R( n_ * ( crd[0] - lon0_ ) ); + // eckit::geometry::reduceTo2Pi(theta); // bracket between 0 and 360 + // theta*=n_; + crd[0] = rho * std::sin( theta ); + crd[1] = rho0_ - rho * std::cos( theta ); } // inverse projection -void LambertProjection::xy2lonlat(double crd[]) const { - // auxiliaries - const double y0 = rho0_-crd[1]; - const double rho = sign_ * std::sqrt(crd[0]*crd[0]+y0*y0); - const double theta = R2D(std::atan2(sign_*crd[0],sign_*y0)); - - // longitude - crd[0] = theta*inv_n_+lon0_; - - // latitude - if (rho==0.) { - crd[1] = sign_ * 90.; - } else { - crd[1] = 2.*R2D(std::atan(std::pow(radius_*F_/rho,inv_n_)))-90.; - } +void LambertProjection::xy2lonlat( double crd[] ) const { + // auxiliaries + const double y0 = rho0_ - crd[1]; + const double rho = sign_ * std::sqrt( crd[0] * crd[0] + y0 * y0 ); + const double theta = R2D( std::atan2( sign_ * crd[0], sign_ * y0 ) ); + + // longitude + crd[0] = theta * inv_n_ + lon0_; + + // latitude + if ( rho == 0. ) { crd[1] = sign_ * 90.; } + else { + crd[1] = 2. * R2D( std::atan( std::pow( radius_ * F_ / rho, inv_n_ ) ) ) - 90.; + } } // specification LambertProjection::Spec LambertProjection::spec() const { - Spec proj_spec; - proj_spec.set("type",static_type()); - proj_spec.set("latitude1",lat1_); - proj_spec.set("latitude2",lat2_); - proj_spec.set("longitude0",lon0_); - if( radius_ != util::Earth::radiusInMeters() ) proj_spec.set("radius",radius_); - return proj_spec; + Spec proj_spec; + proj_spec.set( "type", static_type() ); + proj_spec.set( "latitude1", lat1_ ); + proj_spec.set( "latitude2", lat2_ ); + proj_spec.set( "longitude0", lon0_ ); + if ( radius_ != util::Earth::radiusInMeters() ) proj_spec.set( "radius", radius_ ); + return proj_spec; } void LambertProjection::hash( eckit::Hash& hsh ) const { - hsh.add(static_type()); - hsh.add(lat1_); - hsh.add(lat2_); - hsh.add(lon0_); - hsh.add(radius_); + hsh.add( static_type() ); + hsh.add( lat1_ ); + hsh.add( lat2_ ); + hsh.add( lon0_ ); + hsh.add( radius_ ); } -register_BuilderT1(ProjectionImpl,LambertProjection,LambertProjection::static_type()); +register_BuilderT1( ProjectionImpl, LambertProjection, LambertProjection::static_type() ); } // namespace detail } // namespace projection diff --git a/src/atlas/projection/detail/LambertProjection.h b/src/atlas/projection/detail/LambertProjection.h index 904f478f8..9e80cc569 100644 --- a/src/atlas/projection/detail/LambertProjection.h +++ b/src/atlas/projection/detail/LambertProjection.h @@ -6,25 +6,25 @@ namespace atlas { namespace projection { namespace detail { -class LambertProjection: public ProjectionImpl { - +class LambertProjection : public ProjectionImpl { public: - // constructor - LambertProjection(const eckit::Parametrisation& p); + LambertProjection( const eckit::Parametrisation& p ); // destructor ~LambertProjection() {} // class name - static std::string static_type() {return "lambert";} - virtual std::string type() const override {return static_type();} + static std::string static_type() { return "lambert"; } + virtual 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; + virtual void xy2lonlat( double crd[] ) const override; + virtual void lonlat2xy( double crd[] ) const override; - virtual bool strictlyRegional() const override { return true; } // lambert projection cannot be used for global grids + virtual bool strictlyRegional() const override { + return true; + } // lambert projection cannot be used for global grids // specification virtual Spec spec() const override; @@ -34,12 +34,13 @@ class LambertProjection: public ProjectionImpl { virtual void hash( eckit::Hash& ) const override; private: - - double lat1_, lat2_; // First and second latitude at which the secant cone cuts the sphere - bool is_tangent_; // If the first and second latitude are equal, then the projection is on a tangent cone - double lon0_; // central longitude - double radius_; // sphere radius - double n_, inv_n_, F_, rho0_, sign_; // projection constants + double lat1_, lat2_; // First and second latitude at which the secant cone + // cuts the sphere + bool is_tangent_; // If the first and second latitude are equal, then the + // projection is on a tangent cone + double lon0_; // central longitude + double radius_; // sphere radius + double n_, inv_n_, F_, rho0_, sign_; // projection constants void setup(); }; diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index 6b196feff..7b17d5d33 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -6,28 +6,26 @@ namespace detail { template LonLatProjectionT::LonLatProjectionT( const eckit::Parametrisation& config ) : - ProjectionImpl(), - rotation_(config) { -} + ProjectionImpl(), + rotation_( config ) {} template typename LonLatProjectionT::Spec LonLatProjectionT::spec() const { - Spec proj_spec; - proj_spec.set("type",static_type()); - rotation_.spec(proj_spec); - return proj_spec; + Spec proj_spec; + proj_spec.set( "type", static_type() ); + rotation_.spec( proj_spec ); + return proj_spec; } template void LonLatProjectionT::hash( eckit::Hash& hsh ) const { - hsh.add(static_type()); - rotation_.hash(hsh); + hsh.add( static_type() ); + rotation_.hash( hsh ); } -register_BuilderT1(ProjectionImpl,LonLatProjection,LonLatProjection::static_type()); -register_BuilderT1(ProjectionImpl,RotatedLonLatProjection,RotatedLonLatProjection::static_type()); +register_BuilderT1( ProjectionImpl, LonLatProjection, LonLatProjection::static_type() ); +register_BuilderT1( ProjectionImpl, RotatedLonLatProjection, RotatedLonLatProjection::static_type() ); } // namespace detail } // namespace projection } // namespace atlas - diff --git a/src/atlas/projection/detail/LonLatProjection.h b/src/atlas/projection/detail/LonLatProjection.h index 79ece7eb7..987db83de 100644 --- a/src/atlas/projection/detail/LonLatProjection.h +++ b/src/atlas/projection/detail/LonLatProjection.h @@ -9,46 +9,42 @@ namespace detail { template class LonLatProjectionT : public ProjectionImpl { - private: - friend class ProjectionImpl; - LonLatProjectionT(): ProjectionImpl() {} + friend class ProjectionImpl; + LonLatProjectionT() : ProjectionImpl() {} public: + // constructor + LonLatProjectionT( const eckit::Parametrisation& ); - // constructor - LonLatProjectionT( const eckit::Parametrisation& ); - - // destructor - ~LonLatProjectionT() {} + // destructor + ~LonLatProjectionT() {} - // class name - static std::string static_type() { return Rotation::typePrefix()+"lonlat"; } - virtual std::string type() const override { return static_type(); } + // class name + static std::string static_type() { return Rotation::typePrefix() + "lonlat"; } + virtual 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); } + // projection and inverse projection + virtual void xy2lonlat( double crd[] ) const override { rotation_.rotate( crd ); } + virtual void lonlat2xy( double crd[] ) const override { rotation_.unrotate( crd ); } - virtual bool strictlyRegional() const override { return false; } + virtual bool strictlyRegional() const override { return false; } - // specification - virtual Spec spec() const override; + // specification + virtual Spec spec() const override; - virtual std::string units() const override { return "degrees"; } + virtual std::string units() const override { return "degrees"; } - virtual operator bool() const override { return rotation_.rotated(); } + virtual operator bool() const override { return rotation_.rotated(); } - virtual void hash( eckit::Hash& ) const override; + virtual void hash( eckit::Hash& ) const override; private: - - Rotation rotation_; - + Rotation rotation_; }; typedef LonLatProjectionT LonLatProjection; -typedef LonLatProjectionT RotatedLonLatProjection; +typedef LonLatProjectionT RotatedLonLatProjection; // -------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/projection/detail/MercatorProjection.cc b/src/atlas/projection/detail/MercatorProjection.cc index 6282c3d90..30459d4df 100644 --- a/src/atlas/projection/detail/MercatorProjection.cc +++ b/src/atlas/projection/detail/MercatorProjection.cc @@ -1,23 +1,24 @@ -#include #include "atlas/projection/detail/MercatorProjection.h" +#include #include "atlas/util/Constants.h" #include "atlas/util/Earth.h" /* -Projection formula's for Mercator projection from "Map Projections: A Working Manual" +Projection formula's for Mercator projection from "Map Projections: A Working +Manual" The origin of the xy-system is at (lon0,0) */ namespace { - static double D2R(const double x) { - return atlas::util::Constants::degreesToRadians()*x; - } - static double R2D(const double x) { - return atlas::util::Constants::radiansToDegrees()*x; - } +static double D2R( const double x ) { + return atlas::util::Constants::degreesToRadians() * x; +} +static double R2D( const double x ) { + return atlas::util::Constants::radiansToDegrees() * x; } +} // namespace namespace atlas { namespace projection { @@ -25,66 +26,59 @@ namespace detail { // constructors template -MercatorProjectionT::MercatorProjectionT(const eckit::Parametrisation& params) : - ProjectionImpl(), - rotation_(params) { - - // check presence of radius - if( ! params.get("radius",radius_) ) - radius_=util::Earth::radiusInMeters(); - // check presence of lon0 - if( ! params.get("longitude0",lon0_) ) - lon0_=0.0; - - inv_radius_ = 1./radius_; +MercatorProjectionT::MercatorProjectionT( const eckit::Parametrisation& params ) : + ProjectionImpl(), + rotation_( params ) { + // check presence of radius + if ( !params.get( "radius", radius_ ) ) radius_ = util::Earth::radiusInMeters(); + // check presence of lon0 + if ( !params.get( "longitude0", lon0_ ) ) lon0_ = 0.0; + + inv_radius_ = 1. / radius_; } template -void MercatorProjectionT::lonlat2xy(double crd[]) const { +void MercatorProjectionT::lonlat2xy( double crd[] ) const { + // first unrotate + rotation_.unrotate( crd ); - // first unrotate - rotation_.unrotate(crd); - - // then project - crd[0] = radius_*(D2R(crd[0]-lon0_)); - crd[1] = radius_*std::log(std::tan(D2R(45.+crd[1]*0.5))); + // then project + crd[0] = radius_ * ( D2R( crd[0] - lon0_ ) ); + crd[1] = radius_ * std::log( std::tan( D2R( 45. + crd[1] * 0.5 ) ) ); } template -void MercatorProjectionT::xy2lonlat(double crd[]) const { - - // first projection - crd[0] = lon0_ + R2D(crd[0]*inv_radius_); - crd[1] = 2.*R2D(std::atan(std::exp(crd[1]*inv_radius_)))-90.; +void MercatorProjectionT::xy2lonlat( double crd[] ) const { + // first projection + crd[0] = lon0_ + R2D( crd[0] * inv_radius_ ); + crd[1] = 2. * R2D( std::atan( std::exp( crd[1] * inv_radius_ ) ) ) - 90.; - // then rotate - rotation_.rotate(crd); + // then rotate + rotation_.rotate( crd ); } - // specification template typename MercatorProjectionT::Spec MercatorProjectionT::spec() const { - Spec proj_spec; - proj_spec.set("type",static_type()); - proj_spec.set("longitude0",lon0_); - if( radius_ != util::Earth::radiusInMeters() ) proj_spec.set("radius",radius_); - rotation_.spec(proj_spec); - return proj_spec; + Spec proj_spec; + proj_spec.set( "type", static_type() ); + proj_spec.set( "longitude0", lon0_ ); + if ( radius_ != util::Earth::radiusInMeters() ) proj_spec.set( "radius", radius_ ); + rotation_.spec( proj_spec ); + return proj_spec; } template void MercatorProjectionT::hash( eckit::Hash& hsh ) const { - hsh.add(static_type()); - rotation_.hash(hsh); - hsh.add(lon0_); - hsh.add(radius_); + hsh.add( static_type() ); + rotation_.hash( hsh ); + hsh.add( lon0_ ); + hsh.add( radius_ ); } -register_BuilderT1(ProjectionImpl,MercatorProjection,MercatorProjection::static_type()); -register_BuilderT1(ProjectionImpl,RotatedMercatorProjection,RotatedMercatorProjection::static_type()); +register_BuilderT1( ProjectionImpl, MercatorProjection, MercatorProjection::static_type() ); +register_BuilderT1( ProjectionImpl, RotatedMercatorProjection, RotatedMercatorProjection::static_type() ); } // namespace detail } // namespace projection } // namespace atlas - diff --git a/src/atlas/projection/detail/MercatorProjection.h b/src/atlas/projection/detail/MercatorProjection.h index ae9a4a414..b52d17651 100644 --- a/src/atlas/projection/detail/MercatorProjection.h +++ b/src/atlas/projection/detail/MercatorProjection.h @@ -7,47 +7,43 @@ namespace projection { namespace detail { template -class MercatorProjectionT: public ProjectionImpl { - +class MercatorProjectionT : public ProjectionImpl { public: - // constructor - MercatorProjectionT(const eckit::Parametrisation& p); + MercatorProjectionT( const eckit::Parametrisation& p ); // class name - static std::string static_type() { return Rotation::typePrefix()+"mercator"; } + static std::string static_type() { return Rotation::typePrefix() + "mercator"; } virtual 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; - - virtual bool strictlyRegional() const override { return true; } // Mercator projection cannot be used for global grids + virtual void xy2lonlat( double crd[] ) const override; + virtual void lonlat2xy( double crd[] ) const override; + + virtual bool strictlyRegional() const override { + return true; + } // Mercator projection cannot be used for global grids // specification virtual Spec spec() const override; virtual std::string units() const override { return "meters"; } - + virtual void hash( eckit::Hash& ) const override; protected: + double lon0_; // central longitude + double radius_; // sphere radius + double inv_radius_; // 1/(sphere radius) - double lon0_; // central longitude - double radius_; // sphere radius - double inv_radius_; // 1/(sphere radius) - - void setup(const eckit::Parametrisation& p); + void setup( const eckit::Parametrisation& p ); private: - - Rotation rotation_; - + Rotation rotation_; }; typedef MercatorProjectionT MercatorProjection; -typedef MercatorProjectionT RotatedMercatorProjection; - +typedef MercatorProjectionT RotatedMercatorProjection; } // namespace detail } // namespace projection diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index 4a71949df..e795e0525 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -7,45 +7,40 @@ namespace projection { namespace detail { ProjectionImpl* ProjectionImpl::create() { - // default: no projection, i.e. stay in (lon,lat)-space - return new LonLatProjection(); + // default: no projection, i.e. stay in (lon,lat)-space + return new LonLatProjection(); } -ProjectionImpl* ProjectionImpl::create(const eckit::Parametrisation& p) { - std::string projectionType; - if (p.get("type",projectionType)) { - return eckit::Factory::instance().get(projectionType).create(p); - } +ProjectionImpl* ProjectionImpl::create( const eckit::Parametrisation& p ) { + std::string projectionType; + if ( p.get( "type", projectionType ) ) { + return eckit::Factory::instance().get( projectionType ).create( p ); + } - // should return error here - throw eckit::BadParameter("type missing in Params",Here()); + // should return error here + throw eckit::BadParameter( "type missing in Params", Here() ); } - Rotated::Rotated( const PointLonLat& south_pole, double rotation_angle ) : - util::Rotation(south_pole,rotation_angle) { -} + util::Rotation( south_pole, rotation_angle ) {} -Rotated::Rotated(const eckit::Parametrisation& p) : - util::Rotation(p){ -} +Rotated::Rotated( const eckit::Parametrisation& p ) : util::Rotation( p ) {} -void Rotated::spec(Spec& s) const { - std::vector npole{ northPole().lon(), northPole().lat() }; - std::vector spole{ southPole().lon(), southPole().lat() }; - s.set("north_pole",npole); - s.set("south_pole",spole); - s.set("rotation_angle",rotationAngle()); +void Rotated::spec( Spec& s ) const { + std::vector npole{northPole().lon(), northPole().lat()}; + std::vector spole{southPole().lon(), southPole().lat()}; + s.set( "north_pole", npole ); + s.set( "south_pole", spole ); + s.set( "rotation_angle", rotationAngle() ); } void Rotated::hash( eckit::Hash& hsh ) const { - hsh.add("rotated"); - hsh.add(southPole().lon()); - hsh.add(southPole().lat()); - hsh.add(rotationAngle()); + hsh.add( "rotated" ); + hsh.add( southPole().lon() ); + hsh.add( southPole().lat() ); + 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 a0151aeea..e3229b015 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -1,104 +1,98 @@ #pragma once #include +#include "atlas/util/Config.h" +#include "atlas/util/Point.h" +#include "atlas/util/Rotation.h" #include "eckit/config/Parametrisation.h" #include "eckit/memory/Builder.h" #include "eckit/memory/Owned.h" #include "eckit/utils/Hash.h" -#include "atlas/util/Rotation.h" -#include "atlas/util/Point.h" -#include "atlas/util/Config.h" namespace atlas { namespace projection { namespace detail { class ProjectionImpl : public eckit::Owned { - public: - - using ARG1 = const eckit::Parametrisation&; - using builder_t = eckit::BuilderT1; - using Spec = atlas::util::Config; - static std::string className() {return "atlas.Projection";} + using ARG1 = const eckit::Parametrisation&; + using builder_t = eckit::BuilderT1; + using Spec = atlas::util::Config; + static std::string className() { return "atlas.Projection"; } public: - - static ProjectionImpl* create(); // creates the LonLatProjection - static ProjectionImpl* create(const eckit::Parametrisation& p); + static ProjectionImpl* create(); // creates the LonLatProjection + static ProjectionImpl* create( const eckit::Parametrisation& p ); ProjectionImpl() {} - virtual ~ProjectionImpl() {} // destructor should be virtual + virtual ~ProjectionImpl() {} // destructor should be virtual - virtual std::string type() const =0; + virtual std::string type() const = 0; - virtual void xy2lonlat(double crd[]) const =0; - virtual void lonlat2xy(double crd[]) const =0; + virtual void xy2lonlat( double crd[] ) const = 0; + virtual void lonlat2xy( double crd[] ) const = 0; PointLonLat lonlat( const PointXY& ) const; PointXY xy( const PointLonLat& ) const; - virtual bool strictlyRegional() const =0; + virtual bool strictlyRegional() const = 0; - virtual Spec spec() const =0; + virtual Spec spec() const = 0; - virtual std::string units() const =0; + virtual std::string units() const = 0; virtual operator bool() const { return true; } - - virtual void hash( eckit::Hash& ) const=0; + virtual void hash( eckit::Hash& ) const = 0; }; inline PointLonLat ProjectionImpl::lonlat( const PointXY& xy ) const { - PointLonLat lonlat(xy); - xy2lonlat(lonlat.data()); - return lonlat; + PointLonLat lonlat( xy ); + xy2lonlat( lonlat.data() ); + return lonlat; } inline PointXY ProjectionImpl::xy( const PointLonLat& lonlat ) const { - PointXY xy(lonlat); - lonlat2xy(xy.data()); - return xy; + PointXY xy( lonlat ); + lonlat2xy( xy.data() ); + 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() {} - + static std::string classNamePrefix() { return "Rotated"; } static std::string typePrefix() { return "rotated_"; } - void spec(Spec&) const; + void spec( Spec& ) const; void hash( eckit::Hash& ) const; }; - class NotRotated { - public: - using Spec = ProjectionImpl::Spec; NotRotated() {} NotRotated( const eckit::Parametrisation& ) {} virtual ~NotRotated() {} - - static std::string classNamePrefix() { return ""; } // deliberately empty - static std::string typePrefix() { return ""; } // deliberately empty - void rotate(double crd[]) const { /* do nothing */ } - void unrotate(double crd[]) const { /* do nothing */ } - + static std::string classNamePrefix() { return ""; } // deliberately empty + static std::string typePrefix() { return ""; } // deliberately empty + + void rotate( double crd[] ) const { /* do nothing */ + } + void unrotate( double crd[] ) const { /* do nothing */ + } + bool rotated() const { return false; } - void spec(Spec&) const {} + void spec( Spec& ) const {} void hash( eckit::Hash& ) const {} }; diff --git a/src/atlas/projection/detail/SchmidtProjection.cc b/src/atlas/projection/detail/SchmidtProjection.cc index 8618051ca..2c943327f 100644 --- a/src/atlas/projection/detail/SchmidtProjection.cc +++ b/src/atlas/projection/detail/SchmidtProjection.cc @@ -1,15 +1,15 @@ -#include #include "atlas/projection/detail/SchmidtProjection.h" +#include #include "atlas/util/Constants.h" namespace { - static double D2R(const double x) { - return atlas::util::Constants::degreesToRadians()*x; - } - static double R2D(const double x) { - return atlas::util::Constants::radiansToDegrees()*x; - } +static double D2R( const double x ) { + return atlas::util::Constants::degreesToRadians() * x; +} +static double R2D( const double x ) { + return atlas::util::Constants::radiansToDegrees() * x; } +} // namespace namespace atlas { namespace projection { @@ -17,52 +17,52 @@ namespace detail { // constructor template -SchmidtProjectionT::SchmidtProjectionT(const eckit::Parametrisation& params) : - ProjectionImpl(), - rotation_(params) { - if( ! params.get("stretching_factor",c_) ) - throw eckit::BadParameter("stretching_factor missing in Params",Here()); +SchmidtProjectionT::SchmidtProjectionT( const eckit::Parametrisation& params ) : + ProjectionImpl(), + rotation_( params ) { + if ( !params.get( "stretching_factor", c_ ) ) + throw eckit::BadParameter( "stretching_factor missing in Params", Here() ); } template -void SchmidtProjectionT::xy2lonlat(double crd[]) const { +void SchmidtProjectionT::xy2lonlat( double crd[] ) const { + // stretch + crd[1] = R2D( + std::asin( std::cos( 2. * std::atan( 1 / c_ * std::tan( std::acos( std::sin( D2R( crd[1] ) ) ) * 0.5 ) ) ) ) ); - // stretch - crd[1]=R2D(std::asin(std::cos(2.*std::atan(1/c_*std::tan(std::acos(std::sin(D2R(crd[1])))*0.5))))); - - // perform rotation - rotation_.rotate(crd); + // perform rotation + rotation_.rotate( crd ); } template -void SchmidtProjectionT::lonlat2xy(double crd[]) const { - - // inverse rotation - rotation_.unrotate(crd); +void SchmidtProjectionT::lonlat2xy( double crd[] ) const { + // inverse rotation + rotation_.unrotate( crd ); - // unstretch - crd[1]=R2D(std::asin(std::cos(2.*std::atan(c_*std::tan(std::acos(std::sin(D2R(crd[1])))*0.5))))); + // unstretch + crd[1] = + R2D( std::asin( std::cos( 2. * std::atan( c_ * std::tan( std::acos( std::sin( D2R( crd[1] ) ) ) * 0.5 ) ) ) ) ); } // specification template typename SchmidtProjectionT::Spec SchmidtProjectionT::spec() const { - Spec proj_spec; - proj_spec.set("type",static_type()); - proj_spec.set("stretching_factor",c_); - rotation_.spec(proj_spec); - return proj_spec; + Spec proj_spec; + proj_spec.set( "type", static_type() ); + proj_spec.set( "stretching_factor", c_ ); + rotation_.spec( proj_spec ); + return proj_spec; } template void SchmidtProjectionT::hash( eckit::Hash& hsh ) const { - hsh.add(static_type()); - rotation_.hash(hsh); - hsh.add(c_); + hsh.add( static_type() ); + rotation_.hash( hsh ); + hsh.add( c_ ); } -register_BuilderT1(ProjectionImpl,SchmidtProjection,SchmidtProjection::static_type()); -register_BuilderT1(ProjectionImpl,RotatedSchmidtProjection,RotatedSchmidtProjection::static_type()); +register_BuilderT1( ProjectionImpl, SchmidtProjection, SchmidtProjection::static_type() ); +register_BuilderT1( ProjectionImpl, RotatedSchmidtProjection, RotatedSchmidtProjection::static_type() ); } // namespace detail } // namespace projection diff --git a/src/atlas/projection/detail/SchmidtProjection.h b/src/atlas/projection/detail/SchmidtProjection.h index f07ad2c52..8e9003d48 100644 --- a/src/atlas/projection/detail/SchmidtProjection.h +++ b/src/atlas/projection/detail/SchmidtProjection.h @@ -7,21 +7,19 @@ namespace projection { namespace detail { template -class SchmidtProjectionT: public ProjectionImpl { - +class SchmidtProjectionT : public ProjectionImpl { public: - // constructor - SchmidtProjectionT(const eckit::Parametrisation& p); + SchmidtProjectionT( const eckit::Parametrisation& p ); SchmidtProjectionT() {} // class name - static std::string static_type() { return Rotation::typePrefix()+"schmidt"; } + static std::string static_type() { return Rotation::typePrefix() + "schmidt"; } virtual 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; + virtual void xy2lonlat( double crd[] ) const override; + virtual void lonlat2xy( double crd[] ) const override; virtual bool strictlyRegional() const override { return false; } // schmidt is global grid @@ -33,14 +31,12 @@ class SchmidtProjectionT: public ProjectionImpl { virtual void hash( eckit::Hash& ) const override; private: - - double c_; // stretching factor + double c_; // stretching factor Rotation rotation_; - }; typedef SchmidtProjectionT SchmidtProjection; -typedef SchmidtProjectionT RotatedSchmidtProjection; +typedef SchmidtProjectionT RotatedSchmidtProjection; } // namespace detail } // namespace projection diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index 848fb5b11..b44cf5c0c 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -2,221 +2,194 @@ #include "eckit/config/LibEcKit.h" +#include "atlas/library/config.h" +#include "atlas/runtime/AtlasTool.h" #include "eckit/log/FileTarget.h" #include "eckit/log/PrefixTarget.h" -#include "atlas/runtime/AtlasTool.h" -#include "atlas/library/config.h" - namespace { -int digits(int number) { - int d = 0; - while( number ) { - number /= 10; - d++; - } - return d; +int digits( int number ) { + int d = 0; + while ( number ) { + number /= 10; + d++; + } + return d; } -static std::string debug_prefix(const std::string& libname) { - std::string s = libname; - std::transform(s.begin(), s.end(), s.begin(), ::toupper); - s += "_DEBUG"; - return s; +static std::string debug_prefix( const std::string& libname ) { + std::string s = libname; + std::transform( s.begin(), s.end(), s.begin(), ::toupper ); + s += "_DEBUG"; + return s; } -void debug_addTarget(eckit::LogTarget* target) { - for( std::string libname : eckit::system::Library::list() ) { - const eckit::system::Library& lib = eckit::system::Library::lookup(libname); - if( lib.debug() ) { - lib.debugChannel().addTarget( new eckit::PrefixTarget(debug_prefix(libname), target ) ); +void debug_addTarget( eckit::LogTarget* target ) { + for ( std::string libname : eckit::system::Library::list() ) { + const eckit::system::Library& lib = eckit::system::Library::lookup( libname ); + if ( lib.debug() ) { + 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) { - for( std::string libname : eckit::system::Library::list() ) { - const eckit::system::Library& lib = eckit::system::Library::lookup(libname); - if( lib.debug() ) { - lib.debugChannel().setTarget( new eckit::PrefixTarget(debug_prefix(libname), target ) ); +void debug_setTarget( eckit::LogTarget* target ) { + for ( std::string libname : eckit::system::Library::list() ) { + const eckit::system::Library& lib = eckit::system::Library::lookup( libname ); + if ( lib.debug() ) { + 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(); + 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( 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; } -} +} // namespace -void atlas::AtlasTool::add_option(eckit::option::Option *option) -{ - options_.push_back( option ); +void atlas::AtlasTool::add_option( eckit::option::Option* option ) { + options_.push_back( option ); } -void atlas::AtlasTool::help(std::ostream &out) -{ - out << "NAME\n" << indent() << name(); - std::string brief = briefDescription(); - if ( brief.size() ) out << " - " << brief << '\n'; +void atlas::AtlasTool::help( std::ostream& out ) { + out << "NAME\n" << indent() << name(); + std::string brief = briefDescription(); + if ( brief.size() ) out << " - " << brief << '\n'; - std::string usg = usage(); - if ( usg.size() ) { - out << '\n'; - out << "SYNOPSIS\n" << indent() << usg << '\n'; - } - std::string desc = longDescription(); - if ( desc.size() ) { + std::string usg = usage(); + if ( usg.size() ) { + out << '\n'; + out << "SYNOPSIS\n" << indent() << usg << '\n'; + } + std::string desc = longDescription(); + if ( desc.size() ) { + out << '\n'; + out << "DESCRIPTION\n" << indent() << desc << '\n'; + } out << '\n'; - out << "DESCRIPTION\n" << indent() << desc << '\n'; - } - out << '\n'; - out << "OPTIONS\n"; - for( Options::const_iterator it = options_.begin(); it!= options_.end(); ++it ) { - out << indent() << (**it) << "\n\n"; - } - out << std::flush; + out << "OPTIONS\n"; + for ( Options::const_iterator it = options_.begin(); it != options_.end(); ++it ) { + out << indent() << ( **it ) << "\n\n"; + } + out << std::flush; } -bool atlas::AtlasTool::handle_help() -{ - for( int i=1; i("help","Print this help") ); - add_option( new SimpleOption("debug","Debug level") ); - taskID( eckit::mpi::comm("world").rank()); + add_option( new SimpleOption( "help", "Print this help" ) ); + add_option( new SimpleOption( "debug", "Debug level" ) ); + taskID( eckit::mpi::comm( "world" ).rank() ); } -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; - } - 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(); - } - - return status; -} +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; + } + 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; - - if( argc()-1 < minimumPositionalArguments() ) - { - if( taskID() == 0 ) - std::cout << "Usage: " << usage() << std::endl; - return; - } - Options opts = options_; - Args args(&atlas::usage, - opts, - numberOfPositionalArguments(), - minimumPositionalArguments()); - - atlas::Library::instance().initialise(); - setupLogging(); - execute(args); - atlas::Library::instance().finalise(); + return status; } -void atlas::AtlasTool::setupLogging() -{ - int log_rank = getEnv( "ATLAS_LOG_RANK", 0 ); - bool use_logfile = getEnv( "ATLAS_LOG_FILE", false ); - - if( use_logfile ) { +void atlas::AtlasTool::run() { + if ( handle_help() ) return; - int d = digits(mpi::comm().size()); - std::string rankstr = std::to_string(taskID()); - for( int i = rankstr.size(); i #include +#include #include "eckit/option/CmdArgs.h" #include "eckit/option/Separator.h" @@ -26,60 +27,53 @@ //-------------------------------------------------------------------------------- -using eckit::option::SimpleOption; -using eckit::option::VectorOption; -using eckit::option::Separator; +using atlas::util::Config; using eckit::option::CmdArgs; using eckit::option::Option; -using atlas::util::Config; +using eckit::option::Separator; +using eckit::option::SimpleOption; +using eckit::option::VectorOption; namespace atlas { -static void usage( const std::string& name ) -{ - Log::info() << "dummy usage" << std::endl; +static void usage( const std::string& name ) { + Log::info() << "dummy usage" << std::endl; } class AtlasTool : public eckit::Tool { - - protected: + typedef std::vector Options; + typedef eckit::option::CmdArgs Args; - typedef std::vector Options; - typedef eckit::option::CmdArgs Args; + virtual bool serial() { return false; } + virtual std::string indent() { return " "; } + virtual std::string briefDescription() { return ""; } + virtual std::string longDescription() { return ""; } + virtual std::string usage() { return name() + " [OPTION]... [--help,-h] [--debug]"; } - virtual bool serial() { return false; } - virtual std::string indent() { return " "; } - virtual std::string briefDescription() { return ""; } - virtual std::string longDescription() { return ""; } - virtual std::string usage() { return name() + " [OPTION]... [--help,-h] [--debug]"; } + void add_option( eckit::option::Option* option ); + virtual void help( std::ostream& out = Log::info() ); - void add_option( eckit::option::Option* option ); + virtual int numberOfPositionalArguments() { return -1; } + virtual int minimumPositionalArguments() { return 0; } - virtual void help( std::ostream &out = Log::info() ); - - virtual int numberOfPositionalArguments() { return -1; } - virtual int minimumPositionalArguments() { return 0; } - - bool handle_help(); + bool handle_help(); public: + AtlasTool( int argc, char** argv ); - AtlasTool(int argc,char **argv); + int start(); - int start(); + virtual void run(); - virtual void run(); - - virtual void execute(const Args&) = 0; + virtual void execute( const Args& ) = 0; private: - - void setupLogging(); + void setupLogging(); private: - Options options_; + Options options_; }; -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/runtime/ErrorHandling.cc b/src/atlas/runtime/ErrorHandling.cc index 70226ee9f..88e00333c 100644 --- a/src/atlas/runtime/ErrorHandling.cc +++ b/src/atlas/runtime/ErrorHandling.cc @@ -1,215 +1,181 @@ +#include "atlas/runtime/ErrorHandling.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Log.h" #include "eckit/log/CodeLocation.h" #include "eckit/os/BackTrace.h" #include "eckit/utils/Translator.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/runtime/Log.h" -#include "atlas/runtime/ErrorHandling.h" using namespace atlas; -namespace { // anonymous +namespace { // anonymous template -static bool get_env(const std::string& var,T& val){ - const char* env = ::getenv(var.c_str()); - if( env ) { - std::string val_str = env; - val = eckit::Translator()(val_str); - return true; - } - return false; +static bool get_env( const std::string& var, T& val ) { + const char* env = ::getenv( var.c_str() ); + if ( env ) { + std::string val_str = env; + val = eckit::Translator()( val_str ); + return true; + } + return false; } -} // namespace anonymous +} // namespace namespace atlas { namespace runtime { -Error::Error() -{ - clear(); - throws_ = false; - aborts_ = true; - backtrace_ = true; - get_env("ATLAS_ERROR_THROWS",throws_); - get_env("ATLAS_ERROR_ABORTS",aborts_); - get_env("ATLAS_ERROR_BACKTRACE",backtrace_); -} - -Error& Error::instance() -{ - static Error error_instance; - return error_instance; -} - -void Error::clear() -{ - code_ = atlas_err_cleared; - msg_ = std::string("Error code was not set!"); -} - -void handle_error(const eckit::Exception& exception, const int errorCode) -{ - std::stringstream msg; - if( Error::instance().backtrace() || Error::instance().aborts() ) - { - msg << "=========================================\n" - << "ERROR\n" - << "-----------------------------------------\n" - << exception.what() << "\n"; - if( exception.location() ) - msg << "-----------------------------------------\n" - << "LOCATION: " << exception.location() << "\n"; - - - msg << "-----------------------------------------\n" - << "BACKTRACE\n" - << "-----------------------------------------\n" - << exception.callStack() << "\n" - << "========================================="; - } - else - { - msg << exception.what(); - } - Error::instance().set_code(errorCode); - Error::instance().set_msg(msg.str()); - - if( Error::instance().aborts() ) - { - Log::error() << msg.str() << std::endl; - mpi::comm().abort(errorCode); - } - if( Error::instance().throws() ) - { - throw exception; - } - -} - -} // namespace runtime -} // namespace atlas +Error::Error() { + clear(); + throws_ = false; + aborts_ = true; + backtrace_ = true; + get_env( "ATLAS_ERROR_THROWS", throws_ ); + get_env( "ATLAS_ERROR_ABORTS", aborts_ ); + get_env( "ATLAS_ERROR_BACKTRACE", backtrace_ ); +} + +Error& Error::instance() { + static Error error_instance; + return error_instance; +} + +void Error::clear() { + code_ = atlas_err_cleared; + msg_ = std::string( "Error code was not set!" ); +} + +void handle_error( const eckit::Exception& exception, const int errorCode ) { + std::stringstream msg; + if ( Error::instance().backtrace() || Error::instance().aborts() ) { + msg << "=========================================\n" + << "ERROR\n" + << "-----------------------------------------\n" + << exception.what() << "\n"; + if ( exception.location() ) + msg << "-----------------------------------------\n" + << "LOCATION: " << exception.location() << "\n"; + + msg << "-----------------------------------------\n" + << "BACKTRACE\n" + << "-----------------------------------------\n" + << exception.callStack() << "\n" + << "========================================="; + } + else { + msg << exception.what(); + } + Error::instance().set_code( errorCode ); + Error::instance().set_msg( msg.str() ); + + if ( Error::instance().aborts() ) { + Log::error() << msg.str() << std::endl; + mpi::comm().abort( errorCode ); + } + if ( Error::instance().throws() ) { throw exception; } +} + +} // namespace runtime +} // namespace atlas +using eckit::AssertionFailed; +using eckit::BackTrace; using eckit::CodeLocation; using eckit::Exception; -using eckit::BackTrace; using eckit::Exception; using eckit::NotImplemented; using eckit::OutOfRange; -using eckit::UserError; -using eckit::AssertionFailed; using eckit::SeriousBug; +using eckit::UserError; - -void atlas__Error_set_aborts (int on_off) -{ - atlas::runtime::Error::instance().set_aborts(on_off); +void atlas__Error_set_aborts( int on_off ) { + atlas::runtime::Error::instance().set_aborts( on_off ); } -void atlas__Error_set_throws (int on_off) -{ - atlas::runtime::Error::instance().set_throws(on_off); +void atlas__Error_set_throws( int on_off ) { + atlas::runtime::Error::instance().set_throws( on_off ); } -void atlas__Error_set_backtrace (int on_off) -{ - atlas::runtime::Error::instance().set_backtrace(on_off); +void atlas__Error_set_backtrace( int on_off ) { + atlas::runtime::Error::instance().set_backtrace( on_off ); } -void atlas__Error_success () -{ - atlas::runtime::Error::instance().set_code(atlas::runtime::atlas_err_noerr); - atlas::runtime::Error::instance().set_msg(std::string()); +void atlas__Error_success() { + atlas::runtime::Error::instance().set_code( atlas::runtime::atlas_err_noerr ); + atlas::runtime::Error::instance().set_msg( std::string() ); } -void atlas__Error_clear () -{ - atlas::runtime::Error::instance().clear(); +void atlas__Error_clear() { + atlas::runtime::Error::instance().clear(); } -int atlas__Error_code() -{ - return atlas::runtime::Error::instance().code(); +int atlas__Error_code() { + return atlas::runtime::Error::instance().code(); } -char* atlas__Error_msg() -{ - return const_cast(atlas::runtime::Error::instance().msg().c_str()); +char* atlas__Error_msg() { + return const_cast( atlas::runtime::Error::instance().msg().c_str() ); } -template< typename EXCEPTION> -EXCEPTION create_exception(char* msg, char* file, int line, char* function) -{ - if( file && std::string(file).size() && std::string(msg).size() ) - return EXCEPTION( std::string(msg), CodeLocation(file,line,function) ); - else if( file && std::string(file).size() ) - return EXCEPTION( std::string(), CodeLocation(file,line,function) ); - else if( std::string(msg).size() ) - return EXCEPTION( std::string(msg), CodeLocation() ); - else - return EXCEPTION( std::string(), CodeLocation() ); +template +EXCEPTION create_exception( char* msg, char* file, int line, char* function ) { + if ( file && std::string( file ).size() && std::string( msg ).size() ) + return EXCEPTION( std::string( msg ), CodeLocation( file, line, function ) ); + else if ( file && std::string( file ).size() ) + return EXCEPTION( std::string(), CodeLocation( file, line, function ) ); + else if ( std::string( msg ).size() ) + return EXCEPTION( std::string( msg ), CodeLocation() ); + else + return EXCEPTION( std::string(), CodeLocation() ); } -void atlas__throw_exception(char* msg, char* file, int line, char* function) -{ - Exception exception ( create_exception(msg,file,line,function) ); - atlas::runtime::handle_error(exception, atlas::runtime::atlas_err_exception); +void atlas__throw_exception( char* msg, char* file, int line, char* function ) { + Exception exception( create_exception( msg, file, line, function ) ); + atlas::runtime::handle_error( exception, atlas::runtime::atlas_err_exception ); } -void atlas__throw_notimplemented (char* msg, char* file, int line, char* function) -{ - NotImplemented exception ( create_exception(msg,file,line,function) ); - atlas::runtime::handle_error(exception, atlas::runtime::atlas_err_notimplemented); +void atlas__throw_notimplemented( char* msg, char* file, int line, char* function ) { + NotImplemented exception( create_exception( msg, file, line, function ) ); + atlas::runtime::handle_error( exception, atlas::runtime::atlas_err_notimplemented ); } -void atlas__throw_outofrange (char* msg, char* file, int line, char* function) -{ - OutOfRange exception ( create_exception(msg,file,line,function) ); - atlas::runtime::handle_error(exception, atlas::runtime::atlas_err_outofrange); +void atlas__throw_outofrange( char* msg, char* file, int line, char* function ) { + OutOfRange exception( create_exception( msg, file, line, function ) ); + atlas::runtime::handle_error( exception, atlas::runtime::atlas_err_outofrange ); } -void atlas__throw_usererror (char* msg, char* file, int line, char* function) -{ - UserError exception ( create_exception(msg,file,line,function) ); - atlas::runtime::handle_error(exception, atlas::runtime::atlas_err_usererror); +void atlas__throw_usererror( char* msg, char* file, int line, char* function ) { + UserError exception( create_exception( msg, file, line, function ) ); + atlas::runtime::handle_error( exception, atlas::runtime::atlas_err_usererror ); } -void atlas__throw_assertionfailed (char* msg, char* file, int line, char* function) -{ - AssertionFailed exception ( create_exception(msg,file,line,function) ); - atlas::runtime::handle_error(exception, atlas::runtime::atlas_err_assertionfailed); +void atlas__throw_assertionfailed( char* msg, char* file, int line, char* function ) { + AssertionFailed exception( create_exception( msg, file, line, function ) ); + atlas::runtime::handle_error( exception, atlas::runtime::atlas_err_assertionfailed ); } -void atlas__throw_seriousbug (char* msg, char* file, int line, char* function) -{ - SeriousBug exception ( create_exception(msg,file,line,function) ); - atlas::runtime::handle_error(exception, atlas::runtime::atlas_err_seriousbug); +void atlas__throw_seriousbug( char* msg, char* file, int line, char* function ) { + SeriousBug exception( create_exception( msg, file, line, function ) ); + atlas::runtime::handle_error( exception, atlas::runtime::atlas_err_seriousbug ); } -void atlas__abort(char* msg, char* file, int line, char* function ) -{ - Log::error() << "=========================================\n" - << "ABORT\n"; - if( msg && std::string(msg).size() ) - Log::error() << "-----------------------------------------\n" - << msg << "\n"; +void atlas__abort( char* msg, char* file, int line, char* function ) { + Log::error() << "=========================================\n" + << "ABORT\n"; + if ( msg && std::string( msg ).size() ) + Log::error() << "-----------------------------------------\n" << msg << "\n"; - if( file && std::string(file).size() ) - Log::error() << "-----------------------------------------\n" - << "LOCATION: " << CodeLocation(file,line,function) << "\n"; + if ( file && std::string( file ).size() ) + Log::error() << "-----------------------------------------\n" + << "LOCATION: " << CodeLocation( file, line, function ) << "\n"; - Log::error() << "-----------------------------------------\n" - << "BACKTRACE\n" - << "-----------------------------------------\n" - << BackTrace::dump() << "\n" - << "=========================================" - << std::endl; + Log::error() << "-----------------------------------------\n" + << "BACKTRACE\n" + << "-----------------------------------------\n" + << BackTrace::dump() << "\n" + << "=========================================" << std::endl; - mpi::comm().abort(-1); + mpi::comm().abort( -1 ); } -void atlas__error_example() -{ - ATLAS_ERROR_HANDLING( - throw OutOfRange(12,5,Here()) - ); +void atlas__error_example() { + ATLAS_ERROR_HANDLING( throw OutOfRange( 12, 5, Here() ) ); } - diff --git a/src/atlas/runtime/ErrorHandling.h b/src/atlas/runtime/ErrorHandling.h index 05dda6a6a..8b083a15a 100644 --- a/src/atlas/runtime/ErrorHandling.h +++ b/src/atlas/runtime/ErrorHandling.h @@ -5,15 +5,15 @@ namespace atlas { namespace runtime { -static const int atlas_err_cleared = 1 ; -static const int atlas_err_noerr = 0 ; -static const int atlas_err_exception = -1 ; -static const int atlas_err_usererror = -2 ; -static const int atlas_err_seriousbug = -3 ; -static const int atlas_err_notimplemented = -4 ; -static const int atlas_err_assertionfailed = -5 ; -static const int atlas_err_badparameter = -6 ; -static const int atlas_err_outofrange = -7 ; +static const int atlas_err_cleared = 1; +static const int atlas_err_noerr = 0; +static const int atlas_err_exception = -1; +static const int atlas_err_usererror = -2; +static const int atlas_err_seriousbug = -3; +static const int atlas_err_notimplemented = -4; +static const int atlas_err_assertionfailed = -5; +static const int atlas_err_badparameter = -6; +static const int atlas_err_outofrange = -7; static const int atlas_err_stop = -100; static const int atlas_err_abort = -101; static const int atlas_err_cancel = -102; @@ -21,80 +21,101 @@ static const int atlas_err_readerror = -200; static const int atlas_err_writeerror = -201; static const int atlas_err_unknown = -999; -void handle_error(const eckit::Exception& exception, const int err_code); - -#define ATLAS_ERROR_HANDLING(STATEMENTS) \ -do { try{ STATEMENTS; } \ -catch (eckit::SeriousBug& e ) { atlas::runtime::handle_error(e, atlas::runtime::atlas_err_seriousbug); } \ -catch (eckit::NotImplemented& e ) { atlas::runtime::handle_error(e, atlas::runtime::atlas_err_notimplemented); } \ -catch (eckit::OutOfRange& e ) { atlas::runtime::handle_error(e, atlas::runtime::atlas_err_outofrange); } \ -catch (eckit::UserError& e ) { atlas::runtime::handle_error(e, atlas::runtime::atlas_err_usererror); } \ -catch (eckit::AssertionFailed& e ) { atlas::runtime::handle_error(e, atlas::runtime::atlas_err_assertionfailed); } \ -catch (eckit::BadParameter& e ) { atlas::runtime::handle_error(e, atlas::runtime::atlas_err_badparameter); } \ -catch (eckit::ReadError& e ) { atlas::runtime::handle_error(e, atlas::runtime::atlas_err_readerror); } \ -catch (eckit::WriteError& e ) { atlas::runtime::handle_error(e, atlas::runtime::atlas_err_writeerror); } \ -catch (eckit::Exception& e ) { atlas::runtime::handle_error(e, atlas::runtime::atlas_err_exception); } \ -catch (...) { atlas::runtime::handle_error(eckit::Exception("Unknown exception"),atlas::runtime::atlas_err_exception); } \ -} while (0) - - -class Error -{ +void handle_error( const eckit::Exception& exception, const int err_code ); + +#define ATLAS_ERROR_HANDLING( STATEMENTS ) \ + do { \ + try { \ + STATEMENTS; \ + } \ + catch ( eckit::SeriousBug & e ) { \ + atlas::runtime::handle_error( e, atlas::runtime::atlas_err_seriousbug ); \ + } \ + catch ( eckit::NotImplemented & e ) { \ + atlas::runtime::handle_error( e, atlas::runtime::atlas_err_notimplemented ); \ + } \ + catch ( eckit::OutOfRange & e ) { \ + atlas::runtime::handle_error( e, atlas::runtime::atlas_err_outofrange ); \ + } \ + catch ( eckit::UserError & e ) { \ + atlas::runtime::handle_error( e, atlas::runtime::atlas_err_usererror ); \ + } \ + catch ( eckit::AssertionFailed & e ) { \ + atlas::runtime::handle_error( e, atlas::runtime::atlas_err_assertionfailed ); \ + } \ + catch ( eckit::BadParameter & e ) { \ + atlas::runtime::handle_error( e, atlas::runtime::atlas_err_badparameter ); \ + } \ + catch ( eckit::ReadError & e ) { \ + atlas::runtime::handle_error( e, atlas::runtime::atlas_err_readerror ); \ + } \ + catch ( eckit::WriteError & e ) { \ + atlas::runtime::handle_error( e, atlas::runtime::atlas_err_writeerror ); \ + } \ + catch ( eckit::Exception & e ) { \ + atlas::runtime::handle_error( e, atlas::runtime::atlas_err_exception ); \ + } \ + catch ( ... ) { \ + atlas::runtime::handle_error( eckit::Exception( "Unknown exception" ), \ + atlas::runtime::atlas_err_exception ); \ + } \ + } while ( 0 ) + +class Error { private: - Error(); + Error(); public: - static Error& instance(); + static Error& instance(); - int code() const { return code_; } + int code() const { return code_; } - const std::string& msg() const { return msg_; } + const std::string& msg() const { return msg_; } - bool throws() const { return throws_; } + bool throws() const { return throws_; } - bool backtrace() const { return backtrace_; } + bool backtrace() const { return backtrace_; } - bool aborts() const { return aborts_; } + bool aborts() const { return aborts_; } - void set_code( int c ) { code_ = c; } + void set_code( int c ) { code_ = c; } - void set_msg( const std::string& m ) { msg_ = m; } + void set_msg( const std::string& m ) { msg_ = m; } - void set_aborts( bool b ) { aborts_ = b; } + void set_aborts( bool b ) { aborts_ = b; } - void set_throws( bool b ) { throws_ = b; } + void set_throws( bool b ) { throws_ = b; } - void set_backtrace( bool b ) { backtrace_ = b; } + void set_backtrace( bool b ) { backtrace_ = b; } - void clear(); + void clear(); private: - std::string msg_; - int code_; - bool aborts_; - bool throws_; - bool backtrace_; + std::string msg_; + int code_; + bool aborts_; + bool throws_; + bool backtrace_; }; -} // namespace runtime -} // namespace atlas - -extern "C" -{ - void atlas__abort (char* msg, char* file, int line, char* function); - void atlas__throw_exception (char* msg, char* file, int line, char* function); - void atlas__throw_notimplemented (char* msg, char* file, int line, char* function); - void atlas__throw_outofrange (char* msg, char* file, int line, char* function); - void atlas__throw_seriousbug (char* msg, char* file, int line, char* function); - void atlas__throw_usererror (char* msg, char* file, int line, char* function); - void atlas__throw_assertionfailed (char* msg, char* file, int line, char* function); - void atlas__throw_ (char* msg, char* file, int line, char* function); - int atlas__Error_code (); - void atlas__Error_clear (); - void atlas__Error_success (); - void atlas__Error_set_aborts (int on_off); - void atlas__Error_set_throws (int on_off); - void atlas__Error_set_backtrace (int on_off); - char* atlas__Error_msg (); - void atlas__error_example(); +} // namespace runtime +} // namespace atlas + +extern "C" { +void atlas__abort( char* msg, char* file, int line, char* function ); +void atlas__throw_exception( char* msg, char* file, int line, char* function ); +void atlas__throw_notimplemented( char* msg, char* file, int line, char* function ); +void atlas__throw_outofrange( char* msg, char* file, int line, char* function ); +void atlas__throw_seriousbug( char* msg, char* file, int line, char* function ); +void atlas__throw_usererror( char* msg, char* file, int line, char* function ); +void atlas__throw_assertionfailed( char* msg, char* file, int line, char* function ); +void atlas__throw_( char* msg, char* file, int line, char* function ); +int atlas__Error_code(); +void atlas__Error_clear(); +void atlas__Error_success(); +void atlas__Error_set_aborts( int on_off ); +void atlas__Error_set_throws( int on_off ); +void atlas__Error_set_backtrace( int on_off ); +char* atlas__Error_msg(); +void atlas__error_example(); } diff --git a/src/atlas/runtime/Log.cc b/src/atlas/runtime/Log.cc index d95e69e04..ed39f363a 100644 --- a/src/atlas/runtime/Log.cc +++ b/src/atlas/runtime/Log.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,23 +16,23 @@ namespace atlas { std::string backtrace() { - return eckit::BackTrace::dump(); + return eckit::BackTrace::dump(); } namespace detail { void debug_parallel_here( const eckit::CodeLocation& here ) { - const auto& comm = mpi::comm(); - comm.barrier(); - Log::info() << "DEBUG_PARALLEL() @ " << here << std::endl; + const auto& comm = mpi::comm(); + comm.barrier(); + Log::info() << "DEBUG_PARALLEL() @ " << here << std::endl; } void debug_parallel_what( const eckit::CodeLocation& here, const std::string& what ) { - const auto& comm = mpi::comm(); - comm.barrier(); - Log::info() << "DEBUG_PARALLEL(" << what << ") @ " << here << std::endl; + const auto& comm = mpi::comm(); + comm.barrier(); + Log::info() << "DEBUG_PARALLEL(" << what << ") @ " << here << std::endl; } -} // namespace detail +} // namespace detail -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/runtime/Log.h b/src/atlas/runtime/Log.h index d05a71bfe..9fc10bc10 100644 --- a/src/atlas/runtime/Log.h +++ b/src/atlas/runtime/Log.h @@ -6,67 +6,96 @@ #ifdef ATLAS_HAVE_FORTRAN #include "fckit/Log.h" -namespace atlas { namespace detail { typedef fckit::Log LogBase; } } +namespace atlas { +namespace detail { +typedef fckit::Log LogBase; +} +} // namespace atlas #else #include "eckit/log/Log.h" -namespace atlas { namespace detail { typedef eckit::Log LogBase; } } +namespace atlas { +namespace detail { +typedef eckit::Log LogBase; +} +} // namespace atlas #endif namespace atlas { class Log : public detail::LogBase { - public: + using Channel = eckit::Channel; // derives from std::ostream - using Channel = eckit::Channel; // derives from std::ostream - - static Channel& info() { return atlas::Library::instance().infoChannel(); } + static Channel& info() { return atlas::Library::instance().infoChannel(); } static Channel& trace() { return atlas::Library::instance().traceChannel(); } static Channel& debug() { return atlas::Library::instance().debugChannel(); } #ifndef ATLAS_HAVE_FORTRAN // Stubs for what fckit::Log provides - enum Style { - SIMPLE=0,PREFIX=1,TIMESTAMP=2 + enum Style + { + SIMPLE = 0, + PREFIX = 1, + TIMESTAMP = 2 }; - static void addFortranUnit(int unit, Style=PREFIX, const char* prefix="") { /*NOTIMP*/ } - static void setFortranUnit(int unit, Style=PREFIX, const char* prefix="") { /*NOTIMP*/ } + static void addFortranUnit( int unit, Style = PREFIX, const char* prefix = "" ) { /*NOTIMP*/ + } + static void setFortranUnit( int unit, Style = PREFIX, const char* prefix = "" ) { /*NOTIMP*/ + } // Fortran unit numbers static int output_unit() { return 6; } - static int error_unit() { return 0; } + static int error_unit() { return 0; } #endif }; std::string backtrace(); namespace detail { - void debug_parallel_here( const eckit::CodeLocation& ); - void debug_parallel_what( const eckit::CodeLocation&, const std::string& ); -} +void debug_parallel_here( const eckit::CodeLocation& ); +void debug_parallel_what( const eckit::CodeLocation&, const std::string& ); +} // namespace detail -} // namespace atlas +} // namespace atlas #include #include "atlas/util/detail/BlackMagic.h" -#define ATLAS_DEBUG_HERE() do{ ::atlas::Log::info() << "DEBUG() @ " << Here() << std::endl; } while(0) -#define ATLAS_DEBUG_WHAT(WHAT) do{ ::atlas::Log::info() << "DEBUG(" << WHAT << ") @ " << Here() << std::endl; } while(0) -#define ATLAS_DEBUG_VAR(VAR) do{ ::atlas::Log::info() << "DEBUG( " << #VAR << " : " << VAR << " ) @ " << Here() << std::endl; } while(0) - -#define ATLAS_DEBUG(...) __ATLAS_SPLICE( __ATLAS_DEBUG_, __ATLAS_NARG(__VA_ARGS__) ) (__VA_ARGS__) +#define ATLAS_DEBUG_HERE() \ + do { \ + ::atlas::Log::info() << "DEBUG() @ " << Here() << std::endl; \ + } while ( 0 ) +#define ATLAS_DEBUG_WHAT( WHAT ) \ + do { \ + ::atlas::Log::info() << "DEBUG(" << WHAT << ") @ " << Here() << std::endl; \ + } while ( 0 ) +#define ATLAS_DEBUG_VAR( VAR ) \ + do { \ + ::atlas::Log::info() << "DEBUG( " << #VAR << " : " << VAR << " ) @ " << Here() << std::endl; \ + } while ( 0 ) + +#define ATLAS_DEBUG( ... ) __ATLAS_SPLICE( __ATLAS_DEBUG_, __ATLAS_NARG( __VA_ARGS__ ) )( __VA_ARGS__ ) #define __ATLAS_DEBUG_0 ATLAS_DEBUG_HERE #define __ATLAS_DEBUG_1 ATLAS_DEBUG_WHAT -#define ATLAS_DEBUG_BACKTRACE() do{ ::atlas::Log::info() << "DEBUG() @ " << Here() << "Backtrace:\n" << ::atlas::backtrace() << std::endl; } while (0) - -#define ATLAS_DEBUG_PARALLEL_HERE() do{ ::atlas::detail::debug_parallel_here( Here() ); } while (0) -#define ATLAS_DEBUG_PARALLEL_WHAT(WHAT) do{ \ - std::stringstream w;\ - w << WHAT;\ - ::atlas::detail::debug_parallel_what( Here(), w.str() ); } while (0) - -#define ATLAS_DEBUG_PARALLEL(...) __ATLAS_SPLICE( __ATLAS_DEBUG_PARALLEL_, __ATLAS_NARG(__VA_ARGS__) ) (__VA_ARGS__) +#define ATLAS_DEBUG_BACKTRACE() \ + do { \ + ::atlas::Log::info() << "DEBUG() @ " << Here() << "Backtrace:\n" << ::atlas::backtrace() << std::endl; \ + } while ( 0 ) + +#define ATLAS_DEBUG_PARALLEL_HERE() \ + do { \ + ::atlas::detail::debug_parallel_here( Here() ); \ + } while ( 0 ) +#define ATLAS_DEBUG_PARALLEL_WHAT( WHAT ) \ + do { \ + std::stringstream w; \ + w << WHAT; \ + ::atlas::detail::debug_parallel_what( Here(), w.str() ); \ + } while ( 0 ) + +#define ATLAS_DEBUG_PARALLEL( ... ) \ + __ATLAS_SPLICE( __ATLAS_DEBUG_PARALLEL_, __ATLAS_NARG( __VA_ARGS__ ) ) \ + ( __VA_ARGS__ ) #define __ATLAS_DEBUG_PARALLEL_0 ATLAS_DEBUG_PARALLEL_HERE #define __ATLAS_DEBUG_PARALLEL_1 ATLAS_DEBUG_PARALLEL_WHAT - diff --git a/src/atlas/runtime/Trace.h b/src/atlas/runtime/Trace.h index 3907be741..ce3773038 100644 --- a/src/atlas/runtime/Trace.h +++ b/src/atlas/runtime/Trace.h @@ -4,16 +4,17 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include "atlas/library/config.h" -#include "atlas/runtime/trace/TraceT.h" #include "atlas/runtime/trace/Barriers.h" #include "atlas/runtime/trace/Logging.h" +#include "atlas/runtime/trace/TraceT.h" //----------------------------------------------------------------------------------------------------------- @@ -49,8 +50,8 @@ /// // trace "custom" ends /// } /// -#define ATLAS_TRACE(...) -#define ATLAS_TRACE_SCOPE(...) +#define ATLAS_TRACE( ... ) +#define ATLAS_TRACE_SCOPE( ... ) //----------------------------------------------------------------------------------------------------------- @@ -61,14 +62,14 @@ struct TraceTraits { using Tracing = runtime::trace::Logging; }; -class Trace : public runtime::trace::TraceT< TraceTraits > { - using Base = runtime::trace::TraceT< TraceTraits >; +class Trace : public runtime::trace::TraceT { + using Base = runtime::trace::TraceT; + public: using Base::Base; }; -} // namespace atlas - +} // namespace atlas //----------------------------------------------------------------------------------------------------------- @@ -79,8 +80,8 @@ class Trace : public runtime::trace::TraceT< TraceTraits > { #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/runtime/trace/Barriers.cc b/src/atlas/runtime/trace/Barriers.cc index 5aacb919e..fafe90a9b 100644 --- a/src/atlas/runtime/trace/Barriers.cc +++ b/src/atlas/runtime/trace/Barriers.cc @@ -4,17 +4,17 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include "Barriers.h" +#include #include "atlas/library/Library.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/trace/StopWatch.h" - //----------------------------------------------------------------------------------------------------------- namespace atlas { @@ -23,78 +23,69 @@ namespace trace { class BarriersState { private: - BarriersState() { - barriers_ = atlas::Library::instance().traceBarriers(); - } + BarriersState() { barriers_ = atlas::Library::instance().traceBarriers(); } bool barriers_; StopWatch stopwatch_; + public: - BarriersState(BarriersState const&) = delete; - void operator=(BarriersState const&) = delete; + BarriersState( BarriersState const& ) = delete; + void operator=( BarriersState const& ) = delete; static BarriersState& instance() { static BarriersState state; return state; } - operator bool() const { - return barriers_; - } - void set( bool state ) { - barriers_ = state; - } + operator bool() const { return barriers_; } + void set( bool state ) { barriers_ = state; } StopWatch& stopwatch() { return stopwatch_; } 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; - } - return out.str(); + std::stringstream out; + double time = stopwatch_.elapsed(); + if ( time ) { out << "Total time spent in mpi barriers due to load imbalance : " << time << "s" << std::endl; } + return out.str(); } }; -Barriers::Barriers(bool state) : - previous_state_( BarriersState::instance() ) { - BarriersState::instance().set(state); +Barriers::Barriers( bool state ) : previous_state_( BarriersState::instance() ) { + BarriersState::instance().set( state ); } Barriers::~Barriers() { - restore(); + restore(); } void Barriers::restore() { - BarriersState::instance().set( previous_state_ ); + BarriersState::instance().set( previous_state_ ); } bool Barriers::state() { - return BarriersState::instance(); + return BarriersState::instance(); } void Barriers::execute() { - if( state() ) { - BarriersState::instance().stopwatch().start(); - mpi::comm().barrier(); - BarriersState::instance().stopwatch().stop(); - } + if ( state() ) { + BarriersState::instance().stopwatch().start(); + mpi::comm().barrier(); + BarriersState::instance().stopwatch().stop(); + } } double Barriers::time() { - return BarriersState::instance().stopwatch().elapsed(); + return BarriersState::instance().stopwatch().elapsed(); } double NoBarriers::time() { - return BarriersState::instance().stopwatch().elapsed(); + return BarriersState::instance().stopwatch().elapsed(); } std::string Barriers::report() { - return BarriersState::instance().report(); + return BarriersState::instance().report(); } std::string NoBarriers::report() { - return BarriersState::instance().report(); + return BarriersState::instance().report(); } -} // namespace trace -} // namespace runtime -} // namespace atlas - +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/Barriers.h b/src/atlas/runtime/trace/Barriers.h index 2936ad24c..475a4f63c 100644 --- a/src/atlas/runtime/trace/Barriers.h +++ b/src/atlas/runtime/trace/Barriers.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -19,10 +20,10 @@ namespace trace { class NoBarriers { public: - NoBarriers(bool state) {} + NoBarriers( bool state ) {} void restore() {} -public: // static methods +public: // static methods static bool state() { return false; } static void execute() {} static double time(); @@ -31,20 +32,20 @@ class NoBarriers { class Barriers { public: - Barriers(bool state); + Barriers( bool state ); ~Barriers(); void restore(); -public: // static methods +public: // static methods static bool state(); static void execute(); static double time(); static std::string report(); + private: bool previous_state_; }; -} // namespace trace -} // namespace runtime -} // namespace atlas - +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/CallStack.cc b/src/atlas/runtime/trace/CallStack.cc index 6b39ccc74..9e18301fb 100644 --- a/src/atlas/runtime/trace/CallStack.cc +++ b/src/atlas/runtime/trace/CallStack.cc @@ -9,21 +9,21 @@ namespace runtime { namespace trace { void CallStack::push_front( const eckit::CodeLocation& loc ) { - stack_.push_front( std::hash{}(loc.asString()) ); + stack_.push_front( std::hash{}( loc.asString() ) ); } void CallStack::pop_front() { - stack_.pop_front(); + stack_.pop_front(); } size_t CallStack::hash() const { - if( hash_ ) return hash_; - for( auto h : stack_ ) { - hash_ ^= (h << 1); - } - return hash_; + if ( hash_ ) return hash_; + for ( auto h : stack_ ) { + hash_ ^= ( h << 1 ); + } + return hash_; } -} // namespace trace -} // namespace runtime -} // namespace atlas +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/CallStack.h b/src/atlas/runtime/trace/CallStack.h index 45d3e1064..793234dd7 100644 --- a/src/atlas/runtime/trace/CallStack.h +++ b/src/atlas/runtime/trace/CallStack.h @@ -1,8 +1,11 @@ #pragma once +#include #include -namespace eckit { class CodeLocation; } +namespace eckit { +class CodeLocation; +} namespace atlas { namespace runtime { @@ -11,33 +14,28 @@ namespace trace { /// @class CallStack /// Instances of CallStack can keep track of nested eckit::CodeLocations class CallStack { - public: - - using const_iterator = std::list::const_iterator; - using const_reverse_iterator = std::list::const_reverse_iterator; + using const_iterator = std::list::const_iterator; + using const_reverse_iterator = std::list::const_reverse_iterator; public: + void push_front( const eckit::CodeLocation& ); + void pop_front(); - void push_front( const eckit::CodeLocation& ); - void pop_front(); - - const_iterator begin() const { return stack_.begin(); } - const_iterator end() const { return stack_.end(); } + const_iterator begin() const { return stack_.begin(); } + const_iterator end() const { return stack_.end(); } - const_reverse_iterator rbegin() const { return stack_.rbegin(); } - const_reverse_iterator rend() const { return stack_.rend(); } + const_reverse_iterator rbegin() const { return stack_.rbegin(); } + const_reverse_iterator rend() const { return stack_.rend(); } - size_t hash() const; - size_t size() const { return stack_.size(); } + size_t hash() const; + size_t size() const { return stack_.size(); } private: - - std::list stack_; - mutable size_t hash_{0}; - + std::list stack_; + mutable size_t hash_{0}; }; -} // namespace trace -} // namespace runtime -} // namespace atlas +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/Logging.cc b/src/atlas/runtime/trace/Logging.cc index ddb05c9e9..22c96aa71 100644 --- a/src/atlas/runtime/trace/Logging.cc +++ b/src/atlas/runtime/trace/Logging.cc @@ -4,15 +4,16 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "Logging.h" #include -#include "eckit/log/Channel.h" #include "atlas/library/Library.h" +#include "eckit/log/Channel.h" //----------------------------------------------------------------------------------------------------------- @@ -26,12 +27,9 @@ class LoggingState { private: std::ostream* channel_; - LoggingState() { - channel_ = &atlas::Library::instance().traceChannel(); - } + LoggingState() { channel_ = &atlas::Library::instance().traceChannel(); } public: - static eckit::Channel& empty_channel() { static eckit::Channel channel; return channel; @@ -46,57 +44,53 @@ class LoggingState { operator std::ostream*() { return channel_; } void set( std::ostream& channel ) { channel_ = &channel; } - void set( bool state ) { if( state == false ) channel_ = &empty_channel(); } + void set( bool state ) { + if ( state == false ) channel_ = &empty_channel(); + } }; //----------------------------------------------------------------------------------------------------------- -Logging::Logging( bool state ) : - previous_state_( LoggingState::instance() ) { +Logging::Logging( bool state ) : previous_state_( LoggingState::instance() ) { LoggingState::instance().set( state ); } -Logging::Logging( std::ostream& channel ) : - previous_state_( LoggingState::instance() ) { +Logging::Logging( std::ostream& channel ) : previous_state_( LoggingState::instance() ) { LoggingState::instance().set( channel ); } Logging::~Logging() { - LoggingState::instance().set( *previous_state_ ); + LoggingState::instance().set( *previous_state_ ); } std::ostream& Logging::channel() { - return LoggingState::instance(); + return LoggingState::instance(); } bool Logging::enabled() { - return LoggingState::instance(); + return LoggingState::instance(); } 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; } //----------------------------------------------------------------------------------------------------------- std::ostream& NoLogging::channel() { - return LoggingState::empty_channel(); + return LoggingState::empty_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; } //----------------------------------------------------------------------------------------------------------- -} // namespace trace -} // namespace runtime -} // namespace atlas - +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/Logging.h b/src/atlas/runtime/trace/Logging.h index fd1a3ab2a..ab0bd07a7 100644 --- a/src/atlas/runtime/trace/Logging.h +++ b/src/atlas/runtime/trace/Logging.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -26,7 +27,7 @@ class NoLogging { NoLogging( bool state ); NoLogging( std::ostream& channel ); -public: // static methods +public: // static methods static std::ostream& channel(); static bool enabled(); static void start( const std::string& ) {} @@ -45,14 +46,14 @@ class Logging { Logging( std::ostream& channel ); virtual ~Logging(); -public: // static methods +public: // static methods static std::ostream& channel(); static bool enabled(); static void start( const std::string& title ); static void stop( const std::string& title, double seconds ); - + private: - std::ostream* previous_state_; + std::ostream* previous_state_; }; //----------------------------------------------------------------------------------------------------------- @@ -64,14 +65,13 @@ class LoggingResult : public Logging { public: using Logging::Logging; -public: // static methods +public: // static methods static void start( const std::string& ) {} static void stop( const std::string& title, double seconds ); }; //----------------------------------------------------------------------------------------------------------- -} // namespace trace -} // namespace runtime -} // namespace atlas - +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/Nesting.cc b/src/atlas/runtime/trace/Nesting.cc index 8fb2943f0..67c8b2077 100644 --- a/src/atlas/runtime/trace/Nesting.cc +++ b/src/atlas/runtime/trace/Nesting.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,54 +17,46 @@ namespace atlas { namespace runtime { namespace trace { - class NestingState { private: - NestingState() {} - CallStack stack_; + NestingState() {} + CallStack stack_; + public: - NestingState(NestingState const&) = delete; - void operator=(NestingState const&) = delete; - static NestingState& instance() { - static NestingState state; - return state; - } - operator CallStack() const { - return stack_; - } - CallStack& push( const eckit::CodeLocation& loc ) { - stack_.push_front(loc); - return stack_; - } - void pop() { - stack_.pop_front(); - } + NestingState( NestingState const& ) = delete; + void operator=( NestingState const& ) = delete; + static NestingState& instance() { + static NestingState state; + return state; + } + operator CallStack() const { return stack_; } + CallStack& push( const eckit::CodeLocation& loc ) { + stack_.push_front( loc ); + return stack_; + } + void pop() { stack_.pop_front(); } }; -Nesting::Nesting( const eckit::CodeLocation& loc ) : - loc_(loc), - stack_( NestingState::instance().push( loc ) ) { -} +Nesting::Nesting( const eckit::CodeLocation& loc ) : loc_( loc ), stack_( NestingState::instance().push( loc ) ) {} Nesting::~Nesting() { - stop(); + stop(); } void Nesting::stop() { - if( running_ ) { - NestingState::instance().pop(); - running_ = false; - } + if ( running_ ) { + NestingState::instance().pop(); + running_ = false; + } } void Nesting::start() { - if( not running_ ) { - NestingState::instance().push( loc_ ); - running_ = true; - } + if ( not running_ ) { + NestingState::instance().push( loc_ ); + running_ = true; + } } -} // namespace trace -} // namespace runtime -} // namespace atlas - +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/Nesting.h b/src/atlas/runtime/trace/Nesting.h index cb12cdcb2..86ef5fafe 100644 --- a/src/atlas/runtime/trace/Nesting.h +++ b/src/atlas/runtime/trace/Nesting.h @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "eckit/log/CodeLocation.h" #include "atlas/runtime/trace/CallStack.h" +#include "eckit/log/CodeLocation.h" //----------------------------------------------------------------------------------------------------------- @@ -19,7 +20,6 @@ namespace atlas { namespace runtime { namespace trace { - class Nesting { public: Nesting( const eckit::CodeLocation& ); @@ -27,14 +27,13 @@ class Nesting { operator CallStack() const { return stack_; } void stop(); void start(); + private: CallStack stack_; eckit::CodeLocation loc_; bool running_{true}; }; - -} // namespace trace -} // namespace runtime -} // namespace atlas - +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/StopWatch.h b/src/atlas/runtime/trace/StopWatch.h index 923055d4d..67bcf0924 100644 --- a/src/atlas/runtime/trace/StopWatch.h +++ b/src/atlas/runtime/trace/StopWatch.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,55 +16,53 @@ namespace atlas { namespace runtime { namespace trace { - + //----------------------------------------------------------------------------------------------------------- - + class StopWatch { public: - StopWatch(); - StopWatch(double elapsed); - void start(); - void stop(); - void reset(); - double elapsed() const; + StopWatch(); + StopWatch( double elapsed ); + void start(); + void stop(); + void reset(); + double elapsed() const; + private: - std::chrono::duration elapsed_; - std::chrono::steady_clock::time_point start_; - bool running_{false}; + std::chrono::duration elapsed_; + std::chrono::steady_clock::time_point start_; + bool running_{false}; }; //----------------------------------------------------------------------------------------------------------- -inline StopWatch::StopWatch() : elapsed_(0) { -} +inline StopWatch::StopWatch() : elapsed_( 0 ) {} -inline StopWatch::StopWatch(double elapsed) : - elapsed_(elapsed) { -} +inline StopWatch::StopWatch( double elapsed ) : elapsed_( elapsed ) {} inline void StopWatch::start() { - start_ = std::chrono::steady_clock::now(); - running_ = true; + start_ = std::chrono::steady_clock::now(); + running_ = true; } -inline void StopWatch::stop() { - if( running_ ) { - elapsed_ += (std::chrono::steady_clock::now() - start_); - running_ = false; - } +inline void StopWatch::stop() { + if ( running_ ) { + elapsed_ += ( std::chrono::steady_clock::now() - start_ ); + running_ = false; + } } inline void StopWatch::reset() { - elapsed_ = std::chrono::seconds::zero(); - start_ = std::chrono::steady_clock::now(); + elapsed_ = std::chrono::seconds::zero(); + start_ = std::chrono::steady_clock::now(); } inline double StopWatch::elapsed() const { - return elapsed_.count(); + return elapsed_.count(); } //----------------------------------------------------------------------------------------------------------- -} // trace -} // runtime -} // atlas +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/Timings.cc b/src/atlas/runtime/trace/Timings.cc index e00cf185f..cdbd8a9ed 100644 --- a/src/atlas/runtime/trace/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -4,22 +4,23 @@ * 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 + * 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 +#include +#include #include "Timings.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/trace/CallStack.h" +#include "atlas/util/Config.h" #include "eckit/config/Configuration.h" #include "eckit/filesystem/PathName.h" -#include "atlas/util/Config.h" -#include "atlas/runtime/trace/CallStack.h" -#include "atlas/parallel/mpi/mpi.h" //----------------------------------------------------------------------------------------------------------- @@ -28,27 +29,23 @@ namespace runtime { namespace trace { class TimingsRegistry { - private: + std::vector counts_; + std::vector tot_timings_; + std::vector min_timings_; + std::vector max_timings_; + std::vector var_timings_; + std::vector titles_; + std::vector locations_; + std::vector nest_; + std::vector stack_; + std::map index_; - std::vector counts_; - std::vector tot_timings_; - std::vector min_timings_; - std::vector max_timings_; - std::vector var_timings_; - std::vector titles_; - std::vector locations_; - std::vector nest_; - std::vector stack_; - std::map index_; - - std::map > labels_; + std::map> labels_; - TimingsRegistry() { - } + TimingsRegistry() {} public: - static TimingsRegistry& instance() { static TimingsRegistry registry; return registry; @@ -61,333 +58,300 @@ class TimingsRegistry { size_t size() const; void report( std::ostream& out, const eckit::Configuration& config ); -private: +private: std::string filter_filepath( const std::string& filepath ) const; - - }; -size_t TimingsRegistry::add( const eckit::CodeLocation& loc, const CallStack& stack, const std::string& title, const Timings::Labels& labels ) { - +size_t TimingsRegistry::add( const eckit::CodeLocation& loc, const CallStack& stack, const std::string& title, + const Timings::Labels& labels ) { size_t key = stack.hash(); - auto it = index_.find( key ); - if( it == index_.end() ) { - size_t idx = size(); - index_[key] = idx; - counts_.emplace_back( 0 ); - tot_timings_.emplace_back( 0 ); - min_timings_.emplace_back( std::numeric_limits::max() ); - max_timings_.emplace_back( 0 ); - var_timings_.emplace_back( 0 ); - titles_.emplace_back( title ); - locations_.emplace_back( loc ); - nest_.emplace_back( stack.size() ); - stack_.emplace_back( stack ); - - for( const auto& label: labels ) { - labels_[label].emplace_back(idx); - } - - return idx; + auto it = index_.find( key ); + if ( it == index_.end() ) { + size_t idx = size(); + index_[key] = idx; + counts_.emplace_back( 0 ); + tot_timings_.emplace_back( 0 ); + min_timings_.emplace_back( std::numeric_limits::max() ); + max_timings_.emplace_back( 0 ); + var_timings_.emplace_back( 0 ); + titles_.emplace_back( title ); + locations_.emplace_back( loc ); + nest_.emplace_back( stack.size() ); + stack_.emplace_back( stack ); + + for ( const auto& label : labels ) { + labels_[label].emplace_back( idx ); + } + + return idx; } else { - return it->second; + return it->second; } } void TimingsRegistry::update( size_t idx, double seconds ) { - - auto sqr = [](double x) { return x*x; }; - double n = counts_[idx]+1; - double avg_nm1 = tot_timings_[idx] / std::max(n,1.); - double var_nm1 = var_timings_[idx]; - var_timings_[idx] = n == 1. ? 0. : (n-2.)/(n-1.) * var_nm1 + 1./n * sqr(seconds-avg_nm1); + auto sqr = []( double x ) { return x * x; }; + double n = counts_[idx] + 1; + double avg_nm1 = tot_timings_[idx] / std::max( n, 1. ); + double var_nm1 = var_timings_[idx]; + var_timings_[idx] = n == 1. ? 0. : ( n - 2. ) / ( n - 1. ) * var_nm1 + 1. / n * sqr( seconds - avg_nm1 ); min_timings_[idx] = std::min( seconds, min_timings_[idx] ); max_timings_[idx] = std::max( seconds, max_timings_[idx] ); tot_timings_[idx] += seconds; - counts_[idx] += 1; + counts_[idx] += 1; } -size_t TimingsRegistry::size() const { return counts_.size(); } +size_t TimingsRegistry::size() const { + return counts_.size(); +} void TimingsRegistry::report( std::ostream& out, const eckit::Configuration& config ) { - auto box_horizontal = [](int n) { - std::string s; s.reserve(2*n); - for( size_t i=0; i excluded_labels_vector = config.getStringVector("exclude",std::vector()); + std::string box_corner_tl( "\u250c" ); + std::string box_corner_tr( "\u2510" ); + std::string box_corner_bl( "\u2514" ); + std::string box_corner_br( "\u2518" ); + std::string box_vertical( "\u2502" ); + std::string box_T_down( "\u252C" ); + std::string box_T_up( "\u2534" ); + std::string box_T_right( "\u251C" ); + std::string box_T_left( "\u2524" ); + std::string box_cross( "\u253C" ); + + long indent = config.getLong( "indent", 2 ); + long depth = config.getLong( "depth", 0 ); + long decimals = config.getLong( "decimals", 5 ); + bool header = config.getBool( "header", true ); + std::vector excluded_labels_vector = config.getStringVector( "exclude", std::vector() ); std::vector include_back; - for( auto& label : excluded_labels_vector ) { - size_t found = label.find("/*"); - if (found!=std::string::npos) { - label.erase(found,2); - include_back.push_back(label); - } + for ( auto& label : excluded_labels_vector ) { + size_t found = label.find( "/*" ); + if ( found != std::string::npos ) { + label.erase( found, 2 ); + include_back.push_back( label ); + } } - std::set excluded_labels(excluded_labels_vector.begin(),excluded_labels_vector.end()); + std::set excluded_labels( excluded_labels_vector.begin(), excluded_labels_vector.end() ); - auto digits_before_decimal = [](double x) -> int { - return std::floor(std::log10(std::trunc( std::max(1.,x)) ) )+1; - }; - auto digits = [](long x) -> long { - return std::floor(std::log10( std::max(1l,x) ) )+1l; + auto digits_before_decimal = []( double x ) -> int { + return std::floor( std::log10( std::trunc( std::max( 1., x ) ) ) ) + 1; }; + auto digits = []( long x ) -> long { return std::floor( std::log10( std::max( 1l, x ) ) ) + 1l; }; std::vector excluded_timers_vector; - for( auto label: labels_ ) { - auto name = label.first; - if( excluded_labels.count(name) ) { - auto timers = label.second; - for( size_t j : timers ) { - excluded_timers_vector.push_back(j); + for ( auto label : labels_ ) { + auto name = label.first; + if ( excluded_labels.count( name ) ) { + auto timers = label.second; + for ( size_t j : timers ) { + excluded_timers_vector.push_back( j ); + } } - } } - std::set excluded_timers(excluded_timers_vector.begin(),excluded_timers_vector.end()); - + 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; - return excluded_timers.count(i); + auto excluded = [&]( size_t i ) -> bool { + 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 excluded_nest ) { - excluded_timers.insert(j); - } - if( not excluded(j) ) { - excluded_nest = nest_[j]+1; - } else { - excluded_nest = std::min(excluded_nest,nest_[j]); - } - excluded_nest_stored[j] = excluded_nest; + 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; } + else { + excluded_nest = std::min( excluded_nest, nest_[j] ); + } + excluded_nest_stored[j] = excluded_nest; } - 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); - } + 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 ); + } } - - - - size_t max_title_length(0); - size_t max_location_length(0); - size_t max_nest(0); - long max_count(0); - double max_seconds(0); - for( size_t j=0; j std::string { - std::stringstream out; - char unit = 's'; - if( std::floor(x) >= 60 ) { - x/=60.; - unit = 'm'; - } - out << std::right - << std::fixed - << std::setprecision(decimals) - << std::setw(max_digits_before_decimal+decimals+1) - << x << unit; - return out.str(); - }; + size_t max_count_length = digits( max_count ); + 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_line = [&](size_t length) -> std::string { - return box_horizontal(length); + auto print_time = [max_digits_before_decimal, decimals]( double x ) -> std::string { + std::stringstream out; + char unit = 's'; + if ( std::floor( x ) >= 60 ) { + x /= 60.; + unit = 'm'; + } + out << std::right << std::fixed << std::setprecision( decimals ) + << std::setw( max_digits_before_decimal + decimals + 1 ) << x << unit; + return out.str(); }; - auto print_horizontal = [&](const std::string& sep) -> std::string { - std::stringstream ss; - ss << print_line(max_title_length + digits(size()) + 3) - << sep << print_line(max_count_length) - << sep << print_line(max_digits_before_decimal+decimals+2) - << sep << print_line(max_digits_before_decimal+decimals+2) - << sep << print_line(max_digits_before_decimal+decimals+2) - << sep << print_line(max_digits_before_decimal+decimals+2) - << sep << print_line(max_digits_before_decimal+decimals+2) - << sep << print_line(max_location_length); - return ss.str(); + auto print_line = [&]( size_t length ) -> std::string { return box_horizontal( length ); }; + + auto print_horizontal = [&]( const std::string& sep ) -> std::string { + std::stringstream ss; + ss << print_line( max_title_length + digits( size() ) + 3 ) << sep << print_line( max_count_length ) << sep + << print_line( max_digits_before_decimal + decimals + 2 ) << sep + << print_line( max_digits_before_decimal + decimals + 2 ) << sep + << print_line( max_digits_before_decimal + decimals + 2 ) << sep + << print_line( max_digits_before_decimal + decimals + 2 ) << sep + << print_line( max_digits_before_decimal + decimals + 2 ) << sep << print_line( max_location_length ); + return ss.str(); }; - std::string sept = box_horizontal(1)+box_T_down+box_horizontal(1); - std::string seph = box_horizontal(1)+box_cross+box_horizontal(1); - std::string sep = std::string(" ") +box_vertical+std::string(" "); - std::string sepf = box_horizontal(1)+box_T_up+box_horizontal(1); - + std::string sept = box_horizontal( 1 ) + box_T_down + box_horizontal( 1 ); + std::string seph = box_horizontal( 1 ) + box_cross + box_horizontal( 1 ); + std::string sep = std::string( " " ) + box_vertical + std::string( " " ); + std::string sepf = box_horizontal( 1 ) + box_T_up + box_horizontal( 1 ); out << print_horizontal( sept ) << std::endl; - out << std::left << std::setw(max_title_length + digits(size()) + 3) << "Timers" - << sep << std::setw(max_count_length) << "cnt" - << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "tot" - << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "avg" - << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "std" - << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "min" - << sep << std::setw(max_digits_before_decimal+decimals+2ul) << "max" - << sep << "location" - << std::endl; + out << std::left << std::setw( max_title_length + digits( size() ) + 3 ) << "Timers" << sep + << std::setw( max_count_length ) << "cnt" << sep << std::setw( max_digits_before_decimal + decimals + 2ul ) + << "tot" << sep << std::setw( max_digits_before_decimal + decimals + 2ul ) << "avg" << sep + << std::setw( max_digits_before_decimal + decimals + 2ul ) << "std" << sep + << std::setw( max_digits_before_decimal + decimals + 2ul ) << "min" << sep + << std::setw( max_digits_before_decimal + decimals + 2ul ) << "max" << sep << "location" << std::endl; out << print_horizontal( seph ) << std::endl; - - std::vector prefix_(size()); - if( indent ) { - std::vector active(max_nest,false); - for( long k=long(size())-1; k>=0; --k ) { - const auto& nest = nest_[k]; - - const CallStack& this_stack = stack_[k]; - const CallStack& next_stack = (k==size()-1) ? this_stack : stack_[k+1]; - - auto this_it = this_stack.rbegin(); - 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; - } else { - active[i] = true; - } - } - for( size_t i=nest; i prefix_( size() ); + if ( indent ) { + std::vector active( max_nest, false ); + for ( long k = long( size() ) - 1; k >= 0; --k ) { + const auto& nest = nest_[k]; + + const CallStack& this_stack = stack_[k]; + const CallStack& next_stack = ( k == size() - 1 ) ? this_stack : stack_[k + 1]; + + auto this_it = this_stack.rbegin(); + 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; } + else { + active[i] = true; + } + } + for ( size_t i = nest; i < active.size(); ++i ) { + active[i] = false; + } + + std::stringstream out; + for ( long i = 0; i < nest - 1; ++i ) { + if ( active[i] ) + out << box_vertical; + else + out << " "; + for ( size_t j = 1; j < indent; ++j ) + out << " "; + } + if ( active[nest - 1] ) + out << box_T_right; + else + out << box_corner_bl; + for ( size_t j = 1; j < indent; ++j ) + out << box_horizontal( 1 ); + + prefix_[k] = out.str(); } + } - std::stringstream out; - for( long i=0; i #include +#include //----------------------------------------------------------------------------------------------------------- -namespace eckit { class Configuration; } -namespace eckit { class CodeLocation; } +namespace eckit { +class Configuration; +} +namespace eckit { +class CodeLocation; +} namespace atlas { namespace runtime { @@ -27,12 +32,11 @@ class CallStack; class Timings { public: using Configuration = eckit::Configuration; - using CodeLocation = eckit::CodeLocation; - using Identifier = size_t; - using Labels = std::vector; - -public: // static methods + using CodeLocation = eckit::CodeLocation; + using Identifier = size_t; + using Labels = std::vector; +public: // static methods static Identifier add( const CodeLocation&, const CallStack&, const std::string& title, const Labels& ); static void update( const Identifier& id, double seconds ); @@ -40,11 +44,8 @@ class Timings { static std::string report(); static std::string report( const Configuration& ); - }; - -} // namespace trace -} // namespace runtime -} // namespace atlas - +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/runtime/trace/TraceT.h b/src/atlas/runtime/trace/TraceT.h index 439a0befe..2fe0c9a80 100644 --- a/src/atlas/runtime/trace/TraceT.h +++ b/src/atlas/runtime/trace/TraceT.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,17 +14,16 @@ #include #include #include -#include +#include "atlas/runtime/trace/Nesting.h" #include "atlas/runtime/trace/StopWatch.h" #include "atlas/runtime/trace/Timings.h" -#include "atlas/runtime/trace/Nesting.h" //----------------------------------------------------------------------------------------------------------- namespace eckit { - class CodeLocation; - class Configuration; -} +class CodeLocation; +class Configuration; +} // namespace eckit //----------------------------------------------------------------------------------------------------------- @@ -33,20 +33,18 @@ namespace trace { //----------------------------------------------------------------------------------------------------------- -template< typename TraceTraits > +template class TraceT { public: - using Barriers = typename TraceTraits::Barriers; - using Tracing = typename TraceTraits::Tracing; - using Labels = std::vector; - -public: // static methods + using Barriers = typename TraceTraits::Barriers; + using Tracing = typename TraceTraits::Tracing; + using Labels = std::vector; +public: // static methods static std::string report(); static std::string report( const eckit::Configuration& config ); public: - TraceT( const eckit::CodeLocation& ); TraceT( const eckit::CodeLocation&, const std::string& title ); TraceT( const eckit::CodeLocation&, const std::string& title, const Labels& ); @@ -65,20 +63,17 @@ class TraceT { double elapsed() const; -private: // types - +private: // types using Identifier = Timings::Identifier; -private: // member functions - +private: // member functions void barrier() const; void updateTimings() const; void registerTimer(); -private: // member data - +private: // member data bool running_{true}; StopWatch stopwatch_; eckit::CodeLocation loc_; @@ -91,57 +86,57 @@ class TraceT { //----------------------------------------------------------------------------------------------------------- // Definitions -template< typename TraceTraits > +template inline TraceT::TraceT( const eckit::CodeLocation& loc, const std::string& title ) : - loc_(loc), - title_(title), - nesting_(loc) { - start(); + loc_( loc ), + title_( title ), + nesting_( loc ) { + start(); } -template< typename TraceTraits > +template inline TraceT::TraceT( const eckit::CodeLocation& loc ) : - loc_(loc), - title_( loc_ ? loc_.func() : ""), - nesting_(loc_) { - start(); + loc_( loc ), + title_( loc_ ? loc_.func() : "" ), + nesting_( loc_ ) { + start(); } -template< typename TraceTraits > +template inline TraceT::TraceT( const eckit::CodeLocation& loc, const std::string& title, const Labels& labels ) : - loc_(loc), - title_(title), - nesting_(loc), - labels_(labels) { - start(); + loc_( loc ), + title_( title ), + nesting_( loc ), + labels_( labels ) { + start(); } -template< typename TraceTraits > +template inline TraceT::~TraceT() { stop(); } -template< typename TraceTraits > +template inline void TraceT::barrier() const { Barriers::execute(); } -template< typename TraceTraits > +template inline void TraceT::registerTimer() { - id_ = Timings::add( loc_, nesting_, title_ + (Barriers::state() ? " [b]" : ""), labels_ ); + id_ = Timings::add( loc_, nesting_, title_ + ( Barriers::state() ? " [b]" : "" ), labels_ ); } -template< typename TraceTraits > +template inline void TraceT::updateTimings() const { - Timings::update( id_, stopwatch_.elapsed() ); + Timings::update( id_, stopwatch_.elapsed() ); } -template< typename TraceTraits > +template inline bool TraceT::running() const { return running_; } -template< typename TraceTraits > +template inline void TraceT::start() { registerTimer(); Tracing::start( title_ ); @@ -149,9 +144,9 @@ inline void TraceT::start() { stopwatch_.start(); } -template< typename TraceTraits > +template inline void TraceT::stop() { - if( running_ ) { + if ( running_ ) { barrier(); stopwatch_.stop(); nesting_.stop(); @@ -161,41 +156,41 @@ inline void TraceT::stop() { } } -template< typename TraceTraits > +template inline void TraceT::pause() { - if( running_ ) { - barrier(); - stopwatch_.stop(); - nesting_.stop(); + if ( running_ ) { + barrier(); + stopwatch_.stop(); + nesting_.stop(); } } -template< typename TraceTraits > +template inline void TraceT::resume() { - if( running_ ) { - barrier(); - nesting_.start(); - stopwatch_.start(); + if ( running_ ) { + barrier(); + nesting_.start(); + stopwatch_.start(); } } -template< typename TraceTraits > +template inline double TraceT::elapsed() const { return stopwatch_.elapsed(); } -template< typename TraceTraits > +template inline std::string TraceT::report() { return Timings::report() + Barriers::report(); } -template< typename TraceTraits > +template inline std::string TraceT::report( const eckit::Configuration& config ) { - return Timings::report(config) + Barriers::report(); + return Timings::report( config ) + Barriers::report(); } //----------------------------------------------------------------------------------------------------------- -} // trace -} // runtime -} // atlas +} // namespace trace +} // namespace runtime +} // namespace atlas diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index 554fc640d..dd24ca687 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -4,19 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "eckit/exception/Exceptions.h" #include "eckit/thread/AutoLock.h" #include "eckit/thread/Mutex.h" -#include "eckit/exception/Exceptions.h" #include "eckit/utils/Hash.h" -#include "atlas/trans/Trans.h" -#include "atlas/runtime/Log.h" #include "atlas/functionspace.h" #include "atlas/grid/Grid.h" +#include "atlas/runtime/Log.h" +#include "atlas/trans/Trans.h" #ifdef ATLAS_HAVE_TRANS #include "atlas/trans/ifs/TransIFSNodeColumns.h" @@ -27,242 +28,212 @@ #endif #include "atlas/trans/local/TransLocal.h" - namespace atlas { namespace trans { -TransImpl::~TransImpl() { -} - +TransImpl::~TransImpl() {} namespace { - static eckit::Mutex *local_mutex = 0; - static std::map *m = 0; - static pthread_once_t once = PTHREAD_ONCE_INIT; +static eckit::Mutex* local_mutex = 0; +static std::map* m = 0; +static pthread_once_t once = PTHREAD_ONCE_INIT; - static void init() { - local_mutex = new eckit::Mutex(); - m = new std::map(); - } +static void init() { + local_mutex = new eckit::Mutex(); + m = new std::map(); +} - template void load_builder_functionspace() { TransBuilderFunctionSpace("tmp"); } - template void load_builder_grid() { TransBuilderGrid("tmp"); } +template +void load_builder_functionspace() { + TransBuilderFunctionSpace( "tmp" ); +} +template +void load_builder_grid() { + TransBuilderGrid( "tmp" ); +} - struct force_link { - force_link() - { +struct force_link { + force_link() { #ifdef ATLAS_HAVE_TRANS - load_builder_functionspace(); - load_builder_functionspace(); - load_builder_grid(); + load_builder_functionspace(); + load_builder_functionspace(); + load_builder_grid(); #endif - load_builder_grid(); - } - }; - - TransFactory& factory( const std::string& name ) { - std::map::const_iterator j = m->find(name); - if (j == m->end()) { - Log::error() << "No TransFactory for [" << name << "]" << std::endl; - Log::error() << "TransFactories are:" << std::endl; - for (j = m->begin() ; j != m->end() ; ++j) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No TransFactory called ") + name); - } - return *j->second; + load_builder_grid(); } - - +}; + +TransFactory& factory( const std::string& name ) { + std::map::const_iterator j = m->find( name ); + if ( j == m->end() ) { + Log::error() << "No TransFactory for [" << name << "]" << std::endl; + Log::error() << "TransFactories are:" << std::endl; + for ( j = m->begin(); j != m->end(); ++j ) + Log::error() << " " << ( *j ).first << std::endl; + throw eckit::SeriousBug( std::string( "No TransFactory called " ) + name ); + } + return *j->second; } +} // namespace +TransFactory::TransFactory( const std::string& name ) : name_( name ) { + pthread_once( &once, init ); -TransFactory::TransFactory(const std::string &name): - name_(name) { + eckit::AutoLock lock( local_mutex ); - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); - - ASSERT(m->find(name) == m->end()); - (*m)[name] = this; + ASSERT( m->find( name ) == m->end() ); + ( *m )[name] = this; } - TransFactory::~TransFactory() { - eckit::AutoLock lock(local_mutex); - m->erase(name_); + eckit::AutoLock lock( local_mutex ); + m->erase( name_ ); } +bool TransFactory::has( const std::string& name ) { + pthread_once( &once, init ); -bool TransFactory::has(const std::string& name) { - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - return ( m->find(name) != m->end() ); + return ( m->find( name ) != m->end() ); } +void TransFactory::list( std::ostream& out ) { + pthread_once( &once, init ); -void TransFactory::list(std::ostream& out) { - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; const char* sep = ""; - for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { - out << sep << (*j).first; + for ( std::map::const_iterator j = m->begin(); j != m->end(); ++j ) { + out << sep << ( *j ).first; sep = ", "; } } - -Trans::Implementation *TransFactory::build( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { +Trans::Implementation* TransFactory::build( const FunctionSpace& gp, const FunctionSpace& sp, + const eckit::Configuration& config ) { return build( Cache(), gp, sp, config ); } -Trans::Implementation *TransFactory::build( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { - - pthread_once(&once, init); +Trans::Implementation* TransFactory::build( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, + const eckit::Configuration& config ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::string suffix ( "("+gp.type()+","+sp.type()+")" ); - std::string name = config.getString("type",TRANS_DEFAULT)+suffix; + std::string suffix( "(" + gp.type() + "," + sp.type() + ")" ); + std::string name = config.getString( "type", TRANS_DEFAULT ) + suffix; Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; - if( not config.has("type") and not has(name) ) { - name = std::string("local")+suffix; - Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + if ( not config.has( "type" ) and not has( name ) ) { + name = std::string( "local" ) + suffix; + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; } - return factory(name).make(cache,gp,sp,config); + return factory( name ).make( cache, gp, sp, config ); } -Trans::Implementation *TransFactory::build( const Grid& grid, int truncation, const eckit::Configuration& config ) { +Trans::Implementation* TransFactory::build( const Grid& grid, int truncation, const eckit::Configuration& config ) { return build( Cache(), grid, truncation, config ); } -Trans::Implementation *TransFactory::build( const Cache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { - - pthread_once(&once, init); +Trans::Implementation* TransFactory::build( const Cache& cache, const Grid& grid, int truncation, + const eckit::Configuration& config ) { + pthread_once( &once, init ); - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::string name = config.getString("type",TRANS_DEFAULT); + std::string name = config.getString( "type", TRANS_DEFAULT ); Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; - if( not config.has("type") and not has(name) ) { - name = std::string("local"); - Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + if ( not config.has( "type" ) and not has( name ) ) { + name = std::string( "local" ); + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; } - return factory(name).make(cache,grid,truncation,config); + return factory( name ).make( cache, grid, truncation, config ); } +Trans::Trans() {} - -Trans::Trans() { -} - -Trans::Trans( Implementation* impl ) : - impl_(impl) { -} +Trans::Trans( Implementation* impl ) : impl_( impl ) {} Trans::Trans( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) : - impl_( TransFactory::build(gp,sp,config) ) { -} + impl_( TransFactory::build( gp, sp, config ) ) {} Trans::Trans( const Grid& grid, int truncation, const eckit::Configuration& config ) : - impl_( TransFactory::build(grid,truncation,config) ) { -} + impl_( TransFactory::build( grid, truncation, config ) ) {} -Trans::Trans( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) : - impl_( TransFactory::build(cache,gp,sp,config) ) { -} +Trans::Trans( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, + const eckit::Configuration& config ) : + impl_( TransFactory::build( cache, gp, sp, config ) ) {} Trans::Trans( const Cache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) : - impl_( TransFactory::build(cache,grid,truncation,config) ) { -} + impl_( TransFactory::build( cache, grid, truncation, config ) ) {} -Trans::Trans( const Trans& trans ) : - impl_(trans.impl_) { -} +Trans::Trans( const Trans& trans ) : impl_( trans.impl_ ) {} int Trans::truncation() const { - return impl_->truncation(); + return impl_->truncation(); } const Grid& Trans::grid() const { - return impl_->grid(); + return impl_->grid(); } size_t Trans::spectralCoefficients() const { - return impl_->spectralCoefficients(); + return impl_->spectralCoefficients(); } -void Trans::dirtrans( const Field& gpfield, - Field& spfield, - const eckit::Configuration& config ) const { - impl_->dirtrans( gpfield, spfield, config ); +void Trans::dirtrans( const Field& gpfield, Field& spfield, const eckit::Configuration& config ) const { + impl_->dirtrans( gpfield, spfield, config ); } -void Trans::dirtrans( const FieldSet& gpfields, - FieldSet& spfields, - const eckit::Configuration& config ) const { - impl_->dirtrans( gpfields, spfields, config ); +void Trans::dirtrans( const FieldSet& gpfields, FieldSet& spfields, const eckit::Configuration& config ) const { + impl_->dirtrans( gpfields, spfields, config ); } -void Trans::dirtrans_wind2vordiv( const Field& gpwind, - Field& spvor, Field& spdiv, +void Trans::dirtrans_wind2vordiv( const Field& gpwind, Field& spvor, Field& spdiv, const eckit::Configuration& config ) const { - impl_->dirtrans_wind2vordiv( gpwind, spvor, spdiv, config ); + impl_->dirtrans_wind2vordiv( gpwind, spvor, spdiv, config ); } -void Trans::invtrans( const Field& spfield, - Field& gpfield, - const eckit::Configuration& config ) const { - impl_->invtrans( spfield, gpfield, config ); +void Trans::invtrans( const Field& spfield, Field& gpfield, const eckit::Configuration& config ) const { + impl_->invtrans( spfield, gpfield, config ); } -void Trans::invtrans( const FieldSet& spfields, - FieldSet& gpfields, - const eckit::Configuration& config ) const { - impl_->invtrans( spfields, gpfields, config ); +void Trans::invtrans( const FieldSet& spfields, FieldSet& gpfields, const eckit::Configuration& config ) const { + impl_->invtrans( spfields, gpfields, config ); } -void Trans::invtrans_grad( const Field& spfield, - Field& gradfield, - const eckit::Configuration& config ) const { - impl_->invtrans_grad( spfield, gradfield, config ); +void Trans::invtrans_grad( const Field& spfield, Field& gradfield, const eckit::Configuration& config ) const { + impl_->invtrans_grad( spfield, gradfield, config ); } -void Trans::invtrans_grad( const FieldSet& spfields, - FieldSet& gradfields, - const eckit::Configuration& config ) const { - impl_->invtrans_grad( spfields, gradfields, config ); +void Trans::invtrans_grad( const FieldSet& spfields, FieldSet& gradfields, const eckit::Configuration& config ) const { + impl_->invtrans_grad( spfields, gradfields, config ); } - -void Trans::invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, - Field& gpwind, +void Trans::invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, Field& gpwind, const eckit::Configuration& config ) const { - impl_->invtrans_vordiv2wind( spvor, spdiv, gpwind, config ); + impl_->invtrans_vordiv2wind( spvor, spdiv, gpwind, config ); } // -- IFS type fields -- -// These fields have special interpretation required. You need to know what you're doing. +// These fields have special interpretation required. You need to know what +// you're doing. // See IFS trans library. /*! @@ -274,14 +245,11 @@ void Trans::invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, * @param divergence_spectra * @param gp_fields */ -void Trans::invtrans( const int nb_scalar_fields, const double scalar_spectra[], - const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], +void Trans::invtrans( const int nb_scalar_fields, const double scalar_spectra[], const int nb_vordiv_fields, + const double vorticity_spectra[], const double divergence_spectra[], double gp_fields[], const eckit::Configuration& config ) const { - impl_->invtrans( nb_scalar_fields, scalar_spectra, - nb_vordiv_fields, vorticity_spectra, divergence_spectra, - gp_fields, - config ); + impl_->invtrans( nb_scalar_fields, scalar_spectra, nb_vordiv_fields, vorticity_spectra, divergence_spectra, + gp_fields, config ); } /*! @@ -290,12 +258,9 @@ void Trans::invtrans( const int nb_scalar_fields, const double scalar_spectra[], * @param scalar_spectra * @param scalar_fields */ -void Trans::invtrans( const int nb_scalar_fields, const double scalar_spectra[], - double gp_fields[], +void Trans::invtrans( const int nb_scalar_fields, const double scalar_spectra[], double gp_fields[], const eckit::Configuration& config ) const { - impl_->invtrans( nb_scalar_fields, scalar_spectra, - gp_fields, - config ); + impl_->invtrans( nb_scalar_fields, scalar_spectra, gp_fields, config ); } /*! @@ -303,11 +268,8 @@ void Trans::invtrans( const int nb_scalar_fields, const double scalar_spectra[], * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) */ void Trans::invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const eckit::Configuration& config ) const { - impl_->invtrans( nb_vordiv_fields, vorticity_spectra, divergence_spectra, - gp_fields, - config ); + double gp_fields[], const eckit::Configuration& config ) const { + impl_->invtrans( nb_vordiv_fields, vorticity_spectra, divergence_spectra, gp_fields, config ); } /*! @@ -315,21 +277,17 @@ void Trans::invtrans( const int nb_vordiv_fields, const double vorticity_spectra */ void Trans::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], const eckit::Configuration& config ) const { - impl_->dirtrans( nb_fields, scalar_fields, scalar_spectra, - config ); + impl_->dirtrans( nb_fields, scalar_fields, scalar_spectra, config ); } /*! * @brief Direct transform of wind(U/V) to vorticity/divergence * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) */ -void Trans::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], - const eckit::Configuration& config ) const { - impl_->dirtrans( nb_fields, wind_fields, vorticity_spectra, divergence_spectra, - config ); +void Trans::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], + double divergence_spectra[], const eckit::Configuration& config ) const { + impl_->dirtrans( nb_fields, wind_fields, vorticity_spectra, divergence_spectra, config ); } - - -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/Trans.h b/src/atlas/trans/Trans.h index cb8aaddd5..50753d950 100644 --- a/src/atlas/trans/Trans.h +++ b/src/atlas/trans/Trans.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,10 +14,10 @@ #include #include "eckit/config/Configuration.h" -#include "eckit/memory/Owned.h" -#include "eckit/memory/SharedPtr.h" #include "eckit/io/Buffer.h" #include "eckit/io/DataHandle.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" #include "atlas/util/Config.h" @@ -24,11 +25,11 @@ // Forward declarations namespace atlas { - class Field; - class FieldSet; - class FunctionSpace; - class Grid; -} +class Field; +class FieldSet; +class FunctionSpace; +class Grid; +} // namespace atlas //----------------------------------------------------------------------------- @@ -39,67 +40,59 @@ namespace trans { class TransCacheEntry { public: - operator bool() const { return size() != 0; } - virtual size_t size() const = 0; - virtual const void* data() const = 0; + operator bool() const { return size() != 0; } + virtual size_t size() const = 0; + virtual const void* data() const = 0; }; class EmptyCacheEntry : public TransCacheEntry { public: - virtual size_t size() const override { return 0; } - virtual const void* data() const override { return nullptr; } + virtual size_t size() const override { return 0; } + virtual const void* data() const override { return nullptr; } }; class TransCacheFileEntry : public TransCacheEntry { - eckit::Buffer buffer_; + eckit::Buffer buffer_; + public: - TransCacheFileEntry( const eckit::PathName& path ) : - buffer_(path.size()) { - std::unique_ptr dh( path.fileHandle() ); - dh->openForRead(); - dh->read(buffer_.data(),buffer_.size()); - dh->close(); - } - virtual size_t size() const override { return buffer_.size(); } - virtual const void* data() const override { return buffer_.data(); } + TransCacheFileEntry( const eckit::PathName& path ) : buffer_( path.size() ) { + std::unique_ptr dh( path.fileHandle() ); + dh->openForRead(); + dh->read( buffer_.data(), buffer_.size() ); + dh->close(); + } + virtual size_t size() const override { return buffer_.size(); } + virtual const void* data() const override { return buffer_.data(); } }; class Cache { public: - Cache() : - legendre_( new EmptyCacheEntry() ), - fft_( new EmptyCacheEntry() ) { - } - Cache( const Cache& other ) = default; + Cache() : legendre_( new EmptyCacheEntry() ), fft_( new EmptyCacheEntry() ) {} + Cache( const Cache& other ) = default; + protected: - Cache( const std::shared_ptr& legendre ) : - legendre_(legendre), - fft_( new EmptyCacheEntry() ) { - } - Cache( const std::shared_ptr& legendre, const std::shared_ptr& fft ) : - legendre_(legendre), - fft_(fft) { - } + Cache( const std::shared_ptr& legendre ) : legendre_( legendre ), fft_( new EmptyCacheEntry() ) {} + Cache( const std::shared_ptr& legendre, const std::shared_ptr& fft ) : + legendre_( legendre ), + fft_( fft ) {} + public: - const TransCacheEntry& legendre() const { return *legendre_; } - const TransCacheEntry& fft() const { return *fft_; } + const TransCacheEntry& legendre() const { return *legendre_; } + const TransCacheEntry& fft() const { return *fft_; } + private: - std::shared_ptr legendre_; - std::shared_ptr fft_; + std::shared_ptr legendre_; + std::shared_ptr fft_; }; class LegendreCache : public Cache { public: - LegendreCache( const eckit::PathName& path ) : - Cache( std::shared_ptr( new TransCacheFileEntry( path ) ) ) { - } + LegendreCache( const eckit::PathName& path ) : + Cache( std::shared_ptr( new TransCacheFileEntry( path ) ) ) {} }; - class TransImpl : public eckit::Owned { - public: - virtual ~TransImpl() = 0; virtual int truncation() const = 0; @@ -108,181 +101,175 @@ class TransImpl : public eckit::Owned { virtual const Grid& grid() const = 0; - virtual void dirtrans( const Field& gpfield, - Field& spfield, + virtual void dirtrans( const Field& gpfield, Field& spfield, const eckit::Configuration& = util::NoConfig() ) const = 0; - virtual void dirtrans( const FieldSet& gpfields, - FieldSet& spfields, + virtual void dirtrans( const FieldSet& gpfields, FieldSet& spfields, const eckit::Configuration& = util::NoConfig() ) const = 0; - virtual void dirtrans_wind2vordiv( const Field& gpwind, - Field& spvor, Field& spdiv, + virtual void dirtrans_wind2vordiv( const Field& gpwind, Field& spvor, Field& spdiv, const eckit::Configuration& = util::NoConfig() ) const = 0; - virtual void invtrans( const Field& spfield, - Field& gpfield, + virtual void invtrans( const Field& spfield, Field& gpfield, const eckit::Configuration& = util::NoConfig() ) const = 0; - virtual void invtrans( const FieldSet& spfields, - FieldSet& gpfields, + virtual void invtrans( const FieldSet& spfields, FieldSet& gpfields, const eckit::Configuration& = util::NoConfig() ) const = 0; - virtual void invtrans_grad( const Field& spfield, - Field& gradfield, + virtual void invtrans_grad( const Field& spfield, Field& gradfield, const eckit::Configuration& = util::NoConfig() ) const = 0; - virtual void invtrans_grad( const FieldSet& spfields, - FieldSet& gradfields, + virtual void invtrans_grad( const FieldSet& spfields, FieldSet& gradfields, const eckit::Configuration& = util::NoConfig() ) const = 0; - - virtual void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, - Field& gpwind, + virtual void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, Field& gpwind, const eckit::Configuration& = util::NoConfig() ) const = 0; - // -- IFS type fields -- - // These fields have special interpretation required. You need to know what you're doing. - // See IFS trans library. + // -- IFS type fields -- + // These fields have special interpretation required. You need to know what + // you're doing. + // See IFS trans library. /*! - * @brief invtrans - * @param nb_scalar_fields - * @param scalar_spectra - * @param nb_vordiv_fields - * @param vorticity_spectra - * @param divergence_spectra - * @param gp_fields - */ - virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], + * @brief invtrans + * @param nb_scalar_fields + * @param scalar_spectra + * @param nb_vordiv_fields + * @param vorticity_spectra + * @param divergence_spectra + * @param gp_fields + */ + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], const int nb_vordiv_fields, + const double vorticity_spectra[], const double divergence_spectra[], double gp_fields[], const eckit::Configuration& = util::NoConfig() ) const = 0; /*! - * @brief invtrans - * @param nb_fields - * @param scalar_spectra - * @param scalar_fields - */ - virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - double gp_fields[], + * @brief invtrans + * @param nb_fields + * @param scalar_spectra + * @param scalar_fields + */ + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], double gp_fields[], const eckit::Configuration& = util::NoConfig() ) const = 0; /*! - * @brief Inverse transform of vorticity/divergence to wind(U/V) - * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) - */ - virtual void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], + * @brief Inverse transform of vorticity/divergence to wind(U/V) + * @param nb_fields [in] Number of fields ( both components of wind count as 1 + * ) + */ + virtual void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], + const double divergence_spectra[], double gp_fields[], const eckit::Configuration& = util::NoConfig() ) const = 0; /*! - * @brief Direct transform of scalar fields - */ + * @brief Direct transform of scalar fields + */ virtual void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], const eckit::Configuration& = util::NoConfig() ) const = 0; /*! - * @brief Direct transform of wind(U/V) to vorticity/divergence - * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) - */ - virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], - const eckit::Configuration& = util::NoConfig() ) const = 0; - + * @brief Direct transform of wind(U/V) to vorticity/divergence + * @param nb_fields [in] Number of fields ( both components of wind count as 1 + * ) + */ + virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], + double divergence_spectra[], const eckit::Configuration& = util::NoConfig() ) const = 0; }; // ------------------------------------------------------------------ - - class TransFactory { public: - /*! - * \brief build Trans - * \return TransImpl - */ - static TransImpl* build( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); + * \brief build Trans + * \return TransImpl + */ + static TransImpl* build( const FunctionSpace& gp, const FunctionSpace& sp, + const eckit::Configuration& = util::Config() ); static TransImpl* build( const Grid&, int truncation, const eckit::Configuration& = util::Config() ); - static TransImpl* build( const Cache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::Config() ); + static TransImpl* build( const Cache&, const FunctionSpace& gp, const FunctionSpace& sp, + const eckit::Configuration& = util::Config() ); static TransImpl* build( const Cache&, const Grid&, int truncation, const eckit::Configuration& = util::Config() ); /*! - * \brief list all registered trans implementations - */ - static void list(std::ostream &); + * \brief list all registered trans implementations + */ + static void list( std::ostream& ); - static bool has(const std::string& name); + static bool has( const std::string& name ); private: - std::string name_; - virtual TransImpl* make( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& ) { return nullptr; } + virtual TransImpl* make( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& ) { + return nullptr; + } virtual TransImpl* make( const Grid& gp, int truncation, const eckit::Configuration& ) { return nullptr; } - virtual TransImpl* make( const Cache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& ) { return nullptr; } - virtual TransImpl* make( const Cache&, const Grid& gp, int truncation, const eckit::Configuration& ) { return nullptr; } + virtual TransImpl* make( const Cache&, const FunctionSpace& gp, const FunctionSpace& sp, + const eckit::Configuration& ) { + return nullptr; + } + virtual TransImpl* make( const Cache&, const Grid& gp, int truncation, const eckit::Configuration& ) { + return nullptr; + } protected: - - TransFactory(const std::string&); + TransFactory( const std::string& ); virtual ~TransFactory(); - }; //---------------------------------------------------------------------------------------------------------------------- -template +template class TransBuilderFunctionSpace : public TransFactory { - virtual TransImpl* make( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { - return new T(gp,sp,config); - } - virtual TransImpl* make( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { - return new T(cache,gp,sp,config); - } - virtual TransImpl* make( const Grid&, int, const eckit::Configuration& ) { - throw eckit::SeriousBug("This function should not be called",Here()); - } - virtual TransImpl* make( const Cache&, const Grid&, int, const eckit::Configuration& ) { - throw eckit::SeriousBug("This function should not be called",Here()); - } + virtual TransImpl* make( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& config ) { + return new T( gp, sp, config ); + } + virtual TransImpl* make( const Cache& cache, const FunctionSpace& gp, const FunctionSpace& sp, + const eckit::Configuration& config ) { + return new T( cache, gp, sp, config ); + } + virtual TransImpl* make( const Grid&, int, const eckit::Configuration& ) { + throw eckit::SeriousBug( "This function should not be called", Here() ); + } + virtual TransImpl* make( const Cache&, const Grid&, int, const eckit::Configuration& ) { + throw eckit::SeriousBug( "This function should not be called", Here() ); + } + public: - TransBuilderFunctionSpace(const std::string& name) : TransFactory(name) {} + TransBuilderFunctionSpace( const std::string& name ) : TransFactory( name ) {} }; -template +template class TransBuilderGrid : public TransFactory { - virtual TransImpl* make( const Grid& grid, int truncation, const eckit::Configuration& config ) { - return new T(grid,truncation,config); - } - virtual TransImpl* make( const Cache& cache, const Grid& grid, int truncation, const eckit::Configuration& config ) { - return new T(cache,grid,truncation,config); - } - virtual TransImpl* make( const FunctionSpace&, const FunctionSpace&, const eckit::Configuration& ) { - throw eckit::SeriousBug("This function should not be called",Here()); - } - virtual TransImpl* make( const Cache&, const FunctionSpace&, const FunctionSpace&, const eckit::Configuration& ) { - throw eckit::SeriousBug("This function should not be called",Here()); - } + virtual TransImpl* make( const Grid& grid, int truncation, const eckit::Configuration& config ) { + return new T( grid, truncation, config ); + } + virtual TransImpl* make( const Cache& cache, const Grid& grid, int truncation, + const eckit::Configuration& config ) { + return new T( cache, grid, truncation, config ); + } + virtual TransImpl* make( const FunctionSpace&, const FunctionSpace&, const eckit::Configuration& ) { + throw eckit::SeriousBug( "This function should not be called", Here() ); + } + virtual TransImpl* make( const Cache&, const FunctionSpace&, const FunctionSpace&, const eckit::Configuration& ) { + throw eckit::SeriousBug( "This function should not be called", Here() ); + } + public: - TransBuilderGrid(const std::string& name) : TransFactory(name) {} + TransBuilderGrid( const std::string& name ) : TransFactory( name ) {} }; //---------------------------------------------------------------------------------------------------------------------- class Trans { - public: - - using Implementation = TransImpl; + using Implementation = TransImpl; private: - - eckit::SharedPtr< Implementation > impl_; + eckit::SharedPtr impl_; public: - Trans(); Trans( Implementation* ); Trans( const Trans& ); @@ -290,10 +277,11 @@ class Trans { Trans( const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); Trans( const Grid&, int truncation, const eckit::Configuration& = util::NoConfig() ); - Trans( const Cache&, const FunctionSpace& gp, const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); + Trans( const Cache&, const FunctionSpace& gp, const FunctionSpace& sp, + const eckit::Configuration& = util::NoConfig() ); Trans( const Cache&, const Grid&, int truncation, const eckit::Configuration& = util::NoConfig() ); - void hash(eckit::Hash&) const; + void hash( eckit::Hash& ) const; const Implementation* get() const { return impl_.get(); } operator bool() const { return impl_.owners(); } @@ -301,91 +289,76 @@ class Trans { size_t spectralCoefficients() const; const Grid& grid() const; - void dirtrans( const Field& gpfield, - Field& spfield, - const eckit::Configuration& = util::NoConfig() ) const; + void dirtrans( const Field& gpfield, Field& spfield, const eckit::Configuration& = util::NoConfig() ) const; - void dirtrans( const FieldSet& gpfields, - FieldSet& spfields, - const eckit::Configuration& = util::NoConfig() ) const; + void dirtrans( const FieldSet& gpfields, FieldSet& spfields, const eckit::Configuration& = util::NoConfig() ) const; - void dirtrans_wind2vordiv( const Field& gpwind, - Field& spvor, Field& spdiv, + void dirtrans_wind2vordiv( const Field& gpwind, Field& spvor, Field& spdiv, const eckit::Configuration& = util::NoConfig() ) const; - void invtrans( const Field& spfield, - Field& gpfield, - const eckit::Configuration& = util::NoConfig() ) const; + void invtrans( const Field& spfield, Field& gpfield, const eckit::Configuration& = util::NoConfig() ) const; - void invtrans( const FieldSet& spfields, - FieldSet& gpfields, - const eckit::Configuration& = util::NoConfig() ) const; + void invtrans( const FieldSet& spfields, FieldSet& gpfields, const eckit::Configuration& = util::NoConfig() ) const; - void invtrans_grad( const Field& spfield, - Field& gradfield, - const eckit::Configuration& = util::NoConfig() ) const; + void invtrans_grad( const Field& spfield, Field& gradfield, const eckit::Configuration& = util::NoConfig() ) const; - void invtrans_grad( const FieldSet& spfields, - FieldSet& gradfields, + void invtrans_grad( const FieldSet& spfields, FieldSet& gradfields, const eckit::Configuration& = util::NoConfig() ) const; - - void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, - Field& gpwind, + void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, Field& gpwind, const eckit::Configuration& = util::NoConfig() ) const; - // -- IFS type fields -- - // These fields have special interpretation required. You need to know what you're doing. - // See IFS trans library. + // -- IFS type fields -- + // These fields have special interpretation required. You need to know what + // you're doing. + // See IFS trans library. /*! - * @brief invtrans - * @param nb_scalar_fields - * @param scalar_spectra - * @param nb_vordiv_fields - * @param vorticity_spectra - * @param divergence_spectra - * @param gp_fields - */ - void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], + * @brief invtrans + * @param nb_scalar_fields + * @param scalar_spectra + * @param nb_vordiv_fields + * @param vorticity_spectra + * @param divergence_spectra + * @param gp_fields + */ + void invtrans( const int nb_scalar_fields, const double scalar_spectra[], const int nb_vordiv_fields, + const double vorticity_spectra[], const double divergence_spectra[], double gp_fields[], const eckit::Configuration& = util::NoConfig() ) const; /*! - * @brief invtrans - * @param nb_fields - * @param scalar_spectra - * @param scalar_fields - */ - void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - double gp_fields[], + * @brief invtrans + * @param nb_fields + * @param scalar_spectra + * @param scalar_fields + */ + void invtrans( const int nb_scalar_fields, const double scalar_spectra[], double gp_fields[], const eckit::Configuration& = util::NoConfig() ) const; /*! - * @brief Inverse transform of vorticity/divergence to wind(U/V) - * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) - */ + * @brief Inverse transform of vorticity/divergence to wind(U/V) + * @param nb_fields [in] Number of fields ( both components of wind count as 1 + * ) + */ void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const eckit::Configuration& = util::NoConfig() ) const; + double gp_fields[], const eckit::Configuration& = util::NoConfig() ) const; /*! - * @brief Direct transform of scalar fields - */ + * @brief Direct transform of scalar fields + */ void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], const eckit::Configuration& = util::NoConfig() ) const; /*! - * @brief Direct transform of wind(U/V) to vorticity/divergence - * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) - */ - void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], - const eckit::Configuration& = util::NoConfig() ) const; + * @brief Direct transform of wind(U/V) to vorticity/divergence + * @param nb_fields [in] Number of fields ( both components of wind count as 1 + * ) + */ + void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], + double divergence_spectra[], const eckit::Configuration& = util::NoConfig() ) const; }; //---------------------------------------------------------------------------------------------------------------------- -} // namespace trans -} // namespace atlas - +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/VorDivToUV.cc b/src/atlas/trans/VorDivToUV.cc index 0a5838ab7..8875afc03 100644 --- a/src/atlas/trans/VorDivToUV.cc +++ b/src/atlas/trans/VorDivToUV.cc @@ -4,19 +4,20 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "eckit/exception/Exceptions.h" #include "eckit/thread/AutoLock.h" #include "eckit/thread/Mutex.h" -#include "eckit/exception/Exceptions.h" #include "eckit/utils/Hash.h" -#include "atlas/trans/VorDivToUV.h" -#include "atlas/runtime/Log.h" #include "atlas/functionspace.h" #include "atlas/grid/Grid.h" +#include "atlas/runtime/Log.h" +#include "atlas/trans/VorDivToUV.h" #ifdef ATLAS_HAVE_TRANS #include "atlas/trans/ifs/VorDivToUVIFS.h" @@ -29,171 +30,149 @@ namespace atlas { namespace trans { -VorDivToUVImpl::~VorDivToUVImpl() { -} +VorDivToUVImpl::~VorDivToUVImpl() {} namespace { - static eckit::Mutex *local_mutex = 0; - static std::map *m = 0; - static pthread_once_t once = PTHREAD_ONCE_INIT; +static eckit::Mutex* local_mutex = 0; +static std::map* m = 0; +static pthread_once_t once = PTHREAD_ONCE_INIT; - static void init() { - local_mutex = new eckit::Mutex(); - m = new std::map(); - } +static void init() { + local_mutex = new eckit::Mutex(); + m = new std::map(); +} - template void load_builder() { VorDivToUVBuilder("tmp"); } +template +void load_builder() { + VorDivToUVBuilder( "tmp" ); +} - struct force_link { - force_link() - { +struct force_link { + force_link() { #ifdef ATLAS_HAVE_TRANS - load_builder(); + load_builder(); #endif - load_builder(); - } - }; - - VorDivToUVFactory& factory( const std::string& name ) { - std::map::const_iterator j = m->find(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) - Log::error() << " " << (*j).first << std::endl; - throw eckit::SeriousBug(std::string("No VorDivToUVFactory called ") + name); - } - return *j->second; + load_builder(); } - - +}; + +VorDivToUVFactory& factory( const std::string& name ) { + std::map::const_iterator j = m->find( 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 ) + Log::error() << " " << ( *j ).first << std::endl; + throw eckit::SeriousBug( std::string( "No VorDivToUVFactory called " ) + name ); + } + return *j->second; } +} // namespace +VorDivToUVFactory::VorDivToUVFactory( const std::string& name ) : name_( name ) { + pthread_once( &once, init ); -VorDivToUVFactory::VorDivToUVFactory(const std::string &name): - name_(name) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); - ASSERT(m->find(name) == m->end()); - (*m)[name] = this; + ASSERT( m->find( name ) == m->end() ); + ( *m )[name] = this; } - VorDivToUVFactory::~VorDivToUVFactory() { - eckit::AutoLock lock(local_mutex); - m->erase(name_); + eckit::AutoLock lock( local_mutex ); + m->erase( name_ ); } +bool VorDivToUVFactory::has( const std::string& name ) { + pthread_once( &once, init ); -bool VorDivToUVFactory::has(const std::string& name) { - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - return ( m->find(name) != m->end() ); + return ( m->find( name ) != m->end() ); } +void VorDivToUVFactory::list( std::ostream& out ) { + pthread_once( &once, init ); -void VorDivToUVFactory::list(std::ostream& out) { - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; const char* sep = ""; - for (std::map::const_iterator j = m->begin() ; j != m->end() ; ++j) { - out << sep << (*j).first; + for ( std::map::const_iterator j = m->begin(); j != m->end(); ++j ) { + out << sep << ( *j ).first; sep = ", "; } } +VorDivToUV::Implementation* VorDivToUVFactory::build( const FunctionSpace& sp, const eckit::Configuration& config ) { + pthread_once( &once, init ); -VorDivToUV::Implementation *VorDivToUVFactory::build( const FunctionSpace& sp, const eckit::Configuration& config ) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::string suffix ( "("+sp.type()+")" ); - std::string name = config.getString("type",TRANS_DEFAULT)+suffix; + std::string suffix( "(" + sp.type() + ")" ); + std::string name = config.getString( "type", TRANS_DEFAULT ) + suffix; Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; - if( not config.has("type") and not has(name) ) { - name = std::string("local")+suffix; - Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; + if ( not config.has( "type" ) and not has( name ) ) { + name = std::string( "local" ) + suffix; + Log::debug() << "Looking for TransFactory [" << name << "]" << std::endl; } - return factory(name).make(sp,config); + return factory( name ).make( sp, config ); } +VorDivToUV::Implementation* VorDivToUVFactory::build( int truncation, const eckit::Configuration& config ) { + pthread_once( &once, init ); -VorDivToUV::Implementation *VorDivToUVFactory::build( int truncation, const eckit::Configuration& config ) { - - pthread_once(&once, init); - - eckit::AutoLock lock(local_mutex); + eckit::AutoLock lock( local_mutex ); static force_link static_linking; - std::string name = config.getString("type",TRANS_DEFAULT); + std::string name = config.getString( "type", TRANS_DEFAULT ); Log::debug() << "Looking for VorDivToUVFactory [" << name << "]" << std::endl; - if( not config.has("type") and not has(name) ) { - name = std::string("local"); - Log::debug() << "Looking for VorDivToUVFactory [" << name << "]" << std::endl; + if ( not config.has( "type" ) and not has( name ) ) { + name = std::string( "local" ); + Log::debug() << "Looking for VorDivToUVFactory [" << name << "]" << std::endl; } - return factory(name).make(truncation,config); + return factory( name ).make( truncation, config ); } +VorDivToUV::VorDivToUV() {} -VorDivToUV::VorDivToUV() { -} - -VorDivToUV::VorDivToUV( Implementation* impl ) : - impl_(impl) { -} +VorDivToUV::VorDivToUV( Implementation* impl ) : impl_( impl ) {} VorDivToUV::VorDivToUV( const FunctionSpace& sp, const eckit::Configuration& config ) : - impl_( VorDivToUVFactory::build(sp,config) ) -{ -} + impl_( VorDivToUVFactory::build( sp, config ) ) {} VorDivToUV::VorDivToUV( int truncation, const eckit::Configuration& config ) : - impl_( VorDivToUVFactory::build(truncation,config) ) -{ -} + impl_( VorDivToUVFactory::build( truncation, config ) ) {} -VorDivToUV::VorDivToUV( const VorDivToUV& other ) : - impl_(other.impl_) { -} +VorDivToUV::VorDivToUV( const VorDivToUV& other ) : impl_( other.impl_ ) {} int VorDivToUV::truncation() const { - return impl_->truncation(); + return impl_->truncation(); } // -- IFS type fields -- -// These fields have special interpretation required. You need to know what you're doing. +// These fields have special interpretation required. You need to know what +// you're doing. // See IFS trans library. void VorDivToUV::execute( const int nb_coeff, const int nb_fields, const double vorticity[], const double divergence[], - double U[], double V[], - const eckit::Configuration& config ) const { - impl_->execute( nb_coeff, nb_fields, vorticity, divergence, U, V, config ); + double U[], double V[], const eckit::Configuration& config ) const { + impl_->execute( nb_coeff, nb_fields, vorticity, divergence, U, V, config ); } - -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/VorDivToUV.h b/src/atlas/trans/VorDivToUV.h index ee2febbfb..88a1c198a 100644 --- a/src/atlas/trans/VorDivToUV.h +++ b/src/atlas/trans/VorDivToUV.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,10 +14,10 @@ #include #include "eckit/config/Configuration.h" -#include "eckit/memory/Owned.h" -#include "eckit/memory/SharedPtr.h" #include "eckit/io/Buffer.h" #include "eckit/io/DataHandle.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" #include "atlas/util/Config.h" @@ -24,11 +25,11 @@ // Forward declarations namespace atlas { - class Field; - class FieldSet; - class FunctionSpace; - class Grid; -} +class Field; +class FieldSet; +class FunctionSpace; +class Grid; +} // namespace atlas //----------------------------------------------------------------------------- @@ -38,96 +39,85 @@ namespace trans { //----------------------------------------------------------------------------- class VorDivToUVImpl : public eckit::Owned { - public: - virtual ~VorDivToUVImpl() = 0; virtual int truncation() const = 0; - // -- IFS type fields -- - // These fields have special interpretation required. You need to know what you're doing. - // See IFS trans library. + // -- IFS type fields -- + // These fields have special interpretation required. You need to know what + // you're doing. + // See IFS trans library. /*! - * @brief Compute spectral wind (U/V) from spectral vorticity/divergence - * - * U = u*cos(lat) - * V = v*cos(lat) - * - * @param nb_fields [in] Number of fields - * @param vorticity [in] Spectral vorticity - * @param divergence [in] Spectral divergence - * @param U [out] Spectral wind U = u*cos(lat) - * @param V [out] Spectral wind V = v*cos(lat) - */ - virtual void execute( const int nb_coeff, const int nb_fields, - const double vorticity[], const double divergence[], - double U[], double V[], - const eckit::Configuration& = util::NoConfig() ) const = 0; + * @brief Compute spectral wind (U/V) from spectral vorticity/divergence + * + * U = u*cos(lat) + * V = v*cos(lat) + * + * @param nb_fields [in] Number of fields + * @param vorticity [in] Spectral vorticity + * @param divergence [in] Spectral divergence + * @param U [out] Spectral wind U = u*cos(lat) + * @param V [out] Spectral wind V = v*cos(lat) + */ + virtual void execute( const int nb_coeff, const int nb_fields, const double vorticity[], const double divergence[], + double U[], double V[], const eckit::Configuration& = util::NoConfig() ) const = 0; }; // ------------------------------------------------------------------ - class VorDivToUVFactory { public: - /*! - * \brief build VorDivToUV - * \return VorDivToUVImpl - */ + * \brief build VorDivToUV + * \return VorDivToUVImpl + */ static VorDivToUVImpl* build( const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); static VorDivToUVImpl* build( int truncation, const eckit::Configuration& = util::NoConfig() ); /*! - * \brief list all registered trans implementations - */ - static void list(std::ostream &); + * \brief list all registered trans implementations + */ + static void list( std::ostream& ); - static bool has(const std::string& name); + static bool has( const std::string& name ); private: - std::string name_; virtual VorDivToUVImpl* make( const FunctionSpace& sp, const eckit::Configuration& ) { return nullptr; } virtual VorDivToUVImpl* make( int truncation, const eckit::Configuration& ) { return nullptr; } protected: - - VorDivToUVFactory(const std::string&); + VorDivToUVFactory( const std::string& ); virtual ~VorDivToUVFactory(); - }; //---------------------------------------------------------------------------------------------------------------------- -template +template class VorDivToUVBuilder : public VorDivToUVFactory { - virtual VorDivToUVImpl* make( const FunctionSpace& sp, const eckit::Configuration& config ) { - return new T(sp,config); - } - virtual VorDivToUVImpl* make( int truncation, const eckit::Configuration& config ) { - return new T(truncation, config); - } + virtual VorDivToUVImpl* make( const FunctionSpace& sp, const eckit::Configuration& config ) { + return new T( sp, config ); + } + virtual VorDivToUVImpl* make( int truncation, const eckit::Configuration& config ) { + return new T( truncation, config ); + } + public: - VorDivToUVBuilder(const std::string& name) : VorDivToUVFactory(name) {} + VorDivToUVBuilder( const std::string& name ) : VorDivToUVFactory( name ) {} }; //---------------------------------------------------------------------------------------------------------------------- class VorDivToUV { - public: - - using Implementation = VorDivToUVImpl; + using Implementation = VorDivToUVImpl; private: - - eckit::SharedPtr< Implementation > impl_; + eckit::SharedPtr impl_; public: - VorDivToUV(); VorDivToUV( Implementation* ); VorDivToUV( const VorDivToUV& ); @@ -135,25 +125,22 @@ class VorDivToUV { VorDivToUV( const FunctionSpace& sp, const eckit::Configuration& = util::NoConfig() ); VorDivToUV( int truncation, const eckit::Configuration& = util::NoConfig() ); - void hash(eckit::Hash&) const; + void hash( eckit::Hash& ) const; const Implementation* get() const { return impl_.get(); } operator bool() const { return impl_.owners(); } int truncation() const; - // -- IFS type fields -- - // These fields have special interpretation required. You need to know what you're doing. - // See IFS trans library. - - virtual void execute( const int nb_coeff, const int nb_fields, - const double vorticity[], const double divergence[], - double U[], double V[], - const eckit::Configuration& = util::NoConfig() ) const; + // -- IFS type fields -- + // These fields have special interpretation required. You need to know what + // you're doing. + // See IFS trans library. + virtual void execute( const int nb_coeff, const int nb_fields, const double vorticity[], const double divergence[], + double U[], double V[], const eckit::Configuration& = util::NoConfig() ) const; }; //---------------------------------------------------------------------------------------------------------------------- -} // namespace trans -} // namespace atlas - +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index a49d335dd..aae98839e 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -4,1707 +4,1446 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "atlas/trans/ifs/TransIFS.h" -#include "eckit/parser/JSON.h" #include "atlas/array.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/Spectral.h" #include "atlas/functionspace/StructuredColumns.h" #include "atlas/mesh/IsGhostNode.h" #include "atlas/mesh/Nodes.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "atlas/parallel/mpi/mpi.h" +#include "eckit/parser/JSON.h" using Topology = atlas::mesh::Nodes::Topology; -using atlas::mesh::IsGhostNode; -using atlas::functionspace::StructuredColumns; -using atlas::functionspace::NodeColumns; -using atlas::functionspace::Spectral; using atlas::Field; using atlas::FunctionSpace; using atlas::array::ArrayView; using atlas::array::make_view; +using atlas::functionspace::NodeColumns; +using atlas::functionspace::Spectral; +using atlas::functionspace::StructuredColumns; +using atlas::mesh::IsGhostNode; namespace atlas { namespace trans { namespace { -static TransBuilderGrid builder("ifs"); +static TransBuilderGrid builder( "ifs" ); } class TransParameters { public: - TransParameters( const TransIFS& trans, const eckit::Configuration& config ) : trans_(trans), config_(config) {} - ~TransParameters() {} + TransParameters( const TransIFS& trans, const eckit::Configuration& config ) : trans_( trans ), config_( config ) {} + ~TransParameters() {} - bool scalar_derivatives() const { - return config_.getBool("scalar_derivatives",false); - } + bool scalar_derivatives() const { return config_.getBool( "scalar_derivatives", false ); } - bool wind_EW_derivatives() const { - return config_.getBool("wind_EW_derivatives",false); - } + bool wind_EW_derivatives() const { return config_.getBool( "wind_EW_derivatives", false ); } - bool vorticity_divergence_fields() const { - return config_.getBool("vorticity_divergence_fields",false); - } + bool vorticity_divergence_fields() const { return config_.getBool( "vorticity_divergence_fields", false ); } - bool split_latitudes() const { - return config_.getBool("split_latitudes",true); - } + bool split_latitudes() const { return config_.getBool( "split_latitudes", true ); } - int fft() const { - static const std::map string_to_FFT = { {"FFT992",TRANS_FFT992},{"FFTW",TRANS_FFTW} }; - return string_to_FFT.at( config_.getString("fft","FFTW") ); - } + int fft() const { + static const std::map string_to_FFT = {{"FFT992", TRANS_FFT992}, {"FFTW", TRANS_FFTW}}; + return string_to_FFT.at( config_.getString( "fft", "FFTW" ) ); + } - bool flt() const { - return config_.getBool("flt",false); - } + bool flt() const { return config_.getBool( "flt", false ); } - std::string read_legendre() const { - return config_.getString("read_legendre",""); - } + std::string read_legendre() const { return config_.getString( "read_legendre", "" ); } - std::string write_legendre() const { - return config_.getString("write_legendre",""); - } + std::string write_legendre() const { return config_.getString( "write_legendre", "" ); } - bool global() const { - return config_.getBool("global",false); - } + bool global() const { return config_.getBool( "global", false ); } - int nproma() const { - return config_.getInt("nproma",trans_->ngptot); - } + int nproma() const { return config_.getInt( "nproma", trans_->ngptot ); } - int ngpblks() const { - int _ngptot = trans_->ngptot; - int _nproma = nproma(); - ASSERT(_ngptot%_nproma == 0); // assert _ngptot is divisable by nproma - return _ngptot/_nproma; - } + int ngpblks() const { + int _ngptot = trans_->ngptot; + int _nproma = nproma(); + ASSERT( _ngptot % _nproma == 0 ); // assert _ngptot is divisable by nproma + return _ngptot / _nproma; + } private: - const Trans_t* trans_; - const eckit::Configuration& config_; + const Trans_t* trans_; + const eckit::Configuration& config_; }; namespace { std::string fieldset_functionspace( const FieldSet& fields ) { - std::string functionspace("undefined"); - for( size_t jfld = 0; jfld < fields.size(); ++jfld) { - if( functionspace == "undefined" ) - functionspace = fields[jfld].functionspace().type(); - if( fields[jfld].functionspace().type() != functionspace ) { - throw eckit::SeriousBug(": fielset has fields with different functionspaces",Here()); + std::string functionspace( "undefined" ); + for ( size_t jfld = 0; jfld < fields.size(); ++jfld ) { + if ( functionspace == "undefined" ) functionspace = fields[jfld].functionspace().type(); + if ( fields[jfld].functionspace().type() != functionspace ) { + throw eckit::SeriousBug( ": fielset has fields with different functionspaces", Here() ); + } } - } - return functionspace; + return functionspace; } -void assert_spectral_functionspace( const FieldSet& fields ){ - for( size_t jfld = 0; jfld < fields.size(); ++jfld ) { - ASSERT( functionspace::Spectral( fields[jfld].functionspace() ) ); - } +void assert_spectral_functionspace( const FieldSet& fields ) { + for ( size_t jfld = 0; jfld < fields.size(); ++jfld ) { + ASSERT( functionspace::Spectral( fields[jfld].functionspace() ) ); + } +} + +void trans_check( const int code, const char* msg, const eckit::CodeLocation& location ) { + if ( code != TRANS_SUCCESS ) { + std::stringstream errmsg; + errmsg << "atlas::trans ERROR: " << msg << " failed: \n"; + errmsg << ::trans_error_msg( code ); + throw eckit::Exception( errmsg.str(), location ); + } } +#define TRANS_CHECK( CALL ) trans_check( CALL, #CALL, Here() ) -void trans_check(const int code, const char* msg, const eckit::CodeLocation& location) { - if(code != TRANS_SUCCESS) { - std::stringstream errmsg; - errmsg << "atlas::trans ERROR: " << msg << " failed: \n"; - errmsg << ::trans_error_msg(code); - throw eckit::Exception(errmsg.str(),location); - } +} // namespace + +void TransIFS::dirtrans( const Field& gpfield, Field& spfield, const eckit::Configuration& config ) const { + ASSERT( functionspace::Spectral( spfield.functionspace() ) ); + if ( functionspace::StructuredColumns( gpfield.functionspace() ) ) { + __dirtrans( functionspace::StructuredColumns( gpfield.functionspace() ), gpfield, + functionspace::Spectral( spfield.functionspace() ), spfield, config ); + } + else if ( functionspace::NodeColumns( gpfield.functionspace() ) ) { + __dirtrans( functionspace::NodeColumns( gpfield.functionspace() ), gpfield, + functionspace::Spectral( spfield.functionspace() ), spfield, config ); + } + else { + NOTIMP; + } } -#define TRANS_CHECK( CALL ) trans_check(CALL, #CALL, Here() ) +void TransIFS::dirtrans( const FieldSet& gpfields, FieldSet& spfields, const eckit::Configuration& config ) const { + assert_spectral_functionspace( spfields ); + std::string functionspace( fieldset_functionspace( gpfields ) ); + + if ( functionspace == StructuredColumns::type() ) { + __dirtrans( StructuredColumns( gpfields[0].functionspace() ), gpfields, Spectral( spfields[0].functionspace() ), + spfields, config ); + } + else if ( functionspace == NodeColumns::type() ) { + __dirtrans( NodeColumns( gpfields[0].functionspace() ), gpfields, Spectral( spfields[0].functionspace() ), + spfields, config ); + } + else { + NOTIMP; + } } -void TransIFS::dirtrans( const Field& gpfield, - Field& spfield, - const eckit::Configuration& config ) const { - ASSERT( functionspace::Spectral(spfield.functionspace()) ); - if( functionspace::StructuredColumns( gpfield.functionspace() ) ) { - __dirtrans( functionspace::StructuredColumns( gpfield.functionspace() ), gpfield , functionspace::Spectral( spfield.functionspace() ), spfield, config ); - } else if( functionspace::NodeColumns( gpfield.functionspace() ) ) { - __dirtrans( functionspace::NodeColumns( gpfield.functionspace() ), gpfield, functionspace::Spectral( spfield.functionspace() ), spfield, config ); - } else { - NOTIMP; - } +void TransIFS::invtrans( const Field& spfield, Field& gpfield, const eckit::Configuration& config ) const { + ASSERT( Spectral( spfield.functionspace() ) ); + if ( StructuredColumns( gpfield.functionspace() ) ) { + __invtrans( Spectral( spfield.functionspace() ), spfield, StructuredColumns( gpfield.functionspace() ), gpfield, + config ); + } + else if ( NodeColumns( gpfield.functionspace() ) ) { + __invtrans( Spectral( spfield.functionspace() ), spfield, NodeColumns( gpfield.functionspace() ), gpfield, + config ); + } + else { + NOTIMP; + } } +void TransIFS::invtrans( const FieldSet& spfields, FieldSet& gpfields, const eckit::Configuration& config ) const { + assert_spectral_functionspace( spfields ); + std::string functionspace( fieldset_functionspace( gpfields ) ); -void TransIFS::dirtrans( const FieldSet& gpfields, - FieldSet& spfields, - const eckit::Configuration& config ) const { - assert_spectral_functionspace(spfields); - std::string functionspace( fieldset_functionspace(gpfields) ); - - if( functionspace == StructuredColumns::type() ) { - __dirtrans( StructuredColumns( gpfields[0].functionspace() ), gpfields, - Spectral( spfields[0].functionspace()), spfields, config ); - } else if ( functionspace == NodeColumns::type() ) { - __dirtrans( NodeColumns( gpfields[0].functionspace() ), gpfields, - Spectral( spfields[0].functionspace()), spfields, config ); - } else { - NOTIMP; - } -} - - -void TransIFS::invtrans( const Field& spfield, - Field& gpfield, - const eckit::Configuration& config ) const -{ - ASSERT( Spectral( spfield.functionspace()) ); - if( StructuredColumns( gpfield.functionspace()) ) { - __invtrans( Spectral( spfield.functionspace() ), spfield, StructuredColumns( gpfield.functionspace() ), gpfield, config ); - } else if( NodeColumns( gpfield.functionspace()) ) { - __invtrans( Spectral( spfield.functionspace() ), spfield, NodeColumns( gpfield.functionspace() ), gpfield, config ); - } else { - NOTIMP; - } -} - -void TransIFS::invtrans( const FieldSet& spfields, - FieldSet& gpfields, - const eckit::Configuration& config ) const -{ - assert_spectral_functionspace( spfields ); - std::string functionspace( fieldset_functionspace(gpfields) ); - - if( functionspace == StructuredColumns::type() ) { - __invtrans( Spectral(spfields[0].functionspace()), spfields, StructuredColumns(gpfields[0].functionspace()), gpfields, config ); - } else if ( functionspace == NodeColumns::type() ) { - __invtrans( Spectral(spfields[0].functionspace()), spfields, NodeColumns(gpfields[0].functionspace()), gpfields, config ); - } else { - NOTIMP; - } + if ( functionspace == StructuredColumns::type() ) { + __invtrans( Spectral( spfields[0].functionspace() ), spfields, StructuredColumns( gpfields[0].functionspace() ), + gpfields, config ); + } + else if ( functionspace == NodeColumns::type() ) { + __invtrans( Spectral( spfields[0].functionspace() ), spfields, NodeColumns( gpfields[0].functionspace() ), + gpfields, config ); + } + else { + NOTIMP; + } } // -------------------------------------------------------------------------------------------- -void TransIFS::invtrans_grad( - const Field& spfield, - Field& gradfield, - const eckit::Configuration& config ) const -{ - ASSERT( Spectral(spfield.functionspace()) ); - ASSERT( NodeColumns(gradfield.functionspace()) ); - __invtrans_grad( Spectral(spfield.functionspace()), spfield, NodeColumns(gradfield.functionspace()), gradfield, config ); -} - -void TransIFS::invtrans_grad( - const FieldSet& spfields, - FieldSet& gradfields, - const eckit::Configuration& config ) const -{ - assert_spectral_functionspace(spfields); - std::string functionspace( fieldset_functionspace(gradfields) ); - - if ( functionspace == NodeColumns::type() ) { - __invtrans_grad( Spectral( spfields[0].functionspace()), spfields, - NodeColumns( gradfields[0].functionspace() ), gradfields, config ); - } else { - NOTIMP; - } -} - -void TransIFS::dirtrans_wind2vordiv( - const Field& gpwind, - Field& spvor, Field& spdiv, - const eckit::Configuration& config ) const { - ASSERT( Spectral( spvor.functionspace()) ); - ASSERT( Spectral( spdiv.functionspace()) ); - ASSERT( NodeColumns( gpwind.functionspace()) ); - __dirtrans_wind2vordiv( NodeColumns(gpwind.functionspace()), gpwind, Spectral(spvor.functionspace()), spvor, spdiv, config ); -} - -void TransIFS::invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, - Field& gpwind, +void TransIFS::invtrans_grad( const Field& spfield, Field& gradfield, const eckit::Configuration& config ) const { + ASSERT( Spectral( spfield.functionspace() ) ); + ASSERT( NodeColumns( gradfield.functionspace() ) ); + __invtrans_grad( Spectral( spfield.functionspace() ), spfield, NodeColumns( gradfield.functionspace() ), gradfield, + config ); +} + +void TransIFS::invtrans_grad( const FieldSet& spfields, FieldSet& gradfields, + const eckit::Configuration& config ) const { + assert_spectral_functionspace( spfields ); + std::string functionspace( fieldset_functionspace( gradfields ) ); + + if ( functionspace == NodeColumns::type() ) { + __invtrans_grad( Spectral( spfields[0].functionspace() ), spfields, + NodeColumns( gradfields[0].functionspace() ), gradfields, config ); + } + else { + NOTIMP; + } +} + +void TransIFS::dirtrans_wind2vordiv( const Field& gpwind, Field& spvor, Field& spdiv, const eckit::Configuration& config ) const { - ASSERT( Spectral( spvor.functionspace() ) ); - ASSERT( Spectral( spdiv.functionspace() ) ); - ASSERT( NodeColumns( gpwind.functionspace() ) ); - __invtrans_vordiv2wind( Spectral(spvor.functionspace()), spvor, spdiv, NodeColumns(gpwind.functionspace()), gpwind, config ); -} - - -void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra[], - const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const eckit::Configuration& config ) const -{ - ATLAS_TRACE("TransIFS::invtrans"); - TransParameters params(*this,config); - struct ::InvTrans_t args = new_invtrans(trans_.get()); - args.nscalar = nb_scalar_fields; - args.rspscalar = scalar_spectra; - args.nvordiv = nb_vordiv_fields; - args.rspvor = vorticity_spectra; - args.rspdiv = divergence_spectra; - args.rgp = gp_fields; - args.lglobal = params.global(); - args.lscalarders = params.scalar_derivatives(); - args.luvder_EW = params.wind_EW_derivatives(); - args.lvordivgp = params.vorticity_divergence_fields(); - args.nproma = params.nproma(); - args.ngpblks = params.ngpblks(); - TRANS_CHECK( ::trans_invtrans(&args) ); + ASSERT( Spectral( spvor.functionspace() ) ); + ASSERT( Spectral( spdiv.functionspace() ) ); + ASSERT( NodeColumns( gpwind.functionspace() ) ); + __dirtrans_wind2vordiv( NodeColumns( gpwind.functionspace() ), gpwind, Spectral( spvor.functionspace() ), spvor, + spdiv, config ); } -/////////////////////////////////////////////////////////////////////////////// +void TransIFS::invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, Field& gpwind, + const eckit::Configuration& config ) const { + ASSERT( Spectral( spvor.functionspace() ) ); + ASSERT( Spectral( spdiv.functionspace() ) ); + ASSERT( NodeColumns( gpwind.functionspace() ) ); + __invtrans_vordiv2wind( Spectral( spvor.functionspace() ), spvor, spdiv, NodeColumns( gpwind.functionspace() ), + gpwind, config ); +} -void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra[], - double gp_fields[], - const eckit::Configuration& config ) const -{ - return invtrans( nb_scalar_fields, scalar_spectra, 0, nullptr, nullptr, gp_fields, config ); +void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra[], const int nb_vordiv_fields, + const double vorticity_spectra[], const double divergence_spectra[], double gp_fields[], + const eckit::Configuration& config ) const { + ATLAS_TRACE( "TransIFS::invtrans" ); + TransParameters params( *this, config ); + struct ::InvTrans_t args = new_invtrans( trans_.get() ); + args.nscalar = nb_scalar_fields; + args.rspscalar = scalar_spectra; + args.nvordiv = nb_vordiv_fields; + args.rspvor = vorticity_spectra; + args.rspdiv = divergence_spectra; + args.rgp = gp_fields; + args.lglobal = params.global(); + args.lscalarders = params.scalar_derivatives(); + args.luvder_EW = params.wind_EW_derivatives(); + args.lvordivgp = params.vorticity_divergence_fields(); + args.nproma = params.nproma(); + args.ngpblks = params.ngpblks(); + TRANS_CHECK(::trans_invtrans( &args ) ); } /////////////////////////////////////////////////////////////////////////////// -void TransIFS::invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const eckit::Configuration& config ) const -{ - return invtrans( 0, nullptr, nb_vordiv_fields, vorticity_spectra, divergence_spectra, gp_fields, config ); +void TransIFS::invtrans( const int nb_scalar_fields, const double scalar_spectra[], double gp_fields[], + const eckit::Configuration& config ) const { + return invtrans( nb_scalar_fields, scalar_spectra, 0, nullptr, nullptr, gp_fields, config ); } /////////////////////////////////////////////////////////////////////////////// -void TransIFS::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], - const eckit::Configuration& config ) const -{ - ATLAS_TRACE(); - TransParameters params(*this,config); - struct ::DirTrans_t args = new_dirtrans(trans_.get()); - args.nscalar = nb_fields; - args.rgp = scalar_fields; - args.rspscalar = scalar_spectra; - args.lglobal = params.global(); - args.nproma = params.nproma(); - args.ngpblks = params.ngpblks(); - TRANS_CHECK( ::trans_dirtrans(&args) ); +void TransIFS::invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], + const double divergence_spectra[], double gp_fields[], + const eckit::Configuration& config ) const { + return invtrans( 0, nullptr, nb_vordiv_fields, vorticity_spectra, divergence_spectra, gp_fields, config ); } /////////////////////////////////////////////////////////////////////////////// -void TransIFS::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], - const eckit::Configuration& config ) const -{ - ATLAS_TRACE(); - TransParameters params(*this,config); - struct ::DirTrans_t args = new_dirtrans(trans_.get()); - args.nvordiv = nb_fields; - args.rspvor = vorticity_spectra; - args.rspdiv = divergence_spectra; - args.rgp = wind_fields; - args.lglobal = params.global(); - args.nproma = params.nproma(); - args.ngpblks = params.ngpblks(); - TRANS_CHECK( ::trans_dirtrans(&args) ); +void TransIFS::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& config ) const { + ATLAS_TRACE(); + TransParameters params( *this, config ); + struct ::DirTrans_t args = new_dirtrans( trans_.get() ); + args.nscalar = nb_fields; + args.rgp = scalar_fields; + args.rspscalar = scalar_spectra; + args.lglobal = params.global(); + args.nproma = params.nproma(); + args.ngpblks = params.ngpblks(); + TRANS_CHECK(::trans_dirtrans( &args ) ); } -} +/////////////////////////////////////////////////////////////////////////////// + +void TransIFS::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], + double divergence_spectra[], const eckit::Configuration& config ) const { + ATLAS_TRACE(); + TransParameters params( *this, config ); + struct ::DirTrans_t args = new_dirtrans( trans_.get() ); + args.nvordiv = nb_fields; + args.rspvor = vorticity_spectra; + args.rspdiv = divergence_spectra; + args.rgp = wind_fields; + args.lglobal = params.global(); + args.nproma = params.nproma(); + args.ngpblks = params.ngpblks(); + TRANS_CHECK(::trans_dirtrans( &args ) ); } +} // namespace trans +} // namespace atlas // anonymous namespace namespace { -struct PackNodeColumns -{ - ArrayView& rgpview_; - IsGhostNode is_ghost; - size_t f; - - PackNodeColumns( ArrayView& rgpview, const NodeColumns& fs ) : - rgpview_(rgpview), is_ghost( fs.nodes() ), f(0) {} - - void operator()(const Field& field, int components = 0) { - switch (field.rank()) { - case 1: - pack_1(field,components); - break; - case 2: - pack_2(field,components); - break; - case 3: - pack_3(field,components); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; +struct PackNodeColumns { + ArrayView& rgpview_; + IsGhostNode is_ghost; + size_t f; + + PackNodeColumns( ArrayView& rgpview, const NodeColumns& fs ) : + rgpview_( rgpview ), + is_ghost( fs.nodes() ), + f( 0 ) {} + + void operator()( const Field& field, int components = 0 ) { + switch ( field.rank() ) { + case 1: + pack_1( field, components ); + break; + case 2: + pack_2( field, components ); + break; + case 3: + pack_3( field, components ); + break; + default: + ATLAS_DEBUG_VAR( field.rank() ); + NOTIMP; + break; + } } - } - void pack_1(const Field& field, int) - { - const ArrayView gpfield = make_view( field ); - size_t n=0; - for( size_t jnode=0; jnode gpfield = make_view( field ); - const size_t nvars = gpfield.shape(1); - for( size_t jvar=0; jvar gpfield = make_view( field ); - if( not components ) components = gpfield.shape(2); - for( size_t jcomp=0; jcomp gpfield = make_view( field ); + size_t n = 0; + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + if ( !is_ghost( jnode ) ) { + rgpview_( f, n ) = gpfield( jnode ); + ++n; + } } ++f; - } } - } + void pack_2( const Field& field, int ) { + const ArrayView gpfield = make_view( field ); + const size_t nvars = gpfield.shape( 1 ); + for ( size_t jvar = 0; jvar < nvars; ++jvar ) { + size_t n = 0; + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + if ( !is_ghost( jnode ) ) { + rgpview_( f, n ) = gpfield( jnode, jvar ); + ++n; + } + } + ++f; + } + } + void pack_3( const Field& field, int components ) { + const ArrayView gpfield = make_view( field ); + if ( not components ) components = gpfield.shape( 2 ); + for ( size_t jcomp = 0; jcomp < size_t( components ); ++jcomp ) { + for ( size_t jlev = 0; jlev < gpfield.shape( 1 ); ++jlev ) { + size_t n = 0; + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + if ( !is_ghost( jnode ) ) { + rgpview_( f, n ) = gpfield( jnode, jlev, jcomp ); + ++n; + } + } + ++f; + } + } + } }; - -struct PackStructuredColumns -{ - ArrayView& rgpview_; - size_t f; - - PackStructuredColumns( ArrayView& rgpview ) : - rgpview_(rgpview), f(0) {} - - void operator()(const Field& field) { - switch (field.rank()) { - case 1: - pack_1(field); - break; - case 2: - pack_2(field); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; +struct PackStructuredColumns { + ArrayView& rgpview_; + size_t f; + + PackStructuredColumns( ArrayView& rgpview ) : rgpview_( rgpview ), f( 0 ) {} + + void operator()( const Field& field ) { + switch ( field.rank() ) { + case 1: + pack_1( field ); + break; + case 2: + pack_2( field ); + break; + default: + ATLAS_DEBUG_VAR( field.rank() ); + NOTIMP; + break; + } } - } - void pack_1(const Field& field) - { - const ArrayView gpfield = make_view( field ); - size_t n=0; - for( size_t jnode=0; jnode gpfield = make_view( field ); - const size_t nvars = gpfield.shape(1); - for( size_t jvar=0; jvar gpfield = make_view( field ); + size_t n = 0; + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + rgpview_( f, n ) = gpfield( jnode ); + ++n; + } + ++f; + } + void pack_2( const Field& field ) { + const ArrayView gpfield = make_view( field ); + const size_t nvars = gpfield.shape( 1 ); + for ( size_t jvar = 0; jvar < nvars; ++jvar ) { + size_t n = 0; + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + rgpview_( f, n ) = gpfield( jnode, jvar ); + ++n; + } + ++f; + } + } }; -struct PackSpectral -{ - ArrayView& rspecview_; - size_t f; - PackSpectral( ArrayView& rspecview ) : - rspecview_(rspecview), f(0) {} - - void operator()(const Field& field) { - switch (field.rank()) { - case 1: - pack_1(field); - break; - case 2: - pack_2(field); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; +struct PackSpectral { + ArrayView& rspecview_; + size_t f; + PackSpectral( ArrayView& rspecview ) : rspecview_( rspecview ), f( 0 ) {} + + void operator()( const Field& field ) { + switch ( field.rank() ) { + case 1: + pack_1( field ); + break; + case 2: + pack_2( field ); + break; + default: + ATLAS_DEBUG_VAR( field.rank() ); + NOTIMP; + break; + } } - } - void pack_1(const Field& field) - { - const ArrayView spfield = make_view( field ); + void pack_1( const Field& field ) { + const ArrayView spfield = make_view( field ); - for( size_t jwave=0; jwave spfield = make_view( field ); + void pack_2( const Field& field ) { + const ArrayView spfield = make_view( field ); - const size_t nvars = spfield.shape(1); + const size_t nvars = spfield.shape( 1 ); - for( size_t jvar=0; jvar& rgpview_; - IsGhostNode is_ghost; - size_t f; - - UnpackNodeColumns( const ArrayView& rgpview, const NodeColumns& fs ) : - rgpview_(rgpview), is_ghost( fs.nodes() ), f(0) {} - - void operator()(Field& field, int components = 0) { - switch (field.rank()) { - case 1: - unpack_1(field,components); - break; - case 2: - unpack_2(field,components); - break; - case 3: - unpack_3(field,components); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; +struct UnpackNodeColumns { + const ArrayView& rgpview_; + IsGhostNode is_ghost; + size_t f; + + UnpackNodeColumns( const ArrayView& rgpview, const NodeColumns& fs ) : + rgpview_( rgpview ), + is_ghost( fs.nodes() ), + f( 0 ) {} + + void operator()( Field& field, int components = 0 ) { + switch ( field.rank() ) { + case 1: + unpack_1( field, components ); + break; + case 2: + unpack_2( field, components ); + break; + case 3: + unpack_3( field, components ); + break; + default: + ATLAS_DEBUG_VAR( field.rank() ); + NOTIMP; + break; + } } - } - void unpack_1(Field& field, int) - { - ArrayView gpfield = make_view( field ); - size_t n(0); - for( size_t jnode=0; jnode gpfield = make_view( field ); - const size_t nvars = gpfield.shape(1); - for( size_t jvar=0; jvar gpfield = make_view( field ); - if( not components ) components = gpfield.shape(2); - for( size_t jcomp=0; jcomp gpfield = make_view( field ); + size_t n( 0 ); + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + if ( !is_ghost( jnode ) ) { + gpfield( jnode ) = rgpview_( f, n ); + ++n; + } } ++f; - } } - } + void unpack_2( Field& field, int ) { + ArrayView gpfield = make_view( field ); + const size_t nvars = gpfield.shape( 1 ); + for ( size_t jvar = 0; jvar < nvars; ++jvar ) { + int n = 0; + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + if ( !is_ghost( jnode ) ) { + gpfield( jnode, jvar ) = rgpview_( f, n ); + ++n; + } + } + ++f; + } + } + void unpack_3( Field& field, int components ) { + ArrayView gpfield = make_view( field ); + if ( not components ) components = gpfield.shape( 2 ); + for ( size_t jcomp = 0; jcomp < size_t( components ); ++jcomp ) { + for ( size_t jlev = 0; jlev < gpfield.shape( 1 ); ++jlev ) { + size_t n = 0; + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + if ( !is_ghost( jnode ) ) { + gpfield( jnode, jlev, jcomp ) = rgpview_( f, n ); + ++n; + } + } + ++f; + } + } + } }; -struct UnpackStructuredColumns -{ - const ArrayView& rgpview_; - size_t f; - - UnpackStructuredColumns( const ArrayView& rgpview ) : - rgpview_(rgpview), f(0) {} - - void operator()(Field& field) { - switch (field.rank()) { - case 1: - unpack_1(field); - break; - case 2: - unpack_2(field); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; +struct UnpackStructuredColumns { + const ArrayView& rgpview_; + size_t f; + + UnpackStructuredColumns( const ArrayView& rgpview ) : rgpview_( rgpview ), f( 0 ) {} + + void operator()( Field& field ) { + switch ( field.rank() ) { + case 1: + unpack_1( field ); + break; + case 2: + unpack_2( field ); + break; + default: + ATLAS_DEBUG_VAR( field.rank() ); + NOTIMP; + break; + } } - } - void unpack_1(Field& field) - { - ArrayView gpfield = make_view( field ); - size_t n=0; - for( size_t jnode=0; jnode gpfield = make_view( field ); - const size_t nvars = gpfield.shape(1); - for( size_t jvar=0; jvar gpfield = make_view( field ); + size_t n = 0; + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + gpfield( jnode ) = rgpview_( f, n ); + ++n; + } + ++f; + } + void unpack_2( Field& field ) { + ArrayView gpfield = make_view( field ); + const size_t nvars = gpfield.shape( 1 ); + for ( size_t jvar = 0; jvar < nvars; ++jvar ) { + size_t n = 0; + for ( size_t jnode = 0; jnode < gpfield.shape( 0 ); ++jnode ) { + gpfield( jnode, jvar ) = rgpview_( f, n ); + ++n; + } + ++f; + } + } }; -struct UnpackSpectral -{ - const ArrayView& rspecview_; - size_t f; - UnpackSpectral( const ArrayView& rspecview ) : - rspecview_(rspecview), f(0) {} - - void operator()(Field& field) { - switch (field.rank()) { - case 1: - unpack_1(field); - break; - case 2: - unpack_2(field); - break; - default: - ATLAS_DEBUG_VAR(field.rank()); - NOTIMP; - break; +struct UnpackSpectral { + const ArrayView& rspecview_; + size_t f; + UnpackSpectral( const ArrayView& rspecview ) : rspecview_( rspecview ), f( 0 ) {} + + void operator()( Field& field ) { + switch ( field.rank() ) { + case 1: + unpack_1( field ); + break; + case 2: + unpack_2( field ); + break; + default: + ATLAS_DEBUG_VAR( field.rank() ); + NOTIMP; + break; + } } - } - void unpack_1(Field& field) - { - ArrayView spfield = make_view( field ); + void unpack_1( Field& field ) { + ArrayView spfield = make_view( field ); - for( size_t jwave=0; jwave spfield = make_view( field ); + void unpack_2( Field& field ) { + ArrayView spfield = make_view( field ); - const size_t nvars = spfield.shape(1); + const size_t nvars = spfield.shape( 1 ); - for( size_t jvar=0; jvar( new ::Trans_t, [](::Trans_t* p ) { + ::trans_delete( p ); + delete p; + } ); + + if ( auto gg = grid::GaussianGrid( grid ) ) { + ctor_rgg( gg.ny(), gg.nx().data(), truncation, config ); + return; + } + if ( auto ll = grid::RegularLonLatGrid( grid ) ) { + if ( ll.standard() || ll.shifted() ) { + ctor_lonlat( ll.nx(), ll.ny(), truncation, config ); + return; + } + } + throw eckit::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 long pl[], long truncation, const eckit::Configuration& config ) { + TransParameters p( *this, config ); + 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_set_cache( trans_.get(), cache_, cachesize_ ) ); + + if ( p.read_legendre().size() && mpi::comm().size() == 1 ) { + eckit::PathName file( p.read_legendre() ); + if ( not file.exists() ) { + std::stringstream msg; + msg << "File " << file << " doesn't exist"; + throw eckit::CantOpenFile( msg.str(), Here() ); + } + 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_->fft = p.fft(); + trans_->lsplit = p.split_latitudes(); + trans_->flt = p.flt(); + 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_ ) ); + + if ( p.read_legendre().size() && mpi::comm().size() == 1 ) { + eckit::PathName file( p.read_legendre() ); + if ( not file.exists() ) { + std::stringstream msg; + msg << "File " << file << " doesn't exist"; + throw eckit::CantOpenFile( msg.str(), Here() ); + } + 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_->fft = p.fft(); + trans_->lsplit = p.split_latitudes(); + trans_->flt = p.flt(); + + TRANS_CHECK(::trans_setup( trans_.get() ) ); } +// -------------------------------------------------------------------------------------------- -TransIFS::~TransIFS() -{ +void TransIFS::__dirtrans( const functionspace::NodeColumns& gp, const Field& gpfield, const Spectral& sp, + Field& spfield, const eckit::Configuration& config ) const { + FieldSet gpfields; + gpfields.add( gpfield ); + FieldSet spfields; + spfields.add( spfield ); + __dirtrans( gp, gpfields, sp, spfields, config ); } -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); - delete p; - }); - - if( auto gg = grid::GaussianGrid(grid) ) { - ctor_rgg(gg.ny(), gg.nx().data(), truncation, config ); - return; - } - if( auto ll = grid::RegularLonLatGrid(grid) ) { - if( ll.standard() || ll.shifted() ) { - ctor_lonlat( ll.nx(), ll.ny(), truncation, config ); - return; - } - } - throw eckit::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 long pl[], long truncation, const eckit::Configuration& config ) -{ - TransParameters p(*this,config); - std::vector nloen(nlat); - for( long jlat=0; jlat1)); - 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_)); - - if( p.read_legendre().size() && mpi::comm().size() == 1 ) - { - eckit::PathName file( p.read_legendre() ); - if( not file.exists() ) - { - std::stringstream msg; msg << "File " << file << " doesn't exist"; - throw eckit::CantOpenFile(msg.str(),Here()); - } - 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_->fft = p.fft(); - trans_->lsplit = p.split_latitudes(); - trans_->flt = p.flt(); - 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_)); - - if( p.read_legendre().size() && mpi::comm().size() == 1 ) { - eckit::PathName file( p.read_legendre() ); - if( not file.exists() ) +// -------------------------------------------------------------------------------------------- + +void TransIFS::__dirtrans( const functionspace::NodeColumns& gp, const FieldSet& gpfields, const Spectral& sp, + FieldSet& spfields, const eckit::Configuration& ) const { + assertCompatibleDistributions( gp, sp ); + + // Count total number of fields and do sanity checks + int nfld( 0 ); + for ( size_t jfld = 0; jfld < gpfields.size(); ++jfld ) { + const Field& f = gpfields[jfld]; + nfld += f.stride( 0 ); + } + + int trans_spnfld( 0 ); + for ( size_t jfld = 0; jfld < spfields.size(); ++jfld ) { + const Field& f = spfields[jfld]; + trans_spnfld += f.stride( 0 ); + } + + if ( nfld != trans_spnfld ) { + throw eckit::SeriousBug( "dirtrans: different number of gridpoint fields than spectral fields", Here() ); + } + // Arrays Trans expects + array::ArrayT rgp( nfld, ngptot() ); + array::ArrayT rspec( nspec2(), nfld ); + + array::ArrayView rgpview = array::make_view( rgp ); + array::ArrayView rspecview = array::make_view( rspec ); + + // Pack gridpoints { - std::stringstream msg; msg << "File " << file << " doesn't exist"; - throw eckit::CantOpenFile(msg.str(),Here()); + PackNodeColumns pack( rgpview, gp ); + for ( size_t jfld = 0; jfld < gpfields.size(); ++jfld ) + pack( gpfields[jfld] ); } - 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_->fft = p.fft(); - trans_->lsplit = p.split_latitudes(); - trans_->flt = p.flt(); + // Do transform + { + struct ::DirTrans_t transform = ::new_dirtrans( trans_.get() ); + transform.nscalar = nfld; + transform.rgp = rgp.data(); + transform.rspscalar = rspec.data(); - TRANS_CHECK(::trans_setup(trans_.get())); -} + TRANS_CHECK(::trans_dirtrans( &transform ) ); + } + // Unpack the spectral fields + { + UnpackSpectral unpack( rspecview ); + for ( size_t jfld = 0; jfld < spfields.size(); ++jfld ) + unpack( spfields[jfld] ); + } +} // -------------------------------------------------------------------------------------------- +void TransIFS::__dirtrans( const StructuredColumns& gp, const Field& gpfield, const Spectral& sp, Field& spfield, + const eckit::Configuration& ) const { + ASSERT( gpfield.functionspace() == 0 || functionspace::StructuredColumns( gpfield.functionspace() ) ); + ASSERT( spfield.functionspace() == 0 || functionspace::Spectral( spfield.functionspace() ) ); + assertCompatibleDistributions( gp, sp ); + + if ( gpfield.stride( 0 ) != spfield.stride( 0 ) ) { + throw eckit::SeriousBug( "dirtrans: different number of gridpoint fields than spectral fields", Here() ); + } + if ( (int)gpfield.shape( 0 ) != ngptot() ) { + throw eckit::SeriousBug( "dirtrans: slowest moving index must be ngptot", Here() ); + } + const int nfld = gpfield.stride( 0 ); -void TransIFS::__dirtrans( const functionspace::NodeColumns& gp, const Field& gpfield, - const Spectral& sp, Field& spfield, const eckit::Configuration& config ) const -{ - FieldSet gpfields; gpfields.add(gpfield); - FieldSet spfields; spfields.add(spfield); - __dirtrans(gp,gpfields,sp,spfields,config); + // Do transform + { + struct ::DirTrans_t transform = ::new_dirtrans( trans_.get() ); + transform.nscalar = nfld; + transform.rgp = gpfield.data(); + transform.rspscalar = spfield.data(); + transform.ngpblks = gpfield.shape( 0 ); + transform.nproma = 1; + TRANS_CHECK(::trans_dirtrans( &transform ) ); + } } +void TransIFS::__dirtrans( const StructuredColumns& gp, const FieldSet& gpfields, const Spectral& sp, + FieldSet& spfields, const eckit::Configuration& ) const { + assertCompatibleDistributions( gp, sp ); -// -------------------------------------------------------------------------------------------- + // Count total number of fields and do sanity checks + int nfld( 0 ); + for ( size_t jfld = 0; jfld < gpfields.size(); ++jfld ) { + const Field& f = gpfields[jfld]; + nfld += f.stride( 0 ); + ASSERT( f.functionspace() == 0 || functionspace::StructuredColumns( f.functionspace() ) ); + } -void TransIFS::__dirtrans( const functionspace::NodeColumns& gp,const FieldSet& gpfields, - const Spectral& sp, FieldSet& spfields, const eckit::Configuration& ) const -{ - assertCompatibleDistributions( gp, sp ); - - // Count total number of fields and do sanity checks - int nfld(0); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - { - const Field& f = gpfields[jfld]; - nfld += f.stride(0); - } - - int trans_spnfld(0); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - { - const Field& f = spfields[jfld]; - trans_spnfld += f.stride(0); - } - - if( nfld != trans_spnfld ) - { - throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); - } - // Arrays Trans expects - array::ArrayT rgp(nfld,ngptot()); - array::ArrayT rspec(nspec2(),nfld); - - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); - - // Pack gridpoints - { - PackNodeColumns pack(rgpview,gp); - for( size_t jfld=0; jfld(); - transform.rspscalar = rspec.data(); - - TRANS_CHECK( ::trans_dirtrans(&transform) ); - } - - // Unpack the spectral fields - { - UnpackSpectral unpack(rspecview); - for( size_t jfld=0; jfld rgp( nfld, ngptot() ); + array::ArrayT rspec( nspec2(), nfld ); + array::ArrayView rgpview = array::make_view( rgp ); + array::ArrayView rspecview = array::make_view( rspec ); + + // Pack gridpoints + { + PackStructuredColumns pack( rgpview ); + for ( size_t jfld = 0; jfld < gpfields.size(); ++jfld ) + pack( gpfields[jfld] ); + } + + // Do transform + { + struct ::DirTrans_t transform = ::new_dirtrans( trans_.get() ); + transform.nscalar = nfld; + transform.rgp = rgp.data(); + transform.rspscalar = rspec.data(); + + TRANS_CHECK(::trans_dirtrans( &transform ) ); + } + + // Unpack the spectral fields + { + UnpackSpectral unpack( rspecview ); + for ( size_t jfld = 0; jfld < spfields.size(); ++jfld ) + unpack( spfields[jfld] ); + } } // -------------------------------------------------------------------------------------------- -void TransIFS::__dirtrans( - const StructuredColumns& gp, const Field& gpfield, - const Spectral& sp, Field& spfield, - const eckit::Configuration& ) const -{ - ASSERT( gpfield.functionspace() == 0 || - functionspace::StructuredColumns(gpfield.functionspace()) ); - ASSERT( spfield.functionspace() == 0 || - functionspace::Spectral(spfield.functionspace()) ); - - assertCompatibleDistributions( gp, sp ); - - if ( gpfield.stride(0) != spfield.stride(0) ) - { - throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); - } - if ( (int)gpfield.shape(0) != ngptot() ) - { - throw eckit::SeriousBug("dirtrans: slowest moving index must be ngptot",Here()); - } - const int nfld = gpfield.stride(0); - - // Do transform - { - struct ::DirTrans_t transform = ::new_dirtrans(trans_.get()); - transform.nscalar = nfld; - transform.rgp = gpfield.data(); - transform.rspscalar = spfield.data(); - transform.ngpblks = gpfield.shape(0); - transform.nproma = 1; - TRANS_CHECK( ::trans_dirtrans(&transform) ); - } -} - -void TransIFS::__dirtrans( - const StructuredColumns& gp, const FieldSet& gpfields, - const Spectral& sp, FieldSet& spfields, - const eckit::Configuration& ) const -{ - assertCompatibleDistributions( gp, sp ); - - // Count total number of fields and do sanity checks - int nfld(0); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - { - const Field& f = gpfields[jfld]; - nfld += f.stride(0); - ASSERT( f.functionspace() == 0 || - functionspace::StructuredColumns(f.functionspace()) ); - } - - int trans_spnfld(0); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - { - const Field& f = spfields[jfld]; - trans_spnfld += f.stride(0); - } - - if( nfld != trans_spnfld ) - { - throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); - } - // Arrays Trans expects - array::ArrayT rgp(nfld,ngptot()); - array::ArrayT rspec(nspec2(),nfld); - - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); - - // Pack gridpoints - { - PackStructuredColumns pack(rgpview); - for( size_t jfld=0; jfld(); - transform.rspscalar = rspec.data(); - - TRANS_CHECK( ::trans_dirtrans(&transform) ); - } - - // Unpack the spectral fields - { - UnpackSpectral unpack(rspecview); - for( size_t jfld=0; jfld(1,f.levels()) == f.stride(0) ); - } - - if( nb_gridpoint_field != 2*nfld ) // factor 2 because N-S and E-W derivatives - throw eckit::SeriousBug("invtrans_grad: different number of gridpoint fields than spectral fields",Here()); - - // Arrays Trans expects - // Allocate space for - array::ArrayT rgp(3*nfld,ngptot()); // (scalars) + (NS ders) + (EW ders) - array::ArrayT rspec(nspec2(),nfld); - - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); - - // Pack spectral fields - { - PackSpectral pack(rspecview); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - pack(spfields[jfld]); - } - - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); - transform.nscalar = nfld; - transform.rgp = rgp.data(); - transform.rspscalar = rspec.data(); - transform.lscalarders = true; - - TRANS_CHECK(::trans_invtrans(&transform)); - } - - // Unpack the gridpoint fields - { - mesh::IsGhostNode is_ghost( gp.nodes()); - int f=nfld; // skip to where derivatives start - for(size_t dim=0; dim<2; ++dim) { - for(size_t jfld = 0; jfld < gradfields.size(); ++jfld) - { - const size_t nlev = std::max(1,gradfields[jfld].levels()); - const size_t nb_nodes = gradfields[jfld].shape(0); - - array::LocalView field ( gradfields[jfld].data(), - array::make_shape(nb_nodes, nlev, 2 ) ); - - for( size_t jlev=0; jlev( 1, f.levels() ) == f.stride( 0 ) ); + } + + if ( nb_gridpoint_field != 2 * nfld ) // factor 2 because N-S and E-W derivatives + throw eckit::SeriousBug( + "invtrans_grad: different number of gridpoint " + "fields than spectral fields", + Here() ); + + // Arrays Trans expects + // Allocate space for + array::ArrayT rgp( 3 * nfld, + ngptot() ); // (scalars) + (NS ders) + (EW ders) + array::ArrayT rspec( nspec2(), nfld ); + + array::ArrayView rgpview = array::make_view( rgp ); + array::ArrayView rspecview = array::make_view( rspec ); + + // Pack spectral fields + { + PackSpectral pack( rspecview ); + for ( size_t jfld = 0; jfld < spfields.size(); ++jfld ) + pack( spfields[jfld] ); + } + + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans( trans_.get() ); + transform.nscalar = nfld; + transform.rgp = rgp.data(); + transform.rspscalar = rspec.data(); + transform.lscalarders = true; + + TRANS_CHECK(::trans_invtrans( &transform ) ); + } + + // Unpack the gridpoint fields + { + mesh::IsGhostNode is_ghost( gp.nodes() ); + int f = nfld; // skip to where derivatives start + for ( size_t dim = 0; dim < 2; ++dim ) { + for ( size_t jfld = 0; jfld < gradfields.size(); ++jfld ) { + const size_t nlev = std::max( 1, gradfields[jfld].levels() ); + const size_t nb_nodes = gradfields[jfld].shape( 0 ); + + array::LocalView field( gradfields[jfld].data(), + array::make_shape( nb_nodes, nlev, 2 ) ); + + for ( size_t jlev = 0; jlev < nlev; ++jlev ) { + int n = 0; + for ( size_t jnode = 0; jnode < nb_nodes; ++jnode ) { + if ( !is_ghost( jnode ) ) { + field( jnode, jlev, 1 - dim ) = rgpview( f, n ); + ++n; + } + } + ASSERT( n == ngptot() ); + ++f; + } } - } - ASSERT( n == ngptot() ); - ++f; } - } } - } } // -------------------------------------------------------------------------------------------- -void TransIFS::__invtrans( const Spectral& sp, const Field& spfield, - const functionspace::NodeColumns& gp, Field& gpfield, - const eckit::Configuration& config ) const -{ - FieldSet spfields; spfields.add(spfield); - FieldSet gpfields; gpfields.add(gpfield); - __invtrans(sp,spfields,gp,gpfields,config); +void TransIFS::__invtrans( const Spectral& sp, const Field& spfield, const functionspace::NodeColumns& gp, + Field& gpfield, const eckit::Configuration& config ) const { + FieldSet spfields; + spfields.add( spfield ); + FieldSet gpfields; + gpfields.add( gpfield ); + __invtrans( sp, spfields, gp, gpfields, config ); } - // -------------------------------------------------------------------------------------------- +void TransIFS::__invtrans( const Spectral& sp, const FieldSet& spfields, const functionspace::NodeColumns& gp, + FieldSet& gpfields, const eckit::Configuration& config ) const { + assertCompatibleDistributions( gp, sp ); -void TransIFS::__invtrans( const Spectral& sp, const FieldSet& spfields, - const functionspace::NodeColumns& gp, FieldSet& gpfields, - const eckit::Configuration& config ) const -{ - assertCompatibleDistributions( gp, sp ); - - // Count total number of fields and do sanity checks - int nfld(0); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - { - const Field& f = gpfields[jfld]; - nfld += f.stride(0); - } - - int nb_spectral_fields(0); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - { - const Field& f = spfields[jfld]; - nb_spectral_fields += f.stride(0); - } + // Count total number of fields and do sanity checks + int nfld( 0 ); + for ( size_t jfld = 0; jfld < gpfields.size(); ++jfld ) { + const Field& f = gpfields[jfld]; + nfld += f.stride( 0 ); + } - if( nfld != nb_spectral_fields ) - throw eckit::SeriousBug("invtrans: different number of gridpoint fields than spectral fields",Here()); + int nb_spectral_fields( 0 ); + for ( size_t jfld = 0; jfld < spfields.size(); ++jfld ) { + const Field& f = spfields[jfld]; + nb_spectral_fields += f.stride( 0 ); + } - // Arrays Trans expects - array::ArrayT rgp(nfld,ngptot()); - array::ArrayT rspec(nspec2(),nfld); + if ( nfld != nb_spectral_fields ) + throw eckit::SeriousBug( "invtrans: different number of gridpoint fields than spectral fields", Here() ); - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); + // Arrays Trans expects + array::ArrayT rgp( nfld, ngptot() ); + array::ArrayT rspec( nspec2(), nfld ); - // Pack spectral fields - { - PackSpectral pack(rspecview); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - pack(spfields[jfld]); - } + array::ArrayView rgpview = array::make_view( rgp ); + array::ArrayView rspecview = array::make_view( rspec ); - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); - transform.nscalar = nfld; - transform.rgp = rgp.data(); - transform.rspscalar = rspec.data(); + // Pack spectral fields + { + PackSpectral pack( rspecview ); + for ( size_t jfld = 0; jfld < spfields.size(); ++jfld ) + pack( spfields[jfld] ); + } - TRANS_CHECK(::trans_invtrans(&transform)); - } + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans( trans_.get() ); + transform.nscalar = nfld; + transform.rgp = rgp.data(); + transform.rspscalar = rspec.data(); - // Unpack the gridpoint fields - { - UnpackNodeColumns unpack(rgpview,gp); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - unpack(gpfields[jfld]); - } + TRANS_CHECK(::trans_invtrans( &transform ) ); + } + // Unpack the gridpoint fields + { + UnpackNodeColumns unpack( rgpview, gp ); + for ( size_t jfld = 0; jfld < gpfields.size(); ++jfld ) + unpack( gpfields[jfld] ); + } } // -------------------------------------------------------------------------------------------- - void TransIFS::__invtrans( const functionspace::Spectral& sp, const Field& spfield, const functionspace::StructuredColumns& gp, Field& gpfield, - const eckit::Configuration& config ) const -{ - assertCompatibleDistributions( gp, sp ); - - ASSERT( gpfield.functionspace() == 0 || - functionspace::StructuredColumns( gpfield.functionspace() ) ); - ASSERT( spfield.functionspace() == 0 || - functionspace::Spectral( spfield.functionspace() ) ); - if ( gpfield.stride(0) != spfield.stride(0) ) - { - throw eckit::SeriousBug("dirtrans: different number of gridpoint fields than spectral fields",Here()); - } - if ( (int)gpfield.shape(0) != ngptot() ) - { - throw eckit::SeriousBug("dirtrans: slowest moving index must be ngptot",Here()); - } - const int nfld = gpfield.stride(0); - - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); - transform.nscalar = nfld; - transform.rgp = gpfield.data(); - transform.rspscalar = spfield.data(); - transform.ngpblks = gpfield.shape(0); - transform.nproma = 1; - TRANS_CHECK( ::trans_invtrans(&transform) ); - } -} + const eckit::Configuration& config ) const { + assertCompatibleDistributions( gp, sp ); + ASSERT( gpfield.functionspace() == 0 || functionspace::StructuredColumns( gpfield.functionspace() ) ); + ASSERT( spfield.functionspace() == 0 || functionspace::Spectral( spfield.functionspace() ) ); + if ( gpfield.stride( 0 ) != spfield.stride( 0 ) ) { + throw eckit::SeriousBug( "dirtrans: different number of gridpoint fields than spectral fields", Here() ); + } + if ( (int)gpfield.shape( 0 ) != ngptot() ) { + throw eckit::SeriousBug( "dirtrans: slowest moving index must be ngptot", Here() ); + } + const int nfld = gpfield.stride( 0 ); + + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans( trans_.get() ); + transform.nscalar = nfld; + transform.rgp = gpfield.data(); + transform.rspscalar = spfield.data(); + transform.ngpblks = gpfield.shape( 0 ); + transform.nproma = 1; + TRANS_CHECK(::trans_invtrans( &transform ) ); + } +} // -------------------------------------------------------------------------------------------- void TransIFS::__invtrans( const functionspace::Spectral& sp, const FieldSet& spfields, const functionspace::StructuredColumns& gp, FieldSet& gpfields, - const eckit::Configuration& config ) const -{ - assertCompatibleDistributions( gp, sp ); - - // Count total number of fields and do sanity checks - int nfld(0); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - { - const Field& f = gpfields[jfld]; - nfld += f.stride(0); - ASSERT( f.functionspace() == 0 || - functionspace::StructuredColumns( f.functionspace() ) ); - } - - int nb_spectral_fields(0); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - { - const Field& f = spfields[jfld]; - nb_spectral_fields += f.stride(0); - } - - if( nfld != nb_spectral_fields ) { - std::stringstream msg; - msg << "invtrans: different number of gridpoint fields than spectral fields" - << "[ " << nfld << " != " << nb_spectral_fields << " ]"; - throw eckit::SeriousBug(msg.str(),Here()); - } - - // Arrays Trans expects - array::ArrayT rgp(nfld,ngptot()); - array::ArrayT rspec(nspec2(),nfld); - - array::ArrayView rgpview = array::make_view(rgp); - array::ArrayView rspecview = array::make_view(rspec); - - // Pack spectral fields - { - PackSpectral pack(rspecview); - for(size_t jfld = 0; jfld < spfields.size(); ++jfld) - pack(spfields[jfld]); - } - - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); - transform.nscalar = nfld; - transform.rgp = rgp.data(); - transform.rspscalar = rspec.data(); - - TRANS_CHECK(::trans_invtrans(&transform)); - } - - // Unpack the gridpoint fields - { - UnpackStructuredColumns unpack(rgpview); - for(size_t jfld = 0; jfld < gpfields.size(); ++jfld) - unpack(gpfields[jfld]); - } + const eckit::Configuration& config ) const { + assertCompatibleDistributions( gp, sp ); + + // Count total number of fields and do sanity checks + int nfld( 0 ); + for ( size_t jfld = 0; jfld < gpfields.size(); ++jfld ) { + const Field& f = gpfields[jfld]; + nfld += f.stride( 0 ); + ASSERT( f.functionspace() == 0 || functionspace::StructuredColumns( f.functionspace() ) ); + } + + int nb_spectral_fields( 0 ); + for ( size_t jfld = 0; jfld < spfields.size(); ++jfld ) { + const Field& f = spfields[jfld]; + nb_spectral_fields += f.stride( 0 ); + } + + if ( nfld != nb_spectral_fields ) { + std::stringstream msg; + msg << "invtrans: different number of gridpoint fields than spectral fields" + << "[ " << nfld << " != " << nb_spectral_fields << " ]"; + throw eckit::SeriousBug( msg.str(), Here() ); + } + + // Arrays Trans expects + array::ArrayT rgp( nfld, ngptot() ); + array::ArrayT rspec( nspec2(), nfld ); + + array::ArrayView rgpview = array::make_view( rgp ); + array::ArrayView rspecview = array::make_view( rspec ); + + // Pack spectral fields + { + PackSpectral pack( rspecview ); + for ( size_t jfld = 0; jfld < spfields.size(); ++jfld ) + pack( spfields[jfld] ); + } + + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans( trans_.get() ); + transform.nscalar = nfld; + transform.rgp = rgp.data(); + transform.rspscalar = rspec.data(); + + TRANS_CHECK(::trans_invtrans( &transform ) ); + } + + // Unpack the gridpoint fields + { + UnpackStructuredColumns unpack( rgpview ); + for ( size_t jfld = 0; jfld < gpfields.size(); ++jfld ) + unpack( gpfields[jfld] ); + } } // ----------------------------------------------------------------------------------------------- -void TransIFS::__dirtrans_wind2vordiv( const functionspace::NodeColumns& gp, const Field& gpwind, - const Spectral& sp, Field& spvor, Field&spdiv, - const eckit::Configuration& ) const -{ - assertCompatibleDistributions( gp, sp ); - - // Count total number of fields and do sanity checks - size_t nfld = spvor.stride(0); - if( spdiv.shape(0) != spvor.shape(0) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); - if( spdiv.shape(1) != spvor.shape(1) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); - size_t nwindfld = gpwind.stride(0); - if (nwindfld != 2*nfld && nwindfld != 3*nfld) throw eckit::SeriousBug("dirtrans: wind field is not compatible with vorticity, divergence.",Here()); - - if( spdiv.shape(0) != size_t(nspec2()) ) { - std::stringstream msg; - msg << "dirtrans: Spectral vorticity and divergence have wrong dimension: nspec2 "< rgp(2*nfld,size_t(ngptot())); - array::ArrayView rgpview = array::make_view(rgp); - - // Pack gridpoints - { - PackNodeColumns pack( rgpview, gp ); - int wind_components = 2; - pack(gpwind, wind_components); - } - - // Do transform - { - struct ::DirTrans_t transform = ::new_dirtrans(trans_.get()); - transform.nvordiv = nfld; - transform.rgp = rgp.data(); - transform.rspvor = spvor.data(); - transform.rspdiv = spdiv.data(); - - ASSERT( transform.rspvor ); - ASSERT( transform.rspdiv ); - TRANS_CHECK( ::trans_dirtrans(&transform) ); - } -} +void TransIFS::__dirtrans_wind2vordiv( const functionspace::NodeColumns& gp, const Field& gpwind, const Spectral& sp, + Field& spvor, Field& spdiv, const eckit::Configuration& ) const { + assertCompatibleDistributions( gp, sp ); + + // Count total number of fields and do sanity checks + size_t nfld = spvor.stride( 0 ); + if ( spdiv.shape( 0 ) != spvor.shape( 0 ) ) + throw eckit::SeriousBug( "invtrans: vorticity not compatible with divergence.", Here() ); + if ( spdiv.shape( 1 ) != spvor.shape( 1 ) ) + throw eckit::SeriousBug( "invtrans: vorticity not compatible with divergence.", Here() ); + size_t nwindfld = gpwind.stride( 0 ); + if ( nwindfld != 2 * nfld && nwindfld != 3 * nfld ) + throw eckit::SeriousBug( "dirtrans: wind field is not compatible with vorticity, divergence.", Here() ); + + if ( spdiv.shape( 0 ) != size_t( nspec2() ) ) { + std::stringstream msg; + msg << "dirtrans: Spectral vorticity and divergence have wrong dimension: " + "nspec2 " + << spdiv.shape( 0 ) << " should be " << nspec2(); + throw eckit::SeriousBug( msg.str(), Here() ); + } + + if ( spvor.size() == 0 ) throw eckit::SeriousBug( "dirtrans: spectral vorticity field is empty." ); + if ( spdiv.size() == 0 ) throw eckit::SeriousBug( "dirtrans: spectral divergence field is empty." ); + // Arrays Trans expects + array::ArrayT rgp( 2 * nfld, size_t( ngptot() ) ); + array::ArrayView rgpview = array::make_view( rgp ); + + // Pack gridpoints + { + PackNodeColumns pack( rgpview, gp ); + int wind_components = 2; + pack( gpwind, wind_components ); + } + + // Do transform + { + struct ::DirTrans_t transform = ::new_dirtrans( trans_.get() ); + transform.nvordiv = nfld; + transform.rgp = rgp.data(); + transform.rspvor = spvor.data(); + transform.rspdiv = spdiv.data(); + + ASSERT( transform.rspvor ); + ASSERT( transform.rspdiv ); + TRANS_CHECK(::trans_dirtrans( &transform ) ); + } +} void TransIFS::__invtrans_vordiv2wind( const Spectral& sp, const Field& spvor, const Field& spdiv, const functionspace::NodeColumns& gp, Field& gpwind, - const eckit::Configuration& config ) const -{ - assertCompatibleDistributions( gp, sp ); - - // Count total number of fields and do sanity checks - size_t nfld = spvor.stride(0); - if( spdiv.shape(0) != spvor.shape(0) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); - if( spdiv.shape(1) != spvor.shape(1) ) throw eckit::SeriousBug("invtrans: vorticity not compatible with divergence.",Here()); - size_t nwindfld = gpwind.stride(0); - if (nwindfld != 2*nfld && nwindfld != 3*nfld) throw eckit::SeriousBug("invtrans: wind field is not compatible with vorticity, divergence.",Here()); - - if( spdiv.shape(0) != size_t(nspec2()) ) { - std::stringstream msg; - msg << "invtrans: Spectral vorticity and divergence have wrong dimension: nspec2 "< rgp(2*nfld,size_t(ngptot())); - array::ArrayView rgpview = array::make_view(rgp); - - // Do transform - { - struct ::InvTrans_t transform = ::new_invtrans(trans_.get()); - transform.nvordiv = nfld; - transform.rgp = rgp.data(); - transform.rspvor = spvor.data(); - transform.rspdiv = spdiv.data(); - - ASSERT( transform.rspvor ); - ASSERT( transform.rspdiv ); - TRANS_CHECK(::trans_invtrans(&transform)); - } - - // Unpack the gridpoint fields - { - UnpackNodeColumns unpack( rgpview, gp ); - int wind_components = 2; - unpack(gpwind,wind_components); - } + const eckit::Configuration& config ) const { + assertCompatibleDistributions( gp, sp ); + + // Count total number of fields and do sanity checks + size_t nfld = spvor.stride( 0 ); + if ( spdiv.shape( 0 ) != spvor.shape( 0 ) ) + throw eckit::SeriousBug( "invtrans: vorticity not compatible with divergence.", Here() ); + if ( spdiv.shape( 1 ) != spvor.shape( 1 ) ) + throw eckit::SeriousBug( "invtrans: vorticity not compatible with divergence.", Here() ); + size_t nwindfld = gpwind.stride( 0 ); + if ( nwindfld != 2 * nfld && nwindfld != 3 * nfld ) + throw eckit::SeriousBug( "invtrans: wind field is not compatible with vorticity, divergence.", Here() ); + + if ( spdiv.shape( 0 ) != size_t( nspec2() ) ) { + std::stringstream msg; + msg << "invtrans: Spectral vorticity and divergence have wrong dimension: " + "nspec2 " + << spdiv.shape( 0 ) << " should be " << nspec2(); + throw eckit::SeriousBug( msg.str(), Here() ); + } + + ASSERT( spvor.rank() == 2 ); + ASSERT( spdiv.rank() == 2 ); + if ( spvor.size() == 0 ) throw eckit::SeriousBug( "invtrans: spectral vorticity field is empty." ); + if ( spdiv.size() == 0 ) throw eckit::SeriousBug( "invtrans: spectral divergence field is empty." ); + + // Arrays Trans expects + array::ArrayT rgp( 2 * nfld, size_t( ngptot() ) ); + array::ArrayView rgpview = array::make_view( rgp ); + + // Do transform + { + struct ::InvTrans_t transform = ::new_invtrans( trans_.get() ); + transform.nvordiv = nfld; + transform.rgp = rgp.data(); + transform.rspvor = spvor.data(); + transform.rspdiv = spdiv.data(); + + ASSERT( transform.rspvor ); + ASSERT( transform.rspdiv ); + TRANS_CHECK(::trans_invtrans( &transform ) ); + } + // Unpack the gridpoint fields + { + UnpackNodeColumns unpack( rgpview, gp ); + int wind_components = 2; + unpack( gpwind, wind_components ); + } } /////////////////////////////////////////////////////////////////////////////// - -void TransIFS::distspec( const int nb_fields, const int origin[], const double global_spectra[], double spectra[] ) const -{ - struct ::DistSpec_t args = new_distspec(trans_.get()); - args.nfld = nb_fields; - args.rspecg = global_spectra; - args.nfrom = origin; - args.rspec = spectra; - TRANS_CHECK( ::trans_distspec(&args) ); +void TransIFS::distspec( const int nb_fields, const int origin[], const double global_spectra[], + double spectra[] ) const { + struct ::DistSpec_t args = new_distspec( trans_.get() ); + args.nfld = nb_fields; + args.rspecg = global_spectra; + args.nfrom = origin; + args.rspec = spectra; + TRANS_CHECK(::trans_distspec( &args ) ); } ///////////////////////////////////////////////////////////////////////////// -void TransIFS::gathspec( const int nb_fields, const int destination[], const double spectra[], double global_spectra[] ) const -{ - struct ::GathSpec_t args = new_gathspec(trans_.get()); - args.nfld = nb_fields; - args.rspecg = global_spectra; - args.nto = destination; - args.rspec = spectra; - TRANS_CHECK( ::trans_gathspec(&args) ); +void TransIFS::gathspec( const int nb_fields, const int destination[], const double spectra[], + double global_spectra[] ) const { + struct ::GathSpec_t args = new_gathspec( trans_.get() ); + args.nfld = nb_fields; + args.rspecg = global_spectra; + args.nto = destination; + args.rspec = spectra; + TRANS_CHECK(::trans_gathspec( &args ) ); } ///////////////////////////////////////////////////////////////////////////// -void TransIFS::distgrid( const int nb_fields, const int origin[], const double global_fields[], double fields[] ) const -{ - struct ::DistGrid_t args = new_distgrid(trans_.get()); - args.nfld = nb_fields; - args.nfrom = origin; - args.rgpg = global_fields; - args.rgp = fields; - TRANS_CHECK( ::trans_distgrid(&args) ); +void TransIFS::distgrid( const int nb_fields, const int origin[], const double global_fields[], + double fields[] ) const { + struct ::DistGrid_t args = new_distgrid( trans_.get() ); + args.nfld = nb_fields; + args.nfrom = origin; + args.rgpg = global_fields; + args.rgp = fields; + TRANS_CHECK(::trans_distgrid( &args ) ); } ///////////////////////////////////////////////////////////////////////////// -void TransIFS::gathgrid( const int nb_fields, const int destination[], const double fields[], double global_fields[] ) const -{ - struct ::GathGrid_t args = new_gathgrid(trans_.get()); - args.nfld = nb_fields; - args.nto = destination; - args.rgp = fields; - args.rgpg = global_fields; - TRANS_CHECK( ::trans_gathgrid(&args) ); +void TransIFS::gathgrid( const int nb_fields, const int destination[], const double fields[], + double global_fields[] ) const { + struct ::GathGrid_t args = new_gathgrid( trans_.get() ); + args.nfld = nb_fields; + args.nto = destination; + args.rgp = fields; + args.rgpg = global_fields; + TRANS_CHECK(::trans_gathgrid( &args ) ); } /////////////////////////////////////////////////////////////////////////////// - -void TransIFS::specnorm( const int nb_fields, const double spectra[], double norms[], int rank ) const -{ - struct ::SpecNorm_t args = new_specnorm(trans_.get()); - args.nfld = nb_fields; - args.rspec = spectra; - args.rnorm = norms; - args.nmaster = rank+1; - TRANS_CHECK( ::trans_specnorm(&args) ); +void TransIFS::specnorm( const int nb_fields, const double spectra[], double norms[], int rank ) const { + struct ::SpecNorm_t args = new_specnorm( trans_.get() ); + args.nfld = nb_fields; + args.rspec = spectra; + args.rnorm = norms; + args.nmaster = rank + 1; + TRANS_CHECK(::trans_specnorm( &args ) ); } /////////////////////////////////////////////////////////////////////////////// extern "C" { -TransIFS* atlas__Trans__new (const Grid::Implementation* grid, int nsmax) -{ - TransIFS* trans(0); - ATLAS_ERROR_HANDLING( - ASSERT( grid ); - trans = new TransIFS( Grid(grid) ,nsmax); - ); - return trans; -} - -void atlas__Trans__delete (TransIFS* This) -{ - ASSERT( This ); - ATLAS_ERROR_HANDLING( delete This ); -} - -int atlas__Trans__handle (const TransIFS* This) -{ - ASSERT( This ); - ATLAS_ERROR_HANDLING( - ::Trans_t* t = *This; - return t->handle; - ); - return 0; -} - -void atlas__Trans__distspec( const TransIFS* t, int nb_fields, int origin[], double global_spectra[], double spectra[] ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( t ); - 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_ERROR_HANDLING( - ASSERT( t ); - 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_ERROR_HANDLING( - ASSERT( t ); - 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_ERROR_HANDLING( - ASSERT( t ); - 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_ERROR_HANDLING( - ASSERT( t ); - 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_ERROR_HANDLING( - ASSERT( t ); - 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_ERROR_HANDLING( - ASSERT( t ); - 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_ERROR_HANDLING( - ASSERT( t ); - 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_ERROR_HANDLING( - ASSERT( t ); - return t->specnorm(nb_fields, spectra, norms, rank); - ); -} - -int atlas__Trans__nspec2 (const TransIFS* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->trans()->nspec2; - ); - return 0; +TransIFS* atlas__Trans__new( const Grid::Implementation* grid, int nsmax ) { + TransIFS* trans( 0 ); + ATLAS_ERROR_HANDLING( ASSERT( grid ); trans = new TransIFS( Grid( grid ), nsmax ); ); + return trans; } -int atlas__Trans__nspec2g (const TransIFS* This) -{ - ATLAS_ERROR_HANDLING( +void atlas__Trans__delete( TransIFS* This ) { ASSERT( This ); - return This->trans()->nspec2g; - ); - return 0; + ATLAS_ERROR_HANDLING( delete This ); } -int atlas__Trans__ngptot (const TransIFS* This) -{ - ATLAS_ERROR_HANDLING( +int atlas__Trans__handle( const TransIFS* This ) { ASSERT( This ); - return This->trans()->ngptot; - ); - return 0; + ATLAS_ERROR_HANDLING(::Trans_t* t = *This; return t->handle; ); + return 0; } -int atlas__Trans__ngptotg (const TransIFS* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->trans()->ngptotg; - ); - return 0; +void atlas__Trans__distspec( const TransIFS* t, int nb_fields, int origin[], double global_spectra[], + double spectra[] ) { + ATLAS_ERROR_HANDLING( ASSERT( t ); 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 ) ); ); } -int atlas__Trans__truncation (const TransIFS* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - return This->truncation(); - ); - return 0; +void atlas__Trans__gathspec( const TransIFS* t, int nb_fields, int destination[], double spectra[], + double global_spectra[] ) { + ATLAS_ERROR_HANDLING( ASSERT( t ); 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 ) ); ); } -const Grid::Implementation* atlas__Trans__grid(const TransIFS* This) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( This->grid() ); - ATLAS_DEBUG_VAR( This->grid().get()->owners() ); - return This->grid().get(); - ); - return nullptr; +void atlas__Trans__distgrid( const TransIFS* t, int nb_fields, int origin[], double global_fields[], double fields[] ) { + ATLAS_ERROR_HANDLING( ASSERT( t ); 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__dirtrans_fieldset (const TransIFS* This, const field::FieldSetImpl* gpfields, field::FieldSetImpl* spfields, const eckit::Configuration* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( gpfields ); - ASSERT( spfields ); - ASSERT( parameters ); - FieldSet fspfields(spfields); - This->dirtrans(gpfields,fspfields,*parameters); - ); +void atlas__Trans__gathgrid( const TransIFS* t, int nb_fields, int destination[], double fields[], + double global_fields[] ) { + ATLAS_ERROR_HANDLING( ASSERT( t ); 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__dirtrans_field (const TransIFS* This, const field::FieldImpl* gpfield, field::FieldImpl* spfield, const eckit::Configuration* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( spfield ); - ASSERT( gpfield ); - ASSERT( parameters ); - Field fspfield(spfield); - This->dirtrans(gpfield,fspfield,*parameters); - ); +void atlas__Trans__invtrans_scalar( const TransIFS* t, int nb_fields, double scalar_spectra[], + double scalar_fields[] ) { + ATLAS_ERROR_HANDLING( ASSERT( t ); return t->invtrans( nb_fields, scalar_spectra, scalar_fields ); ); } -void atlas__Trans__invtrans_fieldset (const TransIFS* This, const field::FieldSetImpl* spfields, field::FieldSetImpl* gpfields, const eckit::Configuration* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( spfields ); - ASSERT( gpfields ); - ASSERT( parameters ); - FieldSet fgpfields(gpfields); - This->invtrans(spfields,fgpfields,*parameters); - ); +void atlas__Trans__invtrans_vordiv2wind( const TransIFS* t, int nb_fields, double vorticity_spectra[], + double divergence_spectra[], double wind_fields[] ) { + ATLAS_ERROR_HANDLING( ASSERT( t ); + return t->invtrans( nb_fields, vorticity_spectra, divergence_spectra, wind_fields ); ); } -void atlas__Trans__invtrans_field (const TransIFS* This, const field::FieldImpl* spfield, field::FieldImpl* gpfield, const eckit::Configuration* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( spfield ); - ASSERT( gpfield ); - ASSERT( parameters ); - Field fgpfield(gpfield); - This->invtrans(spfield,fgpfield,*parameters); - ); +void atlas__Trans__dirtrans_scalar( const TransIFS* t, int nb_fields, double scalar_fields[], + double scalar_spectra[] ) { + ATLAS_ERROR_HANDLING( ASSERT( t ); return t->dirtrans( nb_fields, scalar_fields, scalar_spectra ); ); } -void atlas__Trans__dirtrans_wind2vordiv_field (const TransIFS* This, const field::FieldImpl* gpwind, field::FieldImpl* spvor, field::FieldImpl* spdiv, const eckit::Configuration* parameters) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This ); - ASSERT( gpwind ); - ASSERT( spvor ); - ASSERT( spdiv ); - 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_ERROR_HANDLING( - ASSERT( This ); - ASSERT( spvor ); - ASSERT( spdiv ); - ASSERT( gpwind ); - 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_ERROR_HANDLING( - ASSERT(This); - 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_ERROR_HANDLING( - ASSERT( This ); - ASSERT( spfield ); - ASSERT( gpfield ); - Field fgpfield(gpfield); - This->invtrans_grad(spfield,fgpfield,*config); - ); +void atlas__Trans__dirtrans_wind2vordiv( const TransIFS* t, int nb_fields, double wind_fields[], + double vorticity_spectra[], double divergence_spectra[] ) { + ATLAS_ERROR_HANDLING( ASSERT( t ); + 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_ERROR_HANDLING( ASSERT( t ); return t->specnorm( nb_fields, spectra, norms, rank ); ); } +int atlas__Trans__nspec2( const TransIFS* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->trans()->nspec2; ); + return 0; +} + +int atlas__Trans__nspec2g( const TransIFS* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->trans()->nspec2g; ); + return 0; +} + +int atlas__Trans__ngptot( const TransIFS* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->trans()->ngptot; ); + return 0; +} + +int atlas__Trans__ngptotg( const TransIFS* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->trans()->ngptotg; ); + return 0; +} + +int atlas__Trans__truncation( const TransIFS* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); return This->truncation(); ); + return 0; +} + +const Grid::Implementation* atlas__Trans__grid( const TransIFS* This ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( This->grid() ); ATLAS_DEBUG_VAR( This->grid().get()->owners() ); + return This->grid().get(); ); + return nullptr; +} + +void atlas__Trans__dirtrans_fieldset( const TransIFS* This, const field::FieldSetImpl* gpfields, + field::FieldSetImpl* spfields, const eckit::Configuration* parameters ) { + ATLAS_ERROR_HANDLING( ASSERT( This ); ASSERT( gpfields ); ASSERT( spfields ); 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_ERROR_HANDLING( ASSERT( This ); ASSERT( spfield ); ASSERT( gpfield ); 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_ERROR_HANDLING( ASSERT( This ); ASSERT( spfields ); ASSERT( gpfields ); 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_ERROR_HANDLING( ASSERT( This ); ASSERT( spfield ); ASSERT( gpfield ); 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_ERROR_HANDLING( ASSERT( This ); ASSERT( gpwind ); ASSERT( spvor ); ASSERT( spdiv ); 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_ERROR_HANDLING( ASSERT( This ); ASSERT( spvor ); ASSERT( spdiv ); ASSERT( gpwind ); 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_ERROR_HANDLING( ASSERT( This ); + 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_ERROR_HANDLING( ASSERT( This ); ASSERT( spfield ); ASSERT( gpfield ); Field fgpfield( gpfield ); + This->invtrans_grad( spfield, fgpfield, *config ); ); +} } -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h index 233f856e9..aeb9f37e6 100644 --- a/src/atlas/trans/ifs/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -4,63 +4,63 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "eckit/filesystem/PathName.h" -#include "transi/trans.h" #include "atlas/array/LocalView.h" #include "atlas/grid/Grid.h" #include "atlas/trans/Trans.h" +#include "eckit/filesystem/PathName.h" +#include "transi/trans.h" //----------------------------------------------------------------------------- // Forward declarations namespace atlas { - class Field; - class FieldSet; +class Field; +class FieldSet; namespace field { - class FieldImpl; - class FieldSetImpl; -} -} +class FieldImpl; +class FieldSetImpl; +} // namespace field +} // namespace atlas namespace atlas { namespace array { - class Array; -} +class Array; } +} // namespace atlas namespace atlas { namespace functionspace { - class StructuredColumns; - class NodeColumns; - class Spectral; -} -} +class StructuredColumns; +class NodeColumns; +class Spectral; +} // namespace functionspace +} // namespace atlas namespace atlas { namespace functionspace { namespace detail { - class NodeColumns; - class Spectral; -} -} -} +class NodeColumns; +class Spectral; +} // namespace detail +} // namespace functionspace +} // namespace atlas namespace atlas { namespace grid { namespace detail { namespace partitioner { - class TransPartitioner; -} -} +class TransPartitioner; } -} - +} // namespace detail +} // namespace grid +} // namespace atlas //----------------------------------------------------------------------------- @@ -71,435 +71,383 @@ namespace trans { class TransIFS : public trans::TransImpl { private: - typedef struct ::Trans_t Trans_t; + typedef struct ::Trans_t Trans_t; public: + TransIFS( const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); + TransIFS( const Cache&, const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); - TransIFS( const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); - TransIFS( const Cache&, const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); - - virtual ~TransIFS(); - operator ::Trans_t*() const { return trans(); } - ::Trans_t* trans() const { return trans_.get(); } - - virtual int truncation() const override { return std::max(0,trans_->nsmax); } - virtual size_t spectralCoefficients() const override { return trans_->nspec2g; } - - virtual const Grid& grid() const override { return grid_; } - - - - // pure virtual interface - - virtual void dirtrans( const Field& gpfield, - Field& spfield, - const eckit::Configuration& = util::NoConfig() ) const override; - - virtual void dirtrans( const FieldSet& gpfields, - FieldSet& spfields, - const eckit::Configuration& = util::NoConfig() ) const override; - - virtual void dirtrans_wind2vordiv( const Field& gpwind, - Field& spvor, Field& spdiv, - const eckit::Configuration& = util::NoConfig() ) const override; - - virtual void invtrans( const Field& spfield, - Field& gpfield, - const eckit::Configuration& = util::NoConfig() ) const override; - - virtual void invtrans( const FieldSet& spfields, - FieldSet& gpfields, - const eckit::Configuration& = util::NoConfig() ) const override; - - virtual void invtrans_grad( const Field& spfield, - Field& gradfield, - const eckit::Configuration& = util::NoConfig() ) const override; - - virtual void invtrans_grad( const FieldSet& spfields, - FieldSet& gradfields, - const eckit::Configuration& = util::NoConfig() ) const override; - - - virtual void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, - Field& gpwind, - const eckit::Configuration& = util::NoConfig() ) const override; - -// -- IFS style API -- -// These fields have special interpretation required. You need to know what you're doing. -// See IFS trans library. - - /*! - * @brief invtrans - * @param nb_scalar_fields - * @param scalar_spectra [NSPEC2][nb_scalar_fields] - * @param nb_vordiv_fields - * @param vorticity_spectra [NSPEC2][nb_vordiv_fields] - * @param divergence_spectra [NSPEC2][nb_vordiv_fields] - * @param gp_fields Ordering: [NGPBLKS][NFLD][NPROMA] if distributed, - * [NFLD][NGPTOTG] if global ( add option::global() ) - */ - virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const eckit::Configuration& = util::NoConfig() ) const override; - - /*! - * @brief invtrans - * @param nb_fields - * @param scalar_spectra - * @param scalar_fields - */ - virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - double gp_fields[], - const eckit::Configuration& = util::NoConfig() ) const override; - - /*! - * @brief Inverse transform of vorticity/divergence to wind(U/V) - * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) - */ - virtual void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const eckit::Configuration& = util::NoConfig() ) const override; - - /*! - * @brief Direct transform of scalar fields - */ - virtual void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], - const eckit::Configuration& = util::NoConfig() ) const override; - - /*! - * @brief Direct transform of wind(U/V) to vorticity/divergence - * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) - */ - virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], - const eckit::Configuration& = util::NoConfig() ) const override; - - - + virtual ~TransIFS(); + operator ::Trans_t*() const { return trans(); } + ::Trans_t* trans() const { return trans_.get(); } + virtual int truncation() const override { return std::max( 0, trans_->nsmax ); } + virtual size_t spectralCoefficients() const override { return trans_->nspec2g; } + virtual const Grid& grid() const override { return grid_; } + // pure virtual interface + virtual void dirtrans( const Field& gpfield, Field& spfield, + const eckit::Configuration& = util::NoConfig() ) const override; + virtual void dirtrans( const FieldSet& gpfields, FieldSet& spfields, + const eckit::Configuration& = util::NoConfig() ) const override; + virtual void dirtrans_wind2vordiv( const Field& gpwind, Field& spvor, Field& spdiv, + const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans( const Field& spfield, Field& gpfield, + const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans( const FieldSet& spfields, FieldSet& gpfields, + const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans_grad( const Field& spfield, Field& gradfield, + const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans_grad( const FieldSet& spfields, FieldSet& gradfields, + const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, Field& gpwind, + const eckit::Configuration& = util::NoConfig() ) const override; + // -- IFS style API -- + // These fields have special interpretation required. You need to know what + // you're doing. + // See IFS trans library. + /*! + * @brief invtrans + * @param nb_scalar_fields + * @param scalar_spectra [NSPEC2][nb_scalar_fields] + * @param nb_vordiv_fields + * @param vorticity_spectra [NSPEC2][nb_vordiv_fields] + * @param divergence_spectra [NSPEC2][nb_vordiv_fields] + * @param gp_fields Ordering: [NGPBLKS][NFLD][NPROMA] if distributed, + * [NFLD][NGPTOTG] if global ( add option::global() + * ) + */ + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], const int nb_vordiv_fields, + const double vorticity_spectra[], const double divergence_spectra[], double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; + /*! + * @brief invtrans + * @param nb_fields + * @param scalar_spectra + * @param scalar_fields + */ + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; + /*! + * @brief Inverse transform of vorticity/divergence to wind(U/V) + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ + virtual void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], + const double divergence_spectra[], double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; + /*! + * @brief Direct transform of scalar fields + */ + virtual void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& = util::NoConfig() ) const override; + /*! + * @brief Direct transform of wind(U/V) to vorticity/divergence + * @param nb_fields [in] Number of fields ( both components of wind count as 1 ) + */ + virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], + double divergence_spectra[], const eckit::Configuration& = util::NoConfig() ) const override; -// implementations + // implementations public: + void __dirtrans( const functionspace::StructuredColumns&, const Field& gpfield, const functionspace::Spectral&, + Field& spfield, const eckit::Configuration& = util::NoConfig() ) const; + void __dirtrans( const functionspace::StructuredColumns&, const FieldSet& gpfields, const functionspace::Spectral&, + FieldSet& spfields, const eckit::Configuration& = util::NoConfig() ) const; - void __dirtrans(const functionspace::StructuredColumns&, const Field& gpfield, - const functionspace::Spectral&, Field& spfield, - const eckit::Configuration& = util::NoConfig() ) const; - void __dirtrans(const functionspace::StructuredColumns&, const FieldSet& gpfields, - const functionspace::Spectral&, FieldSet& spfields, - const eckit::Configuration& = util::NoConfig() ) const; - - void __dirtrans(const functionspace::NodeColumns&, const Field& gpfield, - const functionspace::Spectral&, Field& spfield, - const eckit::Configuration& = util::NoConfig() ) const; - void __dirtrans(const functionspace::NodeColumns&, const FieldSet& gpfields, - const functionspace::Spectral&, FieldSet& spfields, - const eckit::Configuration& = util::NoConfig() ) const; - - void __dirtrans_wind2vordiv(const functionspace::NodeColumns&, const Field& gpwind, - const functionspace::Spectral&, Field& spvor, Field& spdiv, - const eckit::Configuration& = util::NoConfig() ) const; - + void __dirtrans( const functionspace::NodeColumns&, const Field& gpfield, const functionspace::Spectral&, + Field& spfield, const eckit::Configuration& = util::NoConfig() ) const; + void __dirtrans( const functionspace::NodeColumns&, const FieldSet& gpfields, const functionspace::Spectral&, + FieldSet& spfields, const eckit::Configuration& = util::NoConfig() ) const; - void __invtrans(const functionspace::Spectral&, const Field& spfield, - const functionspace::StructuredColumns&, Field& gpfield, - const eckit::Configuration& = util::NoConfig() ) const; - void __invtrans(const functionspace::Spectral&, const FieldSet& spfields, - const functionspace::StructuredColumns&, FieldSet& gpfields, - const eckit::Configuration& = util::NoConfig() ) const; + void __dirtrans_wind2vordiv( const functionspace::NodeColumns&, const Field& gpwind, const functionspace::Spectral&, + Field& spvor, Field& spdiv, const eckit::Configuration& = util::NoConfig() ) const; - void __invtrans(const functionspace::Spectral&, const Field& spfield, - const functionspace::NodeColumns&, Field& gpfield, - const eckit::Configuration& = util::NoConfig() ) const; - void __invtrans(const functionspace::Spectral&, const FieldSet& spfields, - const functionspace::NodeColumns&, FieldSet& gpfields, - const eckit::Configuration& = util::NoConfig() ) const; + void __invtrans( const functionspace::Spectral&, const Field& spfield, const functionspace::StructuredColumns&, + Field& gpfield, const eckit::Configuration& = util::NoConfig() ) const; + void __invtrans( const functionspace::Spectral&, const FieldSet& spfields, const functionspace::StructuredColumns&, + FieldSet& gpfields, const eckit::Configuration& = util::NoConfig() ) const; - void __invtrans_vordiv2wind(const functionspace::Spectral&, const Field& spvor, const Field& spdiv, - const functionspace::NodeColumns&, Field& gpwind, - const eckit::Configuration& = util::NoConfig() ) const; + void __invtrans( const functionspace::Spectral&, const Field& spfield, const functionspace::NodeColumns&, + Field& gpfield, const eckit::Configuration& = util::NoConfig() ) const; + void __invtrans( const functionspace::Spectral&, const FieldSet& spfields, const functionspace::NodeColumns&, + FieldSet& gpfields, const eckit::Configuration& = util::NoConfig() ) const; - void __invtrans_grad(const functionspace::Spectral& sp, const Field& spfield, - const functionspace::NodeColumns& gp, Field& gradfield, - const eckit::Configuration& = util::NoConfig() ) const; + void __invtrans_vordiv2wind( const functionspace::Spectral&, const Field& spvor, const Field& spdiv, + const functionspace::NodeColumns&, Field& gpwind, + const eckit::Configuration& = util::NoConfig() ) const; + void __invtrans_grad( const functionspace::Spectral& sp, const Field& spfield, const functionspace::NodeColumns& gp, + Field& gradfield, const eckit::Configuration& = util::NoConfig() ) const; - void __invtrans_grad(const functionspace::Spectral& sp, const FieldSet& spfields, - const functionspace::NodeColumns& gp, FieldSet& gradfields, - const eckit::Configuration& = util::NoConfig() ) const; + void __invtrans_grad( const functionspace::Spectral& sp, const FieldSet& spfields, + const functionspace::NodeColumns& gp, FieldSet& gradfields, + const eckit::Configuration& = util::NoConfig() ) const; public: - void specnorm( const int nb_fields, const double spectra[], double norms[], int rank=0 ) const; + void specnorm( const int nb_fields, const double spectra[], double norms[], int rank = 0 ) const; protected: - - void assertCompatibleDistributions( const FunctionSpace& gp, const FunctionSpace& /*sp*/ ) const; + void assertCompatibleDistributions( const FunctionSpace& gp, const FunctionSpace& /*sp*/ ) const; private: + void ctor( const Grid&, long nsmax, const eckit::Configuration& ); - void ctor( const Grid&, long nsmax, const eckit::Configuration& ); - - void ctor_rgg(const long nlat, const long pl[], long nsmax, const eckit::Configuration& ); + void ctor_rgg( const long nlat, const long pl[], long nsmax, const eckit::Configuration& ); - void ctor_lonlat(const long nlon, const long nlat, long nsmax, const eckit::Configuration& ); + void ctor_lonlat( const long nlon, const long nlat, long nsmax, const eckit::Configuration& ); - void ctor_spectral_only(long truncation, const eckit::Configuration& ); + void ctor_spectral_only( long truncation, const eckit::Configuration& ); private: - friend class grid::detail::partitioner::TransPartitioner; - - /// @brief Constructor for grid-only setup (e.g. for partitioning/parallelisation routines) - TransIFS(const Grid& g, const eckit::Configuration& = util::NoConfig() ); - - int handle() const { return trans_->handle; } - int ndgl() const { return trans_->ndgl; } - int nsmax() const { return trans_->nsmax; } - int ngptot() const { return trans_->ngptot; } - int ngptotg() const { return trans_->ngptotg; } - int ngptotmx() const { return trans_->ngptotmx; } - int nspec() const { return trans_->nspec; } - int nspec2() const { return trans_->nspec2; } - int nspec2g() const { return trans_->nspec2g; } - int nspec2mx() const { return trans_->nspec2mx; } - int n_regions_NS() const { return trans_->n_regions_NS; } - int n_regions_EW() const { return trans_->n_regions_EW; } - int nump() const { return trans_->nump; } - int nproc() const { return trans_->nproc; } - int myproc(int proc0=0) const { return trans_->myproc-1+proc0; } - - const int* nloen(int& size) const - { - size = trans_->ndgl; - ASSERT( trans_->nloen != NULL ); - return trans_->nloen; - } - - array::LocalView nloen() const - { - ASSERT( trans_->nloen != NULL ); - return array::LocalView(trans_->nloen, array::make_shape(trans_->ndgl)); - } - - const int* n_regions(int& size) const - { - size = trans_->n_regions_NS; - ASSERT( trans_->n_regions != NULL ); - return trans_->n_regions; - } - - array::LocalView n_regions() const - { - ASSERT( trans_->n_regions != NULL ); - return array::LocalView(trans_->n_regions, array::make_shape(trans_->n_regions_NS)); - } - - - const int* nfrstlat(int& size) const - { - size = trans_->n_regions_NS; - if( trans_->nfrstlat == NULL ) ::trans_inquire(trans_.get(),"nfrstlat"); - return trans_->nfrstlat; - } - - array::LocalView nfrstlat() const - { - if( trans_->nfrstlat == NULL ) ::trans_inquire(trans_.get(),"nfrstlat"); - return array::LocalView(trans_->nfrstlat, array::make_shape(trans_->n_regions_NS)); - } - - const int* nlstlat(int& size) const - { - size = trans_->n_regions_NS; - if( trans_->nlstlat == NULL ) ::trans_inquire(trans_.get(),"nlstlat"); - return trans_->nlstlat; - } - - array::LocalView nlstlat() const - { - if( trans_->nlstlat == NULL ) ::trans_inquire(trans_.get(),"nlstlat"); - return array::LocalView(trans_->nlstlat, array::make_shape(trans_->n_regions_NS)); - } - - const int* nptrfrstlat(int& size) const - { - size = trans_->n_regions_NS; - if( trans_->nptrfrstlat == NULL ) ::trans_inquire(trans_.get(),"nptrfrstlat"); - return trans_->nptrfrstlat; - } - - array::LocalView nptrfrstlat() const - { - if( trans_->nptrfrstlat == NULL ) ::trans_inquire(trans_.get(),"nptrfrstlat"); - return array::LocalView(trans_->nptrfrstlat, array::make_shape(trans_->n_regions_NS)); - } - - const int* nsta(int& sizef2, int& sizef1) const - { - sizef1 = trans_->ndgl+trans_->n_regions_NS-1; - sizef2 = trans_->n_regions_EW; - if( trans_->nsta == NULL ) ::trans_inquire(trans_.get(),"nsta"); - return trans_->nsta; - } - - array::LocalView nsta() const - { - if( trans_->nsta == NULL ) ::trans_inquire(trans_.get(),"nsta"); - return array::LocalView( trans_->nsta, array::make_shape(trans_->n_regions_EW, trans_->ndgl+trans_->n_regions_NS-1) ); - } - - const int* nonl(int& sizef2, int& sizef1) const - { - sizef1 = trans_->ndgl+trans_->n_regions_NS-1; - sizef2 = trans_->n_regions_EW; - if( trans_->nonl == NULL ) ::trans_inquire(trans_.get(),"nonl"); - return trans_->nonl; - } - - array::LocalView nonl() const - { - if( trans_->nonl == NULL ) ::trans_inquire(trans_.get(),"nonl"); - return array::LocalView( trans_->nonl, array::make_shape(trans_->n_regions_EW, trans_->ndgl+trans_->n_regions_NS-1) ); - } - - const int* nmyms(int& size) const - { - size = trans_->nump; - if( trans_->nmyms == NULL ) ::trans_inquire(trans_.get(),"nmyms"); - return trans_->nmyms; - } - - array::LocalView nmyms() const - { - if( trans_->nmyms == NULL ) ::trans_inquire(trans_.get(),"nmyms"); - return array::LocalView (trans_->nmyms, array::make_shape(trans_->nump)); - } - - const int* nasm0(int& size) const - { - size = trans_->nsmax+1; // +1 because zeroth wave included - if( trans_->nasm0 == NULL ) ::trans_inquire(trans_.get(),"nasm0"); - return trans_->nasm0; - } - - array::LocalView nasm0() const - { - if( trans_->nasm0 == NULL ) ::trans_inquire(trans_.get(),"nasm0"); - return array::LocalView (trans_->nasm0, array::make_shape(trans_->nsmax+1) ); - } - - const int* nvalue(int& size) const - { - size = trans_->nspec2; - if( trans_->nvalue == NULL ) ::trans_inquire(trans_.get(),"nvalue"); - return trans_->nvalue; - } - - array::LocalView nvalue() const - { - if( trans_->nvalue == NULL ) ::trans_inquire(trans_.get(),"nvalue"); - return array::LocalView (trans_->nvalue, array::make_shape(trans_->nspec2)); - } - + friend class grid::detail::partitioner::TransPartitioner; + + /// @brief Constructor for grid-only setup (e.g. for + /// partitioning/parallelisation routines) + TransIFS( const Grid& g, const eckit::Configuration& = util::NoConfig() ); + + int handle() const { return trans_->handle; } + int ndgl() const { return trans_->ndgl; } + int nsmax() const { return trans_->nsmax; } + int ngptot() const { return trans_->ngptot; } + int ngptotg() const { return trans_->ngptotg; } + int ngptotmx() const { return trans_->ngptotmx; } + int nspec() const { return trans_->nspec; } + int nspec2() const { return trans_->nspec2; } + int nspec2g() const { return trans_->nspec2g; } + int nspec2mx() const { return trans_->nspec2mx; } + int n_regions_NS() const { return trans_->n_regions_NS; } + int n_regions_EW() const { return trans_->n_regions_EW; } + int nump() const { return trans_->nump; } + int nproc() const { return trans_->nproc; } + int myproc( int proc0 = 0 ) const { return trans_->myproc - 1 + proc0; } + + const int* nloen( int& size ) const { + size = trans_->ndgl; + ASSERT( trans_->nloen != NULL ); + return trans_->nloen; + } + + array::LocalView nloen() const { + ASSERT( trans_->nloen != NULL ); + return array::LocalView( trans_->nloen, array::make_shape( trans_->ndgl ) ); + } + + const int* n_regions( int& size ) const { + size = trans_->n_regions_NS; + ASSERT( trans_->n_regions != NULL ); + return trans_->n_regions; + } + + array::LocalView n_regions() const { + ASSERT( trans_->n_regions != NULL ); + return array::LocalView( trans_->n_regions, array::make_shape( trans_->n_regions_NS ) ); + } + + const int* nfrstlat( int& size ) const { + size = trans_->n_regions_NS; + if ( trans_->nfrstlat == NULL ) ::trans_inquire( trans_.get(), "nfrstlat" ); + return trans_->nfrstlat; + } + + array::LocalView nfrstlat() const { + if ( trans_->nfrstlat == NULL ) ::trans_inquire( trans_.get(), "nfrstlat" ); + return array::LocalView( trans_->nfrstlat, array::make_shape( trans_->n_regions_NS ) ); + } + + const int* nlstlat( int& size ) const { + size = trans_->n_regions_NS; + if ( trans_->nlstlat == NULL ) ::trans_inquire( trans_.get(), "nlstlat" ); + return trans_->nlstlat; + } + + array::LocalView nlstlat() const { + if ( trans_->nlstlat == NULL ) ::trans_inquire( trans_.get(), "nlstlat" ); + return array::LocalView( trans_->nlstlat, array::make_shape( trans_->n_regions_NS ) ); + } + + const int* nptrfrstlat( int& size ) const { + size = trans_->n_regions_NS; + if ( trans_->nptrfrstlat == NULL ) ::trans_inquire( trans_.get(), "nptrfrstlat" ); + return trans_->nptrfrstlat; + } + + array::LocalView nptrfrstlat() const { + if ( trans_->nptrfrstlat == NULL ) ::trans_inquire( trans_.get(), "nptrfrstlat" ); + return array::LocalView( trans_->nptrfrstlat, array::make_shape( trans_->n_regions_NS ) ); + } + + const int* nsta( int& sizef2, int& sizef1 ) const { + sizef1 = trans_->ndgl + trans_->n_regions_NS - 1; + sizef2 = trans_->n_regions_EW; + if ( trans_->nsta == NULL ) ::trans_inquire( trans_.get(), "nsta" ); + return trans_->nsta; + } + + array::LocalView nsta() const { + if ( trans_->nsta == NULL ) ::trans_inquire( trans_.get(), "nsta" ); + return array::LocalView( + trans_->nsta, array::make_shape( trans_->n_regions_EW, trans_->ndgl + trans_->n_regions_NS - 1 ) ); + } + + const int* nonl( int& sizef2, int& sizef1 ) const { + sizef1 = trans_->ndgl + trans_->n_regions_NS - 1; + sizef2 = trans_->n_regions_EW; + if ( trans_->nonl == NULL ) ::trans_inquire( trans_.get(), "nonl" ); + return trans_->nonl; + } + + array::LocalView nonl() const { + if ( trans_->nonl == NULL ) ::trans_inquire( trans_.get(), "nonl" ); + return array::LocalView( + trans_->nonl, array::make_shape( trans_->n_regions_EW, trans_->ndgl + trans_->n_regions_NS - 1 ) ); + } + + const int* nmyms( int& size ) const { + size = trans_->nump; + if ( trans_->nmyms == NULL ) ::trans_inquire( trans_.get(), "nmyms" ); + return trans_->nmyms; + } + + array::LocalView nmyms() const { + if ( trans_->nmyms == NULL ) ::trans_inquire( trans_.get(), "nmyms" ); + return array::LocalView( trans_->nmyms, array::make_shape( trans_->nump ) ); + } + + const int* nasm0( int& size ) const { + size = trans_->nsmax + 1; // +1 because zeroth wave included + if ( trans_->nasm0 == NULL ) ::trans_inquire( trans_.get(), "nasm0" ); + return trans_->nasm0; + } + + array::LocalView nasm0() const { + if ( trans_->nasm0 == NULL ) ::trans_inquire( trans_.get(), "nasm0" ); + return array::LocalView( trans_->nasm0, array::make_shape( trans_->nsmax + 1 ) ); + } + + const int* nvalue( int& size ) const { + size = trans_->nspec2; + if ( trans_->nvalue == NULL ) ::trans_inquire( trans_.get(), "nvalue" ); + return trans_->nvalue; + } + + array::LocalView nvalue() const { + if ( trans_->nvalue == NULL ) ::trans_inquire( trans_.get(), "nvalue" ); + return array::LocalView( trans_->nvalue, array::make_shape( trans_->nspec2 ) ); + } public: - /*! - * @brief distspec - * @param nb_fields - * @param origin - * @param global_spectra - * @param spectra - */ + * @brief distspec + * @param nb_fields + * @param origin + * @param global_spectra + * @param spectra + */ void distspec( const int nb_fields, const int origin[], const double global_spectra[], double spectra[] ) const; /*! - * @brief gathspec - * @param nb_fields - * @param destination - * @param spectra - * @param global_spectra - */ - void gathspec( const int nb_fields, const int destination[], const double spectra[], double global_spectra[] ) const; + * @brief gathspec + * @param nb_fields + * @param destination + * @param spectra + * @param global_spectra + */ + void gathspec( const int nb_fields, const int destination[], const double spectra[], + double global_spectra[] ) const; /*! - * @brief distgrid - * @param nb_fields - * @param origin - * @param global_fields - * @param fields - */ + * @brief distgrid + * @param nb_fields + * @param origin + * @param global_fields + * @param fields + */ void distgrid( const int nb_fields, const int origin[], const double global_fields[], double fields[] ) const; /*! - * @brief gathgrid - * @param nb_fields - * @param destination - * @param fields - * @param global_fields - */ + * @brief gathgrid + * @param nb_fields + * @param destination + * @param fields + * @param global_fields + */ void gathgrid( const int nb_fields, const int destination[], const double fields[], double global_fields[] ) const; - private: - friend class functionspace::detail::Spectral; - mutable std::shared_ptr<::Trans_t> trans_; - grid::StructuredGrid grid_; - const void* cache_{nullptr}; - size_t cachesize_{0}; + friend class functionspace::detail::Spectral; + mutable std::shared_ptr<::Trans_t> trans_; + grid::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); +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 ); } // ------------------------------------------------------------------ -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/TransIFSNodeColumns.cc b/src/atlas/trans/ifs/TransIFSNodeColumns.cc index a7721ac37..447270ff6 100644 --- a/src/atlas/trans/ifs/TransIFSNodeColumns.cc +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,33 +17,21 @@ namespace atlas { namespace trans { -TransIFSNodeColumns::TransIFSNodeColumns( - const functionspace::NodeColumns& gp, - const functionspace::Spectral& sp, - const eckit::Configuration& config ) : - TransIFSNodeColumns( Cache(), gp, sp, config ) { -} - -TransIFSNodeColumns::TransIFSNodeColumns( - const Cache& cache, - const functionspace::NodeColumns& gp, - const functionspace::Spectral& sp, - const eckit::Configuration& config ) : - TransIFS( cache, gp.mesh().grid(), sp.truncation(), config ) { - - assertCompatibleDistributions( gp, sp ); +TransIFSNodeColumns::TransIFSNodeColumns( const functionspace::NodeColumns& gp, const functionspace::Spectral& sp, + const eckit::Configuration& config ) : + TransIFSNodeColumns( Cache(), gp, sp, config ) {} +TransIFSNodeColumns::TransIFSNodeColumns( const Cache& cache, const functionspace::NodeColumns& gp, + const functionspace::Spectral& sp, const eckit::Configuration& config ) : + TransIFS( cache, gp.mesh().grid(), sp.truncation(), config ) { + assertCompatibleDistributions( gp, sp ); } -TransIFSNodeColumns::~TransIFSNodeColumns() -{ -} - +TransIFSNodeColumns::~TransIFSNodeColumns() {} namespace { -static TransBuilderFunctionSpace< TransIFSNodeColumns > builder("ifs(NodeColumns,Spectral)"); +static TransBuilderFunctionSpace builder( "ifs(NodeColumns,Spectral)" ); } - -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/TransIFSNodeColumns.h b/src/atlas/trans/ifs/TransIFSNodeColumns.h index bfff78fce..e0f69f1ee 100644 --- a/src/atlas/trans/ifs/TransIFSNodeColumns.h +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -17,10 +18,10 @@ namespace atlas { namespace functionspace { - class NodeColumns; - class Spectral; -} -} +class NodeColumns; +class Spectral; +} // namespace functionspace +} // namespace atlas //----------------------------------------------------------------------------- @@ -31,22 +32,16 @@ namespace trans { class TransIFSNodeColumns : public trans::TransIFS { public: + TransIFSNodeColumns( const functionspace::NodeColumns&, const functionspace::Spectral&, + const eckit::Configuration& = util::Config() ); - TransIFSNodeColumns( - const functionspace::NodeColumns&, - const functionspace::Spectral&, - const eckit::Configuration& = util::Config() ); + TransIFSNodeColumns( const Cache&, const functionspace::NodeColumns&, const functionspace::Spectral&, + const eckit::Configuration& = util::Config() ); - TransIFSNodeColumns( - const Cache&, - const functionspace::NodeColumns&, - const functionspace::Spectral&, - const eckit::Configuration& = util::Config() ); - - virtual ~TransIFSNodeColumns(); + virtual ~TransIFSNodeColumns(); }; //----------------------------------------------------------------------------- -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc index 7f11697be..adde45c53 100644 --- a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc @@ -4,43 +4,36 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "atlas/trans/ifs/TransIFSStructuredColumns.h" -#include "atlas/functionspace/StructuredColumns.h" #include "atlas/functionspace/Spectral.h" +#include "atlas/functionspace/StructuredColumns.h" namespace atlas { namespace trans { -TransIFSStructuredColumns::TransIFSStructuredColumns( - const functionspace::StructuredColumns& gp, - const functionspace::Spectral& sp, - const eckit::Configuration& config ) : - TransIFSStructuredColumns( Cache(), gp, sp, config ) { -} - -TransIFSStructuredColumns::TransIFSStructuredColumns( - const Cache& cache, - const functionspace::StructuredColumns& gp, - const functionspace::Spectral& sp, - const eckit::Configuration& config ) : - TransIFS( cache, gp.grid(), sp.truncation(), config ) { +TransIFSStructuredColumns::TransIFSStructuredColumns( const functionspace::StructuredColumns& gp, + const functionspace::Spectral& sp, + const eckit::Configuration& config ) : + TransIFSStructuredColumns( Cache(), gp, sp, config ) {} - assertCompatibleDistributions( gp, sp ); +TransIFSStructuredColumns::TransIFSStructuredColumns( const Cache& cache, const functionspace::StructuredColumns& gp, + const functionspace::Spectral& sp, + const eckit::Configuration& config ) : + TransIFS( cache, gp.grid(), sp.truncation(), config ) { + assertCompatibleDistributions( gp, sp ); } - -TransIFSStructuredColumns::~TransIFSStructuredColumns() -{ -} +TransIFSStructuredColumns::~TransIFSStructuredColumns() {} namespace { -static TransBuilderFunctionSpace< TransIFSStructuredColumns > builder("ifs(StructuredColumns,Spectral)"); +static TransBuilderFunctionSpace builder( "ifs(StructuredColumns,Spectral)" ); } -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/TransIFSStructuredColumns.h b/src/atlas/trans/ifs/TransIFSStructuredColumns.h index 5824ee2d8..a43cdce52 100644 --- a/src/atlas/trans/ifs/TransIFSStructuredColumns.h +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -17,10 +18,10 @@ namespace atlas { namespace functionspace { - class StructuredColumns; - class Spectral; -} -} +class StructuredColumns; +class Spectral; +} // namespace functionspace +} // namespace atlas //----------------------------------------------------------------------------- @@ -31,22 +32,16 @@ namespace trans { class TransIFSStructuredColumns : public trans::TransIFS { public: + TransIFSStructuredColumns( const functionspace::StructuredColumns&, const functionspace::Spectral&, + const eckit::Configuration& = util::Config() ); - TransIFSStructuredColumns( - const functionspace::StructuredColumns&, - const functionspace::Spectral&, - const eckit::Configuration& = util::Config() ); + TransIFSStructuredColumns( const Cache&, const functionspace::StructuredColumns&, const functionspace::Spectral&, + const eckit::Configuration& = util::Config() ); - TransIFSStructuredColumns( - const Cache&, - const functionspace::StructuredColumns&, - const functionspace::Spectral&, - const eckit::Configuration& = util::Config() ); - - virtual ~TransIFSStructuredColumns(); + virtual ~TransIFSStructuredColumns(); }; //----------------------------------------------------------------------------- -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/VorDivToUVIFS.cc b/src/atlas/trans/ifs/VorDivToUVIFS.cc index ac43fa55e..c8c7f5164 100644 --- a/src/atlas/trans/ifs/VorDivToUVIFS.cc +++ b/src/atlas/trans/ifs/VorDivToUVIFS.cc @@ -4,68 +4,60 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "atlas/trans/ifs/VorDivToUVIFS.h" #include "atlas/functionspace/Spectral.h" -#include "atlas/runtime/Log.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Log.h" -using atlas::functionspace::Spectral; using atlas::FunctionSpace; +using atlas::functionspace::Spectral; namespace atlas { namespace trans { namespace { -static VorDivToUVBuilder builder("ifs"); +static VorDivToUVBuilder builder( "ifs" ); } namespace { -void trans_check(const int code, const char* msg, const eckit::CodeLocation& location) { - if(code != TRANS_SUCCESS) { - std::stringstream errmsg; - errmsg << "atlas::trans ERROR: " << msg << " failed: \n"; - errmsg << ::trans_error_msg(code); - throw eckit::Exception(errmsg.str(),location); - } -} -#define TRANS_CHECK( CALL ) trans_check(CALL, #CALL, Here() ) - +void trans_check( const int code, const char* msg, const eckit::CodeLocation& location ) { + if ( code != TRANS_SUCCESS ) { + std::stringstream errmsg; + errmsg << "atlas::trans ERROR: " << msg << " failed: \n"; + errmsg << ::trans_error_msg( code ); + throw eckit::Exception( errmsg.str(), location ); + } } - -void VorDivToUVIFS::execute( const int nb_coeff, const int nb_fields, - const double vorticity[], const double divergence[], - double U[], double V[], - const eckit::Configuration& config ) const -{ - struct ::VorDivToUV_t vordiv_to_UV = new_vordiv_to_UV(); - vordiv_to_UV.rspvor = vorticity; - vordiv_to_UV.rspdiv = divergence; - vordiv_to_UV.rspu = U; - vordiv_to_UV.rspv = V; - 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) ); +#define TRANS_CHECK( CALL ) trans_check( CALL, #CALL, Here() ) + +} // namespace + +void VorDivToUVIFS::execute( const int nb_coeff, const int nb_fields, const double vorticity[], + const double divergence[], double U[], double V[], + const eckit::Configuration& config ) const { + struct ::VorDivToUV_t vordiv_to_UV = new_vordiv_to_UV(); + vordiv_to_UV.rspvor = vorticity; + vordiv_to_UV.rspdiv = divergence; + vordiv_to_UV.rspu = U; + vordiv_to_UV.rspv = V; + 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 ) ); } - -VorDivToUVIFS::VorDivToUVIFS( const int truncation, const eckit::Configuration& config ) : - truncation_(truncation) { -} +VorDivToUVIFS::VorDivToUVIFS( const int truncation, const eckit::Configuration& config ) : truncation_( truncation ) {} VorDivToUVIFS::VorDivToUVIFS( const FunctionSpace& fs, const eckit::Configuration& config ) : - truncation_( Spectral(fs).truncation() ) { -} - + truncation_( Spectral( fs ).truncation() ) {} -VorDivToUVIFS::~VorDivToUVIFS() -{ -} +VorDivToUVIFS::~VorDivToUVIFS() {} -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/ifs/VorDivToUVIFS.h b/src/atlas/trans/ifs/VorDivToUVIFS.h index 03a98273a..7c50df964 100644 --- a/src/atlas/trans/ifs/VorDivToUVIFS.h +++ b/src/atlas/trans/ifs/VorDivToUVIFS.h @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include "transi/trans.h" #include "atlas/trans/VorDivToUV.h" +#include "transi/trans.h" //----------------------------------------------------------------------------- // Forward declarations @@ -29,43 +30,40 @@ namespace trans { class VorDivToUVIFS : public trans::VorDivToUVImpl { public: + VorDivToUVIFS( const FunctionSpace&, const eckit::Configuration& = util::NoConfig() ); + VorDivToUVIFS( int truncation, const eckit::Configuration& = util::NoConfig() ); - VorDivToUVIFS( const FunctionSpace&, const eckit::Configuration& = util::NoConfig() ); - VorDivToUVIFS( int truncation, const eckit::Configuration& = util::NoConfig() ); + virtual ~VorDivToUVIFS(); - virtual ~VorDivToUVIFS(); + virtual int truncation() const override { return truncation_; } - virtual int truncation() const override { return truncation_; } + // pure virtual interface -// pure virtual interface + // -- IFS style API -- + // These fields have special interpretation required. You need to know what + // you're doing. + // See IFS trans library. -// -- IFS style API -- -// These fields have special interpretation required. You need to know what you're doing. -// See IFS trans library. - - /*! - * @brief Compute spectral wind (U/V) from spectral vorticity/divergence - * - * U = u*cos(lat) - * V = v*cos(lat) - * - * @param nb_fields [in] Number of fields - * @param vorticity [in] Spectral vorticity - * @param divergence [in] Spectral divergence - * @param U [out] Spectral wind U = u*cos(lat) - * @param V [out] Spectral wind V = v*cos(lat) - */ - virtual void execute( const int nb_coeff, const int nb_fields, - const double vorticity[], const double divergence[], - double U[], double V[], - const eckit::Configuration& = util::NoConfig() ) const override ; + /*! + * @brief Compute spectral wind (U/V) from spectral vorticity/divergence + * + * U = u*cos(lat) + * V = v*cos(lat) + * + * @param nb_fields [in] Number of fields + * @param vorticity [in] Spectral vorticity + * @param divergence [in] Spectral divergence + * @param U [out] Spectral wind U = u*cos(lat) + * @param V [out] Spectral wind V = v*cos(lat) + */ + virtual void execute( const int nb_coeff, const int nb_fields, const double vorticity[], const double divergence[], + double U[], double V[], const eckit::Configuration& = util::NoConfig() ) const override; private: - int truncation_; + int truncation_; }; - // ------------------------------------------------------------------ -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc index 75d3fc816..015f51a1e 100644 --- a/src/atlas/trans/local/FourierTransforms.cc +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -4,69 +4,72 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include +#include "atlas/trans/local/FourierTransforms.h" #include +#include #include -#include "atlas/trans/local/FourierTransforms.h" namespace atlas { namespace trans { //----------------------------------------------------------------------------- -void invtrans_fourier( - const size_t trcFT, - const double lon, // longitude in radians (in) - const int nb_fields, // Number of fields - const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) - const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) - double rgp[] ) // gridpoint +void invtrans_fourier( const size_t trcFT, + const double lon, // longitude in radians (in) + const int nb_fields, // Number of fields + const double rlegReal[], // values of associated Legendre + // functions, size (trc+1)*trc/2 + // (in) + const double rlegImag[], // values of associated Legendre + // functions, size (trc+1)*trc/2 + // (in) + double rgp[] ) // gridpoint { - for( int jfld=0; jfld=linear_truncation || fullgrid ) { +int fourier_truncation( const int truncation, const int nx, const int nxmax, const int ndgl, const double lat, + const bool fullgrid ) { + int linear_truncation = ndgl - 1; + int trc = truncation; + if ( truncation >= linear_truncation || fullgrid ) { // linear - trc = (nx-1)/2; - } else if( truncation>=ndgl*2/3-1 ) { + trc = ( nx - 1 ) / 2; + } + else if ( truncation >= ndgl * 2 / 3 - 1 ) { // quadratic - //trc = (nx-1)/(2+std::pow(std::cos(lat),2)); - trc = (nx-1)/(2+3*(linear_truncation-truncation)/ndgl*std::pow(std::cos(lat),2)); - } else { + // trc = (nx-1)/(2+std::pow(std::cos(lat),2)); + trc = ( nx - 1 ) / ( 2 + 3 * ( linear_truncation - truncation ) / ndgl * std::pow( std::cos( lat ), 2 ) ); + } + else { // cubic - trc = (nx-1)/(2+std::pow(std::cos(lat),2))-1; + trc = ( nx - 1 ) / ( 2 + std::pow( std::cos( lat ), 2 ) ) - 1; } - trc = std::min(truncation, trc); - //std::cout << "truncation=" << truncation << " trc=" << trc << " ndgl*2/3-1=" << ndgl*2/3-1 << " nx=" << nx << " nxmax=" << nxmax << " latsin2=" << std::pow(std::cos(lat),2) << std::endl; + trc = std::min( truncation, trc ); + // std::cout << "truncation=" << truncation << " trc=" << trc << " + // ndgl*2/3-1=" << ndgl*2/3-1 << " nx=" << nx << " nxmax=" << nxmax << " + // latsin2=" << std::pow(std::cos(lat),2) << std::endl; return trc; } // -------------------------------------------------------------------------------------------------------------------- -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/FourierTransforms.h b/src/atlas/trans/local/FourierTransforms.h index dfbf1dccf..44f5a186e 100644 --- a/src/atlas/trans/local/FourierTransforms.h +++ b/src/atlas/trans/local/FourierTransforms.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -22,23 +23,21 @@ namespace trans { // Andreas Mueller *ECMWF* // -void invtrans_fourier( - const size_t trcFT, - const double lon, // longitude in radians (in) - const int nb_fields, // Number of fields - const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) - const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) - double rgp[] ); // gridpoint - -int fourier_truncation( - const int truncation, - const int nx, - const int nxmax, - const int ndgl, - const double lat, - const bool fullgrid ); +void invtrans_fourier( const size_t trcFT, + const double lon, // longitude in radians (in) + const int nb_fields, // Number of fields + const double rlegReal[], // values of associated Legendre + // functions, size (trc+1)*trc/2 + // (in) + const double rlegImag[], // values of associated Legendre + // functions, size (trc+1)*trc/2 + // (in) + double rgp[] ); // gridpoint + +int fourier_truncation( const int truncation, const int nx, const int nxmax, const int ndgl, const double lat, + const bool fullgrid ); // -------------------------------------------------------------------------------------------------------------------- -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index 1693582f4..cae466ea5 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -4,13 +4,14 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/trans/local/LegendrePolynomials.h" #include #include -#include "atlas/trans/local/LegendrePolynomials.h" #include "atlas/array.h" namespace atlas { @@ -18,91 +19,93 @@ namespace trans { //----------------------------------------------------------------------------- -void compute_legendre_polynomials( - const size_t trc, // truncation (in) - const double lat, // latitude in radians (in) - double legpol[] ) // values of associated Legendre functions, size (trc+1)*trc/2 (out) +void compute_legendre_polynomials( const size_t trc, // truncation (in) + const double lat, // latitude in radians (in) + double legpol[] ) // values of associated + // Legendre functions, size + // (trc+1)*trc/2 (out) { - array::ArrayT idxmn_(trc+1,trc+1); - array::ArrayView idxmn = array::make_view(idxmn_); - int j = 0; - for( int jm=0; jm<=trc; ++jm ) { - for( int jn=jm; jn<=trc; ++jn ) { - idxmn(jm,jn) = j++; + array::ArrayT idxmn_( trc + 1, trc + 1 ); + array::ArrayView idxmn = array::make_view( idxmn_ ); + int j = 0; + for ( int jm = 0; jm <= trc; ++jm ) { + for ( int jn = jm; jn <= trc; ++jn ) { + idxmn( jm, jn ) = j++; } } - array::ArrayT zfn_(trc+1,trc+1); - array::ArrayView zfn = array::make_view(zfn_); + array::ArrayT zfn_( trc + 1, trc + 1 ); + array::ArrayView zfn = array::make_view( zfn_ ); int iodd; // Belousov, Swarztrauber use zfn(0,0)=std::sqrt(2.) // IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 - zfn(0,0) = 2.; - for( int jn=1; jn<=trc; ++jn ) { - double zfnn = zfn(0,0); - for( int jgl=1; jgl<=jn; ++jgl) { - zfnn *= std::sqrt(1.-0.25/(jgl*jgl)); + zfn( 0, 0 ) = 2.; + for ( int jn = 1; jn <= trc; ++jn ) { + double zfnn = zfn( 0, 0 ); + for ( int jgl = 1; jgl <= jn; ++jgl ) { + zfnn *= std::sqrt( 1. - 0.25 / ( jgl * jgl ) ); } - iodd = jn % 2; - zfn(jn,jn)=zfnn; - for( int jgl=2; jgl<=jn-iodd; jgl+=2 ) { - zfn(jn,jn-jgl) = zfn(jn,jn-jgl+2) * ((jgl-1.)*(2.*jn-jgl+2.)) / (jgl*(2.*jn-jgl+1.)); + iodd = jn % 2; + zfn( jn, jn ) = zfnn; + for ( int jgl = 2; jgl <= jn - iodd; jgl += 2 ) { + zfn( jn, jn - jgl ) = + zfn( jn, jn - jgl + 2 ) * ( ( jgl - 1. ) * ( 2. * jn - jgl + 2. ) ) / ( jgl * ( 2. * jn - jgl + 1. ) ); } } // -------------------- // 1. First two columns // -------------------- - double zdlx1 = (M_PI_2-lat); // theta - double zdlx = std::cos(zdlx1); // cos(theta) - double zdlsita = std::sqrt(1.-zdlx*zdlx); // sin(theta) (this is how trans library does it) + double zdlx1 = ( M_PI_2 - lat ); // theta + double zdlx = std::cos( zdlx1 ); // cos(theta) + double zdlsita = std::sqrt( 1. - zdlx * zdlx ); // sin(theta) (this is how trans library does it) - legpol[0] = 1.; + legpol[0] = 1.; double zdl1sita = 0.; // if we are less than 1 meter from the pole, - if( std::abs(zdlsita) <= std::sqrt(std::numeric_limits::epsilon()) ) - { - zdlx = 1.; + if ( std::abs( zdlsita ) <= std::sqrt( std::numeric_limits::epsilon() ) ) { + zdlx = 1.; zdlsita = 0.; - } else { - zdl1sita = 1./zdlsita; + } + else { + zdl1sita = 1. / zdlsita; } // ordinary Legendre polynomials from series expansion // --------------------------------------------------- // even N - for( int jn=2; jn<=trc; jn+=2 ) { - double zdlk = 0.5*zfn(jn,0); + for ( int jn = 2; jn <= trc; jn += 2 ) { + double zdlk = 0.5 * zfn( jn, 0 ); double zdlldn = 0.0; // represented by only even k - for (int jk=2; jk<=jn; jk+=2 ) { + for ( int jk = 2; jk <= jn; jk += 2 ) { // normalised ordinary Legendre polynomial == \overbar{P_n}^0 - zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); + zdlk = zdlk + zfn( jn, jk ) * std::cos( jk * zdlx1 ); // normalised associated Legendre polynomial == \overbar{P_n}^1 - zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); + zdlldn = zdlldn + 1. / std::sqrt( jn * ( jn + 1. ) ) * zfn( jn, jk ) * jk * std::sin( jk * zdlx1 ); } - legpol[idxmn(0,jn)] = zdlk; - legpol[idxmn(1,jn)] = zdlldn; + legpol[idxmn( 0, jn )] = zdlk; + legpol[idxmn( 1, jn )] = zdlldn; } // odd N - for( int jn=1; jn<=trc; jn+=2 ) { - zfn(jn,0) = 0.; - double zdlk = 0.; + for ( int jn = 1; jn <= trc; jn += 2 ) { + zfn( jn, 0 ) = 0.; + double zdlk = 0.; double zdlldn = 0.0; // represented by only even k - for (int jk=1; jk<=jn; jk+=2 ) { + for ( int jk = 1; jk <= jn; jk += 2 ) { // normalised ordinary Legendre polynomial == \overbar{P_n}^0 - zdlk = zdlk + zfn(jn,jk)*std::cos(jk*zdlx1); + zdlk = zdlk + zfn( jn, jk ) * std::cos( jk * zdlx1 ); // normalised associated Legendre polynomial == \overbar{P_n}^1 - zdlldn = zdlldn + 1./std::sqrt(jn*(jn+1.))*zfn(jn,jk)*jk*std::sin(jk*zdlx1); + zdlldn = zdlldn + 1. / std::sqrt( jn * ( jn + 1. ) ) * zfn( jn, jk ) * jk * std::sin( jk * zdlx1 ); } - legpol[idxmn(0,jn)] = zdlk; - legpol[idxmn(1,jn)] = zdlldn; + legpol[idxmn( 0, jn )] = zdlk; + legpol[idxmn( 1, jn )] = zdlldn; } // -------------------------------------------------------------- @@ -110,30 +113,33 @@ void compute_legendre_polynomials( // Belousov, equation (23) // -------------------------------------------------------------- - double zdls = zdl1sita*std::numeric_limits::min(); - for( int jn=2; jn<=trc; ++jn ) { - legpol[idxmn(jn,jn)] = legpol[idxmn(jn-1,jn-1)]*zdlsita*std::sqrt((2.*jn+1.)/(2.*jn)); - if( std::abs(legpol[idxmn(jn,jn)]) < zdls ) legpol[idxmn(jn,jn)] = 0.0; + double zdls = zdl1sita * std::numeric_limits::min(); + for ( int jn = 2; jn <= trc; ++jn ) { + legpol[idxmn( jn, jn )] = + legpol[idxmn( jn - 1, jn - 1 )] * zdlsita * std::sqrt( ( 2. * jn + 1. ) / ( 2. * jn ) ); + if ( std::abs( legpol[idxmn( jn, jn )] ) < zdls ) legpol[idxmn( jn, jn )] = 0.0; } // --------------------------------------------- // 3. General recurrence (Belousov, equation 17) // --------------------------------------------- - for( int jn=3; jn<=trc; ++jn ) { - for( int jm=2; jm #include "atlas/trans/local/LegendreTransforms.h" +#include namespace atlas { namespace trans { //----------------------------------------------------------------------------- -void invtrans_legendre( - const size_t trc, // truncation (in) - const size_t trcFT, // truncation for Fourier transformation (in) - const size_t trcLP, // truncation of Legendre polynomials data legpol. Needs to be >= trc (in) - const double legpol[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) - const int nb_fields, // number of fields - const double spec[], // spectral data, size (trc+1)*trc (in) - double leg_real[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) - double leg_imag[] ) // values of associated Legendre functions, size (trc+1)*trc/2 (out) +void invtrans_legendre( const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + const size_t trcLP, // truncation of Legendre polynomials data legpol. Needs + // to be >= trc (in) + const double legpol[], // values of associated Legendre functions, size + // (trc+1)*trc/2 (in) + const int nb_fields, // number of fields + const double spec[], // spectral data, size (trc+1)*trc (in) + double leg_real[], // values of associated Legendre functions, size + // (trc+1)*trc/2 (out) + double leg_imag[] ) // values of associated Legendre functions, size + // (trc+1)*trc/2 (out) { // Legendre transformation: int k = 0, klp = 0; - for( int jm=0; jm<=trcFT; ++jm ) { - for( int jfld=0; jfld0 - leg_real[jm*nb_fields+jfld] += 2. * spec[(2*k )*nb_fields+jfld] * legpol[klp]; - leg_imag[jm*nb_fields+jfld] += 2. * spec[(2*k+1)*nb_fields+jfld] * legpol[klp]; + for ( int jn = jm; jn <= trcLP; ++jn, ++klp ) { + if ( jn <= trc ) { + for ( int jfld = 0; jfld < nb_fields; ++jfld ) { + // not completely sure where this factor 2 comes from. One possible + // explanation: + // normalization of trigonometric functions in the spherical harmonics + // integral over square of trig function is 1 for m=0 and 0.5 (?) for + // m>0 + leg_real[jm * nb_fields + jfld] += 2. * spec[( 2 * k ) * nb_fields + jfld] * legpol[klp]; + leg_imag[jm * nb_fields + jfld] += 2. * spec[( 2 * k + 1 ) * nb_fields + jfld] * legpol[klp]; } ++k; } } } // Undo factor 2 for (jm == 0) - for( int jfld=0; jfld= trc (in) - const double legpol[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) - const int nb_fields, // number of fields - const double spec[], // spectral data, size (trc+1)*trc (in) - double leg_real[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) - double leg_imag[] ); // values of associated Legendre functions, size (trc+1)*trc/2 (out) +void invtrans_legendre( const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + const size_t trcLP, // truncation of Legendre polynomials data legpol. Needs + // to be >= trc (in) + const double legpol[], // values of associated Legendre functions, size + // (trc+1)*trc/2 (in) + const int nb_fields, // number of fields + const double spec[], // spectral data, size (trc+1)*trc (in) + double leg_real[], // values of associated Legendre functions, size + // (trc+1)*trc/2 (out) + double leg_imag[] ); // values of associated Legendre functions, size + // (trc+1)*trc/2 (out) // -------------------------------------------------------------------------------------------------------------------- -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 900911c2e..0f534831e 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -4,78 +4,80 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "atlas/trans/local/TransLocal.h" #include "atlas/array.h" +#include "atlas/option.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "atlas/parallel/mpi/mpi.h" +#include "atlas/trans/VorDivToUV.h" #include "atlas/trans/local/FourierTransforms.h" -#include "atlas/trans/local/LegendreTransforms.h" #include "atlas/trans/local/LegendrePolynomials.h" -#include "atlas/trans/VorDivToUV.h" -#include "atlas/option.h" +#include "atlas/trans/local/LegendreTransforms.h" namespace atlas { namespace trans { namespace { -static TransBuilderGrid builder("local"); +static TransBuilderGrid builder( "local" ); } // -------------------------------------------------------------------------------------------------------------------- // Helper functions // -------------------------------------------------------------------------------------------------------------------- -namespace { // anonymous +namespace { // anonymous size_t legendre_size( const size_t truncation ) { - return (truncation+2)*(truncation+1)/2; + return ( truncation + 2 ) * ( truncation + 1 ) / 2; } -} // namespace anonymous +} // namespace // -------------------------------------------------------------------------------------------------------------------- // Class TransLocal // -------------------------------------------------------------------------------------------------------------------- -TransLocal::TransLocal( const Cache& cache, const Grid& grid, const long truncation, const eckit::Configuration& config ) : - grid_(grid), - truncation_(truncation), - precompute_ ( config.getBool("precompute", true) ) -{ +TransLocal::TransLocal( const Cache& cache, const Grid& grid, const long truncation, + const eckit::Configuration& config ) : + grid_( grid ), + truncation_( truncation ), + precompute_( config.getBool( "precompute", true ) ) { if ( precompute_ ) { - if( grid::StructuredGrid(grid_) && not grid_.projection() ) { - ATLAS_TRACE("Precompute legendre structured"); - grid::StructuredGrid g(grid_); - size_t size(0); + if ( grid::StructuredGrid( grid_ ) && not grid_.projection() ) { + ATLAS_TRACE( "Precompute legendre structured" ); + grid::StructuredGrid g( grid_ ); + size_t size( 0 ); legendre_begin_.resize( g.ny() ); - for( size_t j=0; j 0. // // Author: // Andreas Mueller *ECMWF* // -void TransLocal::invtrans_uv( - const int truncation, - const int nb_scalar_fields, const int nb_vordiv_fields, const double scalar_spectra[], - double gp_fields[], - const eckit::Configuration& config ) const -{ - if( nb_scalar_fields>0 ) { +void TransLocal::invtrans_uv( const int truncation, const int nb_scalar_fields, const int nb_vordiv_fields, + const double scalar_spectra[], double gp_fields[], + const eckit::Configuration& config ) const { + if ( nb_scalar_fields > 0 ) { int nb_fields = nb_scalar_fields; // Depending on "precompute_legendre_", we have to compute the // legendre polynomials for every latitute std::vector recomputed_legendre_; - auto legPol = [&](double lat, int j) -> const double * { - if( precompute_ ) { - return legendre_data(j); - } else { - recomputed_legendre_.resize( legendre_size( truncation ) ); - compute_legendre_polynomials( truncation, lat, recomputed_legendre_.data() ); - return recomputed_legendre_.data(); - } + auto legPol = [&]( double lat, int j ) -> const double* { + if ( precompute_ ) { return legendre_data( j ); } + else { + recomputed_legendre_.resize( legendre_size( truncation ) ); + compute_legendre_polynomials( truncation, lat, recomputed_legendre_.data() ); + return recomputed_legendre_.data(); + } }; // Temporary storage for legendre space - std::vector legReal(nb_fields*(truncation+1)); - std::vector legImag(nb_fields*(truncation+1)); - std::vector gp_tmp(nb_fields*grid_.size(), 0.); + std::vector legReal( nb_fields * ( truncation + 1 ) ); + std::vector legImag( nb_fields * ( truncation + 1 ) ); + std::vector gp_tmp( nb_fields * grid_.size(), 0. ); // Transform - if( grid::StructuredGrid g = grid_ ) { - ATLAS_TRACE( "invtrans_uv structured"); + if ( grid::StructuredGrid g = grid_ ) { + ATLAS_TRACE( "invtrans_uv structured" ); int idx = 0; - for( size_t j=0; j vorticity_spectra_extended(nb_vordiv_spec_ext,0.); - std::vector divergence_spectra_extended(nb_vordiv_spec_ext,0.); - extend_truncation(truncation_, nb_vordiv_fields, vorticity_spectra, vorticity_spectra_extended.data()); - extend_truncation(truncation_, nb_vordiv_fields, divergence_spectra, divergence_spectra_extended.data()); + int nb_vordiv_spec_ext = 2 * legendre_size( truncation_ + 1 ) * nb_vordiv_fields; + std::vector vorticity_spectra_extended( nb_vordiv_spec_ext, 0. ); + std::vector divergence_spectra_extended( nb_vordiv_spec_ext, 0. ); + extend_truncation( truncation_, nb_vordiv_fields, vorticity_spectra, vorticity_spectra_extended.data() ); + extend_truncation( truncation_, nb_vordiv_fields, divergence_spectra, divergence_spectra_extended.data() ); // call vd2uv to compute u and v in spectral space - std::vector U_ext(nb_vordiv_spec_ext,0.); - std::vector V_ext(nb_vordiv_spec_ext,0.); - trans::VorDivToUV vordiv_to_UV_ext(truncation_+1, option::type("local")); - vordiv_to_UV_ext.execute( nb_vordiv_spec_ext, nb_vordiv_fields, vorticity_spectra_extended.data(), divergence_spectra_extended.data(), U_ext.data(), V_ext.data() ); + std::vector U_ext( nb_vordiv_spec_ext, 0. ); + std::vector V_ext( nb_vordiv_spec_ext, 0. ); + trans::VorDivToUV vordiv_to_UV_ext( truncation_ + 1, option::type( "local" ) ); + vordiv_to_UV_ext.execute( nb_vordiv_spec_ext, nb_vordiv_fields, vorticity_spectra_extended.data(), + divergence_spectra_extended.data(), U_ext.data(), V_ext.data() ); // perform spectral transform to compute all fields in grid point space - invtrans_uv(truncation_+1, nb_vordiv_fields, nb_vordiv_fields, U_ext.data(), gp_fields, config); - invtrans_uv(truncation_+1, nb_vordiv_fields, nb_vordiv_fields, V_ext.data(), gp_fields+nb_gp*nb_vordiv_fields, config); - invtrans_uv(truncation_ , nb_scalar_fields, 0, scalar_spectra, gp_fields+2*nb_gp*nb_vordiv_fields, config); - + invtrans_uv( truncation_ + 1, nb_vordiv_fields, nb_vordiv_fields, U_ext.data(), gp_fields, config ); + invtrans_uv( truncation_ + 1, nb_vordiv_fields, nb_vordiv_fields, V_ext.data(), + gp_fields + nb_gp * nb_vordiv_fields, config ); + invtrans_uv( truncation_, nb_scalar_fields, 0, scalar_spectra, gp_fields + 2 * nb_gp * nb_vordiv_fields, config ); } // -------------------------------------------------------------------------------------------------------------------- -void TransLocal::dirtrans( - const Field& gpfield, - Field& spfield, - const eckit::Configuration& config ) const -{ - NOTIMP; - // Not implemented and not planned. - // Use the TransIFS implementation instead. +void TransLocal::dirtrans( const Field& gpfield, Field& spfield, const eckit::Configuration& config ) const { + NOTIMP; + // Not implemented and not planned. + // Use the TransIFS implementation instead. } // -------------------------------------------------------------------------------------------------------------------- -void TransLocal::dirtrans( - const FieldSet& gpfields, - FieldSet& spfields, - const eckit::Configuration& config ) const -{ - NOTIMP; - // Not implemented and not planned. - // Use the TransIFS implementation instead. +void TransLocal::dirtrans( const FieldSet& gpfields, FieldSet& spfields, const eckit::Configuration& config ) const { + NOTIMP; + // Not implemented and not planned. + // Use the TransIFS implementation instead. } // -------------------------------------------------------------------------------------------------------------------- -void TransLocal::dirtrans_wind2vordiv( - const Field& gpwind, - Field& spvor, Field& spdiv, - const eckit::Configuration& config ) const -{ - NOTIMP; - // Not implemented and not planned. - // Use the TransIFS implementation instead. +void TransLocal::dirtrans_wind2vordiv( const Field& gpwind, Field& spvor, Field& spdiv, + const eckit::Configuration& config ) const { + NOTIMP; + // Not implemented and not planned. + // Use the TransIFS implementation instead. } // -------------------------------------------------------------------------------------------------------------------- -void TransLocal::dirtrans( - const int nb_fields, - const double scalar_fields[], - double scalar_spectra[], - const eckit::Configuration& ) const -{ - NOTIMP; - // Not implemented and not planned. - // Use the TransIFS implementation instead. +void TransLocal::dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& ) const { + NOTIMP; + // Not implemented and not planned. + // Use the TransIFS implementation instead. } // -------------------------------------------------------------------------------------------------------------------- -void TransLocal::dirtrans( - const int nb_fields, - const double wind_fields[], - double vorticity_spectra[], - double divergence_spectra[], - const eckit::Configuration& ) const -{ - NOTIMP; - // Not implemented and not planned. - // Use the TransIFS implementation instead. +void TransLocal::dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], + double divergence_spectra[], const eckit::Configuration& ) const { + NOTIMP; + // Not implemented and not planned. + // Use the TransIFS implementation instead. } // -------------------------------------------------------------------------------------------------------------------- -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/TransLocal.h b/src/atlas/trans/local/TransLocal.h index d88dd45d7..41a3d51a8 100644 --- a/src/atlas/trans/local/TransLocal.h +++ b/src/atlas/trans/local/TransLocal.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -18,9 +19,9 @@ // Forward declarations namespace atlas { - class Field; - class FieldSet; -} +class Field; +class FieldSet; +} // namespace atlas //----------------------------------------------------------------------------- @@ -42,94 +43,79 @@ namespace trans { /// @note: Direct transforms are not implemented and cannot be unless /// the grid is global. There are no plans to support this at the moment. class TransLocal : public trans::TransImpl { - public: + TransLocal( const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); + TransLocal( const Cache&, const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); - TransLocal( const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); - TransLocal( const Cache&, const Grid& g, const long truncation, const eckit::Configuration& = util::NoConfig() ); - - virtual ~TransLocal(); - - virtual int truncation() const override { return truncation_; } - virtual size_t spectralCoefficients() const override { return (truncation_+1)*(truncation_+2); } + virtual ~TransLocal(); - virtual const Grid& grid() const override { return grid_; } + virtual int truncation() const override { return truncation_; } + virtual size_t spectralCoefficients() const override { return ( truncation_ + 1 ) * ( truncation_ + 2 ); } + virtual const Grid& grid() const override { return grid_; } - virtual void invtrans( const Field& spfield, - Field& gpfield, - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans( const Field& spfield, Field& gpfield, + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void invtrans( const FieldSet& spfields, - FieldSet& gpfields, - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans( const FieldSet& spfields, FieldSet& gpfields, + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void invtrans_grad( const Field& spfield, - Field& gradfield, - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans_grad( const Field& spfield, Field& gradfield, + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void invtrans_grad( const FieldSet& spfields, - FieldSet& gradfields, - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans_grad( const FieldSet& spfields, FieldSet& gradfields, + const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, Field& gpwind, + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void invtrans_vordiv2wind( const Field& spvor, const Field& spdiv, - Field& gpwind, - const eckit::Configuration& = util::NoConfig() ) const override; + // -- IFS style API -- -// -- IFS style API -- + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], const int nb_vordiv_fields, + const double vorticity_spectra[], const double divergence_spectra[], double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void invtrans( const int nb_scalar_fields, const double scalar_spectra[], - double gp_fields[], - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], + const double divergence_spectra[], double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void invtrans( const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], - double gp_fields[], - const eckit::Configuration& = util::NoConfig() ) const override; + // -- NOT SUPPORTED -- // -// -- NOT SUPPORTED -- // + virtual void dirtrans( const Field& gpfield, Field& spfield, + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void dirtrans( const Field& gpfield, - Field& spfield, - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void dirtrans( const FieldSet& gpfields, FieldSet& spfields, + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void dirtrans( const FieldSet& gpfields, - FieldSet& spfields, - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void dirtrans_wind2vordiv( const Field& gpwind, Field& spvor, Field& spdiv, + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void dirtrans_wind2vordiv( const Field& gpwind, - Field& spvor, Field& spdiv, - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], + const eckit::Configuration& = util::NoConfig() ) const override; - virtual void dirtrans( const int nb_fields, const double scalar_fields[], double scalar_spectra[], - const eckit::Configuration& = util::NoConfig() ) const override; - - virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], double divergence_spectra[], - const eckit::Configuration& = util::NoConfig() ) const override; + virtual void dirtrans( const int nb_fields, const double wind_fields[], double vorticity_spectra[], + double divergence_spectra[], const eckit::Configuration& = util::NoConfig() ) const override; private: + const double* legendre_data( int j ) const { return legendre_.data() + legendre_begin_[j]; } + double* legendre_data( int j ) { return legendre_.data() + legendre_begin_[j]; } - const double* legendre_data( int j ) const { return legendre_.data() + legendre_begin_[j]; } - double* legendre_data( int j ) { return legendre_.data() + legendre_begin_[j]; } - - void invtrans_uv(const int truncation, const int nb_scalar_fields, const int nb_vordiv_fields, const double scalar_spectra[], - double gp_fields[], - const eckit::Configuration& = util::NoConfig() ) const; + void invtrans_uv( const int truncation, const int nb_scalar_fields, const int nb_vordiv_fields, + const double scalar_spectra[], double gp_fields[], + const eckit::Configuration& = util::NoConfig() ) const; private: - int truncation_; - Grid grid_; - bool precompute_; - std::vector legendre_; - std::vector legendre_begin_; + int truncation_; + Grid grid_; + bool precompute_; + std::vector legendre_; + std::vector legendre_begin_; }; //----------------------------------------------------------------------------- -} // namespace trans -} // namespace atlas +} // namespace trans +} // namespace atlas diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index adc866595..4d60dfd2e 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,186 +15,171 @@ #include "atlas/runtime/Log.h" #include "atlas/util/Earth.h" -using atlas::functionspace::Spectral; using atlas::FunctionSpace; +using atlas::functionspace::Spectral; namespace atlas { namespace trans { namespace { -static VorDivToUVBuilder builder("local"); +static VorDivToUVBuilder builder( "local" ); } // -------------------------------------------------------------------------------------------------------------------- // Routine to copy spectral data into internal storage form of IFS trans // Ported to C++ by: Andreas Mueller *ECMWF* -void prfi1b( - const int truncation, - const int km, // zonal wavenumber - const int nb_fields, // number of fields - const double rspec[], // spectral data - double pia[]) // spectral components in data layout of trans library +void prfi1b( const int truncation, + const int km, // zonal wavenumber + const int nb_fields, // number of fields + const double rspec[], // spectral data + double pia[] ) // spectral components in data layout of trans library { - int ilcm = truncation+1-km, ioff = (2*truncation-km+3)*km, nlei1 = truncation+4+(truncation+4+1)%2; - for( int j=1; j<=ilcm; j++ ) { - int inm = ioff+(ilcm-j)*2; - for( int jfld=0; jfld repsnm((truncation+1)*(truncation+6)/2); + std::vector repsnm( ( truncation + 1 ) * ( truncation + 6 ) / 2 ); int idx = 0; - for( int jm=0; jm<=truncation; ++jm ) { - for( int jn=jm; jn<=truncation+2; ++jn, ++idx ) { - repsnm[idx] = std::sqrt((jn*jn-jm*jm)/(4.*jn*jn-1.)); + for ( int jm = 0; jm <= truncation; ++jm ) { + for ( int jn = jm; jn <= truncation + 2; ++jn, ++idx ) { + repsnm[idx] = std::sqrt( ( jn * jn - jm * jm ) / ( 4. * jn * jn - 1. ) ); } } repsnm[0] = 0.; // rlapin: constant factor from eq.(2.2) and (2.3) in [Temperton 1991] - std::vector rlapin(truncation+3); - for( int jn=1; jn<=truncation+2; ++jn ) { - rlapin[jn] = -util::Earth::radiusInMeters()*util::Earth::radiusInMeters()/(jn*(jn+1.)); + std::vector rlapin( truncation + 3 ); + for ( int jn = 1; jn <= truncation + 2; ++jn ) { + rlapin[jn] = -util::Earth::radiusInMeters() * util::Earth::radiusInMeters() / ( jn * ( jn + 1. ) ); } rlapin[0] = 0.; // inverse the order of repsnm and rlapin for improved accuracy - std::vector zepsnm(truncation+6); - std::vector zlapin(truncation+6); - std::vector zn (truncation+6); - for( int jn=km-1; jn<=truncation+2; ++jn ) { - int ij = truncation+3-jn; - if( jn>=0 ) { + std::vector zepsnm( truncation + 6 ); + std::vector zlapin( truncation + 6 ); + std::vector zn( truncation + 6 ); + for ( int jn = km - 1; jn <= truncation + 2; ++jn ) { + int ij = truncation + 3 - jn; + if ( jn >= 0 ) { zlapin[ij] = rlapin[jn]; - if ( jn rvor(2*nb_vordiv_fields*nlei1); - std::vector rdiv(2*nb_vordiv_fields*nlei1); - std::vector ru (2*nb_vordiv_fields*nlei1); - std::vector rv (2*nb_vordiv_fields*nlei1); - prfi1b(truncation, km, nb_vordiv_fields, vorticity_spectra, rvor.data()); - prfi1b(truncation, km, nb_vordiv_fields, divergence_spectra, rdiv.data()); + std::vector rvor( 2 * nb_vordiv_fields * nlei1 ); + std::vector rdiv( 2 * nb_vordiv_fields * nlei1 ); + std::vector ru( 2 * nb_vordiv_fields * nlei1 ); + std::vector rv( 2 * nb_vordiv_fields * nlei1 ); + prfi1b( truncation, km, nb_vordiv_fields, vorticity_spectra, rvor.data() ); + prfi1b( truncation, km, nb_vordiv_fields, divergence_spectra, rdiv.data() ); // compute eq.(2.12) and (2.13) in [Temperton 1991]: - if( km==0 ) { - for( int jfld=0; jfld=0; i--) { - str[i] = (flags&1)?'1':'0'; - flags >>= 1; - } - return std::string(str,9); - } + static std::string bitstr( int flags ) { + char str[9] = {0}; + int i; + for ( i = 7; i >= 0; i-- ) { + str[i] = ( flags & 1 ) ? '1' : '0'; + flags >>= 1; + } + return std::string( str, 9 ); + } }; -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Checksum.cc b/src/atlas/util/Checksum.cc index df6388a39..52268fe36 100644 --- a/src/atlas/util/Checksum.cc +++ b/src/atlas/util/Checksum.cc @@ -1,57 +1,53 @@ +#include "atlas/util/Checksum.h" #include #include -#include "atlas/util/Checksum.h" namespace atlas { namespace util { -namespace { // anonymous +namespace { // anonymous // Inefficient implementation of Fletcher's checksum algorithm static uint16_t fletcher16( const uint8_t* data, int size ) { - uint16_t s1(0), s2(0); - for (int i=0; i(data), size/sizeof(uint32_t) ); - // return fletcher32( reinterpret_cast(data), size/sizeof(uint16_t) ); - return fletcher16( reinterpret_cast(data), size/sizeof(uint8_t) ); +static checksum_t checksum( const char* data, size_t size ) { + // return fletcher64( reinterpret_cast(data), + // size/sizeof(uint32_t) ); + // return fletcher32( reinterpret_cast(data), + // size/sizeof(uint16_t) ); + return fletcher16( reinterpret_cast( data ), size / sizeof( uint8_t ) ); } -checksum_t checksum(const int values[], size_t size) -{ - return checksum(reinterpret_cast(&values[0]),size*sizeof(int)/sizeof(char)); +checksum_t checksum( const int values[], size_t size ) { + return checksum( reinterpret_cast( &values[0] ), size * sizeof( int ) / sizeof( char ) ); } -checksum_t checksum(const long values[], size_t size) -{ - return checksum(reinterpret_cast(&values[0]),size*sizeof(long)/sizeof(char)); +checksum_t checksum( const long values[], size_t size ) { + return checksum( reinterpret_cast( &values[0] ), size * sizeof( long ) / sizeof( char ) ); } -checksum_t checksum(const float values[], size_t size) -{ - return checksum(reinterpret_cast(&values[0]),size*sizeof(float)/sizeof(char)); +checksum_t checksum( const float values[], size_t size ) { + return checksum( reinterpret_cast( &values[0] ), size * sizeof( float ) / sizeof( char ) ); } -checksum_t checksum(const double values[], size_t size) -{ - return checksum(reinterpret_cast(&values[0]),size*sizeof(double)/sizeof(char)); +checksum_t checksum( const double values[], size_t size ) { + return checksum( reinterpret_cast( &values[0] ), size * sizeof( double ) / sizeof( char ) ); } -checksum_t checksum(const checksum_t values[], size_t size) -{ - return checksum(reinterpret_cast(&values[0]),size*sizeof(checksum_t)/sizeof(char)); +checksum_t checksum( const checksum_t values[], size_t size ) { + return checksum( reinterpret_cast( &values[0] ), size * sizeof( checksum_t ) / sizeof( char ) ); } -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Checksum.h b/src/atlas/util/Checksum.h index b13ed1e70..a8f68ee33 100644 --- a/src/atlas/util/Checksum.h +++ b/src/atlas/util/Checksum.h @@ -1,15 +1,17 @@ #pragma once +#include + namespace atlas { namespace util { typedef unsigned long checksum_t; -checksum_t checksum(const int values[], size_t size); -checksum_t checksum(const long values[], size_t size); -checksum_t checksum(const float values[], size_t size); -checksum_t checksum(const double values[], size_t size); -checksum_t checksum(const checksum_t values[], size_t size); +checksum_t checksum( const int values[], size_t size ); +checksum_t checksum( const long values[], size_t size ); +checksum_t checksum( const float values[], size_t size ); +checksum_t checksum( const double values[], size_t size ); +checksum_t checksum( const checksum_t values[], size_t size ); -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Config.cc b/src/atlas/util/Config.cc index fa415fad5..67424cc39 100644 --- a/src/atlas/util/Config.cc +++ b/src/atlas/util/Config.cc @@ -4,22 +4,23 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/util/Config.h" +#include #include -#include #include -#include +#include +#include "atlas/grid/Grid.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/runtime/ErrorHandling.h" #include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" #include "eckit/parser/JSON.h" #include "eckit/parser/YAMLParser.h" -#include "atlas/grid/Grid.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/util/Config.h" -#include "atlas/runtime/ErrorHandling.h" using std::string; @@ -28,86 +29,74 @@ namespace util { namespace { -static eckit::Value yaml_from_stream(std::istream& stream){ +static eckit::Value yaml_from_stream( std::istream& stream ) { eckit::YAMLParser parser( stream ); return parser.parse(); } -static eckit::Value yaml_from_path(const eckit::PathName& path){ - if( ! path.exists() ) { - throw eckit::Exception("File "+std::string(path)+" does not exist."); - } - std::ifstream file(path.localPath()); - if (!file.is_open()) { - throw eckit::Exception("Unable to open json file "+std::string(path),Here()); - } - eckit::Value value = yaml_from_stream(file); - file.close(); - return value; +static eckit::Value yaml_from_path( const eckit::PathName& path ) { + if ( !path.exists() ) { throw eckit::Exception( "File " + std::string( path ) + " does not exist." ); } + std::ifstream file( path.localPath() ); + if ( !file.is_open() ) { throw eckit::Exception( "Unable to open json file " + std::string( path ), Here() ); } + eckit::Value value = yaml_from_stream( file ); + file.close(); + return value; } -} +} // namespace Config::Config() : eckit::LocalConfiguration() {} -Config::Config(const eckit::Configuration &p): eckit::LocalConfiguration(p) {} +Config::Config( const eckit::Configuration& p ) : eckit::LocalConfiguration( p ) {} -Config::Config(std::istream& stream, const std::string &format ) : - eckit::LocalConfiguration(yaml_from_stream(stream)) { -} +Config::Config( std::istream& stream, const std::string& format ) : + eckit::LocalConfiguration( yaml_from_stream( stream ) ) {} -Config::Config( const eckit::PathName& path ) : - eckit::LocalConfiguration(yaml_from_path(path)) { -} +Config::Config( const eckit::PathName& path ) : eckit::LocalConfiguration( yaml_from_path( path ) ) {} -Config Config::operator|(const Config& other) const -{ - Config config( *this ); - config.set(other); - return config; +Config Config::operator|( const Config& other ) const { + Config config( *this ); + config.set( other ); + return config; } -Config& Config::set(const eckit::LocalConfiguration& other) -{ - eckit::ValueMap otherval = other.get(); +Config& Config::set( const eckit::LocalConfiguration& other ) { + eckit::ValueMap otherval = other.get(); - for( eckit::ValueMap::const_iterator vit = otherval.begin(); vit != otherval.end(); ++vit ) - { - root_[vit->first]=vit->second; - } - return *this; + for ( eckit::ValueMap::const_iterator vit = otherval.begin(); vit != otherval.end(); ++vit ) { + root_[vit->first] = vit->second; + } + return *this; } -Config& Config::set(const std::string& name, const std::vector& values ) -{ - std::vector metadatavalues(values.size()); - for( size_t i=0; i& values ) { + std::vector metadatavalues( values.size() ); + for ( size_t i = 0; i < metadatavalues.size(); ++i ) + metadatavalues[i] = values[i]; + set( name, metadatavalues ); + return *this; } -bool Config::get(const std::string& name, std::vector& value) const { - bool found = has(name); - if( found ) { - std::vector properties = getSubConfigurations(name); - value.resize(properties.size()); - for( size_t i=0; i& value ) const { + bool found = has( name ); + if ( found ) { + std::vector properties = getSubConfigurations( name ); + value.resize( properties.size() ); + for ( size_t i = 0; i < value.size(); ++i ) { + value[i] = Config( properties[i] ); + } } - } - return found; + return found; } -void Config::hash(eckit::Hash& hsh) const -{ - eckit::ValueMap map = get(); - for( eckit::ValueMap::const_iterator vit = map.begin(); vit != map.end(); ++vit ) - { - hsh.add(vit->first.as()); - /// @note below, we assume all Values translate to std::string, this needs more verification - hsh.add(vit->second.as()); - } +void Config::hash( eckit::Hash& hsh ) const { + eckit::ValueMap map = get(); + for ( eckit::ValueMap::const_iterator vit = map.begin(); vit != map.end(); ++vit ) { + hsh.add( vit->first.as() ); + /// @note below, we assume all Values translate to std::string, this needs + /// more verification + hsh.add( vit->second.as() ); + } } //================================================================== @@ -115,236 +104,154 @@ void Config::hash(eckit::Hash& hsh) const // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -Config* atlas__Config__new () { - return new Config(); +Config* atlas__Config__new() { + return new Config(); } -Config* atlas__Config__new_from_json (const char* json) { - std::stringstream s; - s << json; - return new Config(s); +Config* atlas__Config__new_from_json( const char* json ) { + std::stringstream s; + s << json; + return new Config( s ); } - -Config* atlas__Config__new_from_file (const char* path) -{ - return new Config( eckit::PathName(path) ); +Config* atlas__Config__new_from_file( const char* path ) { + return new Config( eckit::PathName( path ) ); } -void atlas__Config__delete (Config* This) { - ASSERT( This != 0 ); - delete This; +void atlas__Config__delete( Config* This ) { + ASSERT( This != 0 ); + delete This; } -void atlas__Config__set_config (Config* This, const char* name, const Config* value) -{ - ATLAS_ERROR_HANDLING( This->set( std::string(name), *value ) ); +void atlas__Config__set_config( Config* This, const char* name, const Config* value ) { + ATLAS_ERROR_HANDLING( This->set( std::string( name ), *value ) ); } -void atlas__Config__set_config_list (Config* This, const char* name, const Config* value[], int size) -{ - std::vector params(size); - for(int i = 0; i < size; ++i) - { - params[i] = Config(*value[i]); - } - ATLAS_ERROR_HANDLING( This->set( std::string(name), params ) ); +void atlas__Config__set_config_list( Config* This, const char* name, const Config* value[], int size ) { + std::vector params( size ); + for ( int i = 0; i < size; ++i ) { + params[i] = Config( *value[i] ); + } + ATLAS_ERROR_HANDLING( This->set( std::string( name ), params ) ); } -void atlas__Config__set_int (Config* This, const char* name, int value) -{ - ATLAS_ERROR_HANDLING( This->set( std::string(name), long(value) ) ); +void atlas__Config__set_int( Config* This, const char* name, int value ) { + ATLAS_ERROR_HANDLING( This->set( std::string( name ), long( value ) ) ); } -void atlas__Config__set_long (Config* This, const char* name, long value) -{ - ATLAS_ERROR_HANDLING( This->set( std::string(name), value ) ); +void atlas__Config__set_long( Config* This, const char* name, long value ) { + ATLAS_ERROR_HANDLING( This->set( std::string( name ), value ) ); } -void atlas__Config__set_float (Config* This, const char* name, float value) -{ - ATLAS_ERROR_HANDLING( This->set( std::string(name), double(value) ) ); +void atlas__Config__set_float( Config* This, const char* name, float value ) { + ATLAS_ERROR_HANDLING( This->set( std::string( name ), double( value ) ) ); } -void atlas__Config__set_double (Config* This, const char* name, double value) -{ - ATLAS_ERROR_HANDLING( This->set( std::string(name), value ) ); +void atlas__Config__set_double( Config* This, const char* name, double value ) { + ATLAS_ERROR_HANDLING( This->set( std::string( name ), value ) ); } -void atlas__Config__set_string (Config* This, const char* name, const char* value) -{ - ATLAS_ERROR_HANDLING( This->set( std::string(name), std::string(value) ) ); +void atlas__Config__set_string( Config* This, const char* name, const char* value ) { + ATLAS_ERROR_HANDLING( This->set( std::string( name ), std::string( value ) ) ); } -void atlas__Config__set_array_int (Config* This, const char* name, int value[], int size) -{ - ATLAS_ERROR_HANDLING( - std::vector v; - v.assign(value,value+size); - This->set( std::string(name), v ); - ); +void atlas__Config__set_array_int( Config* This, const char* name, int value[], int size ) { + ATLAS_ERROR_HANDLING( std::vector v; v.assign( value, value + size ); This->set( std::string( name ), v ); ); } -void atlas__Config__set_array_long (Config* This, const char* name, long value[], int size) -{ - ATLAS_ERROR_HANDLING( - std::vector v; - v.assign(value,value+size); - This->set( std::string(name), v ); - ); +void atlas__Config__set_array_long( Config* This, const char* name, long value[], int size ) { + ATLAS_ERROR_HANDLING( std::vector v; v.assign( value, value + size ); This->set( std::string( name ), v ); ); } -void atlas__Config__set_array_float (Config* This, const char* name, float value[], int size) -{ - ATLAS_ERROR_HANDLING( - std::vector v; - v.assign(value,value+size); - This->set( std::string(name), v ); - ); +void atlas__Config__set_array_float( Config* This, const char* name, float value[], int size ) { + ATLAS_ERROR_HANDLING( std::vector v; v.assign( value, value + size ); This->set( std::string( name ), v ); ); } -void atlas__Config__set_array_double (Config* This, const char* name, double value[], int size) -{ - ATLAS_ERROR_HANDLING( - std::vector v; - v.assign(value,value+size); - This->set( std::string(name), v ); - ); +void atlas__Config__set_array_double( Config* This, const char* name, double value[], int size ) { + ATLAS_ERROR_HANDLING( std::vector v; v.assign( value, value + size ); + This->set( std::string( name ), v ); ); } -int atlas__Config__get_config (Config* This, const char* name, Config* value) -{ - ATLAS_ERROR_HANDLING ( if( ! This->get(std::string(name),*value) ) return false; ); - return true; +int atlas__Config__get_config( Config* This, const char* name, Config* value ) { + ATLAS_ERROR_HANDLING( if ( !This->get( std::string( name ), *value ) ) return false; ); + return true; } -int atlas__Config__get_config_list (Config* This, const char* name, Config** &value, int &size, int &allocated) -{ - value = 0; - ATLAS_ERROR_HANDLING ( - std::vector vector; - if( ! This->get(std::string(name),vector) ) return false; - size = vector.size(); - value = new Config*[size]; - allocated = true; - for(int i = 0; i < size; ++i) { - value[i] = new Config(vector[i]); - } - ); - return true; -} - -int atlas__Config__get_int (Config* This, const char* name, int& value) -{ - long long_value = value; - ATLAS_ERROR_HANDLING ( if( ! This->get(std::string(name),long_value) ) return false; ); - ASSERT( int(long_value) == long_value ); - value = long_value; - return true; -} -int atlas__Config__get_long (Config* This, const char* name, long& value) -{ - ATLAS_ERROR_HANDLING ( if( ! This->get(std::string(name),value) ) return false; ); - return true; - -} -int atlas__Config__get_float (Config* This, const char* name, float& value) -{ - double double_value; - ATLAS_ERROR_HANDLING ( if ( ! This->get(std::string(name), double_value) ) return false ; ); - value = double_value; - return true; -} -int atlas__Config__get_double (Config* This, const char* name, double& value) -{ - ATLAS_ERROR_HANDLING ( 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 ) -{ - ATLAS_ERROR_HANDLING( - std::string s; - if( ! This->get(std::string(name),s) ) - { - value = NULL; - return false; - } - size = s.size()+1; - value = new char[size]; - strcpy(value,s.c_str()); - allocated = true; - ); - return true; -} -int atlas__Config__get_array_int (Config* This, const char* name, int* &value, int& size, int& allocated) -{ - ATLAS_ERROR_HANDLING( - std::vector 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 ) { - ASSERT(int(v[j]) == v[j]); - value[j] = v[j]; - } - allocated = true; - ); - return true; -} -int atlas__Config__get_array_long (Config* This, const char* name, long* &value, int& size, int& allocated) -{ - ATLAS_ERROR_HANDLING( - std::vector v; - if( ! This->get(std::string(name),v) ) - return false; - size = v.size(); - value = new long[size]; - for( size_t j=0; j 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 ) { - value[j] = v[j]; - } - allocated = true; - ); +int atlas__Config__get_config_list( Config* This, const char* name, Config**& value, int& size, int& allocated ) { + value = 0; + ATLAS_ERROR_HANDLING( std::vector vector; if ( !This->get( std::string( name ), vector ) ) return false; + size = vector.size(); value = new Config*[size]; allocated = true; + for ( int i = 0; i < size; ++i ) { value[i] = new Config( vector[i] ); } ); return true; } -int atlas__Config__get_array_double (Config* This, const char* name, double* &value, int& size, int& allocated) -{ - ATLAS_ERROR_HANDLING( - std::vector v; - if( ! This->get(std::string(name),v) ) - return false; - size = v.size(); - value = new double[size]; - for( size_t j=0; jget( std::string( name ), long_value ) ) return false; ); + ASSERT( int( long_value ) == long_value ); + value = long_value; + return true; +} +int atlas__Config__get_long( Config* This, const char* name, long& value ) { + ATLAS_ERROR_HANDLING( if ( !This->get( std::string( name ), value ) ) return false; ); + return true; +} +int atlas__Config__get_float( Config* This, const char* name, float& value ) { + double double_value; + ATLAS_ERROR_HANDLING( if ( !This->get( std::string( name ), double_value ) ) return false; ); + value = double_value; + return true; +} +int atlas__Config__get_double( Config* This, const char* name, double& value ) { + ATLAS_ERROR_HANDLING( 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 ) { + ATLAS_ERROR_HANDLING( std::string s; if ( !This->get( std::string( name ), s ) ) { + value = NULL; + return false; + } size = s.size() + 1; + value = new char[size]; strcpy( value, s.c_str() ); allocated = true; ); + return true; +} +int atlas__Config__get_array_int( Config* This, const char* name, int*& value, int& size, int& allocated ) { + ATLAS_ERROR_HANDLING( std::vector 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 ) { + ASSERT( int( v[j] ) == v[j] ); + value[j] = v[j]; + } allocated = true; ); + return true; +} +int atlas__Config__get_array_long( Config* This, const char* name, long*& value, int& size, int& allocated ) { + ATLAS_ERROR_HANDLING( std::vector 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 ) 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_ERROR_HANDLING( std::vector 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 ) { value[j] = v[j]; } allocated = true; ); + return true; +} +int atlas__Config__get_array_double( Config* This, const char* name, double*& value, int& size, int& allocated ) { + ATLAS_ERROR_HANDLING( std::vector 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 ) value[j] = v[j]; allocated = true; ); + return true; } -int atlas__Config__has (Config *This, const char *name) { - ATLAS_ERROR_HANDLING( return This->has( std::string(name) )); +int atlas__Config__has( Config* This, const char* name ) { + ATLAS_ERROR_HANDLING( return This->has( std::string( name ) ) ); return 0; } -void atlas__Config__json(Config* This, char* &json, int &size, int &allocated) -{ - std::stringstream s; - eckit::JSON j(s); - j.precision(16); - j << *This; - std::string json_str = s.str(); - size = json_str.size(); - json = new char[size+1]; allocated = true; - strcpy(json,json_str.c_str()); - allocated = true; +void atlas__Config__json( Config* This, char*& json, int& size, int& allocated ) { + std::stringstream s; + eckit::JSON j( s ); + j.precision( 16 ); + j << *This; + std::string json_str = s.str(); + size = json_str.size(); + json = new char[size + 1]; + allocated = true; + strcpy( json, json_str.c_str() ); + allocated = true; } // ------------------------------------------------------------------ -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Config.h b/src/atlas/util/Config.h index c391583e0..0cb3466d6 100644 --- a/src/atlas/util/Config.h +++ b/src/atlas/util/Config.h @@ -4,21 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #ifndef atlas_Config_h #define atlas_Config_h -#include #include -#include "eckit/config/Parametrisation.h" +#include #include "atlas/util/Metadata.h" +#include "eckit/config/Parametrisation.h" #include "eckit/utils/Hash.h" namespace eckit { - class PathName; +class PathName; } namespace atlas { @@ -26,142 +27,130 @@ namespace util { /// @brief Configuration class used to construct various /// atlas components -class Config: public eckit::LocalConfiguration { - +class Config : public eckit::LocalConfiguration { public: + // -- Constructors -// -- Constructors - - Config(); - - /// @brief Constructor starting from a path - Config( const eckit::PathName& ); - - /// @brief Constructor starting from a stream - Config( std::istream&, const std::string &format = "json" ); + Config(); - /// @brief Constructor starting from a Configuration - Config( const eckit::Configuration& ); + /// @brief Constructor starting from a path + Config( const eckit::PathName& ); - /// @brief Constructor immediately setting a value. - template - Config( const std::string& name, const ValueT& value ); + /// @brief Constructor starting from a stream + Config( std::istream&, const std::string& format = "json" ); -// -- Mutators + /// @brief Constructor starting from a Configuration + Config( const eckit::Configuration& ); - /// @brief Operator that sets a key-value pair. - template - Config operator()(const std::string& name, const ValueT& value); + /// @brief Constructor immediately setting a value. + template + Config( const std::string& name, const ValueT& value ); - Config operator()(const std::string& name, const std::initializer_list& value); + // -- Mutators - // Overload operators to merge two Config objects. - Config operator|(const Config& other) const; + /// @brief Operator that sets a key-value pair. + template + Config operator()( const std::string& name, const ValueT& value ); - /// @brief Set a key-value parameter - using eckit::LocalConfiguration::set; + Config operator()( const std::string& name, const std::initializer_list& value ); - Config& set(const std::string& name, const std::vector& ); + // Overload operators to merge two Config objects. + Config operator|( const Config& other ) const; - Config& set(const eckit::LocalConfiguration&); + /// @brief Set a key-value parameter + using eckit::LocalConfiguration::set; -// -- Accessors, overloaded from eckit::Parametrisation + Config& set( const std::string& name, const std::vector& ); - using eckit::LocalConfiguration::get; - bool get(const std::string& name, std::vector& value) const; + Config& set( const eckit::LocalConfiguration& ); + // -- Accessors, overloaded from eckit::Parametrisation - void hash(eckit::Hash&) const; + using eckit::LocalConfiguration::get; + bool get( const std::string& name, std::vector& value ) const; + void hash( eckit::Hash& ) const; }; // ------------------------------------------------------------------ -template -inline Config::Config(const std::string& name, const ValueT& value) : - eckit::LocalConfiguration() { - set(name,value); +template +inline Config::Config( const std::string& name, const ValueT& value ) : eckit::LocalConfiguration() { + set( name, value ); } -template -inline Config Config::operator()(const std::string& name, const ValueT& value) -{ - set(name,value); - return *this; +template +inline Config Config::operator()( const std::string& name, const ValueT& value ) { + set( name, value ); + return *this; } -inline Config Config::operator()(const std::string& name, const std::initializer_list& value) -{ - set(name, std::vector(value.begin(),value.end())); - return *this; +inline Config Config::operator()( const std::string& name, const std::initializer_list& value ) { + set( name, std::vector( value.begin(), value.end() ) ); + return *this; } - // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines - -extern "C" -{ - Config* atlas__Config__new (); - Config* atlas__Config__new_from_json (const char* json); - Config* atlas__Config__new_from_file (const char* path); - void atlas__Config__delete (Config* This); - int atlas__Config__has (Config* This, const char* name); - void atlas__Config__set_config (Config* This, const char* name, const Config* value); - void atlas__Config__set_config_list (Config* This, const char* name, const Config* value[], int size); - void atlas__Config__set_int (Config* This, const char* name, int value); - void atlas__Config__set_long (Config* This, const char* name, long value); - void atlas__Config__set_float (Config* This, const char* name, float value); - void atlas__Config__set_double (Config* This, const char* name, double value); - void atlas__Config__set_string (Config* This, const char* name, const char* value); - void atlas__Config__set_array_int (Config* This, const char* name, int value[], int size); - void atlas__Config__set_array_long (Config* This, const char* name, long value[], int size); - void atlas__Config__set_array_float (Config* This, const char* name, float value[], int size); - void atlas__Config__set_array_double (Config* This, const char* name, double value[], int size); - - int atlas__Config__get_config (Config* This, const char* name, Config* value); - int atlas__Config__get_config_list (Config* This, const char* name, Config** &value, int &size, int &allocated); - int atlas__Config__get_int (Config* This, const char* name, int &value); - int atlas__Config__get_long (Config* This, const char* name, long &value); - int atlas__Config__get_float (Config* This, const char* name, float &value); - int atlas__Config__get_double (Config* This, const char* name, double &value); - int atlas__Config__get_string (Config* This, const char* name, char* &value, int &size, int &allocated); - int atlas__Config__get_array_int (Config* This, const char* name, int* &value, int &size, int &allocated); - int atlas__Config__get_array_long (Config* This, const char* name, long* &value, int &size, int &allocated); - int atlas__Config__get_array_float (Config* This, const char* name, float* &value, int &size, int &allocated); - int atlas__Config__get_array_double (Config* This, const char* name, double* &value, int &size, int &allocated); - void atlas__Config__json (Config* This, char* &json, int &size, int &allocated); +// clang-format off +extern "C" { +Config* atlas__Config__new(); +Config* atlas__Config__new_from_json( const char* json ); +Config* atlas__Config__new_from_file( const char* path ); +void atlas__Config__delete( Config* This ); +int atlas__Config__has( Config* This, const char* name ); +void atlas__Config__set_config( Config* This, const char* name, const Config* value ); +void atlas__Config__set_config_list( Config* This, const char* name, const Config* value[], int size ); +void atlas__Config__set_int( Config* This, const char* name, int value ); +void atlas__Config__set_long( Config* This, const char* name, long value ); +void atlas__Config__set_float( Config* This, const char* name, float value ); +void atlas__Config__set_double( Config* This, const char* name, double value ); +void atlas__Config__set_string( Config* This, const char* name, const char* value ); +void atlas__Config__set_array_int( Config* This, const char* name, int value[], int size ); +void atlas__Config__set_array_long( Config* This, const char* name, long value[], int size ); +void atlas__Config__set_array_float( Config* This, const char* name, float value[], int size ); +void atlas__Config__set_array_double( Config* This, const char* name, double value[], int size ); + +int atlas__Config__get_config( Config* This, const char* name, Config* value ); +int atlas__Config__get_config_list( Config* This, const char* name, Config** &value, int& size, int& allocated ); +int atlas__Config__get_int( Config* This, const char* name, int& value ); +int atlas__Config__get_long( Config* This, const char* name, long& value ); +int atlas__Config__get_float( Config* This, const char* name, float& value ); +int atlas__Config__get_double( Config* This, const char* name, double& value ); +int atlas__Config__get_string( Config* This, const char* name, char*& value, int& size, int& allocated ); +int atlas__Config__get_array_int( Config* This, const char* name, int*& value, int& size, int& allocated ); +int atlas__Config__get_array_long( Config* This, const char* name, long*& value, int& size, int& allocated ); +int atlas__Config__get_array_float( Config* This, const char* name, float*& value, int& size, int& allocated ); +int atlas__Config__get_array_double( Config* This, const char* name, double*& value, int& size, int& allocated ); +void atlas__Config__json( Config* This, char*& json, int& size, int& allocated ); } - +// clang-format on // ------------------------------------------------------------------ -class NoConfig: public Config { - -public: // methods - +class NoConfig : public Config { +public: // methods /// Destructor redundant but fixes sanity compiler warnings virtual ~NoConfig() {} - virtual bool has(const std::string& name) const { return false; } - - virtual bool get(const std::string& name, std::string& value) const { return false; } - virtual bool get(const std::string& name, bool& value) const { return false; } - virtual bool get(const std::string& name, int& value) const { return false; } - virtual bool get(const std::string& name, long& value) const { return false; } - virtual bool get(const std::string& name, size_t& value) const { return false; } - virtual bool get(const std::string& name, float& value) const { return false; } - virtual bool get(const std::string& name, double& value) const { return false; } - - virtual bool get(const std::string& name, std::vector& value) const { return false; } - virtual bool get(const std::string& name, std::vector& value) const { return false; } - virtual bool get(const std::string& name, std::vector& value) const { return false; } - virtual bool get(const std::string& name, std::vector& value) const { return false; } - virtual bool get(const std::string& name, std::vector& value) const { return false; } - virtual bool get(const std::string& name, std::vector& value) const { return false; } - + virtual bool has( const std::string& name ) const { return false; } + + virtual bool get( const std::string& name, std::string& value ) const { return false; } + virtual bool get( const std::string& name, bool& value ) const { return false; } + virtual bool get( const std::string& name, int& value ) const { return false; } + virtual bool get( const std::string& name, long& value ) const { return false; } + virtual bool get( const std::string& name, size_t& value ) const { return false; } + virtual bool get( const std::string& name, float& value ) const { return false; } + virtual bool get( const std::string& name, double& value ) const { return false; } + + virtual bool get( const std::string& name, std::vector& value ) const { return false; } + virtual bool get( const std::string& name, std::vector& value ) const { return false; } + virtual bool get( const std::string& name, std::vector& value ) const { return false; } + virtual bool get( const std::string& name, std::vector& value ) const { return false; } + virtual bool get( const std::string& name, std::vector& value ) const { return false; } + virtual bool get( const std::string& name, std::vector& value ) const { return false; } }; -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas -#endif // Parametrisation_h +#endif // Parametrisation_h diff --git a/src/atlas/util/Constants.h b/src/atlas/util/Constants.h index 890c48087..92ed3fe03 100644 --- a/src/atlas/util/Constants.h +++ b/src/atlas/util/Constants.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -20,13 +21,12 @@ namespace util { //------------------------------------------------------------------------------------------------------ /// Some useful constants -struct Constants -{ +struct Constants { static constexpr double radiansToDegrees() { return 180. * M_1_PI; } static constexpr double degreesToRadians() { return M_PI / 180.; } }; //------------------------------------------------------------------------------------------------------ -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/CoordinateEnums.h b/src/atlas/util/CoordinateEnums.h index f710ac130..9cff0d23e 100644 --- a/src/atlas/util/CoordinateEnums.h +++ b/src/atlas/util/CoordinateEnums.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -16,12 +17,21 @@ namespace atlas { //------------------------------------------------------------------------------------------------------ -enum XYZ { XX = 0, YY = 1, ZZ = 2 }; +enum XYZ +{ + XX = 0, + YY = 1, + ZZ = 2 +}; // ---------------------------------------------------------------------------------------------------- -enum LONLAT { LON = 0, LAT = 1 }; +enum LONLAT +{ + LON = 0, + LAT = 1 +}; // ---------------------------------------------------------------------------------------------------- -} // namespace atlas +} // namespace atlas diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index bcbd18925..998241f93 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -4,151 +4,141 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "atlas/util/Earth.h" #include #include -#include "eckit/types/FloatCompare.h" -#include "eckit/exception/Exceptions.h" #include "atlas/util/Constants.h" #include "atlas/util/Point.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/types/FloatCompare.h" namespace atlas { namespace util { //---------------------------------------------------------------------------------------------------------------------- -static inline double between_m180_and_p180(double a) { - while (a > 180) { +static inline double between_m180_and_p180( double a ) { + while ( a > 180 ) { a -= 360; } - while (a < -180 ) { + while ( a < -180 ) { a += 360; } return a; } - //---------------------------------------------------------------------------------------------------------------------- -double Sphere::centralAngle(const PointLonLat& p1, const PointLonLat& p2) { +double Sphere::centralAngle( const PointLonLat& p1, const PointLonLat& p2 ) { using namespace std; /* - * Δσ = atan( ((cos(Ï•2) * sin(Δλ))^2 + (cos(Ï•1) * sin(Ï•2) - sin(Ï•1) * cos(Ï•2) * cos(Δλ))^2) / - * (sin(Ï•1) * sin(Ï•2) + cos(Ï•1) * cos(Ï•2) * cos(Δλ)) ) - * - * @article{doi:10.1179/sre.1975.23.176.88, - * author = {T. Vincenty}, - * title = {Direct and Inverse Solutions of Geodesics on the Ellipsoid With Application of Nested Equations}, - * journal = {Survey Review}, - * volume = {23}, - * number = {176}, - * pages = {88-93}, - * year = {1975}, - * doi = {10.1179/sre.1975.23.176.88} - * } - */ - - if (!(-90. <= p1.lat() && p1.lat() <= 90.)) { + * Δσ = atan( ((cos(Ï•2) * sin(Δλ))^2 + (cos(Ï•1) * sin(Ï•2) - sin(Ï•1) * cos(Ï•2) + * * cos(Δλ))^2) / + * (sin(Ï•1) * sin(Ï•2) + cos(Ï•1) * cos(Ï•2) * cos(Δλ)) ) + * + * @article{doi:10.1179/sre.1975.23.176.88, + * author = {T. Vincenty}, + * title = {Direct and Inverse Solutions of Geodesics on the Ellipsoid With + * Application of Nested Equations}, + * journal = {Survey Review}, + * volume = {23}, + * number = {176}, + * pages = {88-93}, + * year = {1975}, + * doi = {10.1179/sre.1975.23.176.88} + * } + */ + + if ( !( -90. <= p1.lat() && p1.lat() <= 90. ) ) { std::ostringstream oss; - oss.precision(std::numeric_limits::max_digits10); + oss.precision( std::numeric_limits::max_digits10 ); oss << "Invalid latitude " << p1.lat(); - throw eckit::BadValue(oss.str(), Here()); + throw eckit::BadValue( oss.str(), Here() ); } - if (!(-90. <= p2.lat() && p2.lat() <= 90.)) { + if ( !( -90. <= p2.lat() && p2.lat() <= 90. ) ) { std::ostringstream oss; - oss.precision(std::numeric_limits::max_digits10); + oss.precision( std::numeric_limits::max_digits10 ); oss << "Invalid latitude " << p2.lat(); - throw eckit::BadValue(oss.str(), Here()); + throw eckit::BadValue( oss.str(), Here() ); } const double phi1 = Constants::degreesToRadians() * p1.lat(); const double phi2 = Constants::degreesToRadians() * p2.lat(); - const double lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()); + const double lambda = Constants::degreesToRadians() * ( p2.lon() - p1.lon() ); - const double cos_phi1 = cos(phi1); - const double sin_phi1 = sin(phi1); - const double cos_phi2 = cos(phi2); - const double sin_phi2 = sin(phi2); - const double cos_lambda = cos(lambda); - const double sin_lambda = sin(lambda); + const double cos_phi1 = cos( phi1 ); + const double sin_phi1 = sin( phi1 ); + const double cos_phi2 = cos( phi2 ); + const double sin_phi2 = sin( phi2 ); + const double cos_lambda = cos( lambda ); + const double sin_lambda = sin( lambda ); const double angle = atan2( - sqrt(pow(cos_phi2 * sin_lambda, 2) + - pow(cos_phi1 * sin_phi2 - sin_phi1 * cos_phi2 * cos_lambda, 2)), - sin_phi1 * sin_phi2 + cos_phi1 * cos_phi2 * cos_lambda ); + sqrt( pow( cos_phi2 * sin_lambda, 2 ) + pow( cos_phi1 * sin_phi2 - sin_phi1 * cos_phi2 * cos_lambda, 2 ) ), + sin_phi1 * sin_phi2 + cos_phi1 * cos_phi2 * cos_lambda ); - if (eckit::types::is_approximately_equal(angle, 0.)) { - return 0.; - } + if ( eckit::types::is_approximately_equal( angle, 0. ) ) { return 0.; } - ASSERT(angle > 0.); + ASSERT( angle > 0. ); return angle; } - -double Sphere::centralAngle(const PointXYZ& p1, const PointXYZ& p2, const double& radius) { - ASSERT(radius > 0.); +double Sphere::centralAngle( const PointXYZ& p1, const PointXYZ& p2, const double& radius ) { + ASSERT( radius > 0. ); // Δσ = 2 * asin( chord / 2 ) - const double d2 = PointXYZ::distance2(p1, p2); - if (eckit::types::is_approximately_equal(d2, 0.)) { - return 0.; - } + const double d2 = PointXYZ::distance2( p1, p2 ); + if ( eckit::types::is_approximately_equal( d2, 0. ) ) { return 0.; } - const double chord = std::sqrt(d2) / radius; - const double angle = std::asin(chord * 0.5) * 2.; + const double chord = std::sqrt( d2 ) / radius; + const double angle = std::asin( chord * 0.5 ) * 2.; return angle; } - -double Sphere::distanceInMeters(const PointLonLat& p1, const PointLonLat& p2, const double& radius) { - return radius * centralAngle(p1, p2); +double Sphere::distanceInMeters( const PointLonLat& p1, const PointLonLat& p2, const double& radius ) { + return radius * centralAngle( p1, p2 ); } - -double Sphere::distanceInMeters(const PointXYZ& p1, const PointXYZ& p2, const double& radius) { - return radius * centralAngle(p1, p2, radius); +double Sphere::distanceInMeters( const PointXYZ& p1, const PointXYZ& p2, const double& radius ) { + return radius * centralAngle( p1, p2, radius ); } - -void Sphere::greatCircleLatitudeGivenLongitude(const PointLonLat& p1, const PointLonLat& p2, PointLonLat& p) { +void Sphere::greatCircleLatitudeGivenLongitude( const PointLonLat& p1, const PointLonLat& p2, PointLonLat& p ) { using namespace std; // Intermediate great circle points (not applicable for meridians), see // http://www.edwilliams.org/avform.htm#Int - ASSERT(!eckit::types::is_approximately_equal(p1.lon(), p2.lon())); + ASSERT( !eckit::types::is_approximately_equal( p1.lon(), p2.lon() ) ); const double phi1 = Constants::degreesToRadians() * p1.lat(); const double phi2 = Constants::degreesToRadians() * p2.lat(); - const double lambda1p = Constants::degreesToRadians() * (p.lon() - p1.lon()); - const double lambda2p = Constants::degreesToRadians() * (p.lon() - p2.lon()); - const double lambda = Constants::degreesToRadians() * (p2.lon() - p1.lon()); + const double lambda1p = Constants::degreesToRadians() * ( p.lon() - p1.lon() ); + const double lambda2p = Constants::degreesToRadians() * ( p.lon() - p2.lon() ); + const double lambda = Constants::degreesToRadians() * ( p2.lon() - p1.lon() ); - p.lat() = Constants::radiansToDegrees() * atan( - (tan(phi2) * sin(lambda1p) - tan(phi1) * sin(lambda2p)) / - (sin(lambda)) ); + p.lat() = Constants::radiansToDegrees() * + atan( ( tan( phi2 ) * sin( lambda1p ) - tan( phi1 ) * sin( lambda2p ) ) / ( sin( lambda ) ) ); } +PointXYZ Sphere::convertSphericalToCartesian( const PointLonLat& p, const double& radius, const double& height ) { + ASSERT( radius > 0. ); -PointXYZ Sphere::convertSphericalToCartesian(const PointLonLat& p, const double& radius, const double& height) { - ASSERT(radius > 0.); - - if (!(-90. <= p.lat() && p.lat() <= 90.)) { + if ( !( -90. <= p.lat() && p.lat() <= 90. ) ) { std::ostringstream oss; - oss.precision(std::numeric_limits::max_digits10); + oss.precision( std::numeric_limits::max_digits10 ); oss << "Invalid latitude " << p.lat(); - throw eckit::BadValue(oss.str(), Here()); + throw eckit::BadValue( oss.str(), Here() ); } // See https://en.wikipedia.org/wiki/Reference_ellipsoid#Coordinates @@ -156,87 +146,72 @@ PointXYZ Sphere::convertSphericalToCartesian(const PointLonLat& p, const double& const double& a = radius; const double& b = radius; - const double lambda_deg = between_m180_and_p180(p.lon()); - const double lambda = Constants::degreesToRadians() * lambda_deg; - const double phi = Constants::degreesToRadians() * p.lat(); + const double lambda_deg = between_m180_and_p180( p.lon() ); + const double lambda = Constants::degreesToRadians() * lambda_deg; + const double phi = Constants::degreesToRadians() * p.lat(); - const double sin_phi = std::sin(phi); - const double cos_phi = std::sqrt(1. - sin_phi * sin_phi); - const double sin_lambda = std::abs(lambda_deg) < 180. ? std::sin(lambda) : 0.; - const double cos_lambda = std::abs(lambda_deg) > 90. ? std::cos(lambda) : std::sqrt(1. - sin_lambda * sin_lambda); + const double sin_phi = std::sin( phi ); + const double cos_phi = std::sqrt( 1. - sin_phi * sin_phi ); + const double sin_lambda = std::abs( lambda_deg ) < 180. ? std::sin( lambda ) : 0.; + const double cos_lambda = + std::abs( lambda_deg ) > 90. ? std::cos( lambda ) : std::sqrt( 1. - sin_lambda * sin_lambda ); - if (eckit::types::is_approximately_equal(a,b)) { // no eccentricity case + if ( eckit::types::is_approximately_equal( a, b ) ) { // no eccentricity case - return PointXYZ( - (a + height) * cos_phi * cos_lambda, - (a + height) * cos_phi * sin_lambda, - (a + height) * sin_phi ); + return PointXYZ( ( a + height ) * cos_phi * cos_lambda, ( a + height ) * cos_phi * sin_lambda, + ( a + height ) * sin_phi ); } - const double N_phi = a * a / std::sqrt(a * a * cos_phi * cos_phi + b * b * sin_phi * sin_phi); + const double N_phi = a * a / std::sqrt( a * a * cos_phi * cos_phi + b * b * sin_phi * sin_phi ); - return PointXYZ( - (N_phi + height) * cos_phi * cos_lambda, - (N_phi + height) * cos_phi * sin_lambda, - (N_phi * (b * b) / (a * a) + height) * sin_phi ); + return PointXYZ( ( N_phi + height ) * cos_phi * cos_lambda, ( N_phi + height ) * cos_phi * sin_lambda, + ( N_phi * ( b * b ) / ( a * a ) + height ) * sin_phi ); } - -PointLonLat Sphere::convertCartesianToSpherical(const PointXYZ& p, const double& radius) { - ASSERT(radius > 0.); +PointLonLat Sphere::convertCartesianToSpherical( const PointXYZ& p, const double& radius ) { + ASSERT( radius > 0. ); // numerical conditioning for both z (poles) and y const double x = p.x(); - const double y = eckit::types::is_approximately_equal(p.y(), 0.) ? 0. : p.y(); - const double z = std::min(radius, std::max(-radius, p.z())) / radius; + const double y = eckit::types::is_approximately_equal( p.y(), 0. ) ? 0. : p.y(); + const double z = std::min( radius, std::max( -radius, p.z() ) ) / radius; - return PointLonLat( - Constants::radiansToDegrees() * std::atan2(y, x), - Constants::radiansToDegrees() * std::asin(z) ); + return PointLonLat( Constants::radiansToDegrees() * std::atan2( y, x ), + Constants::radiansToDegrees() * std::asin( z ) ); } - //---------------------------------------------------------------------------------------------------------------------- - -double Earth::centralAngle(const PointLonLat& p1, const PointLonLat& p2) { - return Sphere::centralAngle(p1, p2); +double Earth::centralAngle( const PointLonLat& p1, const PointLonLat& p2 ) { + return Sphere::centralAngle( p1, p2 ); } - -double Earth::centralAngle(const PointXYZ& p1, const PointXYZ& p2, const double& radius) { - return Sphere::centralAngle(p1, p2, radius); +double Earth::centralAngle( const PointXYZ& p1, const PointXYZ& p2, const double& radius ) { + return Sphere::centralAngle( p1, p2, radius ); } - -double Earth::distanceInMeters(const PointLonLat& p1, const PointLonLat& p2, const double& radius) { - return Sphere::distanceInMeters(p1, p2, radius); +double Earth::distanceInMeters( const PointLonLat& p1, const PointLonLat& p2, const double& radius ) { + return Sphere::distanceInMeters( p1, p2, radius ); } - -double Earth::distanceInMeters(const PointXYZ& p1, const PointXYZ& p2, const double& radius) { - return Sphere::distanceInMeters(p1, p2, radius); +double Earth::distanceInMeters( const PointXYZ& p1, const PointXYZ& p2, const double& radius ) { + return Sphere::distanceInMeters( p1, p2, radius ); } - -void Earth::greatCircleLatitudeGivenLongitude(const PointLonLat& p1, const PointLonLat& p2, PointLonLat& p) { - Sphere::greatCircleLatitudeGivenLongitude(p1, p2, p); +void Earth::greatCircleLatitudeGivenLongitude( const PointLonLat& p1, const PointLonLat& p2, PointLonLat& p ) { + Sphere::greatCircleLatitudeGivenLongitude( p1, p2, p ); } - -PointXYZ Earth::convertGeodeticToGeocentric(const PointLonLat& p, const double& radius, const double& height) { - return Sphere::convertSphericalToCartesian(p, radius, height); +PointXYZ Earth::convertGeodeticToGeocentric( const PointLonLat& p, const double& radius, const double& height ) { + return Sphere::convertSphericalToCartesian( p, radius, height ); } - -PointLonLat Earth::convertGeocentricToGeodetic(const PointXYZ& p, const double& radius) { - return Sphere::convertCartesianToSpherical(p, radius); +PointLonLat Earth::convertGeocentricToGeodetic( const PointXYZ& p, const double& radius ) { + return Sphere::convertCartesianToSpherical( p, radius ); } - //---------------------------------------------------------------------------------------------------------------------- - } // namespace util } // namespace atlas diff --git a/src/atlas/util/Earth.h b/src/atlas/util/Earth.h index 647fc866b..f934395dc 100644 --- a/src/atlas/util/Earth.h +++ b/src/atlas/util/Earth.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,7 +16,7 @@ namespace atlas { class PointLonLat; class PointXYZ; -} +} // namespace atlas //------------------------------------------------------------------------------------------------------ @@ -24,60 +25,61 @@ namespace util { //------------------------------------------------------------------------------------------------------ -struct Sphere -{ +struct Sphere { // Great-circle central angle between two points, in radians - static double centralAngle(const PointLonLat&, const PointLonLat&); - static double centralAngle(const PointXYZ&, const PointXYZ&, const double& radius); + static double centralAngle( const PointLonLat&, const PointLonLat& ); + static double centralAngle( const PointXYZ&, const PointXYZ&, const double& radius ); // Great-circle distance between two points - static double distanceInMeters(const PointLonLat&, const PointLonLat&, const double& radius); - static double distanceInMeters(const PointXYZ&, const PointXYZ&, const double& radius); + static double distanceInMeters( const PointLonLat&, const PointLonLat&, const double& radius ); + static double distanceInMeters( const PointXYZ&, const PointXYZ&, const double& radius ); - // Great-circle intermediate position provided two circle points and longitude, in degrees - static void greatCircleLatitudeGivenLongitude(const PointLonLat&, const PointLonLat&, PointLonLat&); + // Great-circle intermediate position provided two circle points and + // longitude, in degrees + static void greatCircleLatitudeGivenLongitude( const PointLonLat&, const PointLonLat&, PointLonLat& ); // Convert spherical coordinates to Cartesian - static PointXYZ convertSphericalToCartesian(const PointLonLat&, const double& radius, const double& height); + static PointXYZ convertSphericalToCartesian( const PointLonLat&, const double& radius, const double& height ); // Convert Cartesian coordinates to spherical - static PointLonLat convertCartesianToSpherical(const PointXYZ&, const double& radius); - + static PointLonLat convertCartesianToSpherical( const PointXYZ&, const double& radius ); }; //------------------------------------------------------------------------------------------------------ -struct Earth -{ +struct Earth { // 6371229 -- IFS // 6367470 -- GRIB1 // 6378137 -- WGS84 semi-major axis static constexpr double radiusInMeters() { return 6371229.; } - static constexpr double radiusInKm() { return radiusInMeters() / 1e3; } + static constexpr double radiusInKm() { return radiusInMeters() / 1e3; } static constexpr double areaInSqMeters() { return 4. * M_PI * radiusInMeters() * radiusInMeters(); } - static constexpr double areaInSqKm() { return 4. * M_PI * radiusInKm() * radiusInKm(); } + static constexpr double areaInSqKm() { return 4. * M_PI * radiusInKm() * radiusInKm(); } // Great-circle central angle between two points, in radians - static double centralAngle(const PointLonLat&, const PointLonLat&); - static double centralAngle(const PointXYZ&, const PointXYZ&, const double& radius = radiusInMeters()); + static double centralAngle( const PointLonLat&, const PointLonLat& ); + static double centralAngle( const PointXYZ&, const PointXYZ&, const double& radius = radiusInMeters() ); // Great-circle distance between two points - static double distanceInMeters(const PointLonLat&, const PointLonLat&, const double& radius = radiusInMeters()); - static double distanceInMeters(const PointXYZ&, const PointXYZ&, const double& radius = radiusInMeters()); - - // Great-circle intermediate position provided two circle points and longitude, in degrees - static void greatCircleLatitudeGivenLongitude(const PointLonLat&, const PointLonLat&, PointLonLat&); + static double distanceInMeters( const PointLonLat&, const PointLonLat&, const double& radius = radiusInMeters() ); + static double distanceInMeters( const PointXYZ&, const PointXYZ&, const double& radius = radiusInMeters() ); - // Convert geodetic coordinates to geocentric Cartesian (ECEF: Earth-centered, Earth-fixed) - static PointXYZ convertGeodeticToGeocentric(const PointLonLat&, const double& radius = radiusInMeters(), const double& height = 0.); + // Great-circle intermediate position provided two circle points and + // longitude, in degrees + static void greatCircleLatitudeGivenLongitude( const PointLonLat&, const PointLonLat&, PointLonLat& ); - // Convert geocentric Cartesian (ECEF: Earth-centered, Earth-fixed) to geodetic coordinates - static PointLonLat convertGeocentricToGeodetic(const PointXYZ&, const double& radius = radiusInMeters()); + // Convert geodetic coordinates to geocentric Cartesian (ECEF: Earth-centered, + // Earth-fixed) + static PointXYZ convertGeodeticToGeocentric( const PointLonLat&, const double& radius = radiusInMeters(), + const double& height = 0. ); + // Convert geocentric Cartesian (ECEF: Earth-centered, Earth-fixed) to + // geodetic coordinates + static PointLonLat convertGeocentricToGeodetic( const PointXYZ&, const double& radius = radiusInMeters() ); }; //------------------------------------------------------------------------------------------------------ -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/GaussianLatitudes.cc b/src/atlas/util/GaussianLatitudes.cc index e61db6d16..a1ae367f0 100644 --- a/src/atlas/util/GaussianLatitudes.cc +++ b/src/atlas/util/GaussianLatitudes.cc @@ -4,36 +4,34 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @author Willem Deconinck /// @date Jan 2014 - #include "atlas/util/GaussianLatitudes.h" #include "atlas/grid/detail/spacing/gaussian/Latitudes.h" namespace atlas { namespace util { -void gaussian_latitudes_npole_equator(const size_t N, double latitudes[]) { - grid::spacing::gaussian::gaussian_latitudes_npole_equator(N,latitudes); +void gaussian_latitudes_npole_equator( const size_t N, double latitudes[] ) { + grid::spacing::gaussian::gaussian_latitudes_npole_equator( N, latitudes ); } -void gaussian_quadrature_npole_equator(const size_t N, double latitudes[], double weights[]) { - grid::spacing::gaussian::gaussian_quadrature_npole_equator(N,latitudes,weights); +void gaussian_quadrature_npole_equator( const size_t N, double latitudes[], double weights[] ) { + grid::spacing::gaussian::gaussian_quadrature_npole_equator( N, latitudes, weights ); } - -void gaussian_latitudes_npole_spole(const size_t N, double latitudes[]) { - grid::spacing::gaussian::gaussian_latitudes_npole_spole(N,latitudes); +void gaussian_latitudes_npole_spole( const size_t N, double latitudes[] ) { + grid::spacing::gaussian::gaussian_latitudes_npole_spole( N, latitudes ); } - -void gaussian_quadrature_npole_spole (const size_t N, double latitudes[], double weights[]) { - grid::spacing::gaussian::gaussian_quadrature_npole_spole(N,latitudes,weights); +void gaussian_quadrature_npole_spole( const size_t N, double latitudes[], double weights[] ) { + grid::spacing::gaussian::gaussian_quadrature_npole_spole( N, latitudes, weights ); } } // namespace util diff --git a/src/atlas/util/GaussianLatitudes.h b/src/atlas/util/GaussianLatitudes.h index 65da7e804..04c2ffd67 100644 --- a/src/atlas/util/GaussianLatitudes.h +++ b/src/atlas/util/GaussianLatitudes.h @@ -4,53 +4,55 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ /// @author Willem Deconinck /// @date Jan 2014 - #pragma once #include - namespace atlas { namespace util { /** * @brief Compute gaussian latitudes between North pole and equator - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @param N [in] Number of latitudes between pole and equator (Gaussian + * N number) * @param latitudes [out] latitudes in degrees */ -void gaussian_latitudes_npole_equator(const size_t N, double latitudes[]); - +void gaussian_latitudes_npole_equator( const size_t N, double latitudes[] ); /** - * @brief Compute gaussian latitudes and quadrature weights between North pole and equator - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @brief Compute gaussian latitudes and quadrature weights between North pole + * and equator + * @param N [in] Number of latitudes between pole and equator (Gaussian + * N number) * @param latitudes [out] latitudes in degrees * @param weights [out] quadrature weights */ -void gaussian_quadrature_npole_equator(const size_t N, double latitudes[], double weights[]); - +void gaussian_quadrature_npole_equator( const size_t N, double latitudes[], double weights[] ); /** * @brief Compute gaussian latitudes between North pole and South pole - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @param N [in] Number of latitudes between pole and equator (Gaussian + * N number) * @param latitudes [out] latitudes in degrees (size 2*N) */ -void gaussian_latitudes_npole_spole(const size_t N, double latitudes[]); - +void gaussian_latitudes_npole_spole( const size_t N, double latitudes[] ); /** - * @brief Compute gaussian latitudes and quadrature weights between North pole and South pole - * @param N [in] Number of latitudes between pole and equator (Gaussian N number) + * @brief Compute gaussian latitudes and quadrature weights between North pole + * and South pole + * @param N [in] Number of latitudes between pole and equator (Gaussian + * N number) * @param latitudes [out] latitudes in degrees (size 2*N) * @param weights [out] quadrature weights (size 2*N) */ -void gaussian_quadrature_npole_spole (const size_t N, double latitudes[], double weights[]); +void gaussian_quadrature_npole_spole( const size_t N, double latitudes[], double weights[] ); } // namespace util } // namespace atlas diff --git a/src/atlas/util/LonLatMicroDeg.h b/src/atlas/util/LonLatMicroDeg.h index a55fdc33a..8889791cf 100644 --- a/src/atlas/util/LonLatMicroDeg.h +++ b/src/atlas/util/LonLatMicroDeg.h @@ -4,17 +4,18 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once +#include "atlas/array/ArrayView.h" #include "atlas/library/config.h" -#include "atlas/util/Point.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/MicroDeg.h" -#include "atlas/array/ArrayView.h" +#include "atlas/util/Point.h" namespace atlas { namespace util { @@ -29,51 +30,65 @@ uidx_t unique_lonlat( const LonLatMicroDeg& ); /// @brief LonLatMicroDegrees /// -/// Data is stored and accessed in microdegrees in int type (32 bits per coordinate component) +/// Data is stored and accessed in microdegrees in int type (32 bits per +/// coordinate component) /// This structure is used to compare 2 lon-lat points in sorting algorithms /// or to use in sending in MPI buffers using minimal memory, /// The maximum range in degrees is [-2147.48 2147.48] -class LonLatMicroDeg -{ +class LonLatMicroDeg { public: - -// -- Constructors taking already microdegrees - LonLatMicroDeg( int lonlat[2] ) { p_[LON]=lonlat[LON]; p_[LAT]=lonlat[LAT]; } - LonLatMicroDeg( int lon, int lat ) { p_[LON]=lon; p_[LAT]=lat; } - -// -- Constructors taking degrees - LonLatMicroDeg( const double& lon, const double& lat ) { p_[LON]=microdeg(lon); p_[LAT]=microdeg(lat); } - LonLatMicroDeg( const double lonlat[2] ) { p_[LON]=microdeg(lonlat[LON]); p_[LAT]=microdeg(lonlat[LAT]); } - //LonLatMicroDeg( const array::ArrayView& lonlat ) { p_[LON]=microdeg(lonlat[LON]); p_[LAT]=microdeg(lonlat[LAT]); } - LonLatMicroDeg( const PointLonLat& p ) { p_[LON]=microdeg(p.lon()); p_[LAT]=microdeg(p.lat()); } - -// -- Methods - int lon() const { return p_[LON]; } - int lat() const { return p_[LAT]; } - void set_lon(int lon) { p_[LON]=lon; } - void set_lat(int lat) { p_[LAT]=lat; } - const int* data() const { return p_; } - uidx_t unique() { return unique_lonlat(*this); } - -// -- Comparison operator - bool operator < (const LonLatMicroDeg& other) const; + // -- Constructors taking already microdegrees + LonLatMicroDeg( int lonlat[2] ) { + p_[LON] = lonlat[LON]; + p_[LAT] = lonlat[LAT]; + } + LonLatMicroDeg( int lon, int lat ) { + p_[LON] = lon; + p_[LAT] = lat; + } + + // -- Constructors taking degrees + LonLatMicroDeg( const double& lon, const double& lat ) { + p_[LON] = microdeg( lon ); + p_[LAT] = microdeg( lat ); + } + LonLatMicroDeg( const double lonlat[2] ) { + p_[LON] = microdeg( lonlat[LON] ); + p_[LAT] = microdeg( lonlat[LAT] ); + } + // LonLatMicroDeg( const array::ArrayView& lonlat ) { + // p_[LON]=microdeg(lonlat[LON]); p_[LAT]=microdeg(lonlat[LAT]); } + LonLatMicroDeg( const PointLonLat& p ) { + p_[LON] = microdeg( p.lon() ); + p_[LAT] = microdeg( p.lat() ); + } + + // -- Methods + int lon() const { return p_[LON]; } + int lat() const { return p_[LAT]; } + void set_lon( int lon ) { p_[LON] = lon; } + void set_lat( int lat ) { p_[LAT] = lat; } + const int* data() const { return p_; } + uidx_t unique() { return unique_lonlat( *this ); } + + // -- Comparison operator + bool operator<( const LonLatMicroDeg& other ) const; private: - int p_[2]; + int p_[2]; }; // ------------------------------------------------------------------------------------ -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]); - return false; +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] ); + return false; } // ------------------------------------------------------------------------------------ -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas #include "atlas/util/Unique.h" diff --git a/src/atlas/util/LonLatPolygon.cc b/src/atlas/util/LonLatPolygon.cc index 36ba22f94..9c4a00479 100644 --- a/src/atlas/util/LonLatPolygon.cc +++ b/src/atlas/util/LonLatPolygon.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -19,44 +20,29 @@ namespace atlas { namespace util { - //------------------------------------------------------------------------------------------------------ - namespace { - -double cross_product_analog(const PointLonLat& A, const PointLonLat& B, const PointLonLat& C) { - return (A.lon() - C.lon()) * (B.lat() - C.lat()) - - (A.lat() - C.lat()) * (B.lon() - C.lon()); +double cross_product_analog( const PointLonLat& A, const PointLonLat& B, const PointLonLat& C ) { + return ( A.lon() - C.lon() ) * ( B.lat() - C.lat() ) - ( A.lat() - C.lat() ) * ( B.lon() - C.lon() ); } - -} // (anonymous) - +} // namespace //------------------------------------------------------------------------------------------------------ +LonLatPolygon::LonLatPolygon( const Polygon& poly, const atlas::Field& lonlat, bool removeAlignedPoints ) : + PolygonCoordinates( poly, lonlat, removeAlignedPoints ) {} -LonLatPolygon::LonLatPolygon( - const Polygon& poly, - const atlas::Field& lonlat, - bool removeAlignedPoints ) : - PolygonCoordinates(poly, lonlat, removeAlignedPoints) { -} - - -LonLatPolygon::LonLatPolygon(const std::vector& points ) : - PolygonCoordinates(points) { -} - +LonLatPolygon::LonLatPolygon( const std::vector& points ) : PolygonCoordinates( points ) {} -bool LonLatPolygon::contains(const PointLonLat& P) const { - ASSERT(coordinates_.size() >= 2); +bool LonLatPolygon::contains( const PointLonLat& P ) const { + ASSERT( coordinates_.size() >= 2 ); // check first bounding box - if (coordinatesMax_.lon() <= P.lon() || P.lon() < coordinatesMin_.lon() || - coordinatesMax_.lat() <= P.lat() || P.lat() < coordinatesMin_.lat() ) { + if ( coordinatesMax_.lon() <= P.lon() || P.lon() < coordinatesMin_.lon() || coordinatesMax_.lat() <= P.lat() || + P.lat() < coordinatesMin_.lat() ) { return false; } @@ -64,22 +50,22 @@ bool LonLatPolygon::contains(const PointLonLat& P) const { int wn = 0; // loop on polygon edges - for (size_t i = 1; i < coordinates_.size(); ++i) { - const PointLonLat& A = coordinates_[i-1]; - const PointLonLat& B = coordinates_[ i ]; + for ( size_t i = 1; i < coordinates_.size(); ++i ) { + const PointLonLat& A = coordinates_[i - 1]; + const PointLonLat& B = coordinates_[i]; // check point-edge side and direction, using 2D-analog cross-product; - // tests if P is left|on|right of a directed A-B infinite line, by intersecting either: + // tests if P is left|on|right of a directed A-B infinite line, by + // intersecting either: // - "up" on upward crossing & P left of edge, or // - "down" on downward crossing & P right of edge - const bool APB = (A.lat() <= P.lat() && P.lat() < B.lat()); - const bool BPA = (B.lat() <= P.lat() && P.lat() < A.lat()); - - if (APB != BPA) { - const double side = cross_product_analog(P, A, B); - if (APB && side > 0) { - ++wn; - } else if (BPA && side < 0) { + const bool APB = ( A.lat() <= P.lat() && P.lat() < B.lat() ); + const bool BPA = ( B.lat() <= P.lat() && P.lat() < A.lat() ); + + if ( APB != BPA ) { + const double side = cross_product_analog( P, A, B ); + if ( APB && side > 0 ) { ++wn; } + else if ( BPA && side < 0 ) { --wn; } } @@ -89,10 +75,7 @@ bool LonLatPolygon::contains(const PointLonLat& P) const { return wn != 0; } - //------------------------------------------------------------------------------------------------------ - -} // util -} // atlas - +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/LonLatPolygon.h b/src/atlas/util/LonLatPolygon.h index 0e82cf63e..265347eda 100644 --- a/src/atlas/util/LonLatPolygon.h +++ b/src/atlas/util/LonLatPolygon.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -20,27 +21,26 @@ namespace util { class LonLatPolygon : public PolygonCoordinates { public: - // -- Constructors - LonLatPolygon(const Polygon&, const atlas::Field& lonlat, bool removeAlignedPoints = true); + LonLatPolygon( const Polygon&, const atlas::Field& lonlat, bool removeAlignedPoints = true ); - LonLatPolygon(const std::vector& points); + LonLatPolygon( const std::vector& points ); // -- Overridden methods /* - * Point-in-polygon test based on winding number - * @note reference Inclusion of a Point in a Polygon - * @param[in] P given point - * @return if point is in polygon - */ - bool contains(const PointLonLat& P) const; - + * Point-in-polygon test based on winding number + * @note reference Inclusion of a Point + * in a Polygon + * @param[in] P given point + * @return if point is in polygon + */ + bool contains( const PointLonLat& P ) const; }; //------------------------------------------------------------------------------------------------------ -} // util -} // atlas - +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index b627c42be..a8b2daabb 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -4,18 +4,19 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include "atlas/util/Metadata.h" #include -#include #include +#include -#include "eckit/exception/Exceptions.h" #include "atlas/parallel/mpi/mpi.h" +#include "eckit/exception/Exceptions.h" #include "eckit/parser/JSON.h" #include "eckit/parser/JSONParser.h" #include "eckit/utils/Hash.h" @@ -27,339 +28,224 @@ using std::string; namespace atlas { namespace util { -void Metadata::throw_exception(const std::string& name) const { - std::stringstream msg; - msg << "Could not find metadata \"" << name << "\""; - throw eckit::OutOfRange(msg.str(),Here()); +void Metadata::throw_exception( const std::string& name ) const { + std::stringstream msg; + msg << "Could not find metadata \"" << name << "\""; + throw eckit::OutOfRange( msg.str(), Here() ); } -size_t Metadata::footprint() const -{ - // TODO - size_t size = sizeof(*this); - return size; +size_t Metadata::footprint() const { + // TODO + size_t size = sizeof( *this ); + return size; } -void Metadata::broadcast() -{ - size_t root = 0; - get( "owner", root ); - broadcast(*this,root); +void Metadata::broadcast() { + size_t root = 0; + get( "owner", root ); + broadcast( *this, root ); } -void Metadata::broadcast(const size_t root) -{ - broadcast(*this,root); +void Metadata::broadcast( const size_t root ) { + broadcast( *this, root ); } -void Metadata::broadcast(Metadata& dest) -{ - size_t root = 0; - get( "owner", root ); - broadcast(dest,root); +void Metadata::broadcast( Metadata& dest ) { + size_t root = 0; + get( "owner", root ); + broadcast( dest, root ); } -void Metadata::broadcast(Metadata& dest, const size_t root) -{ - std::string buffer; - int buffer_size; - if( atlas::mpi::comm().rank() == root ) - { - std::stringstream s; - eckit::JSON json(s); - json.precision(17); - json << *this; - buffer = s.str(); - buffer_size = buffer.size(); - } - - ATLAS_TRACE_MPI( BROADCAST ) { - atlas::mpi::comm().broadcast(buffer_size,root); - } - - if( atlas::mpi::comm().rank() != root ) { - buffer.resize(buffer_size); - } - - ATLAS_TRACE_MPI( BROADCAST ) { - atlas::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); - } - - if( not (&dest==this && atlas::mpi::comm().rank() == root ) ) - { - std::stringstream s; - s << buffer; - eckit::JSONParser parser( s ); - dest = Metadata( parser.parse() ); - } -} +void Metadata::broadcast( Metadata& dest, const size_t root ) { + std::string buffer; + int buffer_size; + if ( atlas::mpi::comm().rank() == root ) { + std::stringstream s; + eckit::JSON json( s ); + json.precision( 17 ); + json << *this; + buffer = s.str(); + buffer_size = buffer.size(); + } + + ATLAS_TRACE_MPI( BROADCAST ) { atlas::mpi::comm().broadcast( buffer_size, root ); } + + if ( atlas::mpi::comm().rank() != root ) { buffer.resize( buffer_size ); } -void Metadata::broadcast(Metadata& dest) const -{ - size_t root = 0; - get( "owner", root ); - broadcast(dest,root); + ATLAS_TRACE_MPI( BROADCAST ) { atlas::mpi::comm().broadcast( buffer.begin(), buffer.end(), root ); } + + if ( not( &dest == this && atlas::mpi::comm().rank() == root ) ) { + std::stringstream s; + s << buffer; + eckit::JSONParser parser( s ); + dest = Metadata( parser.parse() ); + } } -void Metadata::broadcast(Metadata& dest, const size_t root) const -{ - std::string buffer; - int buffer_size; - if( atlas::mpi::comm().rank() == root ) - { - std::stringstream s; - eckit::JSON json(s); - json.precision(17); - json << *this; - buffer = s.str(); - buffer_size = buffer.size(); - } - - ATLAS_TRACE_MPI( BROADCAST ) { - atlas::mpi::comm().broadcast(buffer_size,root); - } - - if( atlas::mpi::comm().rank() != root ) { - buffer.resize(buffer_size); - } - - ATLAS_TRACE_MPI( BROADCAST ) { - atlas::mpi::comm().broadcast(buffer.begin(), buffer.end(), root); - } - - // Fill in dest - { - std::stringstream s; - s << buffer; - eckit::JSONParser parser( s ); - dest = Metadata( parser.parse() ); - } +void Metadata::broadcast( Metadata& dest ) const { + size_t root = 0; + get( "owner", root ); + broadcast( dest, root ); } +void Metadata::broadcast( Metadata& dest, const size_t root ) const { + std::string buffer; + int buffer_size; + if ( atlas::mpi::comm().rank() == root ) { + std::stringstream s; + eckit::JSON json( s ); + json.precision( 17 ); + json << *this; + buffer = s.str(); + buffer_size = buffer.size(); + } + + ATLAS_TRACE_MPI( BROADCAST ) { atlas::mpi::comm().broadcast( buffer_size, root ); } + + if ( atlas::mpi::comm().rank() != root ) { buffer.resize( buffer_size ); } -void Metadata::hash(eckit::Hash& hsh) const -{ - eckit::ValueMap map = get(); - for( eckit::ValueMap::const_iterator vit = map.begin(); vit != map.end(); ++vit ) - { - hsh.add(vit->first.as()); - /// @note below, we assume all Values translate to std::string, this needs more verification - hsh.add(vit->second.as()); - } + ATLAS_TRACE_MPI( BROADCAST ) { atlas::mpi::comm().broadcast( buffer.begin(), buffer.end(), root ); } + + // Fill in dest + { + std::stringstream s; + s << buffer; + eckit::JSONParser parser( s ); + dest = Metadata( parser.parse() ); + } } -Metadata::Metadata( const eckit::Value& value ) : - eckit::LocalConfiguration(value) { +void Metadata::hash( eckit::Hash& hsh ) const { + eckit::ValueMap map = get(); + for ( eckit::ValueMap::const_iterator vit = map.begin(); vit != map.end(); ++vit ) { + hsh.add( vit->first.as() ); + /// @note below, we assume all Values translate to std::string, this needs + /// more verification + hsh.add( vit->second.as() ); + } } +Metadata::Metadata( const eckit::Value& value ) : eckit::LocalConfiguration( value ) {} + // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines -Metadata* atlas__Metadata__new () { - return new Metadata(); -} - -void atlas__Metadata__delete (Metadata* This) { - delete This; -} - -void atlas__Metadata__set_int (Metadata* This, const char* name, int value) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - This->set( std::string(name), long(value) ) - ); -} -void atlas__Metadata__set_long (Metadata* This, const char* name, long value) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - This->set( std::string(name), value ); - ); -} -void atlas__Metadata__set_float (Metadata* This, const char* name, float value) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - This->set( std::string(name), double(value) ); - ); -} -void atlas__Metadata__set_double (Metadata* This, const char* name, double value) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - This->set( std::string(name), value ); - ); -} -void atlas__Metadata__set_string (Metadata* This, const char* name, const char* value) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - This->set( std::string(name), std::string(value) ); - ); -} -void atlas__Metadata__set_array_int (Metadata* This, const char* name, int value[], int size) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - std::vector v; - v.assign(value,value+size); - This->set( std::string(name), v ); - ); -} -void atlas__Metadata__set_array_long (Metadata* This, const char* name, long value[], int size) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - std::vector v; - v.assign(value,value+size); - This->set( std::string(name), v ); - ); -} -void atlas__Metadata__set_array_float (Metadata* This, const char* name, float value[], int size) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - std::vector v; - v.assign(value,value+size); - This->set( std::string(name), v ); - ); -} -void atlas__Metadata__set_array_double (Metadata* This, const char* name, double value[], int size) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - std::vector v; - v.assign(value,value+size); - This->set( std::string(name), v ); - ); -} -int atlas__Metadata__get_int (Metadata* This, const char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - return This->get( std::string(name) ) - ); - return 0; -} -long atlas__Metadata__get_long (Metadata* This, const char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - return This->get( std::string(name) ); - ); - return 0; -} -float atlas__Metadata__get_float (Metadata* This, const char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - return This->get( std::string(name) ); - ); - return 0; -} -double atlas__Metadata__get_double (Metadata* This, const char* name) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - return This->get( std::string(name) ); - ); - return 0; -} -void atlas__Metadata__get_string( Metadata* This, const char* name, char* output_str, int max_len ) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - std::string s = This->get( std::string(name) ); - if(s.size() > size_t(max_len)) - { - std::stringstream msg; - msg << "Cannot copy string `"< v = This->get< std::vector >( std::string(name ) ); - size = v.size(); - value = new int[size]; - for( size_t j=0; j v = This->get< std::vector >( std::string(name ) ); - size = v.size(); - value = new long[size]; - for( size_t j=0; j v = This->get< std::vector >( std::string(name ) ); - size = v.size(); - value = new float[size]; - for( size_t j=0; j v = This->get< std::vector >( std::string(name ) ); - size = v.size(); - value = new double[size]; - for( size_t j=0; jhas( std::string(name) ); - ); - return 0; +void atlas__Metadata__delete( Metadata* This ) { + delete This; } -void atlas__Metadata__print (Metadata* This, std::ostream* channel) -{ - ATLAS_ERROR_HANDLING( - ASSERT( This != NULL ); - ASSERT( channel != NULL ); - *channel << *This; - ); +void atlas__Metadata__set_int( Metadata* This, const char* name, int value ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); This->set( std::string( name ), long( value ) ) ); +} +void atlas__Metadata__set_long( Metadata* This, const char* name, long value ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); This->set( std::string( name ), value ); ); +} +void atlas__Metadata__set_float( Metadata* This, const char* name, float value ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); This->set( std::string( name ), double( value ) ); ); +} +void atlas__Metadata__set_double( Metadata* This, const char* name, double value ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); This->set( std::string( name ), value ); ); +} +void atlas__Metadata__set_string( Metadata* This, const char* name, const char* value ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); This->set( std::string( name ), std::string( value ) ); ); +} +void atlas__Metadata__set_array_int( Metadata* This, const char* name, int value[], int size ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); std::vector v; v.assign( value, value + size ); + This->set( std::string( name ), v ); ); +} +void atlas__Metadata__set_array_long( Metadata* This, const char* name, long value[], int size ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); std::vector v; v.assign( value, value + size ); + This->set( std::string( name ), v ); ); +} +void atlas__Metadata__set_array_float( Metadata* This, const char* name, float value[], int size ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); std::vector v; v.assign( value, value + size ); + This->set( std::string( name ), v ); ); +} +void atlas__Metadata__set_array_double( Metadata* This, const char* name, double value[], int size ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); std::vector v; v.assign( value, value + size ); + This->set( std::string( name ), v ); ); +} +int atlas__Metadata__get_int( Metadata* This, const char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); return This->get( std::string( name ) ) ); + return 0; +} +long atlas__Metadata__get_long( Metadata* This, const char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); return This->get( std::string( name ) ); ); + return 0; +} +float atlas__Metadata__get_float( Metadata* This, const char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); return This->get( std::string( name ) ); ); + return 0; +} +double atlas__Metadata__get_double( Metadata* This, const char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); return This->get( std::string( name ) ); ); + return 0; +} +void atlas__Metadata__get_string( Metadata* This, const char* name, char* output_str, int max_len ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); std::string s = This->get( std::string( name ) ); + if ( s.size() > size_t( max_len ) ) { + std::stringstream msg; + msg << "Cannot copy string `" << s << "` of metadata `" << name + << "`" + "in buffer of length " + << max_len; + throw eckit::OutOfRange( msg.str(), Here() ); + } strcpy( output_str, s.c_str() ); + return ); + output_str = NULL; +} +void atlas__Metadata__get_array_int( Metadata* This, const char* name, int*& value, int& size, int& allocated ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); + std::vector v = This->get>( std::string( name ) ); size = v.size(); + value = new int[size]; 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 ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); + std::vector v = This->get>( std::string( name ) ); size = v.size(); + value = new long[size]; 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 ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); + std::vector v = This->get>( std::string( name ) ); size = v.size(); + value = new float[size]; 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 ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); + std::vector v = This->get>( std::string( name ) ); + size = v.size(); value = new double[size]; + for ( size_t j = 0; j < v.size(); ++j ) value[j] = v[j]; allocated = true; ); } -void atlas__Metadata__json(Metadata* This, char* &json, int &size, int &allocated) -{ - std::stringstream s; - eckit::JSON j(s); - j.precision(16); - j << *This; - std::string json_str = s.str(); - size = json_str.size(); - json = new char[size+1]; allocated = true; - strcpy(json,json_str.c_str()); - allocated = true; +int atlas__Metadata__has( Metadata* This, const char* name ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); return This->has( std::string( name ) ); ); + return 0; +} + +void atlas__Metadata__print( Metadata* This, std::ostream* channel ) { + ATLAS_ERROR_HANDLING( ASSERT( This != NULL ); ASSERT( channel != NULL ); *channel << *This; ); +} + +void atlas__Metadata__json( Metadata* This, char*& json, int& size, int& allocated ) { + std::stringstream s; + eckit::JSON j( s ); + j.precision( 16 ); + j << *This; + std::string json_str = s.str(); + size = json_str.size(); + json = new char[size + 1]; + allocated = true; + strcpy( json, json_str.c_str() ); + allocated = true; } // ------------------------------------------------------------------ -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Metadata.h b/src/atlas/util/Metadata.h index e4962758d..49993b90f 100644 --- a/src/atlas/util/Metadata.h +++ b/src/atlas/util/Metadata.h @@ -4,61 +4,63 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once #include -#include "eckit/config/Parametrisation.h" #include "eckit/config/LocalConfiguration.h" +#include "eckit/config/Parametrisation.h" #include "eckit/utils/Hash.h" namespace atlas { namespace util { -class Metadata: public eckit::LocalConfiguration { - +class Metadata : public eckit::LocalConfiguration { public: + Metadata() : eckit::LocalConfiguration() {} - Metadata(): eckit::LocalConfiguration() {} + Metadata( const eckit::LocalConfiguration& p ) : eckit::LocalConfiguration( p ) {} + Metadata( const Metadata& p ) : eckit::LocalConfiguration( p ) {} - Metadata(const eckit::LocalConfiguration& p): eckit::LocalConfiguration(p) {} - Metadata(const Metadata& p): eckit::LocalConfiguration(p) {} + using eckit::LocalConfiguration::set; - using eckit::LocalConfiguration::set; + template + Metadata& set( const std::string& name, const ValueT& value ) { + eckit::LocalConfiguration::set( name, value ); + return *this; + } - template - Metadata& set(const std::string& name, const ValueT& value) { - eckit::LocalConfiguration::set(name,value); - return *this; - } + using eckit::LocalConfiguration::get; - using eckit::LocalConfiguration::get; + template + ValueT get( const std::string& name ) const { + ValueT value; + if ( not eckit::LocalConfiguration::get( name, value ) ) throw_exception( name ); + return value; + } - template - ValueT get(const std::string& name) const { - ValueT value; - if( not eckit::LocalConfiguration::get(name,value) ) throw_exception(name); - return value; - } + friend std::ostream& operator<<( std::ostream& s, const Metadata& v ) { + v.print( s ); + return s; + } - friend std::ostream& operator<<(std::ostream& s, const Metadata& v) { v.print(s); return s; } + void broadcast(); + void broadcast( const size_t root ); + void broadcast( Metadata& ); + void broadcast( Metadata&, const size_t root ); + void broadcast( Metadata& ) const; + void broadcast( Metadata&, const size_t root ) const; - void broadcast(); - void broadcast(const size_t root); - void broadcast(Metadata&); - void broadcast(Metadata&, const size_t root); - void broadcast(Metadata&) const; - void broadcast(Metadata&, const size_t root) const; - - size_t footprint() const; + size_t footprint() const; - void hash(eckit::Hash&) const; + void hash( eckit::Hash& ) const; private: - void throw_exception(const std::string&) const; + void throw_exception( const std::string& ) const; Metadata( const eckit::Value& ); }; @@ -66,37 +68,35 @@ class Metadata: public eckit::LocalConfiguration { // ------------------------------------------------------------------ // C wrapper interfaces to C++ routines - -extern "C" -{ - Metadata* atlas__Metadata__new (); - - void atlas__Metadata__delete (Metadata* This); - void atlas__Metadata__print (Metadata* This, std::ostream* channel); - void atlas__Metadata__json (Metadata* This, char* &json, int &size, int &allocated); - int atlas__Metadata__has (Metadata* This, const char* name); - void atlas__Metadata__set_int (Metadata* This, const char* name, int value); - void atlas__Metadata__set_long (Metadata* This, const char* name, long value); - void atlas__Metadata__set_float (Metadata* This, const char* name, float value); - void atlas__Metadata__set_double (Metadata* This, const char* name, double value); - void atlas__Metadata__set_string (Metadata* This, const char* name, const char* value); - void atlas__Metadata__set_array_int (Metadata* This, const char* name, int value[], int size); - void atlas__Metadata__set_array_long (Metadata* This, const char* name, long value[], int size); - void atlas__Metadata__set_array_float (Metadata* This, const char* name, float value[], int size); - void atlas__Metadata__set_array_double (Metadata* This, const char* name, double value[], int size); - - int atlas__Metadata__get_int (Metadata* This, const char* name); - long atlas__Metadata__get_long (Metadata* This, const char* name); - float atlas__Metadata__get_float (Metadata* This, const char* name); - double atlas__Metadata__get_double (Metadata* This, const char* name); - void atlas__Metadata__get_string (Metadata* This, const char* name, char* output_str, int max_len); - void atlas__Metadata__get_array_int (Metadata* This, const char* name, int* &value, int &size, int &allocated); - void atlas__Metadata__get_array_long (Metadata* This, const char* name, long* &value, int &size, int &allocated); - void atlas__Metadata__get_array_float (Metadata* This, const char* name, float* &value, int &size, int &allocated); - void atlas__Metadata__get_array_double (Metadata* This, const char* name, double* &value, int &size, int &allocated); +extern "C" { +Metadata* atlas__Metadata__new(); + +void atlas__Metadata__delete( Metadata* This ); +void atlas__Metadata__print( Metadata* This, std::ostream* channel ); +void atlas__Metadata__json( Metadata* This, char*& json, int& size, int& allocated ); +int atlas__Metadata__has( Metadata* This, const char* name ); +void atlas__Metadata__set_int( Metadata* This, const char* name, int value ); +void atlas__Metadata__set_long( Metadata* This, const char* name, long value ); +void atlas__Metadata__set_float( Metadata* This, const char* name, float value ); +void atlas__Metadata__set_double( Metadata* This, const char* name, double value ); +void atlas__Metadata__set_string( Metadata* This, const char* name, const char* value ); +void atlas__Metadata__set_array_int( Metadata* This, const char* name, int value[], int size ); +void atlas__Metadata__set_array_long( Metadata* This, const char* name, long value[], int size ); +void atlas__Metadata__set_array_float( Metadata* This, const char* name, float value[], int size ); +void atlas__Metadata__set_array_double( Metadata* This, const char* name, double value[], int size ); + +int atlas__Metadata__get_int( Metadata* This, const char* name ); +long atlas__Metadata__get_long( Metadata* This, const char* name ); +float atlas__Metadata__get_float( Metadata* This, const char* name ); +double atlas__Metadata__get_double( Metadata* This, const char* name ); +void atlas__Metadata__get_string( Metadata* This, const char* name, char* output_str, int max_len ); +void atlas__Metadata__get_array_int( Metadata* This, const char* name, int*& value, int& size, int& allocated ); +void atlas__Metadata__get_array_long( Metadata* This, const char* name, long*& value, int& size, int& allocated ); +void atlas__Metadata__get_array_float( Metadata* This, const char* name, float*& value, int& size, int& allocated ); +void atlas__Metadata__get_array_double( Metadata* This, const char* name, double*& value, int& size, int& allocated ); } // ------------------------------------------------------------------ -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/MicroDeg.h b/src/atlas/util/MicroDeg.h index bc07f324e..e8c51cc24 100644 --- a/src/atlas/util/MicroDeg.h +++ b/src/atlas/util/MicroDeg.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,12 +14,11 @@ namespace atlas { namespace util { -inline int microdeg( const double& deg ) -{ - assert( deg < 2145. ); // Since INT_MAX == 2147483647 - assert( deg > -2145. ); // Since INT_MIN == –2147483648 - return int(deg*1.e6 + 0.5); +inline int microdeg( const double& deg ) { + assert( deg < 2145. ); // Since INT_MAX == 2147483647 + assert( deg > -2145. ); // Since INT_MIN == –2147483648 + return int( deg * 1.e6 + 0.5 ); } -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Point.h b/src/atlas/util/Point.h index 22ba9843d..4cb22c012 100644 --- a/src/atlas/util/Point.h +++ b/src/atlas/util/Point.h @@ -16,11 +16,11 @@ /// - lonlat_to_geocentric : Converts a PointLonLat to a PointXYZ defined in /// Earth-centred coordinates. -#include #include +#include +#include "atlas/util/Earth.h" #include "eckit/geometry/Point2.h" #include "eckit/geometry/Point3.h" -#include "atlas/util/Earth.h" namespace atlas { @@ -28,96 +28,93 @@ using Point2 = eckit::geometry::Point2; using Point3 = eckit::geometry::Point3; class PointXY : public Point2 { - using array_t = std::array; + using array_t = std::array; public: + using Point2::Point2; - using Point2::Point2; + PointXY() : Point2() {} - PointXY() : Point2() {} + // Allow initialization through PointXY xy = {0,0}; + PointXY( std::initializer_list list ) : PointXY( list.begin() ) {} + PointXY( const array_t& arr ) : PointXY( arr.data() ) {} - // Allow initialization through PointXY xy = {0,0}; - PointXY(std::initializer_list list) : PointXY(list.begin()) {} - PointXY(const array_t& arr) : PointXY(arr.data()) {} + double x() const { return x_[0]; } + double y() const { return x_[1]; } + double& x() { return x_[0]; } + double& y() { return x_[1]; } - double x() const { return x_[0]; } - double y() const { return x_[1]; } - double& x() { return x_[0]; } - double& y() { return x_[1]; } - - using Point2::assign; - - void assign( double x, double y ) { - x_[0] = x; - x_[1] = y; - } + using Point2::assign; + void assign( double x, double y ) { + x_[0] = x; + x_[1] = y; + } }; class PointXYZ : public Point3 { - using array_t = std::array; + using array_t = std::array; - PointXYZ(double,double) {/* No automatic converion allowed, otherwise inherited from Point3 */} + PointXYZ( double, double ) { /* No automatic converion allowed, otherwise + inherited from Point3 */ + } public: + using Point3::Point3; - using Point3::Point3; - - PointXYZ() : Point3() {} - - // Allow initialization through PointXYZ xyz = {0,0,0}; - PointXYZ(std::initializer_list list) : PointXYZ(list.begin()) {} + PointXYZ() : Point3() {} - PointXYZ(const array_t& arr) : PointXYZ(arr.data()) {} + // Allow initialization through PointXYZ xyz = {0,0,0}; + PointXYZ( std::initializer_list list ) : PointXYZ( list.begin() ) {} - double x() const { return x_[0]; } - double y() const { return x_[1]; } - double z() const { return x_[2]; } - double& x() { return x_[0]; } - double& y() { return x_[1]; } - double& z() { return x_[2]; } + PointXYZ( const array_t& arr ) : PointXYZ( arr.data() ) {} - using Point3::assign; + double x() const { return x_[0]; } + double y() const { return x_[1]; } + double z() const { return x_[2]; } + double& x() { return x_[0]; } + double& y() { return x_[1]; } + double& z() { return x_[2]; } - void assign( double x, double y, double z ) { - x_[0] = x; - x_[1] = y; - x_[2] = z; - } + using Point3::assign; + void assign( double x, double y, double z ) { + x_[0] = x; + x_[1] = y; + x_[2] = z; + } }; class PointLonLat : public Point2 { - using array_t = std::array; + using array_t = std::array; public: + using Point2::Point2; - using Point2::Point2; + PointLonLat() : Point2() {} - PointLonLat() : Point2() {} + // Allow initialization through PointXY lonlat = {0,0}; + PointLonLat( std::initializer_list list ) : PointLonLat( list.begin() ) {} - // Allow initialization through PointXY lonlat = {0,0}; - PointLonLat(std::initializer_list list) : PointLonLat(list.begin()) {} + PointLonLat( const array_t& arr ) : PointLonLat( arr.data() ) {} - PointLonLat(const array_t& arr) : PointLonLat(arr.data()) {} + double lon() const { return x_[0]; } + double lat() const { return x_[1]; } + double& lon() { return x_[0]; } + double& lat() { return x_[1]; } - double lon() const { return x_[0]; } - double lat() const { return x_[1]; } - double& lon() { return x_[0]; } - double& lat() { return x_[1]; } + using Point2::assign; - using Point2::assign; + void assign( double lon, double lat ) { + x_[0] = lon; + x_[1] = lat; + } - void assign( double lon, double lat ) { - x_[0] = lon; - x_[1] = lat; - } - - PointLonLat& operator*=(double a) { - x_[0] *= a; - x_[1] *= a; - return *this; - } + PointLonLat& operator*=( double a ) { + x_[0] *= a; + x_[1] *= a; + return *this; + } }; -} +} // namespace atlas diff --git a/src/atlas/util/Polygon.cc b/src/atlas/util/Polygon.cc index d4650c989..137844ae6 100644 --- a/src/atlas/util/Polygon.cc +++ b/src/atlas/util/Polygon.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,184 +15,154 @@ #include #include #include -#include "eckit/exception/Exceptions.h" -#include "eckit/types/FloatCompare.h" #include "atlas/mesh/Nodes.h" #include "atlas/util/CoordinateEnums.h" +#include "eckit/exception/Exceptions.h" +#include "eckit/types/FloatCompare.h" namespace atlas { namespace util { namespace { - //------------------------------------------------------------------------------------------------------ - -double cross_product_analog(const PointLonLat& A, const PointLonLat& B, const PointLonLat& C) { - return (A.lon() - C.lon()) * (B.lat() - C.lat()) - - (A.lat() - C.lat()) * (B.lon() - C.lon()); +double cross_product_analog( const PointLonLat& A, const PointLonLat& B, const PointLonLat& C ) { + return ( A.lon() - C.lon() ) * ( B.lat() - C.lat() ) - ( A.lat() - C.lat() ) * ( B.lon() - C.lon() ); } - -} // (anonymous) - +} // namespace //------------------------------------------------------------------------------------------------------ +Polygon::Polygon() {} -Polygon::Polygon() { -} - - -Polygon::Polygon(const Polygon::edge_set_t& edges) { +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); - } + for ( const edge_t& e : edges ) { + if ( !extEdges.erase( e.reverse() ) ) { extEdges.insert( e ); } } - ASSERT(extEdges.size() >= 2); + ASSERT( extEdges.size() >= 2 ); - // set one polygon cycle, by picking next edge with first node same as second node of last edge + // set one polygon cycle, by picking next edge with first node same as second + // node of last edge clear(); - reserve(extEdges.size() + 1); + reserve( extEdges.size() + 1 ); - push_back(extEdges.begin()->first); - for (edge_set_t::iterator e = extEdges.begin(); e != extEdges.end() && e->first == back(); - e = extEdges.lower_bound(edge_t(back(), std::numeric_limits< idx_t >::min()))) { - push_back(e->second); - extEdges.erase(*e); + push_back( extEdges.begin()->first ); + for ( edge_set_t::iterator e = extEdges.begin(); e != extEdges.end() && e->first == back(); + e = extEdges.lower_bound( edge_t( back(), std::numeric_limits::min() ) ) ) { + push_back( e->second ); + extEdges.erase( *e ); } - ASSERT(front() == back()); + ASSERT( front() == back() ); // exhaust remaining edges, should represent additional cycles, if any - while (!extEdges.empty()) { - operator+=(Polygon(extEdges)); + while ( !extEdges.empty() ) { + operator+=( Polygon( extEdges ) ); } } - Polygon::operator bool() const { return !Polygon::empty(); } - -Polygon& Polygon::operator+=(const Polygon& other) { - - if (empty()) { - return operator=(other); - } +Polygon& Polygon::operator+=( const Polygon& 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) last index - ASSERT(other.front() == other.back()); - const difference_type N = difference_type(other.size()) - 1; - - container_t cycle(2 * size_t(N)); - std::copy(other.begin(), other.begin() + N, cycle.begin()); - std::copy(other.begin(), other.begin() + N, cycle.begin() + N); - - for (const_iterator c = cycle.begin(); c != cycle.begin() + N; ++c) { - iterator here = std::find(begin(), end(), *c); - if (here != end()) { - insert(here, c, c + N); + // Note: a 'cycle' is handled by repeating the indices, excluding (repeated) + // last index + ASSERT( other.front() == other.back() ); + const difference_type N = difference_type( other.size() ) - 1; + + container_t cycle( 2 * size_t( N ) ); + std::copy( other.begin(), other.begin() + N, cycle.begin() ); + std::copy( other.begin(), other.begin() + N, cycle.begin() + N ); + + for ( const_iterator c = cycle.begin(); c != cycle.begin() + N; ++c ) { + iterator here = std::find( begin(), end(), *c ); + if ( here != end() ) { + insert( here, c, c + N ); return *this; } } - throw eckit::AssertionFailed("Polygon: could not merge polygons, they are not connected", Here()); + throw eckit::AssertionFailed( "Polygon: could not merge polygons, they are not connected", Here() ); } - -void Polygon::print(std::ostream& s) const { +void Polygon::print( std::ostream& s ) const { char z = '{'; - for (auto n : static_cast(*this)) { + for ( auto n : static_cast( *this ) ) { s << z << n; z = ','; } s << '}'; } - //------------------------------------------------------------------------------------------------------ - -PolygonCoordinates::PolygonCoordinates( - const Polygon& poly, - const atlas::Field& lonlat, - bool removeAlignedPoints ) { - - ASSERT(poly.size() > 2); - ASSERT(poly.front() == poly.back()); +PolygonCoordinates::PolygonCoordinates( const Polygon& poly, const atlas::Field& lonlat, bool removeAlignedPoints ) { + ASSERT( poly.size() > 2 ); + ASSERT( poly.front() == poly.back() ); // Point coordinates // - use a bounding box to quickly discard points, // - except when that is above/below bounding box but poles should be included coordinates_.clear(); - coordinates_.reserve(poly.size()); + coordinates_.reserve( poly.size() ); - auto ll = array::make_view< double, 2 >(lonlat); - coordinatesMin_ = PointLonLat(ll(poly[0], LON), ll(poly[0], LAT)); + auto ll = array::make_view( lonlat ); + coordinatesMin_ = PointLonLat( ll( poly[0], LON ), ll( poly[0], LAT ) ); coordinatesMax_ = coordinatesMin_; - for (size_t i = 0; i < poly.size(); ++i) { - - PointLonLat A(ll(poly[i], LON), ll(poly[i], LAT)); - coordinatesMin_ = PointLonLat::componentsMin(coordinatesMin_, A); - coordinatesMax_ = PointLonLat::componentsMax(coordinatesMax_, A); + for ( size_t i = 0; i < poly.size(); ++i ) { + PointLonLat A( ll( poly[i], LON ), ll( poly[i], LAT ) ); + coordinatesMin_ = PointLonLat::componentsMin( coordinatesMin_, A ); + coordinatesMax_ = PointLonLat::componentsMax( coordinatesMax_, A ); - // if new point is aligned with existing edge (cross product ~= 0) make the edge longer - if ((coordinates_.size() >= 2) && removeAlignedPoints) { + // if new point is aligned with existing edge (cross product ~= 0) make the + // edge longer + if ( ( coordinates_.size() >= 2 ) && removeAlignedPoints ) { const PointLonLat& B = coordinates_.back(); const PointLonLat& C = coordinates_[coordinates_.size() - 2]; - if (eckit::types::is_approximately_equal( 0., cross_product_analog(A, B, C) )) { + if ( eckit::types::is_approximately_equal( 0., cross_product_analog( A, B, C ) ) ) { coordinates_.back() = A; continue; } } - coordinates_.push_back(A); + coordinates_.push_back( A ); } - ASSERT(coordinates_.size() == poly.size()); + ASSERT( coordinates_.size() == poly.size() ); } - -PolygonCoordinates::PolygonCoordinates(const std::vector& points) : - coordinates_(points) { - - ASSERT(coordinates_.size() > 2); - ASSERT(eckit::geometry::points_equal(coordinates_.front(), coordinates_.back())); +PolygonCoordinates::PolygonCoordinates( const std::vector& points ) : coordinates_( points ) { + ASSERT( coordinates_.size() > 2 ); + ASSERT( eckit::geometry::points_equal( coordinates_.front(), coordinates_.back() ) ); coordinatesMin_ = coordinates_.front(); coordinatesMax_ = coordinatesMin_; - for (const PointLonLat& P : coordinates_) { - coordinatesMin_ = PointLonLat::componentsMin(coordinatesMin_, P); - coordinatesMax_ = PointLonLat::componentsMax(coordinatesMax_, P); + for ( const PointLonLat& P : coordinates_ ) { + coordinatesMin_ = PointLonLat::componentsMin( coordinatesMin_, P ); + coordinatesMax_ = PointLonLat::componentsMax( coordinatesMax_, P ); } } - -PolygonCoordinates::~PolygonCoordinates() { -} - +PolygonCoordinates::~PolygonCoordinates() {} const PointLonLat& PolygonCoordinates::coordinatesMax() const { return coordinatesMax_; } - const PointLonLat& PolygonCoordinates::coordinatesMin() const { return coordinatesMin_; } - //------------------------------------------------------------------------------------------------------ - -} // util -} // atlas - +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Polygon.h b/src/atlas/util/Polygon.h index 52181d212..21eef811c 100644 --- a/src/atlas/util/Polygon.h +++ b/src/atlas/util/Polygon.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -33,64 +34,56 @@ namespace util { /// Polygon class Polygon : public std::vector { public: - // -- Types - struct edge_t : std::pair< idx_t, idx_t > { - edge_t(idx_t A, idx_t B) : std::pair< idx_t, idx_t >(A, B) { - } + struct edge_t : std::pair { + edge_t( idx_t A, idx_t B ) : std::pair( A, B ) {} - edge_t reverse() const { - return edge_t(std::pair< idx_t, idx_t >::second, std::pair< idx_t, idx_t >::first); - } + edge_t reverse() const { return edge_t( std::pair::second, std::pair::first ); } struct LessThan { - bool operator()(const edge_t& e1, const edge_t& e2) const { + bool operator()( const edge_t& e1, const edge_t& e2 ) const { // order ascending by 'first' - return (e1.first < e2.first ? true : - e1.first > e2.first ? false : - e1.second < e2.second ); + return ( e1.first < e2.first ? true : e1.first > e2.first ? false : e1.second < e2.second ); } }; }; - typedef std::set< edge_t, typename edge_t::LessThan > edge_set_t; + typedef std::set edge_set_t; typedef std::vector container_t; // -- Constructors Polygon(); - Polygon(const edge_set_t&); + Polygon( const edge_set_t& ); // -- Operators operator bool() const; - Polygon& operator+=(const Polygon&); + Polygon& operator+=( const Polygon& ); // -- Methods - void print(std::ostream&) const; + void print( std::ostream& ) const; // -- Friends - friend std::ostream& operator<<(std::ostream& s, const Polygon& p) { - p.print(s); + friend std::ostream& operator<<( std::ostream& s, const Polygon& p ) { + p.print( s ); return s; } - }; //------------------------------------------------------------------------------------------------------ class PolygonCoordinates { public: - // -- Constructors - PolygonCoordinates(const Polygon&, const atlas::Field& lonlat, bool removeAlignedPoints); + PolygonCoordinates( const Polygon&, const atlas::Field& lonlat, bool removeAlignedPoints ); - PolygonCoordinates(const std::vector& points); + PolygonCoordinates( const std::vector& points ); // -- Destructor @@ -99,27 +92,24 @@ class PolygonCoordinates { // -- Methods /* - * Point-in-partition test - * @param[in] P given point - * @return if point is in polygon - */ - virtual bool contains(const PointLonLat& P) const = 0; + * Point-in-partition test + * @param[in] P given point + * @return if point is in polygon + */ + virtual bool contains( const PointLonLat& P ) const = 0; const PointLonLat& coordinatesMax() const; const PointLonLat& coordinatesMin() const; protected: - // -- Members PointLonLat coordinatesMin_; PointLonLat coordinatesMax_; - std::vector< PointLonLat > coordinates_; - + std::vector coordinates_; }; //------------------------------------------------------------------------------------------------------ -} // util -} // atlas - +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index 9974e031c..164a458cb 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,10 +13,10 @@ #include #include -#include "eckit/config/Parametrisation.h" #include "atlas/util/Constants.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" +#include "eckit/config/Parametrisation.h" // Temporary option to activate implementation by RMI during ESCAPE #define OLD_IMPLEMENTATION 0 @@ -24,230 +25,218 @@ namespace atlas { namespace util { void Rotation::print( std::ostream& out ) const { - out << "north_pole:"< 90 ) npole_.lon() += 180.; + angle_ = rotation_angle; - spole_ = south_pole; - npole_ = PointLonLat(spole_.lon()-180.,spole_.lat()+180.); - if( npole_.lat() > 90 ) npole_.lon() += 180.; - angle_ = rotation_angle; - - precompute(); + precompute(); } -Rotation::Rotation(const eckit::Parametrisation& p) { - +Rotation::Rotation( const eckit::Parametrisation& p ) { #if OLD_IMPLEMENTATION - npole_ = {0.,90.}; + npole_ = {0., 90.}; #endif - // get rotation angle - p.get("rotation_angle",angle_); - - // get pole - std::vector pole(2); - 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.; - } 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.; - } + // get rotation angle + p.get( "rotation_angle", angle_ ); - precompute(); + // get pole + std::vector pole( 2 ); + 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.; + } + 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.; + } + 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[0]=lont+npole_.lon(); - crd[1]=latt; +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[0] = lont + npole_.lon(); + crd[1] = latt; } +void Rotation::unrotate_old( double crd[] ) const { + // inverse operation of Projection::rotate -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; + 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(); + // 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); + 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; + // 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; + // untilt + x = cos_latrp_ * xt - sin_latrp_ * zt; + y = yt; + 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(); + // back to spherical coordinates + crd[0] = std::atan2( y, x ) * Constants::radiansToDegrees(); + crd[1] = std::asin( z ) * Constants::radiansToDegrees(); } -using RotationMatrix = std::array,3>; +using RotationMatrix = std::array, 3>; -inline PointXYZ rotate_geocentric(const PointXYZ& p, const RotationMatrix& R) { - return PointXYZ ( - R[XX][XX]*p.x() + R[XX][YY]*p.y() + R[XX][ZZ]*p.z() , - R[YY][XX]*p.x() + R[YY][YY]*p.y() + R[YY][ZZ]*p.z() , - R[ZZ][XX]*p.x() + R[ZZ][YY]*p.y() + R[ZZ][ZZ]*p.z() ); +inline PointXYZ rotate_geocentric( const PointXYZ& p, const RotationMatrix& R ) { + return PointXYZ( R[XX][XX] * p.x() + R[XX][YY] * p.y() + R[XX][ZZ] * p.z(), + R[YY][XX] * p.x() + R[YY][YY] * p.y() + R[YY][ZZ] * p.z(), + R[ZZ][XX] * p.x() + R[ZZ][YY] * p.y() + R[ZZ][ZZ] * p.z() ); } - -void Rotation::rotate(double crd[]) const { - +void Rotation::rotate( double crd[] ) const { #if OLD_IMPLEMENTATION - rotate_old(crd); + rotate_old( crd ); return; #endif - if( !rotated_ ) { - return; - } else if( rotation_angle_only_ ) { - crd[LON] -= angle_; - return; + if ( !rotated_ ) { return; } + else if ( rotation_angle_only_ ) { + crd[LON] -= angle_; + return; } const PointLonLat L( crd ); - const PointXYZ P = Earth::convertGeodeticToGeocentric(L, 1.); - const PointXYZ Pt = rotate_geocentric( P, rotate_ ); - const PointLonLat Lt = Earth::convertGeocentricToGeodetic(Pt, 1.); + const PointXYZ P = Earth::convertGeodeticToGeocentric( L, 1. ); + const PointXYZ Pt = rotate_geocentric( P, rotate_ ); + const PointLonLat Lt = Earth::convertGeocentricToGeodetic( Pt, 1. ); crd[LON] = Lt.lon() - angle_; crd[LAT] = Lt.lat(); } - -void Rotation::unrotate(double crd[]) const { - +void Rotation::unrotate( double crd[] ) const { #if OLD_IMPLEMENTATION - unrotate_old(crd); + unrotate_old( crd ); return; #endif - if( !rotated_ ) { - return; - } else if( rotation_angle_only_ ) { - crd[LON] += angle_; - return; + if ( !rotated_ ) { return; } + else if ( rotation_angle_only_ ) { + crd[LON] += angle_; + return; } - PointLonLat Lt ( crd ); + PointLonLat Lt( crd ); Lt.lon() += angle_; - const PointXYZ Pt = Earth::convertGeodeticToGeocentric(Lt, 1.); + const PointXYZ Pt = Earth::convertGeodeticToGeocentric( Lt, 1. ); const PointXYZ P = rotate_geocentric( Pt, unrotate_ ); - const PointLonLat L = Earth::convertGeocentricToGeodetic(P, 1.); + const PointLonLat L = Earth::convertGeocentricToGeodetic( P, 1. ); crd[LON] = L.lon(); crd[LAT] = L.lat(); @@ -255,4 +244,3 @@ void Rotation::unrotate(double crd[]) const { } // namespace util } // namespace atlas - diff --git a/src/atlas/util/Rotation.h b/src/atlas/util/Rotation.h index 82d3bbc4c..b1b1731f4 100644 --- a/src/atlas/util/Rotation.h +++ b/src/atlas/util/Rotation.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -15,7 +16,7 @@ #include "atlas/util/Point.h" namespace eckit { - class Parametrisation; +class Parametrisation; } namespace atlas { @@ -23,9 +24,7 @@ namespace util { // Compute coordinates of a point on a rotated sphere with specified pole class Rotation { - public: - Rotation( const PointLonLat& south_pole, double rotation_angle = 0. ); Rotation( const eckit::Parametrisation& ); @@ -33,42 +32,39 @@ class Rotation { PointLonLat southPole() const { return spole_; } PointLonLat northPole() const { return npole_; } - double rotationAngle() const { return angle_; } - - PointLonLat rotate(const PointLonLat&) const; - PointLonLat unrotate(const PointLonLat&) const; + double rotationAngle() const { return angle_; } - void rotate(double crd[]) const; - void unrotate(double crd[]) const; + PointLonLat rotate( const PointLonLat& ) const; + PointLonLat unrotate( const PointLonLat& ) const; -private: + void rotate( double crd[] ) const; + void unrotate( double crd[] ) const; +private: void precompute(); void print( std::ostream& ) const; - friend std::ostream& operator<< (std::ostream&, const Rotation&); + friend std::ostream& operator<<( std::ostream&, const Rotation& ); private: + PointLonLat npole_ = {-180., 90.}; // North Pole + PointLonLat spole_ = {0., -90.}; // South Pole + double angle_ = {0.}; - PointLonLat npole_ = {-180., 90.}; // North Pole - PointLonLat spole_ = {0. ,-90.}; // South Pole - double angle_ = {0.}; - - - using RotationMatrix = std::array,3>; + using RotationMatrix = std::array, 3>; - RotationMatrix rotate_; // rotate matrix - RotationMatrix unrotate_; // unrotate matrix + RotationMatrix rotate_; // rotate matrix + RotationMatrix unrotate_; // unrotate matrix bool rotation_angle_only_; - bool rotated_ = {true}; + bool rotated_ = {true}; -// ---- Older implementation ---- + // ---- 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 ) + 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 ) }; } // namespace util diff --git a/src/atlas/util/SphericalPolygon.cc b/src/atlas/util/SphericalPolygon.cc index 276616b76..94cd08330 100644 --- a/src/atlas/util/SphericalPolygon.cc +++ b/src/atlas/util/SphericalPolygon.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -14,56 +15,45 @@ #include #include #include -#include "eckit/types/FloatCompare.h" #include "atlas/util/CoordinateEnums.h" +#include "eckit/types/FloatCompare.h" namespace atlas { namespace util { - //------------------------------------------------------------------------------------------------------ +SphericalPolygon::SphericalPolygon( const Polygon& poly, const atlas::Field& lonlat ) : + PolygonCoordinates( poly, lonlat, false ) {} -SphericalPolygon::SphericalPolygon( const Polygon& poly, const atlas::Field& lonlat) : - PolygonCoordinates(poly, lonlat, false) { -} - - -SphericalPolygon::SphericalPolygon(const std::vector& points) : - PolygonCoordinates(points) { -} - +SphericalPolygon::SphericalPolygon( const std::vector& points ) : PolygonCoordinates( points ) {} -bool SphericalPolygon::contains(const PointLonLat& P) const { - ASSERT(coordinates_.size() >= 2); +bool SphericalPolygon::contains( const PointLonLat& P ) const { + 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; // loop on polygon edges - for (size_t i = 1; i < coordinates_.size(); ++i) { - const PointLonLat& A = coordinates_[i-1]; - const PointLonLat& B = coordinates_[ i ]; + for ( size_t i = 1; i < coordinates_.size(); ++i ) { + const PointLonLat& A = coordinates_[i - 1]; + const PointLonLat& B = coordinates_[i]; // test if P is on/above/below of a great circle containing A,B - const bool APB = (A.lon() <= P.lon() && P.lon() < B.lon()); - const bool BPA = (B.lon() <= P.lon() && P.lon() < A.lon()); + const bool APB = ( A.lon() <= P.lon() && P.lon() < B.lon() ); + const bool BPA = ( B.lon() <= P.lon() && P.lon() < A.lon() ); - if (APB != BPA) { - PointLonLat p(P.lon(), std::numeric_limits::quiet_NaN()); - util::Earth::greatCircleLatitudeGivenLongitude(A, B, p); + if ( APB != BPA ) { + PointLonLat p( P.lon(), std::numeric_limits::quiet_NaN() ); + util::Earth::greatCircleLatitudeGivenLongitude( A, B, p ); - ASSERT(!std::isnan(p.lat())); - if (eckit::types::is_approximately_equal(P.lat(), p.lat())) { - return true; - } + ASSERT( !std::isnan( p.lat() ) ); + if ( eckit::types::is_approximately_equal( P.lat(), p.lat() ) ) { return true; } - wn += (P.lat() > p.lat() ? -1:1) * (APB ? -1:1); + wn += ( P.lat() > p.lat() ? -1 : 1 ) * ( APB ? -1 : 1 ); } } @@ -71,10 +61,7 @@ bool SphericalPolygon::contains(const PointLonLat& P) const { return wn != 0; } - //------------------------------------------------------------------------------------------------------ - -} // util -} // atlas - +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/SphericalPolygon.h b/src/atlas/util/SphericalPolygon.h index ca730d96d..3d1b43bb2 100644 --- a/src/atlas/util/SphericalPolygon.h +++ b/src/atlas/util/SphericalPolygon.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -20,27 +21,26 @@ namespace util { class SphericalPolygon : public PolygonCoordinates { public: - // -- Constructors - SphericalPolygon(const Polygon&, const atlas::Field& lonlat); + SphericalPolygon( const Polygon&, const atlas::Field& lonlat ); - SphericalPolygon(const std::vector& points); + SphericalPolygon( const std::vector& points ); // -- Overridden methods /* - * Point-in-polygon test based on winding number - * @note reference Inclusion of a Point in a Polygon - * @param[in] P given point - * @return if point is in polygon - */ - bool contains(const PointLonLat& P) const; - + * Point-in-polygon test based on winding number + * @note reference Inclusion of a Point + * in a Polygon + * @param[in] P given point + * @return if point is in polygon + */ + bool contains( const PointLonLat& P ) const; }; //------------------------------------------------------------------------------------------------------ -} // util -} // atlas - +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/Unique.h b/src/atlas/util/Unique.h index 1bafb2337..ee2cbbacb 100644 --- a/src/atlas/util/Unique.h +++ b/src/atlas/util/Unique.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,83 +13,86 @@ #include #include +#include "atlas/array/ArrayView.h" +#include "atlas/array/IndexView.h" +#include "atlas/array/LocalView.h" +#include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" #include "atlas/library/config.h" +#include "atlas/mesh/Connectivity.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/Connectivity.h" -#include "atlas/field/Field.h" -#include "atlas/util/LonLatMicroDeg.h" #include "atlas/util/CoordinateEnums.h" +#include "atlas/util/LonLatMicroDeg.h" #include "atlas/util/MicroDeg.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/LocalView.h" -#include "atlas/array/IndexView.h" -#include "atlas/array/MakeView.h" namespace atlas { namespace util { // ---------------------------------------------------------------------------- - /// @brief Compute unique positive index from lon-lat coordinates in microdegrees - /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits - uidx_t unique_lonlat_microdeg( const int lon, const int lat ); - - /// @brief Compute unique positive index from lon-lat coordinates in microdegrees - /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits - uidx_t unique_lonlat_microdeg( const int lonlat[] ); - - /// @brief Compute unique positive index from lon-lat coordinates in microdegrees - /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits - uidx_t unique_lonlat( const LonLatMicroDeg& ); - - /// @brief Compute unique positive index from lon-lat coordinates in degrees - /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits - uidx_t unique_lonlat( const double& lon, const double& lat ); - uidx_t unique_lonlat( const double lonlat[] ); - uidx_t unique_lonlat( const array::LocalView& lonlat ); - - /// @brief Compute unique positive index from lon-lat coordinates in degrees. - /// coordinates are stored in order: - /// [ x1, y1, x2, y2, ... , xn, yn ] - /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits - uidx_t unique_lonlat( const double elem_lonlat[], size_t npts ); - - /// @brief Compute unique positive index for a element - /// This class is a functor initialised with the nodes - class UniqueLonLat { - public: - - // UniqueLonLat() {} - - /// @brief Constructor, needs nodes functionspace to cache the lonlat field - UniqueLonLat( const mesh::Nodes& ); - - /// @brief Constructor, needs nodes functionspace to cache the lonlat field - UniqueLonLat( const Mesh& ); - - /// @brief Compute unique positive index of a node defined by node index. - /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits - uidx_t operator()( int node ) const; - - /// @brief Compute unique positive index of element defined by node indices. - /// The assumption is that the elements exist in a lon-lat domain and don't - // degenerate to a line. - /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits - uidx_t operator()( const mesh::Connectivity::Row& elem_nodes ) const; - - /// @brief Compute unique positive index of element defined by node indices. - /// The assumption is that the elements exist in a lon-lat domain and don't - // degenerate to a line. - /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits - uidx_t operator()( const int elem_nodes[], size_t npts ) const; - - /// @brief update the internally cached lonlat view if the field has changed - void update(); - private: - const mesh::Nodes* nodes; - array::ArrayView xy; - }; +/// @brief Compute unique positive index from lon-lat coordinates in +/// microdegrees +/// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits +uidx_t unique_lonlat_microdeg( const int lon, const int lat ); + +/// @brief Compute unique positive index from lon-lat coordinates in +/// microdegrees +/// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits +uidx_t unique_lonlat_microdeg( const int lonlat[] ); + +/// @brief Compute unique positive index from lon-lat coordinates in +/// microdegrees +/// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits +uidx_t unique_lonlat( const LonLatMicroDeg& ); + +/// @brief Compute unique positive index from lon-lat coordinates in degrees +/// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits +uidx_t unique_lonlat( const double& lon, const double& lat ); +uidx_t unique_lonlat( const double lonlat[] ); +uidx_t unique_lonlat( const array::LocalView& lonlat ); + +/// @brief Compute unique positive index from lon-lat coordinates in degrees. +/// coordinates are stored in order: +/// [ x1, y1, x2, y2, ... , xn, yn ] +/// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits +uidx_t unique_lonlat( const double elem_lonlat[], size_t npts ); + +/// @brief Compute unique positive index for a element +/// This class is a functor initialised with the nodes +class UniqueLonLat { +public: + // UniqueLonLat() {} + + /// @brief Constructor, needs nodes functionspace to cache the lonlat field + UniqueLonLat( const mesh::Nodes& ); + + /// @brief Constructor, needs nodes functionspace to cache the lonlat field + UniqueLonLat( const Mesh& ); + + /// @brief Compute unique positive index of a node defined by node index. + /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits + uidx_t operator()( int node ) const; + + /// @brief Compute unique positive index of element defined by node indices. + /// The assumption is that the elements exist in a lon-lat domain and don't + // degenerate to a line. + /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits + uidx_t operator()( const mesh::Connectivity::Row& elem_nodes ) const; + + /// @brief Compute unique positive index of element defined by node indices. + /// The assumption is that the elements exist in a lon-lat domain and don't + // degenerate to a line. + /// @return uidx_t Return type depends on ATLAS_BITS_GLOBAL [32/64] bits + uidx_t operator()( const int elem_nodes[], size_t npts ) const; + + /// @brief update the internally cached lonlat view if the field has changed + void update(); + +private: + const mesh::Nodes* nodes; + array::ArrayView xy; +}; // ---------------------------------------------------------------------------- @@ -96,158 +100,151 @@ namespace util { namespace detail { - /// lon and lat arguments in microdegrees - template inline T uniqueT( const int lon, const int lat ) { return uniqueT(lon,lat); } - template<> inline int uniqueT ( const int lon, const int lat ); - template<> inline long uniqueT ( const int lon, const int lat ); - - /// @brief unique32 computes 32bit positive unique id - /// max precision is 0.02 degrees - /// Numbering follows ECMWF standard grib ordering (from N-S and W-E) - inline int unique32( const int lon_microdeg, const int lat_microdeg ) - { - // Truncate microdegrees to order of degrees (16 bits), and add bits together to 32 bit int. - int iy = static_cast((180000000-lat_microdeg)*5e-5); // (2*microdeg(90.)-lat)*5e-5 - int ix = static_cast((lon_microdeg+720000000)*5e-5); // (lon+2*microdeg(360.))*5e-5 +/// lon and lat arguments in microdegrees +template +inline T uniqueT( const int lon, const int lat ) { + return uniqueT( lon, lat ); +} +template <> +inline int uniqueT( const int lon, const int lat ); +template <> +inline long uniqueT( const int lon, const int lat ); + +/// @brief unique32 computes 32bit positive unique id +/// max precision is 0.02 degrees +/// Numbering follows ECMWF standard grib ordering (from N-S and W-E) +inline int unique32( const int lon_microdeg, const int lat_microdeg ) { + // Truncate microdegrees to order of degrees (16 bits), and add bits together + // to 32 bit int. + int iy = static_cast( ( 180000000 - lat_microdeg ) * 5e-5 ); // (2*microdeg(90.)-lat)*5e-5 + int ix = static_cast( ( lon_microdeg + 720000000 ) * 5e-5 ); // (lon+2*microdeg(360.))*5e-5 iy <<= 17; int id = iy | ix; return id; - } - template<> inline int uniqueT( const int lon, const int lat ) { return unique32(lon,lat); } - - /// @brief unique64 computes 64bit positive unique id - /// max precision is 1 microdegree - /// Numbering follows ECMWF standard grib ordering (from N-S and W-E) - inline long unique64( const int lon_microdeg, const int lat_microdeg ) - { +} +template <> +inline int uniqueT( const int lon, const int lat ) { + return unique32( lon, lat ); +} + +/// @brief unique64 computes 64bit positive unique id +/// max precision is 1 microdegree +/// Numbering follows ECMWF standard grib ordering (from N-S and W-E) +inline long unique64( const int lon_microdeg, const int lat_microdeg ) { // Truncate microdegrees to (32 bits), and add bits together to 64 bit long. - long iy = 360000000l-long(lat_microdeg); // (4*microdeg(90.)-lat) - long ix = long(lon_microdeg)+1440000000l; // (lon+4*microdeg(360.)) + long iy = 360000000l - long( lat_microdeg ); // (4*microdeg(90.)-lat) + long ix = long( lon_microdeg ) + 1440000000l; // (lon+4*microdeg(360.)) iy <<= 31; long id = iy | ix; return id; - } - template<> inline long uniqueT( const int lon, const int lat ) { return unique64(lon,lat); } } - +template <> +inline long uniqueT( const int lon, const int lat ) { + return unique64( lon, lat ); +} +} // namespace detail inline uidx_t unique_lonlat_microdeg( const int lon, const int lat ) { - return detail::uniqueT( lon, lat ); + return detail::uniqueT( lon, lat ); } inline uidx_t unique_lonlat_microdeg( const int lonlat[] ) { - return detail::uniqueT( lonlat[LON], lonlat[LAT] ); + return detail::uniqueT( lonlat[LON], lonlat[LAT] ); } -inline uidx_t unique_lonlat( const LonLatMicroDeg& p ) -{ - return unique_lonlat_microdeg( p.data() ); +inline uidx_t unique_lonlat( const LonLatMicroDeg& p ) { + return unique_lonlat_microdeg( p.data() ); } inline uidx_t unique_lonlat( const double& lon, const double& lat ) { - return detail::uniqueT( microdeg(lon), microdeg(lat) ); + return detail::uniqueT( microdeg( lon ), microdeg( lat ) ); } inline uidx_t unique_lonlat( const double lonlat[] ) { - return detail::uniqueT( microdeg(lonlat[LON]), microdeg(lonlat[LAT]) ); + return detail::uniqueT( microdeg( lonlat[LON] ), microdeg( lonlat[LAT] ) ); } -inline uidx_t unique_lonlat( const array::LocalView& lonlat ) { - return unique_lonlat( lonlat.data() ); +inline uidx_t unique_lonlat( const array::LocalView& lonlat ) { + return unique_lonlat( lonlat.data() ); } - -inline uidx_t unique_lonlat( const double elem_lonlat[], size_t npts ) -{ - double centroid[2]; - centroid[LON] = 0.; - centroid[LAT] = 0.; - for( size_t jnode=0; jnode(npts); - centroid[LAT] /= static_cast(npts); - - // FIXME: this should be `unique_lonlat( centroid )` - // but this causes some weird behavior in parallelisation - return unique_lonlat( centroid[LON], centroid[LAT] ); -// return detail::unique32( microdeg(centroid[LON]), microdeg(centroid[LAT]) ); +inline uidx_t unique_lonlat( const double elem_lonlat[], size_t npts ) { + double centroid[2]; + centroid[LON] = 0.; + centroid[LAT] = 0.; + for ( size_t jnode = 0; jnode < npts; ++jnode ) { + centroid[LON] += elem_lonlat[jnode * 2 + LON]; + centroid[LAT] += elem_lonlat[jnode * 2 + LAT]; + } + centroid[LON] /= static_cast( npts ); + centroid[LAT] /= static_cast( npts ); + + // FIXME: this should be `unique_lonlat( centroid )` + // but this causes some weird behavior in parallelisation + return unique_lonlat( centroid[LON], centroid[LAT] ); + // return detail::unique32( microdeg(centroid[LON]), microdeg(centroid[LAT]) + // ); } - -inline UniqueLonLat::UniqueLonLat( const Mesh& mesh ) - : nodes(&mesh.nodes()), - xy( array::make_view ( nodes->xy() ) ) -{ - ASSERT( mesh.projection().units() == "degrees" ); - update(); +inline UniqueLonLat::UniqueLonLat( const Mesh& mesh ) : + nodes( &mesh.nodes() ), + xy( array::make_view( nodes->xy() ) ) { + ASSERT( mesh.projection().units() == "degrees" ); + update(); } -inline UniqueLonLat::UniqueLonLat( const mesh::Nodes& _nodes ) - : nodes(&_nodes), - xy( array::make_view ( nodes->xy() ) ) -{ - update(); +inline UniqueLonLat::UniqueLonLat( const mesh::Nodes& _nodes ) : + nodes( &_nodes ), + xy( array::make_view( nodes->xy() ) ) { + update(); } -inline uidx_t UniqueLonLat::operator()( int node ) const -{ - return unique_lonlat( xy(node,XX), xy(node,YY) ); +inline uidx_t UniqueLonLat::operator()( int node ) const { + return unique_lonlat( xy( node, XX ), xy( node, YY ) ); } -inline uidx_t UniqueLonLat::operator()( const mesh::Connectivity::Row& elem_nodes ) const -{ - double centroid[2]; - centroid[XX] = 0.; - centroid[YY] = 0.; - size_t npts = elem_nodes.size(); - for( size_t jnode=0; jnode(npts); - centroid[YY] /= static_cast(npts); - - // FIXME: this should be `unique_lonlat( centroid )` - // but this causes some weird behavior in parallelisation - return unique_lonlat( centroid[XX], centroid[YY] ); -// return detail::unique32( microdeg(centroid[XX]), microdeg(centroid[YY]) ); +inline uidx_t UniqueLonLat::operator()( const mesh::Connectivity::Row& elem_nodes ) const { + double centroid[2]; + centroid[XX] = 0.; + centroid[YY] = 0.; + size_t npts = elem_nodes.size(); + for ( size_t jnode = 0; jnode < npts; ++jnode ) { + centroid[XX] += xy( elem_nodes( jnode ), XX ); + centroid[YY] += xy( elem_nodes( jnode ), YY ); + } + centroid[XX] /= static_cast( npts ); + centroid[YY] /= static_cast( npts ); + + // FIXME: this should be `unique_lonlat( centroid )` + // but this causes some weird behavior in parallelisation + return unique_lonlat( centroid[XX], centroid[YY] ); + // return detail::unique32( microdeg(centroid[XX]), microdeg(centroid[YY]) ); } - - -inline uidx_t UniqueLonLat::operator()( const int elem_nodes[], size_t npts ) const -{ - double centroid[2]; - centroid[XX] = 0.; - centroid[YY] = 0.; - for( size_t jnode=0; jnode(npts); - centroid[YY] /= static_cast(npts); - - // FIXME: this should be `unique_lonlat( centroid )` - // but this causes some weird behavior in parallelisation - - return unique_lonlat( centroid[XX], centroid[YY] ); -// return detail::unique32( microdeg(centroid[XX]), microdeg(centroid[YY]) ); +inline uidx_t UniqueLonLat::operator()( const int elem_nodes[], size_t npts ) const { + double centroid[2]; + centroid[XX] = 0.; + centroid[YY] = 0.; + for ( size_t jnode = 0; jnode < npts; ++jnode ) { + centroid[XX] += xy( elem_nodes[jnode], XX ); + centroid[YY] += xy( elem_nodes[jnode], YY ); + } + centroid[XX] /= static_cast( npts ); + centroid[YY] /= static_cast( npts ); + + // FIXME: this should be `unique_lonlat( centroid )` + // but this causes some weird behavior in parallelisation + + return unique_lonlat( centroid[XX], centroid[YY] ); + // return detail::unique32( microdeg(centroid[XX]), microdeg(centroid[YY]) ); } - - -inline void UniqueLonLat::update() -{ - xy = array::make_view ( nodes->xy() ); +inline void UniqueLonLat::update() { + xy = array::make_view( nodes->xy() ); } // ---------------------------------------------------------------------------- -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/detail/BlackMagic.h b/src/atlas/util/detail/BlackMagic.h index 651804430..9105643fd 100644 --- a/src/atlas/util/detail/BlackMagic.h +++ b/src/atlas/util/detail/BlackMagic.h @@ -7,12 +7,12 @@ // Public /// Returns the number of passed arguments -#define __ATLAS_NARG(...) +#define __ATLAS_NARG( ... ) /// Splice a and b together -#define __ATLAS_SPLICE(a,b) +#define __ATLAS_SPLICE( a, b ) -#define __ATLAS_STRINGIFY(a) a +#define __ATLAS_STRINGIFY( a ) a #define __ATLAS_TYPE( Type, ... ) #define __ATLAS_TYPE_SCOPE( Type, ... ) @@ -27,53 +27,63 @@ #undef __ATLAS_TYPE_SCOPE #define __ATLAS_REVERSE 5, 4, 3, 2, 1, 0 -#define __ATLAS_ARGN(_1, _2, _3, _4, _5, N, ...) N -#define __ATLAS_NARG__(dummy, ...) __ATLAS_ARGN(__VA_ARGS__) -#define __ATLAS_NARG_(...) __ATLAS_NARG__(dummy, ##__VA_ARGS__, __ATLAS_REVERSE) -#define __ATLAS_SPLICE(a,b) __ATLAS_SPLICE_1(a,b) -#define __ATLAS_SPLICE_1(a,b) __ATLAS_SPLICE_2(a,b) -#define __ATLAS_SPLICE_2(a,b) a##b - - -#define __ATLAS_ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) _15 -#define __ATLAS_HAS_COMMA(...) __ATLAS_ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) -#define __ATLAS_TRIGGER_PARENTHESIS(...) , -#define __ATLAS_ISEMPTY(...) \ -__ATLAS_ISEMPTY_( \ - /* test if there is just one argument, eventually an empty one */ \ - __ATLAS_HAS_COMMA(__VA_ARGS__), \ - /* test if _TRIGGER_PARENTHESIS_ together with the argument adds a comma */ \ - __ATLAS_HAS_COMMA(__ATLAS_TRIGGER_PARENTHESIS __VA_ARGS__), \ - /* test if the argument together with a parenthesis adds a comma */ \ - __ATLAS_HAS_COMMA(__VA_ARGS__ (/*empty*/)), \ - /* test if placing it between __ATLAS_TRIGGER_PARENTHESIS and the parenthesis adds a comma */ \ - __ATLAS_HAS_COMMA(__ATLAS_TRIGGER_PARENTHESIS __VA_ARGS__ (/*empty*/)) \ -) - -#define __ATLAS_PASTE5(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4 -#define __ATLAS_ISEMPTY_(_0, _1, _2, _3) __ATLAS_HAS_COMMA(__ATLAS_PASTE5(__ATLAS_IS_EMPTY_CASE_, _0, _1, _2, _3)) +#define __ATLAS_ARGN( _1, _2, _3, _4, _5, N, ... ) N +#define __ATLAS_NARG__( dummy, ... ) __ATLAS_ARGN( __VA_ARGS__ ) +#define __ATLAS_NARG_( ... ) __ATLAS_NARG__( dummy, ##__VA_ARGS__, __ATLAS_REVERSE ) +#define __ATLAS_SPLICE( a, b ) __ATLAS_SPLICE_1( a, b ) +#define __ATLAS_SPLICE_1( a, b ) __ATLAS_SPLICE_2( a, b ) +#define __ATLAS_SPLICE_2( a, b ) a##b + +#define __ATLAS_ARG16( _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ... ) _15 +#define __ATLAS_HAS_COMMA( ... ) __ATLAS_ARG16( __VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 ) +#define __ATLAS_TRIGGER_PARENTHESIS( ... ) , +#define __ATLAS_ISEMPTY( ... ) \ + __ATLAS_ISEMPTY_( /* test if there is just one argument, eventually an empty \ + one */ \ + __ATLAS_HAS_COMMA( __VA_ARGS__ ), /* test if \ + _TRIGGER_PARENTHESIS_ \ + together with the \ + argument adds a comma */ \ + __ATLAS_HAS_COMMA( \ + __ATLAS_TRIGGER_PARENTHESIS __VA_ARGS__ ), /* test if the argument together with \ + a parenthesis adds a comma */ \ + __ATLAS_HAS_COMMA( __VA_ARGS__( /*empty*/ ) ), /* test if placing it between \ + __ATLAS_TRIGGER_PARENTHESIS and the \ + parenthesis adds a comma */ \ + __ATLAS_HAS_COMMA( __ATLAS_TRIGGER_PARENTHESIS __VA_ARGS__( /*empty*/ ) ) ) + +#define __ATLAS_PASTE5( _0, _1, _2, _3, _4 ) _0##_1##_2##_3##_4 +#define __ATLAS_ISEMPTY_( _0, _1, _2, _3 ) __ATLAS_HAS_COMMA( __ATLAS_PASTE5( __ATLAS_IS_EMPTY_CASE_, _0, _1, _2, _3 ) ) #define __ATLAS_IS_EMPTY_CASE_0001 , -#define __ATLAS_NARG(...) __ATLAS_SPLICE( __ATLAS_CALL_NARG_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) (__VA_ARGS__) -#define __ATLAS_CALL_NARG_1(...) 0 +#define __ATLAS_NARG( ... ) __ATLAS_SPLICE( __ATLAS_CALL_NARG_, __ATLAS_ISEMPTY( __VA_ARGS__ ) )( __VA_ARGS__ ) +#define __ATLAS_CALL_NARG_1( ... ) 0 #define __ATLAS_CALL_NARG_0 __ATLAS_NARG_ -#define __ATLAS_COMMA_ARGS(...) __ATLAS_SPLICE( __ATLAS_COMMA_ARGS_, __ATLAS_ISEMPTY(__VA_ARGS__) ) (__VA_ARGS__) -#define __ATLAS_COMMA_ARGS_1(...) -#define __ATLAS_COMMA_ARGS_0(...) , __VA_ARGS__ - -#define __ATLAS_ARGS_OR_DUMMY(...) __ATLAS_SPLICE( __ATLAS_ARGS_OR_DUMMY_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) ( __VA_ARGS__) -#define __ATLAS_ARGS_OR_DUMMY_0(...) __VA_ARGS__ -#define __ATLAS_ARGS_OR_DUMMY_1(...) 0 - -#define __ATLAS_TYPE(Type,...) __ATLAS_SPLICE( __ATLAS_TYPE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) ( Type, __ATLAS_ARGS_OR_DUMMY(__VA_ARGS__) ) -#define __ATLAS_TYPE_1( Type, dummy ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) -#define __ATLAS_TYPE_0( Type, ... ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) (__VA_ARGS__) - -#define __ATLAS_TYPE_SCOPE(Type,...) __ATLAS_SPLICE( __ATLAS_TYPE_SCOPE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) ( Type, __ATLAS_ARGS_OR_DUMMY(__VA_ARGS__) ) -#define __ATLAS_TYPE_SCOPE_1( Type, ... ) \ - for( bool __ATLAS_SPLICE( __done_, __LINE__ )=false; __ATLAS_SPLICE( __done_, __LINE__ )!=true; ) \ - for( Type __ATLAS_SPLICE( __variable_, __LINE__ ); __ATLAS_SPLICE( __done_, __LINE__ )!=true; __ATLAS_SPLICE( __done_, __LINE__ )=true ) -#define __ATLAS_TYPE_SCOPE_0( Type, ... ) \ - for( bool __ATLAS_SPLICE( __done_, __LINE__ )=false; __ATLAS_SPLICE( __done_, __LINE__ )!=true; ) \ - for( Type __ATLAS_SPLICE( __variable_, __LINE__ )(__VA_ARGS__); __ATLAS_SPLICE( __done_, __LINE__ )!=true; __ATLAS_SPLICE( __done_, __LINE__ )=true ) +#define __ATLAS_COMMA_ARGS( ... ) __ATLAS_SPLICE( __ATLAS_COMMA_ARGS_, __ATLAS_ISEMPTY( __VA_ARGS__ ) )( __VA_ARGS__ ) +#define __ATLAS_COMMA_ARGS_1( ... ) +#define __ATLAS_COMMA_ARGS_0( ... ) , __VA_ARGS__ + +#define __ATLAS_ARGS_OR_DUMMY( ... ) \ + __ATLAS_SPLICE( __ATLAS_ARGS_OR_DUMMY_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) \ + ( __VA_ARGS__ ) +#define __ATLAS_ARGS_OR_DUMMY_0( ... ) __VA_ARGS__ +#define __ATLAS_ARGS_OR_DUMMY_1( ... ) 0 + +#define __ATLAS_TYPE( Type, ... ) \ + __ATLAS_SPLICE( __ATLAS_TYPE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) \ + ( Type, __ATLAS_ARGS_OR_DUMMY( __VA_ARGS__ ) ) +#define __ATLAS_TYPE_1( Type, dummy ) Type __ATLAS_SPLICE( __variable_, __LINE__ ) +#define __ATLAS_TYPE_0( Type, ... ) Type __ATLAS_SPLICE( __variable_, __LINE__ )( __VA_ARGS__ ) + +#define __ATLAS_TYPE_SCOPE( Type, ... ) \ + __ATLAS_SPLICE( __ATLAS_TYPE_SCOPE_, __ATLAS_ISEMPTY( __VA_ARGS__ ) ) \ + ( Type, __ATLAS_ARGS_OR_DUMMY( __VA_ARGS__ ) ) +#define __ATLAS_TYPE_SCOPE_1( Type, ... ) \ + for ( bool __ATLAS_SPLICE( __done_, __LINE__ ) = false; __ATLAS_SPLICE( __done_, __LINE__ ) != true; ) \ + for ( Type __ATLAS_SPLICE( __variable_, __LINE__ ); __ATLAS_SPLICE( __done_, __LINE__ ) != true; \ + __ATLAS_SPLICE( __done_, __LINE__ ) = true ) +#define __ATLAS_TYPE_SCOPE_0( Type, ... ) \ + for ( bool __ATLAS_SPLICE( __done_, __LINE__ ) = false; __ATLAS_SPLICE( __done_, __LINE__ ) != true; ) \ + for ( Type __ATLAS_SPLICE( __variable_, __LINE__ )( __VA_ARGS__ ); \ + __ATLAS_SPLICE( __done_, __LINE__ ) != true; __ATLAS_SPLICE( __done_, __LINE__ ) = true ) diff --git a/src/atlas/util/detail/Cache.h b/src/atlas/util/detail/Cache.h index 8657d2779..63ae07dea 100644 --- a/src/atlas/util/detail/Cache.h +++ b/src/atlas/util/detail/Cache.h @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -12,8 +13,8 @@ #include #include #include -#include "eckit/memory/SharedPtr.h" #include "atlas/runtime/Log.h" +#include "eckit/memory/SharedPtr.h" namespace atlas { namespace util { @@ -21,44 +22,48 @@ namespace util { template class Cache { public: - using key_type = Key; - using value_type = Value; - using creator_type = std::function; + using key_type = Key; + using value_type = Value; + using creator_type = std::function; - Cache(const std::string& name) : name_(name) {} + Cache( const std::string& name ) : name_( name ) {} - eckit::SharedPtr get_or_create(const key_type& key, const creator_type& creator) { - std::lock_guard guard(lock_); - auto it = map_.find(key); - if (it != map_.end()) { - eckit::SharedPtr value = it->second; - if( value ) { - Log::debug() << "Key \"" << key << "\" was found in cache \""< get_or_create( const key_type& key, const creator_type& creator ) { + std::lock_guard guard( lock_ ); + auto it = map_.find( key ); + if ( it != map_.end() ) { + eckit::SharedPtr value = it->second; + if ( value ) { + Log::debug() << "Key \"" << key << "\" was found in cache \"" << name_ << "\"" << std::endl; + return value; + } + else { + Log::debug() << "Key \"" << key << "\" was found in cache \"" << name_ + << "\" but is not valid. Revert to not found." << std::endl; + } + } + Log::debug() << "Key \"" << key << "\" not found in cache \"" << name_ << "\" , creating new" << std::endl; + eckit::SharedPtr value( creator() ); + map_[key] = value; return value; - } else { - Log::debug() << "Key \"" << key << "\" was found in cache \""< value( creator() ); - map_[key] = value; - return value; - } - void remove(const key_type& key) { - std::lock_guard guard(lock_); - if( map_.erase(key) ) { - Log::debug() << "Erased key \"" << key << "\" from cache \""< guard( lock_ ); + if ( map_.erase( key ) ) { + Log::debug() << "Erased key \"" << key << "\" from cache \"" << name_ << "\"." << std::endl; + } + else { + Log::debug() << "Tried to erase key \"" << key << "\" from cache \"" << name_ << "\" but it was not found." + << std::endl; + } } - } private: - std::string name_; - std::mutex lock_; - std::map< key_type, eckit::SharedPtr > map_; + std::string name_; + std::mutex lock_; + std::map> map_; }; -} // namespace util -} // namespace atlas +} // namespace util +} // namespace atlas diff --git a/src/atlas/util/detail/Debug.h b/src/atlas/util/detail/Debug.h index 72a31c423..b6d67017a 100644 --- a/src/atlas/util/detail/Debug.h +++ b/src/atlas/util/detail/Debug.h @@ -1,104 +1,106 @@ -#include "eckit/config/Resource.h" -#include "atlas/mesh.h" #include "atlas/field.h" #include "atlas/functionspace.h" +#include "atlas/mesh.h" #include "atlas/parallel/mpi/mpi.h" +#include "eckit/config/Resource.h" namespace atlas { namespace debug { -inline gidx_t node_global_index(int i=0) { - static std::vector g = eckit::Resource>("$ATLAS_DEBUG_NODE_GLOBAL_INDEX", std::vector{-1} ); - return g[i]; +inline gidx_t node_global_index( int i = 0 ) { + static std::vector g = + eckit::Resource>( "$ATLAS_DEBUG_NODE_GLOBAL_INDEX", std::vector{-1} ); + return g[i]; } -inline gidx_t edge_global_index(int i=0) { - static std::vector g = eckit::Resource>("$ATLAS_DEBUG_EDGE_GLOBAL_INDEX", std::vector{-1} ); - return g[i]; +inline gidx_t edge_global_index( int i = 0 ) { + static std::vector g = + eckit::Resource>( "$ATLAS_DEBUG_EDGE_GLOBAL_INDEX", std::vector{-1} ); + return g[i]; } -inline gidx_t cell_global_index(int i=0) { - static std::vector g = eckit::Resource>("$ATLAS_DEBUG_CELL_GLOBAL_INDEX", std::vector{-1} ); - return g[i]; +inline gidx_t cell_global_index( int i = 0 ) { + static std::vector g = + eckit::Resource>( "$ATLAS_DEBUG_CELL_GLOBAL_INDEX", std::vector{-1} ); + return g[i]; } -inline gidx_t node_uid(int i=0) { - static std::vector g = eckit::Resource>("$ATLAS_DEBUG_NODE_UID", std::vector{-1} ); - return g[i]; +inline gidx_t node_uid( int i = 0 ) { + static std::vector g = + eckit::Resource>( "$ATLAS_DEBUG_NODE_UID", std::vector{-1} ); + return g[i]; } 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; - } - return false; + static std::vector v = + eckit::Resource>( "$ATLAS_DEBUG_NODE_GLOBAL_INDEX", std::vector() ); + for ( gidx_t g : v ) { + if ( x == g ) return true; + } + return false; } 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; - } - return false; + static std::vector v = + eckit::Resource>( "$ATLAS_DEBUG_EDGE_GLOBAL_INDEX", std::vector() ); + for ( gidx_t g : v ) { + if ( x == g ) return true; + } + return false; } 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; - } - return false; + static std::vector v = + eckit::Resource>( "$ATLAS_DEBUG_CELL_GLOBAL_INDEX", std::vector() ); + for ( gidx_t g : v ) { + if ( x == g ) return true; + } + return false; } 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; - } - return false; + static std::vector v = + eckit::Resource>( "$ATLAS_DEBUG_NODE_UID", std::vector() ); + for ( gidx_t g : v ) { + if ( x == g ) return true; + } + return false; } 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; - } - return false; + static std::vector v = + eckit::Resource>( "$ATLAS_DEBUG_CELL_UID", std::vector() ); + for ( gidx_t g : v ) { + if ( x == g ) return true; + } + return false; } -inline int mpi_rank(int i=0) { - static std::vector g = eckit::Resource>("$ATLAS_DEBUG_MPI_RANK", std::vector{-1} ); - return g[i]; +inline int mpi_rank( int i = 0 ) { + static std::vector g = eckit::Resource>( "$ATLAS_DEBUG_MPI_RANK", std::vector{-1} ); + return g[i]; } 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; - } - return false; + 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; + } + return false; } -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; - } - return false; +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; + } + return false; } inline std::string rank_str() { - static std::string s = "["+std::to_string(mpi::comm().rank())+"] "; - return s; + static std::string s = "[" + std::to_string( mpi::comm().rank() ) + "] "; + return s; } -} -} +} // namespace debug +} // namespace atlas diff --git a/src/atlas_acc_support/atlas_acc_map_data.h b/src/atlas_acc_support/atlas_acc_map_data.h index f0d1f2168..892ebc774 100644 --- a/src/atlas_acc_support/atlas_acc_map_data.h +++ b/src/atlas_acc_support/atlas_acc_map_data.h @@ -4,7 +4,7 @@ extern "C" { #endif -void atlas_acc_map_data(void* cpu_ptr, void* gpu_ptr, unsigned long size); +void atlas_acc_map_data( void* cpu_ptr, void* gpu_ptr, unsigned long size ); #ifdef __cplusplus } diff --git a/src/atlas_f/internals/Library.cc b/src/atlas_f/internals/Library.cc index 9530d37bd..c311493de 100644 --- a/src/atlas_f/internals/Library.cc +++ b/src/atlas_f/internals/Library.cc @@ -4,57 +4,44 @@ //---------------------------------------------------------------------------------------------------------------------- extern "C" { -void atlas__atlas_init_noargs() -{ - atlas::Library::instance().initialise(); +void atlas__atlas_init_noargs() { + atlas::Library::instance().initialise(); } - -void atlas__atlas_finalize() -{ - atlas::Library::instance().finalise(); +void atlas__atlas_finalize() { + atlas::Library::instance().finalise(); } - -const char* atlas__eckit_version() -{ - return eckit_version(); +const char* atlas__eckit_version() { + return eckit_version(); } - -const char* atlas__eckit_git_sha1() -{ - return eckit_git_sha1(); +const char* atlas__eckit_git_sha1() { + return eckit_git_sha1(); } - -const char* atlas__eckit_git_sha1_abbrev(int length) -{ - static std::string git_sha1(eckit_git_sha1()); - if( git_sha1.empty() ) git_sha1 = "not available"; - else git_sha1 = git_sha1.substr(0,std::min(length,40)); - return git_sha1.c_str(); +const char* atlas__eckit_git_sha1_abbrev( int length ) { + static std::string git_sha1( eckit_git_sha1() ); + if ( git_sha1.empty() ) + git_sha1 = "not available"; + else + git_sha1 = git_sha1.substr( 0, std::min( length, 40 ) ); + return git_sha1.c_str(); } - -const char* atlas__atlas_version() -{ - static std::string str = atlas::Library::instance().version(); - return str.c_str(); +const char* atlas__atlas_version() { + static std::string str = atlas::Library::instance().version(); + return str.c_str(); } - -const char* atlas__atlas_git_sha1() -{ - static std::string str = atlas::Library::instance().gitsha1(); - return str.c_str(); +const char* atlas__atlas_git_sha1() { + static std::string str = atlas::Library::instance().gitsha1(); + return str.c_str(); } - -const char* atlas__atlas_git_sha1_abbrev(int length) -{ - static std::string s = atlas::Library::instance().gitsha1(length); - return s.c_str(); +const char* atlas__atlas_git_sha1_abbrev( int length ) { + static std::string s = atlas::Library::instance().gitsha1( length ); + return s.c_str(); } -} // extern "C" +} // extern "C" diff --git a/src/atlas_f/internals/Library.h b/src/atlas_f/internals/Library.h index 9029a16b1..674ca80ce 100644 --- a/src/atlas_f/internals/Library.h +++ b/src/atlas_f/internals/Library.h @@ -1,14 +1,13 @@ #pragma once // C wrapper interfaces to C++ routines -extern "C" -{ - void atlas__atlas_init_noargs(); - void atlas__atlas_finalize (); - const char* atlas__eckit_version(); - const char* atlas__eckit_git_sha1(); - const char* atlas__eckit_git_sha1_abbrev (int length); - const char* atlas__atlas_version(); - const char* atlas__atlas_git_sha1(); - const char* atlas__atlas_git_sha1_abbrev (int length); +extern "C" { +void atlas__atlas_init_noargs(); +void atlas__atlas_finalize(); +const char* atlas__eckit_version(); +const char* atlas__eckit_git_sha1(); +const char* atlas__eckit_git_sha1_abbrev( int length ); +const char* atlas__atlas_version(); +const char* atlas__atlas_git_sha1(); +const char* atlas__atlas_git_sha1_abbrev( int length ); } diff --git a/src/atlas_f/internals/atlas_read_file.cc b/src/atlas_f/internals/atlas_read_file.cc index 6c704363f..e89b7e82a 100644 --- a/src/atlas_f/internals/atlas_read_file.cc +++ b/src/atlas_f/internals/atlas_read_file.cc @@ -1,68 +1,51 @@ -#include "eckit/runtime/Main.h" -#include "eckit/filesystem/PathName.h" #include "eckit/exception/Exceptions.h" +#include "eckit/filesystem/PathName.h" +#include "eckit/runtime/Main.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas_f/internals/atlas_read_file.h" namespace atlas { -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 eckit::CantOpenFile(p.asString(),Here()); +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 eckit::CantOpenFile( p.asString(), Here() ); } + else { + out << in.rdbuf(); + in.close(); + } } - else - { - out << in.rdbuf(); - in.close(); - } - } } -} +} // namespace atlas -extern "C" -{ +extern "C" { //----------------------------------------------------------------------------- -int atlas__read_file( const char* path, char* &content, int& size ) -{ - - ATLAS_ERROR_HANDLING( +int atlas__read_file( const char* path, char*& content, int& size ) { + ATLAS_ERROR_HANDLING( - // eckit::FileReadPolicy p = eckit::Main::instance().behavior().fileReadPolicy(); + // eckit::FileReadPolicy p = + // eckit::Main::instance().behavior().fileReadPolicy(); - // std::stringstream ss; + // std::stringstream ss; - // if( read( p, path, ss ) ) - // { - // std::string s = ss.str(); - // size = s.size()+1; - // content = new char[size]; - // strcpy(content,s.c_str()); - // return true; - // } + // if( read( p, path, ss ) ) + // { + // std::string s = ss.str(); + // size = s.size()+1; + // content = new char[size]; + // strcpy(content,s.c_str()); + // return true; + // } - std::stringstream ss; - atlas::read_file(path,ss); - std::string s = ss.str(); - size = s.size()+1; - content = new char[size]; - strcpy(content,s.c_str()); - return true; - ); - return false; + std::stringstream ss; atlas::read_file( path, ss ); std::string s = ss.str(); size = s.size() + 1; + content = new char[size]; strcpy( content, s.c_str() ); return true; ); + return false; } //----------------------------------------------------------------------------- - } - diff --git a/src/atlas_f/internals/atlas_read_file.h b/src/atlas_f/internals/atlas_read_file.h index 587a7899a..77b9f2037 100644 --- a/src/atlas_f/internals/atlas_read_file.h +++ b/src/atlas_f/internals/atlas_read_file.h @@ -1,8 +1,7 @@ #define Char char -extern "C" -{ -int atlas__read_file (const char* path, Char* &content, int &size); +extern "C" { +int atlas__read_file( const char* path, Char*& content, int& size ); } #undef Char diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc index ff0cf6624..120b4cca8 100644 --- a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -4,33 +4,34 @@ * 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 + * 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 -#include -#include +#include #include +#include +#include +#include +#include +#include #include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" #include "atlas/grid.h" -#include "atlas/meshgenerator.h" #include "atlas/mesh.h" +#include "atlas/mesh/actions/BuildHalo.h" +#include "atlas/meshgenerator.h" +#include "atlas/output/detail/GmshIO.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/AtlasTool.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "atlas/parallel/mpi/mpi.h" #include "atlas/util/Config.h" -#include "atlas/output/detail/GmshIO.h" -#include "atlas/mesh/actions/BuildHalo.h" //------------------------------------------------------------------------------ @@ -42,85 +43,75 @@ using eckit::PathName; //------------------------------------------------------------------------------ class Tool : public AtlasTool { - - virtual void execute(const Args& args); - virtual std::string briefDescription() { - return "Tool to generate a python script that plots the grid-distribution of a given grid"; - } - virtual std::string usage() { - return name() + " --grid=name [OPTION]... OUTPUT [--help]"; - } + virtual void execute( const Args& args ); + virtual std::string briefDescription() { + return "Tool to generate a python script that plots the grid-distribution " + "of a given grid"; + } + virtual std::string usage() { return name() + " --grid=name [OPTION]... OUTPUT [--help]"; } public: - - Tool(int argc,char **argv); + Tool( int argc, char** argv ); private: - - std::string key; - PathName path_in; - PathName path_out; - + std::string key; + PathName path_in; + PathName path_out; }; //----------------------------------------------------------------------------- -Tool::Tool(int argc,char **argv): AtlasTool(argc,argv) -{ - add_option( new SimpleOption("grid","Grid unique identifier\n" - +indent()+" Example values: N80, F40, O24, L32") ); - add_option( new SimpleOption("halo","Number of halos (default=1") ); +Tool::Tool( int argc, char** argv ) : AtlasTool( argc, argv ) { + add_option( new SimpleOption( + "grid", "Grid unique identifier\n" + indent() + " Example values: N80, F40, O24, L32" ) ); + add_option( new SimpleOption( "halo", "Number of halos (default=1" ) ); } //----------------------------------------------------------------------------- -void Tool::execute(const Args& args) -{ - Trace timer(Here(), displayName() ); - key = ""; - args.get("grid",key); - - std::string path_in_str = ""; - if( args.get("grid",path_in_str) ) path_in = path_in_str; - - StructuredGrid grid; - if( key.size() ) - { - try{ grid = Grid(key); } - catch( eckit::BadParameter& e ){} - } - else - { - Log::error() << "No grid specified." << std::endl; - } - - - if( !grid ) return; - - Log::debug() << "Domain: " << grid.domain() << std::endl; - Log::debug() << "Periodic: " << grid.periodic() << std::endl; - - MeshGenerator meshgenerator("structured", util::Config("partitioner","equal_regions")); - - size_t halo = args.getLong("halo",1); - - size_t iterations = 1; - for( size_t i=0; i #include -#include -#include -#include #include -#include -#include +#include #include +#include +#include +#include +#include +#include #include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" #include "atlas/grid.h" -#include "atlas/meshgenerator.h" #include "atlas/mesh.h" +#include "atlas/mesh/actions/BuildHalo.h" +#include "atlas/mesh/actions/BuildParallelFields.h" +#include "atlas/mesh/actions/BuildPeriodicBoundaries.h" +#include "atlas/meshgenerator.h" +#include "atlas/output/detail/GmshIO.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/AtlasTool.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "atlas/parallel/mpi/mpi.h" #include "atlas/util/Config.h" -#include "atlas/output/detail/GmshIO.h" -#include "atlas/mesh/actions/BuildHalo.h" -#include "atlas/mesh/actions/BuildParallelFields.h" -#include "atlas/mesh/actions/BuildPeriodicBoundaries.h" - +#include "atlas/array.h" #include "atlas/field/Field.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Unique.h" -#include "atlas/array.h" using Topology = atlas::mesh::Nodes::Topology; using atlas::util::UniqueLonLat; @@ -53,242 +53,216 @@ using eckit::PathName; //------------------------------------------------------------------------------ namespace atlas { - -struct Node -{ - Node(gidx_t gid, int idx) - { - g = gid; - i = idx; - } - gidx_t g; - gidx_t i; - bool operator < (const Node& other) const - { - return ( g Those specific periodic points at the EAST boundary are not checked for uid, -// and could receive different gidx for different tasks - - UniqueLonLat compute_uid(nodes); - - // unused // int mypart = mpi::comm().rank(); - int nparts = mpi::comm().size(); - size_t root = 0; - - array::ArrayView nodes_glb_idx = array::make_view ( nodes.global_index() ); - //nodes_glb_idx.dump( Log::info() ); - Log::info() << std::endl; - Log::info() << "min = " << nodes.global_index().metadata().getLong("min") << std::endl; - Log::info() << "max = " << nodes.global_index().metadata().getLong("max") << std::endl; - Log::info() << "human_readable = " << nodes.global_index().metadata().getBool("human_readable") << std::endl; - gidx_t glb_idx_max = 0; - - std::vector points_to_edit; - - if( do_all ) { - points_to_edit.resize(nodes_glb_idx.size()); - for( size_t i=0; i glb_idx(points_to_edit.size()); - for( size_t i=0; i recvcounts(mpi::comm().size()); - std::vector recvdispls(mpi::comm().size()); - - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gather(nb_nodes, recvcounts, root); - } - - recvdispls[0]=0; - for (int jpart=1; jpart glb_idx_gathered( glb_nb_nodes ); - ATLAS_TRACE_MPI( GATHER ) { - mpi::comm().gatherv(glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), root); - } - - - // 2) Sort all global indices, and renumber from 1 to glb_nb_edges - std::vector node_sort; node_sort.reserve(glb_nb_nodes); - for( size_t jnode=0; jnode Those specific periodic points at the EAST boundary are not checked for + // uid, + // and could receive different gidx for different tasks + + UniqueLonLat compute_uid( nodes ); + + // unused // int mypart = mpi::comm().rank(); + int nparts = mpi::comm().size(); + size_t root = 0; + + array::ArrayView nodes_glb_idx = array::make_view( nodes.global_index() ); + // nodes_glb_idx.dump( Log::info() ); + Log::info() << std::endl; + Log::info() << "min = " << nodes.global_index().metadata().getLong( "min" ) << std::endl; + Log::info() << "max = " << nodes.global_index().metadata().getLong( "max" ) << std::endl; + Log::info() << "human_readable = " << nodes.global_index().metadata().getBool( "human_readable" ) << std::endl; + gidx_t glb_idx_max = 0; + + std::vector points_to_edit; + + if ( do_all ) { + points_to_edit.resize( nodes_glb_idx.size() ); + for ( size_t i = 0; i < nodes_glb_idx.size(); ++i ) + points_to_edit[i] = i; } - else if( node_sort[jnode].g != node_sort[jnode-1].g ) + 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 ) + 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 ) + glb_idx[i] = nodes_glb_idx( i ); + + ATLAS_DEBUG_VAR( points_to_edit ); + ATLAS_DEBUG_VAR( points_to_edit.size() ); + + ATLAS_TRACE( "distributed_sort" ); + + /* + * Sorting following gidx will define global order of + * gathered fields. Special care needs to be taken for + * pole edges, as their centroid might coincide with + * other edges + */ + int nb_nodes = glb_idx.size(); + + // 1) Gather all global indices, together with location + + std::vector recvcounts( mpi::comm().size() ); + std::vector recvdispls( mpi::comm().size() ); + + ATLAS_TRACE_MPI( GATHER ) { mpi::comm().gather( nb_nodes, recvcounts, root ); } + + recvdispls[0] = 0; + for ( int jpart = 1; jpart < nparts; ++jpart ) // start at 1 { - ++gid; + recvdispls[jpart] = recvcounts[jpart - 1] + recvdispls[jpart - 1]; } - int inode = node_sort[jnode].i; - glb_idx_gathered[inode] = gid; - } + int glb_nb_nodes = std::accumulate( recvcounts.begin(), recvcounts.end(), 0 ); - // 3) Scatter renumbered back - ATLAS_TRACE_MPI( SCATTER ) { - mpi::comm().scatterv(glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), glb_idx.size(), root); - } + std::vector glb_idx_gathered( glb_nb_nodes ); + ATLAS_TRACE_MPI( GATHER ) { + mpi::comm().gatherv( glb_idx.data(), glb_idx.size(), glb_idx_gathered.data(), recvcounts.data(), + recvdispls.data(), root ); + } - for( int jnode=0; jnode node_sort; + node_sort.reserve( glb_nb_nodes ); + for ( size_t jnode = 0; jnode < glb_idx_gathered.size(); ++jnode ) { + node_sort.push_back( Node( glb_idx_gathered[jnode], jnode ) ); + } - //nodes_glb_idx.dump( Log::info() ); - //Log::info() << std::endl; + ATLAS_TRACE_SCOPE( "local_sort" ) { std::sort( node_sort.begin(), node_sort.end() ); } + gidx_t gid = glb_idx_max; + for ( size_t jnode = 0; jnode < node_sort.size(); ++jnode ) { + if ( jnode == 0 ) { ++gid; } + else if ( node_sort[jnode].g != node_sort[jnode - 1].g ) { + ++gid; + } + int inode = node_sort[jnode].i; + glb_idx_gathered[inode] = gid; + } -} + // 3) Scatter renumbered back + ATLAS_TRACE_MPI( SCATTER ) { + mpi::comm().scatterv( glb_idx_gathered.data(), recvcounts.data(), recvdispls.data(), glb_idx.data(), + glb_idx.size(), root ); + } + for ( int jnode = 0; jnode < nb_nodes; ++jnode ) { + nodes_glb_idx( points_to_edit[jnode] ) = glb_idx[jnode]; + } + + // nodes_glb_idx.dump( Log::info() ); + // Log::info() << std::endl; } + +} // namespace atlas //----------------------------------------------------------------------------- class Tool : public AtlasTool { - - virtual void execute(const Args& args); - virtual std::string briefDescription() { - return "Tool to generate a python script that plots the grid-distribution of a given grid"; - } - virtual std::string usage() { - return name() + " (--grid=name) [--help]"; - } + virtual void execute( const Args& args ); + virtual std::string briefDescription() { + return "Tool to generate a python script that plots the grid-distribution " + "of a given grid"; + } + virtual std::string usage() { return name() + " (--grid=name) [--help]"; } public: - - Tool(int argc,char **argv); + Tool( int argc, char** argv ); private: - - std::string key; - PathName path_in; - PathName path_out; - + std::string key; + PathName path_in; + PathName path_out; }; //----------------------------------------------------------------------------- -Tool::Tool(int argc,char **argv): AtlasTool(argc,argv) -{ - add_option( new SimpleOption("grid","Grid unique identifier\n" - +indent()+" Example values: N80, F40, O24, L32") ); - add_option( new SimpleOption("halo","size of halo" ) ); - add_option( new SimpleOption("do-all","Renumber all points" ) ); +Tool::Tool( int argc, char** argv ) : AtlasTool( argc, argv ) { + add_option( new SimpleOption( + "grid", "Grid unique identifier\n" + indent() + " Example values: N80, F40, O24, L32" ) ); + add_option( new SimpleOption( "halo", "size of halo" ) ); + add_option( new SimpleOption( "do-all", "Renumber all points" ) ); } //----------------------------------------------------------------------------- -void Tool::execute(const Args& args) -{ - Trace t( Here(), "main"); +void Tool::execute( const Args& args ) { + Trace t( Here(), "main" ); - key = ""; - args.get("grid",key); + key = ""; + args.get( "grid", key ); - std::string path_in_str = ""; - if( args.get("grid",path_in_str) ) path_in = path_in_str; + std::string path_in_str = ""; + if ( args.get( "grid", path_in_str ) ) path_in = path_in_str; - StructuredGrid grid; - if( key.size() ) - { - try{ grid = Grid(key); } - catch( eckit::BadParameter& e ){} - } - else - { - Log::error() << "No grid specified." << std::endl; - } + StructuredGrid grid; + if ( key.size() ) { + try { + grid = Grid( key ); + } + catch ( eckit::BadParameter& e ) { + } + } + else { + Log::error() << "No grid specified." << std::endl; + } - if( !grid ) return; + if ( !grid ) return; - Log::debug() << "Domain: " << grid.domain() << std::endl; - Log::debug() << "Periodic: " << grid.periodic() << std::endl; + Log::debug() << "Domain: " << grid.domain() << std::endl; + Log::debug() << "Periodic: " << grid.periodic() << std::endl; - MeshGenerator meshgenerator("structured", Config("partitioner","equal_regions") ); + MeshGenerator meshgenerator( "structured", Config( "partitioner", "equal_regions" ) ); - size_t halo = args.getLong("halo",0); - bool do_all = args.getBool("do-all",false); + size_t halo = args.getLong( "halo", 0 ); + bool do_all = args.getBool( "do-all", false ); - ATLAS_DEBUG_VAR( do_all ); + ATLAS_DEBUG_VAR( do_all ); - size_t iterations = 1; - mpi::comm().barrier(); + size_t iterations = 1; + mpi::comm().barrier(); - for( size_t j=0; j<1; ++j ) { - ATLAS_TRACE("outer_iteration"); - Mesh mesh = meshgenerator.generate(grid); + for ( size_t j = 0; j < 1; ++j ) { + ATLAS_TRACE( "outer_iteration" ); + Mesh mesh = meshgenerator.generate( grid ); - atlas::mesh::actions::build_periodic_boundaries(mesh); + atlas::mesh::actions::build_periodic_boundaries( mesh ); - Log::info() << "building halo" << std::endl; - atlas::mesh::actions::BuildHalo build_halo(mesh); - build_halo(halo); + Log::info() << "building halo" << std::endl; + atlas::mesh::actions::BuildHalo build_halo( mesh ); + build_halo( halo ); - Trace::Barriers set_barrier(true); - Trace::Tracing set_channel( Log::info() ); - for( size_t i=0; i #include -#include -#include -#include #include -#include +#include +#include +#include #include +#include +#include #include "atlas/grid.h" -#include "atlas/grid/Partitioner.h" #include "atlas/grid/Distribution.h" -#include "atlas/runtime/AtlasTool.h" +#include "atlas/grid/Partitioner.h" #include "atlas/output/Gmsh.h" -#include "atlas/runtime/Log.h" +#include "atlas/output/detail/GmshIO.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/AtlasTool.h" +#include "atlas/runtime/Log.h" #include "atlas/util/Config.h" -#include "atlas/output/detail/GmshIO.h" #include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" - //------------------------------------------------------------------------------ using namespace atlas; @@ -40,135 +40,159 @@ using eckit::PathName; //------------------------------------------------------------------------------ class Tool : public AtlasTool { - - virtual void execute(const Args& args); - virtual std::string briefDescription() { - return "Tool to generate a python script that plots the grid-distribution of a given grid"; - } - virtual std::string usage() { - return name() + " (--grid.name=name|--grid.json=path) [OPTION]... OUTPUT [--help]"; - } + virtual void execute( const Args& args ); + virtual std::string briefDescription() { + return "Tool to generate a python script that plots the grid-distribution " + "of a given grid"; + } + virtual std::string usage() { return name() + " (--grid.name=name|--grid.json=path) [OPTION]... OUTPUT [--help]"; } public: - - Tool(int argc,char **argv); + Tool( int argc, char** argv ); private: - - std::string key; - PathName path_in; - PathName path_out; - + std::string key; + PathName path_in; + PathName path_out; }; //----------------------------------------------------------------------------- -Tool::Tool(int argc,char **argv): AtlasTool(argc,argv) -{ - add_option( new SimpleOption("grid.name","Grid unique identifier\n" - +indent()+" Example values: N80, F40, O24, L32") ); - add_option( new SimpleOption("grid.json","Grid described by json file") ); - add_option( new SimpleOption("partitioner","Partitioner to be used") ); - add_option( new SimpleOption("partitions","Number of partitions") ); +Tool::Tool( int argc, char** argv ) : AtlasTool( argc, argv ) { + add_option( new SimpleOption( + "grid.name", "Grid unique identifier\n" + indent() + " Example values: N80, F40, O24, L32" ) ); + add_option( new SimpleOption( "grid.json", "Grid described by json file" ) ); + add_option( new SimpleOption( "partitioner", "Partitioner to be used" ) ); + add_option( new SimpleOption( "partitions", "Number of partitions" ) ); } //----------------------------------------------------------------------------- -void Tool::execute(const Args& args) -{ - key = ""; - args.get("grid.name",key); - - std::string path_in_str = ""; - if( args.get("grid.json",path_in_str) ) path_in = path_in_str; - - StructuredGrid grid; - if( key.size() ) - { - try{ grid = Grid(key); } - catch( eckit::BadParameter& e ){} - } - else if( path_in.path().size() ) - { - Log::info() << "Creating grid from file " << path_in << std::endl; - Log::debug() << Config(path_in) << std::endl; - try{ grid = Grid( Config(path_in) ); } - catch( eckit::BadParameter& e ){} - } - else - { - Log::error() << "No grid specified." << std::endl; - } - - if( !grid ) return; - - 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"; - - long N=mpi::comm().size(); - args.get("partitions",N); - - if( mpi::comm().rank() == 0 ) { - - grid::Partitioner partitioner(partitioner_type,N); - grid::Distribution distribution = partitioner.partition(grid); - - Log::info() << distribution << std::endl; - - std::vector< std::vector > x(N); - std::vector< std::vector > y(N); - for( long p=0; p> x( N ); + std::vector> y( N ); + for ( long p = 0; p < N; ++p ) { + size_t nb_pts = distribution.nb_pts()[p]; + x[p].reserve( nb_pts ); + y[p].reserve( nb_pts ); + } + + size_t n = 0; + for ( PointXY pxy : grid.xy() ) { + size_t p = distribution.partition( n++ ); + x[p].push_back( pxy.x() ); + y[p].push_back( pxy.y() ); + } + + std::ofstream f( "grid-distribution.py", std::ios::trunc ); + f << "\n" + "import matplotlib.pyplot as plt" + "\n" + "from matplotlib.path import Path" + "\n" + "import matplotlib.patches as patches" + "\n" + "" + "\n" + "from itertools import cycle" + "\n" + "import matplotlib.cm as cm" + "\n" + "import numpy as np" + "\n" + "cycol = cycle([cm.Paired(i) for i in " + "np.linspace(0,1,12,endpoint=True)]).next" + "\n" + "" + "\n" + "fig = plt.figure()" + "\n" + "ax = fig.add_subplot(111,aspect='equal')" + "\n" + ""; + + for ( long p = 0; p < N; ++p ) { + f << "\n" + "x = ["; + for ( const double& _x : x[p] ) { + f << _x << ", "; + } + f << "]"; + f << "\n" + "y = ["; + for ( const double& _y : y[p] ) { + f << _y << ", "; + } + f << "]"; + f << "\n" + "c = cycol()"; + f << "\n" + "ax.scatter(x, y, color=c, marker='o')"; + f << "\n" + ""; + } + f << "\n" + "ax.set_xlim( 0-5, 360+5)" + "\n" + "ax.set_ylim(-90-5, 90+5)" + "\n" + "ax.set_xticks([0,45,90,135,180,225,270,315,360])" + "\n" + "ax.set_yticks([-90,-45,0,45,90])" + "\n" + "plt.grid()" + "\n" + "plt.show()"; } - f << "\n" "ax.set_xlim( 0-5, 360+5)" - "\n" "ax.set_ylim(-90-5, 90+5)" - "\n" "ax.set_xticks([0,45,90,135,180,225,270,315,360])" - "\n" "ax.set_yticks([-90,-45,0,45,90])" - "\n" "plt.grid()" - "\n" "plt.show()"; - - } } //------------------------------------------------------------------------------ -int main( int argc, char **argv ) -{ - Tool tool(argc,argv); - return tool.start(); +int main( int argc, char** argv ) { + Tool tool( argc, argv ); + return tool.start(); } diff --git a/src/sandbox/interpolation/PartitionedMesh.cc b/src/sandbox/interpolation/PartitionedMesh.cc index d80a4e6cf..e047a7468 100644 --- a/src/sandbox/interpolation/PartitionedMesh.cc +++ b/src/sandbox/interpolation/PartitionedMesh.cc @@ -4,11 +4,11 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include "PartitionedMesh.h" #include "atlas/grid/Partitioner.h" @@ -16,62 +16,48 @@ #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" - namespace atlas { namespace interpolation { - -PartitionedMesh::PartitionedMesh( - const std::string& partitioner, - const std::string& generator, - bool generatorTriangulate, - double generatorAngle ) : - optionPartitioner_(partitioner), - optionGenerator_(generator) { - - generatorParams_.set("three_dimensional", false); - generatorParams_.set("patch_pole", true); - generatorParams_.set("include_pole", false); - generatorParams_.set("triangulate", generatorTriangulate); - generatorParams_.set("angle", generatorAngle); +PartitionedMesh::PartitionedMesh( const std::string& partitioner, const std::string& generator, + bool generatorTriangulate, double generatorAngle ) : + optionPartitioner_( partitioner ), + optionGenerator_( generator ) { + generatorParams_.set( "three_dimensional", false ); + generatorParams_.set( "patch_pole", true ); + generatorParams_.set( "include_pole", false ); + generatorParams_.set( "triangulate", generatorTriangulate ); + generatorParams_.set( "angle", generatorAngle ); } - -void PartitionedMesh::writeGmsh(const std::string& fileName, const FieldSet& fields) { - +void PartitionedMesh::writeGmsh( const std::string& fileName, const FieldSet& fields ) { util::Config output_config; - output_config.set("coordinates", std::string("xyz")); - output_config.set("ghost", true); + output_config.set( "coordinates", std::string( "xyz" ) ); + output_config.set( "ghost", true ); - output::Gmsh out(fileName, output_config); - out.write(mesh_); + 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) { +void PartitionedMesh::partition( const Grid& grid ) { ATLAS_TRACE( "PartitionedMesh::partition()" ); - partitioner_ = Partitioner(optionPartitioner_); + partitioner_ = Partitioner( optionPartitioner_ ); - MeshGenerator meshgen(optionGenerator_, generatorParams_); - mesh_ = meshgen.generate(grid, partitioner_.partition(grid)); + MeshGenerator meshgen( optionGenerator_, generatorParams_ ); + mesh_ = meshgen.generate( grid, partitioner_.partition( grid ) ); } - -void PartitionedMesh::partition(const Grid& grid, const PartitionedMesh& other) { +void PartitionedMesh::partition( const Grid& grid, const PartitionedMesh& other ) { ATLAS_TRACE( "PartitionedMesh::partition(other)" ); - partitioner_ = grid::MatchingMeshPartitioner(other.mesh_, util::Config("type", optionPartitioner_)); + partitioner_ = grid::MatchingMeshPartitioner( other.mesh_, util::Config( "type", optionPartitioner_ ) ); - MeshGenerator meshgen(optionGenerator_, generatorParams_); - mesh_ = meshgen.generate(grid, partitioner_.partition(grid) ); + MeshGenerator meshgen( optionGenerator_, generatorParams_ ); + mesh_ = meshgen.generate( grid, partitioner_.partition( grid ) ); } - } // namespace interpolation } // namespace atlas - diff --git a/src/sandbox/interpolation/PartitionedMesh.h b/src/sandbox/interpolation/PartitionedMesh.h index c9f7d747c..4a88740bf 100644 --- a/src/sandbox/interpolation/PartitionedMesh.h +++ b/src/sandbox/interpolation/PartitionedMesh.h @@ -4,54 +4,45 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #pragma once #include "atlas/field.h" #include "atlas/grid.h" -#include "atlas/meshgenerator.h" #include "atlas/mesh.h" - +#include "atlas/meshgenerator.h" namespace atlas { namespace interpolation { - struct PartitionedMesh { - typedef grid::Partitioner Partitioner; - PartitionedMesh( - const std::string& partitioner, - const std::string& generator, - bool meshGeneratorTriangulate = false, - double meshGeneratorAngle = 0 ); + PartitionedMesh( const std::string& partitioner, const std::string& generator, + bool meshGeneratorTriangulate = false, double meshGeneratorAngle = 0 ); virtual ~PartitionedMesh() {} const Mesh& mesh() const { return mesh_; } - Mesh& mesh() { return mesh_; } + Mesh& mesh() { return mesh_; } - void writeGmsh(const std::string& fileName, const FieldSet& fields = FieldSet()); + void writeGmsh( const std::string& fileName, const FieldSet& fields = FieldSet() ); - void partition(const Grid&); - void partition(const Grid&, const PartitionedMesh&); + void partition( const Grid& ); + void partition( const Grid&, const PartitionedMesh& ); protected: - const std::string optionPartitioner_; const std::string optionGenerator_; MeshGenerator::Parameters generatorParams_; Partitioner partitioner_; Mesh mesh_; - }; - } // namespace interpolation } // namespace atlas diff --git a/src/sandbox/interpolation/atlas-parallel-interpolation.cc b/src/sandbox/interpolation/atlas-parallel-interpolation.cc index 2b3be3548..848bb059f 100644 --- a/src/sandbox/interpolation/atlas-parallel-interpolation.cc +++ b/src/sandbox/interpolation/atlas-parallel-interpolation.cc @@ -4,253 +4,237 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include #include -#include "eckit/config/Resource.h" -#include "eckit/linalg/LinearAlgebra.h" -#include "eckit/log/Plural.h" #include "atlas/field.h" #include "atlas/functionspace.h" #include "atlas/interpolation.h" #include "atlas/runtime/AtlasTool.h" #include "atlas/runtime/Log.h" +#include "eckit/config/Resource.h" +#include "eckit/linalg/LinearAlgebra.h" +#include "eckit/log/Plural.h" #include "PartitionedMesh.h" - using namespace atlas; class AtlasParallelInterpolation : public AtlasTool { - - void execute(const AtlasTool::Args& args); - std::string briefDescription() { - return "Demonstration of parallel interpolation"; - } + void execute( const AtlasTool::Args& args ); + std::string briefDescription() { return "Demonstration of parallel interpolation"; } std::string usage() { - return name() + " [--source-gridname=gridname] [--target-gridname=gridname] [OPTION]... [--help]"; + return name() + + " [--source-gridname=gridname] " + "[--target-gridname=gridname] [OPTION]... [--help]"; } int numberOfPositionalArguments() { return -1; } int minimumPositionalArguments() { return 0; } public: - - AtlasParallelInterpolation(int argc, char* argv[]) : AtlasTool(argc, argv) { - add_option(new SimpleOption ("log-rank", "use specific MPI rank for logging (default 0)")); - add_option(new SimpleOption ("log-statistics", "show simple statistics on source/target (default false)")); - add_option(new SimpleOption ("output-polygons", "Output Python script that plots partitions polygons")); - - add_option(new SimpleOption("method", "interpolation method (default finite-element)")); - add_option(new SimpleOption("backend", "linear algebra backend")); - add_option(new SimpleOption ("k-nearest-neighbours", "k-nearest neighbours (default 1)")); - add_option(new SimpleOption ("with-backward", "Also do backward interpolation (default false)")); - - add_option(new SimpleOption("source-gridname", "source gridname")); - add_option(new SimpleOption("source-mesh-partitioner", "source mesh partitioner (equal_regions (default), ...)")); - add_option(new SimpleOption("source-mesh-generator", "source mesh generator (default structured)")); - add_option(new SimpleOption ("source-mesh-generator-triangulate", "source mesh generator triangulate option (default false)")); - add_option(new SimpleOption ("source-mesh-generator-angle", "source mesh generator angle option (default 0.)")); - add_option(new SimpleOption ("source-mesh-halo", "source mesh halo size (default 1)")); - - add_option(new SimpleOption("target-gridname", "target gridname")); - add_option(new SimpleOption("target-mesh-partitioner", "target mesh partitioner (spherical-polygon, lonlat-polygon, brute-force)")); - add_option(new SimpleOption ("target-mesh-generator", "target mesh generator (default structured)")); - add_option(new SimpleOption ("target-mesh-generator-triangulate", "target mesh generator triangulate option (default false)")); - add_option(new SimpleOption ("target-mesh-generator-angle", "target mesh generator angle option (default 0.)")); - add_option(new SimpleOption ("target-mesh-halo", "target mesh halo size (default 1)")); + AtlasParallelInterpolation( int argc, char* argv[] ) : AtlasTool( argc, argv ) { + add_option( new SimpleOption( "log-rank", "use specific MPI rank for logging (default 0)" ) ); + add_option( + new SimpleOption( "log-statistics", "show simple statistics on source/target (default false)" ) ); + add_option( + new SimpleOption( "output-polygons", "Output Python script that plots partitions polygons" ) ); + + add_option( new SimpleOption( "method", "interpolation method (default finite-element)" ) ); + add_option( new SimpleOption( "backend", "linear algebra backend" ) ); + add_option( new SimpleOption( "k-nearest-neighbours", "k-nearest neighbours (default 1)" ) ); + add_option( new SimpleOption( "with-backward", "Also do backward interpolation (default false)" ) ); + + add_option( new SimpleOption( "source-gridname", "source gridname" ) ); + add_option( new SimpleOption( "source-mesh-partitioner", + "source mesh partitioner (equal_regions (default), ...)" ) ); + add_option( + new SimpleOption( "source-mesh-generator", "source mesh generator (default structured)" ) ); + add_option( new SimpleOption( "source-mesh-generator-triangulate", + "source mesh generator triangulate option (default false)" ) ); + add_option( new SimpleOption( "source-mesh-generator-angle", + "source mesh generator angle option (default 0.)" ) ); + add_option( new SimpleOption( "source-mesh-halo", "source mesh halo size (default 1)" ) ); + + add_option( new SimpleOption( "target-gridname", "target gridname" ) ); + add_option( new SimpleOption( "target-mesh-partitioner", + "target mesh partitioner " + "(spherical-polygon, " + "lonlat-polygon, brute-force)" ) ); + add_option( new SimpleOption( "target-mesh-generator", "target mesh generator (default structured)" ) ); + add_option( new SimpleOption( "target-mesh-generator-triangulate", + "target mesh generator triangulate option (default false)" ) ); + add_option( new SimpleOption( "target-mesh-generator-angle", + "target mesh generator angle option (default 0.)" ) ); + add_option( new SimpleOption( "target-mesh-halo", "target mesh halo size (default 1)" ) ); } - }; - -void AtlasParallelInterpolation::execute(const AtlasTool::Args& args) { - +void AtlasParallelInterpolation::execute( const AtlasTool::Args& args ) { // Get user options std::string option; - bool trigs = false; + bool trigs = false; double angle = 0.; bool log_statistics = false; - args.get("log-statistics", log_statistics); + args.get( "log-statistics", log_statistics ); size_t log_rank = 0; - args.get("log-rank", log_rank); - - if (eckit::mpi::comm().rank() != log_rank) { - Log::reset(); - } + args.get( "log-rank", log_rank ); - if (args.get("backend", option)) { - eckit::linalg::LinearAlgebra::backend(option); - } + if ( eckit::mpi::comm().rank() != log_rank ) { Log::reset(); } + 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 (pre-partitioned) source mesh + // source mesh is partitioned on its own, the target mesh uses + // (pre-partitioned) source mesh - option = args.get("source-gridname", option)? option : "O16"; - Grid src_grid(option); + option = args.get( "source-gridname", option ) ? option : "O16"; + Grid src_grid( option ); size_t source_mesh_halo = 0; - args.get("source-mesh-halo", source_mesh_halo); + args.get( "source-mesh-halo", source_mesh_halo ); - interpolation::PartitionedMesh src( - args.get("source-mesh-partitioner", option)? option : "equal_regions", - args.get("source-mesh-generator", option)? option : "structured", - args.get("source-mesh-generator-triangulate", trigs)? trigs : false, - args.get("source-mesh-generator-angle", angle)? angle : 0. ); + interpolation::PartitionedMesh src( args.get( "source-mesh-partitioner", option ) ? option : "equal_regions", + args.get( "source-mesh-generator", option ) ? option : "structured", + args.get( "source-mesh-generator-triangulate", trigs ) ? trigs : false, + args.get( "source-mesh-generator-angle", angle ) ? angle : 0. ); - - option = args.get("target-gridname", option)? option : "O32"; - Grid tgt_grid(option); + option = args.get( "target-gridname", option ) ? option : "O32"; + Grid tgt_grid( option ); size_t target_mesh_halo = 0; - args.get("target-mesh-halo", target_mesh_halo); - - interpolation::PartitionedMesh tgt( - args.get("target-mesh-partitioner", option)? option : "spherical-polygon", - args.get("target-mesh-generator", option)? option : "structured", - args.get("target-mesh-generator-triangulate", trigs)? trigs : false, - args.get("target-mesh-generator-angle", angle)? angle : 0. ); + args.get( "target-mesh-halo", target_mesh_halo ); - Log::info() << "Partitioning source grid, halo of " << eckit::Plural(source_mesh_halo, "element") << std::endl; - src.partition(src_grid); - functionspace::NodeColumns src_functionspace(src.mesh(), option::halo(source_mesh_halo)); - src.writeGmsh("src-mesh.msh"); + interpolation::PartitionedMesh tgt( args.get( "target-mesh-partitioner", option ) ? option : "spherical-polygon", + args.get( "target-mesh-generator", option ) ? option : "structured", + args.get( "target-mesh-generator-triangulate", trigs ) ? trigs : false, + args.get( "target-mesh-generator-angle", angle ) ? angle : 0. ); - Log::info() << "Partitioning target grid, halo of " << eckit::Plural(target_mesh_halo, "element") << std::endl; - tgt.partition(tgt_grid, src); - functionspace::NodeColumns tgt_functionspace(tgt.mesh(), option::halo(target_mesh_halo)); - tgt.writeGmsh("tgt-mesh.msh"); + Log::info() << "Partitioning source grid, halo of " << eckit::Plural( source_mesh_halo, "element" ) << std::endl; + src.partition( src_grid ); + functionspace::NodeColumns src_functionspace( src.mesh(), option::halo( source_mesh_halo ) ); + src.writeGmsh( "src-mesh.msh" ); + Log::info() << "Partitioning target grid, halo of " << eckit::Plural( target_mesh_halo, "element" ) << std::endl; + tgt.partition( tgt_grid, src ); + functionspace::NodeColumns tgt_functionspace( tgt.mesh(), option::halo( target_mesh_halo ) ); + tgt.writeGmsh( "tgt-mesh.msh" ); /// For debugging purposes - if (eckit::Resource("--output-polygons", false)) { - src.mesh().polygon(0).outputPythonScript("polygons.py"); + if ( eckit::Resource( "--output-polygons", false ) ) { + src.mesh().polygon( 0 ).outputPythonScript( "polygons.py" ); } - - // Setup interpolator relating source & target meshes before setting a source FunctionSpace halo + // Setup interpolator relating source & target meshes before setting a source + // FunctionSpace halo Log::info() << "Computing forward/backward interpolator" << std::endl; std::string interpolation_method = "finite-element"; - args.get("method", interpolation_method); + args.get( "method", interpolation_method ); - Interpolation interpolator_forward( option::type(interpolation_method), src_functionspace, tgt_functionspace); + Interpolation interpolator_forward( option::type( interpolation_method ), src_functionspace, tgt_functionspace ); Interpolation interpolator_backward; bool with_backward = false; - args.get("with-backward", with_backward); - if( with_backward ) { - Log::info() << "Computing backward interpolator" << std::endl; - interpolator_backward = Interpolation( option::type(interpolation_method), tgt_functionspace, src_functionspace); + args.get( "with-backward", with_backward ); + if ( with_backward ) { + Log::info() << "Computing backward interpolator" << std::endl; + interpolator_backward = + Interpolation( option::type( interpolation_method ), tgt_functionspace, src_functionspace ); } - // Create source FunctionSpace and fields FieldSet src_fields; { - src_fields.add( src_functionspace.createField( option::name("funny_scalar_1") ) ); - src_fields.add( src_functionspace.createField( option::name("funny_scalar_2") ) ); + src_fields.add( src_functionspace.createField( option::name( "funny_scalar_1" ) ) ); + src_fields.add( src_functionspace.createField( option::name( "funny_scalar_2" ) ) ); // Helper constants - const double - deg2rad = M_PI / 180., - c_lat = 0. * M_PI, - c_lon = 1. * M_PI, - c_rad = 2. * M_PI / 9.; - - array::ArrayView< double, 2 > lonlat = array::make_view( src.mesh().nodes().lonlat() ); - array::ArrayView< double, 1 > - src_scalar_1 = array::make_view(src_fields[0]), - src_scalar_2 = array::make_view(src_fields[1]); - for (size_t j = 0; j < src.mesh().nodes().size(); ++j) { - const double lon = deg2rad * lonlat(j, 0); // (lon) - const double lat = deg2rad * lonlat(j, 1); // (lat) - const double - c2 = std::cos(lat), - s1 = std::sin((lon-c_lon)/2.), - s2 = std::sin((lat-c_lat)/2.), - dist = 2.0 * std::sqrt( c2*s1*c2*s1 + s2*s2 ); - src_scalar_1(j) = dist < c_rad? 0.5 * (1. + std::cos(M_PI*dist/c_rad)) : 0.; - src_scalar_2(j) = -src_scalar_1(j); - - - double x = lonlat(j, 0) - 180.; - double y = lonlat(j, 1); - - src_scalar_1(j) = -std::tanh(y/10.*std::cos(50./std::sqrt(x*x+y*y))-x/10.*std::sin(50./std::sqrt(x*x+y*y))); - + const double deg2rad = M_PI / 180., c_lat = 0. * M_PI, c_lon = 1. * M_PI, c_rad = 2. * M_PI / 9.; + + array::ArrayView lonlat = array::make_view( src.mesh().nodes().lonlat() ); + array::ArrayView src_scalar_1 = array::make_view( src_fields[0] ), + src_scalar_2 = array::make_view( src_fields[1] ); + for ( size_t j = 0; j < src.mesh().nodes().size(); ++j ) { + const double lon = deg2rad * lonlat( j, 0 ); // (lon) + const double lat = deg2rad * lonlat( j, 1 ); // (lat) + const double c2 = std::cos( lat ), s1 = std::sin( ( lon - c_lon ) / 2. ), + s2 = std::sin( ( lat - c_lat ) / 2. ), dist = 2.0 * std::sqrt( c2 * s1 * c2 * s1 + s2 * s2 ); + src_scalar_1( j ) = dist < c_rad ? 0.5 * ( 1. + std::cos( M_PI * dist / c_rad ) ) : 0.; + src_scalar_2( j ) = -src_scalar_1( j ); + + double x = lonlat( j, 0 ) - 180.; + double y = lonlat( j, 1 ); + + src_scalar_1( j ) = -std::tanh( y / 10. * std::cos( 50. / std::sqrt( x * x + y * y ) ) - + x / 10. * std::sin( 50. / std::sqrt( x * x + y * y ) ) ); } } FieldSet tgt_fields; - for (size_t i = 0; i < src_fields.size(); ++i) { - tgt_fields.add( tgt_functionspace.createField( option::name(src_fields[i].name())) ); + for ( size_t i = 0; i < src_fields.size(); ++i ) { + tgt_fields.add( tgt_functionspace.createField( option::name( src_fields[i].name() ) ) ); } - src_functionspace.haloExchange(src_fields); + src_functionspace.haloExchange( src_fields ); Log::info() << "Writing input to interpolation to src.msh" << std::endl; - src.writeGmsh("src.msh", src_fields); - + src.writeGmsh( "src.msh", src_fields ); Log::info() << "Interpolate forward" << std::endl; - // interpolate (matrix-field vector multiply and synchronize results) (FIXME: necessary?) - interpolator_forward.execute(src_fields, tgt_fields); - tgt_functionspace.haloExchange(tgt_fields); + // interpolate (matrix-field vector multiply and synchronize results) (FIXME: + // necessary?) + interpolator_forward.execute( src_fields, tgt_fields ); + tgt_functionspace.haloExchange( tgt_fields ); - if( with_backward ) { + if ( with_backward ) { Log::info() << "Interpolate backward" << std::endl; - interpolator_backward.execute(tgt_fields, src_fields); - src_functionspace.haloExchange(src_fields); + interpolator_backward.execute( tgt_fields, src_fields ); + src_functionspace.haloExchange( src_fields ); } Log::info() << "Interpolations done" << std::endl; // Report simple statistics (on source & target) - if (log_statistics) { + if ( log_statistics ) { double meanA, minA, maxA, meanB, minB, maxB; size_t nA, nB; - for (size_t i = 0; i < src_fields.size(); ++i) { + for ( size_t i = 0; i < src_fields.size(); ++i ) { + src_functionspace.minimum( src_fields[i], minA ); + src_functionspace.maximum( src_fields[i], maxA ); + src_functionspace.mean( src_fields[i], meanA, nA ); - src_functionspace.minimum(src_fields[i], minA); - src_functionspace.maximum(src_fields[i], maxA); - src_functionspace.mean (src_fields[i], meanA, nA); - - tgt_functionspace.minimum(tgt_fields[i], minB); - tgt_functionspace.maximum(tgt_fields[i], maxB); - tgt_functionspace.mean (tgt_fields[i], meanB, nB); + tgt_functionspace.minimum( tgt_fields[i], minB ); + tgt_functionspace.maximum( tgt_fields[i], maxB ); + tgt_functionspace.mean( tgt_fields[i], meanB, nB ); Log::info() << "Field '" << src_fields[i].name() << "' (N,min,mean,max):" - << "\n\tsource:\t" << nA << ",\t" << minA << ",\t" << meanA << ",\t" << maxA - << "\n\ttarget:\t" << nB << ",\t" << minB << ",\t" << meanB << ",\t" << maxB - << std::endl; + << "\n\tsource:\t" << nA << ",\t" << minA << ",\t" << meanA << ",\t" << maxA << "\n\ttarget:\t" + << nB << ",\t" << minB << ",\t" << meanB << ",\t" << maxB << std::endl; } } - // Output results Log::info() << "Writing forward interpolation results to tgt.msh" << std::endl; - tgt.writeGmsh("tgt.msh", tgt_fields); + tgt.writeGmsh( "tgt.msh", tgt_fields ); - if( with_backward ) { - Log::info() << "Writing backward interpolation results to src-back.msh" << std::endl; - src.writeGmsh("src-back.msh", src_fields); + if ( with_backward ) { + Log::info() << "Writing backward interpolation results to src-back.msh" << std::endl; + src.writeGmsh( "src-back.msh", src_fields ); } } - -int main(int argc, char* argv[]) { - AtlasParallelInterpolation tool(argc, argv); +int main( int argc, char* argv[] ) { + AtlasParallelInterpolation tool( argc, argv ); return tool.start(); } diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index e9e75c036..7934cd7af 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -4,31 +4,31 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #pragma once -#include #include #include +#include +#include "eckit/config/LibEcKit.h" #include "eckit/config/Resource.h" -#include "eckit/eckit_version.h" #include "eckit/eckit_config.h" +#include "eckit/eckit_version.h" +#include "eckit/log/PrefixTarget.h" #include "eckit/mpi/Comm.h" #include "eckit/runtime/Main.h" -#include "eckit/config/Resource.h" -#include "eckit/config/LibEcKit.h" #include "eckit/testing/Test.h" -#include "eckit/log/PrefixTarget.h" #include "atlas/library/Library.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "atlas/util/Config.h" #include "atlas/runtime/trace/StopWatch.h" +#include "atlas/util/Config.h" #ifdef ATLAS_TEST_MPI #ifdef ECKIT_HAVE_MPI @@ -41,61 +41,67 @@ namespace test { //---------------------------------------------------------------------------------------------------------------------- -// Redefine macro's defined in "eckit/testing/Test.h" to include trace information +// Redefine macro's defined in "eckit/testing/Test.h" to include trace +// information -#define _ECKIT_VERSION (ECKIT_MAJOR_VERSION * 10000 \ - + ECKIT_MINOR_VERSION * 100 \ - + ECKIT_PATCH_VERSION) +#define _ECKIT_VERSION ( ECKIT_MAJOR_VERSION * 10000 + ECKIT_MINOR_VERSION * 100 + ECKIT_PATCH_VERSION ) // Test ECKIT_VERSION < 0.19.1 #if _ECKIT_VERSION < 1901 #undef CASE -#define CASE(description) \ -void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection); \ -static eckit::testing::TestRegister UNIQUE_NAME2(test_registration_, __LINE__)(description, &UNIQUE_NAME2(test_, __LINE__)); \ -void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection); \ -void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection) { \ - ATLAS_TRACE(description); \ - UNIQUE_NAME2(traced_test_, __LINE__)(_test_subsection); \ -} \ -void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection) +#define CASE( description ) \ + void UNIQUE_NAME2( test_, __LINE__ )( std::string & _test_subsection ); \ + static eckit::testing::TestRegister UNIQUE_NAME2( test_registration_, __LINE__ )( \ + description, &UNIQUE_NAME2( test_, __LINE__ ) ); \ + void UNIQUE_NAME2( traced_test_, __LINE__ )( std::string & _test_subsection ); \ + void UNIQUE_NAME2( test_, __LINE__ )( std::string & _test_subsection ) { \ + ATLAS_TRACE( description ); \ + UNIQUE_NAME2( traced_test_, __LINE__ )( _test_subsection ); \ + } \ + void UNIQUE_NAME2( traced_test_, __LINE__ )( std::string & _test_subsection ) #undef SECTION -#define SECTION(name) \ - _test_num += 1; \ - _test_count = _test_num; \ - _test_subsection = (name); \ - if ((_test_num - 1) == _test) ATLAS_TRACE_SCOPE(_test_subsection) +#define SECTION( name ) \ + _test_num += 1; \ + _test_count = _test_num; \ + _test_subsection = ( name ); \ + if ( ( _test_num - 1 ) == _test ) ATLAS_TRACE_SCOPE( _test_subsection ) #else #undef CASE -#define CASE(description) \ -void UNIQUE_NAME2(test_, __LINE__) (std::string& , int&, int); \ -static eckit::testing::TestRegister UNIQUE_NAME2(test_registration_, __LINE__)(description, &UNIQUE_NAME2(test_, __LINE__)); \ -void UNIQUE_NAME2(traced_test_, __LINE__)(std::string& _test_subsection, int& _num_subsections, int _subsection); \ -void UNIQUE_NAME2(test_, __LINE__) (std::string& _test_subsection, int& _num_subsections, int _subsection) { \ - ATLAS_TRACE(description); \ - UNIQUE_NAME2(traced_test_, __LINE__)(_test_subsection,_num_subsections,_subsection); \ - if( atlas::test::barrier_timeout( atlas::test::ATLAS_MPI_BARRIER_TIMEOUT() ) ) { \ - atlas::Log::warning() << "\nWARNING: Test \""<< description << "\" failed with MPI deadlock. (${ATLAS_MPI_BARRIER_TIMEOUT}="<("${ATLAS_MPI_BARRIER_TIMEOUT",3.); - return v; + static int v = eckit::Resource( "${ATLAS_MPI_BARRIER_TIMEOUT", 3. ); + return v; } - static int barrier_timeout( double seconds ) { #ifdef ATLAS_TEST_MPI - if( eckit::mpi::comm().size() > 1 ) { - MPI_Request req; - MPI_Ibarrier( MPI_COMM_WORLD, &req ); - - int barrier_succesful = 0; - runtime::trace::StopWatch watch; watch.start(); - while( not barrier_succesful ) { - watch.stop(); - if( watch.elapsed() > seconds ) { - return 1; - } - watch.start(); - std::this_thread::sleep_for( std::chrono::milliseconds(100) ); - MPI_Test( &req, &barrier_succesful, MPI_STATUS_IGNORE ); + if ( eckit::mpi::comm().size() > 1 ) { + MPI_Request req; + MPI_Ibarrier( MPI_COMM_WORLD, &req ); + + int barrier_succesful = 0; + runtime::trace::StopWatch watch; + watch.start(); + while ( not barrier_succesful ) { + watch.stop(); + if ( watch.elapsed() > seconds ) { return 1; } + watch.start(); + std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + MPI_Test( &req, &barrier_succesful, MPI_STATUS_IGNORE ); + } } - } #endif - return 0; + return 0; } - struct AtlasTestEnvironment { - using Config = util::Config; - AtlasTestEnvironment(int argc, char * argv[]) { - eckit::Main::initialise(argc, argv); - eckit::Main::instance().taskID( eckit::mpi::comm("world").rank() ); - if( eckit::mpi::comm("world").size() != 1 ) { - long logtask = eckit::Resource("$ATLAS_LOG_TASK", 0); - if( eckit::Main::instance().taskID() != logtask ) { - eckit::Log::info().reset(); - eckit::Log::warning().reset(); - eckit::Log::debug().reset(); + AtlasTestEnvironment( int argc, char* argv[] ) { + eckit::Main::initialise( argc, argv ); + eckit::Main::instance().taskID( eckit::mpi::comm( "world" ).rank() ); + if ( eckit::mpi::comm( "world" ).size() != 1 ) { + long logtask = eckit::Resource( "$ATLAS_LOG_TASK", 0 ); + if ( eckit::Main::instance().taskID() != logtask ) { + eckit::Log::info().reset(); + eckit::Log::warning().reset(); + eckit::Log::debug().reset(); } eckit::Log::error().setTarget( - new eckit::PrefixTarget( "["+std::to_string(eckit::mpi::comm().rank())+"]" ) ); + new eckit::PrefixTarget( "[" + std::to_string( eckit::mpi::comm().rank() ) + "]" ) ); } - eckit::LibEcKit::instance().setAbortHandler( []{ - Log::error() << "Calling MPI_Abort" << std::endl; - eckit::mpi::comm().abort(); - }); + eckit::LibEcKit::instance().setAbortHandler( [] { + Log::error() << "Calling MPI_Abort" << std::endl; + eckit::mpi::comm().abort(); + } ); Library::instance().initialise(); eckit::mpi::comm().barrier(); } - ~AtlasTestEnvironment() { - Library::instance().finalise(); - } + ~AtlasTestEnvironment() { Library::instance().finalise(); } }; //---------------------------------------------------------------------------------------------------------------------- -template< typename Environment > -int run(int argc, char* argv[]) { +template +int run( int argc, char* argv[] ) { Environment env( argc, argv ); - int errors = eckit::testing::run_tests(argc,argv,false); - if( eckit::mpi::comm().size() > 1 ) { - if( barrier_timeout(ATLAS_MPI_BARRIER_TIMEOUT()) ) { - eckit::Log::warning() << "\nWARNING: Tests failed with MPI deadlock (${ATLAS_MPI_BARRIER_TIMEOUT}="< 1 ) { + if ( barrier_timeout( ATLAS_MPI_BARRIER_TIMEOUT() ) ) { + eckit::Log::warning() << "\nWARNING: Tests failed with MPI deadlock " + "(${ATLAS_MPI_BARRIER_TIMEOUT}=" + << ATLAS_MPI_BARRIER_TIMEOUT() << ").\nCalling MPI_Abort..." << std::endl; + eckit::mpi::comm().abort(); + } + eckit::mpi::comm().allReduceInPlace( errors, eckit::mpi::max() ); } return errors; } -int run(int argc, char* argv[]) { +int run( int argc, char* argv[] ) { return run( argc, argv ); } diff --git a/src/tests/TestMeshes.h b/src/tests/TestMeshes.h index 405470e46..466d27c23 100644 --- a/src/tests/TestMeshes.h +++ b/src/tests/TestMeshes.h @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/library/config.h" #include "atlas/grid.h" -#include "atlas/meshgenerator/StructuredMeshGenerator.h" +#include "atlas/library/config.h" #include "atlas/mesh/Mesh.h" +#include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/parallel/mpi/mpi.h" using namespace atlas; @@ -21,17 +22,14 @@ using namespace atlas::grid; namespace atlas { namespace test { -Mesh generate_mesh( const StructuredGrid& grid ) -{ - meshgenerator::StructuredMeshGenerator generate; - return generate( grid ); +Mesh generate_mesh( const StructuredGrid& grid ) { + meshgenerator::StructuredMeshGenerator generate; + return generate( grid ); } -Mesh generate_mesh( std::initializer_list nx ) -{ - return generate_mesh( ReducedGaussianGrid(nx) ); +Mesh generate_mesh( std::initializer_list nx ) { + return generate_mesh( ReducedGaussianGrid( nx ) ); } - -} // end namespace test -} // end namespace atlas +} // end namespace test +} // end namespace atlas diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index c809a2ed5..a0e46335f 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -4,15 +4,16 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/library/config.h" #include "atlas/array.h" #include "atlas/array/MakeView.h" -#include "tests/AtlasTestEnvironment.h" +#include "atlas/library/config.h" #include "eckit/memory/SharedPtr.h" +#include "tests/AtlasTestEnvironment.h" #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA @@ -23,8 +24,7 @@ #else #define PADDED 0 #endif -#define NOT_PADDED 1-PADDED - +#define NOT_PADDED 1 - PADDED using namespace atlas::array; @@ -34,553 +34,549 @@ namespace test { //----------------------------------------------------------------------------- #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE -CASE("test_array") { - Array* ds = Array::create(4ul); - auto hv = atlas::array::gridtools::make_gt_host_view(*ds); - hv(3) = 4.5; +CASE( "test_array" ) { + Array* ds = Array::create( 4ul ); + auto hv = atlas::array::gridtools::make_gt_host_view( *ds ); + hv( 3 ) = 4.5; - atlas::array::ArrayView atlas_hv = make_host_view(*ds); + atlas::array::ArrayView atlas_hv = make_host_view( *ds ); - EXPECT(hv(3) == 4.5); - EXPECT(atlas_hv(3) == 4.5); + EXPECT( hv( 3 ) == 4.5 ); + EXPECT( atlas_hv( 3 ) == 4.5 ); - delete ds; + delete ds; } #endif -CASE("test_array_zero_size") { - Array* ds = Array::create(0); +CASE( "test_array_zero_size" ) { + Array* ds = Array::create( 0 ); - EXPECT(ds->size() == 0); - delete ds; + EXPECT( ds->size() == 0 ); + delete ds; } #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE -CASE("test_create") { - Array* ds = Array::create(array::DataType::create(), ArrayShape({4, 3})); - auto hv = atlas::array::gridtools::make_gt_host_view(*ds); - hv(3, 2) = 4; +CASE( "test_create" ) { + Array* ds = Array::create( array::DataType::create(), ArrayShape( {4, 3} ) ); + auto hv = atlas::array::gridtools::make_gt_host_view( *ds ); + hv( 3, 2 ) = 4; - atlas::array::ArrayView atlas_hv = make_host_view(*ds); + atlas::array::ArrayView atlas_hv = make_host_view( *ds ); - EXPECT(hv(3, 2) == 4); - EXPECT(atlas_hv(3, 2) == 4); + EXPECT( hv( 3, 2 ) == 4 ); + EXPECT( atlas_hv( 3, 2 ) == 4 ); - delete ds; + delete ds; } #endif #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE -CASE("test_make_view") { - Array* ds = Array::create(4ul); - auto hv = atlas::array::gridtools::make_gt_host_view(*ds); - hv(3) = 4.5; +CASE( "test_make_view" ) { + Array* ds = Array::create( 4ul ); + auto hv = atlas::array::gridtools::make_gt_host_view( *ds ); + hv( 3 ) = 4.5; - atlas::array::ArrayView atlas_hv = make_view(*ds); + atlas::array::ArrayView atlas_hv = make_view( *ds ); - EXPECT(hv(3) == 4.5); - EXPECT(atlas_hv(3) == 4.5); + EXPECT( hv( 3 ) == 4.5 ); + EXPECT( atlas_hv( 3 ) == 4.5 ); - delete ds; + delete ds; } #endif - -CASE("test_localview") { - Array* ds = Array::create(8ul, 4ul, 2ul); - auto hv = make_host_view(*ds); - - EXPECT(hv.shape(0) == 8ul); - EXPECT(hv.shape(1) == 4ul); - EXPECT(hv.shape(2) == 2ul); - EXPECT(hv.size() == 8ul * 4ul * 2ul); - - // Initialize fields - for (size_t i = 0; i < ds->shape(0); ++i) { - for (size_t j = 0; j < ds->shape(1); ++j) { - for (size_t k = 0; k < ds->shape(2); ++k) { - hv(i, j, k) = (i * 100) + (j * 10) + (k); - } +CASE( "test_localview" ) { + Array* ds = Array::create( 8ul, 4ul, 2ul ); + auto hv = make_host_view( *ds ); + + EXPECT( hv.shape( 0 ) == 8ul ); + EXPECT( hv.shape( 1 ) == 4ul ); + EXPECT( hv.shape( 2 ) == 2ul ); + EXPECT( hv.size() == 8ul * 4ul * 2ul ); + + // Initialize fields + for ( size_t i = 0; i < ds->shape( 0 ); ++i ) { + for ( size_t j = 0; j < ds->shape( 1 ); ++j ) { + for ( size_t k = 0; k < ds->shape( 2 ); ++k ) { + hv( i, j, k ) = ( i * 100 ) + ( j * 10 ) + ( k ); + } + } } - } - - // Check values - for (size_t i = 0; i < ds->shape(0); ++i) { - LocalView lv = hv.slice(i,Range::all(),Range::all()); - for (size_t j = 0; j < lv.shape(0); ++j) { - for (size_t k = 0; k < lv.shape(1); ++k) { - EXPECT(lv(j, k) == (i * 100) + (j * 10) + (k)); - } + + // Check values + for ( size_t i = 0; i < ds->shape( 0 ); ++i ) { + LocalView lv = hv.slice( i, Range::all(), Range::all() ); + for ( size_t j = 0; j < lv.shape( 0 ); ++j ) { + for ( size_t k = 0; k < lv.shape( 1 ); ++k ) { + EXPECT( lv( j, k ) == ( i * 100 ) + ( j * 10 ) + ( k ) ); + } + } } - } - delete ds; + delete ds; } #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE -CASE("test_array_shape") { - ArrayShape as{2, 3}; - Array* ds = Array::create(as); - auto gt_hv = atlas::array::gridtools::make_gt_host_view(*ds); - atlas::array::ArrayView atlas_hv = make_host_view(*ds); - - gt_hv(1, 1) = 4.5; - - EXPECT(gt_hv(1, 1) == 4.5); - EXPECT(atlas_hv(1, 1) == 4.5); - - EXPECT(ds->size() == 6); - EXPECT(ds->rank() == 2); - EXPECT(ds->stride(0) == gt_hv.storage_info().stride<0>()); - EXPECT(ds->stride(1) == gt_hv.storage_info().stride<1>()); - EXPECT(ds->contiguous() == NOT_PADDED ); - delete ds; +CASE( "test_array_shape" ) { + ArrayShape as{2, 3}; + Array* ds = Array::create( as ); + auto gt_hv = atlas::array::gridtools::make_gt_host_view( *ds ); + atlas::array::ArrayView atlas_hv = make_host_view( *ds ); + + gt_hv( 1, 1 ) = 4.5; + + EXPECT( gt_hv( 1, 1 ) == 4.5 ); + EXPECT( atlas_hv( 1, 1 ) == 4.5 ); + + EXPECT( ds->size() == 6 ); + EXPECT( ds->rank() == 2 ); + EXPECT( ds->stride( 0 ) == gt_hv.storage_info().stride<0>() ); + EXPECT( ds->stride( 1 ) == gt_hv.storage_info().stride<1>() ); + EXPECT( ds->contiguous() == NOT_PADDED ); + delete ds; } #endif -CASE("test_spec") { - Array* ds = Array::create(4, 5, 6); - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 4 * 5 * 6); - EXPECT(ds->spec().shape()[0] == 4); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 6); - EXPECT(ds->spec().shapef()[0] == 6); - EXPECT(ds->spec().shapef()[1] == 5); - EXPECT(ds->spec().shapef()[2] == 4); - - if( NOT_PADDED ) { - EXPECT(ds->spec().strides()[0] == 6 * 5); - EXPECT(ds->spec().strides()[1] == 6); - EXPECT(ds->spec().strides()[2] == 1); - } - EXPECT(ds->spec().hasDefaultLayout() == true); - - delete ds; +CASE( "test_spec" ) { + Array* ds = Array::create( 4, 5, 6 ); + EXPECT( ds->spec().rank() == 3 ); + EXPECT( ds->spec().size() == 4 * 5 * 6 ); + EXPECT( ds->spec().shape()[0] == 4 ); + EXPECT( ds->spec().shape()[1] == 5 ); + EXPECT( ds->spec().shape()[2] == 6 ); + EXPECT( ds->spec().shapef()[0] == 6 ); + EXPECT( ds->spec().shapef()[1] == 5 ); + EXPECT( ds->spec().shapef()[2] == 4 ); + + if ( NOT_PADDED ) { + EXPECT( ds->spec().strides()[0] == 6 * 5 ); + EXPECT( ds->spec().strides()[1] == 6 ); + EXPECT( ds->spec().strides()[2] == 1 ); + } + EXPECT( ds->spec().hasDefaultLayout() == true ); + + delete ds; } -CASE("test_spec_layout") { - Array* ds = Array::create(make_shape(4,5,6), make_layout(0,1,2)); - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 4 * 5 * 6); - EXPECT(ds->spec().shape()[0] == 4); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 6); - EXPECT(ds->spec().shapef()[0] == 6); - EXPECT(ds->spec().shapef()[1] == 5); - EXPECT(ds->spec().shapef()[2] == 4); - if( NOT_PADDED ) { - EXPECT(ds->spec().strides()[0] == 6 * 5); - EXPECT(ds->spec().strides()[1] == 6); - EXPECT(ds->spec().strides()[2] == 1); - EXPECT(ds->spec().size() == ds->spec().allocatedSize()); - } - EXPECT(ds->spec().hasDefaultLayout() == true); - EXPECT(ds->spec().layout()[0] == 0); - EXPECT(ds->spec().layout()[1] == 1); - EXPECT(ds->spec().layout()[2] == 2); - - delete ds; +CASE( "test_spec_layout" ) { + Array* ds = Array::create( make_shape( 4, 5, 6 ), make_layout( 0, 1, 2 ) ); + EXPECT( ds->spec().rank() == 3 ); + EXPECT( ds->spec().size() == 4 * 5 * 6 ); + EXPECT( ds->spec().shape()[0] == 4 ); + EXPECT( ds->spec().shape()[1] == 5 ); + EXPECT( ds->spec().shape()[2] == 6 ); + EXPECT( ds->spec().shapef()[0] == 6 ); + EXPECT( ds->spec().shapef()[1] == 5 ); + EXPECT( ds->spec().shapef()[2] == 4 ); + if ( NOT_PADDED ) { + EXPECT( ds->spec().strides()[0] == 6 * 5 ); + EXPECT( ds->spec().strides()[1] == 6 ); + EXPECT( ds->spec().strides()[2] == 1 ); + EXPECT( ds->spec().size() == ds->spec().allocatedSize() ); + } + EXPECT( ds->spec().hasDefaultLayout() == true ); + EXPECT( ds->spec().layout()[0] == 0 ); + EXPECT( ds->spec().layout()[1] == 1 ); + EXPECT( ds->spec().layout()[2] == 2 ); + + delete ds; } #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE -CASE("test_spec_layout_rev") { - Array* ds = Array::create(make_shape(4,5,6),make_layout(2,1,0)); - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 4 * 5 * 6); - EXPECT(ds->spec().shape()[0] == 4); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 6); - EXPECT(ds->spec().shapef()[0] == 4); - EXPECT(ds->spec().shapef()[1] == 5); - EXPECT(ds->spec().shapef()[2] == 6); - if( NOT_PADDED ) { - EXPECT(ds->spec().strides()[0] == 1); - EXPECT(ds->spec().strides()[1] == 4); - EXPECT(ds->spec().strides()[2] == 4 * 5); - } - EXPECT(ds->spec().hasDefaultLayout() == false); - EXPECT(ds->spec().layout()[0] == 2); - EXPECT(ds->spec().layout()[1] == 1); - EXPECT(ds->spec().layout()[2] == 0); - - delete ds; - - EXPECT_THROWS_AS( Array::create(make_shape(4,5,6,2),make_layout(0,1,3,2)), eckit::BadParameter ); +CASE( "test_spec_layout_rev" ) { + Array* ds = Array::create( make_shape( 4, 5, 6 ), make_layout( 2, 1, 0 ) ); + EXPECT( ds->spec().rank() == 3 ); + EXPECT( ds->spec().size() == 4 * 5 * 6 ); + EXPECT( ds->spec().shape()[0] == 4 ); + EXPECT( ds->spec().shape()[1] == 5 ); + EXPECT( ds->spec().shape()[2] == 6 ); + EXPECT( ds->spec().shapef()[0] == 4 ); + EXPECT( ds->spec().shapef()[1] == 5 ); + EXPECT( ds->spec().shapef()[2] == 6 ); + if ( NOT_PADDED ) { + EXPECT( ds->spec().strides()[0] == 1 ); + EXPECT( ds->spec().strides()[1] == 4 ); + EXPECT( ds->spec().strides()[2] == 4 * 5 ); + } + EXPECT( ds->spec().hasDefaultLayout() == false ); + EXPECT( ds->spec().layout()[0] == 2 ); + EXPECT( ds->spec().layout()[1] == 1 ); + EXPECT( ds->spec().layout()[2] == 0 ); + + delete ds; + + EXPECT_THROWS_AS( Array::create( make_shape( 4, 5, 6, 2 ), make_layout( 0, 1, 3, 2 ) ), + eckit::BadParameter ); } #endif -CASE("test_resize_throw") { - Array* ds = Array::create(32, 5, 33); +CASE( "test_resize_throw" ) { + Array* ds = Array::create( 32, 5, 33 ); - EXPECT_NO_THROW(ds->resize(32, 5, 33)); - EXPECT_THROWS_AS(ds->resize(32, 4, 33), eckit::BadParameter); - EXPECT_THROWS_AS(ds->resize(32, 5, 32), eckit::BadParameter); - EXPECT_THROWS_AS(ds->resize(32, 5, 33, 4), eckit::BadParameter); + EXPECT_NO_THROW( ds->resize( 32, 5, 33 ) ); + EXPECT_THROWS_AS( ds->resize( 32, 4, 33 ), eckit::BadParameter ); + EXPECT_THROWS_AS( ds->resize( 32, 5, 32 ), eckit::BadParameter ); + EXPECT_THROWS_AS( ds->resize( 32, 5, 33, 4 ), eckit::BadParameter ); - delete ds; + delete ds; } -CASE("test_copy_ctr") { - Array* ds = Array::create(3, 2); - atlas::array::ArrayView hv = make_host_view(*ds); - hv(2, 1) = 4; - hv(1, 1) = 7; +CASE( "test_copy_ctr" ) { + Array* ds = Array::create( 3, 2 ); + atlas::array::ArrayView hv = make_host_view( *ds ); + hv( 2, 1 ) = 4; + hv( 1, 1 ) = 7; - atlas::array::ArrayView hv2(hv); + atlas::array::ArrayView hv2( hv ); - EXPECT(hv2(2, 1) == 4); - EXPECT(hv2(1, 1) == 7); + EXPECT( hv2( 2, 1 ) == 4 ); + EXPECT( hv2( 1, 1 ) == 7 ); - delete ds; + delete ds; } #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE -CASE("test_copy_gt_ctr") { - Array* ds = Array::create(3, 2); - atlas::array::ArrayView hv = make_host_view(*ds); - hv(2, 1) = 4; - hv(1, 1) = 7; - - atlas::array::ArrayView hv2(hv); - - EXPECT(hv2(2, 1) == 4); - EXPECT(hv2(1, 1) == 7); - - auto dims = hv.data_view().storage_info().dims(); - ATLAS_DEBUG_VAR(dims[0]); - ATLAS_DEBUG_VAR(dims[1]); - EXPECT(dims[0] == 3); - if( NOT_PADDED ) EXPECT(dims[1] == 2); - delete ds; +CASE( "test_copy_gt_ctr" ) { + Array* ds = Array::create( 3, 2 ); + atlas::array::ArrayView hv = make_host_view( *ds ); + hv( 2, 1 ) = 4; + hv( 1, 1 ) = 7; + + atlas::array::ArrayView hv2( hv ); + + EXPECT( hv2( 2, 1 ) == 4 ); + EXPECT( hv2( 1, 1 ) == 7 ); + + auto dims = hv.data_view().storage_info().dims(); + ATLAS_DEBUG_VAR( dims[0] ); + ATLAS_DEBUG_VAR( dims[1] ); + EXPECT( dims[0] == 3 ); + if ( NOT_PADDED ) EXPECT( dims[1] == 2 ); + delete ds; } #endif -CASE("test_resize") { - - { - Array* ds = Array::create(0); - EXPECT(ds->size() == 0); - ds->resize(0); - delete ds; - } - - { - Array* ds = Array::create(1); - EXPECT(ds->size() == 1); - ds->resize(2); - delete ds; - } +CASE( "test_resize" ) { + { + Array* ds = Array::create( 0 ); + EXPECT( ds->size() == 0 ); + ds->resize( 0 ); + delete ds; + } - { - Array* ds = Array::create(0); - EXPECT(ds->size() == 0); - ds->resize(make_shape(5)); - delete ds; - } + { + Array* ds = Array::create( 1 ); + EXPECT( ds->size() == 1 ); + ds->resize( 2 ); + delete ds; + } - { - Array* ds = Array::create(2, 3, 4); { - atlas::array::ArrayView hv = make_host_view(*ds); - hv(1, 1, 1) = 4.5; - hv(1, 2, 2) = 7.5; + Array* ds = Array::create( 0 ); + EXPECT( ds->size() == 0 ); + ds->resize( make_shape( 5 ) ); + delete ds; } - ds->resize(3, 4, 5); - atlas::array::ArrayView hv = make_host_view(*ds); + { + Array* ds = Array::create( 2, 3, 4 ); + { + atlas::array::ArrayView hv = make_host_view( *ds ); + hv( 1, 1, 1 ) = 4.5; + hv( 1, 2, 2 ) = 7.5; + } + ds->resize( 3, 4, 5 ); - EXPECT(ds->spec().shape()[0] == 3); - EXPECT(ds->spec().shape()[1] == 4); - EXPECT(ds->spec().shape()[2] == 5); + atlas::array::ArrayView hv = make_host_view( *ds ); - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 3 * 4 * 5); + EXPECT( ds->spec().shape()[0] == 3 ); + EXPECT( ds->spec().shape()[1] == 4 ); + EXPECT( ds->spec().shape()[2] == 5 ); - EXPECT(hv(1, 1, 1) == 4.5); - EXPECT(hv(1, 2, 2) == 7.5); + EXPECT( ds->spec().rank() == 3 ); + EXPECT( ds->spec().size() == 3 * 4 * 5 ); - delete ds; - } + EXPECT( hv( 1, 1, 1 ) == 4.5 ); + EXPECT( hv( 1, 2, 2 ) == 7.5 ); - { - Array* ds = Array::create(3, 2); - { - atlas::array::ArrayView hv = make_host_view(*ds); - hv(2, 1) = 4; - hv(1, 1) = 7; + delete ds; } - ds->resize(6, 2); - atlas::array::ArrayView hv = make_host_view(*ds); - EXPECT(ds->spec().shape()[0] == 6); - EXPECT(ds->spec().shape()[1] == 2); + { + Array* ds = Array::create( 3, 2 ); + { + atlas::array::ArrayView hv = make_host_view( *ds ); + hv( 2, 1 ) = 4; + hv( 1, 1 ) = 7; + } + ds->resize( 6, 2 ); + atlas::array::ArrayView hv = make_host_view( *ds ); - EXPECT(ds->spec().rank() == 2); - EXPECT(ds->spec().size() == 6 * 2); + EXPECT( ds->spec().shape()[0] == 6 ); + EXPECT( ds->spec().shape()[1] == 2 ); - EXPECT(hv(2, 1) == 4); - EXPECT(hv(1, 1) == 7); + EXPECT( ds->spec().rank() == 2 ); + EXPECT( ds->spec().size() == 6 * 2 ); - delete ds; - } - // test the resize with wrap - { - int vals[6] = {3, 4, 6, 7, 5, 4}; + EXPECT( hv( 2, 1 ) == 4 ); + EXPECT( hv( 1, 1 ) == 7 ); - Array* ds = Array::wrap(vals, array::ArrayShape{3, 2}); - { - atlas::array::ArrayView hv = make_host_view(*ds); - hv(2, 1) = 4; - hv(1, 1) = 7; + delete ds; } - ds->resize(6, 2); - atlas::array::ArrayView hv = make_host_view(*ds); + // test the resize with wrap + { + int vals[6] = {3, 4, 6, 7, 5, 4}; - EXPECT(ds->spec().shape()[0] == 6); - EXPECT(ds->spec().shape()[1] == 2); + Array* ds = Array::wrap( vals, array::ArrayShape{3, 2} ); + { + atlas::array::ArrayView hv = make_host_view( *ds ); + hv( 2, 1 ) = 4; + hv( 1, 1 ) = 7; + } + ds->resize( 6, 2 ); + atlas::array::ArrayView hv = make_host_view( *ds ); - EXPECT(ds->spec().rank() == 2); - EXPECT(ds->spec().size() == 6 * 2); + EXPECT( ds->spec().shape()[0] == 6 ); + EXPECT( ds->spec().shape()[1] == 2 ); - EXPECT(hv(2, 1) == 4); - EXPECT(hv(1, 1) == 7); + EXPECT( ds->spec().rank() == 2 ); + EXPECT( ds->spec().size() == 6 * 2 ); - delete ds; - } + EXPECT( hv( 2, 1 ) == 4 ); + EXPECT( hv( 1, 1 ) == 7 ); + + delete ds; + } } -CASE("test_resize_shape") { - Array* ds = Array::create(7, 5, 8); - { - atlas::array::ArrayView hv = make_host_view(*ds); - hv(3, 3, 3) = 4.5; - hv(6, 4, 7) = 7.5; - } - ds->resize(ArrayShape{32, 5, 33}); +CASE( "test_resize_shape" ) { + Array* ds = Array::create( 7, 5, 8 ); + { + atlas::array::ArrayView hv = make_host_view( *ds ); + hv( 3, 3, 3 ) = 4.5; + hv( 6, 4, 7 ) = 7.5; + } + ds->resize( ArrayShape{32, 5, 33} ); - atlas::array::ArrayView hv = make_host_view(*ds); - EXPECT(ds->spec().shape()[0] == 32); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 33); + atlas::array::ArrayView hv = make_host_view( *ds ); + EXPECT( ds->spec().shape()[0] == 32 ); + EXPECT( ds->spec().shape()[1] == 5 ); + EXPECT( ds->spec().shape()[2] == 33 ); - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 32 * 5 * 33); + EXPECT( ds->spec().rank() == 3 ); + EXPECT( ds->spec().size() == 32 * 5 * 33 ); - EXPECT(hv(3, 3, 3) == 4.5); - EXPECT(hv(6, 4, 7) == 7.5); + EXPECT( hv( 3, 3, 3 ) == 4.5 ); + EXPECT( hv( 6, 4, 7 ) == 7.5 ); - delete ds; + delete ds; } -CASE("test_insert") { - Array* ds = Array::create(7, 5, 8); +CASE( "test_insert" ) { + Array* ds = Array::create( 7, 5, 8 ); - EXPECT( ds->hostNeedsUpdate() == false ); - auto hv = make_host_view(*ds); - hv.assign(-1.); + EXPECT( ds->hostNeedsUpdate() == false ); + auto hv = make_host_view( *ds ); + hv.assign( -1. ); - EXPECT( hv(0,0,0) == -1. ); - hv(1, 3, 3) = 1.5; - hv(2, 3, 3) = 2.5; - hv(3, 3, 3) = 3.5; - hv(6, 4, 7) = 6.5; + EXPECT( hv( 0, 0, 0 ) == -1. ); + hv( 1, 3, 3 ) = 1.5; + hv( 2, 3, 3 ) = 2.5; + hv( 3, 3, 3 ) = 3.5; + hv( 6, 4, 7 ) = 6.5; - ds->insert(3, 2); + ds->insert( 3, 2 ); - EXPECT(ds->spec().shape()[0] == 9); - EXPECT(ds->spec().shape()[1] == 5); - EXPECT(ds->spec().shape()[2] == 8); + EXPECT( ds->spec().shape()[0] == 9 ); + EXPECT( ds->spec().shape()[1] == 5 ); + EXPECT( ds->spec().shape()[2] == 8 ); - EXPECT(ds->spec().rank() == 3); - EXPECT(ds->spec().size() == 9 * 5 * 8); + EXPECT( ds->spec().rank() == 3 ); + EXPECT( ds->spec().size() == 9 * 5 * 8 ); - auto hv2 = make_host_view(*ds); + auto hv2 = make_host_view( *ds ); - // currently we have no mechanism to invalidate the old views after an insertion into the Array - // The original gt data store is deleted and replaced, but the former atlas::array::ArrayView keeps a pointer to it - // wihtout noticing it has been deleted +// currently we have no mechanism to invalidate the old views after an insertion +// into the Array +// The original gt data store is deleted and replaced, but the former +// atlas::array::ArrayView keeps a pointer to it +// wihtout noticing it has been deleted #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE - // Following statement seems to contradict previous comment - EXPECT(hv.valid() == false); + // Following statement seems to contradict previous comment + EXPECT( hv.valid() == false ); #endif - EXPECT(hv2.valid() == true); + EXPECT( hv2.valid() == true ); - EXPECT(hv2(1, 3, 3) == 1.5); - EXPECT(hv2(2, 3, 3) == 2.5); - EXPECT(hv2(5, 3, 3) == 3.5); - EXPECT(hv2(8, 4, 7) == 6.5); + EXPECT( hv2( 1, 3, 3 ) == 1.5 ); + EXPECT( hv2( 2, 3, 3 ) == 2.5 ); + EXPECT( hv2( 5, 3, 3 ) == 3.5 ); + EXPECT( hv2( 8, 4, 7 ) == 6.5 ); - delete ds; + delete ds; } -CASE("test_insert_throw") { - Array* ds = Array::create(7, 5, 8); +CASE( "test_insert_throw" ) { + Array* ds = Array::create( 7, 5, 8 ); - EXPECT_THROWS_AS(ds->insert(8, 2), eckit::BadParameter); + EXPECT_THROWS_AS( ds->insert( 8, 2 ), eckit::BadParameter ); } -CASE("test_wrap_storage") { - { - Array* ds = Array::create(4, 5, 6); +CASE( "test_wrap_storage" ) { + { + Array* ds = Array::create( 4, 5, 6 ); - atlas::array::ArrayView hv = make_host_view(*ds); + atlas::array::ArrayView hv = make_host_view( *ds ); - hv(2, 3, 3) = 2.5; + hv( 2, 3, 3 ) = 2.5; - Array* ds_ext = Array::wrap(hv.data(), ds->spec()); + Array* ds_ext = Array::wrap( hv.data(), ds->spec() ); - atlas::array::ArrayView hv_ext = make_host_view(*ds_ext); + atlas::array::ArrayView hv_ext = make_host_view( *ds_ext ); - EXPECT(hv_ext(2, 3, 3) == 2.5); + EXPECT( hv_ext( 2, 3, 3 ) == 2.5 ); - delete ds; - delete ds_ext; - } - { - std::vector v(4*5*6, 0.); - v[ 2*(5*6) + 3*6 + 3 ] = 2.5; - ArrayShape shape{4, 5, 6}; - Array* ds_ext = Array::wrap(v.data(), shape); + delete ds; + delete ds_ext; + } + { + std::vector v( 4 * 5 * 6, 0. ); + v[2 * ( 5 * 6 ) + 3 * 6 + 3] = 2.5; + ArrayShape shape{4, 5, 6}; + Array* ds_ext = Array::wrap( v.data(), shape ); - atlas::array::ArrayView hv_ext = make_host_view(*ds_ext); + atlas::array::ArrayView hv_ext = make_host_view( *ds_ext ); - EXPECT(hv_ext(2, 3, 3) == 2.5); + EXPECT( hv_ext( 2, 3, 3 ) == 2.5 ); - delete ds_ext; - } + delete ds_ext; + } } -CASE("test_assign") { - Array* ds = Array::create(2ul, 3ul, 4ul); - auto hv = make_host_view(*ds); +CASE( "test_assign" ) { + Array* ds = Array::create( 2ul, 3ul, 4ul ); + auto hv = make_host_view( *ds ); - hv.assign(2.5); + hv.assign( 2.5 ); - EXPECT(hv(1, 2, 3) == 2.5); + EXPECT( hv( 1, 2, 3 ) == 2.5 ); - auto lv = hv.slice(1,Range::all(),Range::all()); - lv.assign(5.0); + auto lv = hv.slice( 1, Range::all(), Range::all() ); + lv.assign( 5.0 ); - EXPECT(hv(0, 2, 3) == 2.5); - EXPECT(hv(1, 2, 3) == 5.0); - EXPECT(lv(2, 3) == 5.0); + EXPECT( hv( 0, 2, 3 ) == 2.5 ); + EXPECT( hv( 1, 2, 3 ) == 5.0 ); + EXPECT( lv( 2, 3 ) == 5.0 ); - delete ds; + delete ds; } -CASE("test_ArrayT") { - { - ArrayT ds(2, 3, 4); - - EXPECT(ds.size() == 2 * 3 * 4); - if( NOT_PADDED ) { - EXPECT(ds.stride(0) == 3 * 4); - EXPECT(ds.stride(1) == 4); - EXPECT(ds.stride(2) == 1); +CASE( "test_ArrayT" ) { + { + ArrayT ds( 2, 3, 4 ); + + EXPECT( ds.size() == 2 * 3 * 4 ); + if ( NOT_PADDED ) { + EXPECT( ds.stride( 0 ) == 3 * 4 ); + EXPECT( ds.stride( 1 ) == 4 ); + EXPECT( ds.stride( 2 ) == 1 ); + } + EXPECT( ds.shape( 0 ) == 2 ); + EXPECT( ds.shape( 1 ) == 3 ); + EXPECT( ds.shape( 2 ) == 4 ); } - EXPECT(ds.shape(0) == 2); - EXPECT(ds.shape(1) == 3); - EXPECT(ds.shape(2) == 4); - } - - { - ArrayT ds(make_shape(2, 3, 4)); - - EXPECT(ds.size() == 2 * 3 * 4); - if( NOT_PADDED ) { - EXPECT(ds.stride(0) == 3 * 4); - EXPECT(ds.stride(1) == 4); - EXPECT(ds.stride(2) == 1); + + { + ArrayT ds( make_shape( 2, 3, 4 ) ); + + EXPECT( ds.size() == 2 * 3 * 4 ); + if ( NOT_PADDED ) { + EXPECT( ds.stride( 0 ) == 3 * 4 ); + EXPECT( ds.stride( 1 ) == 4 ); + EXPECT( ds.stride( 2 ) == 1 ); + } + EXPECT( ds.shape( 0 ) == 2 ); + EXPECT( ds.shape( 1 ) == 3 ); + EXPECT( ds.shape( 2 ) == 4 ); } - EXPECT(ds.shape(0) == 2); - EXPECT(ds.shape(1) == 3); - EXPECT(ds.shape(2) == 4); - } - - { - ArrayT ds(ArraySpec(make_shape(2, 3, 4))); - - EXPECT(ds.size() == 2 * 3 * 4); - if( NOT_PADDED ) { - EXPECT(ds.stride(0) == 3 * 4); - EXPECT(ds.stride(1) == 4); - EXPECT(ds.stride(2) == 1); + + { + ArrayT ds( ArraySpec( make_shape( 2, 3, 4 ) ) ); + + EXPECT( ds.size() == 2 * 3 * 4 ); + if ( NOT_PADDED ) { + EXPECT( ds.stride( 0 ) == 3 * 4 ); + EXPECT( ds.stride( 1 ) == 4 ); + EXPECT( ds.stride( 2 ) == 1 ); + } + EXPECT( ds.shape( 0 ) == 2 ); + EXPECT( ds.shape( 1 ) == 3 ); + EXPECT( ds.shape( 2 ) == 4 ); } - EXPECT(ds.shape(0) == 2); - EXPECT(ds.shape(1) == 3); - EXPECT(ds.shape(2) == 4); - } } -CASE("test_valid") { - - { - Array* ds = Array::create(2, 3, 4); +CASE( "test_valid" ) { + { + Array* ds = Array::create( 2, 3, 4 ); - atlas::array::ArrayView hv = make_host_view(*ds); - hv(1, 1, 1) = 4.5; - hv(1, 2, 2) = 7.5; + atlas::array::ArrayView hv = make_host_view( *ds ); + hv( 1, 1, 1 ) = 4.5; + hv( 1, 2, 2 ) = 7.5; - EXPECT(hv.valid() == true); - ds->resize(3, 4, 5); + EXPECT( hv.valid() == true ); + ds->resize( 3, 4, 5 ); - // Only implemented using gridtools storage for now +// Only implemented using gridtools storage for now #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE - EXPECT(hv.valid() == false); + EXPECT( hv.valid() == false ); #endif - delete ds; - } + delete ds; + } } -CASE("test_wrap") { - - array::ArrayT arr_t(3,2); - EXPECT(arr_t.shape(0) == 3); - 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); - - array::ArrayView arrv_t = array::make_view(arr_t); - for(size_t i=0; i < arrv_t.shape(0); ++i) - { - for(size_t j=0; j < arrv_t.shape(1); ++j) - { - arrv_t(i,j) = i*10+j-1; - } +CASE( "test_wrap" ) { + array::ArrayT arr_t( 3, 2 ); + EXPECT( arr_t.shape( 0 ) == 3 ); + 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 ); + + array::ArrayView arrv_t = array::make_view( arr_t ); + for ( size_t i = 0; i < arrv_t.shape( 0 ); ++i ) { + for ( size_t j = 0; j < arrv_t.shape( 1 ); ++j ) { + arrv_t( i, j ) = i * 10 + j - 1; + } } - eckit::SharedPtr arr ( array::Array::wrap(arrv_t.data(), - array::ArraySpec{array::make_shape(3), array::make_strides(arr_t.stride(0) ) } ) ); + eckit::SharedPtr arr( array::Array::wrap( + arrv_t.data(), array::ArraySpec{array::make_shape( 3 ), array::make_strides( arr_t.stride( 0 ) )} ) ); - EXPECT(arr->shape(0) == 3); - EXPECT(arr->stride(0) == arr_t.stride(0) ); - EXPECT(arr->rank() == 1); + EXPECT( arr->shape( 0 ) == 3 ); + EXPECT( arr->stride( 0 ) == arr_t.stride( 0 ) ); + EXPECT( arr->rank() == 1 ); - auto view = make_host_view(*arr); + auto view = make_host_view( *arr ); - EXPECT(view.shape(0) == 3); - EXPECT(view.stride(0) == arr_t.stride(0) ); - EXPECT(view.rank() == 1); + EXPECT( view.shape( 0 ) == 3 ); + EXPECT( view.stride( 0 ) == arr_t.stride( 0 ) ); + EXPECT( view.rank() == 1 ); - EXPECT(view(0) == -1); - EXPECT(view(1) == 9); - EXPECT(view(2) == 19); + EXPECT( view( 0 ) == -1 ); + EXPECT( view( 1 ) == 9 ); + EXPECT( view( 2 ) == 19 ); } #ifdef ATLAS_HAVE_ACC -CASE("test_acc_map") { - Array* ds = Array::create(2, 3, 4); +CASE( "test_acc_map" ) { + Array* ds = Array::create( 2, 3, 4 ); #ifdef ATLAS_HAVE_ACC EXPECT( ds->accMap() == true ); EXPECT( ds->accMap() == true ); #else EXPECT( ds->accMap() == false ); #endif - } #endif @@ -589,8 +585,6 @@ CASE("test_acc_map") { } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } - diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index 916973ff1..bc5f11791 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -4,36 +4,31 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "eckit/memory/SharedPtr.h" -#include "atlas/library/config.h" #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "atlas/array/helpers/ArraySlicer.h" +#include "atlas/library/config.h" +#include "eckit/memory/SharedPtr.h" #include "tests/AtlasTestEnvironment.h" - using namespace atlas::array; using namespace atlas::array::helpers; -template< typename Value, int Rank > +template struct Slice { - using type = typename std::conditional<(Rank==0), - Value, - std::array - >::type; + using type = typename std::conditional<( Rank == 0 ), Value, std::array>::type; }; - - struct Slicer { - template< int Rank, typename ...Args > - static typename Slice::value>::type apply(Args... args) { - typename Slice::value>::type a; - } - +struct Slicer { + template + static typename Slice::value>::type apply( Args... args ) { + typename Slice::value>::type a; + } }; namespace atlas { @@ -41,340 +36,327 @@ namespace test { //----------------------------------------------------------------------------- -CASE( "test_SliceRank" ){ - - static_assert( SliceRank_impl<1,int >::value == 0, "failed" ); - static_assert( SliceRank_impl<1,Range>::value == 1, "failed" ); - - static_assert( SliceRank_impl<2,int, int >::value == 0, "failed" ); - static_assert( SliceRank_impl<2,Range,int >::value == 1, "failed" ); - static_assert( SliceRank_impl<2,Range,Range>::value == 2, "failed" ); - - static_assert( SliceRank_impl<3,int, int ,int >::value == 0, "failed" ); - static_assert( SliceRank_impl<3,Range,int ,int >::value == 1, "failed" ); - static_assert( SliceRank_impl<3,Range,Range,int >::value == 2, "failed" ); - static_assert( SliceRank_impl<3,int, int ,Range>::value == 1, "failed" ); - static_assert( SliceRank_impl<3,Range,int ,Range>::value == 2, "failed" ); - static_assert( SliceRank_impl<3,Range,Range,Range>::value == 3, "failed" ); - static_assert( SliceRank_impl<3,Range,int ,Range>::value == 2, "failed" ); - static_assert( SliceRank_impl<3,int ,int ,Range>::value == 1, "failed" ); - static_assert( SliceRank_impl<3,int ,Range,Range>::value == 2, "failed" ); +CASE( "test_SliceRank" ) { + static_assert( SliceRank_impl<1, int>::value == 0, "failed" ); + static_assert( SliceRank_impl<1, Range>::value == 1, "failed" ); + + static_assert( SliceRank_impl<2, int, int>::value == 0, "failed" ); + static_assert( SliceRank_impl<2, Range, int>::value == 1, "failed" ); + static_assert( SliceRank_impl<2, Range, Range>::value == 2, "failed" ); + + static_assert( SliceRank_impl<3, int, int, int>::value == 0, "failed" ); + static_assert( SliceRank_impl<3, Range, int, int>::value == 1, "failed" ); + static_assert( SliceRank_impl<3, Range, Range, int>::value == 2, "failed" ); + static_assert( SliceRank_impl<3, int, int, Range>::value == 1, "failed" ); + static_assert( SliceRank_impl<3, Range, int, Range>::value == 2, "failed" ); + static_assert( SliceRank_impl<3, Range, Range, Range>::value == 3, "failed" ); + static_assert( SliceRank_impl<3, Range, int, Range>::value == 2, "failed" ); + static_assert( SliceRank_impl<3, int, int, Range>::value == 1, "failed" ); + static_assert( SliceRank_impl<3, int, Range, Range>::value == 2, "failed" ); } #if 1 -CASE( "test_array_slicer_1d" ) -{ - ArrayT arr(10); - auto view = make_view(arr); - view.assign( {0,1,2,3,4,5,6,7,8,9} ); - - using View = decltype(view); - ArraySlicer slicer(view); - - { - auto slice = slicer.apply(Range{0,2}); - static_assert( std::is_same< decltype(slice) , LocalView >::value, "failed" ); - EXPECT( slice.rank() == 1 ); - EXPECT( slice.shape(0) == 2 ); - EXPECT( slice(0) == 0 ); - EXPECT( slice(1) == 1 ); - } - - { - auto slice = slicer.apply(Range{5,10}); - static_assert( std::is_same< decltype(slice) , LocalView >::value, "failed" ); - EXPECT( slice.rank() == 1 ); - EXPECT( slice.shape(0) == 5 ); - EXPECT( slice(0) == 5 ); - EXPECT( slice(1) == 6 ); - EXPECT( slice(2) == 7 ); - EXPECT( slice(3) == 8 ); - EXPECT( slice(4) == 9 ); - } - - { - auto slice = slicer.apply(5); - EXPECT( slice == 5 ); - static_assert( std::is_same< decltype(slice) , Reference >::value, "failed" ); - } - - { - auto slice = slicer.apply(Range::all(),Range::dummy()); - static_assert( std::is_same< decltype(slice) , LocalView >::value, "failed" ); - EXPECT( slice.rank() == 2 ); - EXPECT( slice.shape(0) == 10 ); - EXPECT( slice.shape(1) == 1 ); - EXPECT( slice(0,0) == 0 ); - EXPECT( slice(1,0) == 1 ); - } - +CASE( "test_array_slicer_1d" ) { + ArrayT arr( 10 ); + auto view = make_view( arr ); + view.assign( {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} ); + + using View = decltype( view ); + ArraySlicer slicer( view ); + + { + auto slice = slicer.apply( Range{0, 2} ); + static_assert( std::is_same>::value, "failed" ); + EXPECT( slice.rank() == 1 ); + EXPECT( slice.shape( 0 ) == 2 ); + EXPECT( slice( 0 ) == 0 ); + EXPECT( slice( 1 ) == 1 ); + } + + { + auto slice = slicer.apply( Range{5, 10} ); + static_assert( std::is_same>::value, "failed" ); + EXPECT( slice.rank() == 1 ); + EXPECT( slice.shape( 0 ) == 5 ); + EXPECT( slice( 0 ) == 5 ); + EXPECT( slice( 1 ) == 6 ); + EXPECT( slice( 2 ) == 7 ); + EXPECT( slice( 3 ) == 8 ); + EXPECT( slice( 4 ) == 9 ); + } + + { + auto slice = slicer.apply( 5 ); + EXPECT( slice == 5 ); + static_assert( std::is_same>::value, "failed" ); + } + + { + auto slice = slicer.apply( Range::all(), Range::dummy() ); + static_assert( std::is_same>::value, "failed" ); + EXPECT( slice.rank() == 2 ); + EXPECT( slice.shape( 0 ) == 10 ); + EXPECT( slice.shape( 1 ) == 1 ); + EXPECT( slice( 0, 0 ) == 0 ); + EXPECT( slice( 1, 0 ) == 1 ); + } } #endif -CASE( "test_array_slicer_2d" ) -{ - ArrayT arr(3,5); - auto view = make_view(arr); - view.assign( {11,12,13,14,15, - 21,22,23,24,25, - 31,32,33,34,35, } ); - using View = decltype(view); - ArraySlicer slicer(view); - -// ArraySlicer slicer(view); - - { - auto slice = slicer.apply(Range{0,2},2); - EXPECT( slice.rank() == 1 ); - EXPECT( slice.shape(0) == 2 ); - EXPECT( slice(0) == 13 ); - EXPECT( slice(1) == 23 ); - } - - { - const double& slice = slicer.apply(1,3); - EXPECT( slice == 24 ); - //static_assert( std::is_same< decltype(slice) , double& >::value, "failed" ); - } - - { - auto slice = slicer.apply(Range{0,2},Range::dummy(),Range{1,3}); - static_assert( std::is_same< decltype(slice) , LocalView >::value, "failed" ); - EXPECT( slice.rank() == 3 ); - EXPECT( slice.shape(0) == 2 ); - EXPECT( slice.shape(1) == 1 ); - EXPECT( slice.shape(2) == 2 ); - EXPECT( slice(0,0,0) == 12 ); - EXPECT( slice(0,0,1) == 13 ); - EXPECT( slice(1,0,0) == 22 ); - EXPECT( slice(1,0,1) == 23 ); - } - +CASE( "test_array_slicer_2d" ) { + ArrayT arr( 3, 5 ); + auto view = make_view( arr ); + view.assign( { + 11, + 12, + 13, + 14, + 15, + 21, + 22, + 23, + 24, + 25, + 31, + 32, + 33, + 34, + 35, + } ); + using View = decltype( view ); + ArraySlicer slicer( view ); + + // ArraySlicer slicer(view); + + { + auto slice = slicer.apply( Range{0, 2}, 2 ); + EXPECT( slice.rank() == 1 ); + EXPECT( slice.shape( 0 ) == 2 ); + EXPECT( slice( 0 ) == 13 ); + EXPECT( slice( 1 ) == 23 ); + } + + { + const double& slice = slicer.apply( 1, 3 ); + EXPECT( slice == 24 ); + // static_assert( std::is_same< decltype(slice) , double& >::value, "failed" + // ); + } + + { + auto slice = slicer.apply( Range{0, 2}, Range::dummy(), Range{1, 3} ); + static_assert( std::is_same>::value, "failed" ); + EXPECT( slice.rank() == 3 ); + EXPECT( slice.shape( 0 ) == 2 ); + EXPECT( slice.shape( 1 ) == 1 ); + EXPECT( slice.shape( 2 ) == 2 ); + EXPECT( slice( 0, 0, 0 ) == 12 ); + EXPECT( slice( 0, 0, 1 ) == 13 ); + EXPECT( slice( 1, 0, 0 ) == 22 ); + EXPECT( slice( 1, 0, 1 ) == 23 ); + } } -CASE( "test_array_slicer_3d" ) -{ - ArrayT arr(2,3,5); - auto view = make_view(arr); - view.assign( {111,112,113,114,115, - 121,122,123,124,125, - 131,132,133,134,135, - - 211,212,213,214,215, - 221,222,223,224,225, - 231,232,233,234,235} ); - - using View = decltype(view); - ArraySlicer slicer(view); - - { - auto slice = slicer.apply(Range{0,2},2,Range{2,5}); - EXPECT( slice.rank() == 2 ); - EXPECT( slice.shape(0) == 2 ); - EXPECT( slice.shape(1) == 3 ); - EXPECT( slice(0,0) == 133 ); - EXPECT( slice(0,1) == 134 ); - EXPECT( slice(0,2) == 135 ); - EXPECT( slice(1,0) == 233 ); - EXPECT( slice(1,1) == 234 ); - EXPECT( slice(1,2) == 235 ); - } - - { - auto slice = slicer.apply(0,0,Range::from(3)); - EXPECT( slice.rank() == 1 ); - EXPECT( slice.shape(0) == 2 ); - EXPECT( slice(0) == 114 ); - EXPECT( slice(1) == 115 ); - } - - { - auto slice = slicer.apply(1,Range::all(),3); - EXPECT( slice.rank() == 1 ); - EXPECT( slice.shape(0) == 3 ); - EXPECT( slice(0) == 214 ); - EXPECT( slice(1) == 224 ); - EXPECT( slice(2) == 234 ); - } - - { - const double& slice = slicer.apply(1,2,3); - EXPECT( slice == 234 ); - } - +CASE( "test_array_slicer_3d" ) { + ArrayT arr( 2, 3, 5 ); + auto view = make_view( arr ); + view.assign( {111, 112, 113, 114, 115, 121, 122, 123, 124, 125, 131, 132, 133, 134, 135, + + 211, 212, 213, 214, 215, 221, 222, 223, 224, 225, 231, 232, 233, 234, 235} ); + + using View = decltype( view ); + ArraySlicer slicer( view ); + + { + auto slice = slicer.apply( Range{0, 2}, 2, Range{2, 5} ); + EXPECT( slice.rank() == 2 ); + EXPECT( slice.shape( 0 ) == 2 ); + EXPECT( slice.shape( 1 ) == 3 ); + EXPECT( slice( 0, 0 ) == 133 ); + EXPECT( slice( 0, 1 ) == 134 ); + EXPECT( slice( 0, 2 ) == 135 ); + EXPECT( slice( 1, 0 ) == 233 ); + EXPECT( slice( 1, 1 ) == 234 ); + EXPECT( slice( 1, 2 ) == 235 ); + } + + { + auto slice = slicer.apply( 0, 0, Range::from( 3 ) ); + EXPECT( slice.rank() == 1 ); + EXPECT( slice.shape( 0 ) == 2 ); + EXPECT( slice( 0 ) == 114 ); + EXPECT( slice( 1 ) == 115 ); + } + + { + auto slice = slicer.apply( 1, Range::all(), 3 ); + EXPECT( slice.rank() == 1 ); + EXPECT( slice.shape( 0 ) == 3 ); + EXPECT( slice( 0 ) == 214 ); + EXPECT( slice( 1 ) == 224 ); + EXPECT( slice( 2 ) == 234 ); + } + + { + const double& slice = slicer.apply( 1, 2, 3 ); + EXPECT( slice == 234 ); + } } +CASE( "test_array_slicer_of_slice" ) { + ArrayT arr( 2, 3, 5 ); + auto view = make_view( arr ); + view.assign( {111, 112, 113, 114, 115, 121, 122, 123, 124, 125, 131, 132, 133, 134, 135, -CASE( "test_array_slicer_of_slice" ) -{ - ArrayT arr(2,3,5); - auto view = make_view(arr); - view.assign( {111,112,113,114,115, - 121,122,123,124,125, - 131,132,133,134,135, - - 211,212,213,214,215, - 221,222,223,224,225, - 231,232,233,234,235} ); + 211, 212, 213, 214, 215, 221, 222, 223, 224, 225, 231, 232, 233, 234, 235} ); - using View = decltype(view); - ArraySlicer slicer(view); + using View = decltype( view ); + ArraySlicer slicer( view ); - auto slice = slicer.apply(Range{0,2},2,Range{2,5}); + auto slice = slicer.apply( Range{0, 2}, 2, Range{2, 5} ); - using Slice = decltype(slice); - ArraySlicer subslicer(slice); + using Slice = decltype( slice ); + ArraySlicer subslicer( slice ); - auto subslice1 = subslicer.apply(0,0); - auto subslice2 = subslicer.apply(Range::all(),Range::all()); - auto subslice3 = subslicer.apply(Range::all(),0); - auto subslice4 = subslicer.apply(0,Range::to(2)); + auto subslice1 = subslicer.apply( 0, 0 ); + auto subslice2 = subslicer.apply( Range::all(), Range::all() ); + auto subslice3 = subslicer.apply( Range::all(), 0 ); + auto subslice4 = subslicer.apply( 0, Range::to( 2 ) ); } +CASE( "test_arrayview_slice_type" ) { + ArrayT arr( 2, 3, 5 ); -CASE( "test_arrayview_slice_type" ) -{ - ArrayT arr(2,3,5); - - // Assign - { - auto view = make_view(arr); - view.assign( {111,112,113,114,115, - 121,122,123,124,125, - 131,132,133,134,135, - - 211,212,213,214,215, - 221,222,223,224,225, - 231,232,233,234,235} ); - } - - { - auto read_write_view = make_view(arr); + // Assign + { + auto view = make_view( arr ); + view.assign( {111, 112, 113, 114, 115, 121, 122, 123, 124, 125, 131, 132, 133, 134, 135, - auto slice1 = read_write_view.slice( Range{0,2}, 2, Range{2,5} ); + 211, 212, 213, 214, 215, 221, 222, 223, 224, 225, 231, 232, 233, 234, 235} ); + } - EXPECT( slice1(0,0) == 133 ); - EXPECT( slice1(0,1) == 134 ); - EXPECT( slice1(0,2) == 135 ); - EXPECT( slice1(1,0) == 233 ); - EXPECT( slice1(1,1) == 234 ); - EXPECT( slice1(1,2) == 235 ); + { + auto read_write_view = make_view( arr ); - auto slice2 = read_write_view.slice( Range::all(), Range::to(2), Range::from(3) ); + auto slice1 = read_write_view.slice( Range{0, 2}, 2, Range{2, 5} ); - EXPECT( slice2(0,0,0) == 114 ); - EXPECT( slice2(0,0,1) == 115 ); - EXPECT( slice2(0,1,0) == 124 ); - EXPECT( slice2(0,1,1) == 125 ); - EXPECT( slice2(1,0,0) == 214 ); - EXPECT( slice2(1,0,1) == 215 ); - EXPECT( slice2(1,1,0) == 224 ); - EXPECT( slice2(1,1,1) == 225 ); + EXPECT( slice1( 0, 0 ) == 133 ); + EXPECT( slice1( 0, 1 ) == 134 ); + EXPECT( slice1( 0, 2 ) == 135 ); + EXPECT( slice1( 1, 0 ) == 233 ); + EXPECT( slice1( 1, 1 ) == 234 ); + EXPECT( slice1( 1, 2 ) == 235 ); - auto slice3 = read_write_view.slice( 0, 1, 2 ); + auto slice2 = read_write_view.slice( Range::all(), Range::to( 2 ), Range::from( 3 ) ); - EXPECT( slice3 == 123 ); + EXPECT( slice2( 0, 0, 0 ) == 114 ); + EXPECT( slice2( 0, 0, 1 ) == 115 ); + EXPECT( slice2( 0, 1, 0 ) == 124 ); + EXPECT( slice2( 0, 1, 1 ) == 125 ); + EXPECT( slice2( 1, 0, 0 ) == 214 ); + EXPECT( slice2( 1, 0, 1 ) == 215 ); + EXPECT( slice2( 1, 1, 0 ) == 224 ); + EXPECT( slice2( 1, 1, 1 ) == 225 ); - // Following static assert fails somehow for Cray <= 8.5 (8.6 OK)... - // Using runtime EXPECT instead works fine - //static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); - EXPECT( read_write_view.ACCESS == Intent::ReadWrite ); + auto slice3 = read_write_view.slice( 0, 1, 2 ); - static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); - static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); - static_assert( std::is_same< decltype(slice3), Reference >::value, "failed" ); - } + EXPECT( slice3 == 123 ); - { - auto read_only_view = make_view(arr); + // Following static assert fails somehow for Cray <= 8.5 (8.6 OK)... + // Using runtime EXPECT instead works fine + // static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); + EXPECT( read_write_view.ACCESS == Intent::ReadWrite ); - auto slice1 = read_only_view.slice( Range{0,2}, 2, Range{2,5} ); + static_assert( std::is_same>::value, "failed" ); + static_assert( std::is_same>::value, "failed" ); + static_assert( std::is_same>::value, "failed" ); + } - EXPECT( slice1(0,0) == 133 ); - EXPECT( slice1(0,1) == 134 ); - EXPECT( slice1(0,2) == 135 ); - EXPECT( slice1(1,0) == 233 ); - EXPECT( slice1(1,1) == 234 ); - EXPECT( slice1(1,2) == 235 ); + { + auto read_only_view = make_view( arr ); - auto slice2 = read_only_view.slice( Range::all(), Range::to(2), Range::from(3) ); + auto slice1 = read_only_view.slice( Range{0, 2}, 2, Range{2, 5} ); - EXPECT( slice2(0,0,0) == 114 ); - EXPECT( slice2(0,0,1) == 115 ); - EXPECT( slice2(0,1,0) == 124 ); - EXPECT( slice2(0,1,1) == 125 ); - EXPECT( slice2(1,0,0) == 214 ); - EXPECT( slice2(1,0,1) == 215 ); - EXPECT( slice2(1,1,0) == 224 ); - EXPECT( slice2(1,1,1) == 225 ); + EXPECT( slice1( 0, 0 ) == 133 ); + EXPECT( slice1( 0, 1 ) == 134 ); + EXPECT( slice1( 0, 2 ) == 135 ); + EXPECT( slice1( 1, 0 ) == 233 ); + EXPECT( slice1( 1, 1 ) == 234 ); + EXPECT( slice1( 1, 2 ) == 235 ); - auto slice3 = read_only_view.slice( 0, 1, 2 ); + auto slice2 = read_only_view.slice( Range::all(), Range::to( 2 ), Range::from( 3 ) ); - EXPECT( slice3 == 123 ); + EXPECT( slice2( 0, 0, 0 ) == 114 ); + EXPECT( slice2( 0, 0, 1 ) == 115 ); + EXPECT( slice2( 0, 1, 0 ) == 124 ); + EXPECT( slice2( 0, 1, 1 ) == 125 ); + EXPECT( slice2( 1, 0, 0 ) == 214 ); + EXPECT( slice2( 1, 0, 1 ) == 215 ); + EXPECT( slice2( 1, 1, 0 ) == 224 ); + EXPECT( slice2( 1, 1, 1 ) == 225 ); - const double& slice4 = read_only_view.slice( 0, 1, 2 ); + auto slice3 = read_only_view.slice( 0, 1, 2 ); - EXPECT( slice4 == 123 ); + EXPECT( slice3 == 123 ); - // Following static assert fails somehow for Cray <= 8.5 (8.6 OK)... - // Using runtime EXPECT instead works fine - //static_assert( read_only_view.ACCESS == Intent::ReadOnly, "failed" ); - EXPECT( read_only_view.ACCESS == Intent::ReadOnly ); + const double& slice4 = read_only_view.slice( 0, 1, 2 ); - static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); - static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); - static_assert( std::is_same< decltype(slice3), Reference >::value, "failed" ); - static_assert( std::is_same< decltype(slice4), double const& >::value , "failed" ); + EXPECT( slice4 == 123 ); - } + // Following static assert fails somehow for Cray <= 8.5 (8.6 OK)... + // Using runtime EXPECT instead works fine + // static_assert( read_only_view.ACCESS == Intent::ReadOnly, "failed" ); + EXPECT( read_only_view.ACCESS == Intent::ReadOnly ); - { - const auto const_read_write_view = make_view( arr ); - auto read_write_view = make_view(arr); + static_assert( std::is_same>::value, "failed" ); + static_assert( std::is_same>::value, "failed" ); + static_assert( std::is_same>::value, "failed" ); + static_assert( std::is_same::value, "failed" ); + } - auto slice1 = const_read_write_view.slice( Range{0,2}, 2, Range{2,5} ); + { + const auto const_read_write_view = make_view( arr ); + auto read_write_view = make_view( arr ); - EXPECT( slice1(0,0) == 133 ); - EXPECT( slice1(0,1) == 134 ); - EXPECT( slice1(0,2) == 135 ); - EXPECT( slice1(1,0) == 233 ); - EXPECT( slice1(1,1) == 234 ); - EXPECT( slice1(1,2) == 235 ); + auto slice1 = const_read_write_view.slice( Range{0, 2}, 2, Range{2, 5} ); - auto slice2 = const_read_write_view.slice( Range::all(), Range::to(2), Range::from(3) ); + EXPECT( slice1( 0, 0 ) == 133 ); + EXPECT( slice1( 0, 1 ) == 134 ); + EXPECT( slice1( 0, 2 ) == 135 ); + EXPECT( slice1( 1, 0 ) == 233 ); + EXPECT( slice1( 1, 1 ) == 234 ); + EXPECT( slice1( 1, 2 ) == 235 ); - EXPECT( slice2(0,0,0) == 114 ); - EXPECT( slice2(0,0,1) == 115 ); - EXPECT( slice2(0,1,0) == 124 ); - EXPECT( slice2(0,1,1) == 125 ); - EXPECT( slice2(1,0,0) == 214 ); - EXPECT( slice2(1,0,1) == 215 ); - EXPECT( slice2(1,1,0) == 224 ); - EXPECT( slice2(1,1,1) == 225 ); + auto slice2 = const_read_write_view.slice( Range::all(), Range::to( 2 ), Range::from( 3 ) ); - auto slice3 = const_read_write_view.slice( 0, 1, 2 ); + EXPECT( slice2( 0, 0, 0 ) == 114 ); + EXPECT( slice2( 0, 0, 1 ) == 115 ); + EXPECT( slice2( 0, 1, 0 ) == 124 ); + EXPECT( slice2( 0, 1, 1 ) == 125 ); + EXPECT( slice2( 1, 0, 0 ) == 214 ); + EXPECT( slice2( 1, 0, 1 ) == 215 ); + EXPECT( slice2( 1, 1, 0 ) == 224 ); + EXPECT( slice2( 1, 1, 1 ) == 225 ); - EXPECT( slice3 == 123 ); - - // Following static assert fails somehow for Cray <= 8.5 (8.6 OK)... - // Using runtime EXPECT instead works fine - //static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); - EXPECT( read_write_view.ACCESS == Intent::ReadWrite ); - - static_assert( std::is_same< decltype(slice1), LocalView >::value, "failed" ); - static_assert( std::is_same< decltype(slice2), LocalView >::value, "failed" ); - static_assert( std::is_same< decltype(slice3), Reference >::value, "failed" ); - } + auto slice3 = const_read_write_view.slice( 0, 1, 2 ); + + EXPECT( slice3 == 123 ); + + // Following static assert fails somehow for Cray <= 8.5 (8.6 OK)... + // Using runtime EXPECT instead works fine + // static_assert( read_write_view.ACCESS == Intent::ReadWrite, "failed" ); + EXPECT( read_write_view.ACCESS == Intent::ReadWrite ); + static_assert( std::is_same>::value, "failed" ); + static_assert( std::is_same>::value, "failed" ); + static_assert( std::is_same>::value, "failed" ); + } } - //----------------------------------------------------------------------------- } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } - diff --git a/src/tests/array/test_array_view_util.cc b/src/tests/array/test_array_view_util.cc index 9e1fa0144..1a02e9958 100644 --- a/src/tests/array/test_array_view_util.cc +++ b/src/tests/array/test_array_view_util.cc @@ -4,13 +4,14 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/array_fwd.h" #include "atlas/array/Array.h" #include "atlas/array/ArrayViewUtil.h" +#include "atlas/array_fwd.h" #include "tests/AtlasTestEnvironment.h" using namespace atlas::array; @@ -20,35 +21,32 @@ namespace test { //----------------------------------------------------------------------------- -CASE("test_var_size") { +CASE( "test_var_size" ) { + Array* ds = Array::create( 4ul, 5ul, 7ul, 9ul ); - Array* ds = Array::create(4ul, 5ul, 7ul, 9ul); + auto arrv = make_host_view( *ds ); + EXPECT( ds->size() == 1260 ); - auto arrv = make_host_view(*ds); - EXPECT(ds->size() == 1260); - - EXPECT( get_var_size<0>(arrv) == 315); - EXPECT( get_var_size<1>(arrv) == 252); - EXPECT( get_var_size<2>(arrv) == 180); - EXPECT( get_var_size<3>(arrv) == 140); + EXPECT( get_var_size<0>( arrv ) == 315 ); + EXPECT( get_var_size<1>( arrv ) == 252 ); + EXPECT( get_var_size<2>( arrv ) == 180 ); + EXPECT( get_var_size<3>( arrv ) == 140 ); delete ds; } -CASE("test_get_parallel_dim") { - - Array* ds = Array::create(4ul, 5ul, 7ul, 9ul); +CASE( "test_get_parallel_dim" ) { + Array* ds = Array::create( 4ul, 5ul, 7ul, 9ul ); - auto arrv = make_host_view(*ds); - EXPECT(ds->size() == 1260); + auto arrv = make_host_view( *ds ); + EXPECT( ds->size() == 1260 ); - EXPECT( get_parallel_dim(arrv) == 0); - EXPECT( get_parallel_dim(arrv) == 3); - EXPECT( get_parallel_dim>(arrv) == 1); - EXPECT( get_parallel_dim>(arrv) == 2); + EXPECT( get_parallel_dim( arrv ) == 0 ); + EXPECT( get_parallel_dim( arrv ) == 3 ); + EXPECT( get_parallel_dim>( arrv ) == 1 ); + EXPECT( get_parallel_dim>( arrv ) == 2 ); delete ds; - } //----------------------------------------------------------------------------- @@ -56,8 +54,6 @@ CASE("test_get_parallel_dim") { } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } - diff --git a/src/tests/array/test_svector.cc b/src/tests/array/test_svector.cc index b649b4a0d..f255f5308 100644 --- a/src/tests/array/test_svector.cc +++ b/src/tests/array/test_svector.cc @@ -4,22 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ +#include "atlas/array/SVector.h" #include "atlas/library/config.h" #include "tests/AtlasTestEnvironment.h" -#include "atlas/array/SVector.h" using namespace atlas::array; namespace atlas { namespace test { -CASE( "test_svector" ) -{ - SVector list_ints(2); +CASE( "test_svector" ) { + SVector list_ints( 2 ); list_ints[0] = 3; list_ints[1] = 4; @@ -27,18 +27,17 @@ CASE( "test_svector" ) EXPECT( list_ints[0] == 3 ); EXPECT( list_ints[1] == 4 ); - EXPECT( list_ints.size() == 2); + EXPECT( list_ints.size() == 2 ); list_ints[0]++; list_ints[1]++; - EXPECT( list_ints[0] == 4); - EXPECT( list_ints[1] == 5); + EXPECT( list_ints[0] == 4 ); + EXPECT( list_ints[1] == 5 ); } -CASE( "test_svector_resize" ) -{ - SVector list_ints(2); +CASE( "test_svector_resize" ) { + SVector list_ints( 2 ); list_ints[0] = 3; list_ints[1] = 4; @@ -46,11 +45,11 @@ CASE( "test_svector_resize" ) EXPECT( list_ints[0] == 3 ); EXPECT( list_ints[1] == 4 ); - EXPECT( list_ints.size()== 2); + EXPECT( list_ints.size() == 2 ); - list_ints.resize(5); + list_ints.resize( 5 ); - EXPECT( list_ints.size()== 5); + EXPECT( list_ints.size() == 5 ); list_ints[3] = 5; list_ints[4] = 6; @@ -58,18 +57,15 @@ CASE( "test_svector_resize" ) list_ints[3]++; list_ints[4]++; - EXPECT( list_ints[0] == 3 ); EXPECT( list_ints[1] == 4 ); EXPECT( list_ints[3] == 6 ); EXPECT( list_ints[4] == 7 ); - } -} // namespace test -} // namespace atlas +} // namespace test +} // namespace atlas -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } - diff --git a/src/tests/array/test_table.cc b/src/tests/array/test_table.cc index c59767ac6..0a669834d 100644 --- a/src/tests/array/test_table.cc +++ b/src/tests/array/test_table.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -25,198 +26,193 @@ namespace test { #define IN_FORTRAN #endif -CASE( "test_table" ) -{ +CASE( "test_table" ) { Table table; - EXPECT(table.rows() == 0); - EXPECT(table.maxcols() == 0); - - constexpr idx_t vals[4] = {2,3,5,6}; - table.add(1, 4, vals, /* fortran-array = */ false); - - EXPECT(table.rows() == 1); - EXPECT(table.cols(0) == 4); - EXPECT(table.mincols() == 4); - EXPECT(table.maxcols() == 4); - - auto trv = make_table_view(table); - EXPECT(trv(0,0) == 2); - EXPECT(trv(0,1) == 3); - EXPECT(trv(0,2) == 5); - EXPECT(trv(0,3) == 6); - - EXPECT(trv.row(0)(0) == 2); - EXPECT(trv.row(0)(1) == 3); - EXPECT(trv.row(0)(2) == 5); - EXPECT(trv.row(0)(3) == 6); - - constexpr idx_t vals2[6] = {1,3,4,3,7,8}; - table.add(2, 3, vals2, /* fortran-array = */ true); - - table.dump(Log::info()); Log::info() << std::endl; - - EXPECT(table.rows() == 3); - EXPECT(table.cols(1) == 3); - EXPECT(table.cols(2) == 3); - EXPECT(table.mincols() == 3); - EXPECT(table.maxcols() == 4); - - trv = make_table_view(table); - EXPECT(trv(1,0) == 1 IN_FORTRAN); - EXPECT(trv(1,1) == 3 IN_FORTRAN); - EXPECT(trv(1,2) == 4 IN_FORTRAN); - - EXPECT(trv.row(2)(0) == 3 IN_FORTRAN); - EXPECT(trv.row(2)(1) == 7 IN_FORTRAN); - EXPECT(trv.row(2)(2) == 8 IN_FORTRAN); - - auto twv = make_table_view(table); - twv(1,1) = 9 IN_FORTRAN; - EXPECT(twv(1,0) == 1 IN_FORTRAN); - EXPECT(twv(1,1) == 9 IN_FORTRAN); - EXPECT(twv(1,2) == 4 IN_FORTRAN); - - constexpr idx_t vals3[3] = {6 IN_FORTRAN,7 IN_FORTRAN,5 IN_FORTRAN}; - twv.row(2) = vals3; - EXPECT(twv(2,0) == 6 IN_FORTRAN); - EXPECT(twv(2,1) == 7 IN_FORTRAN); - EXPECT(twv(2,2) == 5 IN_FORTRAN); + EXPECT( table.rows() == 0 ); + EXPECT( table.maxcols() == 0 ); + + constexpr idx_t vals[4] = {2, 3, 5, 6}; + table.add( 1, 4, vals, /* fortran-array = */ false ); + + EXPECT( table.rows() == 1 ); + EXPECT( table.cols( 0 ) == 4 ); + EXPECT( table.mincols() == 4 ); + EXPECT( table.maxcols() == 4 ); + + auto trv = make_table_view( table ); + EXPECT( trv( 0, 0 ) == 2 ); + EXPECT( trv( 0, 1 ) == 3 ); + EXPECT( trv( 0, 2 ) == 5 ); + EXPECT( trv( 0, 3 ) == 6 ); + + EXPECT( trv.row( 0 )( 0 ) == 2 ); + EXPECT( trv.row( 0 )( 1 ) == 3 ); + EXPECT( trv.row( 0 )( 2 ) == 5 ); + EXPECT( trv.row( 0 )( 3 ) == 6 ); + + constexpr idx_t vals2[6] = {1, 3, 4, 3, 7, 8}; + table.add( 2, 3, vals2, /* fortran-array = */ true ); + + table.dump( Log::info() ); + Log::info() << std::endl; + + EXPECT( table.rows() == 3 ); + EXPECT( table.cols( 1 ) == 3 ); + EXPECT( table.cols( 2 ) == 3 ); + EXPECT( table.mincols() == 3 ); + EXPECT( table.maxcols() == 4 ); + + trv = make_table_view( table ); + EXPECT( trv( 1, 0 ) == 1 IN_FORTRAN ); + EXPECT( trv( 1, 1 ) == 3 IN_FORTRAN ); + EXPECT( trv( 1, 2 ) == 4 IN_FORTRAN ); + + EXPECT( trv.row( 2 )( 0 ) == 3 IN_FORTRAN ); + EXPECT( trv.row( 2 )( 1 ) == 7 IN_FORTRAN ); + EXPECT( trv.row( 2 )( 2 ) == 8 IN_FORTRAN ); + + auto twv = make_table_view( table ); + twv( 1, 1 ) = 9 IN_FORTRAN; + EXPECT( twv( 1, 0 ) == 1 IN_FORTRAN ); + EXPECT( twv( 1, 1 ) == 9 IN_FORTRAN ); + EXPECT( twv( 1, 2 ) == 4 IN_FORTRAN ); + + constexpr idx_t vals3[3] = {6 IN_FORTRAN, 7 IN_FORTRAN, 5 IN_FORTRAN}; + twv.row( 2 ) = vals3; + EXPECT( twv( 2, 0 ) == 6 IN_FORTRAN ); + EXPECT( twv( 2, 1 ) == 7 IN_FORTRAN ); + EXPECT( twv( 2, 2 ) == 5 IN_FORTRAN ); // TODO: following statement should not be allowed to compile! - trv.row(2) = vals3; - - constexpr idx_t vals4[8] = {2,11,51,12,4,13,55,78}; - - table.insert(1, 2, 4, vals4, /* fortran-array = */ false); - - EXPECT(table.mincols() == 3); - EXPECT(table.maxcols() == 4); - - EXPECT(table.rows() == 5); - EXPECT(table.cols(0) == 4); - EXPECT(table.cols(1) == 4); - EXPECT(table.cols(2) == 4); - EXPECT(table.cols(3) == 3); - EXPECT(table.cols(4) == 3); - - - trv = make_table_view(table); - EXPECT(trv(1,0) == 2 ); - EXPECT(trv(1,1) == 11 ); - EXPECT(trv(1,2) == 51 ); - EXPECT(trv(1,3) == 12 ); - - EXPECT(trv(2,0) == 4 ); - EXPECT(trv(2,1) == 13 ); - EXPECT(trv(2,2) == 55 ); - EXPECT(trv(2,3) == 78 ); - - EXPECT(trv(3,0) == 1 IN_FORTRAN); - EXPECT(trv(3,1) == 9 IN_FORTRAN); - EXPECT(trv(3,2) == 4 IN_FORTRAN); - - - constexpr idx_t vals5[2] = {3,6}; - table.insert(3, 1, 2, vals5, true); - - EXPECT(table.mincols() == 2); - EXPECT(table.maxcols() == 4); - - EXPECT(table.rows() ==6); - EXPECT(table.cols(3),2); - EXPECT(table.cols(4),3); - - trv = make_table_view(table); - EXPECT(trv(3,0) == 3 IN_FORTRAN); - EXPECT(trv(3,1) == 6 IN_FORTRAN); - - EXPECT(trv(4,0) == 1 IN_FORTRAN); - EXPECT(trv(4,1) == 9 IN_FORTRAN); - EXPECT(trv(4,2) == 4 IN_FORTRAN); - - //insert 3 rows with 1 column - table.insert(4, 3, 1); - - EXPECT(table.rows() == 9); - EXPECT(table.cols(4) == 1); - EXPECT(table.cols(5) == 1); - EXPECT(table.mincols() == 1); - EXPECT(table.maxcols() == 4); - - trv = make_table_view(table); - EXPECT(trv(7,0) == 1 IN_FORTRAN); - EXPECT(trv(7,1) == 9 IN_FORTRAN); - EXPECT(trv(7,2) == 4 IN_FORTRAN); - - constexpr size_t cols[3] = {3,7,1}; - EXPECT(table.cols(2),4); - //insert in position 2, 3 rows with cols[3] number of columns - table.insert(2, 3, cols); - - EXPECT(table.mincols() == 1); - EXPECT(table.maxcols() == 7); - - EXPECT(table.rows() == 12); - EXPECT(table.cols(2) == 3); - EXPECT(table.cols(3) == 7); - EXPECT(table.cols(4) == 1); - EXPECT(table.cols(5) == 4); - - trv = make_table_view(table); - EXPECT(trv(5,0) == 4 ); - EXPECT(trv(5,1) == 13 ); - EXPECT(trv(5,2) == 55 ); - EXPECT(trv(5,3) == 78 ); - + trv.row( 2 ) = vals3; + + constexpr idx_t vals4[8] = {2, 11, 51, 12, 4, 13, 55, 78}; + + table.insert( 1, 2, 4, vals4, /* fortran-array = */ false ); + + EXPECT( table.mincols() == 3 ); + EXPECT( table.maxcols() == 4 ); + + EXPECT( table.rows() == 5 ); + EXPECT( table.cols( 0 ) == 4 ); + EXPECT( table.cols( 1 ) == 4 ); + EXPECT( table.cols( 2 ) == 4 ); + EXPECT( table.cols( 3 ) == 3 ); + EXPECT( table.cols( 4 ) == 3 ); + + trv = make_table_view( table ); + EXPECT( trv( 1, 0 ) == 2 ); + EXPECT( trv( 1, 1 ) == 11 ); + EXPECT( trv( 1, 2 ) == 51 ); + EXPECT( trv( 1, 3 ) == 12 ); + + EXPECT( trv( 2, 0 ) == 4 ); + EXPECT( trv( 2, 1 ) == 13 ); + EXPECT( trv( 2, 2 ) == 55 ); + EXPECT( trv( 2, 3 ) == 78 ); + + EXPECT( trv( 3, 0 ) == 1 IN_FORTRAN ); + EXPECT( trv( 3, 1 ) == 9 IN_FORTRAN ); + EXPECT( trv( 3, 2 ) == 4 IN_FORTRAN ); + + constexpr idx_t vals5[2] = {3, 6}; + table.insert( 3, 1, 2, vals5, true ); + + EXPECT( table.mincols() == 2 ); + EXPECT( table.maxcols() == 4 ); + + EXPECT( table.rows() == 6 ); + EXPECT( table.cols( 3 ), 2 ); + EXPECT( table.cols( 4 ), 3 ); + + trv = make_table_view( table ); + EXPECT( trv( 3, 0 ) == 3 IN_FORTRAN ); + EXPECT( trv( 3, 1 ) == 6 IN_FORTRAN ); + + EXPECT( trv( 4, 0 ) == 1 IN_FORTRAN ); + EXPECT( trv( 4, 1 ) == 9 IN_FORTRAN ); + EXPECT( trv( 4, 2 ) == 4 IN_FORTRAN ); + + // insert 3 rows with 1 column + table.insert( 4, 3, 1 ); + + EXPECT( table.rows() == 9 ); + EXPECT( table.cols( 4 ) == 1 ); + EXPECT( table.cols( 5 ) == 1 ); + EXPECT( table.mincols() == 1 ); + EXPECT( table.maxcols() == 4 ); + + trv = make_table_view( table ); + EXPECT( trv( 7, 0 ) == 1 IN_FORTRAN ); + EXPECT( trv( 7, 1 ) == 9 IN_FORTRAN ); + EXPECT( trv( 7, 2 ) == 4 IN_FORTRAN ); + + constexpr size_t cols[3] = {3, 7, 1}; + EXPECT( table.cols( 2 ), 4 ); + // insert in position 2, 3 rows with cols[3] number of columns + table.insert( 2, 3, cols ); + + EXPECT( table.mincols() == 1 ); + EXPECT( table.maxcols() == 7 ); + + EXPECT( table.rows() == 12 ); + EXPECT( table.cols( 2 ) == 3 ); + EXPECT( table.cols( 3 ) == 7 ); + EXPECT( table.cols( 4 ) == 1 ); + EXPECT( table.cols( 5 ) == 4 ); + + trv = make_table_view( table ); + EXPECT( trv( 5, 0 ) == 4 ); + EXPECT( trv( 5, 1 ) == 13 ); + EXPECT( trv( 5, 2 ) == 55 ); + EXPECT( trv( 5, 3 ) == 78 ); } -CASE( "test_irregular_insert" ) -{ +CASE( "test_irregular_insert" ) { Table table; - EXPECT(table.rows() == 0); - EXPECT(table.maxcols() == 0); - - constexpr idx_t vals[4] = {2,3,5,6}; - table.insert(0, 1, 4, vals, false); - - EXPECT(table.rows() ==1); - EXPECT(table.cols(0) == 4); - EXPECT(table.mincols() == 4); - EXPECT(table.maxcols() == 4); - - auto trv = make_table_view(table); - EXPECT(trv(0,0) == 2 ); - EXPECT(trv(0,1) == 3 ); - EXPECT(trv(0,2) == 5 ); - EXPECT(trv(0,3) == 6 ); - - EXPECT(trv.row(0)(0) == 2); - EXPECT(trv.row(0)(1) == 3); - EXPECT(trv.row(0)(2) == 5); - EXPECT(trv.row(0)(3) == 6); + EXPECT( table.rows() == 0 ); + EXPECT( table.maxcols() == 0 ); + + constexpr idx_t vals[4] = {2, 3, 5, 6}; + table.insert( 0, 1, 4, vals, false ); + + EXPECT( table.rows() == 1 ); + EXPECT( table.cols( 0 ) == 4 ); + EXPECT( table.mincols() == 4 ); + EXPECT( table.maxcols() == 4 ); + + auto trv = make_table_view( table ); + EXPECT( trv( 0, 0 ) == 2 ); + EXPECT( trv( 0, 1 ) == 3 ); + EXPECT( trv( 0, 2 ) == 5 ); + EXPECT( trv( 0, 3 ) == 6 ); + + EXPECT( trv.row( 0 )( 0 ) == 2 ); + EXPECT( trv.row( 0 )( 1 ) == 3 ); + EXPECT( trv.row( 0 )( 2 ) == 5 ); + EXPECT( trv.row( 0 )( 3 ) == 6 ); } -CASE( "test_table_row" ) -{ +CASE( "test_table_row" ) { Table table; - EXPECT(table.rows() == 0); - EXPECT(table.maxcols() == 0); + EXPECT( table.rows() == 0 ); + EXPECT( table.maxcols() == 0 ); - constexpr idx_t vals[4] = {2,3,5,6}; - table.insert(0, 1, 4, vals, /*fortran_array =*/false); + constexpr idx_t vals[4] = {2, 3, 5, 6}; + table.insert( 0, 1, 4, vals, /*fortran_array =*/false ); - auto twv = make_table_view(table); - auto trv = make_table_view(table); + auto twv = make_table_view( table ); + auto trv = make_table_view( table ); - auto row_write = twv.row(0); - auto row_read = trv.row(0); + auto row_write = twv.row( 0 ); + auto row_read = trv.row( 0 ); - EXPECT( row_read(1) == 3 ); - EXPECT( row_write(1) == 3 ); - row_write(1) = 5; - row_write(1) += 2; - EXPECT( row_read(1) == 7 ); - EXPECT( row_write(1) == 7 ); + EXPECT( row_read( 1 ) == 3 ); + EXPECT( row_write( 1 ) == 3 ); + row_write( 1 ) = 5; + row_write( 1 ) += 2; + EXPECT( row_read( 1 ) == 7 ); + EXPECT( row_write( 1 ) == 7 ); } //----------------------------------------------------------------------------- @@ -224,8 +220,6 @@ CASE( "test_table_row" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } - diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index 1191c0387..97fc36393 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -4,26 +4,26 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "tests/AtlasTestEnvironment.h" -#include "eckit/types/Types.h" -#include "eckit/memory/ScopedPtr.h" -#include "atlas/library/Library.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/Spectral.h" +#include "atlas/grid/Grid.h" +#include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" -#include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/mesh/Nodes.h" -#include "atlas/grid/Grid.h" -#include "atlas/field/Field.h" +#include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/trans/Trans.h" - +#include "eckit/memory/ScopedPtr.h" +#include "eckit/types/Types.h" +#include "tests/AtlasTestEnvironment.h" using namespace eckit; using namespace atlas::functionspace; @@ -34,619 +34,591 @@ namespace test { //----------------------------------------------------------------------------- -CASE( "test_functionspace_NodeColumns_no_halo" ) -{ - Grid grid("O8"); - Mesh mesh = meshgenerator::StructuredMeshGenerator().generate(grid); - functionspace::NodeColumns nodes_fs(mesh); - Field field( nodes_fs.createField() ); - array::ArrayView value = array::make_view( field ); - array::ArrayView ghost = array::make_view( mesh.nodes().ghost() ); - const size_t nb_nodes = mesh.nodes().size(); - for( size_t j=0; j() ); + array::ArrayView value = array::make_view( field ); + 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; } + else { + value( j ) = 1; + } } - else - { - value(j) = 1; + nodes_fs.haloExchange( field ); + for ( size_t j = 0; j < nb_nodes; ++j ) { + EXPECT( value( j ) == 1 ); } - } - nodes_fs.haloExchange(field); - for( size_t j=0; j grid( Grid::create("O2") ); +CASE( "test_functionspace_NodeColumns" ) { + // ScopedPtr grid( Grid::create("O2") ); - grid::ReducedGaussianGrid grid( {4,8,8,4} ); + grid::ReducedGaussianGrid grid( {4, 8, 8, 4} ); - meshgenerator::StructuredMeshGenerator generator; - //generator.options.set("3d",true); - Mesh mesh = generator.generate(grid); + meshgenerator::StructuredMeshGenerator generator; + // generator.options.set("3d",true); + Mesh mesh = generator.generate( grid ); - //grid.reset(); + // grid.reset(); + + size_t nb_levels = 10; - size_t nb_levels = 10; + functionspace::NodeColumns nodes_fs( mesh, option::halo( 1 ) | option::levels( nb_levels ) ); + // NodesColumnFunctionSpace columns_fs("columns",mesh,nb_levels,Halo(1)); - functionspace::NodeColumns nodes_fs(mesh,option::halo(1)|option::levels(nb_levels)); - //NodesColumnFunctionSpace columns_fs("columns",mesh,nb_levels,Halo(1)); + // EXPECT( nodes_fs.nb_nodes() == columns_fs.nb_nodes() ); + // EXPECT( columns_fs.nb_levels() == 10 ); - //EXPECT( nodes_fs.nb_nodes() == columns_fs.nb_nodes() ); - //EXPECT( columns_fs.nb_levels() == 10 ); + Field surface_scalar_field = nodes_fs.createField( option::name( "scalar" ) | option::levels( false ) ); + Field surface_vector_field = + nodes_fs.createField( option::name( "vector" ) | option::levels( false ) | option::variables( 2 ) ); + Field surface_tensor_field = + nodes_fs.createField( option::name( "tensor" ) | option::levels( false ) | option::variables( 2 * 2 ) ); + EXPECT( surface_scalar_field.name() == std::string( "scalar" ) ); + EXPECT( surface_vector_field.name() == std::string( "vector" ) ); + EXPECT( surface_tensor_field.name() == std::string( "tensor" ) ); - Field surface_scalar_field = nodes_fs.createField(option::name("scalar")|option::levels(false)); - Field surface_vector_field = nodes_fs.createField(option::name("vector")|option::levels(false)|option::variables(2)); - Field surface_tensor_field = nodes_fs.createField(option::name("tensor")|option::levels(false)|option::variables(2*2)); + EXPECT( surface_scalar_field.size() == nodes_fs.nb_nodes() ); + EXPECT( surface_vector_field.size() == nodes_fs.nb_nodes() * 2 ); + EXPECT( surface_tensor_field.size() == nodes_fs.nb_nodes() * 2 * 2 ); - EXPECT( surface_scalar_field.name() == std::string("scalar") ); - EXPECT( surface_vector_field.name() == std::string("vector") ); - EXPECT( surface_tensor_field.name() == std::string("tensor") ); + EXPECT( surface_scalar_field.rank() == 1 ); + EXPECT( surface_vector_field.rank() == 2 ); + EXPECT( surface_tensor_field.rank() == 2 ); - EXPECT( surface_scalar_field.size() == nodes_fs.nb_nodes() ); - EXPECT( surface_vector_field.size() == nodes_fs.nb_nodes()*2 ); - EXPECT( surface_tensor_field.size() == nodes_fs.nb_nodes()*2*2 ); + EXPECT( surface_scalar_field.levels() == 0 ); + EXPECT( surface_vector_field.levels() == 0 ); + EXPECT( surface_tensor_field.levels() == 0 ); - EXPECT( surface_scalar_field.rank() == 1 ); - EXPECT( surface_vector_field.rank() == 2 ); - EXPECT( surface_tensor_field.rank() == 2 ); + array::ArrayView surface_scalar = array::make_view( surface_scalar_field ); + array::ArrayView surface_vector = array::make_view( surface_vector_field ); + array::ArrayView surface_tensor = array::make_view( surface_tensor_field ); - EXPECT( surface_scalar_field.levels() == 0 ); - EXPECT( surface_vector_field.levels() == 0 ); - EXPECT( surface_tensor_field.levels() == 0 ); + EXPECT( surface_scalar.shape( 0 ) == nodes_fs.nb_nodes() ); + EXPECT( surface_vector.shape( 0 ) == nodes_fs.nb_nodes() ); + EXPECT( surface_tensor.shape( 0 ) == nodes_fs.nb_nodes() ); + EXPECT( surface_vector.shape( 1 ) == 2 ); + EXPECT( surface_tensor.shape( 1 ) == 2 * 2 ); - array::ArrayView surface_scalar = array::make_view( surface_scalar_field ); - array::ArrayView surface_vector = array::make_view( surface_vector_field ); - array::ArrayView surface_tensor = array::make_view( surface_tensor_field ); + Field columns_scalar_field = nodes_fs.createField( option::name( "scalar" ) ); + Field columns_vector_field = nodes_fs.createField( option::name( "vector" ) | option::variables( 2 ) ); + Field columns_tensor_field = nodes_fs.createField( option::name( "tensor" ) | option::variables( 2 * 2 ) ); - EXPECT( surface_scalar.shape(0) == nodes_fs.nb_nodes() ); - EXPECT( surface_vector.shape(0) == nodes_fs.nb_nodes() ); - EXPECT( surface_tensor.shape(0) == nodes_fs.nb_nodes() ); - EXPECT( surface_vector.shape(1) == 2 ); - EXPECT( surface_tensor.shape(1) == 2*2 ); + EXPECT( columns_scalar_field.name() == std::string( "scalar" ) ); + EXPECT( columns_vector_field.name() == std::string( "vector" ) ); + EXPECT( columns_tensor_field.name() == std::string( "tensor" ) ); - Field columns_scalar_field = nodes_fs.createField(option::name("scalar")); - Field columns_vector_field = nodes_fs.createField(option::name("vector")|option::variables(2)); - Field columns_tensor_field = nodes_fs.createField(option::name("tensor")|option::variables(2*2)); + EXPECT( columns_scalar_field.size() == nodes_fs.nb_nodes() * nb_levels ); + EXPECT( columns_vector_field.size() == nodes_fs.nb_nodes() * nb_levels * 2 ); + EXPECT( columns_tensor_field.size() == nodes_fs.nb_nodes() * nb_levels * 2 * 2 ); - EXPECT( columns_scalar_field.name() == std::string("scalar") ); - EXPECT( columns_vector_field.name() == std::string("vector") ); - EXPECT( columns_tensor_field.name() == std::string("tensor") ); + EXPECT( columns_scalar_field.rank() == 2 ); + EXPECT( columns_vector_field.rank() == 3 ); + EXPECT( columns_tensor_field.rank() == 3 ); - EXPECT( columns_scalar_field.size() == nodes_fs.nb_nodes()*nb_levels ); - EXPECT( columns_vector_field.size() == nodes_fs.nb_nodes()*nb_levels*2 ); - EXPECT( columns_tensor_field.size() == nodes_fs.nb_nodes()*nb_levels*2*2 ); + EXPECT( columns_scalar_field.levels() == nb_levels ); + EXPECT( columns_vector_field.levels() == nb_levels ); + EXPECT( columns_tensor_field.levels() == nb_levels ); - EXPECT( columns_scalar_field.rank() == 2 ); - EXPECT( columns_vector_field.rank() == 3 ); - EXPECT( columns_tensor_field.rank() == 3 ); + array::ArrayView columns_scalar = array::make_view( columns_scalar_field ); + array::ArrayView columns_vector = array::make_view( columns_vector_field ); + array::ArrayView columns_tensor = array::make_view( columns_tensor_field ); - EXPECT( columns_scalar_field.levels() == nb_levels ); - EXPECT( columns_vector_field.levels() == nb_levels ); - EXPECT( columns_tensor_field.levels() == nb_levels ); + EXPECT( columns_scalar.shape( 0 ) == nodes_fs.nb_nodes() ); + EXPECT( columns_vector.shape( 0 ) == nodes_fs.nb_nodes() ); + EXPECT( columns_tensor.shape( 0 ) == nodes_fs.nb_nodes() ); + EXPECT( columns_scalar.shape( 1 ) == nb_levels ); + EXPECT( columns_vector.shape( 1 ) == nb_levels ); + EXPECT( columns_tensor.shape( 1 ) == nb_levels ); + EXPECT( columns_vector.shape( 2 ) == 2 ); + EXPECT( columns_tensor.shape( 2 ) == 2 * 2 ); - array::ArrayView columns_scalar = array::make_view( columns_scalar_field ); - array::ArrayView columns_vector = array::make_view( columns_vector_field ); - array::ArrayView columns_tensor = array::make_view( columns_tensor_field ); + Field field = nodes_fs.createField( option::name( "partition" ) ); + array::ArrayView arr = array::make_view( field ); + arr.assign( mpi::comm().rank() ); + // field->dump( Log::info() ); + nodes_fs.haloExchange( field ); + // field->dump( Log::info() ); - EXPECT( columns_scalar.shape(0) == nodes_fs.nb_nodes() ); - EXPECT( columns_vector.shape(0) == nodes_fs.nb_nodes() ); - EXPECT( columns_tensor.shape(0) == nodes_fs.nb_nodes() ); - EXPECT( columns_scalar.shape(1) == nb_levels ); - EXPECT( columns_vector.shape(1) == nb_levels ); - EXPECT( columns_tensor.shape(1) == nb_levels ); - EXPECT( columns_vector.shape(2) == 2 ); - EXPECT( columns_tensor.shape(2) == 2*2 ); + Field field2 = nodes_fs.createField( option::name( "partition2" ) | option::variables( 2 ) ); + Log::info() << "field2.rank() = " << field2.rank() << std::endl; + array::ArrayView arr2 = array::make_view( field2 ); + arr2.assign( mpi::comm().rank() ); - Field field = nodes_fs.createField(option::name("partition")); - array::ArrayView arr = array::make_view(field); - arr.assign(mpi::comm().rank()); - //field->dump( Log::info() ); - nodes_fs.haloExchange(field); - //field->dump( Log::info() ); + // field2->dump( Log::info() ); + nodes_fs.haloExchange( field2 ); + // field2->dump( Log::info() ); - Field field2 = nodes_fs.createField(option::name("partition2")|option::variables(2)); - Log::info() << "field2.rank() = " << field2.rank() << std::endl; - array::ArrayView arr2 = array::make_view(field2); - arr2.assign(mpi::comm().rank()); + Log::info() << nodes_fs.checksum( field ) << std::endl; - //field2->dump( Log::info() ); - nodes_fs.haloExchange(field2); - //field2->dump( Log::info() ); + size_t root = mpi::comm().size() - 1; + Field glb_field = nodes_fs.createField( option::name( "partition" ) | option::datatype( field.datatype() ) | + option::levels( field.levels() ) | option::variables( field.variables() ) | + option::global( root ) ); + nodes_fs.gather( field, glb_field ); - Log::info() << nodes_fs.checksum(field) << std::endl; - - size_t root = mpi::comm().size()-1; - Field glb_field = nodes_fs.createField( - option::name("partition") | - option::datatype(field.datatype()) | - option::levels( field.levels() ) | - option::variables( field.variables() ) | - option::global(root) ); - nodes_fs.gather(field,glb_field); + EXPECT( glb_field.rank() == field.rank() ); + EXPECT( glb_field.levels() == nb_levels ); + EXPECT( field.levels() == nb_levels ); + + Log::info() << "field = " << field << std::endl; + Log::info() << "global_field = " << glb_field << std::endl; + + Log::info() << "local points = " << nodes_fs.nb_nodes() << std::endl; + Log::info() << "grid points = " << grid.size() << std::endl; + Log::info() << "glb_field.shape(0) = " << glb_field.shape( 0 ) << std::endl; + + EXPECT( glb_field.metadata().get( "global" ) == true ); + EXPECT( glb_field.metadata().get( "owner" ) == root ); + + // glb_field->dump( Log::info() ); + + if ( mpi::comm().rank() == root ) glb_field.metadata().set( "test_broadcast", 123 ); + + arr.assign( -1 ); + nodes_fs.scatter( glb_field, field ); + EXPECT( field.metadata().get( "test_broadcast" ) == 123 ); + nodes_fs.haloExchange( field ); + // field->dump( Log::info() ); + + Log::info() << nodes_fs.checksum( field ) << std::endl; + + FieldSet fields; + fields.add( field ); + fields.add( field2 ); + Log::info() << nodes_fs.checksum( fields ) << std::endl; + + Log::info() << "Testing collectives for nodes scalar field" << std::endl; + { + const Field& field = surface_scalar_field; + const functionspace::NodeColumns fs = nodes_fs; + + double max; + double min; + double sum; + double mean; + double stddev; + size_t N; + gidx_t gidx_max; + gidx_t gidx_min; + + array::ArrayView sfc_arr = array::make_view( field ); + sfc_arr.assign( mpi::comm().rank() + 1 ); + fs.maximum( surface_scalar_field, max ); + EXPECT( max == double( mpi::comm().size() ) ); + + fs.minimum( surface_scalar_field, min ); + EXPECT( min == 1 ); + + fs.maximumAndLocation( field, max, gidx_max ); + EXPECT( max == double( mpi::comm().size() ) ); + Log::info() << "global index for maximum: " << gidx_max << std::endl; + + fs.minimumAndLocation( field, min, gidx_min ); + EXPECT( min == 1 ); + Log::info() << "global index for minimum: " << gidx_min << std::endl; + + fs.orderIndependentSum( field, sum, N ); + Log::info() << "oisum: " << sum << std::endl; + Log::info() << "oiN: " << N << std::endl; + + fs.sum( field, sum, N ); + Log::info() << "sum: " << sum << std::endl; + Log::info() << "N: " << N << std::endl; + + fs.mean( field, mean, N ); + Log::info() << "mean: " << mean << std::endl; + Log::info() << "N: " << N << std::endl; + + fs.meanAndStandardDeviation( field, mean, stddev, N ); + Log::info() << "mean: " << mean << std::endl; + Log::info() << "standard deviation: " << stddev << std::endl; + Log::info() << "N: " << N << std::endl; + + int sumint; + fs.orderIndependentSum( field, sumint, N ); + Log::info() << "sumint: " << sumint << std::endl; + + fs.sum( field, sumint, N ); + Log::info() << "sumint: " << sumint << std::endl; + } - EXPECT( glb_field.rank() == field.rank() ); - EXPECT( glb_field.levels() == nb_levels ); - EXPECT( field.levels() == nb_levels ); - - Log::info() << "field = " << field << std::endl; - Log::info() << "global_field = " << glb_field << std::endl; - - Log::info() << "local points = " << nodes_fs.nb_nodes() << std::endl; - Log::info() << "grid points = " << grid.size() << std::endl; - Log::info() << "glb_field.shape(0) = " << glb_field.shape(0) << std::endl; - - EXPECT( glb_field.metadata().get("global") == true ); - EXPECT( glb_field.metadata().get("owner") == root ); - - //glb_field->dump( Log::info() ); - - if( mpi::comm().rank() == root ) - glb_field.metadata().set("test_broadcast",123); - - arr.assign(-1); - nodes_fs.scatter(glb_field,field); - EXPECT( field.metadata().get("test_broadcast") == 123 ); - nodes_fs.haloExchange(field); - //field->dump( Log::info() ); - - Log::info() << nodes_fs.checksum(field) << std::endl; - - FieldSet fields; - fields.add(field); - fields.add(field2); - Log::info() << nodes_fs.checksum(fields) << std::endl; - - - - Log::info() << "Testing collectives for nodes scalar field" << std::endl; - { - const Field& field = surface_scalar_field; - const functionspace::NodeColumns fs = nodes_fs; - - double max; - double min; - double sum; - double mean; - double stddev; - size_t N; - gidx_t gidx_max; - gidx_t gidx_min; - - array::ArrayView sfc_arr = array::make_view( field ); - sfc_arr.assign( mpi::comm().rank()+1 ); - fs.maximum(surface_scalar_field,max); - EXPECT( max == double(mpi::comm().size()) ); - - fs.minimum(surface_scalar_field,min); - EXPECT( min == 1 ); - - fs.maximumAndLocation(field,max,gidx_max); - EXPECT( max == double(mpi::comm().size()) ); - Log::info() << "global index for maximum: " << gidx_max << std::endl; - - fs.minimumAndLocation(field,min,gidx_min); - EXPECT( min == 1 ); - Log::info() << "global index for minimum: " << gidx_min << std::endl; - - fs.orderIndependentSum(field,sum,N); - Log::info() << "oisum: " << sum << std::endl; - Log::info() << "oiN: " << N << std::endl; - - fs.sum(field,sum,N); - Log::info() << "sum: " << sum << std::endl; - Log::info() << "N: " << N << std::endl; - - fs.mean(field,mean,N); - Log::info() << "mean: " << mean << std::endl; - Log::info() << "N: " << N << std::endl; - - fs.meanAndStandardDeviation(field,mean,stddev,N); - Log::info() << "mean: " << mean << std::endl; - Log::info() << "standard deviation: " << stddev << std::endl; - Log::info() << "N: " << N << std::endl; - - int sumint; - fs.orderIndependentSum(field,sumint,N); - Log::info() << "sumint: " << sumint << std::endl; - - fs.sum(field,sumint,N); - Log::info() << "sumint: " << sumint << std::endl; - - } - - - Log::info() << "Testing collectives for nodes vector field" << std::endl; - { - const Field& field = surface_vector_field; - const functionspace::NodeColumns fs = nodes_fs; - - std::vector max; - std::vector min; - std::vector sum; - std::vector mean; - std::vector stddev; - size_t N; - std::vector gidx_max; - std::vector gidx_min; - - auto vec_arr = array::make_view( field ); - vec_arr.assign( mpi::comm().rank()+1 ); - fs.maximum(field, max); - std::vector check_max(field.variables(), mpi::comm().size()); - EXPECT( max == check_max ); - - fs.minimum(field,min); - std::vector check_min(field.variables(), 1); - EXPECT( min == check_min ); - - fs.maximumAndLocation(field,max, gidx_max); - EXPECT( max == check_max ); - Log::info() << "global index for maximum: " << gidx_max << std::endl; - - fs.minimumAndLocation(field,min, gidx_min); - EXPECT( min == check_min ); - Log::info() << "global index for minimum: " << gidx_min << std::endl; - - fs.orderIndependentSum(field,sum,N); - Log::info() << "oisum: " << sum << std::endl; - Log::info() << "oiN: " << N << std::endl; - - fs.mean(field,mean,N); - Log::info() << "mean: " << mean << std::endl; - Log::info() << "N: " << N << std::endl; - - fs.meanAndStandardDeviation(field,mean,stddev,N); - Log::info() << "mean: " << mean << std::endl; - Log::info() << "standard deviation: " << stddev << std::endl; - Log::info() << "N: " << N << std::endl; - - std::vector sumint; - fs.orderIndependentSum(field,sumint,N); - Log::info() << "sumint: " << sumint << std::endl; - - fs.sum(field,sumint,N); - Log::info() << "sumint: " << sumint << std::endl; - - } - - Log::info() << "Testing collectives for columns scalar field" << std::endl; - if(1) { - const Field& field = columns_scalar_field; - const functionspace::NodeColumns fs = nodes_fs; - double max; - double min; - double sum; - double mean; - double stddev; - size_t N; - gidx_t gidx_max; - gidx_t gidx_min; - size_t level; - - EXPECT(field.levels() == nb_levels); - - array::ArrayView arr = array::make_view( field ); - arr.assign( mpi::comm().rank()+1 ); - fs.maximum(field,max); - EXPECT( max == double(mpi::comm().size()) ); - - fs.minimum(field,min); - EXPECT( min == 1 ); - - fs.maximumAndLocation(field,max,gidx_max,level); - EXPECT( max == double(mpi::comm().size()) ); - Log::info() << "global index for maximum: " << gidx_max << std::endl; - Log::info() << "level for maximum: " << level << std::endl; - - fs.minimumAndLocation(field,min,gidx_min,level); - EXPECT( min == 1 ); - Log::info() << "global index for minimum: " << gidx_min << std::endl; - Log::info() << "level for minimum: " << level << std::endl; - - fs.orderIndependentSum(field,sum,N); - Log::info() << "order independent sum: " << sum << std::endl; - Log::info() << "N: " << N << std::endl; - - fs.sum(field,sum,N); - Log::info() << "sum: " << sum << std::endl; - Log::info() << "N: " << N << std::endl; - - fs.mean(field,mean,N); - Log::info() << "mean: " << mean << std::endl; - Log::info() << "N: " << N << std::endl; - - fs.meanAndStandardDeviation(field,mean,stddev,N); - Log::info() << "mean: " << mean << std::endl; - Log::info() << "standard deviation: " << stddev << std::endl; - Log::info() << "N: " << N << std::endl; - - int sumint; - fs.orderIndependentSum(field,sumint,N); - Log::info() << "order independent sum in int: " << sumint << std::endl; - - fs.sum(field,sumint,N); - Log::info() << "sum in int: " << sumint << std::endl; - - Field max_per_level ( "max", array::make_datatype(), array::make_shape(nb_levels) ); - Field min_per_level ( "min", array::make_datatype(), array::make_shape(nb_levels) ); - Field sum_per_level ( "sum", array::make_datatype(), array::make_shape(nb_levels) ); - Field mean_per_level ( "mean", array::make_datatype(), array::make_shape(nb_levels) ); - Field stddev_per_level ( "stddev", array::make_datatype(), array::make_shape(nb_levels) ); - Field gidx_per_level ( "gidx", array::make_datatype(), array::make_shape(nb_levels) ); - - fs.maximumPerLevel(field,max_per_level); - //max_per_level.dump(Log::info()); - fs.minimumPerLevel(field,min_per_level); - //min_per_level.dump(Log::info()); - fs.sumPerLevel(field,sum_per_level,N); - //sum_per_level.dump(Log::info()); - fs.meanPerLevel(field,mean_per_level,N); - //mean_per_level.dump(Log::info()); - fs.meanAndStandardDeviationPerLevel(field,mean_per_level,stddev_per_level,N); - //mean_per_level.dump(Log::info()); - //stddev_per_level.dump(Log::info()); - fs.orderIndependentSumPerLevel(field,sum_per_level,N); - //sum_per_level.dump(Log::info()); - - } - - Log::info() << "Testing collectives for columns vector field" << std::endl; - if(1) { - const Field& field = columns_vector_field; - const functionspace::NodeColumns fs = nodes_fs; - size_t nvar = field.variables(); - std::vector max; - std::vector min; - std::vector sum; - std::vector mean; - std::vector stddev; - size_t N; - std::vector gidx_max; - std::vector gidx_min; - std::vector levels; - - array::ArrayView vec_arr = array::make_view( field ); - vec_arr.assign( mpi::comm().rank()+1 ); - fs.maximum(field,max); - std::vector check_max(nvar,mpi::comm().size()); - EXPECT( max == check_max ); - - fs.minimum(field,min); - std::vector check_min(nvar,1); - EXPECT( min == check_min ); - - fs.maximumAndLocation(field,max,gidx_max,levels); - EXPECT( max == check_max ); - Log::info() << "global index for maximum: " << gidx_max << std::endl; - - fs.minimumAndLocation(field,min,gidx_min,levels); - EXPECT( min == check_min ); - Log::info() << "global index for minimum: " << gidx_min << std::endl; - - fs.orderIndependentSum(field,sum,N); - Log::info() << "oisum: " << sum << std::endl; - Log::info() << "N: " << N << std::endl; - - fs.mean(field,mean,N); - Log::info() << "mean: " << mean << std::endl; - Log::info() << "N: " << N << std::endl; - - fs.meanAndStandardDeviation(field,mean,stddev,N); - Log::info() << "mean: " << mean << std::endl; - Log::info() << "standard deviation: " << stddev << std::endl; - Log::info() << "N: " << N << std::endl; - - std::vector sumint; - fs.orderIndependentSum(field,sumint,N); - Log::info() << "sumint: " << sumint << std::endl; - - fs.sum(field,sumint,N); - Log::info() << "sumint: " << sumint << std::endl; - - Field max_per_level ( "max", array::make_datatype(), array::make_shape(nb_levels,nvar) ); - Field min_per_level ( "min", array::make_datatype(), array::make_shape(nb_levels,nvar) ); - Field sum_per_level ( "sum", array::make_datatype(), array::make_shape(nb_levels,nvar) ); - Field mean_per_level ( "mean", array::make_datatype(), array::make_shape(nb_levels,nvar) ); - Field stddev_per_level ( "stddev", array::make_datatype(), array::make_shape(nb_levels,nvar) ); - Field gidx_per_level ( "gidx", array::make_datatype(), array::make_shape(nb_levels,nvar) ); - - fs.maximumPerLevel(field,max_per_level); - //max_per_level.dump(Log::info()); - - fs.minimumPerLevel(field,min_per_level); - //min_per_level.dump(Log::info()); - - fs.sumPerLevel(field,sum_per_level,N); - //sum_per_level.dump(Log::info()); - - fs.meanPerLevel(field,mean_per_level,N); - //mean_per_level.dump(Log::info()); - - fs.meanAndStandardDeviationPerLevel(field,mean_per_level,stddev_per_level,N); - //mean_per_level.dump(Log::info()); - //stddev_per_level.dump(Log::info()); - - fs.orderIndependentSumPerLevel(field,sum_per_level,N); - //sum_per_level.dump(Log::info()); - } - - - - Field tmp = - nodes_fs.createField( option::datatypeT() | option::global(0) | option::levels(10) | option::name("tmp") ); + Log::info() << "Testing collectives for nodes vector field" << std::endl; + { + const Field& field = surface_vector_field; + const functionspace::NodeColumns fs = nodes_fs; + + std::vector max; + std::vector min; + std::vector sum; + std::vector mean; + std::vector stddev; + size_t N; + std::vector gidx_max; + std::vector gidx_min; + + auto vec_arr = array::make_view( field ); + vec_arr.assign( mpi::comm().rank() + 1 ); + fs.maximum( field, max ); + std::vector check_max( field.variables(), mpi::comm().size() ); + EXPECT( max == check_max ); + + fs.minimum( field, min ); + std::vector check_min( field.variables(), 1 ); + EXPECT( min == check_min ); + + fs.maximumAndLocation( field, max, gidx_max ); + EXPECT( max == check_max ); + Log::info() << "global index for maximum: " << gidx_max << std::endl; + + fs.minimumAndLocation( field, min, gidx_min ); + EXPECT( min == check_min ); + Log::info() << "global index for minimum: " << gidx_min << std::endl; + + fs.orderIndependentSum( field, sum, N ); + Log::info() << "oisum: " << sum << std::endl; + Log::info() << "oiN: " << N << std::endl; + + fs.mean( field, mean, N ); + Log::info() << "mean: " << mean << std::endl; + Log::info() << "N: " << N << std::endl; + + fs.meanAndStandardDeviation( field, mean, stddev, N ); + Log::info() << "mean: " << mean << std::endl; + Log::info() << "standard deviation: " << stddev << std::endl; + Log::info() << "N: " << N << std::endl; + + std::vector sumint; + fs.orderIndependentSum( field, sumint, N ); + Log::info() << "sumint: " << sumint << std::endl; + + fs.sum( field, sumint, N ); + Log::info() << "sumint: " << sumint << std::endl; + } -} + Log::info() << "Testing collectives for columns scalar field" << std::endl; + if ( 1 ) { + const Field& field = columns_scalar_field; + const functionspace::NodeColumns fs = nodes_fs; + double max; + double min; + double sum; + double mean; + double stddev; + size_t N; + gidx_t gidx_max; + gidx_t gidx_min; + size_t level; + + EXPECT( field.levels() == nb_levels ); + + array::ArrayView arr = array::make_view( field ); + arr.assign( mpi::comm().rank() + 1 ); + fs.maximum( field, max ); + EXPECT( max == double( mpi::comm().size() ) ); + + fs.minimum( field, min ); + EXPECT( min == 1 ); + + fs.maximumAndLocation( field, max, gidx_max, level ); + EXPECT( max == double( mpi::comm().size() ) ); + Log::info() << "global index for maximum: " << gidx_max << std::endl; + Log::info() << "level for maximum: " << level << std::endl; + + fs.minimumAndLocation( field, min, gidx_min, level ); + EXPECT( min == 1 ); + Log::info() << "global index for minimum: " << gidx_min << std::endl; + Log::info() << "level for minimum: " << level << std::endl; + + fs.orderIndependentSum( field, sum, N ); + Log::info() << "order independent sum: " << sum << std::endl; + Log::info() << "N: " << N << std::endl; + + fs.sum( field, sum, N ); + Log::info() << "sum: " << sum << std::endl; + Log::info() << "N: " << N << std::endl; + + fs.mean( field, mean, N ); + Log::info() << "mean: " << mean << std::endl; + Log::info() << "N: " << N << std::endl; + + fs.meanAndStandardDeviation( field, mean, stddev, N ); + Log::info() << "mean: " << mean << std::endl; + Log::info() << "standard deviation: " << stddev << std::endl; + Log::info() << "N: " << N << std::endl; + + int sumint; + fs.orderIndependentSum( field, sumint, N ); + Log::info() << "order independent sum in int: " << sumint << std::endl; + + fs.sum( field, sumint, N ); + Log::info() << "sum in int: " << sumint << std::endl; + + Field max_per_level( "max", array::make_datatype(), array::make_shape( nb_levels ) ); + Field min_per_level( "min", array::make_datatype(), array::make_shape( nb_levels ) ); + Field sum_per_level( "sum", array::make_datatype(), array::make_shape( nb_levels ) ); + Field mean_per_level( "mean", array::make_datatype(), array::make_shape( nb_levels ) ); + Field stddev_per_level( "stddev", array::make_datatype(), array::make_shape( nb_levels ) ); + Field gidx_per_level( "gidx", array::make_datatype(), array::make_shape( nb_levels ) ); + + fs.maximumPerLevel( field, max_per_level ); + // max_per_level.dump(Log::info()); + fs.minimumPerLevel( field, min_per_level ); + // min_per_level.dump(Log::info()); + fs.sumPerLevel( field, sum_per_level, N ); + // sum_per_level.dump(Log::info()); + fs.meanPerLevel( field, mean_per_level, N ); + // mean_per_level.dump(Log::info()); + fs.meanAndStandardDeviationPerLevel( field, mean_per_level, stddev_per_level, N ); + // mean_per_level.dump(Log::info()); + // stddev_per_level.dump(Log::info()); + fs.orderIndependentSumPerLevel( field, sum_per_level, N ); + // sum_per_level.dump(Log::info()); + } + Log::info() << "Testing collectives for columns vector field" << std::endl; + if ( 1 ) { + const Field& field = columns_vector_field; + const functionspace::NodeColumns fs = nodes_fs; + size_t nvar = field.variables(); + std::vector max; + std::vector min; + std::vector sum; + std::vector mean; + std::vector stddev; + size_t N; + std::vector gidx_max; + std::vector gidx_min; + std::vector levels; + + array::ArrayView vec_arr = array::make_view( field ); + vec_arr.assign( mpi::comm().rank() + 1 ); + fs.maximum( field, max ); + std::vector check_max( nvar, mpi::comm().size() ); + EXPECT( max == check_max ); + + fs.minimum( field, min ); + std::vector check_min( nvar, 1 ); + EXPECT( min == check_min ); + + fs.maximumAndLocation( field, max, gidx_max, levels ); + EXPECT( max == check_max ); + Log::info() << "global index for maximum: " << gidx_max << std::endl; + + fs.minimumAndLocation( field, min, gidx_min, levels ); + EXPECT( min == check_min ); + Log::info() << "global index for minimum: " << gidx_min << std::endl; + + fs.orderIndependentSum( field, sum, N ); + Log::info() << "oisum: " << sum << std::endl; + Log::info() << "N: " << N << std::endl; + + fs.mean( field, mean, N ); + Log::info() << "mean: " << mean << std::endl; + Log::info() << "N: " << N << std::endl; + + fs.meanAndStandardDeviation( field, mean, stddev, N ); + Log::info() << "mean: " << mean << std::endl; + Log::info() << "standard deviation: " << stddev << std::endl; + Log::info() << "N: " << N << std::endl; + + std::vector sumint; + fs.orderIndependentSum( field, sumint, N ); + Log::info() << "sumint: " << sumint << std::endl; + + fs.sum( field, sumint, N ); + Log::info() << "sumint: " << sumint << std::endl; + + Field max_per_level( "max", array::make_datatype(), array::make_shape( nb_levels, nvar ) ); + Field min_per_level( "min", array::make_datatype(), array::make_shape( nb_levels, nvar ) ); + Field sum_per_level( "sum", array::make_datatype(), array::make_shape( nb_levels, nvar ) ); + Field mean_per_level( "mean", array::make_datatype(), array::make_shape( nb_levels, nvar ) ); + Field stddev_per_level( "stddev", array::make_datatype(), array::make_shape( nb_levels, nvar ) ); + Field gidx_per_level( "gidx", array::make_datatype(), array::make_shape( nb_levels, nvar ) ); + + fs.maximumPerLevel( field, max_per_level ); + // max_per_level.dump(Log::info()); + + fs.minimumPerLevel( field, min_per_level ); + // min_per_level.dump(Log::info()); + + fs.sumPerLevel( field, sum_per_level, N ); + // sum_per_level.dump(Log::info()); + + fs.meanPerLevel( field, mean_per_level, N ); + // mean_per_level.dump(Log::info()); + + fs.meanAndStandardDeviationPerLevel( field, mean_per_level, stddev_per_level, N ); + // mean_per_level.dump(Log::info()); + // stddev_per_level.dump(Log::info()); + + fs.orderIndependentSumPerLevel( field, sum_per_level, N ); + // sum_per_level.dump(Log::info()); + } -CASE( "test_SpectralFunctionSpace" ) -{ - size_t truncation = 159; - size_t nb_levels = 10; - size_t nspec2g = (truncation+1)*(truncation+2); + Field tmp = nodes_fs.createField( option::datatypeT() | option::global( 0 ) | option::levels( 10 ) | + option::name( "tmp" ) ); +} - Spectral spectral_fs(truncation); +CASE( "test_SpectralFunctionSpace" ) { + size_t truncation = 159; + size_t nb_levels = 10; + size_t nspec2g = ( truncation + 1 ) * ( truncation + 2 ); - Field surface_scalar_field = spectral_fs.createField( option::name("scalar") ); + Spectral spectral_fs( truncation ); - EXPECT( surface_scalar_field.name() == std::string("scalar") ); + Field surface_scalar_field = spectral_fs.createField( option::name( "scalar" ) ); - EXPECT( surface_scalar_field.size() == nspec2g ); + EXPECT( surface_scalar_field.name() == std::string( "scalar" ) ); - EXPECT( surface_scalar_field.rank() == 1 ); + EXPECT( surface_scalar_field.size() == nspec2g ); - auto surface_scalar = array::make_view( surface_scalar_field ); + EXPECT( surface_scalar_field.rank() == 1 ); - EXPECT( surface_scalar.shape(0) == nspec2g ); + auto surface_scalar = array::make_view( surface_scalar_field ); - Field columns_scalar_field = spectral_fs.createField( option::name("scalar") | option::levels(nb_levels) ); + EXPECT( surface_scalar.shape( 0 ) == nspec2g ); - EXPECT( columns_scalar_field.name() == std::string("scalar") ); + Field columns_scalar_field = + spectral_fs.createField( option::name( "scalar" ) | option::levels( nb_levels ) ); - EXPECT( columns_scalar_field.size() == nspec2g*nb_levels ); + EXPECT( columns_scalar_field.name() == std::string( "scalar" ) ); - EXPECT( columns_scalar_field.rank() == 2 ); + EXPECT( columns_scalar_field.size() == nspec2g * nb_levels ); - auto columns_scalar = array::make_view( columns_scalar_field ); + EXPECT( columns_scalar_field.rank() == 2 ); - EXPECT( columns_scalar.shape(0) == nspec2g ); - EXPECT( columns_scalar.shape(1) == nb_levels ); + auto columns_scalar = array::make_view( columns_scalar_field ); + EXPECT( columns_scalar.shape( 0 ) == nspec2g ); + EXPECT( columns_scalar.shape( 1 ) == nb_levels ); } - #ifdef ATLAS_HAVE_TRANS -CASE( "test_SpectralFunctionSpace_trans_dist" ) -{ - trans::Trans trans(Grid("F80"),159); - size_t nb_levels(10); - - Spectral spectral_fs( trans ); - size_t nspec2 = spectral_fs.nb_spectral_coefficients(); +CASE( "test_SpectralFunctionSpace_trans_dist" ) { + trans::Trans trans( Grid( "F80" ), 159 ); + size_t nb_levels( 10 ); - Field surface_scalar_field = spectral_fs.createField( option::name("scalar") ); + Spectral spectral_fs( trans ); + size_t nspec2 = spectral_fs.nb_spectral_coefficients(); - EXPECT( surface_scalar_field.name() == std::string("scalar") ); + Field surface_scalar_field = spectral_fs.createField( option::name( "scalar" ) ); - EXPECT( surface_scalar_field.size() == nspec2 ); + EXPECT( surface_scalar_field.name() == std::string( "scalar" ) ); - EXPECT( surface_scalar_field.rank() == 1 ); + EXPECT( surface_scalar_field.size() == nspec2 ); - auto surface_scalar = array::make_view( surface_scalar_field ); + EXPECT( surface_scalar_field.rank() == 1 ); - EXPECT( surface_scalar.shape(0) == nspec2 ); - // size_t surface_scalar_shape[] = { nspec2 }; - // EXPECT( eckit::testing::make_view( surface_scalar.shape(),surface_scalar.shape()+1) == eckit::testing::make_view(surface_scalar_shape,surface_scalar_shape+1) ); + auto surface_scalar = array::make_view( surface_scalar_field ); - Field columns_scalar_field = spectral_fs.createField( option::name("scalar") | option::levels(nb_levels) ); + EXPECT( surface_scalar.shape( 0 ) == nspec2 ); + // size_t surface_scalar_shape[] = { nspec2 }; + // EXPECT( eckit::testing::make_view( + // surface_scalar.shape(),surface_scalar.shape()+1) == + // eckit::testing::make_view(surface_scalar_shape,surface_scalar_shape+1) ); - EXPECT( columns_scalar_field.name() == std::string("scalar") ); + Field columns_scalar_field = + spectral_fs.createField( option::name( "scalar" ) | option::levels( nb_levels ) ); - EXPECT( columns_scalar_field.size() == nspec2*nb_levels ); + EXPECT( columns_scalar_field.name() == std::string( "scalar" ) ); - EXPECT( columns_scalar_field.rank() == 2 ); + EXPECT( columns_scalar_field.size() == nspec2 * nb_levels ); - auto columns_scalar = array::make_view( columns_scalar_field ); + EXPECT( columns_scalar_field.rank() == 2 ); - EXPECT(columns_scalar.shape(0) == nspec2); - EXPECT(columns_scalar.shape(1) == nb_levels); - // size_t columns_scalar_shape[] = { nspec2, nb_levels }; - // EXPECT(eckit::testing::make_view(columns_scalar.shape(),columns_scalar.shape()+2) == eckit::testing::make_view(columns_scalar_shape,columns_scalar_shape+2)); + auto columns_scalar = array::make_view( columns_scalar_field ); + EXPECT( columns_scalar.shape( 0 ) == nspec2 ); + EXPECT( columns_scalar.shape( 1 ) == nb_levels ); + // size_t columns_scalar_shape[] = { nspec2, nb_levels }; + // EXPECT(eckit::testing::make_view(columns_scalar.shape(),columns_scalar.shape()+2) + // == eckit::testing::make_view(columns_scalar_shape,columns_scalar_shape+2)); } -CASE( "test_SpectralFunctionSpace_trans_global" ) -{ - size_t nb_levels(10); - size_t truncation = 159; +CASE( "test_SpectralFunctionSpace_trans_global" ) { + size_t nb_levels( 10 ); + size_t truncation = 159; - Spectral spectral_fs( truncation, option::levels(nb_levels) ); - size_t nspec2g = spectral_fs.nb_spectral_coefficients_global(); + Spectral spectral_fs( truncation, option::levels( nb_levels ) ); + size_t nspec2g = spectral_fs.nb_spectral_coefficients_global(); - Field surface_scalar_field = spectral_fs.createField( - option::name("scalar") | - option::levels(false) | - option::global() ); + Field surface_scalar_field = + spectral_fs.createField( option::name( "scalar" ) | option::levels( false ) | option::global() ); - EXPECT( surface_scalar_field.name() == std::string("scalar") ); + 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 ); + EXPECT( surface_scalar_field.rank() == 1 ); - EXPECT( surface_scalar_field.metadata().get("global") ); + EXPECT( surface_scalar_field.metadata().get( "global" ) ); - EXPECT( surface_scalar_field.metadata().get("owner") == 0 ); + EXPECT( surface_scalar_field.metadata().get( "owner" ) == 0 ); - auto surface_scalar = array::make_view( surface_scalar_field ); + auto surface_scalar = array::make_view( surface_scalar_field ); - if( eckit::mpi::comm().rank() == 0 ) { - EXPECT( surface_scalar.shape(0) == nspec2g ); - } - Field columns_scalar_field = spectral_fs.createField( - option::name("scalar") | - option::global() ); + 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") ); + EXPECT( columns_scalar_field.name() == std::string( "scalar" ) ); - if( eckit::mpi::comm().rank() == 0 ) { - EXPECT( columns_scalar_field.size() == nspec2g*nb_levels ); - } else { - EXPECT( columns_scalar_field.size() == 0 ); - } + if ( eckit::mpi::comm().rank() == 0 ) { EXPECT( columns_scalar_field.size() == nspec2g * nb_levels ); } + else { + EXPECT( columns_scalar_field.size() == 0 ); + } - EXPECT( columns_scalar_field.rank() == 2 ); + EXPECT( columns_scalar_field.rank() == 2 ); - auto columns_scalar = array::make_view( columns_scalar_field ); + auto columns_scalar = array::make_view( columns_scalar_field ); - if( eckit::mpi::comm().rank() == 0 ) { - EXPECT( columns_scalar.shape(0) == nspec2g ); - EXPECT( columns_scalar.shape(1) == nb_levels ); - } + if ( eckit::mpi::comm().rank() == 0 ) { + EXPECT( columns_scalar.shape( 0 ) == nspec2g ); + EXPECT( columns_scalar.shape( 1 ) == nb_levels ); + } } -CASE( "test_SpectralFunctionSpace_norm" ) -{ - trans::Trans trans(Grid("F80"),159); - size_t nb_levels(10); - - Spectral spectral_fs( trans ); - - Field twoD_field = spectral_fs.createField( option::name("2d")); - Field threeD_field = spectral_fs.createField( option::name("3d") | option::levels(nb_levels) ); - - // Set first wave number - { - auto twoD = array::make_view( twoD_field ); - twoD.assign(0.); - if( mpi::comm().rank() == 0 ) twoD(0) = 1.; - - auto threeD = array::make_view( threeD_field ); - threeD.assign(0.); - for( size_t jlev=0; jlev( option::name( "2d" ) ); + Field threeD_field = spectral_fs.createField( option::name( "3d" ) | option::levels( nb_levels ) ); + + // Set first wave number + { + auto twoD = array::make_view( twoD_field ); + twoD.assign( 0. ); + 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; + } } - } - double twoD_norm(0.); - std::vector threeD_norms(threeD_field.levels(),0.); + double twoD_norm( 0. ); + std::vector threeD_norms( threeD_field.levels(), 0. ); - spectral_fs.norm(twoD_field,twoD_norm); - spectral_fs.norm(threeD_field,threeD_norms); + spectral_fs.norm( twoD_field, twoD_norm ); + spectral_fs.norm( threeD_field, threeD_norms ); - if( eckit::mpi::comm().rank() == 0 ) { - EXPECT( eckit::types::is_approximately_equal(twoD_norm, 1.0) ); // before is_approximately_equal tolerance was 1.e-10 - for( size_t jlev=0; jlev(), array::make_shape(10,2) ); - auto xy = array::make_view(points); - xy.assign( { - 00. , 0., - 10. , 0., - 20. , 0., - 30. , 0., - 40. , 0., - 50. , 0., - 60. , 0., - 70. , 0., - 80. , 0., - 90. , 0. - } ); - - functionspace::PointCloud pointcloud( points ); - EXPECT( pointcloud.size() == 10 ); - - points.dump( Log::info() ); - Log::info() << std::endl; +CASE( "test_functionspace_PointCloud" ) { + Field points( "points", array::make_datatype(), array::make_shape( 10, 2 ) ); + auto xy = array::make_view( points ); + xy.assign( {00., 0., 10., 0., 20., 0., 30., 0., 40., 0., 50., 0., 60., 0., 70., 0., 80., 0., 90., 0.} ); + + functionspace::PointCloud pointcloud( points ); + EXPECT( pointcloud.size() == 10 ); + points.dump( Log::info() ); + Log::info() << std::endl; } //----------------------------------------------------------------------------- @@ -55,7 +41,6 @@ CASE( "test_functionspace_PointCloud" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/functionspace/test_structuredcolumns.cc b/src/tests/functionspace/test_structuredcolumns.cc index 17a1fe099..19d6945bd 100644 --- a/src/tests/functionspace/test_structuredcolumns.cc +++ b/src/tests/functionspace/test_structuredcolumns.cc @@ -4,30 +4,29 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - -#include "eckit/types/Types.h" -#include "eckit/memory/ScopedPtr.h" -#include "atlas/library/Library.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/StructuredColumns.h" #include "atlas/grid/Grid.h" -#include "atlas/field/Field.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/output/Gmsh.h" +#include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" #include "atlas/meshgenerator/MeshGenerator.h" +#include "atlas/output/Gmsh.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/MicroDeg.h" +#include "eckit/memory/ScopedPtr.h" +#include "eckit/types/Types.h" #include "tests/AtlasTestEnvironment.h" - using namespace eckit; using namespace atlas::functionspace; using namespace atlas::util; @@ -37,168 +36,216 @@ namespace test { //----------------------------------------------------------------------------- -CASE( "test_functionspace_StructuredColumns_no_halo" ) -{ - int root=0; - Grid grid("O8"); - util::Config config; - config.set("halo",0); - functionspace::StructuredColumns fs(grid, grid::Partitioner("equal_regions"), config ); - - Field field = fs.createField( option::name("field") ); - Field field_glb = fs.createField( option::name("field_global") | option::global(root)); - - auto value = array::make_view( field ); - auto value_glb = array::make_view( field_glb ); - - value.assign(mpi::comm().rank()); - - fs.gather(field,field_glb); - - Log::info() << "field checksum = " << fs.checksum(field) << std::endl; - -// for( size_t j=0; j check{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; - - EXPECT( value_glb.size() == check.size() ); - for( size_t j=0; j( option::name( "field" ) ); + Field field_glb = fs.createField( option::name( "field_global" ) | option::global( root ) ); + + auto value = array::make_view( field ); + auto value_glb = array::make_view( field_glb ); + + value.assign( mpi::comm().rank() ); + + fs.gather( field, field_glb ); + + Log::info() << "field checksum = " << fs.checksum( field ) << std::endl; + + // for( size_t j=0; j check{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; + + EXPECT( value_glb.size() == check.size() ); + for ( size_t j = 0; j < value_glb.size(); ++j ) { + EXPECT( value_glb( j ) == check[j] ); + } } - } - output::Gmsh gmsh("structured.msh"); + output::Gmsh gmsh( "structured.msh" ); - gmsh.write( MeshGenerator("structured").generate(grid) ); - gmsh.write( field ); + gmsh.write( MeshGenerator( "structured" ).generate( grid ) ); + gmsh.write( field ); } -CASE( "test_functionspace_StructuredColumns_halo" ) -{ - ATLAS_DEBUG_VAR( mpi::comm().size() ); - int root=0; -// grid::StructuredGrid grid( -// grid::StructuredGrid::XSpace( {0.,360.} , {2,4,6,6,4,2} , false ), -// grid::StructuredGrid::YSpace( grid::LinearSpacing( {80.,-80.}, 6 ) ), -// Projection(), -// Domain() ); - - std::string gridname = eckit::Resource("--grid","O8"); - - grid::StructuredGrid grid(gridname); - - int halo = eckit::Resource("--halo",2); - util::Config config; - config.set("halo",halo); - functionspace::StructuredColumns fs(grid, grid::Partitioner("equal_regions"), config ); - - Field field = fs.createField( option::name("field") ); - - auto value = array::make_view( field ); - auto xy = array::make_view( fs.xy() ); - auto g = array::make_view( fs.global_index() ); - auto r = array::make_view( fs.remote_index() ); - auto p = array::make_view( fs.partition() ); - - for( idx_t j=fs.j_begin(); j( "--grid", "O8" ); + + grid::StructuredGrid grid( gridname ); + + int halo = eckit::Resource( "--halo", 2 ); + util::Config config; + config.set( "halo", halo ); + functionspace::StructuredColumns fs( grid, grid::Partitioner( "equal_regions" ), config ); + + Field field = fs.createField( option::name( "field" ) ); + + auto value = array::make_view( field ); + auto xy = array::make_view( fs.xy() ); + auto g = array::make_view( fs.global_index() ); + auto r = array::make_view( fs.remote_index() ); + auto p = array::make_view( fs.partition() ); + + for ( idx_t j = fs.j_begin(); j < fs.j_end(); ++j ) { + for ( idx_t i = fs.i_begin( j ); i < fs.i_end( j ); ++i ) { + idx_t n = fs.index( i, j ); + value( n ) = util::microdeg( xy( n, XX ) ); + } } - } - - //EXPECT( fs.checksum(field) == "cef2694016492d408fa157b7c59ce741" ); - - fs.haloExchange(field); - - //EXPECT( fs.checksum(field) == "cef2694016492d408fa157b7c59ce741" ); - - eckit::PathName filepath("test_functionspace_StructuredColumns_halo_p"+std::to_string(mpi::comm().rank())+".py"); - - std::ofstream f(filepath.asString().c_str(), std::ios::trunc ); - - f << "\n" "import matplotlib.pyplot as plt" - "\n" "from matplotlib.path import Path" - "\n" "import matplotlib.patches as patches" - "\n" "" - "\n" "from itertools import cycle" - "\n" "import matplotlib.cm as cm" - "\n" "import numpy as np" - "\n" "" - "\n" "fig = plt.figure(figsize=(20,10))" - "\n" "ax = fig.add_subplot(111,aspect='equal')" - "\n" ""; - - double xmin= std::numeric_limits::max(); - double xmax=-std::numeric_limits::max(); - double ymin= std::numeric_limits::max(); - double ymax=-std::numeric_limits::max(); - f << "\n" "x = ["; - for( idx_t j=fs.j_begin_halo(); j::max(); + double xmax = -std::numeric_limits::max(); + double ymin = std::numeric_limits::max(); + double ymax = -std::numeric_limits::max(); + f << "\n" + "x = ["; + for ( idx_t j = fs.j_begin_halo(); j < fs.j_end_halo(); ++j ) { + for ( idx_t i = fs.i_begin_halo( j ); i < fs.i_end_halo( j ); ++i ) { + idx_t n = fs.index( i, j ); + f << xy( n, XX ) << ", "; + xmin = std::min( xmin, xy( n, XX ) ); + xmax = std::max( xmax, xy( n, XX ) ); + } } - } - f << "]"; - - f << "\n" "y = ["; - for( idx_t j=fs.j_begin_halo(); j(), array::make_shape(10,2)); - const array::Array& const_array = field; - array::Array& array = field; + Grid g( "O6" ); - array::ArrayView arrv = array::make_view(array); - arrv(0,0) = 8.; + Field arr( util::Config( "creator", "ArraySpec" )( "shape", array::make_shape( 10, 2 ) ) ); + EXPECT( arr.shape( 0 ) == 10 ); + EXPECT( arr.shape( 1 ) == 2 ); + EXPECT( arr.datatype() == array::DataType::real64() ); - const array::ArrayView carrv = array::make_view(const_array); - EXPECT( carrv(0,0) == 8. ); + util::Config ifs_parameters = util::Config( "creator", "IFS" )( "nlev", 137 )( "nproma", 10 )( "ngptot", g.size() ); - const array::ArrayView cfieldv = array::make_view(field); - EXPECT( cfieldv(0,0) == 8. ); + Log::info() << "Creating IFS field " << std::endl; + Field ifs( util::Config( ifs_parameters )( "name", "myfield" )( "datatype", array::DataType::int32().str() )( + "nvar", 8 ) ); - take_array(field); - TakeArray ta(field); + ATLAS_DEBUG_VAR( ifs ); + EXPECT( ifs.shape( 0 ) == 36 ); + EXPECT( ifs.shape( 1 ) == 8 ); + EXPECT( ifs.shape( 2 ) == 137 ); + EXPECT( ifs.shape( 3 ) == 10 ); - const Field& f = field; - TakeArray cta(f); + Log::flush(); } +CASE( "test_implicit_conversion" ) { + Field field( "tmp", array::make_datatype(), array::make_shape( 10, 2 ) ); + const array::Array& const_array = field; + array::Array& array = field; + + array::ArrayView arrv = array::make_view( array ); + arrv( 0, 0 ) = 8.; -CASE( "test_wrap_rawdata_through_array" ) -{ - std::vector rawdata(20,8.); - SharedPtr array( array::Array::wrap(rawdata.data(),array::make_shape(10,2)) ); - Field field( "wrapped",array.get() ); + const array::ArrayView carrv = array::make_view( const_array ); + EXPECT( carrv( 0, 0 ) == 8. ); - EXPECT( array->owners() == 2 ); - const array::ArrayView cfieldv = array::make_view(field); - EXPECT( cfieldv(9,1) == 8. ); + const array::ArrayView cfieldv = array::make_view( field ); + EXPECT( cfieldv( 0, 0 ) == 8. ); + + take_array( field ); + TakeArray ta( field ); + + const Field& f = field; + TakeArray cta( f ); +} + +CASE( "test_wrap_rawdata_through_array" ) { + std::vector rawdata( 20, 8. ); + SharedPtr array( array::Array::wrap( rawdata.data(), array::make_shape( 10, 2 ) ) ); + Field field( "wrapped", array.get() ); + + EXPECT( array->owners() == 2 ); + const array::ArrayView cfieldv = array::make_view( field ); + EXPECT( cfieldv( 9, 1 ) == 8. ); } -CASE( "test_wrap_rawdata_direct" ) -{ - std::vector rawdata(20,8.); - Field field( "wrapped",rawdata.data(),array::make_shape(10,2) ); +CASE( "test_wrap_rawdata_direct" ) { + std::vector rawdata( 20, 8. ); + Field field( "wrapped", rawdata.data(), array::make_shape( 10, 2 ) ); - EXPECT( field.array().owners() == 1 ); - const array::ArrayView cfieldv = array::make_view(field); - EXPECT( cfieldv(9,1) == 8. ); + EXPECT( field.array().owners() == 1 ); + const array::ArrayView cfieldv = array::make_view( field ); + EXPECT( cfieldv( 9, 1 ) == 8. ); } //----------------------------------------------------------------------------- @@ -153,7 +126,6 @@ CASE( "test_wrap_rawdata_direct" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_grid_ptr.cc b/src/tests/grid/test_grid_ptr.cc index d44f16f0f..52f7c2136 100644 --- a/src/tests/grid/test_grid_ptr.cc +++ b/src/tests/grid/test_grid_ptr.cc @@ -4,19 +4,18 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include #include - +#include #include "atlas/grid/Grid.h" -#include "atlas/util/Config.h" #include "atlas/runtime/Log.h" - +#include "atlas/util/Config.h" #include "atlas/mesh/Mesh.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" @@ -34,191 +33,176 @@ namespace test { //----------------------------------------------------------------------------- -CASE( "test_from_string_L32" ) -{ - Grid grid; - EXPECT( not grid ); - - grid = Grid("L32"); - EXPECT( grid ); - EXPECT( StructuredGrid(grid) == true ); - EXPECT( RegularGrid(grid) == true ); - - auto structured = StructuredGrid(grid); - EXPECT( structured.ny() == 65 ); - EXPECT( structured.periodic() == true ); - EXPECT( structured.nx(0) == 128 ); - EXPECT( structured.y().front() == 90. ); - EXPECT( structured.y().back() == -90. ); - - auto regular = RegularGrid(grid); - EXPECT( regular.ny() == 65 ); - EXPECT( regular.periodic() == true ); - EXPECT( regular.nx() == 128 ); - EXPECT( regular.y().front() == 90. ); - EXPECT( regular.y().back() == -90. ); - +CASE( "test_from_string_L32" ) { + Grid grid; + EXPECT( not grid ); + + grid = Grid( "L32" ); + EXPECT( grid ); + EXPECT( StructuredGrid( grid ) == true ); + EXPECT( RegularGrid( grid ) == true ); + + auto structured = StructuredGrid( grid ); + EXPECT( structured.ny() == 65 ); + EXPECT( structured.periodic() == true ); + EXPECT( structured.nx( 0 ) == 128 ); + EXPECT( structured.y().front() == 90. ); + EXPECT( structured.y().back() == -90. ); + + auto regular = RegularGrid( grid ); + EXPECT( regular.ny() == 65 ); + EXPECT( regular.periodic() == true ); + EXPECT( regular.nx() == 128 ); + EXPECT( regular.y().front() == 90. ); + EXPECT( regular.y().back() == -90. ); } -CASE( "test_from_string_O32" ) -{ - Grid grid; - EXPECT( not grid ); +CASE( "test_from_string_O32" ) { + Grid grid; + EXPECT( not grid ); - grid = Grid("O32"); - EXPECT( grid ); + grid = Grid( "O32" ); + EXPECT( grid ); - EXPECT( StructuredGrid(grid)); - EXPECT( !RegularGrid(grid) ); + EXPECT( StructuredGrid( grid ) ); + EXPECT( !RegularGrid( grid ) ); - auto structured = StructuredGrid(grid); - EXPECT( structured.ny() == 64 ); - EXPECT( structured.periodic() == true ); - EXPECT( structured.nx().front() == 20 ); + auto structured = StructuredGrid( grid ); + EXPECT( structured.ny() == 64 ); + EXPECT( structured.periodic() == true ); + EXPECT( structured.nx().front() == 20 ); } -CASE( "test_from_string_O32_with_domain" ) -{ - Grid grid; - EXPECT( not grid ); - - grid = Grid("O32",RectangularDomain( {0,90}, {0,90} ) ); - EXPECT( grid ); +CASE( "test_from_string_O32_with_domain" ) { + Grid grid; + EXPECT( not grid ); - EXPECT( StructuredGrid(grid)); - EXPECT( !RegularGrid(grid)); + grid = Grid( "O32", RectangularDomain( {0, 90}, {0, 90} ) ); + EXPECT( grid ); - auto structured = StructuredGrid(grid); - EXPECT( structured.ny() == 32 ); - EXPECT( structured.periodic() == false ); - EXPECT( structured.nx().front() == 6 ); + EXPECT( StructuredGrid( grid ) ); + EXPECT( !RegularGrid( grid ) ); - output::Gmsh gmsh("test_grid_ptr_O32_subdomain.msh"); - Mesh mesh = meshgenerator::StructuredMeshGenerator().generate(grid); - gmsh.write(mesh); + auto structured = StructuredGrid( grid ); + EXPECT( structured.ny() == 32 ); + EXPECT( structured.periodic() == false ); + EXPECT( structured.nx().front() == 6 ); + output::Gmsh gmsh( "test_grid_ptr_O32_subdomain.msh" ); + Mesh mesh = meshgenerator::StructuredMeshGenerator().generate( grid ); + gmsh.write( mesh ); } - -CASE( "test_structured_1" ) -{ - std::stringstream json; - json << - "{" - "\"type\" : \"structured\"," - "\"yspace\" : { \"type\":\"linear\", \"N\":9, \"start\":90, \"end\":-90 }," - "\"xspace\" : { \"type\":\"linear\", \"N\":16, \"start\":0, \"end\":360, \"endpoint\":false }" - "}"; - json.seekp(0); - - Grid grid; - EXPECT( not grid ); - - Config json_config(json); - - grid = StructuredGrid( json_config ); - EXPECT( grid ); - EXPECT( StructuredGrid(grid) ); - EXPECT( RegularGrid(grid) ); - - auto structured = StructuredGrid(grid); - EXPECT( structured.ny() == 9 ); - EXPECT( structured.periodic() == true ); - EXPECT( structured.nx(0) == 16 ); - EXPECT( structured.y().front() == 90. ); - EXPECT( structured.y().back() == -90. ); - - auto regular = RegularGrid(grid); - EXPECT( regular.ny() == 9 ); - EXPECT( regular.periodic() == true ); - EXPECT( regular.nx() == 16 ); - EXPECT( regular.y().front() == 90. ); - EXPECT( regular.y().back() == -90. ); - - output::Gmsh gmsh("test_grid_ptr.msh"); - Mesh mesh = meshgenerator::StructuredMeshGenerator().generate(grid); - gmsh.write(mesh); +CASE( "test_structured_1" ) { + std::stringstream json; + json << "{" + "\"type\" : \"structured\"," + "\"yspace\" : { \"type\":\"linear\", \"N\":9, \"start\":90, " + "\"end\":-90 }," + "\"xspace\" : { \"type\":\"linear\", \"N\":16, \"start\":0, " + "\"end\":360, \"endpoint\":false }" + "}"; + json.seekp( 0 ); + + Grid grid; + EXPECT( not grid ); + + Config json_config( json ); + + grid = StructuredGrid( json_config ); + EXPECT( grid ); + EXPECT( StructuredGrid( grid ) ); + EXPECT( RegularGrid( grid ) ); + + auto structured = StructuredGrid( grid ); + EXPECT( structured.ny() == 9 ); + EXPECT( structured.periodic() == true ); + EXPECT( structured.nx( 0 ) == 16 ); + EXPECT( structured.y().front() == 90. ); + EXPECT( structured.y().back() == -90. ); + + auto regular = RegularGrid( grid ); + EXPECT( regular.ny() == 9 ); + EXPECT( regular.periodic() == true ); + EXPECT( regular.nx() == 16 ); + EXPECT( regular.y().front() == 90. ); + EXPECT( regular.y().back() == -90. ); + + output::Gmsh gmsh( "test_grid_ptr.msh" ); + Mesh mesh = meshgenerator::StructuredMeshGenerator().generate( grid ); + gmsh.write( mesh ); } +CASE( "test_structured_2" ) { + using XSpace = StructuredGrid::XSpace; + using YSpace = StructuredGrid::YSpace; + using Domain = StructuredGrid::Domain; + using Projection = StructuredGrid::Projection; + StructuredGrid grid( XSpace( {0., 360.}, {2, 4, 6, 6, 4, 2}, false ), + YSpace( grid::LinearSpacing( {90., -90.}, 6 ) ), Projection(), Domain() ); + EXPECT( grid ); -CASE( "test_structured_2" ) -{ - using XSpace = StructuredGrid::XSpace; - using YSpace = StructuredGrid::YSpace; - using Domain = StructuredGrid::Domain; - using Projection = StructuredGrid::Projection; - StructuredGrid grid( - XSpace( {0.,360.} , {2,4,6,6,4,2} , false ), - YSpace( grid::LinearSpacing( {90.,-90.}, 6 ) ), - Projection(), - Domain() ); - EXPECT( grid ); + output::Gmsh gmsh( "test_grid_ptr_structured_2.msh" ); + Mesh mesh = meshgenerator::StructuredMeshGenerator().generate( grid ); + gmsh.write( mesh ); - output::Gmsh gmsh("test_grid_ptr_structured_2.msh"); - Mesh mesh = meshgenerator::StructuredMeshGenerator().generate(grid); - gmsh.write(mesh); + Log::info() << grid.spec() << std::endl; - Log::info() << grid.spec() << std::endl; + Grid newgrid( grid.spec() ); + Log::info() << newgrid.spec() << std::endl; - Grid newgrid( grid.spec() ); - Log::info() << newgrid.spec() << std::endl; - - Log::info() << "original: " << grid.uid() << std::endl; - Log::info() << "fromspec: " << newgrid.uid() << std::endl; - EXPECT( grid == newgrid ); + Log::info() << "original: " << grid.uid() << std::endl; + Log::info() << "fromspec: " << newgrid.uid() << std::endl; + EXPECT( grid == newgrid ); } -CASE( "test_structured_3" ) -{ - StructuredGrid grid( "O32" ); - EXPECT( grid ); +CASE( "test_structured_3" ) { + StructuredGrid grid( "O32" ); + EXPECT( grid ); - Log::info() << grid.spec() << std::endl; + Log::info() << grid.spec() << std::endl; - Grid newgrid( grid.spec() ); - Log::info() << newgrid.spec() << std::endl; + Grid newgrid( grid.spec() ); + Log::info() << newgrid.spec() << std::endl; - Log::info() << "original: " << grid.uid() << std::endl; - Log::info() << "fromspec: " << newgrid.uid() << std::endl; - EXPECT( grid == newgrid ); - EXPECT( grid.name() == "O32" ); - EXPECT( newgrid.name() == "O32" ); + Log::info() << "original: " << grid.uid() << std::endl; + Log::info() << "fromspec: " << newgrid.uid() << std::endl; + EXPECT( grid == newgrid ); + EXPECT( grid.name() == "O32" ); + EXPECT( newgrid.name() == "O32" ); } +CASE( "test_iterator" ) { + Grid grid( "O4" ); -CASE( "test_iterator" ) -{ - Grid grid("O4"); - - for( atlas::PointXY xy : grid.xy() ) { - Log::debug() << xy << '\n'; - } + for ( atlas::PointXY xy : grid.xy() ) { + Log::debug() << xy << '\n'; + } - for( atlas::PointLonLat ll : grid.lonlat() ) { - Log::debug() << ll << '\n'; - } - Log::debug() << std::flush; + for ( atlas::PointLonLat ll : grid.lonlat() ) { + Log::debug() << ll << '\n'; + } + Log::debug() << std::flush; } -CASE( "test_iterator_with_predicate" ) -{ - Grid grid("O4"); +CASE( "test_iterator_with_predicate" ) { + Grid grid( "O4" ); - auto filter = [](long n) { - bool b = (n>=5 && n<10); - if( b ) Log::debug() << "n = " << n << std::endl; - return b; - }; + auto filter = []( long n ) { + bool b = ( n >= 5 && n < 10 ); + if ( b ) Log::debug() << "n = " << n << std::endl; + return b; + }; - // auto pred = std::bind( filter, std::placeholders::_1, w_begin, w_end ); + // auto pred = std::bind( filter, std::placeholders::_1, w_begin, w_end ); - int i(0); - for( atlas::PointXY xy : grid.xy(filter) ) { - Log::debug() << i++ << " " << xy << std::endl; - } - EXPECT( i == 5 ); + int i( 0 ); + for ( atlas::PointXY xy : grid.xy( filter ) ) { + Log::debug() << i++ << " " << xy << std::endl; + } + EXPECT( i == 5 ); - Log::debug() << std::flush; + Log::debug() << std::flush; } //----------------------------------------------------------------------------- @@ -226,7 +210,6 @@ CASE( "test_iterator_with_predicate" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_grids.cc b/src/tests/grid/test_grids.cc index 179828070..533b93ed6 100644 --- a/src/tests/grid/test_grids.cc +++ b/src/tests/grid/test_grids.cc @@ -4,17 +4,18 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include #include +#include -#include "atlas/library/Library.h" -#include "atlas/grid/Grid.h" #include "atlas/grid.h" +#include "atlas/grid/Grid.h" +#include "atlas/library/Library.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/util/Config.h" #include "eckit/memory/Builder.h" @@ -23,128 +24,117 @@ #include "tests/AtlasTestEnvironment.h" -using StructuredGrid = atlas::grid::StructuredGrid; -using Grid = atlas::Grid; -using Regular = atlas::grid::RegularGrid; -using ReducedGaussianGrid = atlas::grid::ReducedGaussianGrid; +using StructuredGrid = atlas::grid::StructuredGrid; +using Grid = atlas::Grid; +using Regular = atlas::grid::RegularGrid; +using ReducedGaussianGrid = atlas::grid::ReducedGaussianGrid; namespace atlas { namespace test { //----------------------------------------------------------------------------- -CASE( "test_factory" ) -{ - StructuredGrid structured = Grid("N80"); - - Grid grid = Grid("N24"); +CASE( "test_factory" ) { + StructuredGrid structured = Grid( "N80" ); - std::cout << "structured.ny() = " << structured.ny() << std::endl; - std::cout << "grid.npts() = " << grid.size() << std::endl; + Grid grid = Grid( "N24" ); + std::cout << "structured.ny() = " << structured.ny() << std::endl; + std::cout << "grid.npts() = " << grid.size() << std::endl; } -CASE( "test_regular_gg" ) -{ - Regular grid( "F32" ); - - EXPECT(grid.ny() == 64); - EXPECT(grid.size() == 8192); - // EXPECT(grid.type() == "regular_gaussian"); - - // Full Gaussian Grid - - Grid::Config config; - config.set("type","regular_gaussian"); - config.set("N",32); - grid = Grid(config); - EXPECT(grid.size() == 8192); - // EXPECT(grid.type() == "regular_gaussian"); +CASE( "test_regular_gg" ) { + Regular grid( "F32" ); + EXPECT( grid.ny() == 64 ); + EXPECT( grid.size() == 8192 ); + // EXPECT(grid.type() == "regular_gaussian"); + // Full Gaussian Grid + Grid::Config config; + config.set( "type", "regular_gaussian" ); + config.set( "N", 32 ); + grid = Grid( config ); + EXPECT( grid.size() == 8192 ); + // EXPECT(grid.type() == "regular_gaussian"); } -CASE( "test_reduced_gg" ) -{ - StructuredGrid grid; +CASE( "test_reduced_gg" ) { + StructuredGrid grid; - grid = Grid( "N32" ); - EXPECT(grid.ny() == 64); - EXPECT(grid.size() == 6114); + grid = Grid( "N32" ); + EXPECT( grid.ny() == 64 ); + EXPECT( grid.size() == 6114 ); - grid = grid::ReducedGaussianGrid( {4,6,8,8,6,4} ); + grid = grid::ReducedGaussianGrid( {4, 6, 8, 8, 6, 4} ); - EXPECT(grid.ny() == 6); - EXPECT(grid.size() == 8+12+16); + EXPECT( grid.ny() == 6 ); + EXPECT( grid.size() == 8 + 12 + 16 ); } -CASE( "test_reduced_gg_ifs" ) -{ - StructuredGrid grid( "N32" ); - - // EXPECT(grid.N() == 32); - EXPECT(grid.ny() == 64); - EXPECT(grid.size() == 6114); - // EXPECT(grid.type() == "classic_gaussian"); +CASE( "test_reduced_gg_ifs" ) { + StructuredGrid grid( "N32" ); + // EXPECT(grid.N() == 32); + EXPECT( grid.ny() == 64 ); + EXPECT( grid.size() == 6114 ); + // EXPECT(grid.type() == "classic_gaussian"); } -CASE( "test_regular_ll" ) -{ - // Constructor for N=8 - size_t nlon = 32; - size_t nlat = 16; - std::stringstream name; name << "Slat" << nlon << "x" << nlat; - Regular grid( name.str() ); - - EXPECT(grid.nx() == nlon); - EXPECT(grid.ny() == nlat); - EXPECT(grid.size() == 512); - // EXPECT(grid.type() == "shifted_lat"); - EXPECT(grid.y(0) == 90.-0.5*(180./16.)); - EXPECT(grid.y(grid.ny()-1) == -90.+0.5*(180./16.)); - EXPECT(grid.x(0) == 0.); - EXPECT(grid.x(grid.nx()-1) == 360.-360./32.); - - // Construct using builders/factories - - // Global Grid - Grid::Config config1; - config1.set("type","shifted_lat"); - config1.set("nx",32); - config1.set("ny",16); - grid = Grid(config1); - EXPECT(grid.size() == 512); - // EXPECT(gridptr->type() == "shifted_lat"); - - Grid::Config config2; - config2.set("type","shifted_lat"); - config2.set("N",8); - grid = Grid(config2); - EXPECT(grid.size() == 512); - // EXPECT(gridptr->type() == "shifted_lat"); - - Regular ll_poles( "L4x3" ); - EXPECT( ll_poles.nx() == 4); - EXPECT( ll_poles.ny() == 3); - - Regular ll_nopoles( "Slat4x2" ); - EXPECT( ll_nopoles.nx() == 4); - EXPECT( ll_nopoles.ny() == 2); - EXPECT( eckit::types::is_approximately_equal( ll_nopoles.y(0), 45.) ); // tolerance was previously 1.e-5 - EXPECT( eckit::types::is_approximately_equal( ll_nopoles.y(1), -45. ) ); // tolerance was previously 1.e-5 - EXPECT( eckit::types::is_approximately_equal( ll_nopoles.x(0), 0. ) ); // tolerance was previously 1.e-5 - EXPECT( eckit::types::is_approximately_equal( ll_nopoles.x(1), 90. ) ); // tolerance was previously 1.e-5 - +CASE( "test_regular_ll" ) { + // Constructor for N=8 + size_t nlon = 32; + size_t nlat = 16; + std::stringstream name; + name << "Slat" << nlon << "x" << nlat; + Regular grid( name.str() ); + + EXPECT( grid.nx() == nlon ); + EXPECT( grid.ny() == nlat ); + EXPECT( grid.size() == 512 ); + // EXPECT(grid.type() == "shifted_lat"); + EXPECT( grid.y( 0 ) == 90. - 0.5 * ( 180. / 16. ) ); + EXPECT( grid.y( grid.ny() - 1 ) == -90. + 0.5 * ( 180. / 16. ) ); + EXPECT( grid.x( 0 ) == 0. ); + EXPECT( grid.x( grid.nx() - 1 ) == 360. - 360. / 32. ); + + // Construct using builders/factories + + // Global Grid + Grid::Config config1; + config1.set( "type", "shifted_lat" ); + config1.set( "nx", 32 ); + config1.set( "ny", 16 ); + grid = Grid( config1 ); + EXPECT( grid.size() == 512 ); + // EXPECT(gridptr->type() == "shifted_lat"); + + Grid::Config config2; + config2.set( "type", "shifted_lat" ); + config2.set( "N", 8 ); + grid = Grid( config2 ); + EXPECT( grid.size() == 512 ); + // EXPECT(gridptr->type() == "shifted_lat"); + + Regular ll_poles( "L4x3" ); + EXPECT( ll_poles.nx() == 4 ); + EXPECT( ll_poles.ny() == 3 ); + + Regular ll_nopoles( "Slat4x2" ); + EXPECT( ll_nopoles.nx() == 4 ); + EXPECT( ll_nopoles.ny() == 2 ); + EXPECT( eckit::types::is_approximately_equal( ll_nopoles.y( 0 ), 45. ) ); // tolerance was previously 1.e-5 + EXPECT( eckit::types::is_approximately_equal( ll_nopoles.y( 1 ), -45. ) ); // tolerance was previously 1.e-5 + EXPECT( eckit::types::is_approximately_equal( ll_nopoles.x( 0 ), 0. ) ); // tolerance was previously 1.e-5 + EXPECT( eckit::types::is_approximately_equal( ll_nopoles.x( 1 ), 90. ) ); // tolerance was previously 1.e-5 } -CASE( "test_reducedgaussian" ) -{ - StructuredGrid N640( "N640" ); - EXPECT(N640.size() == 2140702); - ReducedGaussianGrid custom( N640.nx() ); - EXPECT(N640.size() == custom.size()); +CASE( "test_reducedgaussian" ) { + StructuredGrid N640( "N640" ); + EXPECT( N640.size() == 2140702 ); + ReducedGaussianGrid custom( N640.nx() ); + EXPECT( N640.size() == custom.size() ); } //----------------------------------------------------------------------------- @@ -152,7 +142,6 @@ CASE( "test_reducedgaussian" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_rotation.cc b/src/tests/grid/test_rotation.cc index 8831b0b26..f25b3a4d6 100644 --- a/src/tests/grid/test_rotation.cc +++ b/src/tests/grid/test_rotation.cc @@ -4,230 +4,218 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include #include "atlas/library/Library.h" +#include "atlas/runtime/Log.h" #include "atlas/util/Config.h" #include "atlas/util/Constants.h" #include "atlas/util/Rotation.h" -#include "atlas/runtime/Log.h" #include "eckit/types/FloatCompare.h" #include "tests/AtlasTestEnvironment.h" -using atlas::util::Rotation; using atlas::util::Config; +using atlas::util::Rotation; namespace atlas { namespace test { //----------------------------------------------------------------------------- -constexpr double eps() { return 1.e-5; } +constexpr double eps() { + return 1.e-5; +} 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 ) \ + 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() ) ); \ + } //----------------------------------------------------------------------------- class MagicsRotation { -// For reference, this what magics uses, it appears as if it originated from fortran code -// Strangely the definition of rotate and unrotate are switched. + // For reference, this what magics uses, it appears as if it originated from + // fortran code + // Strangely the definition of rotate and unrotate are switched. public: + MagicsRotation( const PointLonLat& south_pole ) : south_pole_( south_pole ) {} - MagicsRotation( const PointLonLat& south_pole ) : - south_pole_(south_pole) { - } + PointLonLat rotate( const PointLonLat& point ) const { + return magics_unrotate( point ); /// Switch meaning !!! + } - PointLonLat rotate( const PointLonLat& point ) const - { - return magics_unrotate(point); /// Switch meaning !!! - } - - PointLonLat unrotate( const PointLonLat& point ) const - { - return magics_rotate(point); /// Swich meaning !!! - } + PointLonLat unrotate( const PointLonLat& point ) const { + return magics_rotate( point ); /// Swich meaning !!! + } private: - - PointLonLat south_pole_; - - PointLonLat magics_rotate( const PointLonLat& point ) const - { - double lat_y = point.lat(); - double lon_x = point.lon(); - - double sin_south_pole_lat = std::sin(d2r*(south_pole_.lat()+90.)); - double cos_south_pole_lat = std::cos(d2r*(south_pole_.lat()+90.)); - - double ZXMXC = d2r*(lon_x - south_pole_.lon()); - double sin_lon_decr_sp = std::sin(ZXMXC); - double cos_lon_decr_sp = std::cos(ZXMXC); - double sin_lat = std::sin(d2r*lat_y); - double cos_lat = std::cos(d2r*lat_y); - double ZSYROT = cos_south_pole_lat*sin_lat - sin_south_pole_lat*cos_lat*cos_lon_decr_sp; - ZSYROT = std::max( std::min(ZSYROT, +1.0), -1.0 ); - - double PYROT = std::asin(ZSYROT)*r2d; - - double ZCYROT = std::cos(PYROT*d2r); - double ZCXROT = (cos_south_pole_lat*cos_lat*cos_lon_decr_sp + sin_south_pole_lat*sin_lat)/ZCYROT; - ZCXROT = std::max( std::min(ZCXROT, +1.0), -1.0 ); - double ZSXROT = cos_lat*sin_lon_decr_sp/ZCYROT; - - double PXROT = std::acos(ZCXROT)*r2d; - - if( ZSXROT < 0.0) - PXROT = -PXROT; - - return PointLonLat( PXROT, PYROT); - } - - PointLonLat magics_unrotate( const PointLonLat& point ) const - { - double lat_y = point.lat(); - double lon_x = point.lon(); - - double sin_south_pole_lat = std::sin(d2r*(south_pole_.lat()+90.)); - double cos_south_pole_lat = std::cos(d2r*(south_pole_.lat()+90.)); - double cos_lon = std::cos(d2r*lon_x); - double sin_lat = std::sin(d2r*lat_y); - double cos_lat = std::cos(d2r*lat_y); - double ZSYREG = cos_south_pole_lat*sin_lat + sin_south_pole_lat*cos_lat*cos_lon; - ZSYREG = std::max( std::min(ZSYREG, +1.0), -1.0 ); - double PYREG = std::asin(ZSYREG)*r2d; - double ZCYREG = std::cos(PYREG*d2r); - double ZCXMXC = (cos_south_pole_lat*cos_lat*cos_lon - sin_south_pole_lat*sin_lat)/ZCYREG; - 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; - double PXREG = ZXMXC + south_pole_.lon(); - - return PointLonLat( PXREG, PYREG); - } - - + PointLonLat south_pole_; + + PointLonLat magics_rotate( const PointLonLat& point ) const { + double lat_y = point.lat(); + double lon_x = point.lon(); + + double sin_south_pole_lat = std::sin( d2r * ( south_pole_.lat() + 90. ) ); + double cos_south_pole_lat = std::cos( d2r * ( south_pole_.lat() + 90. ) ); + + double ZXMXC = d2r * ( lon_x - south_pole_.lon() ); + double sin_lon_decr_sp = std::sin( ZXMXC ); + double cos_lon_decr_sp = std::cos( ZXMXC ); + double sin_lat = std::sin( d2r * lat_y ); + double cos_lat = std::cos( d2r * lat_y ); + double ZSYROT = cos_south_pole_lat * sin_lat - sin_south_pole_lat * cos_lat * cos_lon_decr_sp; + ZSYROT = std::max( std::min( ZSYROT, +1.0 ), -1.0 ); + + double PYROT = std::asin( ZSYROT ) * r2d; + + double ZCYROT = std::cos( PYROT * d2r ); + double ZCXROT = ( cos_south_pole_lat * cos_lat * cos_lon_decr_sp + sin_south_pole_lat * sin_lat ) / ZCYROT; + ZCXROT = std::max( std::min( ZCXROT, +1.0 ), -1.0 ); + double ZSXROT = cos_lat * sin_lon_decr_sp / ZCYROT; + + double PXROT = std::acos( ZCXROT ) * r2d; + + if ( ZSXROT < 0.0 ) PXROT = -PXROT; + + return PointLonLat( PXROT, PYROT ); + } + + PointLonLat magics_unrotate( const PointLonLat& point ) const { + double lat_y = point.lat(); + double lon_x = point.lon(); + + double sin_south_pole_lat = std::sin( d2r * ( south_pole_.lat() + 90. ) ); + double cos_south_pole_lat = std::cos( d2r * ( south_pole_.lat() + 90. ) ); + double cos_lon = std::cos( d2r * lon_x ); + double sin_lat = std::sin( d2r * lat_y ); + double cos_lat = std::cos( d2r * lat_y ); + double ZSYREG = cos_south_pole_lat * sin_lat + sin_south_pole_lat * cos_lat * cos_lon; + ZSYREG = std::max( std::min( ZSYREG, +1.0 ), -1.0 ); + double PYREG = std::asin( ZSYREG ) * r2d; + double ZCYREG = std::cos( PYREG * d2r ); + double ZCXMXC = ( cos_south_pole_lat * cos_lat * cos_lon - sin_south_pole_lat * sin_lat ) / ZCYREG; + 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; + double PXREG = ZXMXC + south_pole_.lon(); + + return PointLonLat( PXREG, PYREG ); + } }; //----------------------------------------------------------------------------- -CASE( "test_rotation" ) -{ - Config config; - config.set("north_pole", std::vector{-176,40} ); - Rotation rotation(config); - MagicsRotation magics(rotation.southPole()); - Log::info() << rotation << std::endl; - - EXPECT( rotation.rotated() ); - - PointLonLat p, r; - - p = {0.,90.}; - r = {-176.,40.}; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( magics. rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); - EXPECT_EQUIVALENT( magics. unrotate(r), p ); - - p = {0.,0.}; - r = {-176.,-50.}; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( magics. rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); - EXPECT_EQUIVALENT( magics. unrotate(r), p ); - - - p = {-180.,45.}; - r = {-176.,85.}; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( magics. rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); - EXPECT_EQUIVALENT( magics. unrotate(r), p ); +CASE( "test_rotation" ) { + Config config; + config.set( "north_pole", std::vector{-176, 40} ); + Rotation rotation( config ); + MagicsRotation magics( rotation.southPole() ); + Log::info() << rotation << std::endl; + + EXPECT( rotation.rotated() ); + + PointLonLat p, r; + + p = {0., 90.}; + r = {-176., 40.}; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( magics.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); + EXPECT_EQUIVALENT( magics.unrotate( r ), p ); + + p = {0., 0.}; + r = {-176., -50.}; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( magics.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); + EXPECT_EQUIVALENT( magics.unrotate( r ), p ); + + p = {-180., 45.}; + r = {-176., 85.}; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( magics.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); + EXPECT_EQUIVALENT( magics.unrotate( r ), p ); } - - -CASE( "test_no_rotation" ) -{ - Config config; - Rotation rotation(config); - MagicsRotation magics(rotation.southPole()); - - Log::info() << rotation << std::endl; - - EXPECT( not rotation.rotated() ); - - PointLonLat p, r; - - p = {0.,90.}; - r = p; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( magics. rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); - EXPECT_EQUIVALENT( magics. unrotate(r), p ); - - p = {0.,0.}; - r = p; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( magics. rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); - EXPECT_EQUIVALENT( magics. unrotate(r), p ); - - - p = {-180.,45.}; - r = p; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( magics. rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); - EXPECT_EQUIVALENT( magics. unrotate(r), p ); +CASE( "test_no_rotation" ) { + Config config; + Rotation rotation( config ); + MagicsRotation magics( rotation.southPole() ); + + Log::info() << rotation << std::endl; + + EXPECT( not rotation.rotated() ); + + PointLonLat p, r; + + p = {0., 90.}; + r = p; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( magics.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); + EXPECT_EQUIVALENT( magics.unrotate( r ), p ); + + p = {0., 0.}; + r = p; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( magics.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); + EXPECT_EQUIVALENT( magics.unrotate( r ), p ); + + p = {-180., 45.}; + r = p; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( magics.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); + EXPECT_EQUIVALENT( magics.unrotate( r ), p ); } -CASE( "test_rotation_angle_only" ) -{ - Config config; - config.set("rotation_angle",-180.); - Rotation rotation(config); - MagicsRotation magics(rotation.southPole()); +CASE( "test_rotation_angle_only" ) { + Config config; + config.set( "rotation_angle", -180. ); + Rotation rotation( config ); + MagicsRotation magics( rotation.southPole() ); - Log::info() << rotation << std::endl; + Log::info() << rotation << std::endl; - EXPECT( rotation.rotated() ); + EXPECT( rotation.rotated() ); - PointLonLat p, r; + PointLonLat p, r; - p = {0.,90.}; - r = {-180.,90}; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); + p = {0., 90.}; + r = {-180., 90}; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); - p = {0.,0.}; - r = {-180.,0.}; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); + p = {0., 0.}; + r = {-180., 0.}; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); - p = {270.,25.}; - r = {90.,25.}; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); + p = {270., 25.}; + r = {90., 25.}; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); - p = {-180.,45.}; - r = {-360.,45.}; - EXPECT_EQUIVALENT( rotation.rotate(p), r ); - EXPECT_EQUIVALENT( rotation.unrotate(r), p ); + p = {-180., 45.}; + r = {-360., 45.}; + EXPECT_EQUIVALENT( rotation.rotate( p ), r ); + EXPECT_EQUIVALENT( rotation.unrotate( r ), p ); } //----------------------------------------------------------------------------- @@ -235,7 +223,6 @@ CASE( "test_rotation_angle_only" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/grid/test_state.cc b/src/tests/grid/test_state.cc index 06c9359df..97f5c8b17 100644 --- a/src/tests/grid/test_state.cc +++ b/src/tests/grid/test_state.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,19 +14,19 @@ #include "atlas/library/config.h" -#include "eckit/memory/ScopedPtr.h" #include "eckit/exception/Exceptions.h" +#include "eckit/memory/ScopedPtr.h" #include "eckit/parser/JSON.h" #include "eckit/parser/JSONParser.h" -#include "atlas/library/Library.h" -#include "atlas/field/State.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/field/Field.h" -#include "atlas/grid/Grid.h" -#include "atlas/array/DataType.h" #include "atlas/array/ArrayView.h" +#include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" +#include "atlas/field/State.h" +#include "atlas/grid/Grid.h" +#include "atlas/library/Library.h" +#include "atlas/mesh/Mesh.h" #include "atlas/runtime/Log.h" #include "tests/AtlasTestEnvironment.h" @@ -42,169 +43,154 @@ namespace test { // --- Declaration (in .h file) class MyStateGenerator : public StateGenerator { public: - MyStateGenerator( const eckit::Parametrisation& p = util::Config() ) : StateGenerator(p) {} - ~MyStateGenerator() {} - virtual void generate( State& state, const eckit::Parametrisation& p = util::Config() ) const; + MyStateGenerator( const eckit::Parametrisation& p = util::Config() ) : StateGenerator( p ) {} + ~MyStateGenerator() {} + virtual void generate( State& state, const eckit::Parametrisation& p = util::Config() ) const; }; // --- Implementation (in .cc file) -void MyStateGenerator::generate( State& state, const eckit::Parametrisation& p ) const -{ - const util::Config *params = dynamic_cast(&p); - if( !params ) - { - throw eckit::Exception("Parametrisation has to be of atlas::util::Config type"); - } - - util::Config geometry; - if( ! params->get("geometry",geometry) ) { - throw eckit::BadParameter("Could not find 'geometry' in Parametrisation",Here()); - } - - std::string grid_uid; - if( geometry.get("grid", grid_uid) ) - { - Grid grid(grid_uid); - if (!geometry.has("ngptot")) { - geometry.set("ngptot", grid.size()); +void MyStateGenerator::generate( State& state, const eckit::Parametrisation& p ) const { + const util::Config* params = dynamic_cast( &p ); + if ( !params ) { throw eckit::Exception( "Parametrisation has to be of atlas::util::Config type" ); } + + util::Config geometry; + if ( !params->get( "geometry", geometry ) ) { + throw eckit::BadParameter( "Could not find 'geometry' in Parametrisation", Here() ); } - } - - if( ! geometry.has("ngptot") ) { - throw eckit::BadParameter("Could not find 'ngptot' in Parametrisation"); - } - - std::vector fields; - if( params->get("fields",fields) ) - { - for( size_t i=0; i fields; + if ( params->get( "fields", fields ) ) { + for ( size_t i = 0; i < fields.size(); ++i ) { + util::Config fieldparams; + // Subsequent "set" calls can overwrite eachother, so that + // finetuning is possible in e.g. the fields Parametrisation (such as + // creator, nlev, ngptot) + fieldparams.set( "creator", "IFS" ); + fieldparams.set( geometry ); + fieldparams.set( fields[i] ); + state.add( Field( fieldparams ) ); + + // debug info + std::stringstream s; + eckit::JSON json( s ); + json << fieldparams; + Log::debug() << "fieldparams = " << s.str() << std::endl; + } } - } } // Register in factory -StateGeneratorBuilder __MyStateGenerator("MyStateGenerator"); +StateGeneratorBuilder __MyStateGenerator( "MyStateGenerator" ); // =================================================================== // BEGIN TESTS // =================================================================== -CASE( "state" ) -{ - State state; - EXPECT( state.size() == 0 ); - - state.add( Field( "myfield", array::make_datatype(), array::make_shape(10,1) ) ); - state.add( Field( "", array::make_datatype(), array::make_shape(10,2) ) ); - state.add( Field( "", array::make_datatype(), array::make_shape(10,3) ) ); +CASE( "state" ) { + State state; + EXPECT( state.size() == 0 ); - EXPECT( state.size() == 3 ); - EXPECT( state.has("myfield") ); - EXPECT( state.has("field_00001") ); - EXPECT( state.has("field_00002") ); + state.add( Field( "myfield", array::make_datatype(), array::make_shape( 10, 1 ) ) ); + state.add( Field( "", array::make_datatype(), array::make_shape( 10, 2 ) ) ); + state.add( Field( "", array::make_datatype(), array::make_shape( 10, 3 ) ) ); - EXPECT( state.field(0).name() == std::string("field_00001") ); - EXPECT( state.field(1).name() == std::string("field_00002") ); - EXPECT( state.field(2).name() == std::string("myfield") ); + EXPECT( state.size() == 3 ); + EXPECT( state.has( "myfield" ) ); + EXPECT( state.has( "field_00001" ) ); + EXPECT( state.has( "field_00002" ) ); - state.remove("myfield"); - EXPECT( state.size() == 2 ); - EXPECT( ! state.has("myfield") ); + EXPECT( state.field( 0 ).name() == std::string( "field_00001" ) ); + EXPECT( state.field( 1 ).name() == std::string( "field_00002" ) ); + EXPECT( state.field( 2 ).name() == std::string( "myfield" ) ); - state.remove("field_00002"); - EXPECT( state.size() == 1 ); - EXPECT( ! state.has("field_00002") ); + state.remove( "myfield" ); + EXPECT( state.size() == 2 ); + EXPECT( !state.has( "myfield" ) ); + state.remove( "field_00002" ); + EXPECT( state.size() == 1 ); + EXPECT( !state.has( "field_00002" ) ); } -CASE( "state_generator" ) -{ - EXPECT( StateGeneratorFactory::has("MyStateGenerator") ); - eckit::ScopedPtr stategenerator ( StateGeneratorFactory::build("MyStateGenerator") ); +CASE( "state_generator" ) { + EXPECT( StateGeneratorFactory::has( "MyStateGenerator" ) ); + eckit::ScopedPtr stategenerator( StateGeneratorFactory::build( "MyStateGenerator" ) ); } -CASE( "state_create" ) -{ - - util::Config p; - util::Config geometry; - geometry.set("grid","O80"); - geometry.set("ngptot",350); - geometry.set("nproma",3); - geometry.set("nlev",5); - p.set("geometry",geometry); +CASE( "state_create" ) { + util::Config p; + util::Config geometry; + geometry.set( "grid", "O80" ); + geometry.set( "ngptot", 350 ); + geometry.set( "nproma", 3 ); + geometry.set( "nlev", 5 ); + p.set( "geometry", geometry ); - std::vector fields(5); - fields[0].set("name","temperature"); - fields[0].set("datatype",array::DataType::real32().str()); + std::vector fields( 5 ); + fields[0].set( "name", "temperature" ); + fields[0].set( "datatype", array::DataType::real32().str() ); - fields[1].set("name","wind"); - fields[1].set("nvar",2); // vector field u,v - fields[1].set("datatype",array::DataType::real64().str()); + fields[1].set( "name", "wind" ); + fields[1].set( "nvar", 2 ); // vector field u,v + fields[1].set( "datatype", array::DataType::real64().str() ); - fields[2].set("name","soiltype"); - fields[2].set("datatype",array::DataType::int32().str()); - fields[2].set("nlev",1); // We can overwrite nlev from geometry here + fields[2].set( "name", "soiltype" ); + fields[2].set( "datatype", array::DataType::int32().str() ); + fields[2].set( "nlev", 1 ); // We can overwrite nlev from geometry here - fields[3].set("name","GFL"); - fields[3].set("nvar",12); // assume 12 variables in GFL array - fields[3].set("datatype",array::DataType::real64().str()); + fields[3].set( "name", "GFL" ); + fields[3].set( "nvar", 12 ); // assume 12 variables in GFL array + fields[3].set( "datatype", array::DataType::real64().str() ); - fields[4].set("name","array"); - fields[4].set("datatype",array::DataType::int64().str()); - fields[4].set("creator","ArraySpec"); - fields[4].set("shape",array::make_shape(10,2)); + fields[4].set( "name", "array" ); + fields[4].set( "datatype", array::DataType::int64().str() ); + fields[4].set( "creator", "ArraySpec" ); + fields[4].set( "shape", array::make_shape( 10, 2 ) ); - p.set("fields",fields); + p.set( "fields", fields ); - // We can also translate parameters to a json: - std::stringstream json; - eckit::JSON js(json); js << p; - Log::info() << "json = " << json.str() << std::endl; + // We can also translate parameters to a json: + std::stringstream json; + eckit::JSON js( json ); + js << p; + Log::info() << "json = " << json.str() << std::endl; - // And we can create back parameters from json: - util::Config from_json_stream(json); + // And we can create back parameters from json: + util::Config from_json_stream( json ); - // And if we have a json file, we could create Parameters from the file: + // And if we have a json file, we could create Parameters from the file: // StateGenerater::Parameters from_json_file( eckit::PathName("file.json") ); - State state ( "MyStateGenerator",p ); + State state( "MyStateGenerator", p ); - EXPECT( state.has("temperature") ); - EXPECT( state.has("wind") ); - EXPECT( state.has("soiltype") ); + EXPECT( state.has( "temperature" ) ); + EXPECT( state.has( "wind" ) ); + EXPECT( state.has( "soiltype" ) ); - Log::info() << state.field("temperature") << std::endl; - Log::info() << state.field("wind") << std::endl; - Log::info() << state.field("soiltype") << std::endl; - Log::info() << state.field("GFL") << std::endl; + Log::info() << state.field( "temperature" ) << std::endl; + Log::info() << state.field( "wind" ) << std::endl; + Log::info() << state.field( "soiltype" ) << std::endl; + Log::info() << state.field( "GFL" ) << std::endl; - array::ArrayView temperature = array::make_view( state.field("temperature") ); - temperature(0,0,0,0) = 0; + array::ArrayView temperature = array::make_view( state.field( "temperature" ) ); + temperature( 0, 0, 0, 0 ) = 0; - array::ArrayView wind = array::make_view( state.field("wind") ); - wind(0,0,0,0) = 0; + array::ArrayView wind = array::make_view( state.field( "wind" ) ); + wind( 0, 0, 0, 0 ) = 0; - array::ArrayView soiltype = array::make_view( state.field("soiltype") ); - soiltype(0,0,0,0) = 0; - - array::ArrayView array = array::make_view( state["array"] ); - array(0,0) = 0; + array::ArrayView soiltype = array::make_view( state.field( "soiltype" ) ); + soiltype( 0, 0, 0, 0 ) = 0; + array::ArrayView array = array::make_view( state["array"] ); + array( 0, 0 ) = 0; } //----------------------------------------------------------------------------- @@ -212,7 +198,6 @@ CASE( "state_create" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/interpolation/test_Quad3D.cc b/src/tests/interpolation/test_Quad3D.cc index b575c7d7e..77e0be07f 100644 --- a/src/tests/interpolation/test_Quad3D.cc +++ b/src/tests/interpolation/test_Quad3D.cc @@ -4,22 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - -#include "atlas/interpolation/method/Ray.h" #include "atlas/interpolation/element/Quad3D.h" +#include "atlas/interpolation/method/Ray.h" #include "atlas/util/Point.h" -#include "tests/AtlasTestEnvironment.h" #include "eckit/types/FloatCompare.h" +#include "tests/AtlasTestEnvironment.h" +using atlas::PointXYZ; using atlas::interpolation::element::Quad3D; using atlas::interpolation::method::Intersect; using atlas::interpolation::method::Ray; -using atlas::PointXYZ; namespace atlas { namespace test { @@ -28,203 +28,194 @@ namespace test { const double relative_error = 0.0001; -CASE( "test_quad_area" ) -{ - PointXYZ v0(0.,0.,0.); - PointXYZ v1(1.,0.,0.); - PointXYZ v2(1.,1.,0.); - PointXYZ v3(0.,1.,0.); +CASE( "test_quad_area" ) { + PointXYZ v0( 0., 0., 0. ); + PointXYZ v1( 1., 0., 0. ); + PointXYZ v2( 1., 1., 0. ); + PointXYZ v3( 0., 1., 0. ); - Quad3D quad1(v0.data(),v1.data(),v2.data(),v3.data()); + Quad3D quad1( v0.data(), v1.data(), v2.data(), v3.data() ); EXPECT( quad1.validate() ); double area = quad1.area(); - EXPECT ( eckit::types::is_approximately_equal( area, 1.0, relative_error ) ); + EXPECT( eckit::types::is_approximately_equal( area, 1.0, relative_error ) ); - PointXYZ c0(-2.,-2.,3.); // 4 - PointXYZ c1( 3.,-2.,3.); // 6 - PointXYZ c2( 3.,0.5,3.); // 1.5 - PointXYZ c3(-2.,0.5,3.); // 1 + PointXYZ c0( -2., -2., 3. ); // 4 + PointXYZ c1( 3., -2., 3. ); // 6 + PointXYZ c2( 3., 0.5, 3. ); // 1.5 + PointXYZ c3( -2., 0.5, 3. ); // 1 - Quad3D quad2(c0.data(),c1.data(),c2.data(),c3.data()); + Quad3D quad2( c0.data(), c1.data(), c2.data(), c3.data() ); EXPECT( quad2.validate() ); area = quad2.area(); - EXPECT ( eckit::types::is_approximately_equal( area, 12.5, relative_error ) ); + EXPECT( eckit::types::is_approximately_equal( area, 12.5, relative_error ) ); } -CASE( "test_quadrilateral_intersection_refquad" ) -{ - PointXYZ v0(0.,0.,0.); - PointXYZ v1(1.,0.,0.); - PointXYZ v2(1.,1.,0.); - PointXYZ v3(0.,1.,0.); +CASE( "test_quadrilateral_intersection_refquad" ) { + PointXYZ v0( 0., 0., 0. ); + PointXYZ v1( 1., 0., 0. ); + PointXYZ v2( 1., 1., 0. ); + PointXYZ v3( 0., 1., 0. ); - Quad3D quad(v0.data(),v1.data(),v2.data(),v3.data()); + Quad3D quad( v0.data(), v1.data(), v2.data(), v3.data() ); - EXPECT( quad.validate() ); + EXPECT( quad.validate() ); - PointXYZ orig(0.25,0.25,1.); - PointXYZ dir (0.,0.,-1.); + PointXYZ orig( 0.25, 0.25, 1. ); + PointXYZ dir( 0., 0., -1. ); - Ray ray(orig.data(),dir.data()); + Ray ray( orig.data(), dir.data() ); - Intersect isect = quad.intersects(ray); + Intersect isect = quad.intersects( ray ); - EXPECT( isect ); - EXPECT ( eckit::types::is_approximately_equal( isect.u, 0.25, relative_error ) ); - EXPECT ( eckit::types::is_approximately_equal( isect.v, 0.25, relative_error ) ); + EXPECT( isect ); + EXPECT( eckit::types::is_approximately_equal( isect.u, 0.25, relative_error ) ); + EXPECT( eckit::types::is_approximately_equal( isect.v, 0.25, relative_error ) ); } -CASE( "test_quadrilateral_intersection_doublequad" ) -{ - PointXYZ v0(0.,0.,0.); - PointXYZ v1(2.,0.,0.); - PointXYZ v2(2.,2.,0.); - PointXYZ v3(0.,2.,0.); +CASE( "test_quadrilateral_intersection_doublequad" ) { + PointXYZ v0( 0., 0., 0. ); + PointXYZ v1( 2., 0., 0. ); + PointXYZ v2( 2., 2., 0. ); + PointXYZ v3( 0., 2., 0. ); - Quad3D quad(v0.data(),v1.data(),v2.data(),v3.data()); + Quad3D quad( v0.data(), v1.data(), v2.data(), v3.data() ); - EXPECT( quad.validate() ); + EXPECT( quad.validate() ); - PointXYZ orig(0.5,0.5,1.); - PointXYZ dir (0.,0.,-1.); + PointXYZ orig( 0.5, 0.5, 1. ); + PointXYZ dir( 0., 0., -1. ); - Ray ray(orig.data(),dir.data()); + Ray ray( orig.data(), dir.data() ); - Intersect isect = quad.intersects(ray); + Intersect isect = quad.intersects( ray ); - EXPECT( isect ); - EXPECT ( eckit::types::is_approximately_equal( isect.u, 0.25, relative_error ) ); - EXPECT ( eckit::types::is_approximately_equal( isect.v, 0.25, relative_error ) ); + EXPECT( isect ); + EXPECT( eckit::types::is_approximately_equal( isect.u, 0.25, relative_error ) ); + EXPECT( eckit::types::is_approximately_equal( isect.v, 0.25, relative_error ) ); } -CASE( "test_quadrilateral_intersection_rotatedquad" ) -{ - PointXYZ v0( 0.,-1.,0.); - PointXYZ v1( 1., 0.,0.); - PointXYZ v2( 0., 1.,0.); - PointXYZ v3(-1., 0.,0.); +CASE( "test_quadrilateral_intersection_rotatedquad" ) { + PointXYZ v0( 0., -1., 0. ); + PointXYZ v1( 1., 0., 0. ); + PointXYZ v2( 0., 1., 0. ); + PointXYZ v3( -1., 0., 0. ); - Quad3D quad(v0.data(),v1.data(),v2.data(),v3.data()); + Quad3D quad( v0.data(), v1.data(), v2.data(), v3.data() ); - EXPECT( quad.validate() ); + EXPECT( quad.validate() ); - PointXYZ orig(0.,0.,1.); - PointXYZ dir (0.,0.,-1.); + PointXYZ orig( 0., 0., 1. ); + PointXYZ dir( 0., 0., -1. ); - Ray ray(orig.data(),dir.data()); + Ray ray( orig.data(), dir.data() ); - Intersect isect = quad.intersects(ray); + Intersect isect = quad.intersects( ray ); - EXPECT( isect ); - EXPECT ( eckit::types::is_approximately_equal( isect.u, 0.5, relative_error ) ); - EXPECT ( eckit::types::is_approximately_equal( isect.v, 0.5, relative_error ) ); + EXPECT( isect ); + EXPECT( eckit::types::is_approximately_equal( isect.u, 0.5, relative_error ) ); + EXPECT( eckit::types::is_approximately_equal( isect.v, 0.5, relative_error ) ); } -CASE( "test_quadrilateral_intersection_slopequad" ) -{ - PointXYZ v0( 2., 0.,2.); - PointXYZ v1( 2., 0.,0.); - PointXYZ v2( 0., 2.,0.); - PointXYZ v3( 0., 2.,2.); +CASE( "test_quadrilateral_intersection_slopequad" ) { + PointXYZ v0( 2., 0., 2. ); + PointXYZ v1( 2., 0., 0. ); + PointXYZ v2( 0., 2., 0. ); + PointXYZ v3( 0., 2., 2. ); - Quad3D quad(v0.data(),v1.data(),v2.data(),v3.data()); + Quad3D quad( v0.data(), v1.data(), v2.data(), v3.data() ); - EXPECT( quad.validate() ); + EXPECT( quad.validate() ); - PointXYZ orig(2.,2.,1.); - PointXYZ dir (-1.,-1.,0.); + PointXYZ orig( 2., 2., 1. ); + PointXYZ dir( -1., -1., 0. ); - Ray ray(orig.data(),dir.data()); + Ray ray( orig.data(), dir.data() ); - Intersect isect = quad.intersects(ray); + Intersect isect = quad.intersects( ray ); - EXPECT( isect ); - EXPECT ( eckit::types::is_approximately_equal( isect.u, 0.5, relative_error ) ); - EXPECT ( eckit::types::is_approximately_equal( isect.v, 0.5, relative_error ) ); + EXPECT( isect ); + EXPECT( eckit::types::is_approximately_equal( isect.u, 0.5, relative_error ) ); + EXPECT( eckit::types::is_approximately_equal( isect.v, 0.5, relative_error ) ); } -CASE( "test_quadrilateral_intersection_nointersect" ) -{ - PointXYZ v0( 0.,-1.,0.); - PointXYZ v1( 1., 0.,0.); - PointXYZ v2( 0., 1.,0.); - PointXYZ v3(-1., 0.,0.); +CASE( "test_quadrilateral_intersection_nointersect" ) { + PointXYZ v0( 0., -1., 0. ); + PointXYZ v1( 1., 0., 0. ); + PointXYZ v2( 0., 1., 0. ); + PointXYZ v3( -1., 0., 0. ); - Quad3D quad(v0.data(),v1.data(),v2.data(),v3.data()); + Quad3D quad( v0.data(), v1.data(), v2.data(), v3.data() ); - EXPECT( quad.validate() ); + EXPECT( quad.validate() ); - PointXYZ orig(2.,2.,1.); - PointXYZ dir (0.,0.,-1.); + PointXYZ orig( 2., 2., 1. ); + PointXYZ dir( 0., 0., -1. ); - Ray ray(orig.data(),dir.data()); + Ray ray( orig.data(), dir.data() ); - Intersect isect = quad.intersects(ray); - EXPECT( ! isect ); + Intersect isect = quad.intersects( ray ); + EXPECT( !isect ); } -CASE( "test_quadrilateral_intersection_nointersect_aimoff" ) -{ - PointXYZ v0( 0.,-1.,0.); - PointXYZ v1( 1., 0.,0.); - PointXYZ v2( 0., 1.,0.); - PointXYZ v3(-1., 0.,0.); +CASE( "test_quadrilateral_intersection_nointersect_aimoff" ) { + PointXYZ v0( 0., -1., 0. ); + PointXYZ v1( 1., 0., 0. ); + PointXYZ v2( 0., 1., 0. ); + PointXYZ v3( -1., 0., 0. ); - Quad3D quad(v0.data(),v1.data(),v2.data(),v3.data()); + Quad3D quad( v0.data(), v1.data(), v2.data(), v3.data() ); - EXPECT( quad.validate() ); + EXPECT( quad.validate() ); - PointXYZ orig(0.,0.,1.); - PointXYZ dir (0.,1.,0.); // aim off + PointXYZ orig( 0., 0., 1. ); + PointXYZ dir( 0., 1., 0. ); // aim off - Ray ray(orig.data(),dir.data()); + Ray ray( orig.data(), dir.data() ); - Intersect isect = quad.intersects(ray); - EXPECT( ! isect ); + Intersect isect = quad.intersects( ray ); + EXPECT( !isect ); } -CASE( "test_quadrilateral_intersection_corners" ) -{ - PointXYZ v0( 0.0,-2.0, 0.); - PointXYZ v1( 2.5, 0.0, 0.); - PointXYZ v2( 0.0, 3.5, 0.); - PointXYZ v3(-1.5, 0.0, 0.); +CASE( "test_quadrilateral_intersection_corners" ) { + PointXYZ v0( 0.0, -2.0, 0. ); + PointXYZ v1( 2.5, 0.0, 0. ); + PointXYZ v2( 0.0, 3.5, 0. ); + PointXYZ v3( -1.5, 0.0, 0. ); - Quad3D quad(v0.data(),v1.data(),v2.data(),v3.data()); + Quad3D quad( v0.data(), v1.data(), v2.data(), v3.data() ); - EXPECT( quad.validate() ); + EXPECT( quad.validate() ); - std::vector corners; - corners.push_back( PointXYZ( 0.0,-2.0, 1.) ); - corners.push_back( PointXYZ( 2.5, 0.0, 1.) ); - corners.push_back( PointXYZ( 0.0, 3.5, 1.) ); - corners.push_back( PointXYZ(-1.5, 0.0, 1.) ); + std::vector corners; + corners.push_back( PointXYZ( 0.0, -2.0, 1. ) ); + corners.push_back( PointXYZ( 2.5, 0.0, 1. ) ); + corners.push_back( PointXYZ( 0.0, 3.5, 1. ) ); + corners.push_back( PointXYZ( -1.5, 0.0, 1. ) ); - std::vector< std::pair > uvs; - uvs.push_back( std::make_pair(0.,0.) ); - uvs.push_back( std::make_pair(1.,0.) ); - uvs.push_back( std::make_pair(1.,1.) ); - uvs.push_back( std::make_pair(0.,1.) ); + std::vector> uvs; + uvs.push_back( std::make_pair( 0., 0. ) ); + uvs.push_back( std::make_pair( 1., 0. ) ); + uvs.push_back( std::make_pair( 1., 1. ) ); + uvs.push_back( std::make_pair( 0., 1. ) ); - for( size_t i = 0; i < 4; ++i ) - { - PointXYZ orig = corners[i]; - PointXYZ dir (0.,0.,-1.); + for ( size_t i = 0; i < 4; ++i ) { + PointXYZ orig = corners[i]; + PointXYZ dir( 0., 0., -1. ); - Ray ray(orig.data(),dir.data()); + Ray ray( orig.data(), dir.data() ); - Intersect isect = quad.intersects(ray); + Intersect isect = quad.intersects( ray ); - EXPECT( isect ); - EXPECT ( eckit::types::is_approximately_equal( isect.u, uvs[i].first , relative_error ) ); - EXPECT ( eckit::types::is_approximately_equal( isect.v, uvs[i].second, relative_error ) ); - } + EXPECT( isect ); + EXPECT( eckit::types::is_approximately_equal( isect.u, uvs[i].first, relative_error ) ); + EXPECT( eckit::types::is_approximately_equal( isect.v, uvs[i].second, relative_error ) ); + } } //----------------------------------------------------------------------------- @@ -232,7 +223,6 @@ CASE( "test_quadrilateral_intersection_corners" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/interpolation/test_interpolation_finite_element.cc b/src/tests/interpolation/test_interpolation_finite_element.cc index 0e4e9f8bc..095b28c1c 100644 --- a/src/tests/interpolation/test_interpolation_finite_element.cc +++ b/src/tests/interpolation/test_interpolation_finite_element.cc @@ -4,21 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include -#include "eckit/types/FloatCompare.h" #include "atlas/functionspace/PointCloud.h" +#include "eckit/types/FloatCompare.h" #include "atlas/array.h" -#include "atlas/grid.h" -#include "atlas/meshgenerator.h" -#include "atlas/mesh.h" #include "atlas/functionspace.h" +#include "atlas/grid.h" #include "atlas/interpolation.h" +#include "atlas/mesh.h" +#include "atlas/meshgenerator.h" #include "atlas/util/CoordinateEnums.h" #include "tests/AtlasTestEnvironment.h" @@ -32,62 +33,49 @@ namespace test { //----------------------------------------------------------------------------- -CASE( "test_interpolation_finite_element" ) -{ - - Grid grid("O64"); - MeshGenerator meshgen("structured"); - Mesh mesh = meshgen.generate(grid); - NodeColumns fs(mesh); - - // Some points at the equator - PointCloud pointcloud( { - {00., 0.}, - {10., 0.}, - {20., 0.}, - {30., 0.}, - {40., 0.}, - {50., 0.}, - {60., 0.}, - {70., 0.}, - {80., 0.}, - {90., 0.}}); - - auto func = [](double x) -> double { return std::sin(x*M_PI/180.); }; - - Interpolation interpolation(Config("type","finite-element"),fs,pointcloud); - - Field field_source = fs.createField(option::name("source")); - Field field_target("target",array::make_datatype(),array::make_shape(pointcloud.size())); - - auto lonlat = array::make_view(fs.nodes().lonlat()); - auto source = array::make_view(field_source); - for( size_t j=0; j(field_target); - - auto check = std::vector { - func( 00. ), - func( 10. ), - func( 20. ), - func( 30. ), - func( 40. ), - func( 50. ), - func( 60. ), - func( 70. ), - func( 80. ), - func( 90. )}; - - for( size_t j=0; j double { return std::sin( x * M_PI / 180. ); }; + + Interpolation interpolation( Config( "type", "finite-element" ), fs, pointcloud ); + + Field field_source = fs.createField( option::name( "source" ) ); + Field field_target( "target", array::make_datatype(), array::make_shape( pointcloud.size() ) ); + + auto lonlat = array::make_view( fs.nodes().lonlat() ); + auto source = array::make_view( field_source ); + for ( size_t j = 0; j < fs.nodes().size(); ++j ) { + source( j ) = func( lonlat( j, LON ) ); + } + + interpolation.execute( field_source, field_target ); + + auto target = array::make_view( field_target ); + + auto check = std::vector{func( 00. ), func( 10. ), func( 20. ), func( 30. ), func( 40. ), + func( 50. ), func( 60. ), func( 70. ), func( 80. ), func( 90. )}; + + for ( size_t j = 0; j < pointcloud.size(); ++j ) { + static double interpolation_tolerance = 1.e-4; + Log::info() << target( j ) << " " << check[j] << std::endl; + EXPECT( eckit::types::is_approximately_equal( target( j ), check[j], interpolation_tolerance ) ); + } } //----------------------------------------------------------------------------- @@ -95,7 +83,6 @@ CASE( "test_interpolation_finite_element" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/io/test_gmsh.cc b/src/tests/io/test_gmsh.cc index a29f4d38c..c43dc083d 100644 --- a/src/tests/io/test_gmsh.cc +++ b/src/tests/io/test_gmsh.cc @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "tests/TestMeshes.h" #include "atlas/mesh/Mesh.h" -#include "atlas/output/Output.h" #include "atlas/output/Gmsh.h" +#include "atlas/output/Output.h" +#include "tests/TestMeshes.h" #include "tests/AtlasTestEnvironment.h" @@ -20,15 +21,12 @@ namespace test { //----------------------------------------------------------------------------- -CASE( "test_gmsh_output" ) -{ - Mesh mesh = test::generate_mesh( Grid("N128") ); +CASE( "test_gmsh_output" ) { + Mesh mesh = test::generate_mesh( Grid( "N128" ) ); - atlas::output::GmshFileStream file("bs.msh","w"); - output::Gmsh gmsh ( "test_gmsh_output.msh", util::Config - ("binary",true) - ("file","test_gmsh_output.msh") ); - gmsh.write(mesh); + atlas::output::GmshFileStream file( "bs.msh", "w" ); + output::Gmsh gmsh( "test_gmsh_output.msh", util::Config( "binary", true )( "file", "test_gmsh_output.msh" ) ); + gmsh.write( mesh ); } //----------------------------------------------------------------------------- @@ -36,7 +34,6 @@ CASE( "test_gmsh_output" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/io/test_pointcloud_io.cc b/src/tests/io/test_pointcloud_io.cc index d330f9dd0..a5a2b426c 100644 --- a/src/tests/io/test_pointcloud_io.cc +++ b/src/tests/io/test_pointcloud_io.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,19 +14,19 @@ #include "atlas/library/config.h" -#include "eckit/memory/ScopedPtr.h" #include "eckit/exception/Exceptions.h" +#include "eckit/memory/ScopedPtr.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" +#include "atlas/functionspace/NodeColumns.h" #include "atlas/grid/Grid.h" +#include "atlas/grid/detail/grid/Unstructured.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/grid/detail/grid/Unstructured.h" #include "atlas/output/detail/PointCloudIO.h" -#include "atlas/functionspace/NodeColumns.h" #include "atlas/parallel/mpi/mpi.h" #include "eckit/types/FloatCompare.h" @@ -35,65 +36,61 @@ namespace { - namespace test_arrays { - - const size_t nb_pts = 5; - const size_t nb_fld = 2; - const size_t nb_columns = 2+nb_fld; - - const double lon[] = { -31.233, -28.717, -27.217, -25.750, -16.917 }; - const double lat[] = { 39.467, 38.583, 38.483, 37.817, 32.650 }; - - const double helper_f1[] = { 1., 2., 3., 4., 5. }; - const double helper_f2[] = { -0.1, -0.2, -0.3, -0.4, -0.5 }; - - const double *fvalues[] = { helper_f1, helper_f2 }; - const char *fnames [] = { " f_1 ", "f 2 " }; +namespace test_arrays { - } +const size_t nb_pts = 5; +const size_t nb_fld = 2; +const size_t nb_columns = 2 + nb_fld; - namespace test_vectors { +const double lon[] = {-31.233, -28.717, -27.217, -25.750, -16.917}; +const double lat[] = {39.467, 38.583, 38.483, 37.817, 32.650}; - const size_t nb_pts = test_arrays::nb_pts; - const size_t nb_fld = test_arrays::nb_fld; - const size_t nb_columns = test_arrays::nb_columns; +const double helper_f1[] = {1., 2., 3., 4., 5.}; +const double helper_f2[] = {-0.1, -0.2, -0.3, -0.4, -0.5}; - const std::vector< double > lon(test_arrays::lon, test_arrays::lon + nb_pts); - const std::vector< double > lat(test_arrays::lat, test_arrays::lat + nb_pts); +const double* fvalues[] = {helper_f1, helper_f2}; +const char* fnames[] = {" f_1 ", "f 2 "}; - std::vector< double > helper_f1(test_arrays::helper_f1, test_arrays::helper_f1 + nb_pts); - std::vector< double > helper_f2(test_arrays::helper_f2, test_arrays::helper_f2 + nb_pts); - std::vector< double >* helper_fvalues[] = { &helper_f1, &helper_f2 }; +} // namespace test_arrays - const std::vector< std::vector< double >* > fvalues (helper_fvalues, helper_fvalues + nb_fld); - const std::vector< std::string > fnames (test_arrays::fnames, test_arrays::fnames + nb_fld); +namespace test_vectors { - } +const size_t nb_pts = test_arrays::nb_pts; +const size_t nb_fld = test_arrays::nb_fld; +const size_t nb_columns = test_arrays::nb_columns; +const std::vector lon( test_arrays::lon, test_arrays::lon + nb_pts ); +const std::vector lat( test_arrays::lat, test_arrays::lat + nb_pts ); - bool test_write_file(const std::string& file_path, const size_t& nb_pts, const size_t& nb_columns) - { - if (!nb_pts) - return false; - std::ofstream f(file_path.c_str()); - return (f && f << "PointCloudIO " << nb_pts << " " << nb_columns << " lon lat f_1 __f3 more resilience \n" - "-31.233 39.467 1. -0.1\n" - "-28.717 38.583 2. -0.2 even more resilience\n" - "-27.217 38.483 3. -0.3\n" - "-25.750 37.817 4. -0.4\n" - "-16.917 32.650 5. -0.5\n" ); - } +std::vector helper_f1( test_arrays::helper_f1, test_arrays::helper_f1 + nb_pts ); +std::vector helper_f2( test_arrays::helper_f2, test_arrays::helper_f2 + nb_pts ); +std::vector* helper_fvalues[] = {&helper_f1, &helper_f2}; +const std::vector*> fvalues( helper_fvalues, helper_fvalues + nb_fld ); +const std::vector fnames( test_arrays::fnames, test_arrays::fnames + nb_fld ); - bool test_write_file_bad(const std::string& file_path) - { - std::ofstream f(file_path.c_str()); - return (f && f << '?'); - } +} // 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; + std::ofstream f( file_path.c_str() ); + return ( f && f << "PointCloudIO " << nb_pts << " " << nb_columns + << " lon lat f_1 " + "__f3 more resilience \n" + "-31.233 39.467 1. -0.1\n" + "-28.717 38.583 2. -0.2 even more " + "resilience\n" + "-27.217 38.483 3. -0.3\n" + "-25.750 37.817 4. -0.4\n" + "-16.917 32.650 5. -0.5\n" ); +} -} // end anonymous namespace +bool test_write_file_bad( const std::string& file_path ) { + std::ofstream f( file_path.c_str() ); + return ( f && f << '?' ); +} +} // end anonymous namespace // ------------------------------------------------------------------ @@ -102,348 +99,292 @@ namespace test { // ------------------------------------------------------------------ -CASE( "read_inexistent_file" ) -{ - EXPECT_THROWS_AS( - output::detail::PointCloudIO::read("pointcloud.txt_should_not_exist"), - eckit::CantOpenFile ); +CASE( "read_inexistent_file" ) { + EXPECT_THROWS_AS( output::detail::PointCloudIO::read( "pointcloud.txt_should_not_exist" ), eckit::CantOpenFile ); } - -CASE( "read_badly_formatted_file" ) -{ - EXPECT(test_write_file_bad("pointcloud.txt")); - EXPECT_THROWS_AS( - output::detail::PointCloudIO::read("pointcloud.txt"), - eckit::BadParameter ); +CASE( "read_badly_formatted_file" ) { + EXPECT( test_write_file_bad( "pointcloud.txt" ) ); + EXPECT_THROWS_AS( output::detail::PointCloudIO::read( "pointcloud.txt" ), eckit::BadParameter ); } +CASE( "read_grid_sample_file" ) { + // test sample file, header properly formatted (some fluff is present) + EXPECT( test_write_file( "pointcloud.txt", test_arrays::nb_pts, test_arrays::nb_columns ) ); + Log::info() << "pointcloud.txt created" << std::endl; -CASE( "read_grid_sample_file" ) -{ - // test sample file, header properly formatted (some fluff is present) - EXPECT(test_write_file( - "pointcloud.txt", - test_arrays::nb_pts, - test_arrays::nb_columns )); - - Log::info() << "pointcloud.txt created" << std::endl; - - Mesh mesh = output::detail::PointCloudIO::read("pointcloud.txt"); + Mesh mesh = output::detail::PointCloudIO::read( "pointcloud.txt" ); - Log::info() << "Mesh created" << std::endl; - Grid grid( new grid::detail::grid::Unstructured(mesh) ); - EXPECT(grid); + Log::info() << "Mesh created" << std::endl; + Grid grid( new grid::detail::grid::Unstructured( mesh ) ); + EXPECT( grid ); - EXPECT(grid.size() == test_arrays::nb_pts); - EXPECT(mesh.nodes().has_field("f_1") == true); - EXPECT(mesh.nodes().has_field("f3") == true); + EXPECT( grid.size() == test_arrays::nb_pts ); + EXPECT( mesh.nodes().has_field( "f_1" ) == true ); + EXPECT( mesh.nodes().has_field( "f3" ) == true ); } +CASE( "read_grid_sample_file_header_less_rows" ) { + Log::info() << "Creating Mesh..." << std::endl; + // test sample file with (wrong) header with less rows + EXPECT( test_write_file( "pointcloud.txt", test_arrays::nb_pts - 2, test_arrays::nb_columns ) ); -CASE( "read_grid_sample_file_header_less_rows" ) -{ - Log::info() << "Creating Mesh..." << std::endl; - // test sample file with (wrong) header with less rows - EXPECT(test_write_file( - "pointcloud.txt", - test_arrays::nb_pts-2, - test_arrays::nb_columns )); - - Log::info() << "Creating Mesh..." << std::endl; - Mesh mesh = output::detail::PointCloudIO::read("pointcloud.txt"); - Log::info() << "Creating Mesh...done" << std::endl; - Grid grid( new grid::detail::grid::Unstructured(mesh) ); - EXPECT(grid); - - EXPECT(grid.size() == test_arrays::nb_pts-2); - EXPECT(mesh.nodes().has_field("f_1") == true); - EXPECT(mesh.nodes().has_field("f3") == true); -} + Log::info() << "Creating Mesh..." << std::endl; + Mesh mesh = output::detail::PointCloudIO::read( "pointcloud.txt" ); + Log::info() << "Creating Mesh...done" << std::endl; + Grid grid( new grid::detail::grid::Unstructured( mesh ) ); + EXPECT( grid ); + EXPECT( grid.size() == test_arrays::nb_pts - 2 ); + EXPECT( mesh.nodes().has_field( "f_1" ) == true ); + EXPECT( mesh.nodes().has_field( "f3" ) == true ); +} -CASE( "read_grid_sample_file_header_less_columns_1" ) -{ - // test sample file with (wrong) header with one field less - EXPECT(test_write_file( - "pointcloud.txt", - test_arrays::nb_pts, - test_arrays::nb_columns-1 )); +CASE( "read_grid_sample_file_header_less_columns_1" ) { + // test sample file with (wrong) header with one field less + EXPECT( test_write_file( "pointcloud.txt", test_arrays::nb_pts, test_arrays::nb_columns - 1 ) ); - Mesh mesh = output::detail::PointCloudIO::read("pointcloud.txt"); - Grid grid( new grid::detail::grid::Unstructured(mesh) ); - EXPECT(grid); + Mesh mesh = output::detail::PointCloudIO::read( "pointcloud.txt" ); + Grid grid( new grid::detail::grid::Unstructured( mesh ) ); + EXPECT( grid ); - EXPECT(grid.size() == test_arrays::nb_pts); - EXPECT(mesh.nodes().has_field("f_1") == true); - EXPECT(mesh.nodes().has_field("f3") == false); + EXPECT( grid.size() == test_arrays::nb_pts ); + EXPECT( mesh.nodes().has_field( "f_1" ) == true ); + EXPECT( mesh.nodes().has_field( "f3" ) == false ); } +CASE( "read_grid_sample_file_header_less_columns_2" ) { + // test sample file with (wrong) header with no fields + EXPECT( test_write_file( "pointcloud.txt", test_arrays::nb_pts, test_arrays::nb_columns - test_arrays::nb_fld ) ); -CASE( "read_grid_sample_file_header_less_columns_2" ) -{ - // test sample file with (wrong) header with no fields - EXPECT(test_write_file( - "pointcloud.txt", - test_arrays::nb_pts, - test_arrays::nb_columns-test_arrays::nb_fld )); + Mesh mesh = output::detail::PointCloudIO::read( "pointcloud.txt" ); + Grid grid( new grid::detail::grid::Unstructured( mesh ) ); + EXPECT( grid ); - Mesh mesh = output::detail::PointCloudIO::read("pointcloud.txt"); - Grid grid( new grid::detail::grid::Unstructured(mesh) ); - EXPECT(grid); - - EXPECT(grid.size() == test_arrays::nb_pts); - EXPECT(mesh.nodes().has_field("f_1") == false); - EXPECT(mesh.nodes().has_field("f3") == false); + EXPECT( grid.size() == test_arrays::nb_pts ); + EXPECT( mesh.nodes().has_field( "f_1" ) == false ); + EXPECT( mesh.nodes().has_field( "f3" ) == false ); } - -CASE( "write_array" ) -{ - std::ifstream f; - std::string signature, str_lon, str_lat, str_f1, str_f2; - size_t nb_pts, nb_columns; - - output::detail::PointCloudIO::write( - "pointcloud.txt", - test_arrays::nb_pts, test_arrays::lon, test_arrays::lat ); - f.open("pointcloud.txt"); - EXPECT(f); - f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; - f.close(); - - EXPECT( nb_pts == test_arrays::nb_pts ); - EXPECT( nb_columns == test_arrays::nb_columns-test_arrays::nb_fld ); - EXPECT( str_lon == "lon" ); - EXPECT( str_lat == "lat" ); - EXPECT( str_f1 != "f_1" ); // (this column is not written) - EXPECT( str_f2 != "f____2" ); // (this column is not written) +CASE( "write_array" ) { + std::ifstream f; + std::string signature, str_lon, str_lat, str_f1, str_f2; + size_t nb_pts, nb_columns; + + output::detail::PointCloudIO::write( "pointcloud.txt", test_arrays::nb_pts, test_arrays::lon, test_arrays::lat ); + f.open( "pointcloud.txt" ); + EXPECT( f ); + f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; + f.close(); + + EXPECT( nb_pts == test_arrays::nb_pts ); + EXPECT( nb_columns == test_arrays::nb_columns - test_arrays::nb_fld ); + EXPECT( str_lon == "lon" ); + EXPECT( str_lat == "lat" ); + EXPECT( str_f1 != "f_1" ); // (this column is not written) + EXPECT( str_f2 != "f____2" ); // (this column is not written) } - -CASE( "write_array_less_rows" ) -{ - std::ifstream f; - std::string signature, str_lon, str_lat, str_f1, str_f2; - size_t nb_pts, nb_columns; - - output::detail::PointCloudIO::write( - "pointcloud.txt", - test_arrays::nb_pts-1 /* deliberate */, test_arrays::lon, test_arrays::lat, - test_arrays::nb_fld, test_arrays::fvalues, test_arrays::fnames ); - f.open("pointcloud.txt"); - EXPECT(f); - f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; - f.close(); - - EXPECT( nb_pts == test_arrays::nb_pts-1 ); // (one row is not written) - EXPECT( nb_columns == test_arrays::nb_columns ); - EXPECT( str_lon == "lon" ); - EXPECT( str_lat == "lat" ); - EXPECT( str_f1 == "f_1" ); - EXPECT( str_f2 == "f____2" ); +CASE( "write_array_less_rows" ) { + std::ifstream f; + std::string signature, str_lon, str_lat, str_f1, str_f2; + size_t nb_pts, nb_columns; + + output::detail::PointCloudIO::write( "pointcloud.txt", test_arrays::nb_pts - 1 /* deliberate */, test_arrays::lon, + test_arrays::lat, test_arrays::nb_fld, test_arrays::fvalues, + test_arrays::fnames ); + f.open( "pointcloud.txt" ); + EXPECT( f ); + f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; + f.close(); + + EXPECT( nb_pts == test_arrays::nb_pts - 1 ); // (one row is not written) + EXPECT( nb_columns == test_arrays::nb_columns ); + EXPECT( str_lon == "lon" ); + EXPECT( str_lat == "lat" ); + EXPECT( str_f1 == "f_1" ); + EXPECT( str_f2 == "f____2" ); } - -CASE( "write_array_less_columns" ) -{ - std::ifstream f; - std::string signature, str_lon, str_lat, str_f1, str_f2; - size_t nb_pts, nb_columns; - - output::detail::PointCloudIO::write( - "pointcloud.txt", - test_arrays::nb_pts, test_arrays::lon, test_arrays::lat, - test_arrays::nb_fld-1 /* deliberate */, test_arrays::fvalues, test_arrays::fnames ); - f.open("pointcloud.txt"); - EXPECT(f); - f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; - f.close(); - - EXPECT( nb_pts == test_arrays::nb_pts ); - EXPECT( nb_columns == test_arrays::nb_columns-1 ); // (one column is not written) - EXPECT( str_lon == "lon" ); - EXPECT( str_lat == "lat" ); - EXPECT( str_f1 == "f_1" ); - EXPECT( str_f2 != "f____2" ); // (this column is not written) +CASE( "write_array_less_columns" ) { + std::ifstream f; + std::string signature, str_lon, str_lat, str_f1, str_f2; + size_t nb_pts, nb_columns; + + output::detail::PointCloudIO::write( "pointcloud.txt", test_arrays::nb_pts, test_arrays::lon, test_arrays::lat, + test_arrays::nb_fld - 1 /* deliberate */, test_arrays::fvalues, + test_arrays::fnames ); + f.open( "pointcloud.txt" ); + EXPECT( f ); + f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; + f.close(); + + EXPECT( nb_pts == test_arrays::nb_pts ); + EXPECT( nb_columns == test_arrays::nb_columns - 1 ); // (one column is not written) + EXPECT( str_lon == "lon" ); + EXPECT( str_lat == "lat" ); + EXPECT( str_f1 == "f_1" ); + EXPECT( str_f2 != "f____2" ); // (this column is not written) } - -CASE( "write_vector_all_fields" ) -{ - std::ifstream f; - std::string signature, str_lon, str_lat, str_f1, str_f2; - size_t nb_pts, nb_columns; - - output::detail::PointCloudIO::write( - "pointcloud.txt", - test_vectors::lon, test_vectors::lat, - test_vectors::fvalues, test_vectors::fnames ); - f.open("pointcloud.txt"); - EXPECT(f); - f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; - f.close(); - - EXPECT( nb_pts == test_vectors::nb_pts ); - EXPECT( nb_columns == test_vectors::nb_columns ); - EXPECT( str_lon == "lon" ); - EXPECT( str_lat == "lat" ); - EXPECT( str_f1 == "f_1" ); - EXPECT( str_f2 == "f____2" ); +CASE( "write_vector_all_fields" ) { + std::ifstream f; + std::string signature, str_lon, str_lat, str_f1, str_f2; + size_t nb_pts, nb_columns; + + output::detail::PointCloudIO::write( "pointcloud.txt", test_vectors::lon, test_vectors::lat, test_vectors::fvalues, + test_vectors::fnames ); + f.open( "pointcloud.txt" ); + EXPECT( f ); + f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; + f.close(); + + EXPECT( nb_pts == test_vectors::nb_pts ); + EXPECT( nb_columns == test_vectors::nb_columns ); + EXPECT( str_lon == "lon" ); + EXPECT( str_lat == "lat" ); + EXPECT( str_f1 == "f_1" ); + EXPECT( str_f2 == "f____2" ); } - -CASE( "write_vector_no_fields" ) -{ - std::ifstream f; - std::string signature, str_lon, str_lat, str_f1, str_f2; - size_t nb_pts, nb_columns; - - output::detail::PointCloudIO::write( - "pointcloud.txt", - test_vectors::lon, test_vectors::lat ); - f.open("pointcloud.txt"); - EXPECT(f); - f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; - f.close(); - - EXPECT( nb_pts == test_vectors::nb_pts); - EXPECT( nb_columns == test_vectors::nb_columns-test_vectors::nb_fld); - EXPECT( str_lon == "lon" ); - EXPECT( str_lat == "lat" ); - EXPECT( str_f1 != "f_1" ); // (this column is not written) - EXPECT( str_f2 != "f____2" ); // (this column is not written) +CASE( "write_vector_no_fields" ) { + std::ifstream f; + std::string signature, str_lon, str_lat, str_f1, str_f2; + size_t nb_pts, nb_columns; + + output::detail::PointCloudIO::write( "pointcloud.txt", test_vectors::lon, test_vectors::lat ); + f.open( "pointcloud.txt" ); + EXPECT( f ); + f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f1 >> str_f2; + f.close(); + + EXPECT( nb_pts == test_vectors::nb_pts ); + EXPECT( nb_columns == test_vectors::nb_columns - test_vectors::nb_fld ); + EXPECT( str_lon == "lon" ); + EXPECT( str_lat == "lat" ); + EXPECT( str_f1 != "f_1" ); // (this column is not written) + EXPECT( str_f2 != "f____2" ); // (this column is not written) } -static double funny_formula( int x ) -{ - return ((double) (x)) * std::pow((double) -1.,(int) (x)); +static double funny_formula( int x ) { + return ( (double)( x ) ) * std::pow( (double)-1., (int)( x ) ); } -CASE( "write_read_write_field" ) -{ - // build suitable data structures do hold field name & values - std::string field_name("my_super_field"); - std::vector< double > field_values(test_vectors::nb_pts,0.); - for (size_t i=0; i* >(1, &field_values ), - std::vector< std::string >(1, field_name ) ); - f.open("pointcloud.txt"); - EXPECT(f); - f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f; - f.close(); - - EXPECT( nb_pts == test_vectors::nb_pts); - EXPECT( nb_columns == 2+1); // (lon,lat,my_super_field) - EXPECT( str_lon == "lon" ); - EXPECT( str_lat == "lat" ); - EXPECT( str_f == "my_super_field" ); - - - // PART 2 - // read field vector from just-created file - Log::info() << "Part 2" << std::endl; - - Mesh mesh = output::detail::PointCloudIO::read("pointcloud.txt"); - Grid grid( new grid::detail::grid::Unstructured(mesh) ); - EXPECT(grid); - - EXPECT(grid.size() == test_vectors::nb_pts); - - mesh::Nodes& nodes = mesh.nodes(); - EXPECT(nodes.has_field("my_super_field") == true); - EXPECT(nodes.has_field("_StRaNgE_FiElD_NaMe_") == false); - - - // PART 3 - // check field values to a very small tolerance (relative tol. 0.001%) - Log::info() << "Part 3" << std::endl; - - Field& field(nodes.field("my_super_field")); - EXPECT( +CASE( "write_read_write_field" ) { + // build suitable data structures do hold field name & values + std::string field_name( "my_super_field" ); + std::vector field_values( test_vectors::nb_pts, 0. ); + for ( size_t i = 0; i < test_vectors::nb_pts; ++i ) { + field_values[i] = funny_formula( i ); + } + + // PART 1 + // write field vector values as column in file "pointcloud.txt" + Log::info() << "Part 1" << std::endl; + + std::ifstream f; + std::string signature, str_lon, str_lat, str_f; + size_t nb_pts, nb_columns; + + output::detail::PointCloudIO::write( "pointcloud.txt", test_vectors::lon, test_vectors::lat, + std::vector*>( 1, &field_values ), + std::vector( 1, field_name ) ); + f.open( "pointcloud.txt" ); + EXPECT( f ); + f >> signature >> nb_pts >> nb_columns >> str_lon >> str_lat >> str_f; + f.close(); + + EXPECT( nb_pts == test_vectors::nb_pts ); + EXPECT( nb_columns == 2 + 1 ); // (lon,lat,my_super_field) + EXPECT( str_lon == "lon" ); + EXPECT( str_lat == "lat" ); + EXPECT( str_f == "my_super_field" ); + + // PART 2 + // read field vector from just-created file + Log::info() << "Part 2" << std::endl; + + Mesh mesh = output::detail::PointCloudIO::read( "pointcloud.txt" ); + Grid grid( new grid::detail::grid::Unstructured( mesh ) ); + EXPECT( grid ); + + EXPECT( grid.size() == test_vectors::nb_pts ); + + mesh::Nodes& nodes = mesh.nodes(); + EXPECT( nodes.has_field( "my_super_field" ) == true ); + EXPECT( nodes.has_field( "_StRaNgE_FiElD_NaMe_" ) == false ); + + // PART 3 + // check field values to a very small tolerance (relative tol. 0.001%) + Log::info() << "Part 3" << std::endl; + + Field& field( nodes.field( "my_super_field" ) ); + EXPECT( /* data used to write file*/ test_vectors::nb_pts == - /* data read from file*/ field.size() ); - - array::ArrayView< double, 1 > field_data = array::make_view(field); - for (size_t i=0; i() != field_from_FieldSet.data() ); - EXPECT( field.data() != field_from_Grid.data() ); - - array::ArrayView< double,1 > field_from_FieldSet_data = array::make_view(field_from_FieldSet); - array::ArrayView< double,1 > field_from_Grid_data = array::make_view(field_from_Grid ); - for (size_t i=0; i field_data = array::make_view( field ); + for ( size_t i = 0; i < field_data.size(); ++i ) { + EXPECT( eckit::types::is_approximately_equal( funny_formula( i ), field_data( i ), + 0.001 ) ); // 0.001% relative error + } + + // PART 4 + // write to file a Field (the just-read one), + // a FieldSet, and + // a Grid (should be exactly the same) + Log::info() << "Part 4" << std::endl; + + FieldSet fieldset; + EXPECT_NO_THROW( fieldset.add( field ) ); + + functionspace::NodeColumns functionspace( mesh ); + EXPECT_NO_THROW( output::detail::PointCloudIO::write( "pointcloud_FieldSet.txt", fieldset, functionspace ) ); + EXPECT_NO_THROW( output::detail::PointCloudIO::write( "pointcloud_Grid.txt", mesh ) ); + + Mesh mesh_from_FieldSet = output::detail::PointCloudIO::read( "pointcloud_FieldSet.txt" ); + Grid grid_from_FieldSet( new grid::detail::grid::Unstructured( mesh_from_FieldSet ) ); + + Mesh mesh_from_Grid( output::detail::PointCloudIO::read( "pointcloud_Grid.txt" ) ); + Grid grid_from_Grid( new grid::detail::grid::Unstructured( mesh_from_Grid ) ); + + EXPECT( grid_from_FieldSet ); + EXPECT( grid_from_Grid ); + + // (guarantee different grid, to make checks useful) + EXPECT( grid != grid_from_FieldSet ); + EXPECT( grid != grid_from_Grid ); + + // PART 5 + // compare reading of reference data to: + // - grid_from_FieldSet, and + // - grid_from_Grid (all different but equivalent writing methods) + Log::info() << "Part 5" << std::endl; + + // (header section) + EXPECT( grid_from_FieldSet.size() == test_arrays::nb_pts ); + EXPECT( mesh_from_FieldSet.nodes().has_field( "my_super_field" ) == true ); + EXPECT( mesh_from_FieldSet.nodes().has_field( "_StRaNgE_FiElD_NaMe_" ) == false ); + + EXPECT( grid_from_Grid.size() == test_arrays::nb_pts ); + EXPECT( mesh_from_FieldSet.nodes().has_field( "my_super_field" ) == true ); + EXPECT( mesh_from_FieldSet.nodes().has_field( "_StRaNgE_FiElD_NaMe_" ) == false ); + + // (data section: guarantee data are from different places, to make checks + // useful) + const Field& field_from_FieldSet( mesh_from_FieldSet.nodes().field( "my_super_field" ) ); + const Field& field_from_Grid( mesh_from_FieldSet.nodes().field( "my_super_field" ) ); + EXPECT( field.data() != field_from_FieldSet.data() ); + EXPECT( field.data() != field_from_Grid.data() ); + + array::ArrayView field_from_FieldSet_data = array::make_view( field_from_FieldSet ); + array::ArrayView field_from_Grid_data = array::make_view( field_from_Grid ); + for ( size_t i = 0; i < test_arrays::nb_pts; ++i ) { + EXPECT( eckit::types::is_approximately_equal( field_data( i ), field_from_FieldSet_data( i ), + 0.001 ) ); // 0.001% relative error + EXPECT( eckit::types::is_approximately_equal( field_data( i ), field_from_Grid_data( i ), 0.001 ) ); // ... + } } //----------------------------------------------------------------------------- @@ -451,7 +392,6 @@ CASE( "write_read_write_field" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_accumulate_facets.cc b/src/tests/mesh/test_accumulate_facets.cc index 585ca327a..4a3d59a76 100644 --- a/src/tests/mesh/test_accumulate_facets.cc +++ b/src/tests/mesh/test_accumulate_facets.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -13,11 +14,11 @@ #include "atlas/library/Library.h" #include "atlas/mesh/detail/AccumulateFacets.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/HybridElements.h" +#include "atlas/mesh/Mesh.h" #include "atlas/mesh/actions/BuildEdges.h" +#include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/util/Unique.h" #include "tests/AtlasTestEnvironment.h" @@ -30,826 +31,481 @@ namespace test { //----------------------------------------------------------------------------- - -CASE( "test_accumulate_facets" ) -{ - Grid grid("O2"); - meshgenerator::StructuredMeshGenerator generator( Config - ("angle",29.0) - ("triangulate",false) - ("ghost_at_end",false) ); - - Mesh mesh = generator.generate(grid); - - // storage for edge-to-node-connectivity shape=(nb_edges,2) - std::vector< idx_t > edge_nodes_data; - - // storage for edge-to-cell-connectivity shape=(nb_edges,2) - std::vector< idx_t > edge_to_cell_data; - - size_t nb_edges; - size_t nb_inner_edges; - idx_t missing_value; - - // Accumulate facets of cells ( edges in 2D ) - mesh::detail::accumulate_facets(mesh.cells(),mesh.nodes(),edge_nodes_data,edge_to_cell_data,nb_edges,nb_inner_edges,missing_value); - - idx_t edge_nodes_check[] = { - 0, 21, - 21, 22, - 22, 1, - 1, 0, - 22, 23, - 23, 2, - 2, 1, - 3, 25, - 25, 26, - 26, 4, - 4, 3, - 26, 27, - 27, 5, - 5, 4, - 27, 28, - 28, 6, - 6, 5, - 28, 29, - 29, 7, - 7, 6, - 8, 31, - 31, 32, - 32, 9, - 9, 8, - 32, 33, - 33, 10, - 10, 9, - 33, 34, - 34, 11, - 11, 10, - 34, 35, - 35, 12, - 12, 11, - 13, 37, - 37, 38, - 38, 14, - 14, 13, - 38, 39, - 39, 15, - 15, 14, - 39, 40, - 40, 16, - 16, 15, - 40, 41, - 41, 17, - 17, 16, - 18, 43, - 43, 44, - 44, 19, - 19, 18, - 44, 45, - 45, 20, - 20, 19, - 21, 46, - 46, 47, - 47, 22, - 47, 48, - 48, 23, - 48, 49, - 49, 24, - 24, 23, - 49, 50, - 50, 25, - 25, 24, - 50, 51, - 51, 26, - 51, 52, - 52, 27, - 52, 53, - 53, 28, - 53, 54, - 54, 29, - 54, 55, - 55, 30, - 30, 29, - 55, 56, - 56, 31, - 31, 30, - 56, 57, - 57, 32, - 57, 58, - 58, 33, - 58, 59, - 59, 34, - 59, 60, - 60, 35, - 60, 61, - 61, 36, - 36, 35, - 61, 62, - 62, 37, - 37, 36, - 62, 63, - 63, 38, - 63, 64, - 64, 39, - 64, 65, - 65, 40, - 65, 66, - 66, 41, - 66, 67, - 67, 42, - 42, 41, - 67, 68, - 68, 43, - 43, 42, - 68, 69, - 69, 44, - 69, 70, - 70, 45, - 46, 71, - 71, 72, - 72, 47, - 72, 73, - 73, 48, - 50, 74, - 74, 75, - 75, 51, - 75, 76, - 76, 52, - 76, 77, - 77, 53, - 77, 78, - 78, 54, - 56, 79, - 79, 80, - 80, 57, - 80, 81, - 81, 58, - 81, 82, - 82, 59, - 82, 83, - 83, 60, - 62, 84, - 84, 85, - 85, 63, - 85, 86, - 86, 64, - 86, 87, - 87, 65, - 87, 88, - 88, 66, - 68, 89, - 89, 90, - 90, 69, - 90, 91, - 91, 70, - 24, 2, - 24, 3, - 3, 2, - 30, 7, - 30, 8, - 8, 7, - 36, 12, - 36, 13, - 13, 12, - 42, 17, - 42, 18, - 18, 17, - 73, 49, - 73, 74, - 74, 49, - 78, 55, - 78, 79, - 79, 55, - 83, 61, - 83, 84, - 84, 61, - 88, 67, - 88, 89, - 89, 67 - }; - EXPECT( edge_nodes_data == eckit::testing::make_view(edge_nodes_check, edge_nodes_check+2*nb_edges) ); - - idx_t edge_to_cell_check[] = { - 0, missing_value, - 0, 16, - 0, 1, - 0, missing_value, - 1, 17, - 1, 56, - 1, missing_value, - 2, 58, - 2, 20, - 2, 3, - 2, missing_value, - 3, 21, - 3, 4, - 3, missing_value, - 4, 22, - 4, 5, - 4, missing_value, - 5, 23, - 5, 59, - 5, missing_value, - 6, 61, - 6, 26, - 6, 7, - 6, missing_value, - 7, 27, - 7, 8, - 7, missing_value, - 8, 28, - 8, 9, - 8, missing_value, - 9, 29, - 9, 62, - 9, missing_value, - 10, 64, - 10, 32, - 10, 11, - 10, missing_value, - 11, 33, - 11, 12, - 11, missing_value, - 12, 34, - 12, 13, - 12, missing_value, - 13, 35, - 13, 65, - 13, missing_value, - 14, 67, - 14, 38, - 14, 15, - 14, missing_value, - 15, 39, - 15, missing_value, - 15, missing_value, - 16, missing_value, - 16, 40, - 16, 17, - 17, 41, - 17, 18, - 18, 68, - 18, 19, - 18, 56, - 19, 70, - 19, 20, - 19, 58, - 20, 42, - 20, 21, - 21, 43, - 21, 22, - 22, 44, - 22, 23, - 23, 45, - 23, 24, - 24, 71, - 24, 25, - 24, 59, - 25, 73, - 25, 26, - 25, 61, - 26, 46, - 26, 27, - 27, 47, - 27, 28, - 28, 48, - 28, 29, - 29, 49, - 29, 30, - 30, 74, - 30, 31, - 30, 62, - 31, 76, - 31, 32, - 31, 64, - 32, 50, - 32, 33, - 33, 51, - 33, 34, - 34, 52, - 34, 35, - 35, 53, - 35, 36, - 36, 77, - 36, 37, - 36, 65, - 37, 79, - 37, 38, - 37, 67, - 38, 54, - 38, 39, - 39, 55, - 39, missing_value, - 40, missing_value, - 40, missing_value, - 40, 41, - 41, missing_value, - 41, 68, - 42, 70, - 42, missing_value, - 42, 43, - 43, missing_value, - 43, 44, - 44, missing_value, - 44, 45, - 45, missing_value, - 45, 71, - 46, 73, - 46, missing_value, - 46, 47, - 47, missing_value, - 47, 48, - 48, missing_value, - 48, 49, - 49, missing_value, - 49, 74, - 50, 76, - 50, missing_value, - 50, 51, - 51, missing_value, - 51, 52, - 52, missing_value, - 52, 53, - 53, missing_value, - 53, 77, - 54, 79, - 54, missing_value, - 54, 55, - 55, missing_value, - 55, missing_value, - 56, 57, - 57, 58, - 57, missing_value, - 59, 60, - 60, 61, - 60, missing_value, - 62, 63, - 63, 64, - 63, missing_value, - 65, 66, - 66, 67, - 66, missing_value, - 68, 69, - 69, missing_value, - 69, 70, - 71, 72, - 72, missing_value, - 72, 73, - 74, 75, - 75, missing_value, - 75, 76, - 77, 78, - 78, missing_value, - 78, 79 - }; - EXPECT( edge_to_cell_data == eckit::testing::make_view(edge_to_cell_check, edge_to_cell_check+2*nb_edges) ); +CASE( "test_accumulate_facets" ) { + Grid grid( "O2" ); + meshgenerator::StructuredMeshGenerator generator( + Config( "angle", 29.0 )( "triangulate", false )( "ghost_at_end", false ) ); + + Mesh mesh = generator.generate( grid ); + + // storage for edge-to-node-connectivity shape=(nb_edges,2) + std::vector edge_nodes_data; + + // storage for edge-to-cell-connectivity shape=(nb_edges,2) + std::vector edge_to_cell_data; + + size_t nb_edges; + size_t nb_inner_edges; + idx_t missing_value; + + // Accumulate facets of cells ( edges in 2D ) + mesh::detail::accumulate_facets( mesh.cells(), mesh.nodes(), edge_nodes_data, edge_to_cell_data, nb_edges, + nb_inner_edges, missing_value ); + + idx_t edge_nodes_check[] = { + 0, 21, 21, 22, 22, 1, 1, 0, 22, 23, 23, 2, 2, 1, 3, 25, 25, 26, 26, 4, 4, 3, 26, 27, 27, 5, 5, + 4, 27, 28, 28, 6, 6, 5, 28, 29, 29, 7, 7, 6, 8, 31, 31, 32, 32, 9, 9, 8, 32, 33, 33, 10, 10, 9, + 33, 34, 34, 11, 11, 10, 34, 35, 35, 12, 12, 11, 13, 37, 37, 38, 38, 14, 14, 13, 38, 39, 39, 15, 15, 14, 39, + 40, 40, 16, 16, 15, 40, 41, 41, 17, 17, 16, 18, 43, 43, 44, 44, 19, 19, 18, 44, 45, 45, 20, 20, 19, 21, 46, + 46, 47, 47, 22, 47, 48, 48, 23, 48, 49, 49, 24, 24, 23, 49, 50, 50, 25, 25, 24, 50, 51, 51, 26, 51, 52, 52, + 27, 52, 53, 53, 28, 53, 54, 54, 29, 54, 55, 55, 30, 30, 29, 55, 56, 56, 31, 31, 30, 56, 57, 57, 32, 57, 58, + 58, 33, 58, 59, 59, 34, 59, 60, 60, 35, 60, 61, 61, 36, 36, 35, 61, 62, 62, 37, 37, 36, 62, 63, 63, 38, 63, + 64, 64, 39, 64, 65, 65, 40, 65, 66, 66, 41, 66, 67, 67, 42, 42, 41, 67, 68, 68, 43, 43, 42, 68, 69, 69, 44, + 69, 70, 70, 45, 46, 71, 71, 72, 72, 47, 72, 73, 73, 48, 50, 74, 74, 75, 75, 51, 75, 76, 76, 52, 76, 77, 77, + 53, 77, 78, 78, 54, 56, 79, 79, 80, 80, 57, 80, 81, 81, 58, 81, 82, 82, 59, 82, 83, 83, 60, 62, 84, 84, 85, + 85, 63, 85, 86, 86, 64, 86, 87, 87, 65, 87, 88, 88, 66, 68, 89, 89, 90, 90, 69, 90, 91, 91, 70, 24, 2, 24, + 3, 3, 2, 30, 7, 30, 8, 8, 7, 36, 12, 36, 13, 13, 12, 42, 17, 42, 18, 18, 17, 73, 49, 73, 74, 74, 49, + 78, 55, 78, 79, 79, 55, 83, 61, 83, 84, 84, 61, 88, 67, 88, 89, 89, 67}; + EXPECT( edge_nodes_data == eckit::testing::make_view( edge_nodes_check, edge_nodes_check + 2 * nb_edges ) ); + + idx_t edge_to_cell_check[] = {0, missing_value, + 0, 16, + 0, 1, + 0, missing_value, + 1, 17, + 1, 56, + 1, missing_value, + 2, 58, + 2, 20, + 2, 3, + 2, missing_value, + 3, 21, + 3, 4, + 3, missing_value, + 4, 22, + 4, 5, + 4, missing_value, + 5, 23, + 5, 59, + 5, missing_value, + 6, 61, + 6, 26, + 6, 7, + 6, missing_value, + 7, 27, + 7, 8, + 7, missing_value, + 8, 28, + 8, 9, + 8, missing_value, + 9, 29, + 9, 62, + 9, missing_value, + 10, 64, + 10, 32, + 10, 11, + 10, missing_value, + 11, 33, + 11, 12, + 11, missing_value, + 12, 34, + 12, 13, + 12, missing_value, + 13, 35, + 13, 65, + 13, missing_value, + 14, 67, + 14, 38, + 14, 15, + 14, missing_value, + 15, 39, + 15, missing_value, + 15, missing_value, + 16, missing_value, + 16, 40, + 16, 17, + 17, 41, + 17, 18, + 18, 68, + 18, 19, + 18, 56, + 19, 70, + 19, 20, + 19, 58, + 20, 42, + 20, 21, + 21, 43, + 21, 22, + 22, 44, + 22, 23, + 23, 45, + 23, 24, + 24, 71, + 24, 25, + 24, 59, + 25, 73, + 25, 26, + 25, 61, + 26, 46, + 26, 27, + 27, 47, + 27, 28, + 28, 48, + 28, 29, + 29, 49, + 29, 30, + 30, 74, + 30, 31, + 30, 62, + 31, 76, + 31, 32, + 31, 64, + 32, 50, + 32, 33, + 33, 51, + 33, 34, + 34, 52, + 34, 35, + 35, 53, + 35, 36, + 36, 77, + 36, 37, + 36, 65, + 37, 79, + 37, 38, + 37, 67, + 38, 54, + 38, 39, + 39, 55, + 39, missing_value, + 40, missing_value, + 40, missing_value, + 40, 41, + 41, missing_value, + 41, 68, + 42, 70, + 42, missing_value, + 42, 43, + 43, missing_value, + 43, 44, + 44, missing_value, + 44, 45, + 45, missing_value, + 45, 71, + 46, 73, + 46, missing_value, + 46, 47, + 47, missing_value, + 47, 48, + 48, missing_value, + 48, 49, + 49, missing_value, + 49, 74, + 50, 76, + 50, missing_value, + 50, 51, + 51, missing_value, + 51, 52, + 52, missing_value, + 52, 53, + 53, missing_value, + 53, 77, + 54, 79, + 54, missing_value, + 54, 55, + 55, missing_value, + 55, missing_value, + 56, 57, + 57, 58, + 57, missing_value, + 59, 60, + 60, 61, + 60, missing_value, + 62, 63, + 63, 64, + 63, missing_value, + 65, 66, + 66, 67, + 66, missing_value, + 68, 69, + 69, missing_value, + 69, 70, + 71, 72, + 72, missing_value, + 72, 73, + 74, 75, + 75, missing_value, + 75, 76, + 77, 78, + 78, missing_value, + 78, 79}; + EXPECT( edge_to_cell_data == eckit::testing::make_view( edge_to_cell_check, edge_to_cell_check + 2 * nb_edges ) ); } -CASE( "test_build_edges" ) -{ - idx_t missing_value = -1; - Grid grid("O2"); - meshgenerator::StructuredMeshGenerator generator( Config - ("angle",29.0) - ("triangulate",false) - ("ghost_at_end",false) ); - Mesh mesh = generator.generate(grid); - - // Accumulate facets of cells ( edges in 2D ) - mesh::actions::build_edges(mesh); - - idx_t edge_nodes_check[] = { - 0, 21, - 21, 22, - 22, 1, - 1, 0, - 22, 23, - 23, 2, - 2, 1, - 3, 25, - 25, 26, - 26, 4, - 4, 3, - 26, 27, - 27, 5, - 5, 4, - 27, 28, - 28, 6, - 6, 5, - 28, 29, - 29, 7, - 7, 6, - 8, 31, - 31, 32, - 32, 9, - 9, 8, - 32, 33, - 33, 10, - 10, 9, - 33, 34, - 34, 11, - 11, 10, - 34, 35, - 35, 12, - 12, 11, - 13, 37, - 37, 38, - 38, 14, - 14, 13, - 38, 39, - 39, 15, - 15, 14, - 39, 40, - 40, 16, - 16, 15, - 40, 41, - 41, 17, - 17, 16, - 18, 43, - 43, 44, - 44, 19, - 19, 18, - 44, 45, - 45, 20, - 20, 19, - 21, 46, - 46, 47, - 47, 22, - 47, 48, - 48, 23, - 48, 49, - 49, 24, - 24, 23, - 49, 50, - 50, 25, - 25, 24, - 50, 51, - 51, 26, - 51, 52, - 52, 27, - 52, 53, - 53, 28, - 53, 54, - 54, 29, - 54, 55, - 55, 30, - 30, 29, - 55, 56, - 56, 31, - 31, 30, - 56, 57, - 57, 32, - 57, 58, - 58, 33, - 58, 59, - 59, 34, - 59, 60, - 60, 35, - 60, 61, - 61, 36, - 36, 35, - 61, 62, - 62, 37, - 37, 36, - 62, 63, - 63, 38, - 63, 64, - 64, 39, - 64, 65, - 65, 40, - 65, 66, - 66, 41, - 66, 67, - 67, 42, - 42, 41, - 67, 68, - 68, 43, - 43, 42, - 68, 69, - 69, 44, - 69, 70, - 70, 45, - 46, 71, - 71, 72, - 72, 47, - 72, 73, - 73, 48, - 50, 74, - 74, 75, - 75, 51, - 75, 76, - 76, 52, - 76, 77, - 77, 53, - 77, 78, - 78, 54, - 56, 79, - 79, 80, - 80, 57, - 80, 81, - 81, 58, - 81, 82, - 82, 59, - 82, 83, - 83, 60, - 62, 84, - 84, 85, - 85, 63, - 85, 86, - 86, 64, - 86, 87, - 87, 65, - 87, 88, - 88, 66, - 68, 89, - 89, 90, - 90, 69, - 90, 91, - 91, 70, - 24, 2, - 24, 3, - 3, 2, - 30, 7, - 30, 8, - 8, 7, - 36, 12, - 36, 13, - 13, 12, - 42, 17, - 42, 18, - 18, 17, - 73, 49, - 73, 74, - 74, 49, - 78, 55, - 78, 79, - 79, 55, - 83, 61, - 83, 84, - 84, 61, - 88, 67, - 88, 89, - 89, 67 - }; +CASE( "test_build_edges" ) { + idx_t missing_value = -1; + Grid grid( "O2" ); + meshgenerator::StructuredMeshGenerator generator( + Config( "angle", 29.0 )( "triangulate", false )( "ghost_at_end", false ) ); + Mesh mesh = generator.generate( grid ); + + // Accumulate facets of cells ( edges in 2D ) + mesh::actions::build_edges( mesh ); + + idx_t edge_nodes_check[] = { + 0, 21, 21, 22, 22, 1, 1, 0, 22, 23, 23, 2, 2, 1, 3, 25, 25, 26, 26, 4, 4, 3, 26, 27, 27, 5, 5, + 4, 27, 28, 28, 6, 6, 5, 28, 29, 29, 7, 7, 6, 8, 31, 31, 32, 32, 9, 9, 8, 32, 33, 33, 10, 10, 9, + 33, 34, 34, 11, 11, 10, 34, 35, 35, 12, 12, 11, 13, 37, 37, 38, 38, 14, 14, 13, 38, 39, 39, 15, 15, 14, 39, + 40, 40, 16, 16, 15, 40, 41, 41, 17, 17, 16, 18, 43, 43, 44, 44, 19, 19, 18, 44, 45, 45, 20, 20, 19, 21, 46, + 46, 47, 47, 22, 47, 48, 48, 23, 48, 49, 49, 24, 24, 23, 49, 50, 50, 25, 25, 24, 50, 51, 51, 26, 51, 52, 52, + 27, 52, 53, 53, 28, 53, 54, 54, 29, 54, 55, 55, 30, 30, 29, 55, 56, 56, 31, 31, 30, 56, 57, 57, 32, 57, 58, + 58, 33, 58, 59, 59, 34, 59, 60, 60, 35, 60, 61, 61, 36, 36, 35, 61, 62, 62, 37, 37, 36, 62, 63, 63, 38, 63, + 64, 64, 39, 64, 65, 65, 40, 65, 66, 66, 41, 66, 67, 67, 42, 42, 41, 67, 68, 68, 43, 43, 42, 68, 69, 69, 44, + 69, 70, 70, 45, 46, 71, 71, 72, 72, 47, 72, 73, 73, 48, 50, 74, 74, 75, 75, 51, 75, 76, 76, 52, 76, 77, 77, + 53, 77, 78, 78, 54, 56, 79, 79, 80, 80, 57, 80, 81, 81, 58, 81, 82, 82, 59, 82, 83, 83, 60, 62, 84, 84, 85, + 85, 63, 85, 86, 86, 64, 86, 87, 87, 65, 87, 88, 88, 66, 68, 89, 89, 90, 90, 69, 90, 91, 91, 70, 24, 2, 24, + 3, 3, 2, 30, 7, 30, 8, 8, 7, 36, 12, 36, 13, 13, 12, 42, 17, 42, 18, 18, 17, 73, 49, 73, 74, 74, 49, + 78, 55, 78, 79, 79, 55, 83, 61, 83, 84, 84, 61, 88, 67, 88, 89, 89, 67}; - { - const mesh::HybridElements::Connectivity& edge_node_connectivity = mesh.edges().node_connectivity(); - EXPECT( mesh.projection().units() == "degrees" ); - const util::UniqueLonLat compute_uid( mesh ); - for( size_t jedge=0; jedge -#include #include -#include +#include +#include #include +#include -#include "atlas/library/config.h" +#include "atlas/grid/Grid.h" #include "atlas/library/Library.h" +#include "atlas/library/config.h" #include "atlas/mesh/Mesh.h" -#include "atlas/grid/Grid.h" #include "atlas/meshgenerator/DelaunayMeshGenerator.h" #include "atlas/output/Gmsh.h" @@ -31,17 +32,16 @@ using namespace atlas::output; #define NLATS 64 #define NLONG 128 -int main(int argc, char **argv) -{ - atlas::Library::instance().initialise(argc,argv); +int main( int argc, char** argv ) { + atlas::Library::instance().initialise( argc, argv ); Grid grid( "L33x11" ); // Build a mesh from grid DelaunayMeshGenerator generate; - Mesh mesh = generate(grid); + Mesh mesh = generate( grid ); - Gmsh gmsh("earth.msh", util::Config("coordinates","xyz") ); - gmsh.write(mesh); + Gmsh gmsh( "earth.msh", util::Config( "coordinates", "xyz" ) ); + gmsh.write( mesh ); atlas::Library::instance().finalise(); return 0; diff --git a/src/tests/mesh/test_connectivity.cc b/src/tests/mesh/test_connectivity.cc index 901211c91..27ee56118 100644 --- a/src/tests/mesh/test_connectivity.cc +++ b/src/tests/mesh/test_connectivity.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -34,206 +35,198 @@ namespace test { #define IN_FORTRAN #endif -CASE( "test_irregular_connectivity" ) -{ - IrregularConnectivity conn("mesh"); - EXPECT(conn.rows() == 0); - EXPECT(conn.maxcols() == 0); - - constexpr idx_t vals[4] = {2,3,5,6}; - conn.add(1, 4, vals, /* fortran-array = */ false); - - EXPECT(conn.rows() == 1); - EXPECT(conn.cols(0) == 4); - EXPECT(conn.mincols() == 4); - EXPECT(conn.maxcols() == 4); - - EXPECT(conn(0,0) == 2); - EXPECT(conn(0,1) == 3); - EXPECT(conn(0,2) == 5); - EXPECT(conn(0,3) == 6); - - EXPECT(conn.row(0)(0) == 2); - EXPECT(conn.row(0)(1) == 3); - EXPECT(conn.row(0)(2) == 5); - EXPECT(conn.row(0)(3) == 6); - - constexpr idx_t vals2[6] = {1,3,4,3,7,8}; - conn.add(2, 3, vals2, /* fortran-array = */ true); - - conn.dump(Log::info()); Log::info() << std::endl; - - EXPECT(conn.rows() == 3); - EXPECT(conn.cols(1) == 3); - EXPECT(conn.cols(2) == 3); - EXPECT(conn.mincols() == 3); - EXPECT(conn.maxcols() == 4); - - EXPECT(conn(1,0) == 1 IN_FORTRAN); - EXPECT(conn(1,1) == 3 IN_FORTRAN); - EXPECT(conn(1,2) == 4 IN_FORTRAN); - - EXPECT(conn.row(2)(0) == 3 IN_FORTRAN); - EXPECT(conn.row(2)(1) == 7 IN_FORTRAN); - EXPECT(conn.row(2)(2) == 8 IN_FORTRAN); - - conn.set(1,1,9 IN_FORTRAN); - EXPECT(conn(1,0) == 1 IN_FORTRAN); - EXPECT(conn(1,1) == 9 IN_FORTRAN); - EXPECT(conn(1,2) == 4 IN_FORTRAN); - - constexpr idx_t vals3[3] = {6 IN_FORTRAN,7 IN_FORTRAN,5 IN_FORTRAN}; - conn.set(2, vals3); - EXPECT(conn(2,0) == 6 IN_FORTRAN); - EXPECT(conn(2,1) == 7 IN_FORTRAN); - EXPECT(conn(2,2) == 5 IN_FORTRAN); - - constexpr idx_t vals4[8] = {2,11,51,12,4,13,55,78}; - - conn.insert(1, 2, 4, vals4, /* fortran-array = */ false); - EXPECT(conn.mincols() == 3); - EXPECT(conn.maxcols() == 4); - - EXPECT(conn.rows() == 5); - EXPECT(conn.cols(0) == 4); - EXPECT(conn.cols(1) == 4); - EXPECT(conn.cols(2) == 4); - EXPECT(conn.cols(3) == 3); - EXPECT(conn.cols(4) == 3); - - EXPECT(conn(1,0) == 2 ); - EXPECT(conn(1,1) == 11 ); - EXPECT(conn(1,2) == 51 ); - EXPECT(conn(1,3) == 12 ); - - EXPECT(conn(2,0) == 4 ); - EXPECT(conn(2,1) == 13 ); - EXPECT(conn(2,2) == 55 ); - EXPECT(conn(2,3) == 78 ); - - EXPECT(conn(3,0) == 1 IN_FORTRAN); - EXPECT(conn(3,1) == 9 IN_FORTRAN); - EXPECT(conn(3,2) == 4 IN_FORTRAN); - - - constexpr idx_t vals5[2] = {3,6}; - conn.insert(3, 1, 2, vals5, true); - - EXPECT(conn.mincols() == 2); - EXPECT(conn.maxcols() == 4); - - EXPECT(conn.rows() == 6); - EXPECT(conn.cols(3) == 2); - EXPECT(conn.cols(4) == 3); - - EXPECT(conn(3,0) == 3 IN_FORTRAN); - EXPECT(conn(3,1) == 6 IN_FORTRAN); - - EXPECT(conn(4,0) == 1 IN_FORTRAN); - EXPECT(conn(4,1) == 9 IN_FORTRAN); - EXPECT(conn(4,2) == 4 IN_FORTRAN); - - //insert 3 rows with 1 column - conn.insert(4, 3, 1); - - EXPECT(conn.rows() == 9); - EXPECT(conn.cols(4) == 1); - EXPECT(conn.cols(5) == 1); - EXPECT(conn.mincols() == 1); - EXPECT(conn.maxcols() == 4); - - EXPECT(conn(7,0) == 1 IN_FORTRAN); - EXPECT(conn(7,1) == 9 IN_FORTRAN); - EXPECT(conn(7,2) == 4 IN_FORTRAN); - - constexpr size_t cols[3] = {3,7,1}; - EXPECT(conn.cols(2) == 4); - //insert in position 2, 3 rows with cols[3] number of columns - conn.insert(2, 3, cols); - - EXPECT(conn.mincols() == 1); - EXPECT(conn.maxcols() == 7); - - EXPECT(conn.rows() == 12); - EXPECT(conn.cols(2) == 3); - EXPECT(conn.cols(3) == 7); - EXPECT(conn.cols(4) == 1); - EXPECT(conn.cols(5) == 4); - - EXPECT(conn(5,0) == 4 ); - EXPECT(conn(5,1) == 13 ); - EXPECT(conn(5,2) == 55 ); - EXPECT(conn(5,3) == 78 ); - +CASE( "test_irregular_connectivity" ) { + IrregularConnectivity conn( "mesh" ); + EXPECT( conn.rows() == 0 ); + EXPECT( conn.maxcols() == 0 ); + + constexpr idx_t vals[4] = {2, 3, 5, 6}; + conn.add( 1, 4, vals, /* fortran-array = */ false ); + + EXPECT( conn.rows() == 1 ); + EXPECT( conn.cols( 0 ) == 4 ); + EXPECT( conn.mincols() == 4 ); + EXPECT( conn.maxcols() == 4 ); + + EXPECT( conn( 0, 0 ) == 2 ); + EXPECT( conn( 0, 1 ) == 3 ); + EXPECT( conn( 0, 2 ) == 5 ); + EXPECT( conn( 0, 3 ) == 6 ); + + EXPECT( conn.row( 0 )( 0 ) == 2 ); + EXPECT( conn.row( 0 )( 1 ) == 3 ); + EXPECT( conn.row( 0 )( 2 ) == 5 ); + EXPECT( conn.row( 0 )( 3 ) == 6 ); + + constexpr idx_t vals2[6] = {1, 3, 4, 3, 7, 8}; + conn.add( 2, 3, vals2, /* fortran-array = */ true ); + + conn.dump( Log::info() ); + Log::info() << std::endl; + + EXPECT( conn.rows() == 3 ); + EXPECT( conn.cols( 1 ) == 3 ); + EXPECT( conn.cols( 2 ) == 3 ); + EXPECT( conn.mincols() == 3 ); + EXPECT( conn.maxcols() == 4 ); + + EXPECT( conn( 1, 0 ) == 1 IN_FORTRAN ); + EXPECT( conn( 1, 1 ) == 3 IN_FORTRAN ); + EXPECT( conn( 1, 2 ) == 4 IN_FORTRAN ); + + EXPECT( conn.row( 2 )( 0 ) == 3 IN_FORTRAN ); + EXPECT( conn.row( 2 )( 1 ) == 7 IN_FORTRAN ); + EXPECT( conn.row( 2 )( 2 ) == 8 IN_FORTRAN ); + + conn.set( 1, 1, 9 IN_FORTRAN ); + EXPECT( conn( 1, 0 ) == 1 IN_FORTRAN ); + EXPECT( conn( 1, 1 ) == 9 IN_FORTRAN ); + EXPECT( conn( 1, 2 ) == 4 IN_FORTRAN ); + + constexpr idx_t vals3[3] = {6 IN_FORTRAN, 7 IN_FORTRAN, 5 IN_FORTRAN}; + conn.set( 2, vals3 ); + EXPECT( conn( 2, 0 ) == 6 IN_FORTRAN ); + EXPECT( conn( 2, 1 ) == 7 IN_FORTRAN ); + EXPECT( conn( 2, 2 ) == 5 IN_FORTRAN ); + + constexpr idx_t vals4[8] = {2, 11, 51, 12, 4, 13, 55, 78}; + + conn.insert( 1, 2, 4, vals4, /* fortran-array = */ false ); + EXPECT( conn.mincols() == 3 ); + EXPECT( conn.maxcols() == 4 ); + + EXPECT( conn.rows() == 5 ); + EXPECT( conn.cols( 0 ) == 4 ); + EXPECT( conn.cols( 1 ) == 4 ); + EXPECT( conn.cols( 2 ) == 4 ); + EXPECT( conn.cols( 3 ) == 3 ); + EXPECT( conn.cols( 4 ) == 3 ); + + EXPECT( conn( 1, 0 ) == 2 ); + EXPECT( conn( 1, 1 ) == 11 ); + EXPECT( conn( 1, 2 ) == 51 ); + EXPECT( conn( 1, 3 ) == 12 ); + + EXPECT( conn( 2, 0 ) == 4 ); + EXPECT( conn( 2, 1 ) == 13 ); + EXPECT( conn( 2, 2 ) == 55 ); + EXPECT( conn( 2, 3 ) == 78 ); + + EXPECT( conn( 3, 0 ) == 1 IN_FORTRAN ); + EXPECT( conn( 3, 1 ) == 9 IN_FORTRAN ); + EXPECT( conn( 3, 2 ) == 4 IN_FORTRAN ); + + constexpr idx_t vals5[2] = {3, 6}; + conn.insert( 3, 1, 2, vals5, true ); + + EXPECT( conn.mincols() == 2 ); + EXPECT( conn.maxcols() == 4 ); + + EXPECT( conn.rows() == 6 ); + EXPECT( conn.cols( 3 ) == 2 ); + EXPECT( conn.cols( 4 ) == 3 ); + + EXPECT( conn( 3, 0 ) == 3 IN_FORTRAN ); + EXPECT( conn( 3, 1 ) == 6 IN_FORTRAN ); + + EXPECT( conn( 4, 0 ) == 1 IN_FORTRAN ); + EXPECT( conn( 4, 1 ) == 9 IN_FORTRAN ); + EXPECT( conn( 4, 2 ) == 4 IN_FORTRAN ); + + // insert 3 rows with 1 column + conn.insert( 4, 3, 1 ); + + EXPECT( conn.rows() == 9 ); + EXPECT( conn.cols( 4 ) == 1 ); + EXPECT( conn.cols( 5 ) == 1 ); + EXPECT( conn.mincols() == 1 ); + EXPECT( conn.maxcols() == 4 ); + + EXPECT( conn( 7, 0 ) == 1 IN_FORTRAN ); + EXPECT( conn( 7, 1 ) == 9 IN_FORTRAN ); + EXPECT( conn( 7, 2 ) == 4 IN_FORTRAN ); + + constexpr size_t cols[3] = {3, 7, 1}; + EXPECT( conn.cols( 2 ) == 4 ); + // insert in position 2, 3 rows with cols[3] number of columns + conn.insert( 2, 3, cols ); + + EXPECT( conn.mincols() == 1 ); + EXPECT( conn.maxcols() == 7 ); + + EXPECT( conn.rows() == 12 ); + EXPECT( conn.cols( 2 ) == 3 ); + EXPECT( conn.cols( 3 ) == 7 ); + EXPECT( conn.cols( 4 ) == 1 ); + EXPECT( conn.cols( 5 ) == 4 ); + + EXPECT( conn( 5, 0 ) == 4 ); + EXPECT( conn( 5, 1 ) == 13 ); + EXPECT( conn( 5, 2 ) == 55 ); + EXPECT( conn( 5, 3 ) == 78 ); } - CASE( "test_irregular_insert" ) -{ - IrregularConnectivity conn("mesh"); - EXPECT(conn.rows() == 0); - EXPECT(conn.maxcols() == 0); - - constexpr idx_t vals[4] = {2,3,5,6}; - conn.insert(0, 1, 4, vals, false); +CASE( "test_irregular_insert" ) { + IrregularConnectivity conn( "mesh" ); + EXPECT( conn.rows() == 0 ); + EXPECT( conn.maxcols() == 0 ); - EXPECT(conn.rows() == 1); - EXPECT(conn.cols(0) == 4); - EXPECT(conn.mincols() == 4); - EXPECT(conn.maxcols() == 4); + constexpr idx_t vals[4] = {2, 3, 5, 6}; + conn.insert( 0, 1, 4, vals, false ); - EXPECT(conn(0,0) == 2 ); - EXPECT(conn(0,1) == 3 ); - EXPECT(conn(0,2) == 5 ); - EXPECT(conn(0,3) == 6 ); + EXPECT( conn.rows() == 1 ); + EXPECT( conn.cols( 0 ) == 4 ); + EXPECT( conn.mincols() == 4 ); + EXPECT( conn.maxcols() == 4 ); - EXPECT(conn.row(0)(0) == 2); - EXPECT(conn.row(0)(1) == 3); - EXPECT(conn.row(0)(2) == 5); - EXPECT(conn.row(0)(3) == 6); + EXPECT( conn( 0, 0 ) == 2 ); + EXPECT( conn( 0, 1 ) == 3 ); + EXPECT( conn( 0, 2 ) == 5 ); + EXPECT( conn( 0, 3 ) == 6 ); + EXPECT( conn.row( 0 )( 0 ) == 2 ); + EXPECT( conn.row( 0 )( 1 ) == 3 ); + EXPECT( conn.row( 0 )( 2 ) == 5 ); + EXPECT( conn.row( 0 )( 3 ) == 6 ); } - CASE( "test_block_connectivity" ) -{ - idx_t vals[15] = {3,7,1,4,5,6,4,56,8,4,1,3,76,4,3}; - BlockConnectivity conn(3,5, vals); - EXPECT(conn.rows() == 3); - EXPECT(conn.cols() == 5); +CASE( "test_block_connectivity" ) { + idx_t vals[15] = {3, 7, 1, 4, 5, 6, 4, 56, 8, 4, 1, 3, 76, 4, 3}; + BlockConnectivity conn( 3, 5, vals ); + EXPECT( conn.rows() == 3 ); + EXPECT( conn.cols() == 5 ); - EXPECT(conn(0,2) == 1 ); - EXPECT(conn(1,1) == 4 ); - EXPECT(conn(2,2) == 76 ); + EXPECT( conn( 0, 2 ) == 1 ); + EXPECT( conn( 1, 1 ) == 4 ); + EXPECT( conn( 2, 2 ) == 76 ); } - CASE( "test_block_connectivity_add" ) { +CASE( "test_block_connectivity_add" ) { BlockConnectivity conn; - idx_t vals2[10] = {2,3,9,34,356,86,3,24,84,45}; - - conn.add(2,5, vals2); - EXPECT(conn.rows() == 2); - EXPECT(conn.cols() == 5); + idx_t vals2[10] = {2, 3, 9, 34, 356, 86, 3, 24, 84, 45}; - EXPECT(conn(0,2) == 9 ); - EXPECT(conn(0,4) == 356 ); - EXPECT(conn(1,1) == 3 ); + conn.add( 2, 5, vals2 ); + EXPECT( conn.rows() == 2 ); + EXPECT( conn.cols() == 5 ); + EXPECT( conn( 0, 2 ) == 9 ); + EXPECT( conn( 0, 4 ) == 356 ); + EXPECT( conn( 1, 1 ) == 3 ); } - CASE( "test_block_connectivity_empty_add" ) -{ +CASE( "test_block_connectivity_empty_add" ) { BlockConnectivity conn; - EXPECT(conn.rows() == 0); - EXPECT(conn.cols() == 0); + EXPECT( conn.rows() == 0 ); + EXPECT( conn.cols() == 0 ); - idx_t vals2[12] = {2,3,9,34,356,86,3,24,84,45,2,2}; + idx_t vals2[12] = {2, 3, 9, 34, 356, 86, 3, 24, 84, 45, 2, 2}; - conn.add(2,5, vals2); - EXPECT(conn.rows() == 2); - EXPECT(conn.cols() == 5); - - EXPECT(conn(0,2) == 9 ); - EXPECT(conn(0,4) == 356 ); - EXPECT(conn(1,1) == 3 ); + conn.add( 2, 5, vals2 ); + EXPECT( conn.rows() == 2 ); + EXPECT( conn.cols() == 5 ); + EXPECT( conn( 0, 2 ) == 9 ); + EXPECT( conn( 0, 4 ) == 356 ); + EXPECT( conn( 1, 1 ) == 3 ); } #if 0 @@ -267,294 +260,262 @@ CASE("test_multi_block_connectivity_default") { } #endif -CASE("test_multi_block_connectivity_add") { - MultiBlockConnectivity mbc("mbc"); - idx_t vals[6] = {1, 3, 4, - 2, 3, 4}; +CASE( "test_multi_block_connectivity_add" ) { + MultiBlockConnectivity mbc( "mbc" ); + idx_t vals[6] = {1, 3, 4, 2, 3, 4}; - mbc.add(2, 3, vals, false); - EXPECT(mbc(0, 2) == 4 ); - EXPECT(mbc(1, 1) == 3 ); + mbc.add( 2, 3, vals, false ); + EXPECT( mbc( 0, 2 ) == 4 ); + EXPECT( mbc( 1, 1 ) == 3 ); - EXPECT(mbc(0, 1, 2) == 4 ); + EXPECT( mbc( 0, 1, 2 ) == 4 ); - idx_t vals2[12]{4, 5, 6, 7, - 23, 54, 6, 9, - 11, 12, 13, 14}; - mbc.add(3, 4, vals2, false); + idx_t vals2[12]{4, 5, 6, 7, 23, 54, 6, 9, 11, 12, 13, 14}; + mbc.add( 3, 4, vals2, false ); - EXPECT(mbc(2, 2) == 6 ); - EXPECT(mbc(3, 3) == 9 ); - EXPECT(mbc(4, 0) == 11 ); + EXPECT( mbc( 2, 2 ) == 6 ); + EXPECT( mbc( 3, 3 ) == 9 ); + EXPECT( mbc( 4, 0 ) == 11 ); - idx_t vals3[4]{ 17, 18, - 21, 24}; - mbc.add(2, 2, vals3, false); + idx_t vals3[4]{17, 18, 21, 24}; + mbc.add( 2, 2, vals3, false ); - EXPECT(mbc(5, 0) == 17 ); - EXPECT(mbc(6, 1) == 24 ); - - EXPECT(mbc(0, 1, 2) == 4 ); - EXPECT(mbc(1, 1, 0) == 23 ); - EXPECT(mbc(2, 1, 1) == 24 ); + EXPECT( mbc( 5, 0 ) == 17 ); + EXPECT( mbc( 6, 1 ) == 24 ); + EXPECT( mbc( 0, 1, 2 ) == 4 ); + EXPECT( mbc( 1, 1, 0 ) == 23 ); + EXPECT( mbc( 2, 1, 1 ) == 24 ); } -CASE("test_multi_block_connectivity_add_block") { - -Log::info() << "\n\n\ntest_multi_block_connectivity_add_block\n" << std::endl; - - MultiBlockConnectivity mbc("mbc"); - - - EXPECT( mbc.blocks() == 0 ); - - { - BlockConnectivity conn1( 3,5, { - 3,7, 1,4,5, - 6,4,56,8,4, - 1,3,76,4,3 } ); - EXPECT( conn1.owns() ); - - EXPECT(conn1(0,2) == 1 ); - EXPECT(conn1(1,1) == 4 ); - EXPECT(conn1(2,2) == 76 ); - - mbc.add(conn1); - } - EXPECT( mbc.blocks() == 1 ); - - EXPECT(mbc(0,2) == 1 ); - EXPECT(mbc(1,1) == 4 ); - EXPECT(mbc(2,2) == 76 ); - - EXPECT(mbc(0, 0,2) == 1 ); - EXPECT(mbc(0, 1,1) == 4 ); - EXPECT(mbc(0, 2,2) == 76 ); - - { - BlockConnectivity conn2(3,2, { - 31,71, - 61,41, - 11,31 }); - EXPECT( conn2.owns() ); - EXPECT(conn2(0,0) == 31); - EXPECT(conn2(1,1) == 41); - EXPECT(conn2(2,0) == 11); - - mbc.add(conn2); - } - EXPECT( mbc.blocks() == 2 ); - - EXPECT(mbc(0,2) == 1 ); - EXPECT(mbc(1,1) == 4 ); - EXPECT(mbc(2,2) == 76 ); - EXPECT(mbc(3,0) == 31 ); - EXPECT(mbc(4,1) == 41 ); - EXPECT(mbc(5,0) == 11 ); - - EXPECT(mbc(0, 0,2) == 1 ); - EXPECT(mbc(0, 1,1) == 4 ); - EXPECT(mbc(0, 2,2) == 76 ); - EXPECT(mbc(1, 0,0) == 31 ); - EXPECT(mbc(1, 1,1) == 41 ); - EXPECT(mbc(1, 2,0) == 11 ); - - const BlockConnectivity& b0 = mbc.block(0); - EXPECT( b0.owns() == false ); - EXPECT(b0(0,2) == 1 ); - EXPECT(b0(1,1) == 4 ); - EXPECT(b0(2,2) == 76 ); - - const BlockConnectivity& b1 = mbc.block(1); - EXPECT( b1.owns() == false ); - EXPECT(b1(0,0) == 31 ); - EXPECT(b1(1,1) == 41 ); - EXPECT(b1(2,0) == 11 ); - - MultiBlockConnectivity& ic = mbc; - EXPECT(ic(0,2) == 1 ); - EXPECT(ic(1,1) == 4 ); - EXPECT(ic(2,2) == 76 ); - EXPECT(ic(3,0) == 31 ); - EXPECT(ic(4,1) == 41 ); - EXPECT(ic(5,0) == 11 ); - - ic.set(5,0,12); - EXPECT(b1(2,0) == 12); +CASE( "test_multi_block_connectivity_add_block" ) { + Log::info() << "\n\n\ntest_multi_block_connectivity_add_block\n" << std::endl; + + MultiBlockConnectivity mbc( "mbc" ); + + EXPECT( mbc.blocks() == 0 ); + + { + BlockConnectivity conn1( 3, 5, {3, 7, 1, 4, 5, 6, 4, 56, 8, 4, 1, 3, 76, 4, 3} ); + EXPECT( conn1.owns() ); + + EXPECT( conn1( 0, 2 ) == 1 ); + EXPECT( conn1( 1, 1 ) == 4 ); + EXPECT( conn1( 2, 2 ) == 76 ); + + mbc.add( conn1 ); + } + EXPECT( mbc.blocks() == 1 ); + + EXPECT( mbc( 0, 2 ) == 1 ); + EXPECT( mbc( 1, 1 ) == 4 ); + EXPECT( mbc( 2, 2 ) == 76 ); + + EXPECT( mbc( 0, 0, 2 ) == 1 ); + EXPECT( mbc( 0, 1, 1 ) == 4 ); + EXPECT( mbc( 0, 2, 2 ) == 76 ); + + { + BlockConnectivity conn2( 3, 2, {31, 71, 61, 41, 11, 31} ); + EXPECT( conn2.owns() ); + EXPECT( conn2( 0, 0 ) == 31 ); + EXPECT( conn2( 1, 1 ) == 41 ); + EXPECT( conn2( 2, 0 ) == 11 ); + + mbc.add( conn2 ); + } + EXPECT( mbc.blocks() == 2 ); + + EXPECT( mbc( 0, 2 ) == 1 ); + EXPECT( mbc( 1, 1 ) == 4 ); + EXPECT( mbc( 2, 2 ) == 76 ); + EXPECT( mbc( 3, 0 ) == 31 ); + EXPECT( mbc( 4, 1 ) == 41 ); + EXPECT( mbc( 5, 0 ) == 11 ); + + EXPECT( mbc( 0, 0, 2 ) == 1 ); + EXPECT( mbc( 0, 1, 1 ) == 4 ); + EXPECT( mbc( 0, 2, 2 ) == 76 ); + EXPECT( mbc( 1, 0, 0 ) == 31 ); + EXPECT( mbc( 1, 1, 1 ) == 41 ); + EXPECT( mbc( 1, 2, 0 ) == 11 ); + + const BlockConnectivity& b0 = mbc.block( 0 ); + EXPECT( b0.owns() == false ); + EXPECT( b0( 0, 2 ) == 1 ); + EXPECT( b0( 1, 1 ) == 4 ); + EXPECT( b0( 2, 2 ) == 76 ); + + const BlockConnectivity& b1 = mbc.block( 1 ); + EXPECT( b1.owns() == false ); + EXPECT( b1( 0, 0 ) == 31 ); + EXPECT( b1( 1, 1 ) == 41 ); + EXPECT( b1( 2, 0 ) == 11 ); + + MultiBlockConnectivity& ic = mbc; + EXPECT( ic( 0, 2 ) == 1 ); + EXPECT( ic( 1, 1 ) == 4 ); + EXPECT( ic( 2, 2 ) == 76 ); + EXPECT( ic( 3, 0 ) == 31 ); + EXPECT( ic( 4, 1 ) == 41 ); + EXPECT( ic( 5, 0 ) == 11 ); + + ic.set( 5, 0, 12 ); + EXPECT( b1( 2, 0 ) == 12 ); } -CASE("test_multi_block_connectivity_add_block_em") { - MultiBlockConnectivity mbc("mbc"); - EXPECT( mbc.blocks() == 0 ); - - { - idx_t vals[15]{ - 3,7,1,4,5, - 6,4,56,8,4, - 1,3,76,4,3}; +CASE( "test_multi_block_connectivity_add_block_em" ) { + MultiBlockConnectivity mbc( "mbc" ); + EXPECT( mbc.blocks() == 0 ); - BlockConnectivity conn(3,5, vals); + { + idx_t vals[15]{3, 7, 1, 4, 5, 6, 4, 56, 8, 4, 1, 3, 76, 4, 3}; - mbc.add(conn); - } - EXPECT( mbc.blocks() == 1 ); + BlockConnectivity conn( 3, 5, vals ); - EXPECT(mbc(0,2) == 1 ); - EXPECT(mbc(1,1) == 4 ); - EXPECT(mbc(2,2) == 76 ); + mbc.add( conn ); + } + EXPECT( mbc.blocks() == 1 ); - EXPECT(mbc(0, 0,2) == 1 ); - EXPECT(mbc(0, 1,1) == 4 ); - EXPECT(mbc(0, 2,2) == 76 ); + EXPECT( mbc( 0, 2 ) == 1 ); + EXPECT( mbc( 1, 1 ) == 4 ); + EXPECT( mbc( 2, 2 ) == 76 ); - { - idx_t vals5[6]{ - 4,75, - 65,45, - 51,35}; + EXPECT( mbc( 0, 0, 2 ) == 1 ); + EXPECT( mbc( 0, 1, 1 ) == 4 ); + EXPECT( mbc( 0, 2, 2 ) == 76 ); - BlockConnectivity conn2(3,2, vals5); + { + idx_t vals5[6]{4, 75, 65, 45, 51, 35}; - mbc.add(conn2); - } - EXPECT( mbc.blocks() == 2 ); + BlockConnectivity conn2( 3, 2, vals5 ); + mbc.add( conn2 ); + } + EXPECT( mbc.blocks() == 2 ); - EXPECT(mbc(3,1) == 75 ); - EXPECT(mbc(4,1) == 45 ); - EXPECT(mbc(5,0) == 51 ); + EXPECT( mbc( 3, 1 ) == 75 ); + EXPECT( mbc( 4, 1 ) == 45 ); + EXPECT( mbc( 5, 0 ) == 51 ); - EXPECT(mbc(1, 0,1) == 75 ); - EXPECT(mbc(1, 1,1) == 45 ); - EXPECT(mbc(1, 2,0) == 51 ); + EXPECT( mbc( 1, 0, 1 ) == 75 ); + EXPECT( mbc( 1, 1, 1 ) == 45 ); + EXPECT( mbc( 1, 2, 0 ) == 51 ); } -CASE("test_multi_block_connectivity_insert") { - MultiBlockConnectivity mbc("mbc"); - EXPECT( mbc.blocks() == 0 ); - - mbc.add( BlockConnectivity(3,5,{ - 3,7,1,4,5, - 6,4,56,8,4, - 1,3,76,4,3} ) ); - - EXPECT(mbc(0,2) == 1 ); - EXPECT(mbc(1,1) == 4 ); - EXPECT(mbc(2,2) == 76 ); - - EXPECT(mbc(0, 0,2) == 1 ); - EXPECT(mbc(0, 1,1) == 4 ); - EXPECT(mbc(0, 2,2) == 76 ); - - EXPECT( mbc.block(0).rows() == 3 ); - - { - idx_t vals[10]{ - 31,71,61,41,42, - 11,31,33,54,56}; +CASE( "test_multi_block_connectivity_insert" ) { + MultiBlockConnectivity mbc( "mbc" ); + EXPECT( mbc.blocks() == 0 ); - mbc.insert(0, 2,5, vals); - } + mbc.add( BlockConnectivity( 3, 5, {3, 7, 1, 4, 5, 6, 4, 56, 8, 4, 1, 3, 76, 4, 3} ) ); - /* - idx_t check[] = { - 31,71,61,41,42, - 11,31,33,54,56, - 3,7,1,4,5, - 6,4,56,8,4, - 1,3,76,4,3 - }; - */ + EXPECT( mbc( 0, 2 ) == 1 ); + EXPECT( mbc( 1, 1 ) == 4 ); + EXPECT( mbc( 2, 2 ) == 76 ); - EXPECT( mbc.block(0).rows() == 5 ); + EXPECT( mbc( 0, 0, 2 ) == 1 ); + EXPECT( mbc( 0, 1, 1 ) == 4 ); + EXPECT( mbc( 0, 2, 2 ) == 76 ); - EXPECT(mbc(0,2) == 61 ); - EXPECT(mbc(1,1) == 31 ); + EXPECT( mbc.block( 0 ).rows() == 3 ); - EXPECT(mbc(2,2) == 1 ); - EXPECT(mbc(3,1) == 4 ); - EXPECT(mbc(4,2) == 76 ); + { + idx_t vals[10]{31, 71, 61, 41, 42, 11, 31, 33, 54, 56}; - EXPECT(mbc(0, 2,2) == 1 ); - EXPECT(mbc(0, 3,1) == 4 ); - EXPECT(mbc(0, 4,2) == 76 ); + mbc.insert( 0, 2, 5, vals ); + } - mbc.add(BlockConnectivity(3,2,{ - 4,75, - 65,45, - 51,35})); - - /* - idx_t check[] = { + /* + idx_t check[] = { 31,71,61,41,42, 11,31,33,54,56, 3,7,1,4,5, 6,4,56,8,4, - 1,3,76,4,3, - 4,75, - 65,45, - 51,35}; - */ - - EXPECT( mbc.block(0).rows() == 5 ); - EXPECT( mbc.block(1).rows() == 3 ); - - EXPECT(mbc(0, 2,2) == 1 ); - EXPECT(mbc(0, 3,1) == 4 ); - EXPECT(mbc(0, 4,2) == 76 ); - - EXPECT(mbc(5,1) == 75 ); - EXPECT(mbc(7,0) == 51 ); - - EXPECT(mbc(1, 0,1) == 75 ); - EXPECT(mbc(1, 2,0) == 51 ); - - { - idx_t vals[10]{ - 19,72,62,42,43, - 12,32,34,55,57}; - - mbc.insert(5, 2,5, vals); - } - - EXPECT(mbc.rows() == 10); - EXPECT(mbc.block(0).rows() == 7); - EXPECT(mbc.block(1).rows() == 3); - EXPECT(mbc.blocks() == 2); - - /* - idx_t check[] = { - 31,71,61,41,42, - 11,31,33,54,56, - 3,7,1,4,5, - 6,4,56,8,4, - 1,3,76,4,3, - 19,72,62,42,43, // inserted - 12,32,34,55,57, // inserted - - 4,75, - 65,45, - 51,35}; - */ - - EXPECT( mbc.block(0)(0,0) == 31); - EXPECT( mbc(0, 0,0) == 31); - EXPECT( mbc(0,0) == 31); - EXPECT( mbc.block(0)(5,0) == 19); - EXPECT( mbc(0, 5,0) == 19); - EXPECT( mbc(5,0) == 19); - EXPECT( mbc.block(1)(0,0) == 4); - EXPECT( mbc(1, 0,0) == 4); - EXPECT( mbc(7,0) == 4); - - { - idx_t vals[] = { - 67, 38, 89, - 2, 5, 7}; - - EXPECT_THROWS_AS( mbc.insert(2, 2,3, vals), eckit::AssertionFailed ); - } + 1,3,76,4,3 + }; +*/ + + EXPECT( mbc.block( 0 ).rows() == 5 ); + + EXPECT( mbc( 0, 2 ) == 61 ); + EXPECT( mbc( 1, 1 ) == 31 ); + + EXPECT( mbc( 2, 2 ) == 1 ); + EXPECT( mbc( 3, 1 ) == 4 ); + EXPECT( mbc( 4, 2 ) == 76 ); + + EXPECT( mbc( 0, 2, 2 ) == 1 ); + EXPECT( mbc( 0, 3, 1 ) == 4 ); + EXPECT( mbc( 0, 4, 2 ) == 76 ); + + mbc.add( BlockConnectivity( 3, 2, {4, 75, 65, 45, 51, 35} ) ); + + /* + idx_t check[] = { + 31,71,61,41,42, + 11,31,33,54,56, + 3,7,1,4,5, + 6,4,56,8,4, + 1,3,76,4,3, + 4,75, + 65,45, + 51,35}; +*/ + + EXPECT( mbc.block( 0 ).rows() == 5 ); + EXPECT( mbc.block( 1 ).rows() == 3 ); + + EXPECT( mbc( 0, 2, 2 ) == 1 ); + EXPECT( mbc( 0, 3, 1 ) == 4 ); + EXPECT( mbc( 0, 4, 2 ) == 76 ); + + EXPECT( mbc( 5, 1 ) == 75 ); + EXPECT( mbc( 7, 0 ) == 51 ); + + EXPECT( mbc( 1, 0, 1 ) == 75 ); + EXPECT( mbc( 1, 2, 0 ) == 51 ); + + { + idx_t vals[10]{19, 72, 62, 42, 43, 12, 32, 34, 55, 57}; + + mbc.insert( 5, 2, 5, vals ); + } + + EXPECT( mbc.rows() == 10 ); + EXPECT( mbc.block( 0 ).rows() == 7 ); + EXPECT( mbc.block( 1 ).rows() == 3 ); + EXPECT( mbc.blocks() == 2 ); + + /* + idx_t check[] = { + 31,71,61,41,42, + 11,31,33,54,56, + 3,7,1,4,5, + 6,4,56,8,4, + 1,3,76,4,3, + 19,72,62,42,43, // inserted + 12,32,34,55,57, // inserted + + 4,75, + 65,45, + 51,35}; +*/ + + EXPECT( mbc.block( 0 )( 0, 0 ) == 31 ); + EXPECT( mbc( 0, 0, 0 ) == 31 ); + EXPECT( mbc( 0, 0 ) == 31 ); + EXPECT( mbc.block( 0 )( 5, 0 ) == 19 ); + EXPECT( mbc( 0, 5, 0 ) == 19 ); + EXPECT( mbc( 5, 0 ) == 19 ); + EXPECT( mbc.block( 1 )( 0, 0 ) == 4 ); + EXPECT( mbc( 1, 0, 0 ) == 4 ); + EXPECT( mbc( 7, 0 ) == 4 ); + + { + idx_t vals[] = {67, 38, 89, 2, 5, 7}; + + EXPECT_THROWS_AS( mbc.insert( 2, 2, 3, vals ), eckit::AssertionFailed ); + } } //----------------------------------------------------------------------------- @@ -562,7 +523,6 @@ CASE("test_multi_block_connectivity_insert") { } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_distmesh.cc b/src/tests/mesh/test_distmesh.cc index 90a632478..b9971c073 100644 --- a/src/tests/mesh/test_distmesh.cc +++ b/src/tests/mesh/test_distmesh.cc @@ -4,32 +4,33 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include +#include -#include "atlas/parallel/mpi/mpi.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/MakeView.h" +#include "atlas/grid/Grid.h" #include "atlas/library/Library.h" -#include "tests/TestMeshes.h" +#include "atlas/mesh/IsGhostNode.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/grid/Grid.h" -#include "atlas/output/Gmsh.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/MakeView.h" +#include "atlas/mesh/actions/BuildDualMesh.h" +#include "atlas/mesh/actions/BuildEdges.h" #include "atlas/mesh/actions/BuildHalo.h" #include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildPeriodicBoundaries.h" -#include "atlas/mesh/actions/BuildEdges.h" -#include "atlas/mesh/actions/BuildDualMesh.h" #include "atlas/mesh/actions/WriteLoadBalanceReport.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/mesh/IsGhostNode.h" +#include "atlas/output/Gmsh.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" +#include "atlas/util/CoordinateEnums.h" #include "eckit/types/FloatCompare.h" +#include "tests/TestMeshes.h" #include "tests/AtlasTestEnvironment.h" @@ -43,110 +44,90 @@ namespace test { //----------------------------------------------------------------------------- +double dual_volume( Mesh& mesh ) { + mesh::Nodes& nodes = mesh.nodes(); + mesh::IsGhostNode is_ghost_node( nodes ); + int nb_nodes = nodes.size(); + array::ArrayView dual_volumes = array::make_view( nodes.field( "dual_volumes" ) ); + double area = 0; -double dual_volume(Mesh& mesh) -{ - mesh::Nodes& nodes = mesh.nodes(); - mesh::IsGhostNode is_ghost_node(nodes); - int nb_nodes = nodes.size(); - array::ArrayView dual_volumes = array::make_view( nodes.field("dual_volumes") ); - double area=0; - - for( int node=0; node 1e-8 ) { std::cout << "difference = " << difference << std::endl; } - mesh::actions::build_parallel_fields(m); - mesh::actions::build_periodic_boundaries(m); - mesh::actions::build_halo(m,1); - //mesh::actions::renumber_nodes_glb_idx(m.nodes()); - mesh::actions::build_edges(m); - mesh::actions::build_pole_edges(m); - mesh::actions::build_edges_parallel_fields(m); - mesh::actions::build_median_dual_mesh(m); + Gmsh( "dist.msh" ).write( m ); - 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; - } + mesh::actions::write_load_balance_report( m, "load_balance.dat" ); - Gmsh("dist.msh").write(m); + Mesh& mesh1 = m; + EXPECT( mesh1.nodes().size() == m.nodes().size() ); - mesh::actions::write_load_balance_report(m,"load_balance.dat"); + const array::ArrayView part = array::make_view( m.nodes().partition() ); + const array::ArrayView ghost = array::make_view( m.nodes().ghost() ); + const array::ArrayView flags = array::make_view( m.nodes().field( "flags" ) ); - Mesh& mesh1 = m; - EXPECT( mesh1.nodes().size() == m.nodes().size() ); - - const array::ArrayView part = array::make_view( m.nodes().partition() ); - const array::ArrayView ghost = array::make_view( m.nodes().ghost() ); - const array::ArrayView flags = array::make_view( m.nodes().field("flags") ); - - Log::info() << "partition = [ "; - for( size_t jnode=0; jnode -#include #include +#include #include "atlas/library/config.h" -#include "eckit/memory/ScopedPtr.h" #include "eckit/exception/Exceptions.h" +#include "eckit/memory/ScopedPtr.h" +#include "atlas/field/Field.h" #include "atlas/library/Library.h" -#include "atlas/runtime/Log.h" +#include "atlas/mesh/Connectivity.h" #include "atlas/mesh/ElementType.h" #include "atlas/mesh/Elements.h" #include "atlas/mesh/Nodes.h" -#include "atlas/field/Field.h" -#include "atlas/mesh/Connectivity.h" +#include "atlas/runtime/Log.h" +#include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" -#include "atlas/grid/Grid.h" #include "tests/AtlasTestEnvironment.h" @@ -39,430 +40,375 @@ namespace test { // ------------------------------------------------------------------ -CASE( "hybrid_elements" ) -{ - HybridElements hybrid_elements; +CASE( "hybrid_elements" ) { + HybridElements hybrid_elements; - idx_t triangle_nodes[] = { - 1,5,3, - 1,5,2 - }; + idx_t triangle_nodes[] = {1, 5, 3, 1, 5, 2}; - size_t triags_type_idx = hybrid_elements.add( new Triangle(), 2, triangle_nodes ); + size_t triags_type_idx = hybrid_elements.add( new Triangle(), 2, triangle_nodes ); - EXPECT( triags_type_idx == 0 ); + EXPECT( triags_type_idx == 0 ); - hybrid_elements.add(Field("surface",array::make_datatype(),array::make_shape(hybrid_elements.size()))); + hybrid_elements.add( + Field( "surface", array::make_datatype(), array::make_shape( hybrid_elements.size() ) ) ); - std::vector quad_nodes(4); - quad_nodes[0] = 0; - quad_nodes[1] = 1; - quad_nodes[2] = 2; - quad_nodes[3] = 3; + std::vector quad_nodes( 4 ); + quad_nodes[0] = 0; + quad_nodes[1] = 1; + quad_nodes[2] = 2; + quad_nodes[3] = 3; - size_t quads_type_idx = hybrid_elements.add( new Quadrilateral(), 1, quad_nodes ); + size_t quads_type_idx = hybrid_elements.add( new Quadrilateral(), 1, quad_nodes ); - EXPECT( quads_type_idx == 1 ); + EXPECT( quads_type_idx == 1 ); - { - const HybridElements::Connectivity& connectivity = hybrid_elements.node_connectivity(); - for( size_t e=0; e(block_connectivity).set(0,quad0); - //elements.set_node_connectivity(0,quad0); - - if( t==0 ) { - EXPECT( block_connectivity(0,0) == 9 ); - EXPECT( block_connectivity(0,1) == 8 ); - EXPECT( block_connectivity(0,2) == 7 ); - EXPECT( block_connectivity(1,0) == 1 ); - EXPECT( block_connectivity(1,1) == 5 ); - EXPECT( block_connectivity(1,2) == 2 ); - } - if( t==1 ) { - EXPECT( block_connectivity(0,0) == 9 ); - EXPECT( block_connectivity(0,1) == 8 ); - EXPECT( block_connectivity(0,2) == 7 ); - EXPECT( block_connectivity(0,3) == 6 ); - } - - eckit::Log::info() << "name = " << elements.name() << std::endl; - eckit::Log::info() << "nb_elements = " << elements.size() << std::endl; - const BlockConnectivity& connectivity = elements.node_connectivity(); - for( size_t e=0; e(block_connectivity).set(0,quad0); + // elements.set_node_connectivity(0,quad0); + + if ( t == 0 ) { + EXPECT( block_connectivity( 0, 0 ) == 9 ); + EXPECT( block_connectivity( 0, 1 ) == 8 ); + EXPECT( block_connectivity( 0, 2 ) == 7 ); + EXPECT( block_connectivity( 1, 0 ) == 1 ); + EXPECT( block_connectivity( 1, 1 ) == 5 ); + EXPECT( block_connectivity( 1, 2 ) == 2 ); + } + if ( t == 1 ) { + EXPECT( block_connectivity( 0, 0 ) == 9 ); + EXPECT( block_connectivity( 0, 1 ) == 8 ); + EXPECT( block_connectivity( 0, 2 ) == 7 ); + EXPECT( block_connectivity( 0, 3 ) == 6 ); + } + + eckit::Log::info() << "name = " << elements.name() << std::endl; + eckit::Log::info() << "nb_elements = " << elements.size() << std::endl; + const BlockConnectivity& connectivity = elements.node_connectivity(); + for ( size_t e = 0; e < elements.size(); ++e ) { + eckit::Log::info() << " nodes = [ "; + for ( size_t n = 0; n < elements.nb_nodes(); ++n ) { + eckit::Log::info() << connectivity( e, n ) << " "; + } + eckit::Log::info() << "]" << std::endl; + } } - eckit::Log::info() << "]" << std::endl; - } } - } + + size_t nb_elements = 3; + EXPECT( hybrid_elements.size() == nb_elements ); + EXPECT( hybrid_elements.global_index().size() == nb_elements ); + EXPECT( hybrid_elements.partition().size() == nb_elements ); + EXPECT( hybrid_elements.remote_index().size() == nb_elements ); + EXPECT( hybrid_elements.field( "surface" ).size() == nb_elements ); + EXPECT( hybrid_elements.elements( 0 ).begin() == 0 ); + EXPECT( hybrid_elements.elements( 0 ).end() == 2 ); + EXPECT( hybrid_elements.elements( 1 ).begin() == 2 ); + EXPECT( hybrid_elements.elements( 1 ).end() == 3 ); + // EXPECT( hybrid_elements.elements(0).type_idx() == 0 ); + // EXPECT( hybrid_elements.elements(1).type_idx() == 1 ); } -CASE( "hybrid_connectivity" ) -{ - eckit::Log::info() << "\nhybrid_connectivity" << std::endl; - - idx_t triangle_nodes[] = { - 1,5,3, - 1,5,2 - }; - MultiBlockConnectivity hybrid_connectivity; - hybrid_connectivity.add(2,3,triangle_nodes); - for( size_t e=0; e #include #include +#include -#include "atlas/parallel/mpi/mpi.h" +#include "atlas/array.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/IndexView.h" #include "atlas/library/config.h" -#include "tests/TestMeshes.h" -#include "atlas/output/Gmsh.h" +#include "atlas/mesh/IsGhostNode.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/array/IndexView.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array.h" +#include "atlas/mesh/actions/BuildDualMesh.h" +#include "atlas/mesh/actions/BuildEdges.h" #include "atlas/mesh/actions/BuildHalo.h" #include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/actions/BuildPeriodicBoundaries.h" -#include "atlas/mesh/actions/BuildEdges.h" -#include "atlas/mesh/actions/BuildDualMesh.h" +#include "atlas/output/Gmsh.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/MicroDeg.h" #include "atlas/util/Unique.h" -#include "atlas/mesh/IsGhostNode.h" #include "eckit/types/FloatCompare.h" +#include "tests/TestMeshes.h" #include "tests/AtlasTestEnvironment.h" @@ -41,26 +42,19 @@ using namespace atlas::meshgenerator; namespace atlas { namespace test { -double dual_volume(Mesh& mesh) -{ - mesh::Nodes& nodes = mesh.nodes(); - mesh::IsGhostNode is_ghost_node(nodes); - int nb_nodes = nodes.size(); - array::ArrayView dual_volumes = array::make_view( nodes.field("dual_volumes") ); - double area=0; - for( int node=0; node 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 ); } } - } - ATLAS_TRACE_MPI( ALLREDUCE ) { - mpi::comm().allReduceInPlace(area, eckit::mpi::sum()); - } + ATLAS_TRACE_MPI( ALLREDUCE ) { mpi::comm().allReduceInPlace( area, eckit::mpi::sum() ); } - return area; + return area; } #if 0 @@ -108,388 +102,132 @@ CASE( "test_small" ) #endif #if 1 -CASE( "test_custom" ) -{ - // Mesh m = test::generate_mesh( T63() ); - - Mesh m = test::generate_mesh( {10, 12, 14, 16, 16, 16, 16, 14, 12, 10} ); - - mesh::actions::build_nodes_parallel_fields(m.nodes()); - mesh::actions::build_periodic_boundaries(m); - mesh::actions::build_halo(m,1); - //mesh::actions::build_edges(m); - //mesh::actions::build_pole_edges(m); - //mesh::actions::build_edges_parallel_fields(m.function_space("edges"),m.nodes()); - //mesh::actions::build_centroid_dual_mesh(m); - - std::stringstream filename; filename << "custom.msh"; - Gmsh(filename.str(),util::Config("ghost",true)).write(m); - -// EXPECT( eckit::types::is_approximately_equal( test::dual_volume(m), 2.*M_PI*M_PI, 1e-6 )); - - auto lonlat = array::make_view( m.nodes().lonlat() ); - - std::vector check; - switch( mpi::comm().rank() ) { - case 0: check = { - 607990293346953216, - 607990293382953216, - 607990293418953216, - 607990293454953216, - 607990293490953216, - 607990293526953216, - 607990293562953216, - 607990293598953216, - 607990293634953216, - 607990293670953216, - 644481443595331584, - 644481443625331584, - 644481443655331584, - 644481443685331584, - 644481443715331584, - 644481443745331584, - 644481443775331584, - 644481443805331584, - 644481443835331584, - 644481443865331584, - 644481443895331584, - 644481443925331584, - 681187136050079744, - 681187136075794030, - 681187136101508315, - 681187136127222601, - 681187136152936887, - 681187136178651173, - 607990293706953216, - 644481443955331584, - 681187136204365458, - 681187136230079744, - 681187136255794030, - 681187136281508315, - 681187136307222601, - 681187136332936887, - 681187136358651173, - 681187136384365458, - 717939789677242368, - 717939789699742368, - 717939789722242368, - 717939789744742368, - 717939789767242368, - 717939789789742368, - 717939789812242368, - 754708008265885696, - 754708008288385696, - 754708008310885696, - 754708008333385696, - 754708008355885696, - 754708008378385696, - 754708008400885696, - 717939789834742368, - 717939789857242368, - 717939789879742368, - 717939789902242368, - 754708008423385696, - 681187136410079744, - 717939789924742368, - 717939789947242368, - 717939789969742368, - 717939789992242368, - 717939790014742368, - 607990293310953217, - 644481443565331585, - 681187136024365459, - 717939789654742369, - 754708008243385697, - 607990293742953216, - 644481443985331584, - 681187136435794030 - }; - break; - case 1: - check = { - 717939789677242368, - 717939789699742368, - 717939789722242368, - 717939789744742368, - 717939789767242368, - 717939789789742368, - 754708008265885696, - 754708008288385696, - 754708008310885696, - 754708008333385696, - 754708008355885696, - 754708008378385696, - 791480219026630656, - 791480219049130656, - 791480219071630656, - 791480219094130656, - 791480219116630656, - 828248437615273984, - 828248437637773984, - 828248437660273984, - 828248437682773984, - 828248437705273984, - 865001091242436608, - 865001091268150894, - 865001091293865179, - 865001091319579465, - 865001091345293751, - 717939789812242368, - 754708008400885696, - 791480219139130656, - 828248437727773984, - 865001091371008037, - 901706783697184768, - 901706783727184768, - 901706783757184768, - 901706783787184768, - 901706783817184768, - 681187136050079744, - 681187136075794030, - 681187136101508315, - 681187136127222601, - 681187136152936887, - 681187136178651173, - 681187136204365458, - 717939789834742368, - 754708008423385696, - 791480219161630656, - 791480219184130656, - 828248437750273984, - 865001091396722322, - 901706783847184768, - 938197933945563136, - 938197933981563136, - 938197934017563136, - 938197934053563136, - 938197934089563136, - 717939789654742369, - 754708008243385697, - 791480219004130657, - 828248437592773985, - 865001091216722323, - 901706783667184769 - }; - break; - case 2: - check = { - 681187136204365458, - 681187136230079744, - 681187136255794030, - 717939789812242368, - 717939789834742368, - 717939789857242368, - 717939789879742368, - 717939789902242368, - 754708008400885696, - 754708008423385696, - 754708008445885696, - 754708008468385696, - 754708008490885696, - 791480219139130656, - 791480219161630656, - 791480219184130656, - 791480219206630656, - 791480219229130656, - 828248437727773984, - 828248437750273984, - 828248437772773984, - 828248437795273984, - 828248437817773984, - 865001091371008037, - 865001091396722322, - 865001091422436608, - 865001091448150894, - 681187136281508315, - 717939789924742368, - 754708008378385696, - 754708008513385696, - 791480219251630656, - 828248437840273984, - 865001091345293751, - 865001091473865179, - 901706783817184768, - 901706783847184768, - 901706783877184768, - 901706783907184768, - 644481443745331584, - 644481443775331584, - 644481443805331584, - 644481443835331584, - 681187136178651173, - 681187136307222601, - 717939789789742368, - 717939789767242368, - 754708008355885696, - 791480219116630656, - 828248437705273984, - 865001091319579465, - 901706783787184768, - 717939789947242368, - 754708008535885696, - 791480219274130656, - 791480219296630656, - 828248437862773984, - 865001091499579465, - 901706783937184768, - 938197934053563136, - 938197934089563136, - 938197934125563136, - 938197934161563136 - }; - break; - case 3: - check = { - 681187136281508315, - 681187136307222601, - 681187136332936887, - 681187136358651173, - 681187136384365458, - 717939789924742368, - 717939789947242368, - 717939789969742368, - 717939789992242368, - 717939790014742368, - 754708008513385696, - 754708008535885696, - 754708008558385696, - 754708008580885696, - 754708008603385696, - 791480219251630656, - 791480219274130656, - 791480219296630656, - 791480219319130656, - 791480219341630656, - 791480219364130656, - 828248437840273984, - 828248437862773984, - 828248437885273984, - 828248437907773984, - 828248437930273984, - 828248437952773984, - 644481443955331584, - 681187136410079744, - 717939789902242368, - 717939790037242368, - 754708008490885696, - 754708008625885696, - 791480219386630656, - 828248437975273984, - 865001091473865179, - 865001091499579465, - 865001091525293751, - 865001091551008037, - 865001091576722322, - 865001091602436608, - 607990293706953216, - 644481443805331584, - 644481443835331584, - 644481443865331584, - 644481443895331584, - 644481443925331584, - 681187136255794030, - 717939789879742368, - 754708008468385696, - 791480219229130656, - 828248437817773984, - 865001091448150894, - 901706783907184768, - 901706783937184768, - 901706783967184768, - 901706783997184768, - 901706784027184768, - 901706784057184768, - 644481443985331584, - 681187136435794030, - 717939790059742368, - 754708008648385696, - 791480219409130656, - 828248437997773984, - 865001091628150894 - }; - break; - case 4: - check = { - 865001091473865179, - 865001091499579465, - 865001091525293751, - 865001091551008037, - 865001091576722322, - 901706783697184768, - 901706783727184768, - 901706783757184768, - 901706783787184768, - 901706783817184768, - 901706783847184768, - 901706783877184768, - 901706783907184768, - 901706783937184768, - 901706783967184768, - 901706783997184768, - 901706784027184768, - 938197933945563136, - 938197933981563136, - 938197934017563136, - 938197934053563136, - 938197934089563136, - 938197934125563136, - 938197934161563136, - 938197934197563136, - 938197934233563136, - 938197934269563136, - 865001091602436608, - 901706784057184768, - 938197934305563136, - 865001091242436608, - 865001091268150894, - 865001091293865179, - 865001091319579465, - 865001091345293751, - 865001091371008037, - 828248437840273984, - 865001091396722322, - 865001091422436608, - 865001091448150894, - 828248437862773984, - 828248437885273984, - 828248437907773984, - 828248437930273984, - 828248437952773984, - 828248437975273984, - 865001091216722323, - 901706783667184769, - 938197933909563137, - 828248437997773984, - 865001091628150894, - 901706784087184768, - 938197934341563136 - }; - break; - default: - check.clear(); - } - std::vector uid(m.nodes().size()); - for( size_t j=0; j dual_volumes ( nodes.field( "dual_volumes" ) ); -// array::array::ArrayView dual_normals ( edges.field( "dual_normals" ) ); +CASE( "test_custom" ) { + // Mesh m = test::generate_mesh( T63() ); + + Mesh m = test::generate_mesh( {10, 12, 14, 16, 16, 16, 16, 14, 12, 10} ); + + mesh::actions::build_nodes_parallel_fields( m.nodes() ); + mesh::actions::build_periodic_boundaries( m ); + mesh::actions::build_halo( m, 1 ); + // mesh::actions::build_edges(m); + // mesh::actions::build_pole_edges(m); + // mesh::actions::build_edges_parallel_fields(m.function_space("edges"),m.nodes()); + // mesh::actions::build_centroid_dual_mesh(m); + + std::stringstream filename; + filename << "custom.msh"; + Gmsh( filename.str(), util::Config( "ghost", true ) ).write( m ); + + // EXPECT( eckit::types::is_approximately_equal( test::dual_volume(m), + // 2.*M_PI*M_PI, 1e-6 )); + + auto lonlat = array::make_view( m.nodes().lonlat() ); + + std::vector check; + switch ( mpi::comm().rank() ) { + case 0: + check = {607990293346953216, 607990293382953216, 607990293418953216, 607990293454953216, 607990293490953216, + 607990293526953216, 607990293562953216, 607990293598953216, 607990293634953216, 607990293670953216, + 644481443595331584, 644481443625331584, 644481443655331584, 644481443685331584, 644481443715331584, + 644481443745331584, 644481443775331584, 644481443805331584, 644481443835331584, 644481443865331584, + 644481443895331584, 644481443925331584, 681187136050079744, 681187136075794030, 681187136101508315, + 681187136127222601, 681187136152936887, 681187136178651173, 607990293706953216, 644481443955331584, + 681187136204365458, 681187136230079744, 681187136255794030, 681187136281508315, 681187136307222601, + 681187136332936887, 681187136358651173, 681187136384365458, 717939789677242368, 717939789699742368, + 717939789722242368, 717939789744742368, 717939789767242368, 717939789789742368, 717939789812242368, + 754708008265885696, 754708008288385696, 754708008310885696, 754708008333385696, 754708008355885696, + 754708008378385696, 754708008400885696, 717939789834742368, 717939789857242368, 717939789879742368, + 717939789902242368, 754708008423385696, 681187136410079744, 717939789924742368, 717939789947242368, + 717939789969742368, 717939789992242368, 717939790014742368, 607990293310953217, 644481443565331585, + 681187136024365459, 717939789654742369, 754708008243385697, 607990293742953216, 644481443985331584, + 681187136435794030}; + break; + case 1: + check = {717939789677242368, 717939789699742368, 717939789722242368, 717939789744742368, 717939789767242368, + 717939789789742368, 754708008265885696, 754708008288385696, 754708008310885696, 754708008333385696, + 754708008355885696, 754708008378385696, 791480219026630656, 791480219049130656, 791480219071630656, + 791480219094130656, 791480219116630656, 828248437615273984, 828248437637773984, 828248437660273984, + 828248437682773984, 828248437705273984, 865001091242436608, 865001091268150894, 865001091293865179, + 865001091319579465, 865001091345293751, 717939789812242368, 754708008400885696, 791480219139130656, + 828248437727773984, 865001091371008037, 901706783697184768, 901706783727184768, 901706783757184768, + 901706783787184768, 901706783817184768, 681187136050079744, 681187136075794030, 681187136101508315, + 681187136127222601, 681187136152936887, 681187136178651173, 681187136204365458, 717939789834742368, + 754708008423385696, 791480219161630656, 791480219184130656, 828248437750273984, 865001091396722322, + 901706783847184768, 938197933945563136, 938197933981563136, 938197934017563136, 938197934053563136, + 938197934089563136, 717939789654742369, 754708008243385697, 791480219004130657, 828248437592773985, + 865001091216722323, 901706783667184769}; + break; + case 2: + check = {681187136204365458, 681187136230079744, 681187136255794030, 717939789812242368, 717939789834742368, + 717939789857242368, 717939789879742368, 717939789902242368, 754708008400885696, 754708008423385696, + 754708008445885696, 754708008468385696, 754708008490885696, 791480219139130656, 791480219161630656, + 791480219184130656, 791480219206630656, 791480219229130656, 828248437727773984, 828248437750273984, + 828248437772773984, 828248437795273984, 828248437817773984, 865001091371008037, 865001091396722322, + 865001091422436608, 865001091448150894, 681187136281508315, 717939789924742368, 754708008378385696, + 754708008513385696, 791480219251630656, 828248437840273984, 865001091345293751, 865001091473865179, + 901706783817184768, 901706783847184768, 901706783877184768, 901706783907184768, 644481443745331584, + 644481443775331584, 644481443805331584, 644481443835331584, 681187136178651173, 681187136307222601, + 717939789789742368, 717939789767242368, 754708008355885696, 791480219116630656, 828248437705273984, + 865001091319579465, 901706783787184768, 717939789947242368, 754708008535885696, 791480219274130656, + 791480219296630656, 828248437862773984, 865001091499579465, 901706783937184768, 938197934053563136, + 938197934089563136, 938197934125563136, 938197934161563136}; + break; + case 3: + check = {681187136281508315, 681187136307222601, 681187136332936887, 681187136358651173, 681187136384365458, + 717939789924742368, 717939789947242368, 717939789969742368, 717939789992242368, 717939790014742368, + 754708008513385696, 754708008535885696, 754708008558385696, 754708008580885696, 754708008603385696, + 791480219251630656, 791480219274130656, 791480219296630656, 791480219319130656, 791480219341630656, + 791480219364130656, 828248437840273984, 828248437862773984, 828248437885273984, 828248437907773984, + 828248437930273984, 828248437952773984, 644481443955331584, 681187136410079744, 717939789902242368, + 717939790037242368, 754708008490885696, 754708008625885696, 791480219386630656, 828248437975273984, + 865001091473865179, 865001091499579465, 865001091525293751, 865001091551008037, 865001091576722322, + 865001091602436608, 607990293706953216, 644481443805331584, 644481443835331584, 644481443865331584, + 644481443895331584, 644481443925331584, 681187136255794030, 717939789879742368, 754708008468385696, + 791480219229130656, 828248437817773984, 865001091448150894, 901706783907184768, 901706783937184768, + 901706783967184768, 901706783997184768, 901706784027184768, 901706784057184768, 644481443985331584, + 681187136435794030, 717939790059742368, 754708008648385696, 791480219409130656, 828248437997773984, + 865001091628150894}; + break; + case 4: + check = {865001091473865179, 865001091499579465, 865001091525293751, 865001091551008037, 865001091576722322, + 901706783697184768, 901706783727184768, 901706783757184768, 901706783787184768, 901706783817184768, + 901706783847184768, 901706783877184768, 901706783907184768, 901706783937184768, 901706783967184768, + 901706783997184768, 901706784027184768, 938197933945563136, 938197933981563136, 938197934017563136, + 938197934053563136, 938197934089563136, 938197934125563136, 938197934161563136, 938197934197563136, + 938197934233563136, 938197934269563136, 865001091602436608, 901706784057184768, 938197934305563136, + 865001091242436608, 865001091268150894, 865001091293865179, 865001091319579465, 865001091345293751, + 865001091371008037, 828248437840273984, 865001091396722322, 865001091422436608, 865001091448150894, + 828248437862773984, 828248437885273984, 828248437907773984, 828248437930273984, 828248437952773984, + 828248437975273984, 865001091216722323, 901706783667184769, 938197933909563137, 828248437997773984, + 865001091628150894, 901706784087184768, 938197934341563136}; + break; + default: + check.clear(); + } + std::vector uid( m.nodes().size() ); + for ( size_t j = 0; j < m.nodes().size(); ++j ) { + uid[j] = util::unique_lonlat( lonlat( j, 0 ), lonlat( j, 1 ) ); + } + if ( check.size() && mpi::comm().size() == 5 ) { + ATLAS_DEBUG_VAR( uid.size() ); + ATLAS_DEBUG_VAR( check.size() ); + EXPECT( uid.size() == check.size() ); + EXPECT( uid == check ); + } -// std::string checksum; -// checksum = nodes.checksum()->execute(dual_volumes); -// DEBUG("dual_volumes checksum "< dual_volumes ( nodes.field( + // "dual_volumes" ) ); + // array::array::ArrayView dual_normals ( edges.field( + // "dual_normals" ) ); -// checksum = edges.checksum()->execute(dual_normals); -// DEBUG("dual_normals checksum "<execute(dual_volumes); + // DEBUG("dual_volumes checksum "<execute(dual_normals); + // DEBUG("dual_normals checksum "< #include +#include #include "atlas/parallel/mpi/mpi.h" -#include "atlas/mesh/actions/BuildParallelFields.h" -#include "atlas/mesh/actions/BuildPeriodicBoundaries.h" -#include "atlas/library/config.h" -#include "atlas/output/Gmsh.h" +#include "atlas/array.h" #include "atlas/field/Field.h" +#include "atlas/grid.h" +#include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" +#include "atlas/library/config.h" #include "atlas/mesh/Mesh.h" -#include "atlas/util/Metadata.h" #include "atlas/mesh/Nodes.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" -#include "atlas/grid.h" +#include "atlas/mesh/actions/BuildParallelFields.h" +#include "atlas/mesh/actions/BuildPeriodicBoundaries.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" +#include "atlas/output/Gmsh.h" #include "atlas/parallel/mpi/mpi.h" -#include "atlas/array.h" +#include "atlas/util/CoordinateEnums.h" +#include "atlas/util/Metadata.h" #include "tests/AtlasTestEnvironment.h" @@ -41,168 +42,182 @@ namespace test { //----------------------------------------------------------------------------- -class IsGhost -{ +class IsGhost { public: - IsGhost( const mesh::Nodes& nodes ) : - part_( make_view(nodes.partition()) ), - ridx_( make_indexview(nodes.remote_index()) ), - mypart_(mpi::comm().rank()) - { - - } - - bool operator()(size_t idx) const - { - if( part_(idx) != mypart_ ) return true; - if( ridx_(idx) != (int)idx ) return true; - return false; - } + IsGhost( const mesh::Nodes& nodes ) : + part_( make_view( nodes.partition() ) ), + ridx_( make_indexview( nodes.remote_index() ) ), + mypart_( mpi::comm().rank() ) {} + + bool operator()( size_t idx ) const { + if ( part_( idx ) != mypart_ ) return true; + if ( ridx_( idx ) != (int)idx ) return true; + return false; + } + private: - array::ArrayView part_; - IndexView ridx_; - int mypart_; + array::ArrayView part_; + IndexView ridx_; + int mypart_; }; - -#define DISABLE if(0) -#define ENABLE if(1) +#define DISABLE if ( 0 ) +#define ENABLE if ( 1 ) //----------------------------------------------------------------------------- -CASE( "test1" ) -{ - Mesh m; - - mesh::Nodes& nodes = m.nodes(); - nodes.resize(10); - array::ArrayView xy = make_view( nodes.xy()); - array::ArrayView glb_idx = make_view( nodes.global_index()); - array::ArrayView part = make_view( nodes.partition() ); - array::ArrayView flags = make_view( nodes.field("flags") ); - flags.assign(Topology::NONE); - - // This is typically available - glb_idx(0) = 1; part(0) = 0; - glb_idx(1) = 2; part(1) = 0; - glb_idx(2) = 3; part(2) = 0; - glb_idx(3) = 4; part(3) = 0; - glb_idx(4) = 5; part(4) = 0; - glb_idx(5) = 6; part(5) = std::min(1,(int)mpi::comm().size()-1); - glb_idx(6) = 7; part(6) = std::min(1,(int)mpi::comm().size()-1); - glb_idx(7) = 8; part(7) = std::min(1,(int)mpi::comm().size()-1); - glb_idx(8) = 9; part(8) = std::min(1,(int)mpi::comm().size()-1); - glb_idx(9) = 10; part(9) = std::min(1,(int)mpi::comm().size()-1); - - xy(0,XX) = 0.; xy(0,YY) = 80.; Topology::set( flags(0), Topology::BC|Topology::WEST ); - xy(1,XX) = 0.; xy(1,YY) =-80.; Topology::set( flags(1), Topology::BC|Topology::WEST ); - xy(2,XX) = 90.; xy(2,YY) = 80.; - xy(3,XX) = 90.; xy(3,YY) =-80.; - xy(4,XX) = 180.; xy(4,YY) = 80.; - xy(5,XX) = 180.; xy(5,YY) =-80.; - xy(6,XX) = 270.; xy(6,YY) = 80.; - xy(7,XX) = 270.; xy(7,YY) =-80.; - xy(8,XX) = 360.; xy(8,YY) = 80.; Topology::set( flags(8), Topology::BC|Topology::EAST ); - xy(9,XX) = 360.; xy(9,YY) =-80.; Topology::set( flags(9), Topology::BC|Topology::EAST ); - - mesh::actions::build_parallel_fields(m); - - EXPECT( nodes.has_field("remote_idx") ); - - IndexView loc = make_indexview( nodes.remote_index() ); - EXPECT( loc(0) == 0 ); - EXPECT( loc(1) == 1 ); - EXPECT( loc(2) == 2 ); - EXPECT( loc(3) == 3 ); - EXPECT( loc(4) == 4 ); - EXPECT( loc(5) == 5 ); - EXPECT( loc(6) == 6 ); - EXPECT( loc(7) == 7 ); - EXPECT( loc(8) == 8 ); - EXPECT( loc(9) == 9 ); - - test::IsGhost is_ghost( m.nodes() ); - - switch ( mpi::comm().rank() ) - { - case 0: - EXPECT( is_ghost(0) == false ); - EXPECT( is_ghost(1) == false ); - EXPECT( is_ghost(2) == false ); - EXPECT( is_ghost(3) == false ); - EXPECT( is_ghost(4) == false ); - EXPECT( is_ghost(5) == true ); - EXPECT( is_ghost(6) == true ); - EXPECT( is_ghost(7) == true ); - EXPECT( is_ghost(8) == true ); - EXPECT( is_ghost(9) == true ); - break; - case 1: - EXPECT( is_ghost(0) == true ); - EXPECT( is_ghost(1) == true ); - EXPECT( is_ghost(2) == true ); - EXPECT( is_ghost(3) == true ); - EXPECT( is_ghost(4) == true ); - EXPECT( is_ghost(5) == false ); - EXPECT( is_ghost(6) == false ); - EXPECT( is_ghost(7) == false ); - EXPECT( is_ghost(8) == false ); - EXPECT( is_ghost(9) == false ); - break; - } - - mesh::actions::build_periodic_boundaries(m); - - // points 8 and 9 are periodic slave points of points 0 and 1 - EXPECT( part(8) == 0 ); - EXPECT( part(9) == 0 ); - EXPECT( loc(8) == 0 ); - EXPECT( loc(9) == 1 ); - if( mpi::comm().rank() == 1 ) - { - EXPECT( is_ghost(8) == true ); - EXPECT( is_ghost(9) == true ); - } - +CASE( "test1" ) { + Mesh m; + + mesh::Nodes& nodes = m.nodes(); + nodes.resize( 10 ); + array::ArrayView xy = make_view( nodes.xy() ); + array::ArrayView glb_idx = make_view( nodes.global_index() ); + array::ArrayView part = make_view( nodes.partition() ); + array::ArrayView flags = make_view( nodes.field( "flags" ) ); + flags.assign( Topology::NONE ); + + // This is typically available + glb_idx( 0 ) = 1; + part( 0 ) = 0; + glb_idx( 1 ) = 2; + part( 1 ) = 0; + glb_idx( 2 ) = 3; + part( 2 ) = 0; + glb_idx( 3 ) = 4; + part( 3 ) = 0; + glb_idx( 4 ) = 5; + part( 4 ) = 0; + glb_idx( 5 ) = 6; + part( 5 ) = std::min( 1, (int)mpi::comm().size() - 1 ); + glb_idx( 6 ) = 7; + part( 6 ) = std::min( 1, (int)mpi::comm().size() - 1 ); + glb_idx( 7 ) = 8; + part( 7 ) = std::min( 1, (int)mpi::comm().size() - 1 ); + glb_idx( 8 ) = 9; + part( 8 ) = std::min( 1, (int)mpi::comm().size() - 1 ); + glb_idx( 9 ) = 10; + part( 9 ) = std::min( 1, (int)mpi::comm().size() - 1 ); + + xy( 0, XX ) = 0.; + xy( 0, YY ) = 80.; + Topology::set( flags( 0 ), Topology::BC | Topology::WEST ); + xy( 1, XX ) = 0.; + xy( 1, YY ) = -80.; + Topology::set( flags( 1 ), Topology::BC | Topology::WEST ); + xy( 2, XX ) = 90.; + xy( 2, YY ) = 80.; + xy( 3, XX ) = 90.; + xy( 3, YY ) = -80.; + xy( 4, XX ) = 180.; + xy( 4, YY ) = 80.; + xy( 5, XX ) = 180.; + xy( 5, YY ) = -80.; + xy( 6, XX ) = 270.; + xy( 6, YY ) = 80.; + xy( 7, XX ) = 270.; + xy( 7, YY ) = -80.; + xy( 8, XX ) = 360.; + xy( 8, YY ) = 80.; + Topology::set( flags( 8 ), Topology::BC | Topology::EAST ); + xy( 9, XX ) = 360.; + xy( 9, YY ) = -80.; + Topology::set( flags( 9 ), Topology::BC | Topology::EAST ); + + mesh::actions::build_parallel_fields( m ); + + EXPECT( nodes.has_field( "remote_idx" ) ); + + IndexView loc = make_indexview( nodes.remote_index() ); + EXPECT( loc( 0 ) == 0 ); + EXPECT( loc( 1 ) == 1 ); + EXPECT( loc( 2 ) == 2 ); + EXPECT( loc( 3 ) == 3 ); + EXPECT( loc( 4 ) == 4 ); + EXPECT( loc( 5 ) == 5 ); + EXPECT( loc( 6 ) == 6 ); + EXPECT( loc( 7 ) == 7 ); + EXPECT( loc( 8 ) == 8 ); + EXPECT( loc( 9 ) == 9 ); + + test::IsGhost is_ghost( m.nodes() ); + + switch ( mpi::comm().rank() ) { + case 0: + EXPECT( is_ghost( 0 ) == false ); + EXPECT( is_ghost( 1 ) == false ); + EXPECT( is_ghost( 2 ) == false ); + EXPECT( is_ghost( 3 ) == false ); + EXPECT( is_ghost( 4 ) == false ); + EXPECT( is_ghost( 5 ) == true ); + EXPECT( is_ghost( 6 ) == true ); + EXPECT( is_ghost( 7 ) == true ); + EXPECT( is_ghost( 8 ) == true ); + EXPECT( is_ghost( 9 ) == true ); + break; + case 1: + EXPECT( is_ghost( 0 ) == true ); + EXPECT( is_ghost( 1 ) == true ); + EXPECT( is_ghost( 2 ) == true ); + EXPECT( is_ghost( 3 ) == true ); + EXPECT( is_ghost( 4 ) == true ); + EXPECT( is_ghost( 5 ) == false ); + EXPECT( is_ghost( 6 ) == false ); + EXPECT( is_ghost( 7 ) == false ); + EXPECT( is_ghost( 8 ) == false ); + EXPECT( is_ghost( 9 ) == false ); + break; + } + + mesh::actions::build_periodic_boundaries( m ); + + // points 8 and 9 are periodic slave points of points 0 and 1 + EXPECT( part( 8 ) == 0 ); + EXPECT( part( 9 ) == 0 ); + EXPECT( loc( 8 ) == 0 ); + EXPECT( loc( 9 ) == 1 ); + if ( mpi::comm().rank() == 1 ) { + EXPECT( is_ghost( 8 ) == true ); + EXPECT( is_ghost( 9 ) == true ); + } } -CASE( "test2" ) -{ - util::Config meshgen_options; - meshgen_options.set("angle",27.5); - meshgen_options.set("triangulate",false); - meshgenerator::StructuredMeshGenerator generate(meshgen_options); - Mesh m = generate( Grid("N32") ); - mesh::actions::build_parallel_fields(m); +CASE( "test2" ) { + util::Config meshgen_options; + meshgen_options.set( "angle", 27.5 ); + meshgen_options.set( "triangulate", false ); + meshgenerator::StructuredMeshGenerator generate( meshgen_options ); + Mesh m = generate( Grid( "N32" ) ); + mesh::actions::build_parallel_fields( m ); - mesh::Nodes& nodes = m.nodes(); + mesh::Nodes& nodes = m.nodes(); - test::IsGhost is_ghost(nodes); + test::IsGhost is_ghost( nodes ); - size_t nb_ghost = 0; - for( size_t jnode=0; jnode #include #include +#include -#include "atlas/library/Library.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/library/config.h" -#include "atlas/grid/detail/spacing/gaussian/Latitudes.h" +#include "atlas/array/ArrayView.h" +#include "atlas/array/MakeView.h" +#include "atlas/field/Field.h" #include "atlas/grid.h" -#include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" -#include "atlas/output/Gmsh.h" -#include "atlas/util/Config.h" +#include "atlas/grid/detail/spacing/gaussian/Latitudes.h" +#include "atlas/library/Library.h" +#include "atlas/library/config.h" +#include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" -#include "atlas/mesh/Elements.h" -#include "atlas/field/Field.h" -#include "atlas/util/Metadata.h" -#include "atlas/array/ArrayView.h" -#include "atlas/array/MakeView.h" #include "atlas/mesh/actions/BuildParallelFields.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/util/Config.h" +#include "atlas/meshgenerator/StructuredMeshGenerator.h" +#include "atlas/output/Gmsh.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" +#include "atlas/util/Config.h" +#include "atlas/util/CoordinateEnums.h" +#include "atlas/util/Metadata.h" #include "eckit/types/FloatCompare.h" #include "tests/AtlasTestEnvironment.h" @@ -41,14 +41,14 @@ namespace atlas { namespace grid { namespace spacing { namespace gaussian { -void compute_gaussian_quadrature_npole_equator(const size_t N, double lats[], double weights[]); -} -} -} +void compute_gaussian_quadrature_npole_equator( const size_t N, double lats[], double weights[] ); } +} // namespace spacing +} // namespace grid +} // namespace atlas -#define DISABLE if(0) -#define ENABLE if(1) +#define DISABLE if ( 0 ) +#define ENABLE if ( 1 ) namespace atlas { namespace test { @@ -56,455 +56,391 @@ namespace test { //----------------------------------------------------------------------------- static grid::ReducedGaussianGrid debug_grid() { - return { - 6, - 10, - 18, - 22, - 22, - 22, - 22, - 18, - 10, - 6 - }; + return {6, 10, 18, 22, 22, 22, 22, 18, 10, 6}; } -static grid::StructuredGrid minimal_grid(int N, long lon[]) { - std::vector nx(2*N); - for( long j=0; j nx( 2 * N ); + for ( long j = 0; j < N; ++j ) { + nx[j] = lon[j]; + nx[nx.size() - 1 - j] = nx[j]; + } + return grid::ReducedGaussianGrid( nx ); } - - -double compute_lonlat_area(Mesh& mesh) -{ - mesh::Nodes& nodes = mesh.nodes(); - mesh::Elements& quads = mesh.cells().elements(0); - mesh::Elements& triags = mesh.cells().elements(1); - array::ArrayView lonlat = array::make_view( nodes.lonlat() ); - - const mesh::BlockConnectivity& quad_nodes = quads.node_connectivity(); - const mesh::BlockConnectivity& triag_nodes = triags.node_connectivity(); - - double area=0; - for(size_t e = 0; e < quads.size(); ++e) - { - int n0 = quad_nodes(e,0); - int n1 = quad_nodes(e,1); - int n2 = quad_nodes(e,2); - int n3 = quad_nodes(e,3); - double x0=lonlat(n0,LON), x1=lonlat(n1,LON), x2=lonlat(n2,LON), x3=lonlat(n3,LON); - double y0=lonlat(n0,LAT), y1=lonlat(n1,LAT), y2=lonlat(n2,LAT), y3=lonlat(n3,LAT); - area += std::abs( x0*(y1-y2)+x1*(y2-y0)+x2*(y0-y1) )*0.5; - area += std::abs( x2*(y3-y0)+x3*(y0-y2)+x0*(y2-y3) )*0.5; - } - for(size_t e = 0; e < triags.size(); ++e) - { - int n0 = triag_nodes(e,0); - int n1 = triag_nodes(e,1); - int n2 = triag_nodes(e,2); - double x0=lonlat(n0,LON), x1=lonlat(n1,LON), x2=lonlat(n2,LON); - double y0=lonlat(n0,LAT), y1=lonlat(n1,LAT), y2=lonlat(n2,LAT); - area += std::abs( x0*(y1-y2)+x1*(y2-y0)+x2*(y0-y1) )*0.5; - } - return area; +double compute_lonlat_area( Mesh& mesh ) { + mesh::Nodes& nodes = mesh.nodes(); + mesh::Elements& quads = mesh.cells().elements( 0 ); + mesh::Elements& triags = mesh.cells().elements( 1 ); + array::ArrayView lonlat = array::make_view( nodes.lonlat() ); + + const mesh::BlockConnectivity& quad_nodes = quads.node_connectivity(); + const mesh::BlockConnectivity& triag_nodes = triags.node_connectivity(); + + double area = 0; + for ( size_t e = 0; e < quads.size(); ++e ) { + int n0 = quad_nodes( e, 0 ); + int n1 = quad_nodes( e, 1 ); + int n2 = quad_nodes( e, 2 ); + int n3 = quad_nodes( e, 3 ); + double x0 = lonlat( n0, LON ), x1 = lonlat( n1, LON ), x2 = lonlat( n2, LON ), x3 = lonlat( n3, LON ); + double y0 = lonlat( n0, LAT ), y1 = lonlat( n1, LAT ), y2 = lonlat( n2, LAT ), y3 = lonlat( n3, LAT ); + area += std::abs( x0 * ( y1 - y2 ) + x1 * ( y2 - y0 ) + x2 * ( y0 - y1 ) ) * 0.5; + area += std::abs( x2 * ( y3 - y0 ) + x3 * ( y0 - y2 ) + x0 * ( y2 - y3 ) ) * 0.5; + } + for ( size_t e = 0; e < triags.size(); ++e ) { + int n0 = triag_nodes( e, 0 ); + int n1 = triag_nodes( e, 1 ); + int n2 = triag_nodes( e, 2 ); + double x0 = lonlat( n0, LON ), x1 = lonlat( n1, LON ), x2 = lonlat( n2, LON ); + double y0 = lonlat( n0, LAT ), y1 = lonlat( n1, LAT ), y2 = lonlat( n2, LAT ); + area += std::abs( x0 * ( y1 - y2 ) + x1 * ( y2 - y0 ) + x2 * ( y0 - y1 ) ) * 0.5; + } + return area; } //----------------------------------------------------------------------------- -CASE( "test_eq_caps" ) -{ - std::vector n_regions; - std::vector s_cap; - - grid::detail::partitioner::eq_caps(6, n_regions, s_cap); - EXPECT( n_regions.size() == 3 ); - EXPECT( n_regions[0] == 1 ); - EXPECT( n_regions[1] == 4 ); - EXPECT( n_regions[2] == 1 ); - - grid::detail::partitioner::eq_caps(10, n_regions, s_cap); - EXPECT( n_regions.size() == 4 ); - EXPECT( n_regions[0] == 1 ); - EXPECT( n_regions[1] == 4 ); - EXPECT( n_regions[2] == 4 ); - EXPECT( n_regions[3] == 1 ); +CASE( "test_eq_caps" ) { + std::vector n_regions; + std::vector s_cap; + + grid::detail::partitioner::eq_caps( 6, n_regions, s_cap ); + EXPECT( n_regions.size() == 3 ); + EXPECT( n_regions[0] == 1 ); + EXPECT( n_regions[1] == 4 ); + EXPECT( n_regions[2] == 1 ); + + grid::detail::partitioner::eq_caps( 10, n_regions, s_cap ); + EXPECT( n_regions.size() == 4 ); + EXPECT( n_regions[0] == 1 ); + EXPECT( n_regions[1] == 4 ); + EXPECT( n_regions[2] == 4 ); + EXPECT( n_regions[3] == 1 ); } -CASE( "test_partitioner" ) -{ - Grid g( "S4x2" ); - - // 12 partitions - { - grid::detail::partitioner::EqualRegionsPartitioner partitioner(12); - EXPECT( partitioner.nb_bands() == 4 ); - EXPECT( partitioner.nb_regions(0) == 1 ); - EXPECT( partitioner.nb_regions(1) == 5 ); - EXPECT( partitioner.nb_regions(2) == 5 ); - EXPECT( partitioner.nb_regions(3) == 1 ); - } - - // 24 partitions - { - grid::detail::partitioner::EqualRegionsPartitioner partitioner(24); - EXPECT( partitioner.nb_bands() == 5 ); - EXPECT( partitioner.nb_regions(0) == 1 ); - EXPECT( partitioner.nb_regions(1) == 6 ); - EXPECT( partitioner.nb_regions(2) ==10 ); - EXPECT( partitioner.nb_regions(3) == 6 ); - EXPECT( partitioner.nb_regions(4) == 1 ); - } - - // 48 partitions - { - grid::detail::partitioner::EqualRegionsPartitioner partitioner(48); - EXPECT( partitioner.nb_bands() == 7 ); - EXPECT( partitioner.nb_regions(0) == 1 ); - EXPECT( partitioner.nb_regions(1) == 6 ); - EXPECT( partitioner.nb_regions(2) == 11 ); - EXPECT( partitioner.nb_regions(3) == 12 ); - EXPECT( partitioner.nb_regions(4) == 11 ); - EXPECT( partitioner.nb_regions(5) == 6 ); - EXPECT( partitioner.nb_regions(6) == 1 ); - } - - // 96 partitions - { - grid::detail::partitioner::EqualRegionsPartitioner partitioner(96); - EXPECT( partitioner.nb_bands() == 10 ); - EXPECT( partitioner.nb_regions(0) == 1 ); - EXPECT( partitioner.nb_regions(1) == 6 ); - EXPECT( partitioner.nb_regions(2) == 11 ); - EXPECT( partitioner.nb_regions(3) == 14 ); - EXPECT( partitioner.nb_regions(4) == 16 ); - EXPECT( partitioner.nb_regions(5) == 16 ); - EXPECT( partitioner.nb_regions(6) == 14 ); - EXPECT( partitioner.nb_regions(7) == 11 ); - EXPECT( partitioner.nb_regions(8) == 6 ); - EXPECT( partitioner.nb_regions(9) == 1 ); - } +CASE( "test_partitioner" ) { + Grid g( "S4x2" ); -} + // 12 partitions + { + grid::detail::partitioner::EqualRegionsPartitioner partitioner( 12 ); + EXPECT( partitioner.nb_bands() == 4 ); + EXPECT( partitioner.nb_regions( 0 ) == 1 ); + EXPECT( partitioner.nb_regions( 1 ) == 5 ); + EXPECT( partitioner.nb_regions( 2 ) == 5 ); + EXPECT( partitioner.nb_regions( 3 ) == 1 ); + } -CASE( "test_gaussian_latitudes" ) -{ - std::vector< double > factory_latitudes; - std::vector< double > computed_latitudes; - std::vector< double > computed_weights; - - - size_t size_test_N = 19; - - size_t test_N[] = {16,24,32,48,64,80,96,128,160, - 200,256,320,400,512,576,640, - 800,1024,1280,1600,2000,4000,8000}; - - for( size_t i=0; i("nb_owned") == 156 ); -// EXPECT( m.function_space("quads" ).metadata().get("nb_owned") == 134 ); -// EXPECT( m.function_space("triags").metadata().get("nb_owned") == 32 ); - } - - ENABLE { - meshgenerator::StructuredMeshGenerator generate( - default_opts - ("3d",false) - ("include_pole",false) - ); - m = generate( atlas::test::debug_grid() ); - EXPECT( m.nodes().size() == 166 ); - EXPECT( m.cells().elements(0).size() == 134 ); - EXPECT( m.cells().elements(1).size() == 32 ); -// EXPECT( m.nodes().metadata().get("nb_owned") == 166 ); -// EXPECT( m.function_space("quads" ).metadata().get("nb_owned") == 134 ); -// EXPECT( m.function_space("triags").metadata().get("nb_owned") == 32 ); - } - - ENABLE { - meshgenerator::StructuredMeshGenerator generate( - default_opts - ("3d",true) - ("include_pole",true) - ); - m = generate( atlas::test::debug_grid() ); - EXPECT( m.nodes().size() == 158 ); - EXPECT( m.cells().elements(0).size() == 134 ); - EXPECT( m.cells().elements(1).size() == 44 ); -// EXPECT( m.nodes().metadata().get("nb_owned") == 158 ); -// EXPECT( m.function_space("quads" ).metadata().get("nb_owned") == 134 ); -// EXPECT( m.function_space("triags").metadata().get("nb_owned") == 44 ); - } - - Mesh mesh; - - ENABLE { - meshgenerator::StructuredMeshGenerator generate( - default_opts - ("3d",false) - ("include_pole",false) - ); - int nlat=2; - long lon[] = { 4, 6 }; - mesh = generate( test::minimal_grid(nlat,lon) ); - EXPECT( mesh.nodes().size() == 24 ); - EXPECT( mesh.cells().elements(0).size() == 14 ); - EXPECT( mesh.cells().elements(1).size() == 4 ); - - double max_lat = test::minimal_grid(nlat,lon).y().front(); - EXPECT( eckit::types::is_approximately_equal(test::compute_lonlat_area(mesh), 2.*M_PI*2.*max_lat, 1e-8 )); - output::Gmsh("minimal2.msh").write(mesh); - } - // 3 latitudes - ENABLE { - meshgenerator::StructuredMeshGenerator generate( - default_opts - ("3d",false) - ("include_pole",false) - ); - int nlat=3; - long lon[] = { 4, 6, 8 }; - mesh = generate( test::minimal_grid(nlat,lon) ); - EXPECT( mesh.nodes().size() == 42 ); - EXPECT( mesh.cells().elements(0).size() == 28 ); - EXPECT( mesh.cells().elements(1).size() == 8 ); - output::Gmsh("minimal3.msh").write(mesh); - } - // 4 latitudes - ENABLE { - meshgenerator::StructuredMeshGenerator generate( - default_opts - ("3d",false) - ("include_pole",false) - ); - int nlat=4; - long lon[] = { 4, 6, 8, 10 }; - mesh = generate( test::minimal_grid(nlat,lon) ); - EXPECT( mesh.nodes().size() == 64 ); - EXPECT( mesh.cells().elements(0).size() == 46 ); - EXPECT( mesh.cells().elements(1).size() == 12 ); - output::Gmsh("minimal4.msh").write(mesh); - } - // 5 latitudes WIP - ENABLE { - meshgenerator::StructuredMeshGenerator generate( - default_opts - ("3d",false) - ("include_pole",false) - ); - int nlat=5; - long lon[] = { 6, 10, 18, 22, 22 }; - mesh = generate( test::minimal_grid(nlat,lon) ); - EXPECT( mesh.nodes().size() == 166 ); - EXPECT( mesh.cells().elements(0).size() == 134 ); - EXPECT( mesh.cells().elements(1).size() == 32 ); - output::Gmsh("minimal5.msh").write(mesh); - } + // 96 partitions + { + grid::detail::partitioner::EqualRegionsPartitioner partitioner( 96 ); + EXPECT( partitioner.nb_bands() == 10 ); + EXPECT( partitioner.nb_regions( 0 ) == 1 ); + EXPECT( partitioner.nb_regions( 1 ) == 6 ); + EXPECT( partitioner.nb_regions( 2 ) == 11 ); + EXPECT( partitioner.nb_regions( 3 ) == 14 ); + EXPECT( partitioner.nb_regions( 4 ) == 16 ); + EXPECT( partitioner.nb_regions( 5 ) == 16 ); + EXPECT( partitioner.nb_regions( 6 ) == 14 ); + EXPECT( partitioner.nb_regions( 7 ) == 11 ); + EXPECT( partitioner.nb_regions( 8 ) == 6 ); + EXPECT( partitioner.nb_regions( 9 ) == 1 ); + } } + +CASE( "test_gaussian_latitudes" ) { + std::vector factory_latitudes; + std::vector computed_latitudes; + std::vector computed_weights; + + size_t size_test_N = 19; + + size_t test_N[] = {16, 24, 32, 48, 64, 80, 96, 128, 160, 200, 256, 320, + 400, 512, 576, 640, 800, 1024, 1280, 1600, 2000, 4000, 8000}; + + for ( size_t i = 0; i < size_test_N; ++i ) { + size_t N = test_N[i]; + Log::info() << "Testing gaussian latitude " << N << std::endl; + factory_latitudes.resize( N ); + computed_latitudes.resize( N ); + computed_weights.resize( N ); + // grid::gaussian::latitudes::gaussian_latitudes_npole_equator (N, + // factory_latitudes.data()); + // grid::gaussian::latitudes::compute_gaussian_quadrature_npole_equator(N, + // computed_latitudes.data(), computed_weights.data()); + grid::spacing::gaussian::gaussian_latitudes_npole_equator( N, factory_latitudes.data() ); + grid::spacing::gaussian::compute_gaussian_quadrature_npole_equator( N, computed_latitudes.data(), + computed_weights.data() ); + double wsum = 0; + for ( size_t i = 0; i < N; ++i ) { + EXPECT( eckit::types::is_approximately_equal( computed_latitudes[i], factory_latitudes[i], 0.0000001 ) ); + wsum += computed_weights[i]; + } + EXPECT( eckit::types::is_approximately_equal( wsum * 2., 1., 0.0000001 ) ); + } } -CASE( "test_rgg_meshgen_many_parts" ) -{ - - EXPECT( grid::detail::partitioner::PartitionerFactory::has("equal_regions") ); - size_t nb_parts = 20; - // Alternative grid for debugging - // int nlat=10; - // long lon[] = { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 }; - // test::MinimalGrid grid(nlat,lon); - grid::StructuredGrid grid = Grid("N32"); - //RegularGrid grid(128,64); - - /* - std::cout << grid.spec() << std::endl; - for (int jlat=0;jlat<2*nlat; jlat++) { - std::cout << grid.lon(jlat,0) << ", ... , " << "," << grid.lon(jlat,9) << grid.lon(jlat,10) << std::endl; - } - ASSERT(0); - */ - - double max_lat = grid.y().front(); - double check_area = 360.*2.*max_lat; - double area = 0; - int nodes[] = {313,332,336,338,334,337,348,359,360,361,360,360,359,370,321,334,338,335,348,315}; - int quads[] = {243,290,293,294,291,293,310,320,321,321,320,321,320,331,278,291,294,293,305,245}; - int triags[] = { 42, 13, 12, 13, 12, 14, 0, 1, 0, 1, 1, 0, 1, 0, 14, 12, 13, 11, 14, 42}; - int nb_owned = 0; - - std::vector all_owned ( grid.size(), -1 ); - - for(size_t p = 0; p < nb_parts; ++p) - { - ATLAS_DEBUG_VAR(p); - - meshgenerator::StructuredMeshGenerator generate ( util::Config - ("partitioner","equal_regions") - ("nb_parts",nb_parts) - ("part",p) - ("include_pole",false) - ("3d",false) ); - ATLAS_DEBUG_HERE(); +CASE( "test_rgg_meshgen_one_part" ) { + Mesh m; + util::Config default_opts; + default_opts.set( "nb_parts", 1 ); + default_opts.set( "part", 0 ); + // generate.options.set("nb_parts",1); + // generate.options.set("part", 0); + DISABLE { // This is all valid for meshes generated with MINIMAL NB TRIAGS + ENABLE { + meshgenerator::StructuredMeshGenerator generate( default_opts( "3d", true )( "include_pole", false ) ); + m = generate( atlas::test::debug_grid() ); + EXPECT( m.nodes().size() == 156 ); + EXPECT( m.cells().elements( 0 ).size() == 134 ); + EXPECT( m.cells().elements( 1 ).size() == 32 ); + // EXPECT( m.nodes().metadata().get("nb_owned") == 156 ); + // EXPECT( m.function_space("quads" + // ).metadata().get("nb_owned") == 134 ); + // EXPECT( + // m.function_space("triags").metadata().get("nb_owned") == + // 32 ); + } - Mesh m = generate( grid ); - ATLAS_DEBUG_HERE(); - m.metadata().set("part",p); - Log::info() << "generated grid " << p << std::endl; - array::ArrayView part = array::make_view( m.nodes().partition() ); - array::ArrayView gidx = array::make_view( m.nodes().global_index() ); - array::ArrayView lonlat = array::make_view( m.nodes().lonlat() ); + ENABLE { + meshgenerator::StructuredMeshGenerator generate( default_opts( "3d", false )( "include_pole", false ) ); + m = generate( atlas::test::debug_grid() ); + EXPECT( m.nodes().size() == 166 ); + EXPECT( m.cells().elements( 0 ).size() == 134 ); + EXPECT( m.cells().elements( 1 ).size() == 32 ); + // EXPECT( m.nodes().metadata().get("nb_owned") == 166 ); + // EXPECT( m.function_space("quads" + // ).metadata().get("nb_owned") == 134 ); + // EXPECT( + // m.function_space("triags").metadata().get("nb_owned") == + // 32 ); + } - area += test::compute_lonlat_area(m); - ATLAS_DEBUG_HERE(); + ENABLE { + meshgenerator::StructuredMeshGenerator generate( default_opts( "3d", true )( "include_pole", true ) ); + m = generate( atlas::test::debug_grid() ); + EXPECT( m.nodes().size() == 158 ); + EXPECT( m.cells().elements( 0 ).size() == 134 ); + EXPECT( m.cells().elements( 1 ).size() == 44 ); + // EXPECT( m.nodes().metadata().get("nb_owned") == 158 ); + // EXPECT( m.function_space("quads" + // ).metadata().get("nb_owned") == 134 ); + // EXPECT( + // m.function_space("triags").metadata().get("nb_owned") == + // 44 ); + } - DISABLE { // This is all valid for meshes generated with MINIMAL NB TRIAGS - if( nb_parts == 20 ) - { - EXPECT( m.nodes().size() == nodes[p] ); - EXPECT( m.cells().elements(0).size() == quads[p] ); - EXPECT( m.cells().elements(1).size() == triags[p] ); - } + Mesh mesh; + + ENABLE { + meshgenerator::StructuredMeshGenerator generate( default_opts( "3d", false )( "include_pole", false ) ); + int nlat = 2; + long lon[] = {4, 6}; + mesh = generate( test::minimal_grid( nlat, lon ) ); + EXPECT( mesh.nodes().size() == 24 ); + EXPECT( mesh.cells().elements( 0 ).size() == 14 ); + EXPECT( mesh.cells().elements( 1 ).size() == 4 ); + + double max_lat = test::minimal_grid( nlat, lon ).y().front(); + EXPECT( eckit::types::is_approximately_equal( test::compute_lonlat_area( mesh ), 2. * M_PI * 2. * max_lat, + 1e-8 ) ); + output::Gmsh( "minimal2.msh" ).write( mesh ); + } + // 3 latitudes + ENABLE { + meshgenerator::StructuredMeshGenerator generate( default_opts( "3d", false )( "include_pole", false ) ); + int nlat = 3; + long lon[] = {4, 6, 8}; + mesh = generate( test::minimal_grid( nlat, lon ) ); + EXPECT( mesh.nodes().size() == 42 ); + EXPECT( mesh.cells().elements( 0 ).size() == 28 ); + EXPECT( mesh.cells().elements( 1 ).size() == 8 ); + output::Gmsh( "minimal3.msh" ).write( mesh ); + } + // 4 latitudes + ENABLE { + meshgenerator::StructuredMeshGenerator generate( default_opts( "3d", false )( "include_pole", false ) ); + int nlat = 4; + long lon[] = {4, 6, 8, 10}; + mesh = generate( test::minimal_grid( nlat, lon ) ); + EXPECT( mesh.nodes().size() == 64 ); + EXPECT( mesh.cells().elements( 0 ).size() == 46 ); + EXPECT( mesh.cells().elements( 1 ).size() == 12 ); + output::Gmsh( "minimal4.msh" ).write( mesh ); + } + // 5 latitudes WIP + ENABLE { + meshgenerator::StructuredMeshGenerator generate( default_opts( "3d", false )( "include_pole", false ) ); + int nlat = 5; + long lon[] = {6, 10, 18, 22, 22}; + mesh = generate( test::minimal_grid( nlat, lon ) ); + EXPECT( mesh.nodes().size() == 166 ); + EXPECT( mesh.cells().elements( 0 ).size() == 134 ); + EXPECT( mesh.cells().elements( 1 ).size() == 32 ); + output::Gmsh( "minimal5.msh" ).write( mesh ); + } } - ATLAS_DEBUG_HERE(); +} - output::Gmsh("T63.msh").write(m); +CASE( "test_rgg_meshgen_many_parts" ) { + EXPECT( grid::detail::partitioner::PartitionerFactory::has( "equal_regions" ) ); + size_t nb_parts = 20; + // Alternative grid for debugging + // int nlat=10; + // long lon[] = { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 }; + // test::MinimalGrid grid(nlat,lon); + grid::StructuredGrid grid = Grid( "N32" ); + // RegularGrid grid(128,64); + + /* +std::cout << grid.spec() << std::endl; +for (int jlat=0;jlat<2*nlat; jlat++) { + std::cout << grid.lon(jlat,0) << ", ... , " << "," << grid.lon(jlat,9) << +grid.lon(jlat,10) << std::endl; +} +ASSERT(0); +*/ + + double max_lat = grid.y().front(); + double check_area = 360. * 2. * max_lat; + double area = 0; + int nodes[] = {313, 332, 336, 338, 334, 337, 348, 359, 360, 361, 360, 360, 359, 370, 321, 334, 338, 335, 348, 315}; + int quads[] = {243, 290, 293, 294, 291, 293, 310, 320, 321, 321, 320, 321, 320, 331, 278, 291, 294, 293, 305, 245}; + int triags[] = {42, 13, 12, 13, 12, 14, 0, 1, 0, 1, 1, 0, 1, 0, 14, 12, 13, 11, 14, 42}; + int nb_owned = 0; + + std::vector all_owned( grid.size(), -1 ); + + for ( size_t p = 0; p < nb_parts; ++p ) { + ATLAS_DEBUG_VAR( p ); + + meshgenerator::StructuredMeshGenerator generate( util::Config( "partitioner", "equal_regions" )( + "nb_parts", nb_parts )( "part", p )( "include_pole", false )( "3d", false ) ); + ATLAS_DEBUG_HERE(); + + Mesh m = generate( grid ); + ATLAS_DEBUG_HERE(); + m.metadata().set( "part", p ); + Log::info() << "generated grid " << p << std::endl; + array::ArrayView part = array::make_view( m.nodes().partition() ); + array::ArrayView gidx = array::make_view( m.nodes().global_index() ); + array::ArrayView lonlat = array::make_view( m.nodes().lonlat() ); + + area += test::compute_lonlat_area( m ); + ATLAS_DEBUG_HERE(); + + DISABLE { // This is all valid for meshes generated with MINIMAL NB TRIAGS + if ( nb_parts == 20 ) { + EXPECT( m.nodes().size() == nodes[p] ); + EXPECT( m.cells().elements( 0 ).size() == quads[p] ); + EXPECT( m.cells().elements( 1 ).size() == triags[p] ); + } + } + ATLAS_DEBUG_HERE(); + output::Gmsh( "T63.msh" ).write( m ); - mesh::Nodes& nodes = m.nodes(); - size_t nb_nodes = nodes.size(); + mesh::Nodes& nodes = m.nodes(); + size_t nb_nodes = nodes.size(); - // Test if all nodes are connected - { - std::vector node_elem_connections( nb_nodes, 0 ); - - const mesh::HybridElements::Connectivity& cell_node_connectivity = m.cells().node_connectivity(); - for( size_t jelem=0; jelem node_elem_connections( nb_nodes, 0 ); + + const mesh::HybridElements::Connectivity& cell_node_connectivity = m.cells().node_connectivity(); + for ( size_t jelem = 0; jelem < m.cells().size(); ++jelem ) { + for ( size_t jnode = 0; jnode < cell_node_connectivity.cols( jelem ); ++jnode ) + node_elem_connections[cell_node_connectivity( jelem, jnode )]++; + } + for ( size_t jnode = 0; jnode < nb_nodes; ++jnode ) { + if ( node_elem_connections[jnode] == 0 ) { + std::stringstream ss; + ss << "part " << p << ": node_gid " << gidx( jnode ) << " is not connected to any element."; + DISABLE { Log::error() << ss.str() << std::endl; } + } + } } - } - } - // Test if all nodes are owned - for( size_t n=0; n part = array::make_view( mesh.nodes().partition() ); - const array::ArrayView ghost = array::make_view( mesh.nodes().ghost() ); - const array::ArrayView flags = array::make_view( mesh.nodes().field("flags") ); - - Log::info() << "partition = [ "; - for( size_t jnode=0; jnode part = array::make_view( mesh.nodes().partition() ); + const array::ArrayView ghost = array::make_view( mesh.nodes().ghost() ); + const array::ArrayView flags = array::make_view( mesh.nodes().field( "flags" ) ); + + Log::info() << "partition = [ "; + for ( size_t jnode = 0; jnode < part.size(); ++jnode ) { + Log::info() << part( jnode ) << " "; + } + Log::info() << "]" << std::endl; + + Log::info() << "ghost = [ "; + for ( size_t jnode = 0; jnode < part.size(); ++jnode ) { + Log::info() << ghost( jnode ) << " "; + } + Log::info() << "]" << std::endl; + Log::info() << "flags = [ "; + for ( size_t jnode = 0; jnode < part.size(); ++jnode ) { + Log::info() << mesh::Nodes::Topology::check( flags( jnode ), mesh::Nodes::Topology::GHOST ) << " "; + EXPECT( mesh::Nodes::Topology::check( flags( jnode ), mesh::Nodes::Topology::GHOST ) == ghost( jnode ) ); + } + Log::info() << "]" << std::endl; } //----------------------------------------------------------------------------- @@ -512,7 +448,6 @@ CASE( "test_meshgen_ghost_at_end" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/mesh/test_shapefunctions.cc b/src/tests/mesh/test_shapefunctions.cc index 97481419b..1343285b9 100644 --- a/src/tests/mesh/test_shapefunctions.cc +++ b/src/tests/mesh/test_shapefunctions.cc @@ -4,15 +4,16 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include +#include "eckit/exception/Exceptions.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" -#include "eckit/exception/Exceptions.h" // #include "tests/TestMeshes.h" #include "atlas/mpi/mpi.h" @@ -36,281 +37,210 @@ namespace test { //----------------------------------------------------------------------------- - template< int NDIM > - class Mononomial - { - public: +template +class Mononomial { +public: Mononomial() {} - Mononomial(double coeff_, int power_[NDIM] ) - { - coeff=coeff_; - std::copy(power_,power_+NDIM,power); + Mononomial( double coeff_, int power_[NDIM] ) { + coeff = coeff_; + std::copy( power_, power_ + NDIM, power ); } - Mononomial(double coeff_, int p1_) - { - coeff=coeff_; - power[0]=p1_; + Mononomial( double coeff_, int p1_ ) { + coeff = coeff_; + power[0] = p1_; } - Mononomial(double coeff_, int p1_, int p2_) - { - coeff=coeff_; - power[0]=p1_; - power[1]=p2_; + Mononomial( double coeff_, int p1_, int p2_ ) { + coeff = coeff_; + power[0] = p1_; + power[1] = p2_; } - Mononomial(double coeff_, int p1_, int p2_, int p3_) - { - coeff=coeff_; - power[0]=p1_; - power[1]=p2_; - power[2]=p3_; + Mononomial( double coeff_, int p1_, int p2_, int p3_ ) { + coeff = coeff_; + power[0] = p1_; + power[1] = p2_; + power[2] = p3_; } - double eval( const double point[NDIM] ) const - { - double val = coeff; - for( size_t d=0; d - class Polynomial - { - public: +template +class Polynomial { +public: typedef Mononomial monomial_type; - public: - Polynomial& add( const monomial_type& mononomial ) - { - if( mononomial.coeff != 0 ) - mononomials_.push_back(mononomial); - return *this; +public: + Polynomial& add( const monomial_type& mononomial ) { + if ( mononomial.coeff != 0 ) mononomials_.push_back( mononomial ); + return *this; } - double eval( const double point[NDIM] ) const - { - double val = 0; - for( size_t n=0; n grad() const - { - std::vector g; - for( size_t d=0; d& pvec ) - { - Polynomial p; - for( size_t d=0; d& pvec ) - { - return pvec[1].deriv(0) - pvec[0].deriv(1); - } - - 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==3 ) - { - p[0] = pvec[2].deriv(1) - pvec[1].deriv(2); - p[1] = pvec[0].deriv(2) - pvec[2].deriv(0); - p[2] = pvec[1].deriv(0) - pvec[0].deriv(1); - } - return p; - } - - Polynomial operator+( const Polynomial& p2 ) - { - Polynomial p = *this; - p += p2; - return p; - } - - Polynomial operator-( const Polynomial& p2 ) - { - Polynomial p = *this; - p -= p2; - return p; + std::vector grad() const { + std::vector g; + for ( size_t d = 0; d < NDIM; ++d ) + g.push_back( deriv( d ) ); + return g; } - Polynomial& operator+=( const Polynomial& other ) - { - return addition(other,+1.); - } - - Polynomial& operator-=( const Polynomial& other ) - { - return addition(other,-1.); + static Polynomial div( const std::vector& pvec ) { + Polynomial p; + for ( size_t d = 0; d < NDIM; ++d ) + p += pvec[d].deriv( d ); + return p; } - private: - Polynomial& addition(const Polynomial& other, double sign = 1. ) - { - std::vector matched(other.mononomials_.size(),false); - for( size_t i=0; i& pvec ) { return pvec[1].deriv( 0 ) - pvec[0].deriv( 1 ); } + + 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 == 3 ) { + p[0] = pvec[2].deriv( 1 ) - pvec[1].deriv( 2 ); + p[1] = pvec[0].deriv( 2 ) - pvec[2].deriv( 0 ); + p[2] = pvec[1].deriv( 0 ) - pvec[0].deriv( 1 ); + } + return p; + } + + Polynomial operator+( const Polynomial& p2 ) { + Polynomial p = *this; + p += p2; + return p; + } + + Polynomial operator-( const Polynomial& p2 ) { + Polynomial p = *this; + p -= p2; + return p; + } + + Polynomial& operator+=( const Polynomial& other ) { return addition( other, +1. ); } + + Polynomial& operator-=( const Polynomial& other ) { return addition( other, -1. ); } + +private: + Polynomial& addition( const Polynomial& other, double sign = 1. ) { + std::vector matched( other.mononomials_.size(), false ); + for ( size_t i = 0; i < mononomials_.size(); ++i ) { + for ( size_t j = 0; j < other.mononomials_.size(); ++j ) { + if ( !matched[j] ) { + bool match = true; + for ( size_t d = 0; d < NDIM; ++d ) { + if ( mononomials_[i].power[d] != other.mononomials_[j].power[d] ) { + match = false; + break; + } + } + if ( match ) { + matched[j] = true; + mononomials_[i].coeff += sign * other.mononomials_[j].coeff; + } + } } - } } - } - for( size_t j=0; j mononomials_; +}; - - private: - std::vector< monomial_type > mononomials_; - }; - - class ShapeFunction : public eckit::Owned - { - public: +class ShapeFunction : public eckit::Owned { +public: typedef eckit::SharedPtr Ptr; - public: - ShapeFunction(){} - virtual ~ShapeFunction(){} - }; +public: + ShapeFunction() {} + virtual ~ShapeFunction() {} +}; - class ElementType : public eckit::Owned - { - public: +class ElementType : public eckit::Owned { +public: typedef eckit::SharedPtr Ptr; - typedef std::vector< ElementType::Ptr > Vector; - - public: + typedef std::vector Vector; +public: size_t N() const { return N_; } bool parametric() const { return parametric_; } @@ -319,8 +249,7 @@ namespace test { const ShapeFunction& shape_function() const { return *shape_function_; } - protected: - +protected: bool parametric_; size_t N_; @@ -328,161 +257,147 @@ namespace test { std::vector nodes_; ShapeFunction::Ptr shape_function_; - - }; - - class Point : public ElementType - { - public: - Point() - { - N_ = 1; - parametric_ = false; - shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); - } - }; - - class Polygon : public ElementType - { - public: - Polygon( size_t max_nodes=0 ) - { - parametric_ = false; - N_ = max_nodes; - } - }; - - class QuadP1 : public ElementType - { - public: - QuadP1() - { - parametric_ = true; - N_ = 4; - int nodes_init[] = { - -1., -1., - 1., -1., - 1., 1., - -1., 1. }; - nodes_.assign(nodes_init, nodes_init+N_); - shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); - } - }; - - class TriagP1 : public ElementType - { - public: - TriagP1() - { - parametric_ = true; - N_ = 3; - int nodes_init[] = { - 0., 0., - 1., 0., - 0., 1. }; - nodes_.assign(nodes_init, nodes_init+N_); - shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); - } - }; - - class LineP0 : public ElementType - { - public: - LineP0() - { - parametric_ = true; - N_ = 1; - double nodes_init[] = { 0. }; - nodes_.assign(nodes_init, nodes_init+N_); - shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); - } - }; - - class LineP1 : public ElementType - { - public: - LineP1() - { - parametric_ = true; - N_ = 2; - double nodes_init[] = { -1., 1. }; - nodes_.assign(nodes_init, nodes_init+N_); - shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); - } - }; - - class LineP2 : public ElementType - { - public: - LineP2() - { - parametric_ = true; - N_ = 3; - double nodes_init[] = { -1., 1., 0. }; - nodes_.assign(nodes_init, nodes_init+N_); - shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); - } - }; - - class Structured1D: public ElementType - { - public: - Structured1D(int N) - { - parametric_ = true; - N_ = N; - shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); - } - }; - - class Nodes : public eckit::Owned - { - public: +}; + +class Point : public ElementType { +public: + Point() { + N_ = 1; + parametric_ = false; + shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); + } +}; + +class Polygon : public ElementType { +public: + Polygon( size_t max_nodes = 0 ) { + parametric_ = false; + N_ = max_nodes; + } +}; + +class QuadP1 : public ElementType { +public: + QuadP1() { + parametric_ = true; + N_ = 4; + int nodes_init[] = {-1., -1., 1., -1., 1., 1., -1., 1.}; + nodes_.assign( nodes_init, nodes_init + N_ ); + shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); + } +}; + +class TriagP1 : public ElementType { +public: + TriagP1() { + parametric_ = true; + N_ = 3; + int nodes_init[] = {0., 0., 1., 0., 0., 1.}; + nodes_.assign( nodes_init, nodes_init + N_ ); + shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); + } +}; + +class LineP0 : public ElementType { +public: + LineP0() { + parametric_ = true; + N_ = 1; + double nodes_init[] = {0.}; + nodes_.assign( nodes_init, nodes_init + N_ ); + shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); + } +}; + +class LineP1 : public ElementType { +public: + LineP1() { + parametric_ = true; + N_ = 2; + double nodes_init[] = {-1., 1.}; + nodes_.assign( nodes_init, nodes_init + N_ ); + shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); + } +}; + +class LineP2 : public ElementType { +public: + LineP2() { + parametric_ = true; + N_ = 3; + double nodes_init[] = {-1., 1., 0.}; + nodes_.assign( nodes_init, nodes_init + N_ ); + shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); + } +}; + +class Structured1D : public ElementType { +public: + Structured1D( int N ) { + parametric_ = true; + N_ = N; + shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); + } +}; + +class Nodes : public eckit::Owned { +public: typedef eckit::SharedPtr Ptr; - public: - Nodes() - { - npts_ = 0; - nlev_ = 0; - nlon_ = 0; - nlat_ = 0; - nlev_ = 0; - nproma_ = 0; - nblk_ = 0; - } - size_t npts() const { return npts_; } - size_t nlev() const { return nlev_; } + +public: + Nodes() { + npts_ = 0; + nlev_ = 0; + nlon_ = 0; + nlat_ = 0; + nlev_ = 0; + nproma_ = 0; + nblk_ = 0; + } + size_t npts() const { return npts_; } + size_t nlev() const { return nlev_; } size_t nproma() const { return nproma_; } - size_t nblk() const { return nblk_; } - size_t nlon() const { return nlon_; } - size_t nlat() const { return nlat_; } - private: + size_t nblk() const { return nblk_; } + size_t nlon() const { return nlon_; } + size_t nlat() const { return nlat_; } + +private: size_t npts_; size_t nlev_; size_t nproma_; size_t nblk_; size_t nlon_; size_t nlat_; - }; - - enum IndexType { IDX_NOTUSED=-100, IDX_NODE=-1, IDX_LEVEL=-2, IDX_BLK=-3, IDX_NPROMA=-4, IDX_VAR=-5 }; - - +}; - class NewFunctionSpace - { - public: - - NewFunctionSpace() : nproma_(0), nb_nodes_(0), nblk_(0) {} +enum IndexType +{ + IDX_NOTUSED = -100, + IDX_NODE = -1, + IDX_LEVEL = -2, + IDX_BLK = -3, + IDX_NPROMA = -4, + IDX_VAR = -5 +}; + +class NewFunctionSpace { +public: + NewFunctionSpace() : nproma_( 0 ), nb_nodes_( 0 ), nblk_( 0 ) {} /// @brief Number of element types size_t nb_element_types() const { return nelem_per_type_.size(); } /// @brief Element type at index - const ElementType& element_type(size_t idx) const { ASSERT(idx - atlas::array::ArrayT create_field(int idx1=IDX_NOTUSED, int idx2=IDX_NOTUSED, int idx3=IDX_NOTUSED, int idx4=IDX_NOTUSED, int idx5=IDX_NOTUSED, int idx6=IDX_NOTUSED, 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)); - atlas::array::ArrayT field(shape); - return field; - } - - private: - - int range(int idx_type) const - { - switch( idx_type ) - { - case IDX_NODE: return nb_nodes(); - case IDX_LEVEL: return nb_levels(); - case IDX_BLK: return nblk(); - case IDX_NPROMA: return nproma(); - default: - if( idx_type>=0 ) return idx_type; - } - throw eckit::SeriousBug("idx_type not recognized"); - return 0; - } - - private: + void set_nodes( const Nodes& nodes ) { nodes_ = &nodes; } + + template + atlas::array::ArrayT create_field( int idx1 = IDX_NOTUSED, int idx2 = IDX_NOTUSED, + int idx3 = IDX_NOTUSED, int idx4 = IDX_NOTUSED, + int idx5 = IDX_NOTUSED, int idx6 = IDX_NOTUSED, + 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 ) ); + atlas::array::ArrayT field( shape ); + return field; + } + +private: + int range( int idx_type ) const { + switch ( idx_type ) { + case IDX_NODE: + return nb_nodes(); + case IDX_LEVEL: + return nb_levels(); + case IDX_BLK: + return nblk(); + case IDX_NPROMA: + return nproma(); + default: + if ( idx_type >= 0 ) return idx_type; + } + throw eckit::SeriousBug( "idx_type not recognized" ); + return 0; + } +private: /// @brief Lookup of element_type index by name - std::map index_; + std::map index_; /// @brief Reference to nodes Nodes const* nodes_; @@ -639,74 +548,65 @@ namespace test { size_t nb_owned_nodes_; size_t nb_owned_elements_; - }; +}; - - class Column : public ElementType // Really is a Elementtype in 3D - { - public: - Column(const ElementType::Ptr& horizontal, const ElementType::Ptr& vertical): - horizontal_(horizontal), - vertical_(vertical) - { - shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); +class Column : public ElementType // Really is a Elementtype in 3D +{ +public: + Column( const ElementType::Ptr& horizontal, const ElementType::Ptr& vertical ) : + horizontal_( horizontal ), + vertical_( vertical ) { + shape_function_ = ShapeFunction::Ptr( new ShapeFunction ); } - size_t N() const { return npts()*nlev(); } + size_t N() const { return npts() * nlev(); } size_t npts() const { return horizontal_->N(); } size_t nlev() const { return vertical_->N(); } - protected: + +protected: ElementType::Ptr horizontal_; ElementType::Ptr vertical_; - }; - - template< int NDIM > - std::vector< Polynomial > polynomial_basis(int order, double* points, int npts) - { - std::vector< Polynomial > basis(npts); - - Matrix vandermonde(npts,npts); - Matrix coefficients(npts,npts); - Matrix powers(npts,NDIM); - Matrix::Proxy pts(points,npts,NDIM); - if (NDIM==1) - { - size_t n(0); - for(size_t k=0; k<=order; ++k) - { - powers(n,0) = k; - ++n; - } - for (n=0; n +std::vector> polynomial_basis( int order, double* points, int npts ) { + std::vector> basis( npts ); + + Matrix vandermonde( npts, npts ); + Matrix coefficients( npts, npts ); + Matrix powers( npts, NDIM ); + Matrix::Proxy pts( points, npts, NDIM ); + if ( NDIM == 1 ) { + size_t n( 0 ); + for ( size_t k = 0; k <= order; ++k ) { + powers( n, 0 ) = k; + ++n; } - } - } - else if (NDIM==2) - { - size_t n(0); - for(size_t l=0; l<=order; ++l) { - for(size_t k=0; k<=order; ++k) { - powers(n,0) = k; - powers(n,1) = l; - ++n; + for ( n = 0; n < npts; ++n ) { + double x = pts( n, 0 ); + for ( size_t p = 0; p < npts; ++p ) { + double x_p = ( powers( p, 0 ) == 0. ? 1. : std::pow( x, powers( p, 0 ) ) ); + vandermonde( n, p ) = x_p; + } } - } - for (n=0; n( coefficients(n,i), pwr ) ); - } + for ( size_t n = 0; n < npts; ++n ) { + for ( size_t i = 0; i < npts; ++i ) { + for ( size_t d = 0; d < NDIM; ++d ) + pwr[d] = powers( i, d ); + basis[n].add( Mononomial( coefficients( n, i ), pwr ) ); + } } return basis; - } +} - template - IndexView make_IndexView(atlas::array::ArrayT& array, NewFunctionSpace& elements, int element_type_index) - { - IndexView view; - size_t offset=0; +template +IndexView make_IndexView( atlas::array::ArrayT& array, NewFunctionSpace& elements, + int element_type_index ) { + IndexView view; + size_t offset = 0; size_t strides[2]; size_t shape[2]; ASSERT( element_type_index < elements.nb_element_types() ); - ASSERT( array.shape(1) == elements.N_max() ); + ASSERT( array.shape( 1 ) == elements.N_max() ); - for( int i=0; i( array.data()+offset, strides, shape); - } - - - class Connectivity : public IndexView - { - Connectivity(NewFunctionSpace& elements, int element_type_index) - { + const ElementType& elem_type = elements.element_type( element_type_index ); + strides[0] = array.shape( 1 ); + strides[1] = 1; + shape[0] = elements.nb_elements_in_element_type( element_type_index ); + shape[1] = elem_type.N(); + return IndexView( array.data() + offset, strides, shape ); +} - } - }; +class Connectivity : public IndexView { + Connectivity( NewFunctionSpace& elements, int element_type_index ) {} +}; //----------------------------------------------------------------------------- -CASE( "test_functionspace" ) -{ - ElementType::Ptr point( new Point ); - ElementType::Ptr quad( new QuadP1 ); - ElementType::Ptr levels( new Structured1D(100) ); - - Column quad_column(quad,levels); - Column point_column(point,levels); - - //std::cout << quad->N() << std::endl; - //std::cout << levels->N() << std::endl; - DEBUG_VAR(quad_column.N()); - DEBUG_VAR(quad_column.nlev()); - DEBUG_VAR(quad_column.npts()); - - DEBUG_VAR(point_column.N()); - DEBUG_VAR(point_column.nlev()); - DEBUG_VAR(point_column.npts()); - - Nodes nodes; - - NewFunctionSpace fs; - fs.set_nb_nodes( 8 ); - fs.set_nproma( 4 ); - fs.set_nb_levels(100); - const ElementType& triags = fs.add_elements("TriagP1",2); - EXPECT( fs.nb_element_types()== 1 ); - EXPECT( fs.N_max() == 3 ); - EXPECT( fs.N_min() == 3 ); - EXPECT( fs.nb_elements() == 2 ); - const ElementType& quads = fs.add_elements("QuadP1",2); - EXPECT( fs.nb_element_types()== 2 ); - EXPECT( fs.N_max() == 4 ); - EXPECT( fs.N_min() == 3 ); - EXPECT( fs.nb_elements() == 4 ); - - /// Allocate array for all connectivity across all elements - atlas::array::ArrayT element_node_connectivity(fs.nb_elements(),fs.N_max()); - - /// Access the data across all elements - atlas::IndexView elem_connectivity(element_node_connectivity); - // --- Triangle 1 --- - elem_connectivity(0,0) = 1; - elem_connectivity(0,1) = 2; - elem_connectivity(0,2) = 3; elem_connectivity(0,3) = -1; - // --- Triangle 2--- - elem_connectivity(1,0) = 11; - elem_connectivity(1,1) = 12; - elem_connectivity(1,2) = 13; elem_connectivity(1,3) = -1; - // --- Quad 1 --- - elem_connectivity(2,0) = 21; - elem_connectivity(2,1) = 22; - elem_connectivity(2,2) = 23; - elem_connectivity(2,3) = 24; - // --- Quad 2 --- - elem_connectivity(3,0) = 31; - elem_connectivity(3,1) = 32; - elem_connectivity(3,2) = 33; - elem_connectivity(3,3) = 34; - - /// Access the data - atlas::IndexView triag_node_connectivity = make_IndexView(element_node_connectivity,fs,0); - EXPECT( triag_node_connectivity.shape(0) == 2 ); - EXPECT( triag_node_connectivity.shape(1) == 3 ); - EXPECT( triag_node_connectivity(0,0) == 1 ); - EXPECT( triag_node_connectivity(0,1) == 2 ); - EXPECT( triag_node_connectivity(0,2) == 3 ); - EXPECT( triag_node_connectivity(1,0) == 11 ); - EXPECT( triag_node_connectivity(1,1) == 12 ); - EXPECT( triag_node_connectivity(1,2) == 13 ); - - BOOST_CHECK_THROW( triag_node_connectivity(0,3), eckit::OutOfRange ); // should fail (OUT OF RANGE) - - atlas::IndexView quad_node_connectivity = make_IndexView(element_node_connectivity,fs,1); +CASE( "test_functionspace" ) { + ElementType::Ptr point( new Point ); + ElementType::Ptr quad( new QuadP1 ); + ElementType::Ptr levels( new Structured1D( 100 ) ); + + Column quad_column( quad, levels ); + Column point_column( point, levels ); + + // std::cout << quad->N() << std::endl; + // std::cout << levels->N() << std::endl; + DEBUG_VAR( quad_column.N() ); + DEBUG_VAR( quad_column.nlev() ); + DEBUG_VAR( quad_column.npts() ); + + DEBUG_VAR( point_column.N() ); + DEBUG_VAR( point_column.nlev() ); + DEBUG_VAR( point_column.npts() ); + + Nodes nodes; + + NewFunctionSpace fs; + fs.set_nb_nodes( 8 ); + fs.set_nproma( 4 ); + fs.set_nb_levels( 100 ); + const ElementType& triags = fs.add_elements( "TriagP1", 2 ); + EXPECT( fs.nb_element_types() == 1 ); + EXPECT( fs.N_max() == 3 ); + EXPECT( fs.N_min() == 3 ); + EXPECT( fs.nb_elements() == 2 ); + const ElementType& quads = fs.add_elements( "QuadP1", 2 ); + EXPECT( fs.nb_element_types() == 2 ); + EXPECT( fs.N_max() == 4 ); + EXPECT( fs.N_min() == 3 ); + EXPECT( fs.nb_elements() == 4 ); + + /// Allocate array for all connectivity across all elements + atlas::array::ArrayT element_node_connectivity( fs.nb_elements(), fs.N_max() ); + + /// Access the data across all elements + atlas::IndexView elem_connectivity( element_node_connectivity ); + // --- Triangle 1 --- + elem_connectivity( 0, 0 ) = 1; + elem_connectivity( 0, 1 ) = 2; + elem_connectivity( 0, 2 ) = 3; + elem_connectivity( 0, 3 ) = -1; + // --- Triangle 2--- + elem_connectivity( 1, 0 ) = 11; + elem_connectivity( 1, 1 ) = 12; + elem_connectivity( 1, 2 ) = 13; + elem_connectivity( 1, 3 ) = -1; + // --- Quad 1 --- + elem_connectivity( 2, 0 ) = 21; + elem_connectivity( 2, 1 ) = 22; + elem_connectivity( 2, 2 ) = 23; + elem_connectivity( 2, 3 ) = 24; + // --- Quad 2 --- + elem_connectivity( 3, 0 ) = 31; + elem_connectivity( 3, 1 ) = 32; + elem_connectivity( 3, 2 ) = 33; + elem_connectivity( 3, 3 ) = 34; + + /// Access the data + atlas::IndexView triag_node_connectivity = make_IndexView( element_node_connectivity, fs, 0 ); + EXPECT( triag_node_connectivity.shape( 0 ) == 2 ); + EXPECT( triag_node_connectivity.shape( 1 ) == 3 ); + EXPECT( triag_node_connectivity( 0, 0 ) == 1 ); + EXPECT( triag_node_connectivity( 0, 1 ) == 2 ); + EXPECT( triag_node_connectivity( 0, 2 ) == 3 ); + EXPECT( triag_node_connectivity( 1, 0 ) == 11 ); + EXPECT( triag_node_connectivity( 1, 1 ) == 12 ); + EXPECT( triag_node_connectivity( 1, 2 ) == 13 ); + + BOOST_CHECK_THROW( triag_node_connectivity( 0, 3 ), + eckit::OutOfRange ); // should fail (OUT OF RANGE) + + atlas::IndexView quad_node_connectivity = make_IndexView( element_node_connectivity, fs, 1 ); EXPECT( quad_node_connectivity.shape(0 == 2 ); EXPECT( quad_node_connectivity.shape(1 == 4 ); EXPECT( quad_node_connectivity(0,0 == 21 ); @@ -867,84 +761,84 @@ CASE( "test_functionspace" ) EXPECT( wind_uv_ifs.shape(1) == fs.nb_levels() ); EXPECT( wind_uv_ifs.shape(2) == 2 ); EXPECT( wind_uv_ifs.shape(3) == fs.nblk() ); - } +CASE( "test_polynomial" ) { + typedef Polynomial<2> polynomial_type; + typedef polynomial_type::monomial_type monomial_type; + polynomial_type p; -CASE( "test_polynomial" ) -{ - typedef Polynomial<2> polynomial_type; - typedef polynomial_type::monomial_type monomial_type; + p.add( monomial_type( 3., 0, 0 ) ); + p.add( monomial_type( 1., 1, 0 ) ); + p.add( monomial_type( 1., 2, 0 ) ); + DEBUG_VAR( p( 2, 2 ) ); + polynomial_type dpdx = p.deriv( 0 ); + DEBUG_VAR( dpdx( 2, 2 ) ); - polynomial_type p; + polynomial_type dpdy = p.deriv( 1 ); + DEBUG_VAR( dpdy( 2, 2 ) ); - p.add( monomial_type( 3., 0,0 ) ); - p.add( monomial_type( 1., 1,0 ) ); - p.add( monomial_type( 1., 2,0 ) ); - DEBUG_VAR(p(2,2)); + std::vector grad = p.grad(); - polynomial_type dpdx = p.deriv(0); - DEBUG_VAR(dpdx(2,2)); + std::vector pvec( 2, p ); + polynomial_type div = polynomial_type::div( pvec ); + DEBUG_VAR( div( 2, 2 ) ); - polynomial_type dpdy = p.deriv(1); - DEBUG_VAR(dpdy(2,2)); + DEBUG_VAR( polynomial_type::curl_z( grad )( 2, 2 ) ); - std::vector grad = p.grad(); + typedef std::vector> PolynomialBasis1D; + typedef std::vector> PolynomialBasis2D; - std::vector pvec(2,p); - polynomial_type div = polynomial_type::div(pvec); - DEBUG_VAR(div(2,2)); + Matrix m; + // EXPECT( m.data_ == NULL ); + // EXPECT( m.nr_ == 0 ); + // EXPECT( m.nc_ == 0 ); + m.resize( 2, 3 ); - DEBUG_VAR( polynomial_type::curl_z(grad)(2,2) ); + EXPECT( m.size() == 6 ); + EXPECT( m.rows() == 2 ); + EXPECT( m.cols() == 3 ); - typedef std::vector< Polynomial<1> > PolynomialBasis1D; - typedef std::vector< Polynomial<2> > PolynomialBasis2D; + m( 0, 0 ) = 0; + m( 0, 1 ) = 2; + m( 0, 2 ) = 4; + m( 1, 0 ) = 1; + m( 1, 1 ) = 3; + m( 1, 2 ) = 5; + m *= 10; - Matrix m; -// EXPECT( m.data_ == NULL ); -// EXPECT( m.nr_ == 0 ); -// EXPECT( m.nc_ == 0 ); - m.resize(2,3); + Matrix b = m + m; - EXPECT(m.size() == 6); - EXPECT(m.rows() == 2); - EXPECT(m.cols() == 3); + std::cout << "m = \n" << b << std::endl; - m(0,0) = 0; m(0,1) = 2; m(0,2) = 4; - m(1,0) = 1; m(1,1) = 3; m(1,2) = 5; + double line_pts[] = {-1., 1.}; + int line_npts = 2; + PolynomialBasis1D line_basis = polynomial_basis<1>( 1, line_pts, line_npts ); + for ( size_t n = 0; n < line_npts; ++n ) + DEBUG( n << ": " << line_basis[n]( -1. ) << " " << line_basis[n]( +1. ) ); - m *= 10; + double quad_pts[] = {-1, 1., 1., -1, -1., -1., 1., 1.}; + int quad_npts = 4; + PolynomialBasis2D quad_basis = polynomial_basis<2>( 1, quad_pts, quad_npts ); - Matrix b = m + m; + for ( size_t n = 0; n < quad_npts; ++n ) + DEBUG( n << ": " << quad_basis[n]( -1., -1. ) << " " << quad_basis[n]( 1., -1. ) << " " + << quad_basis[n]( 1., 1. ) << " " << quad_basis[n]( -1., 1. ) ); - std::cout << "m = \n" << b << std::endl; + RowVector vr( 3 ); + vr( 0 ) = 0; + vr( 1 ) = 1; + vr( 2 ) = 2; - double line_pts[] = {-1. , 1.}; - int line_npts = 2; - PolynomialBasis1D line_basis = polynomial_basis<1>(1,line_pts,line_npts); - for( size_t n=0; n(1,quad_pts,quad_npts); - - for( size_t n=0; n vr(3); - vr(0) = 0; vr(1) = 1; vr(2) = 2; - - ColVector vc(3); - vc(0) = 0; vc(1) = 1; vc(2) = 2; - - std::cout << vr << "\n" << vc << "\n\n" << vr*vc << std::endl; + ColVector vc( 3 ); + vc( 0 ) = 0; + vc( 1 ) = 1; + vc( 2 ) = 2; + std::cout << vr << "\n" << vc << "\n\n" << vr * vc << std::endl; } //----------------------------------------------------------------------------- @@ -952,7 +846,6 @@ CASE( "test_polynomial" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/numerics/test_fvm_nabla.cc b/src/tests/numerics/test_fvm_nabla.cc index d4feabf30..a5e5e0182 100644 --- a/src/tests/numerics/test_fvm_nabla.cc +++ b/src/tests/numerics/test_fvm_nabla.cc @@ -4,31 +4,32 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include #include -#include "atlas/library/Library.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/grid/Grid.h" -#include "atlas/util/CoordinateEnums.h" -#include "atlas/meshgenerator/StructuredMeshGenerator.h" +#include "atlas/grid/Partitioner.h" +#include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/numerics/fvm/Method.h" +#include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/numerics/Nabla.h" -#include "atlas/output/Gmsh.h" +#include "atlas/numerics/fvm/Method.h" #include "atlas/option.h" +#include "atlas/output/Gmsh.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/util/Config.h" #include "atlas/util/Constants.h" +#include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" -#include "atlas/grid/Partitioner.h" #include "tests/AtlasTestEnvironment.h" @@ -42,309 +43,285 @@ namespace test { //----------------------------------------------------------------------------- -double dual_volume(const Mesh& mesh) -{ - const mesh::Nodes& nodes = mesh.nodes(); - int nb_nodes = nodes.size(); - const array::ArrayView dual_volumes = array::make_view( nodes.field("dual_volumes") ); - const array::ArrayView is_ghost = array::make_view( nodes.ghost() ); - double area=0; - for( int node=0; node dual_volumes = array::make_view( nodes.field( "dual_volumes" ) ); + 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 ); } } - } - mpi::comm().allReduceInPlace(area, eckit::mpi::sum()); + mpi::comm().allReduceInPlace( area, eckit::mpi::sum() ); - return area; + return area; } - /// @brief Compute magnitude of flow with rotation-angle beta /// (beta=0 --> zonal, beta=pi/2 --> meridional) -void rotated_flow(const fvm::Method& fvm, Field& field, const double& beta) -{ - const double radius = fvm.radius(); - const double USCAL = 20.; - const double pvel = USCAL/radius; - const double deg2rad = M_PI/180.; - - array::ArrayView lonlat_deg = array::make_view(fvm.mesh().nodes().lonlat()); - array::ArrayView var = array::make_view(field); - - size_t nnodes = fvm.mesh().nodes().size(); - for( size_t jnode=0; jnode lonlat_deg = array::make_view( fvm.mesh().nodes().lonlat() ); + array::ArrayView var = array::make_view( field ); + + size_t nnodes = fvm.mesh().nodes().size(); + for ( size_t jnode = 0; jnode < nnodes; ++jnode ) { + double x = lonlat_deg( jnode, LON ) * deg2rad; + double y = lonlat_deg( jnode, LAT ) * deg2rad; + 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 ( size_t jlev = 0; jlev < field.levels(); ++jlev ) { + var( jnode, jlev, LON ) = Ux; + var( jnode, jlev, LAT ) = Uy; + } + } } /// @brief Compute magnitude of flow with rotation-angle beta /// (beta=0 --> zonal, beta=pi/2 --> meridional) -void rotated_flow_magnitude(const fvm::Method& fvm, Field& field, const double& beta) -{ - const double radius = fvm.radius(); - const double USCAL = 20.; - const double pvel = USCAL/radius; - const double deg2rad = M_PI/180.; - - auto lonlat_deg = array::make_view (fvm.mesh().nodes().lonlat()); - auto var = array::make_view (field); - - size_t nnodes = fvm.mesh().nodes().size(); - for( size_t jnode=0; jnode( fvm.mesh().nodes().lonlat() ); + auto var = array::make_view( field ); + + size_t nnodes = fvm.mesh().nodes().size(); + for ( size_t jnode = 0; jnode < nnodes; ++jnode ) { + double x = lonlat_deg( jnode, LON ) * deg2rad; + double y = lonlat_deg( jnode, LAT ) * deg2rad; + 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 ( size_t jlev = 0; jlev < field.levels(); ++jlev ) + var( jnode, jlev ) = std::sqrt( Ux * Ux + Uy * Uy ); + } } -static std::string griduid() { return "Slat80"; } - +static std::string griduid() { + return "Slat80"; +} //----------------------------------------------------------------------------- -CASE( "test_factory" ) -{ - EXPECT( NablaFactory::has("fvm") ); +CASE( "test_factory" ) { + EXPECT( NablaFactory::has( "fvm" ) ); } -CASE( "test_build" ) -{ - Log::info() << "test_build" << std::endl; - MeshGenerator meshgenerator ("structured" ); - Mesh mesh = meshgenerator.generate( Grid("O16") ); - const double R = util::Earth::radiusInMeters(); - fvm::Method fvm(mesh,util::Config("radius",R)); - Nabla nabla( fvm ); - - double spherical_area = 360.*180.; - EXPECT(eckit::types::is_approximately_equal(dual_volume(mesh),spherical_area,5.0)); +CASE( "test_build" ) { + Log::info() << "test_build" << std::endl; + MeshGenerator meshgenerator( "structured" ); + Mesh mesh = meshgenerator.generate( Grid( "O16" ) ); + const double R = util::Earth::radiusInMeters(); + fvm::Method fvm( mesh, util::Config( "radius", R ) ); + Nabla nabla( fvm ); + double spherical_area = 360. * 180.; + EXPECT( eckit::types::is_approximately_equal( dual_volume( mesh ), spherical_area, 5.0 ) ); } +CASE( "test_grad" ) { + Log::info() << "test_grad" << std::endl; + size_t nlev = 1; + auto radius = option::radius( "Earth" ); + Grid grid( griduid() ); + MeshGenerator meshgenerator( "structured" ); + Mesh mesh = meshgenerator.generate( grid, Distribution( grid, Partitioner( "equal_regions" ) ) ); + fvm::Method fvm( mesh, radius | option::levels( nlev ) ); + Nabla nabla( fvm ); + + size_t nnodes = mesh.nodes().size(); + + FieldSet fields; + fields.add( fvm.node_columns().createField( option::name( "scalar" ) ) ); + fields.add( fvm.node_columns().createField( option::name( "rscalar" ) ) ); + fields.add( fvm.node_columns().createField( option::name( "grad" ) | option::variables( 2 ) ) ); + fields.add( fvm.node_columns().createField( option::name( "rgrad" ) | option::variables( 2 ) ) ); + fields.add( fvm.node_columns().createField( option::name( "xder" ) ) ); + fields.add( fvm.node_columns().createField( option::name( "yder" ) ) ); + fields.add( fvm.node_columns().createField( option::name( "rxder" ) ) ); + fields.add( fvm.node_columns().createField( option::name( "ryder" ) ) ); + + EXPECT( fields["scalar"].rank() == 2 ); + EXPECT( fields["grad"].rank() == 3 ); + EXPECT( fields["scalar"].levels() == nlev ); + EXPECT( fields["grad"].levels() == nlev ); + // fields.add( fvm.createField("exact_yder",nlev) ); + + // const double deg2rad = M_PI/180.; + // array::ArrayView var( fields["scalar"] ); + //// array::ArrayView exact_yder( fields["exact_yder"] ); + // for( size_t jnode=0; jnode< nnodes ; ++jnode ) + // { + // const double y = lonlat(jnode,LAT) * deg2rad ; + + // for(size_t jlev = 0; jlev < nlev; ++jlev) { + // var(jnode,jlev) = std::sin(4.*y); + //// exact_yder(jnode,jlev) = 4.*std::cos(4.*y)/radius; + // } + // } + + rotated_flow_magnitude( fvm, fields["scalar"], 0. ); + rotated_flow_magnitude( fvm, fields["rscalar"], M_PI_2 * 0.75 ); + + nabla.gradient( fields["scalar"], fields["grad"] ); + nabla.gradient( fields["rscalar"], fields["rgrad"] ); + auto xder = array::make_view( fields["xder"] ); + auto yder = array::make_view( fields["yder"] ); + auto rxder = array::make_view( fields["rxder"] ); + auto ryder = array::make_view( fields["ryder"] ); + const auto grad = array::make_view( fields["grad"] ); + const auto rgrad = array::make_view( fields["rgrad"] ); + for ( size_t jnode = 0; jnode < nnodes; ++jnode ) { + for ( size_t jlev = 0; jlev < nlev; ++jlev ) { + xder( jnode, jlev ) = grad( jnode, jlev, LON ); + yder( jnode, jlev ) = grad( jnode, jlev, LAT ); + rxder( jnode, jlev ) = rgrad( jnode, jlev, LON ); + ryder( jnode, jlev ) = rgrad( jnode, jlev, LAT ); + } + } -CASE( "test_grad" ) -{ - Log::info() << "test_grad" << std::endl; - size_t nlev = 1; - auto radius = option::radius("Earth"); - Grid grid(griduid()); - MeshGenerator meshgenerator("structured"); - Mesh mesh = meshgenerator.generate(grid, Distribution(grid,Partitioner("equal_regions")) ); - fvm::Method fvm(mesh, radius | option::levels(nlev) ); - Nabla nabla( fvm ); - - size_t nnodes = mesh.nodes().size(); - - FieldSet fields; - fields.add( fvm.node_columns().createField(option::name("scalar") ) ); - fields.add( fvm.node_columns().createField(option::name("rscalar") ) ); - fields.add( fvm.node_columns().createField(option::name("grad") | option::variables(2) ) ); - fields.add( fvm.node_columns().createField(option::name("rgrad") | option::variables(2) ) ); - fields.add( fvm.node_columns().createField(option::name("xder") ) ); - fields.add( fvm.node_columns().createField(option::name("yder") ) ); - fields.add( fvm.node_columns().createField(option::name("rxder") ) ); - fields.add( fvm.node_columns().createField(option::name("ryder") ) ); - - EXPECT( fields["scalar"].rank() == 2 ); - EXPECT( fields["grad"]. rank() == 3 ); - EXPECT( fields["scalar"].levels() == nlev ); - EXPECT( fields["grad"]. levels() == nlev ); - // fields.add( fvm.createField("exact_yder",nlev) ); - -// const double deg2rad = M_PI/180.; -// array::ArrayView var( fields["scalar"] ); -//// array::ArrayView exact_yder( fields["exact_yder"] ); -// for( size_t jnode=0; jnode< nnodes ; ++jnode ) -// { -// const double y = lonlat(jnode,LAT) * deg2rad ; - -// for(size_t jlev = 0; jlev < nlev; ++jlev) { -// var(jnode,jlev) = std::sin(4.*y); -//// exact_yder(jnode,jlev) = 4.*std::cos(4.*y)/radius; -// } -// } - - rotated_flow_magnitude(fvm,fields["scalar"],0.); - rotated_flow_magnitude(fvm,fields["rscalar"],M_PI_2*0.75); - - nabla.gradient(fields["scalar"],fields["grad"]); - nabla.gradient(fields["rscalar"],fields["rgrad"]); - auto xder = array::make_view( fields["xder"] ); - auto yder = array::make_view( fields["yder"] ); - auto rxder = array::make_view( fields["rxder"] ); - auto ryder = array::make_view( fields["ryder"] ); - const auto grad = array::make_view( fields["grad"] ); - const auto rgrad = array::make_view( fields["rgrad"] ); - for( size_t jnode=0; jnode< nnodes ; ++jnode ) - { - for(size_t jlev = 0; jlev < nlev; ++jlev) { - xder(jnode,jlev) = grad(jnode,jlev,LON); - yder(jnode,jlev) = grad(jnode,jlev,LAT); - rxder(jnode,jlev) = rgrad(jnode,jlev,LON); - ryder(jnode,jlev) = rgrad(jnode,jlev,LAT); + // output to gmsh + { + fvm.node_columns().haloExchange( fields ); + output::Gmsh( grid.name() + ".msh" ).write( mesh ); + output::Gmsh gmsh_fields( grid.name() + "_fields.msh" ); + gmsh_fields.write( fields["scalar"] ); + gmsh_fields.write( fields["xder"] ); + gmsh_fields.write( fields["yder"] ); + gmsh_fields.write( fields["rscalar"] ); + gmsh_fields.write( fields["rxder"] ); + gmsh_fields.write( fields["ryder"] ); } - } - - // output to gmsh - { - fvm.node_columns().haloExchange(fields); - output::Gmsh(grid.name()+".msh").write(mesh); - output::Gmsh gmsh_fields(grid.name()+"_fields.msh"); - gmsh_fields.write(fields["scalar"]); - gmsh_fields.write(fields["xder"]); - gmsh_fields.write(fields["yder"]); - gmsh_fields.write(fields["rscalar"]); - gmsh_fields.write(fields["rxder"]); - gmsh_fields.write(fields["ryder"]); - } } +CASE( "test_div" ) { + Log::info() << "test_div" << std::endl; + size_t nlev = 1; + const double radius = util::Earth::radiusInMeters(); + // const double radius = 1.; + Grid grid( griduid() ); + MeshGenerator meshgenerator( "structured" ); + Mesh mesh = meshgenerator.generate( grid, Distribution( grid, Partitioner( "equal_regions" ) ) ); + fvm::Method fvm( mesh, util::Config( "radius", radius ) | option::levels( nlev ) ); + Nabla nabla( fvm ); + + FieldSet fields; + fields.add( fvm.node_columns().createField( option::name( "wind" ) | option::variables( 2 ) ) ); + fields.add( fvm.node_columns().createField( option::name( "div" ) ) ); -CASE( "test_div" ) -{ - Log::info() << "test_div" << std::endl; - size_t nlev = 1; - const double radius = util::Earth::radiusInMeters(); -// const double radius = 1.; - Grid grid(griduid()); - MeshGenerator meshgenerator("structured"); - Mesh mesh = meshgenerator.generate(grid, Distribution(grid,Partitioner("equal_regions")) ); - fvm::Method fvm(mesh, util::Config("radius",radius) | option::levels(nlev) ); - Nabla nabla(fvm); - - FieldSet fields; - fields.add( fvm.node_columns().createField(option::name("wind") | option::variables(2) ) ); - fields.add( fvm.node_columns().createField(option::name("div") ) ); - - rotated_flow(fvm,fields["wind"],M_PI_2*0.75); - - nabla.divergence(fields["wind"],fields["div"]); - - // output to gmsh - { - fvm.node_columns().haloExchange(fields); - output::Gmsh gmsh (grid.name()+"_fields.msh","a"); - gmsh.write(fields["wind"]); - gmsh.write(fields["div"]); - } + rotated_flow( fvm, fields["wind"], M_PI_2 * 0.75 ); + + nabla.divergence( fields["wind"], fields["div"] ); + + // output to gmsh + { + fvm.node_columns().haloExchange( fields ); + output::Gmsh gmsh( grid.name() + "_fields.msh", "a" ); + gmsh.write( fields["wind"] ); + gmsh.write( fields["div"] ); + } } -CASE( "test_curl" ) -{ - Log::info() << "test_curl" << std::endl; - size_t nlev = 1; - const double radius = util::Earth::radiusInMeters(); -// const double radius = 1.; - Grid grid(griduid()); - MeshGenerator meshgenerator("structured"); - Mesh mesh = meshgenerator.generate(grid, Distribution(grid,Partitioner("equal_regions")) ); - fvm::Method fvm(mesh, util::Config("radius",radius) | option::levels(nlev) ); - Nabla nabla( fvm ); - - FieldSet fields; - fields.add( fvm.node_columns().createField( option::name("wind") | option::variables(2) ) ); - fields.add( fvm.node_columns().createField( option::name("vor") ) ); - - rotated_flow(fvm,fields["wind"],M_PI_2*0.75); - - nabla.curl(fields["wind"],fields["vor"]); - - fields.add( fvm.node_columns().createField( option::name("windgrad") | option::variables(2*2) ) ); - nabla.gradient(fields["wind"],fields["windgrad"]); - - fields.add( fvm.node_columns().createField( option::name("windX") | option::levels(false) ) ); - fields.add( fvm.node_columns().createField( option::name("windY") | option::levels(false) ) ); - fields.add( fvm.node_columns().createField( option::name("windXgradX") ) ); - fields.add( fvm.node_columns().createField( option::name("windXgradY") ) ); - fields.add( fvm.node_columns().createField( option::name("windYgradX") ) ); - fields.add( fvm.node_columns().createField( option::name("windYgradY") ) ); - auto wind = array::make_view(fields["wind"]); - auto windgrad = array::make_view(fields["windgrad"]); - - auto windX = array::make_view(fields["windX"]); - auto windY = array::make_view(fields["windY"]); - auto windXgradX = array::make_view(fields["windXgradX"]); - auto windXgradY = array::make_view(fields["windXgradY"]); - auto windYgradX = array::make_view(fields["windYgradX"]); - auto windYgradY = array::make_view(fields["windYgradY"]); - for( size_t j=0; j( option::name( "wind" ) | option::variables( 2 ) ) ); + fields.add( fvm.node_columns().createField( option::name( "vor" ) ) ); + + rotated_flow( fvm, fields["wind"], M_PI_2 * 0.75 ); + + nabla.curl( fields["wind"], fields["vor"] ); + + fields.add( fvm.node_columns().createField( option::name( "windgrad" ) | option::variables( 2 * 2 ) ) ); + nabla.gradient( fields["wind"], fields["windgrad"] ); + + fields.add( fvm.node_columns().createField( option::name( "windX" ) | option::levels( false ) ) ); + fields.add( fvm.node_columns().createField( option::name( "windY" ) | option::levels( false ) ) ); + fields.add( fvm.node_columns().createField( option::name( "windXgradX" ) ) ); + fields.add( fvm.node_columns().createField( option::name( "windXgradY" ) ) ); + fields.add( fvm.node_columns().createField( option::name( "windYgradX" ) ) ); + fields.add( fvm.node_columns().createField( option::name( "windYgradY" ) ) ); + auto wind = array::make_view( fields["wind"] ); + auto windgrad = array::make_view( fields["windgrad"] ); + + auto windX = array::make_view( fields["windX"] ); + auto windY = array::make_view( fields["windY"] ); + auto windXgradX = array::make_view( fields["windXgradX"] ); + auto windXgradY = array::make_view( fields["windXgradY"] ); + auto windYgradX = array::make_view( fields["windYgradX"] ); + auto windYgradY = array::make_view( fields["windYgradY"] ); + for ( size_t j = 0; j < windX.size(); ++j ) { + static const idx_t lev0 = 0; + static const idx_t XdX = XX * 2 + XX; + static const idx_t XdY = XX * 2 + YY; + static const idx_t YdX = YY * 2 + XX; + static const idx_t YdY = YY * 2 + YY; + windX( j ) = wind( j, lev0, XX ); + windY( j ) = wind( j, lev0, YY ); + windXgradX( j, lev0 ) = windgrad( j, lev0, XdX ); + windXgradY( j, lev0 ) = windgrad( j, lev0, XdY ); + windYgradX( j, lev0 ) = windgrad( j, lev0, YdX ); + windYgradY( j, lev0 ) = windgrad( j, lev0, YdY ); + } + // output to gmsh + { + fvm.node_columns().haloExchange( fields ); + output::Gmsh gmsh( grid.name() + "_fields.msh", "a" ); + gmsh.write( fields["vor"] ); + gmsh.write( fields["windX"] ); + gmsh.write( fields["windXgradX"] ); + gmsh.write( fields["windXgradY"] ); + gmsh.write( fields["windY"] ); + gmsh.write( fields["windYgradX"] ); + gmsh.write( fields["windYgradY"] ); + gmsh.write( fields["windgrad"] ); + } +} +CASE( "test_lapl" ) { + Log::info() << "test_lapl" << std::endl; + size_t nlev = 1; + const double radius = util::Earth::radiusInMeters(); + // const double radius = 1.; + Grid grid( griduid() ); + MeshGenerator meshgenerator( "structured" ); + Mesh mesh = meshgenerator.generate( grid, Distribution( grid, Partitioner( "equal_regions" ) ) ); + fvm::Method fvm( mesh, util::Config( "radius", radius ) | option::levels( nlev ) ); + Nabla nabla( fvm ); + FieldSet fields; + fields.add( fvm.node_columns().createField( option::name( "scal" ) ) ); + fields.add( fvm.node_columns().createField( option::name( "lapl" ) ) ); + rotated_flow_magnitude( fvm, fields["scal"], M_PI_2 * 0.75 ); -} + nabla.laplacian( fields["scal"], fields["lapl"] ); -CASE( "test_lapl" ) -{ - Log::info() << "test_lapl" << std::endl; - size_t nlev = 1; - const double radius = util::Earth::radiusInMeters(); -// const double radius = 1.; - Grid grid(griduid()); - MeshGenerator meshgenerator("structured"); - Mesh mesh = meshgenerator.generate(grid, Distribution(grid,Partitioner("equal_regions")) ); - fvm::Method fvm(mesh, util::Config("radius",radius) | option::levels(nlev) ); - Nabla nabla( fvm ); - - FieldSet fields; - fields.add( fvm.node_columns().createField(option::name("scal") ) ); - fields.add( fvm.node_columns().createField(option::name("lapl") ) ); - - rotated_flow_magnitude(fvm,fields["scal"],M_PI_2*0.75); - - nabla.laplacian(fields["scal"],fields["lapl"]); - - // output to gmsh - { - fvm.node_columns().haloExchange(fields); - output::Gmsh gmsh(grid.name()+"_fields.msh","a"); - gmsh.write(fields["lapl"]); - } + // output to gmsh + { + fvm.node_columns().haloExchange( fields ); + output::Gmsh gmsh( grid.name() + "_fields.msh", "a" ); + gmsh.write( fields["lapl"] ); + } } //----------------------------------------------------------------------------- @@ -352,7 +329,6 @@ CASE( "test_lapl" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/parallel/test_gather.cc b/src/tests/parallel/test_gather.cc index 35377d6f9..db7d1f6f2 100644 --- a/src/tests/parallel/test_gather.cc +++ b/src/tests/parallel/test_gather.cc @@ -4,21 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include #include #include +#include -#include "eckit/utils/Translator.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/library/config.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" +#include "atlas/library/config.h" #include "atlas/parallel/GatherScatter.h" +#include "atlas/parallel/mpi/mpi.h" +#include "eckit/utils/Translator.h" #include "tests/AtlasTestEnvironment.h" @@ -30,184 +31,177 @@ namespace test { //----------------------------------------------------------------------------- -template -std::vector vec( const T (&list)[N] ) -{ - return std::vector(list,list+N); +template +std::vector vec( const T ( &list )[N] ) { + return std::vector( list, list + N ); } struct Fixture { - Fixture() - { - int nnodes_c[] = {6, 6, 7}; nb_nodes = vec(nnodes_c); - Nl = nb_nodes[mpi::comm().rank()]; - switch( mpi::comm().rank() ) - { - case 0: - { //./----> extra ghost point with nonstandard gidx - int part_c[] = {2,0,0,0,1,2 }; part = vec(part_c); - int ridx_c[] = {4,1,2,3,1,3 }; ridx = vec(ridx_c); - gidx_t gidx_c[] = {9,1,2,3,4,20}; gidx = vec(gidx_c); - break; - } - case 1: - { - int part_c[] = {0,1,1,1,2,2}; part = vec(part_c); - int ridx_c[] = {3,1,2,3,2,3}; ridx = vec(ridx_c); - gidx_t gidx_c[] = {3,4,5,6,7,8}; gidx = vec(gidx_c); - break; - } - case 2: - { - int part_c[] = {1,1,2,2,2,0,0}; part = vec(part_c); - int ridx_c[] = {2,3,2,3,4,1,2}; ridx = vec(ridx_c); - gidx_t gidx_c[] = {5,6,7,8,9,1,2}; gidx = vec(gidx_c); - break; - } + Fixture() { + int nnodes_c[] = {6, 6, 7}; + nb_nodes = vec( nnodes_c ); + Nl = nb_nodes[mpi::comm().rank()]; + switch ( mpi::comm().rank() ) { + case 0: { //./----> extra ghost point with nonstandard gidx + int part_c[] = {2, 0, 0, 0, 1, 2}; + part = vec( part_c ); + int ridx_c[] = {4, 1, 2, 3, 1, 3}; + ridx = vec( ridx_c ); + gidx_t gidx_c[] = {9, 1, 2, 3, 4, 20}; + gidx = vec( gidx_c ); + break; + } + case 1: { + int part_c[] = {0, 1, 1, 1, 2, 2}; + part = vec( part_c ); + int ridx_c[] = {3, 1, 2, 3, 2, 3}; + ridx = vec( ridx_c ); + gidx_t gidx_c[] = {3, 4, 5, 6, 7, 8}; + gidx = vec( gidx_c ); + break; + } + case 2: { + int part_c[] = {1, 1, 2, 2, 2, 0, 0}; + part = vec( part_c ); + int ridx_c[] = {2, 3, 2, 3, 4, 1, 2}; + ridx = vec( ridx_c ); + gidx_t gidx_c[] = {5, 6, 7, 8, 9, 1, 2}; + gidx = vec( gidx_c ); + break; + } + } + gather_scatter.setup( part.data(), ridx.data(), 0, gidx.data(), Nl ); } - gather_scatter.setup(part.data(),ridx.data(),0,gidx.data(),Nl); - } - parallel::GatherScatter gather_scatter; - std::vector nb_nodes; - std::vector part; - std::vector ridx; - std::vector gidx; - - int Nl; - size_t root; - - int Ng() { return mpi::comm().rank() == root ? gather_scatter.glb_dof() : 0; } -}; - -//----------------------------------------------------------------------------- + parallel::GatherScatter gather_scatter; + std::vector nb_nodes; + std::vector part; + std::vector ridx; + std::vector gidx; -CASE("test_gather") { + int Nl; + size_t root; - SETUP("Fixture") { - Fixture f; - - SECTION( "test_gather_rank0" ) - { - for( f.root=0; f.root loc(f.Nl); - std::vector glb(f.Ng()); + int Ng() { return mpi::comm().rank() == root ? gather_scatter.glb_dof() : 0; } +}; - for( int j=0; j loc( f.Nl ); + std::vector glb( f.Ng() ); -#if 1 - SECTION( "test_gather_rank1_deprecated" ) - { - for( f.root=0; f.root loc(f.Nl,2); - array::ArrayT glb(f.Ng(),2); - array::ArrayT glb1(f.Ng(),1); - array::ArrayT glb2(f.Ng(),1); - array::ArrayView locv = array::make_view(loc); - for( int j=0; j(), loc_strides, loc_extents, 2, - glb.data(), glb_strides, glb_extents, 2, f.root ); - } - if( mpi::comm().rank() == f.root ) - { - auto glbv = array::make_view(glb); - POD glb_c[] = { 10,100, 20,200, 30,300, 40,400, 50,500, 60,600, 70,700, 80,800, 90,900 }; - size_t c(0); - for( size_t i=0; i(), loc_strides, loc_extents, 2, - glb1.data(), glb_strides, glb_extents, 2, f.root ); - } - if( mpi::comm().rank() == f.root ) - { - auto glbv = array::make_view(glb1); - POD glb1_c[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90 }; - size_t c(0); - for( size_t i=0; i()+1, loc_strides, loc_extents, 1, - glb2.data(), glb_strides, glb_extents, 1, f.root ); - } - if( mpi::comm().rank() == f.root ) - { - auto glbv = array::make_view(glb2); - POD glb2_c[] = { 100, 200, 300, 400, 500, 600, 700, 800, 900 }; - size_t c(0); - for( size_t i=0; i loc( f.Nl, 2 ); + array::ArrayT glb( f.Ng(), 2 ); + array::ArrayT glb1( f.Ng(), 1 ); + array::ArrayT glb2( f.Ng(), 1 ); + array::ArrayView locv = array::make_view( loc ); + for ( int j = 0; j < f.Nl; ++j ) { + locv( j, 0 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 10 ); + locv( j, 1 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 100 ); + } + + // Gather complete field + { + size_t loc_strides[] = {loc.stride( 0 ), loc.stride( 1 )}; + size_t loc_extents[] = {1, loc.shape( 1 )}; + size_t glb_strides[] = {glb.stride( 0 ), glb.stride( 1 )}; + size_t glb_extents[] = {1, glb.shape( 1 )}; + + f.gather_scatter.gather( loc.data(), loc_strides, loc_extents, 2, glb.data(), glb_strides, + glb_extents, 2, f.root ); + } + if ( mpi::comm().rank() == f.root ) { + auto glbv = array::make_view( glb ); + POD glb_c[] = {10, 100, 20, 200, 30, 300, 40, 400, 50, 500, 60, 600, 70, 700, 80, 800, 90, 900}; + size_t c( 0 ); + for ( size_t i = 0; i < glb.shape( 0 ); ++i ) { + for ( size_t j = 0; j < glb.shape( 1 ); ++j ) { + EXPECT( glbv( i, j ) == glb_c[c++] ); + } + } + } + + // Gather only first component + { + size_t loc_strides[] = {loc.stride( 0 ), 2}; + size_t loc_extents[] = {1, 1}; + size_t glb_strides[] = {glb1.stride( 0 ), glb1.stride( 1 )}; + size_t glb_extents[] = {1, glb1.shape( 1 )}; + + f.gather_scatter.gather( loc.data(), loc_strides, loc_extents, 2, glb1.data(), + glb_strides, glb_extents, 2, f.root ); + } + if ( mpi::comm().rank() == f.root ) { + auto glbv = array::make_view( glb1 ); + POD glb1_c[] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; + size_t c( 0 ); + for ( size_t i = 0; i < glb1.shape( 0 ); ++i ) { + for ( size_t j = 0; j < glb1.shape( 1 ); ++j ) { + EXPECT( glbv( i, j ) == glb1_c[c++] ); + } + } + } + + // Gather only second component + { + size_t loc_strides[] = {loc.stride( 0 ), 2}; + size_t loc_extents[] = {1, 1}; + size_t glb_strides[] = {glb2.stride( 0 ), glb2.stride( 1 )}; + size_t glb_extents[] = {1, glb2.shape( 2 )}; + f.gather_scatter.gather( loc.data() + 1, loc_strides, loc_extents, 1, glb2.data(), + glb_strides, glb_extents, 1, f.root ); + } + if ( mpi::comm().rank() == f.root ) { + auto glbv = array::make_view( glb2 ); + POD glb2_c[] = {100, 200, 300, 400, 500, 600, 700, 800, 900}; + size_t c( 0 ); + for ( size_t i = 0; i < glb2.shape( 0 ); ++i ) { + for ( size_t j = 0; j < glb2.shape( 1 ); ++j ) { + EXPECT( glbv( i, j ) == glb2_c[c++] ); + } + } + } } - } } - } - } #endif - SECTION( "test_gather_rank1" ) - { - for( f.root=0; f.root loc(f.Nl,2); - array::ArrayT glb(f.Ng(),2); - array::ArrayT glb1(f.Ng(),1); - array::ArrayT glb2(f.Ng(),1); - array::ArrayView locv = array::make_view(loc); - for( int j=0; j loc( f.Nl, 2 ); + array::ArrayT glb( f.Ng(), 2 ); + array::ArrayT glb1( f.Ng(), 1 ); + array::ArrayT glb2( f.Ng(), 1 ); + array::ArrayView locv = array::make_view( loc ); + for ( int j = 0; j < f.Nl; ++j ) { + locv( j, 0 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 10 ); + locv( j, 1 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 100 ); + } + +// Gather complete field +#if 0 { size_t loc_strides[] = {2,1}; size_t loc_extents[] = {size_t(f.Nl), 2}; @@ -246,10 +240,10 @@ CASE("test_gather") { EXPECT(make_view(glb.data(),glb.data()+2*f.Ng()) == make_view(glb_c,glb_c+2*f.Ng())); } } - #endif +#endif - // Gather only first component - #if 0 +// Gather only first component +#if 0 { size_t loc_strides[] = {2,2}; size_t loc_extents[] = {size_t(f.Nl), 1}; @@ -286,10 +280,10 @@ CASE("test_gather") { EXPECT(make_view(glb1.data(),glb1.data()+f.Ng()) == make_view( glb1_c,glb1_c+f.Ng())); } } - #endif +#endif - // Gather only second component - #if 0 +// Gather only second component +#if 0 { size_t loc_strides[] = {2,2}; size_t loc_extents[] = {size_t(f.Nl), 1}; @@ -310,36 +304,32 @@ CASE("test_gather") { POD glb2_c[] = { 100, 200, 300, 400, 500, 600, 700, 800, 900 }; EXPECT(make_view(glb2.data(),glb2.data()+f.Ng()) == make_view(glb2_c,glb2_c+f.Ng())); } - #endif - } - } - - - - SECTION( "test_gather_rank2" ) - { - for( f.root=0; f.root loc(f.Nl,3,2); - array::ArrayT glb(f.Ng(),3,2); - array::ArrayT glbx1(f.Ng(),3); - array::ArrayT glbx2(f.Ng(),3); - array::ArrayT glb1x(f.Ng(),2); - array::ArrayT glb2x(f.Ng(),2); - array::ArrayT glb32(f.Ng()); - - array::ArrayView locv = array::make_view(loc); - for(int p = 0; p < f.Nl; ++p) - { - for(int i = 0; i < 3; ++i) - { - locv(p,i,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); - locv(p,i,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); - } +#endif + } } - // Gather complete field - #if 0 + SECTION( "test_gather_rank2" ) { + for ( f.root = 0; f.root < mpi::comm().size(); ++f.root ) { + array::ArrayT loc( f.Nl, 3, 2 ); + array::ArrayT glb( f.Ng(), 3, 2 ); + array::ArrayT glbx1( f.Ng(), 3 ); + array::ArrayT glbx2( f.Ng(), 3 ); + array::ArrayT glb1x( f.Ng(), 2 ); + array::ArrayT glb2x( f.Ng(), 2 ); + array::ArrayT glb32( f.Ng() ); + + array::ArrayView locv = array::make_view( loc ); + for ( int p = 0; p < f.Nl; ++p ) { + for ( int i = 0; i < 3; ++i ) { + locv( p, i, 0 ) = + ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : -f.gidx[p] * std::pow( 10, i ) ); + locv( p, i, 1 ) = + ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : f.gidx[p] * std::pow( 10, i ) ); + } + } + +// Gather complete field +#if 0 { size_t loc_strides[] = {6,2,1}; size_t loc_extents[] = {size_t(f.Nl), 3, 2}; @@ -368,10 +358,10 @@ CASE("test_gather") { -9,9, -90,90, -900,900 }; EXPECT(make_view(glb.data(),glb.data()+6*f.Ng()) == make_view(glb_c,glb_c+6*f.Ng())); } - #endif +#endif - // Gather var 1 - #if 0 +// Gather var 1 +#if 0 { size_t loc_strides[] = {6,2,2}; size_t loc_extents[] = {size_t(f.Nl), 3, 1}; @@ -400,10 +390,10 @@ CASE("test_gather") { -9, -90, -900 }; EXPECT(make_view(glbx1.data(),glbx1.data()+3*f.Ng()) == make_view(glb_c,glb_c+3*f.Ng())); } - #endif +#endif - // Gather var 2 - #if 0 +// Gather var 2 +#if 0 { size_t loc_strides[] = {6,2,2}; size_t loc_extents[] = {size_t(f.Nl), 3, 1}; @@ -432,10 +422,10 @@ CASE("test_gather") { 9, 90, 900 }; BOOST_CHECK_EQUAL_COLLECTIONS(glbx2.data(),glbx2.data()+3*f.Ng(), glb_c,glb_c+3*f.Ng()); } - #endif +#endif - // Gather lev 1 - #if 0 +// Gather lev 1 +#if 0 { size_t loc_strides[] = {6,6,1}; size_t loc_extents[] = {size_t(f.Nl), 1, 2}; @@ -465,10 +455,10 @@ CASE("test_gather") { -9,9, }; BOOST_CHECK_EQUAL_COLLECTIONS(glb1x.data(),glb1x.data()+2*f.Ng(), glb_c,glb_c+2*f.Ng()); } - #endif +#endif - // Gather lev 2 - #if 0 +// Gather lev 2 +#if 0 { size_t loc_strides[] = {6,6,1}; size_t loc_extents[] = {size_t(f.Nl), 1, 2}; @@ -497,10 +487,10 @@ CASE("test_gather") { -90,90, }; BOOST_CHECK_EQUAL_COLLECTIONS(glb2x.data(),glb2x.data()+2*f.Ng(), glb_c,glb_c+2*f.Ng()); } - #endif +#endif - // Gather lev 3 var 2 - #if 0 +// Gather lev 3 var 2 +#if 0 { size_t loc_strides[] = {6,6,2}; size_t loc_extents[] = {size_t(f.Nl), 1, 1}; @@ -530,240 +520,176 @@ CASE("test_gather") { 900 }; BOOST_CHECK_EQUAL_COLLECTIONS(glb32.data(),glb32.data()+f.Ng(), glb_c,glb_c+f.Ng()); } - #endif - } - } - - - SECTION( "test_gather_rank0_ArrayView" ) - { - for( f.root=0; f.root loc(f.Nl); - array::ArrayT glb(f.Ng()); - - array::ArrayView locv = array::make_view(loc); - array::ArrayView glbv = array::make_view(glb); - for(int p = 0; p < f.Nl; ++p) - { - locv(p) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*10 ); - } - - // Gather complete field - { - f.gather_scatter.gather( locv, glbv, f.root ); - } - if( mpi::comm().rank() == f.root ) - { - POD glb_c[] = { 10, - 20, - 30, - 40, - 50, - 60, - 70, - 80, - 90 }; - for( size_t n=0; n loc(f.Nl,2); - array::ArrayT glb(f.Ng(),2); - - array::ArrayView locv = array::make_view(loc); - array::ArrayView glbv = array::make_view(glb); - for(int p = 0; p < f.Nl; ++p) - { - locv(p,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*10 ); - locv(p,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*10 ); - } - - // Gather complete field - { - f.gather_scatter.gather( locv, glbv, f.root ); - } - if( mpi::comm().rank() == f.root ) - { - POD glb_c[] = { -10,10, - -20,20, - -30,30, - -40,40, - -50,50, - -60,60, - -70,70, - -80,80, - -90,90 }; - - auto glbv = array::make_view(glb); - size_t c(0); - for( size_t i=0; i loc(f.Nl,3,2); - array::ArrayT glb(f.Ng(),3,2); - - array::ArrayView locv = array::make_view(loc); - array::ArrayView glbv = array::make_view(glb); - for(int p = 0; p < f.Nl; ++p) - { - for(int i = 0; i < 3; ++i) - { - locv(p,i,0) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : -f.gidx[p]*std::pow(10,i) ); - locv(p,i,1) = (size_t(f.part[p]) != mpi::comm().rank() ? 0 : f.gidx[p]*std::pow(10,i) ); - } } - // Gather complete field - { - f.gather_scatter.gather( locv, glbv, f.root ); - } - if( mpi::comm().rank() == f.root ) - { - POD glb_c[] = { -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200, - -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400, - -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800, - -9,9, -90,90, -900,900 }; - size_t c(0); - for( size_t i=0; i loc( f.Nl ); + array::ArrayT glb( f.Ng() ); + + array::ArrayView locv = array::make_view( loc ); + array::ArrayView glbv = array::make_view( glb ); + for ( int p = 0; p < f.Nl; ++p ) { + locv( p ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : f.gidx[p] * 10 ); + } + + // Gather complete field + { f.gather_scatter.gather( locv, glbv, f.root ); } + if ( mpi::comm().rank() == f.root ) { + POD glb_c[] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; + for ( size_t n = 0; n < glb.shape( 0 ); ++n ) { + EXPECT( glbv( n ) == glb_c[n] ); + } + } } - } } - } - f.root = 0; - } - - SECTION( "test_scatter_rank2_ArrayView" ) - { - for( f.root=0; f.root loc(f.Nl,3,2); - array::ArrayT glb(f.Ng(),3,2); - - array::ArrayView locv = array::make_view(loc); - array::ArrayView glbv = array::make_view(glb); - if( mpi::comm().rank() == f.root ) - { - POD glb_c[] = { -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200, - -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400, - -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800, - -9,9, -90,90, -900,900 }; - size_t c(0); - for( int i=0; i loc( f.Nl, 2 ); + array::ArrayT glb( f.Ng(), 2 ); + + array::ArrayView locv = array::make_view( loc ); + array::ArrayView glbv = array::make_view( glb ); + for ( int p = 0; p < f.Nl; ++p ) { + locv( p, 0 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : -f.gidx[p] * 10 ); + locv( p, 1 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : f.gidx[p] * 10 ); + } + + // Gather complete field + { f.gather_scatter.gather( locv, glbv, f.root ); } + if ( mpi::comm().rank() == f.root ) { + POD glb_c[] = {-10, 10, -20, 20, -30, 30, -40, 40, -50, 50, -60, 60, -70, 70, -80, 80, -90, 90}; + + auto glbv = array::make_view( glb ); + size_t c( 0 ); + for ( size_t i = 0; i < glb.shape( 0 ); ++i ) { + for ( size_t j = 0; j < glb.shape( 1 ); ++j ) { + EXPECT( glbv( i, j ) == glb_c[c++] ); + } + } + } } - } } - POD nan = -1000.; - locv.assign(nan); - - f.gather_scatter.scatter( glbv, locv, f.root ); - - switch( mpi::comm().rank() ) - { - case 0: { - POD loc_c[] = { nan,nan, nan,nan, nan,nan, - -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200, - -3,3, -30,30, -300,300, - nan,nan, nan,nan, nan,nan, - nan,nan, nan,nan, nan,nan }; - - size_t c(0); - for( size_t i=0; i loc( f.Nl, 3, 2 ); + array::ArrayT glb( f.Ng(), 3, 2 ); + + array::ArrayView locv = array::make_view( loc ); + array::ArrayView glbv = array::make_view( glb ); + for ( int p = 0; p < f.Nl; ++p ) { + for ( int i = 0; i < 3; ++i ) { + locv( p, i, 0 ) = + ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : -f.gidx[p] * std::pow( 10, i ) ); + locv( p, i, 1 ) = + ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : f.gidx[p] * std::pow( 10, i ) ); + } + } + + // Gather complete field + { f.gather_scatter.gather( locv, glbv, f.root ); } + if ( mpi::comm().rank() == f.root ) { + POD glb_c[] = {-1, 1, -10, 10, -100, 100, -2, 2, -20, 20, -200, 200, -3, 3, -30, 30, -300, 300, + -4, 4, -40, 40, -400, 400, -5, 5, -50, 50, -500, 500, -6, 6, -60, 60, -600, 600, + -7, 7, -70, 70, -700, 700, -8, 8, -80, 80, -800, 800, -9, 9, -90, 90, -900, 900}; + size_t c( 0 ); + for ( size_t i = 0; i < glb.shape( 0 ); ++i ) { + for ( size_t j = 0; j < glb.shape( 1 ); ++j ) { + for ( size_t k = 0; k < glb.shape( 2 ); ++k ) { + EXPECT( glbv( i, j, k ) == glb_c[c++] ); + } + } + } + } } - } - break; } - case 1: { - POD loc_c[] = { nan,nan, nan,nan, nan,nan, - -4,4, -40,40, -400,400, - -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - nan,nan, nan,nan, nan,nan, - nan,nan, nan,nan, nan,nan }; - size_t c(0); - for( size_t i=0; i loc( f.Nl, 3, 2 ); + array::ArrayT glb( f.Ng(), 3, 2 ); + + array::ArrayView locv = array::make_view( loc ); + array::ArrayView glbv = array::make_view( glb ); + if ( mpi::comm().rank() == f.root ) { + POD glb_c[] = {-1, 1, -10, 10, -100, 100, -2, 2, -20, 20, -200, 200, -3, 3, -30, 30, -300, 300, + -4, 4, -40, 40, -400, 400, -5, 5, -50, 50, -500, 500, -6, 6, -60, 60, -600, 600, + -7, 7, -70, 70, -700, 700, -8, 8, -80, 80, -800, 800, -9, 9, -90, 90, -900, 900}; + size_t c( 0 ); + for ( int i = 0; i < glb.shape( 0 ); ++i ) { + for ( int j = 0; j < glb.shape( 1 ); ++j ) { + for ( int k = 0; k < glb.shape( 2 ); ++k ) { + glbv( i, j, k ) = glb_c[c++]; + } + } + } + } + + POD nan = -1000.; + locv.assign( nan ); + + f.gather_scatter.scatter( glbv, locv, f.root ); + + switch ( mpi::comm().rank() ) { + case 0: { + POD loc_c[] = {nan, nan, nan, nan, nan, nan, -1, 1, -10, 10, -100, 100, + -2, 2, -20, 20, -200, 200, -3, 3, -30, 30, -300, 300, + nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan}; + + size_t c( 0 ); + for ( size_t i = 0; i < loc.shape( 0 ); ++i ) { + for ( size_t j = 0; j < loc.shape( 1 ); ++j ) { + for ( size_t k = 0; k < loc.shape( 2 ); ++k ) { + EXPECT( locv( i, j, k ) == loc_c[c++] ); + } + } + } + break; + } + case 1: { + POD loc_c[] = {nan, nan, nan, nan, nan, nan, -4, 4, -40, 40, -400, 400, + -5, 5, -50, 50, -500, 500, -6, 6, -60, 60, -600, 600, + nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan}; + size_t c( 0 ); + for ( size_t i = 0; i < loc.shape( 0 ); ++i ) { + for ( size_t j = 0; j < loc.shape( 1 ); ++j ) { + for ( size_t k = 0; k < loc.shape( 2 ); ++k ) { + EXPECT( locv( i, j, k ) == loc_c[c++] ); + } + } + } + break; + } + case 2: { + POD loc_c[] = {nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, -7, 7, + -70, 70, -700, 700, -8, 8, -80, 80, -800, 800, -9, 9, -90, 90, + -900, 900, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan, nan}; + size_t c( 0 ); + for ( size_t i = 0; i < loc.shape( 0 ); ++i ) { + for ( size_t j = 0; j < loc.shape( 1 ); ++j ) { + for ( size_t k = 0; k < loc.shape( 2 ); ++k ) { + EXPECT( locv( i, j, k ) == loc_c[c++] ); + } + } + } + break; + } + } } - } - break; } - case 2: { - POD loc_c[] = { nan,nan, nan,nan, nan,nan, - nan,nan, nan,nan, nan,nan, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800, - -9,9, -90,90, -900,900, - nan,nan, nan,nan, nan,nan, - nan,nan, nan,nan, nan,nan }; - size_t c(0); - for( size_t i=0; i #include #include +#include #include "eckit/memory/SharedPtr.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/library/config.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" +#include "atlas/library/config.h" #include "atlas/parallel/HaloExchange.h" - +#include "atlas/parallel/mpi/mpi.h" #include "tests/AtlasTestEnvironment.h" @@ -32,320 +32,345 @@ namespace test { //----------------------------------------------------------------------------- -template -std::vector vec( const T (&list)[N] ) -{ - return std::vector(list,list+N); +template +std::vector vec( const T ( &list )[N] ) { + return std::vector( list, list + N ); } -template -size_t eval_idx(size_t pos, std::array& strides, FirstDim first) -{ - return first*strides[pos]; +template +size_t eval_idx( size_t pos, std::array& strides, FirstDim first ) { + return first * strides[pos]; } -template -size_t eval_idx(size_t pos, std::array& strides, FirstDim first, Int...dims ) -{ - return first*strides[pos] + eval_idx((size_t)pos+1, strides, dims...); +template +size_t eval_idx( size_t pos, std::array& strides, FirstDim first, Int... dims ) { + return first * strides[pos] + eval_idx( (size_t)pos + 1, strides, dims... ); } -template +template struct validate_impl; -template +template struct validate_impl { - template - static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { - EXPECT(arrv(dims...) == arr_c[eval_idx((size_t)0, strides, dims...)]); + template + static void apply( array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, + Int... dims ) { + EXPECT( arrv( dims... ) == arr_c[eval_idx( (size_t)0, strides, dims... )] ); } }; -template +template struct validate_impl { - - template - static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, Int... dims ) { - for(size_t cnt = 0; cnt < arrv.template shape(); ++cnt) { - validate_impl::apply(arrv, arr_c, strides, dims..., cnt); + template + static void apply( array::ArrayView& arrv, DATA_TYPE arr_c[], std::array& strides, + Int... dims ) { + for ( size_t cnt = 0; cnt < arrv.template shape(); ++cnt ) { + validate_impl::apply( arrv, arr_c, strides, dims..., cnt ); } } }; -template -struct compute_strides; +template +struct compute_strides; -template<> +template <> struct compute_strides<0> { template - static void apply(array::ArrayView& arrv, std::array& strides) {} + static void apply( array::ArrayView& arrv, std::array& strides ) {} }; -template +template struct compute_strides { template - static void apply(array::ArrayView& arrv, std::array& strides) { - strides[Dim-1] = strides[Dim]*arrv.template shape<(unsigned int)Dim>(); - compute_strides::apply(arrv,strides); - + static void apply( array::ArrayView& arrv, std::array& strides ) { + strides[Dim - 1] = strides[Dim] * arrv.template shape<(unsigned int)Dim>(); + compute_strides::apply( arrv, strides ); } }; -template +template struct validate { - - static void apply(array::ArrayView& arrv, DATA_TYPE arr_c[] ) { + static void apply( array::ArrayView& arrv, DATA_TYPE arr_c[] ) { std::array strides; - strides[Rank-1] = 1; - compute_strides::apply(arrv, strides); + strides[Rank - 1] = 1; + compute_strides::apply( arrv, strides ); - for(size_t i = 0; i < arrv.template shape<0>(); ++i) { - validate_impl::apply(arrv, arr_c, strides, i); + for ( size_t i = 0; i < arrv.template shape<0>(); ++i ) { + validate_impl::apply( arrv, arr_c, strides, i ); } } - }; struct Fixture { - Fixture(bool on_device) : on_device_(on_device) - { - int nnodes_c[] = {5, 6, 7}; nb_nodes = vec(nnodes_c); - N = nb_nodes[mpi::comm().rank()]; - switch( mpi::comm().rank() ) - { - case 0: - { - int part_c[] = {2,0,0,0,1}; part = vec(part_c); - int ridx_c[] = {4,1,2,3,1}; ridx = vec(ridx_c); - POD gidx_c[] = {0,1,2,3,0}; gidx = vec(gidx_c); - break; - } - case 1: - { - int part_c[] = {0,1,1,1,2,2}; part = vec(part_c); - int ridx_c[] = {3,1,2,3,2,3}; ridx = vec(ridx_c); - POD gidx_c[] = {0,4,5,6,0,0}; gidx = vec(gidx_c); - break; - } - case 2: - { - int part_c[] = {1,1,2,2,2,0,0}; part = vec(part_c); - int ridx_c[] = {2,3,2,3,4,1,2}; ridx = vec(ridx_c); - POD gidx_c[] = {0,0,7,8,9,0,0}; gidx = vec(gidx_c); - break; - } + Fixture( bool on_device ) : on_device_( on_device ) { + int nnodes_c[] = {5, 6, 7}; + nb_nodes = vec( nnodes_c ); + N = nb_nodes[mpi::comm().rank()]; + switch ( mpi::comm().rank() ) { + case 0: { + int part_c[] = {2, 0, 0, 0, 1}; + part = vec( part_c ); + int ridx_c[] = {4, 1, 2, 3, 1}; + ridx = vec( ridx_c ); + POD gidx_c[] = {0, 1, 2, 3, 0}; + gidx = vec( gidx_c ); + break; + } + case 1: { + int part_c[] = {0, 1, 1, 1, 2, 2}; + part = vec( part_c ); + int ridx_c[] = {3, 1, 2, 3, 2, 3}; + ridx = vec( ridx_c ); + POD gidx_c[] = {0, 4, 5, 6, 0, 0}; + gidx = vec( gidx_c ); + break; + } + case 2: { + int part_c[] = {1, 1, 2, 2, 2, 0, 0}; + part = vec( part_c ); + int ridx_c[] = {2, 3, 2, 3, 4, 1, 2}; + ridx = vec( ridx_c ); + POD gidx_c[] = {0, 0, 7, 8, 9, 0, 0}; + gidx = vec( gidx_c ); + break; + } + } + halo_exchange.setup( part.data(), ridx.data(), 0, N ); } - halo_exchange.setup(part.data(),ridx.data(),0,N); - } - parallel::HaloExchange halo_exchange; - std::vector nb_nodes; - std::vector part; - std::vector ridx; - std::vector gidx; - - int N; - bool on_device_; + parallel::HaloExchange halo_exchange; + std::vector nb_nodes; + std::vector part; + std::vector ridx; + std::vector gidx; + + int N; + bool on_device_; }; //----------------------------------------------------------------------------- -void test_rank0_arrview(Fixture& f) { - array::ArrayT arr(f.N); - array::ArrayView arrv = array::make_host_view(arr); - for( int j=0; j arr( f.N ); + array::ArrayView arrv = array::make_host_view( arr ); + for ( int j = 0; j < f.N; ++j ) { + arrv( j ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] ); } arr.syncHostDevice(); - f.halo_exchange.execute(arr, f.on_device_); + f.halo_exchange.execute( arr, f.on_device_ ); arr.syncHostDevice(); - switch( mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 9, 1, 2, 3, 4}; - validate::apply(arrv, arr_c); break; } - case 1: { POD arr_c[] = { 3, 4, 5, 6, 7, 8}; - validate::apply(arrv, arr_c); break; } - case 2: { POD arr_c[] = { 5, 6, 7, 8, 9, 1, 2}; - validate::apply(arrv, arr_c); break; } + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {9, 1, 2, 3, 4}; + validate::apply( arrv, arr_c ); + break; + } + case 1: { + POD arr_c[] = {3, 4, 5, 6, 7, 8}; + validate::apply( arrv, arr_c ); + break; + } + case 2: { + POD arr_c[] = {5, 6, 7, 8, 9, 1, 2}; + validate::apply( arrv, arr_c ); + break; + } } } -void test_rank1(Fixture& f) { - array::ArrayT arr(f.N,2); - array::ArrayView arrv = array::make_host_view(arr); - for( int j=0; j arr( f.N, 2 ); + array::ArrayView arrv = array::make_host_view( arr ); + for ( int j = 0; j < f.N; ++j ) { + arrv( j, 0 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 10 ); + arrv( j, 1 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 100 ); } arr.syncHostDevice(); - f.halo_exchange.execute(arr, f.on_device_); + f.halo_exchange.execute( arr, f.on_device_ ); arr.syncHostDevice(); - switch( mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; - validate::apply(arrv, arr_c); break; } - case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; - validate::apply(arrv, arr_c); break; } - case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; - validate::apply(arrv, arr_c); break; } + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {90, 900, 10, 100, 20, 200, 30, 300, 40, 400}; + validate::apply( arrv, arr_c ); + break; + } + case 1: { + POD arr_c[] = {30, 300, 40, 400, 50, 500, 60, 600, 70, 700, 80, 800}; + validate::apply( arrv, arr_c ); + break; + } + case 2: { + POD arr_c[] = {50, 500, 60, 600, 70, 700, 80, 800, 90, 900, 10, 100, 20, 200}; + validate::apply( arrv, arr_c ); + break; + } } } -void test_rank1_strided_v1(Fixture& f) { - //create a 2d field from the gidx data, with two components per grid point - array::ArrayT arr_t(f.N,2); - array::ArrayView arrv_t = array::make_host_view(arr_t); - for( int j=0; j arr_t( f.N, 2 ); + array::ArrayView arrv_t = array::make_host_view( arr_t ); + for ( int j = 0; j < f.N; ++j ) { + arrv_t( j, 0 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 10 ); + arrv_t( j, 1 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 100 ); } arr_t.syncHostDevice(); - // create a wrap array where we fake the strides in a way that the second dimension - // (number of components) contains only one component but the associated stride is 2 - // (i.e. we are only selecting and exchanging the first component of the field) + // create a wrap array where we fake the strides in a way that the second + // dimension + // (number of components) contains only one component but the associated + // stride is 2 + // (i.e. we are only selecting and exchanging the first component of the + // field) - eckit::SharedPtr arr ( array::Array::wrap( - arrv_t.data(), - array::ArraySpec{array::make_shape(f.N, 1), + eckit::SharedPtr arr( array::Array::wrap( arrv_t.data(), + array::ArraySpec { + array::make_shape( f.N, 1 ), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(32, 1) } + array::make_strides( 32, 1 ) + } #else - array::make_strides(2, 1) } + array::make_strides( 2, 1 ) + } #endif - ) ); + ) ); arr->syncHostDevice(); - f.halo_exchange.execute(*arr, f.on_device_); + f.halo_exchange.execute( *arr, f.on_device_ ); arr->syncHostDevice(); - switch( mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 90,0, 10,100, 20,200, 30,300, 40,0 }; - validate::apply(arrv_t, arr_c); break; } - case 1: { POD arr_c[] = { 30,0, 40,400, 50,500, 60,600, 70,0, 80,0}; - validate::apply(arrv_t, arr_c); break; } - case 2: { POD arr_c[] = { 50,0, 60,0, 70,700, 80,800, 90,900, 10,0, 20,0}; - validate::apply(arrv_t, arr_c); break; } + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {90, 0, 10, 100, 20, 200, 30, 300, 40, 0}; + validate::apply( arrv_t, arr_c ); + break; + } + case 1: { + POD arr_c[] = {30, 0, 40, 400, 50, 500, 60, 600, 70, 0, 80, 0}; + validate::apply( arrv_t, arr_c ); + break; + } + case 2: { + POD arr_c[] = {50, 0, 60, 0, 70, 700, 80, 800, 90, 900, 10, 0, 20, 0}; + validate::apply( arrv_t, arr_c ); + break; + } } - } -void test_rank1_strided_v2(Fixture& f) { - //create a 2d field from the gidx data, with two components per grid point - array::ArrayT arr_t(f.N,2); - array::ArrayView arrv_t = array::make_host_view(arr_t); - for( int j=0; j arr_t( f.N, 2 ); + array::ArrayView arrv_t = array::make_host_view( arr_t ); + for ( int j = 0; j < f.N; ++j ) { + arrv_t( j, 0 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 10 ); + arrv_t( j, 1 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 100 ); } arr_t.syncHostDevice(); - // create a wrap array where we fake the strides in a way that the second dimension - // (number of components) contains only one component but the associated stride is 2 - // (i.e. we are only selecting and exchanging the first component of the field) + // create a wrap array where we fake the strides in a way that the second + // dimension + // (number of components) contains only one component but the associated + // stride is 2 + // (i.e. we are only selecting and exchanging the first component of the + // field) - eckit::SharedPtr arr ( array::Array::wrap(&(arrv_t(0,1)), - array::ArraySpec{array::make_shape(f.N, 1), + eckit::SharedPtr arr( array::Array::wrap( &( arrv_t( 0, 1 ) ), array::ArraySpec { + array::make_shape( f.N, 1 ), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(32, 1) + array::make_strides( 32, 1 ) #else array::make_strides(2, 1) #endif } ) ); - f.halo_exchange.execute(*arr, false); + f.halo_exchange.execute( *arr, false ); - switch( mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 0,900, 10,100, 20,200, 30,300, 0,400 }; - validate::apply(arrv_t, arr_c); break; } - case 1: { POD arr_c[] = { 0,300, 40,400, 50,500, 60,600, 0,700, 0,800}; - validate::apply(arrv_t, arr_c); break; } - case 2: { POD arr_c[] = { 0,500, 0,600, 70,700, 80,800, 90,900, 0,100, 0,200}; - validate::apply(arrv_t, arr_c); break; } + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {0, 900, 10, 100, 20, 200, 30, 300, 0, 400}; + validate::apply( arrv_t, arr_c ); + break; + } + case 1: { + POD arr_c[] = {0, 300, 40, 400, 50, 500, 60, 600, 0, 700, 0, 800}; + validate::apply( arrv_t, arr_c ); + break; + } + case 2: { + POD arr_c[] = {0, 500, 0, 600, 70, 700, 80, 800, 90, 900, 0, 100, 0, 200}; + validate::apply( arrv_t, arr_c ); + break; + } } } -void test_rank2(Fixture& f) { - array::ArrayT arr(f.N,3,2); - array::ArrayView arrv = array::make_host_view(arr); - for( int p=0; p arr( f.N, 3, 2 ); + array::ArrayView arrv = array::make_host_view( arr ); + for ( int p = 0; p < f.N; ++p ) { + for ( size_t i = 0; i < 3; ++i ) { + arrv( p, i, 0 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : -f.gidx[p] * std::pow( 10, i ) ); + arrv( p, i, 1 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : f.gidx[p] * std::pow( 10, i ) ); + } } arr.syncHostDevice(); - f.halo_exchange.execute(arr, f.on_device_); + f.halo_exchange.execute( arr, f.on_device_ ); arr.syncHostDevice(); - switch( mpi::comm().rank() ) - { - case 0: - { - POD arr_c[] = { -9,9, -90,90, -900,900, - -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200, - -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400}; - validate::apply(arrv, arr_c); break; } - case 1: - { - POD arr_c[] = { -3,3, -30,30, -300,300, - -4,4, -40,40, -400,400, - -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800}; - validate::apply(arrv, arr_c); break; } - case 2: - { - POD arr_c[] = { -5,5, -50,50, -500,500, - -6,6, -60,60, -600,600, - -7,7, -70,70, -700,700, - -8,8, -80,80, -800,800, - -9,9, -90,90, -900,900, - -1,1, -10,10, -100,100, - -2,2, -20,20, -200,200}; - validate::apply(arrv, arr_c); break; } + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {-9, 9, -90, 90, -900, 900, -1, 1, -10, 10, -100, 100, -2, 2, -20, + 20, -200, 200, -3, 3, -30, 30, -300, 300, -4, 4, -40, 40, -400, 400}; + validate::apply( arrv, arr_c ); + break; + } + case 1: { + POD arr_c[] = {-3, 3, -30, 30, -300, 300, -4, 4, -40, 40, -400, 400, -5, 5, -50, 50, -500, 500, + -6, 6, -60, 60, -600, 600, -7, 7, -70, 70, -700, 700, -8, 8, -80, 80, -800, 800}; + validate::apply( arrv, arr_c ); + break; + } + case 2: { + POD arr_c[] = {-5, 5, -50, 50, -500, 500, -6, 6, -60, 60, -600, 600, -7, 7, + -70, 70, -700, 700, -8, 8, -80, 80, -800, 800, -9, 9, -90, 90, + -900, 900, -1, 1, -10, 10, -100, 100, -2, 2, -20, 20, -200, 200}; + validate::apply( arrv, arr_c ); + break; + } } } -void test_rank2_l1(Fixture& f) { - array::ArrayT arr_t(f.N,3,2); - array::ArrayView arrv_t = array::make_host_view(arr_t); - for( int p=0; p arr_t( f.N, 3, 2 ); + array::ArrayView arrv_t = array::make_host_view( arr_t ); + for ( int p = 0; p < f.N; ++p ) { + for ( size_t i = 0; i < 3; ++i ) { + arrv_t( p, i, 0 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : -f.gidx[p] * std::pow( 10, i ) ); + arrv_t( p, i, 1 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : f.gidx[p] * std::pow( 10, i ) ); + } } arr_t.syncHostDevice(); - eckit::SharedPtr arr ( array::Array::wrap( - arrv_t.data(), - array::ArraySpec{array::make_shape(f.N, 1, 2), + eckit::SharedPtr arr( array::Array::wrap( arrv_t.data(), array::ArraySpec { + array::make_shape( f.N, 1, 2 ), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(96,32, 1) + array::make_strides( 96, 32, 1 ) #else array::make_strides(6, 2, 1) #endif @@ -354,380 +379,329 @@ void test_rank2_l1(Fixture& f) { arr_t.syncHostDevice(); - f.halo_exchange.execute(*arr, false); + f.halo_exchange.execute( *arr, false ); arr_t.syncHostDevice(); - switch( mpi::comm().rank() ) - { - case 0: - { - POD arr_c[] = { -9,9, 0, 0, 0, 0, // halo - -1,1, -10,10, -100,100, // core - -2,2, -20,20, -200,200, // core - -3,3, -30,30, -300,300, // core - -4,4, 0, 0, 0, 0}; // halo - validate::apply(arrv_t, arr_c); - break; - } - case 1: - { - POD arr_c[] = { -3,3, 0, 0, 0, 0, // halo - -4,4, -40,40, -400,400, // core - -5,5, -50,50, -500,500, // core - -6,6, -60,60, -600,600, // core - -7,7, 0, 0, 0, 0, // halo - -8,8, 0, 0, 0, 0}; // halo - validate::apply(arrv_t, arr_c); - break; - } - case 2: - { - POD arr_c[] = { -5,5, 0, 0, 0, 0, // halo - -6,6, 0, 0, 0, 0, // halo - -7,7, -70,70, -700,700, // core - -8,8, -80,80, -800,800, // core - -9,9, -90,90, -900,900, // core - -1,1, 0, 0, 0, 0, // halo - -2,2, 0, 0, 0, 0}; // halo - validate::apply(arrv_t, arr_c); - break; - } + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {-9, 9, 0, 0, 0, 0, // halo + -1, 1, -10, 10, -100, 100, // core + -2, 2, -20, 20, -200, 200, // core + -3, 3, -30, 30, -300, 300, // core + -4, 4, 0, 0, 0, 0}; // halo + validate::apply( arrv_t, arr_c ); + break; + } + case 1: { + POD arr_c[] = {-3, 3, 0, 0, 0, 0, // halo + -4, 4, -40, 40, -400, 400, // core + -5, 5, -50, 50, -500, 500, // core + -6, 6, -60, 60, -600, 600, // core + -7, 7, 0, 0, 0, 0, // halo + -8, 8, 0, 0, 0, 0}; // halo + validate::apply( arrv_t, arr_c ); + break; + } + case 2: { + POD arr_c[] = {-5, 5, 0, 0, 0, 0, // halo + -6, 6, 0, 0, 0, 0, // halo + -7, 7, -70, 70, -700, 700, // core + -8, 8, -80, 80, -800, 800, // core + -9, 9, -90, 90, -900, 900, // core + -1, 1, 0, 0, 0, 0, // halo + -2, 2, 0, 0, 0, 0}; // halo + validate::apply( arrv_t, arr_c ); + break; + } } } -void test_rank2_l2_v2(Fixture& f) { +void test_rank2_l2_v2( Fixture& f ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST // Test rank 2 halo-exchange - array::ArrayT arr_t(f.N,3,2); - array::ArrayView arrv_t = array::make_host_view(arr_t); - for( int p=0; p arr_t( f.N, 3, 2 ); + array::ArrayView arrv_t = array::make_host_view( arr_t ); + for ( int p = 0; p < f.N; ++p ) { + for ( size_t i = 0; i < 3; ++i ) { + arrv_t( p, i, 0 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : -f.gidx[p] * std::pow( 10, i ) ); + arrv_t( p, i, 1 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : f.gidx[p] * std::pow( 10, i ) ); + } } - eckit::SharedPtr arr ( array::Array::wrap(&arrv_t(0,1,1), - array::ArraySpec{array::make_shape(f.N, 1, 1), + eckit::SharedPtr arr( array::Array::wrap( &arrv_t( 0, 1, 1 ), array::ArraySpec { + array::make_shape( f.N, 1, 1 ), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(192, 32, 1) + array::make_strides( 192, 32, 1 ) #else array::make_strides(6, 2, 1) #endif } ) ); - f.halo_exchange.execute(*arr, f.on_device_); - - switch( mpi::comm().rank() ) - { - case 0: - { - POD arr_c[] = { 0,0, 0,90, 0, 0, // halo - -1,1, -10,10, -100,100, // core - -2,2, -20,20, -200,200, // core - -3,3, -30,30, -300,300, // core - 0,0, 0,40, 0, 0}; // halo - validate::apply(arrv_t, arr_c); - break; - } - case 1: - { - POD arr_c[] = { 0,0, 0,30, 0, 0, // halo - -4,4, -40,40, -400,400, // core - -5,5, -50,50, -500,500, // core - -6,6, -60,60, -600,600, // core - 0,0, 0,70, 0, 0, // halo - 0,0, 0,80, 0, 0}; // halo - validate::apply(arrv_t, arr_c); - break; - } - case 2: - { - POD arr_c[] = { 0,0, 0,50, 0, 0, // halo - 0,0, 0,60, 0, 0, // halo - -7,7, -70,70, -700,700, // core - -8,8, -80,80, -800,800, // core - -9,9, -90,90, -900,900, // core - 0,0, 0,10, 0, 0, // halo - 0,0, 0,20, 0, 0}; // halo - validate::apply(arrv_t, arr_c); - break; - } + f.halo_exchange.execute( *arr, f.on_device_ ); + + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {0, 0, 0, 90, 0, 0, // halo + -1, 1, -10, 10, -100, 100, // core + -2, 2, -20, 20, -200, 200, // core + -3, 3, -30, 30, -300, 300, // core + 0, 0, 0, 40, 0, 0}; // halo + validate::apply( arrv_t, arr_c ); + break; + } + case 1: { + POD arr_c[] = {0, 0, 0, 30, 0, 0, // halo + -4, 4, -40, 40, -400, 400, // core + -5, 5, -50, 50, -500, 500, // core + -6, 6, -60, 60, -600, 600, // core + 0, 0, 0, 70, 0, 0, // halo + 0, 0, 0, 80, 0, 0}; // halo + validate::apply( arrv_t, arr_c ); + break; + } + case 2: { + POD arr_c[] = {0, 0, 0, 50, 0, 0, // halo + 0, 0, 0, 60, 0, 0, // halo + -7, 7, -70, 70, -700, 700, // core + -8, 8, -80, 80, -800, 800, // core + -9, 9, -90, 90, -900, 900, // core + 0, 0, 0, 10, 0, 0, // halo + 0, 0, 0, 20, 0, 0}; // halo + validate::apply( arrv_t, arr_c ); + break; + } } #endif } -void test_rank2_v2(Fixture& f) { +void test_rank2_v2( Fixture& f ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST - array::ArrayT arr_t(f.N,3,2); - array::ArrayView arrv_t = array::make_view(arr_t); - for( int p=0; p arr_t( f.N, 3, 2 ); + array::ArrayView arrv_t = array::make_view( arr_t ); + for ( int p = 0; p < f.N; ++p ) { + for ( size_t i = 0; i < 3; ++i ) { + arrv_t( p, i, 0 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : -f.gidx[p] * std::pow( 10, i ) ); + arrv_t( p, i, 1 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : f.gidx[p] * std::pow( 10, i ) ); + } } - eckit::SharedPtr arr ( array::Array::wrap(&arrv_t(0,0,1), - array::ArraySpec{array::make_shape(f.N, 3, 1), + eckit::SharedPtr arr( array::Array::wrap( &arrv_t( 0, 0, 1 ), array::ArraySpec { + array::make_shape( f.N, 3, 1 ), #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - array::make_strides(192, 32, 2) + array::make_strides( 192, 32, 2 ) #else array::make_strides(6, 2, 2) #endif } ) ); - f.halo_exchange.execute(*arr, f.on_device_); - - switch( mpi::comm().rank() ) - { - case 0: - { - POD arr_c[] = { 0,9, 0,90, 0,900, // halo - -1,1, -10,10, -100,100, // core - -2,2, -20,20, -200,200, // core - -3,3, -30,30, -300,300, // core - 0,4, 0,40, 0,400}; // halo - validate::apply(arrv_t, arr_c); - break; - } - case 1: - { - POD arr_c[] = { 0,3, 0,30, 0,300, // halo - -4,4, -40,40, -400,400, // core - -5,5, -50,50, -500,500, // core - -6,6, -60,60, -600,600, // core - 0,7, 0,70, 0,700, // halo - 0,8, 0,80, 0,800}; // halo - validate::apply(arrv_t, arr_c); - break; - } - case 2: - { - POD arr_c[] = { 0,5, 0,50, 0,500, // halo - 0,6, 0,60, 0,600, // halo - -7,7, -70,70, -700,700, // core - -8,8, -80,80, -800,800, // core - -9,9, -90,90, -900,900, // core - 0,1, 0,10, 0,100, // halo - 0,2, 0,20, 0,200}; // halo - validate::apply(arrv_t, arr_c); - break; - } + f.halo_exchange.execute( *arr, f.on_device_ ); + + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {0, 9, 0, 90, 0, 900, // halo + -1, 1, -10, 10, -100, 100, // core + -2, 2, -20, 20, -200, 200, // core + -3, 3, -30, 30, -300, 300, // core + 0, 4, 0, 40, 0, 400}; // halo + validate::apply( arrv_t, arr_c ); + break; + } + case 1: { + POD arr_c[] = {0, 3, 0, 30, 0, 300, // halo + -4, 4, -40, 40, -400, 400, // core + -5, 5, -50, 50, -500, 500, // core + -6, 6, -60, 60, -600, 600, // core + 0, 7, 0, 70, 0, 700, // halo + 0, 8, 0, 80, 0, 800}; // halo + validate::apply( arrv_t, arr_c ); + break; + } + case 2: { + POD arr_c[] = {0, 5, 0, 50, 0, 500, // halo + 0, 6, 0, 60, 0, 600, // halo + -7, 7, -70, 70, -700, 700, // core + -8, 8, -80, 80, -800, 800, // core + -9, 9, -90, 90, -900, 900, // core + 0, 1, 0, 10, 0, 100, // halo + 0, 2, 0, 20, 0, 200}; // halo + validate::apply( arrv_t, arr_c ); + break; + } } #endif } -void test_rank0_wrap(Fixture& f) { - eckit::SharedPtr arr ( array::Array::wrap(f.gidx.data(), array::make_shape(f.N) ) ); - array::ArrayView arrv = array::make_view(*arr); +void test_rank0_wrap( Fixture& f ) { + eckit::SharedPtr arr( array::Array::wrap( f.gidx.data(), array::make_shape( f.N ) ) ); + array::ArrayView arrv = array::make_view( *arr ); arr->syncHostDevice(); - f.halo_exchange.execute(*arr, f.on_device_); + f.halo_exchange.execute( *arr, f.on_device_ ); arr->syncHostDevice(); - switch( mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 9, 1, 2, 3, 4}; - validate::apply(arrv, arr_c); break; } - case 1: { POD arr_c[] = { 3, 4, 5, 6, 7, 8}; - validate::apply(arrv, arr_c); break; } - case 2: { POD arr_c[] = { 5, 6, 7, 8, 9, 1, 2}; - validate::apply(arrv, arr_c); break; } + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {9, 1, 2, 3, 4}; + validate::apply( arrv, arr_c ); + break; + } + case 1: { + POD arr_c[] = {3, 4, 5, 6, 7, 8}; + validate::apply( arrv, arr_c ); + break; + } + case 2: { + POD arr_c[] = {5, 6, 7, 8, 9, 1, 2}; + validate::apply( arrv, arr_c ); + break; + } } } -void test_rank1_paralleldim1(Fixture& f) { - array::ArrayT arr(2,f.N); - array::ArrayView arrv = array::make_view(arr); - for( int j=0; j arr( 2, f.N ); + array::ArrayView arrv = array::make_view( arr ); + for ( int j = 0; j < f.N; ++j ) { + arrv( 0, j ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 10 ); + arrv( 1, j ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 100 ); } - f.halo_exchange.execute(arr, false); + f.halo_exchange.execute( arr, false ); - switch( mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 90, 10, 20 , 30 , 40, 900, 100, 200, 300, 400 }; //90,900, 10,100, 20,200, 30,300, 40,400 }; - validate::apply(arrv, arr_c); break; } - case 1: { POD arr_c[] = { 30,40,50,60,70,80, 300,400,500,600,700,800}; - validate::apply(arrv, arr_c); break; } - case 2: { POD arr_c[] = { 50,60,70,80,90,10,20, 500,600,700,800,900,100,200}; - validate::apply(arrv, arr_c); break; } + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {90, 10, 20, 30, 40, 900, 100, 200, 300, 400}; // 90,900, 10,100, 20,200, 30,300, 40,400 }; + validate::apply( arrv, arr_c ); + break; + } + case 1: { + POD arr_c[] = {30, 40, 50, 60, 70, 80, 300, 400, 500, 600, 700, 800}; + validate::apply( arrv, arr_c ); + break; + } + case 2: { + POD arr_c[] = {50, 60, 70, 80, 90, 10, 20, 500, 600, 700, 800, 900, 100, 200}; + validate::apply( arrv, arr_c ); + break; + } } } -void test_rank2_paralleldim2(Fixture& f) { - array::ArrayT arr(3,f.N,2); - array::ArrayView arrv = array::make_view(arr); - for( int p=0; p arr( 3, f.N, 2 ); + array::ArrayView arrv = array::make_view( arr ); + for ( int p = 0; p < f.N; ++p ) { + for ( size_t i = 0; i < 3; ++i ) { + arrv( i, p, 0 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : -f.gidx[p] * std::pow( 10, i ) ); + arrv( i, p, 1 ) = ( size_t( f.part[p] ) != mpi::comm().rank() ? 0 : f.gidx[p] * std::pow( 10, i ) ); + } } - f.halo_exchange.execute >(arr, false); - - switch( mpi::comm().rank() ) - { - case 0: - { - POD arr_c[] = { -9,9, -1,1, -2,2, -3,3, -4,4, - -90,90, -10,10, -20,20, -30,30, -40,40, - -900,900, -100,100, -200,200, -300,300, -400,400}; - - validate::apply(arrv, arr_c); - break; - } - case 1: - { - POD arr_c[] = { -3,3, -4,4, -5,5, -6,6, -7,7, -8,8, - -30,30, -40,40, -50,50, -60,60, -70,70, -80,80, - -300,300, -400,400, -500,500, -600,600, -700,700, -800,800}; - validate::apply(arrv, arr_c); - break; - } - case 2: - { - POD arr_c[] = { -5,5, -6,6, -7,7, -8,8, -9,9, -1,1, -2,2, - -50,50, -60,60, -70,70, -80,80, -90,90, -10,10, -20,20, - -500,500, -600,600, -700,700, -800,800, -900,900, -100,100, -200,200}; - validate::apply(arrv, arr_c); - break; - } + f.halo_exchange.execute>( arr, false ); + + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {-9, 9, -1, 1, -2, 2, -3, 3, -4, 4, -90, 90, -10, 10, -20, + 20, -30, 30, -40, 40, -900, 900, -100, 100, -200, 200, -300, 300, -400, 400}; + + validate::apply( arrv, arr_c ); + break; + } + case 1: { + POD arr_c[] = {-3, 3, -4, 4, -5, 5, -6, 6, -7, 7, -8, 8, -30, 30, -40, 40, -50, 50, + -60, 60, -70, 70, -80, 80, -300, 300, -400, 400, -500, 500, -600, 600, -700, 700, -800, 800}; + validate::apply( arrv, arr_c ); + break; + } + case 2: { + POD arr_c[] = {-5, 5, -6, 6, -7, 7, -8, 8, -9, 9, -1, 1, -2, 2, + -50, 50, -60, 60, -70, 70, -80, 80, -90, 90, -10, 10, -20, 20, + -500, 500, -600, 600, -700, 700, -800, 800, -900, 900, -100, 100, -200, 200}; + validate::apply( arrv, arr_c ); + break; + } } } -void test_rank1_cinterface(Fixture& f) { - +void test_rank1_cinterface( Fixture& f ) { #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST - array::ArrayT arr(f.N,2); - array::ArrayView arrv = array::make_host_view(arr); - for( int j=0; j arr( f.N, 2 ); + array::ArrayView arrv = array::make_host_view( arr ); + for ( int j = 0; j < f.N; ++j ) { + arrv( j, 0 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 10 ); + arrv( j, 1 ) = ( size_t( f.part[j] ) != mpi::comm().rank() ? 0 : f.gidx[j] * 100 ); } arr.syncHostDevice(); - int shapes[2] = {(int)arrv.shape(0), (int)arrv.shape(1)}; - int strides[2] = {(int)arrv.stride(0), (int)arrv.stride(1)}; + int shapes[2] = {(int)arrv.shape( 0 ), (int)arrv.shape( 1 )}; + int strides[2] = {(int)arrv.stride( 0 ), (int)arrv.stride( 1 )}; - atlas__HaloExchange__execute_strided_double(&(f.halo_exchange), arrv.data(), &(strides[1]), &(shapes[1]), 1); + atlas__HaloExchange__execute_strided_double( &( f.halo_exchange ), arrv.data(), &( strides[1] ), &( shapes[1] ), + 1 ); - switch( mpi::comm().rank() ) - { - case 0: { POD arr_c[] = { 90,900, 10,100, 20,200, 30,300, 40,400 }; - validate::apply(arrv, arr_c); break; } - case 1: { POD arr_c[] = { 30,300, 40,400, 50,500, 60,600, 70,700, 80,800}; - validate::apply(arrv, arr_c); break; } - case 2: { POD arr_c[] = { 50,500, 60,600, 70,700, 80,800, 90,900, 10,100, 20,200}; - validate::apply(arrv, arr_c); break; } + switch ( mpi::comm().rank() ) { + case 0: { + POD arr_c[] = {90, 900, 10, 100, 20, 200, 30, 300, 40, 400}; + validate::apply( arrv, arr_c ); + break; + } + case 1: { + POD arr_c[] = {30, 300, 40, 400, 50, 500, 60, 600, 70, 700, 80, 800}; + validate::apply( arrv, arr_c ); + break; + } + case 2: { + POD arr_c[] = {50, 500, 60, 600, 70, 700, 80, 800, 90, 900, 10, 100, 20, 200}; + validate::apply( arrv, arr_c ); + break; + } } #endif } -CASE("test_haloexchange") { - SETUP("HaloExchanges_cpu") { - Fixture f(false); +CASE( "test_haloexchange" ) { + SETUP( "HaloExchanges_cpu" ) { + Fixture f( false ); - SECTION( "test_rank0_arrview" ) - { - test_rank0_arrview(f); - } + SECTION( "test_rank0_arrview" ) { test_rank0_arrview( f ); } - SECTION( "test_rank1" ) - { - test_rank1(f); - } + SECTION( "test_rank1" ) { test_rank1( f ); } - SECTION( "test_rank1_strided_v1" ) - { - test_rank1_strided_v1(f); - } + SECTION( "test_rank1_strided_v1" ) { test_rank1_strided_v1( f ); } - SECTION( "test_rank1_strided_v2" ) - { - test_rank1_strided_v2(f); - } + SECTION( "test_rank1_strided_v2" ) { test_rank1_strided_v2( f ); } - SECTION( "test_rank2" ) - { - test_rank2(f); - } + SECTION( "test_rank2" ) { test_rank2( f ); } - SECTION( "test_rank2_l1" ) - { - test_rank2_l1(f); - } + SECTION( "test_rank2_l1" ) { test_rank2_l1( f ); } - SECTION( "test_rank2_l2_v2" ) - { - test_rank2_l2_v2(f); - } + SECTION( "test_rank2_l2_v2" ) { test_rank2_l2_v2( f ); } - SECTION( "test_rank2_v2" ) - { - test_rank2_v2(f); - } + SECTION( "test_rank2_v2" ) { test_rank2_v2( f ); } - SECTION( "test_rank0_wrap" ) - { - test_rank0_wrap(f); - } + SECTION( "test_rank0_wrap" ) { test_rank0_wrap( f ); } - SECTION( "test_rank1_paralleldim_1" ) - { - test_rank1_paralleldim1(f); - } + SECTION( "test_rank1_paralleldim_1" ) { test_rank1_paralleldim1( f ); } - SECTION( "test_rank2_paralleldim_2" ) - { - test_rank2_paralleldim2(f); - } - SECTION( "test_rank1_cinterface" ) - { - test_rank1_cinterface(f); - } + SECTION( "test_rank2_paralleldim_2" ) { test_rank2_paralleldim2( f ); } + SECTION( "test_rank1_cinterface" ) { test_rank1_cinterface( f ); } #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA - f.on_device_ = true; + f.on_device_ = true; - SECTION( "test_rank0_arrview" ) - { - test_rank0_arrview(f); - } - - SECTION( "test_rank1" ) - { - test_rank1(f); - } + SECTION( "test_rank0_arrview" ) { test_rank0_arrview( f ); } - SECTION( "test_rank2" ) - { - test_rank2(f); - } - SECTION( "test_rank0_wrap" ) - { - test_rank0_wrap(f); - } + SECTION( "test_rank1" ) { test_rank1( f ); } + SECTION( "test_rank2" ) { test_rank2( f ); } + SECTION( "test_rank0_wrap" ) { test_rank0_wrap( f ); } #endif - - } - + } } //----------------------------------------------------------------------------- @@ -735,8 +709,6 @@ CASE("test_haloexchange") { } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } - diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 73e15759d..6d9e6b685 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -4,35 +4,35 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include -#include "atlas/library/Library.h" +#include "atlas/array/MakeView.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/Spectral.h" #include "atlas/functionspace/StructuredColumns.h" +#include "atlas/grid.h" #include "atlas/grid/Distribution.h" #include "atlas/grid/Partitioner.h" -#include "atlas/grid.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" #include "atlas/grid/detail/partitioner/TransPartitioner.h" -#include "atlas/meshgenerator/StructuredMeshGenerator.h" +#include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/output/Gmsh.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/trans/Trans.h" #include "atlas/trans/VorDivToUV.h" -#include "atlas/array/MakeView.h" -#include "tests/AtlasTestEnvironment.h" -#include "eckit/io/DataHandle.h" #include "eckit/filesystem/PathName.h" +#include "eckit/io/DataHandle.h" +#include "tests/AtlasTestEnvironment.h" #ifdef ATLAS_HAVE_TRANS #include "atlas/trans/ifs/TransIFS.h" @@ -41,8 +41,8 @@ #endif using namespace eckit; -using atlas::grid::detail::partitioner::TransPartitioner; using atlas::grid::detail::partitioner::EqualRegionsPartitioner; +using atlas::grid::detail::partitioner::TransPartitioner; namespace atlas { namespace test { @@ -50,527 +50,488 @@ namespace test { //----------------------------------------------------------------------------- struct AtlasTransEnvironment : public AtlasTestEnvironment { - AtlasTransEnvironment(int argc, char * argv[]) : AtlasTestEnvironment(argc, argv) { - if( mpi::comm().size() == 1 ) - trans_use_mpi(false); - trans_init(); - } - - ~AtlasTransEnvironment() { - trans_finalize(); - } + AtlasTransEnvironment( int argc, char* argv[] ) : AtlasTestEnvironment( argc, argv ) { + if ( mpi::comm().size() == 1 ) trans_use_mpi( false ); + trans_init(); + } + + ~AtlasTransEnvironment() { trans_finalize(); } }; //----------------------------------------------------------------------------- -void read_rspecg(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( int i=0; i& rspecg, std::vector& nfrom, int& nfld ) { + Log::info() << "read_rspecg ...\n"; + nfld = 2; + if ( mpi::comm().rank() == 0 ) { + rspecg.resize( nfld * trans.spectralCoefficients() ); + for ( int i = 0; i < trans.spectralCoefficients(); ++i ) { + rspecg[i * nfld + 0] = ( i == 0 ? 1. : 0. ); // scalar field 1 + rspecg[i * nfld + 1] = ( i == 0 ? 2. : 0. ); // scalar field 2 + } } - } - nfrom.resize(nfld); - for (int jfld=0; jfld( spec ); - ASSERT( view.shape(1) >= 2 ); - for( int i=0; i( spec ); + 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 + view( i, 1 ) = ( i == 0 ? 2. : 0. ); // scalar field 2 + } } - } - Log::info() << "read_rspecg ... done" << std::endl; + Log::info() << "read_rspecg ... done" << std::endl; } //----------------------------------------------------------------------------- -CASE( "test_trans_distribution_matches_atlas" ) -{ - EXPECT( grid::Partitioner::exists("trans") ); - +CASE( "test_trans_distribution_matches_atlas" ) { + EXPECT( grid::Partitioner::exists( "trans" ) ); - // Create grid and trans object - Grid g( "N80" ); + // Create grid and trans object + Grid g( "N80" ); - EXPECT( grid::StructuredGrid(g).ny() == 160 ); + EXPECT( grid::StructuredGrid( g ).ny() == 160 ); - auto trans_partitioner = new TransPartitioner(); - grid::Partitioner partitioner( trans_partitioner ); - grid::Distribution distribution( g, partitioner ); + auto trans_partitioner = new TransPartitioner(); + grid::Partitioner partitioner( trans_partitioner ); + grid::Distribution distribution( g, partitioner ); - trans::TransIFS trans( g, 159 ); - ::Trans_t* t = trans; + trans::TransIFS trans( g, 159 ); + ::Trans_t* t = trans; - ATLAS_DEBUG_VAR( trans.truncation() ); - EXPECT( trans.truncation() == 159 ); + ATLAS_DEBUG_VAR( trans.truncation() ); + EXPECT( trans.truncation() == 159 ); - // -------------- do checks -------------- // - EXPECT( t->nproc == mpi::comm().size() ); - EXPECT( t->myproc == mpi::comm().rank()+1 ); + // -------------- do checks -------------- // + EXPECT( t->nproc == mpi::comm().size() ); + EXPECT( t->myproc == mpi::comm().rank() + 1 ); + if ( mpi::comm().rank() == 0 ) // all tasks do the same, so only one needs to check + { + int max_nb_regions_EW( 0 ); + for ( int j = 0; j < trans_partitioner->nb_bands(); ++j ) + max_nb_regions_EW = std::max( max_nb_regions_EW, trans_partitioner->nb_regions( j ) ); - if( mpi::comm().rank() == 0 ) // all tasks do the same, so only one needs to check - { - int max_nb_regions_EW(0); - for( int j=0; jnb_bands(); ++j ) - max_nb_regions_EW = std::max(max_nb_regions_EW, trans_partitioner->nb_regions(j)); - - EXPECT( t->n_regions_NS == trans_partitioner->nb_bands() ); - EXPECT( t->n_regions_EW == max_nb_regions_EW ); + EXPECT( t->n_regions_NS == trans_partitioner->nb_bands() ); + EXPECT( t->n_regions_EW == max_nb_regions_EW ); - EXPECT( distribution.nb_partitions() == mpi::comm().size() ); - EXPECT( distribution.partition().size() == g.size() ); + EXPECT( distribution.nb_partitions() == mpi::comm().size() ); + EXPECT( distribution.partition().size() == g.size() ); - std::vector npts(distribution.nb_partitions(),0); + std::vector npts( distribution.nb_partitions(), 0 ); - for(size_t j = 0; j < g.size(); ++j) - ++npts[distribution.partition(j)]; + for ( size_t j = 0; j < g.size(); ++j ) + ++npts[distribution.partition( j )]; - EXPECT( t->ngptotg == g.size() ); - EXPECT( t->ngptot == npts[mpi::comm().rank()] ); - EXPECT( t->ngptotmx == *std::max_element(npts.begin(),npts.end()) ); + EXPECT( t->ngptotg == g.size() ); + EXPECT( t->ngptot == npts[mpi::comm().rank()] ); + EXPECT( t->ngptotmx == *std::max_element( npts.begin(), npts.end() ) ); - // array::LocalView n_regions ( trans.n_regions() ) ; - for( int j=0; jnb_bands(); ++j ) - EXPECT( t->n_regions[j] == trans_partitioner->nb_regions(j) ); - } + // array::LocalView n_regions ( trans.n_regions() ) ; + for ( int j = 0; j < trans_partitioner->nb_bands(); ++j ) + EXPECT( t->n_regions[j] == trans_partitioner->nb_regions( j ) ); + } } -CASE( "test_trans_options" ) -{ - util::Config opts ( - option::fft("FFTW") | - option::split_latitudes(false) | - option::read_legendre("readfile") ); - Log::info() << "trans_opts = " << opts << std::endl; +CASE( "test_trans_options" ) { + util::Config opts( option::fft( "FFTW" ) | option::split_latitudes( false ) | option::read_legendre( "readfile" ) ); + Log::info() << "trans_opts = " << opts << std::endl; } #ifdef TRANS_HAVE_IO -CASE( "test_write_read_cache" ) -{ - Log::info() << "test_write_read_cache" << std::endl; - using namespace trans; - if( mpi::comm().size() == 1 ) { - // Create trans that will write file - Trans trans_write_F24( Grid("F24"), 23, option::write_legendre("cached_legendre_coeffs-F24") | option::flt(false) ); - Trans trans_write_N24( Grid("N24"), 23, option::write_legendre("cached_legendre_coeffs-N24") | option::flt(false) ); - Trans trans_write_O24( Grid("O24"), 23, option::write_legendre("cached_legendre_coeffs-O24") | option::flt(false) ); - - // Create trans that will read from file - Trans trans_read_F24( Grid("F24"), 23, option::read_legendre("cached_legendre_coeffs-F24") | option::flt(false) ); - Trans trans_read_N24( Grid("N24"), 23, option::read_legendre("cached_legendre_coeffs-N24") | option::flt(false) ); - Trans trans_read_O24( Grid("O24"), 23, option::read_legendre("cached_legendre_coeffs-O24") | option::flt(false) ); - - LegendreCache legendre_cache_F24( "cached_legendre_coeffs-F24" ); - LegendreCache legendre_cache_N24( "cached_legendre_coeffs-N24" ); - LegendreCache legendre_cache_O24( "cached_legendre_coeffs-O24" ); - - Trans trans_cache_F24( legendre_cache_F24, Grid("F24"), 23, option::flt(false) ); - Trans trans_cache_N24( legendre_cache_N24, Grid("N24"), 23, option::flt(false) ); - Trans trans_cache_O24( legendre_cache_O24, Grid("O24"), 23, option::flt(false) ); - } +CASE( "test_write_read_cache" ) { + Log::info() << "test_write_read_cache" << std::endl; + using namespace trans; + if ( mpi::comm().size() == 1 ) { + // Create trans that will write file + Trans trans_write_F24( Grid( "F24" ), 23, + option::write_legendre( "cached_legendre_coeffs-F24" ) | option::flt( false ) ); + Trans trans_write_N24( Grid( "N24" ), 23, + option::write_legendre( "cached_legendre_coeffs-N24" ) | option::flt( false ) ); + Trans trans_write_O24( Grid( "O24" ), 23, + option::write_legendre( "cached_legendre_coeffs-O24" ) | option::flt( false ) ); + + // Create trans that will read from file + Trans trans_read_F24( Grid( "F24" ), 23, + option::read_legendre( "cached_legendre_coeffs-F24" ) | option::flt( false ) ); + Trans trans_read_N24( Grid( "N24" ), 23, + option::read_legendre( "cached_legendre_coeffs-N24" ) | option::flt( false ) ); + Trans trans_read_O24( Grid( "O24" ), 23, + option::read_legendre( "cached_legendre_coeffs-O24" ) | option::flt( false ) ); + + LegendreCache legendre_cache_F24( "cached_legendre_coeffs-F24" ); + LegendreCache legendre_cache_N24( "cached_legendre_coeffs-N24" ); + LegendreCache legendre_cache_O24( "cached_legendre_coeffs-O24" ); + + Trans trans_cache_F24( legendre_cache_F24, Grid( "F24" ), 23, option::flt( false ) ); + Trans trans_cache_N24( legendre_cache_N24, Grid( "N24" ), 23, option::flt( false ) ); + Trans trans_cache_O24( legendre_cache_O24, Grid( "O24" ), 23, option::flt( false ) ); + } } #endif +CASE( "test_distspec" ) { + trans::TransIFS trans( Grid( "F80" ), 159 ); + Log::info() << "Trans initialized" << std::endl; + std::vector rspecg; + std::vector nfrom; + int nfld; + Log::info() << "Read rspecg" << std::endl; + read_rspecg( trans, rspecg, nfrom, nfld ); + + std::vector rspec( nfld * trans.trans()->nspec2 ); + std::vector nto( nfld, 1 ); + std::vector rgp( nfld * trans.trans()->ngptot ); + std::vector rgpg( nfld * trans.grid().size() ); + std::vector specnorms( nfld, 0 ); + + trans.distspec( nfld, nfrom.data(), rspecg.data(), rspec.data() ); + trans.specnorm( nfld, rspec.data(), specnorms.data() ); + trans.invtrans( nfld, rspec.data(), rgp.data() ); + trans.gathgrid( nfld, nto.data(), rgp.data(), rgpg.data() ); + + if ( mpi::comm().rank() == 0 ) { + EXPECT( eckit::types::is_approximately_equal( specnorms[0], 1., 1.e-10 ) ); + EXPECT( eckit::types::is_approximately_equal( specnorms[1], 2., 1.e-10 ) ); + } -CASE( "test_distspec" ) -{ - trans::TransIFS trans( Grid("F80"), 159 ); - Log::info() << "Trans initialized" << std::endl; - std::vector rspecg; - std::vector nfrom; - int nfld; - Log::info() << "Read rspecg" << std::endl; - read_rspecg(trans,rspecg,nfrom,nfld); - - std::vector rspec(nfld*trans.trans()->nspec2); - std::vector nto(nfld,1); - std::vector rgp(nfld*trans.trans()->ngptot); - std::vector rgpg(nfld*trans.grid().size()); - std::vector specnorms(nfld,0); - - trans.distspec( nfld, nfrom.data(), rspecg.data(), rspec.data() ); - trans.specnorm( nfld, rspec.data(), specnorms.data() ); - trans.invtrans( nfld, rspec.data(), rgp.data() ); - trans.gathgrid( nfld, nto.data(), rgp.data(), rgpg.data() ); - - if( mpi::comm().rank() == 0 ) { - 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" << std::endl; + Log::info() << "end test_distspec" << std::endl; } -CASE( "test_distspec_speconly" ) -{ - functionspace::Spectral fs(159); - int nfld = 2; - Field glb = fs.createField(option::global()|option::levels(nfld)); - read_rspecg(glb); +CASE( "test_distspec_speconly" ) { + functionspace::Spectral fs( 159 ); + int nfld = 2; + Field glb = fs.createField( option::global() | option::levels( nfld ) ); + read_rspecg( glb ); - std::vector specnorms(nfld,0); + std::vector specnorms( nfld, 0 ); - Field dist = fs.createField(glb); + Field dist = fs.createField( glb ); - fs.scatter(glb,dist); - fs.norm(dist,specnorms); + fs.scatter( glb, dist ); + fs.norm( dist, specnorms ); - if( mpi::comm().rank() == 0 ) { - 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 ( mpi::comm().rank() == 0 ) { + 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; } -CASE( "test_distribution" ) -{ - Grid g( "O80" ); - - Log::info() << "test_distribution" << std::endl; - - grid::Distribution d_trans = grid::Partitioner( new TransPartitioner() ).partition(g); - Log::info() << "trans distribution created" << std::endl; +CASE( "test_distribution" ) { + Grid g( "O80" ); + Log::info() << "test_distribution" << std::endl; - grid::Distribution d_eqreg = grid::Partitioner( new EqualRegionsPartitioner() ).partition(g); - Log::info() << "eqregions distribution created" << std::endl; + grid::Distribution d_trans = grid::Partitioner( new TransPartitioner() ).partition( g ); + Log::info() << "trans distribution created" << std::endl; - if( mpi::comm().rank() == 0 ) - { - EXPECT( d_trans.nb_partitions() == d_eqreg.nb_partitions() ); - EXPECT( d_trans.max_pts() == d_eqreg.max_pts() ); - EXPECT( d_trans.min_pts() == d_eqreg.min_pts() ); + grid::Distribution d_eqreg = grid::Partitioner( new EqualRegionsPartitioner() ).partition( g ); + Log::info() << "eqregions distribution created" << std::endl; - EXPECT( d_trans.nb_pts() == d_eqreg.nb_pts() ); - } + if ( mpi::comm().rank() == 0 ) { + EXPECT( d_trans.nb_partitions() == d_eqreg.nb_partitions() ); + EXPECT( d_trans.max_pts() == d_eqreg.max_pts() ); + EXPECT( d_trans.min_pts() == d_eqreg.min_pts() ); + EXPECT( d_trans.nb_pts() == d_eqreg.nb_pts() ); + } } -CASE( "test_generate_mesh" ) -{ - Log::info() << "test_generate_mesh" << std::endl; - Grid g( "O80" ); - meshgenerator::StructuredMeshGenerator generate( atlas::util::Config - ("angle",0) - ("triangulate",true) - ); +CASE( "test_generate_mesh" ) { + Log::info() << "test_generate_mesh" << std::endl; + Grid g( "O80" ); + meshgenerator::StructuredMeshGenerator generate( atlas::util::Config( "angle", 0 )( "triangulate", true ) ); - Mesh m_default = generate( g ); + Mesh m_default = generate( g ); - Log::info() << "trans_distribution" << std::endl; - grid::Distribution trans_distribution = grid::Partitioner( new TransPartitioner() ).partition(g); - Mesh m_trans = generate( g, trans_distribution ); + Log::info() << "trans_distribution" << std::endl; + grid::Distribution trans_distribution = grid::Partitioner( new TransPartitioner() ).partition( g ); + Mesh m_trans = generate( g, trans_distribution ); - Log::info() << "eqreg_distribution" << std::endl; - grid::Distribution eqreg_distribution = grid::Partitioner( new EqualRegionsPartitioner() ).partition(g); - Mesh m_eqreg = generate( g, eqreg_distribution ); + Log::info() << "eqreg_distribution" << std::endl; + grid::Distribution eqreg_distribution = grid::Partitioner( new EqualRegionsPartitioner() ).partition( g ); + Mesh m_eqreg = generate( g, eqreg_distribution ); - array::ArrayView p_default = array::make_view( m_default.nodes().partition() ); - array::ArrayView p_trans = array::make_view( m_trans .nodes().partition() ); - array::ArrayView p_eqreg = array::make_view( m_eqreg .nodes().partition() ); + array::ArrayView p_default = array::make_view( m_default.nodes().partition() ); + array::ArrayView p_trans = array::make_view( m_trans.nodes().partition() ); + array::ArrayView p_eqreg = array::make_view( m_eqreg.nodes().partition() ); - for( size_t j=0; j( option::name( "spf" ) ); + Field gpf = nodal.createField( option::name( "gpf" ) ); - Field spf = spectral.createField(option::name("spf")); - Field gpf = nodal. createField(option::name("gpf")); + EXPECT_NO_THROW( trans.dirtrans( gpf, spf ) ); + EXPECT_NO_THROW( trans.invtrans( spf, gpf ) ); + FieldSet gpfields; + gpfields.add( gpf ); + FieldSet spfields; + spfields.add( spf ); - EXPECT_NO_THROW( trans.dirtrans(gpf,spf) ); - EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); - - FieldSet gpfields; gpfields.add(gpf); - FieldSet spfields; spfields.add(spf); - - EXPECT_NO_THROW( trans.dirtrans(gpfields,spfields) ); - EXPECT_NO_THROW( trans.invtrans(spfields,gpfields) ); - - gpfields.add(gpf); - EXPECT_THROWS_AS(trans.dirtrans(gpfields,spfields),eckit::SeriousBug); + EXPECT_NO_THROW( trans.dirtrans( gpfields, spfields ) ); + EXPECT_NO_THROW( trans.invtrans( spfields, gpfields ) ); + gpfields.add( gpf ); + EXPECT_THROWS_AS( trans.dirtrans( gpfields, spfields ), eckit::SeriousBug ); } +CASE( "test_nomesh" ) { + Log::info() << "test_spectral_fields" << std::endl; -CASE( "test_nomesh" ) -{ - Log::info() << "test_spectral_fields" << std::endl; - - Grid g( "O48" ); - trans::Trans trans(g,47) ; + Grid g( "O48" ); + trans::Trans trans( g, 47 ); - functionspace::Spectral spectral (trans); - functionspace::StructuredColumns gridpoints (g); + functionspace::Spectral spectral( trans ); + functionspace::StructuredColumns gridpoints( g ); - Field spfg = spectral. createField(option::name("spf") | option::global()); - Field spf = spectral. createField(option::name("spf")); - Field gpf = gridpoints.createField(option::name("gpf")); - Field gpfg = gridpoints.createField(option::name("gpf") | option::global()); + Field spfg = spectral.createField( option::name( "spf" ) | option::global() ); + Field spf = spectral.createField( option::name( "spf" ) ); + Field gpf = gridpoints.createField( option::name( "gpf" ) ); + Field gpfg = gridpoints.createField( option::name( "gpf" ) | option::global() ); - array::ArrayView spg = array::make_view(spfg); - if( mpi::comm().rank() == 0 ) { - spg.assign(0.); - spg(0) = 4.; - } + array::ArrayView spg = array::make_view( spfg ); + if ( mpi::comm().rank() == 0 ) { + spg.assign( 0. ); + spg( 0 ) = 4.; + } - EXPECT_NO_THROW( spectral.scatter(spfg,spf) ); + EXPECT_NO_THROW( spectral.scatter( spfg, spf ) ); - if( mpi::comm().rank() == 0 ) { - array::ArrayView sp = array::make_view(spf); - EXPECT( eckit::types::is_approximately_equal( sp(0), 4., 0.001 )); - for( size_t jp=0; jp sp = array::make_view( spf ); + EXPECT( eckit::types::is_approximately_equal( sp( 0 ), 4., 0.001 ) ); + for ( size_t jp = 0; jp < sp.size(); ++jp ) { + Log::debug() << "sp(" << jp << ") : " << sp( jp ) << std::endl; + } } - } - EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); + EXPECT_NO_THROW( trans.invtrans( spf, gpf ) ); - EXPECT_NO_THROW( gridpoints.gather(gpf,gpfg) ); + EXPECT_NO_THROW( gridpoints.gather( gpf, gpfg ) ); - if( mpi::comm().rank() == 0 ) { - array::ArrayView gpg = array::make_view(gpfg); - for( size_t jp=0; jp gpg = array::make_view( gpfg ); + for ( size_t jp = 0; jp < gpg.size(); ++jp ) { + EXPECT( eckit::types::is_approximately_equal( gpg( jp ), 4., 0.001 ) ); + Log::debug() << "gpg(" << jp << ") : " << gpg( jp ) << std::endl; + } } - } - EXPECT_NO_THROW( gridpoints.scatter(gpfg,gpf) ); + EXPECT_NO_THROW( gridpoints.scatter( gpfg, gpf ) ); - EXPECT_NO_THROW( trans.dirtrans(gpf,spf) ); + EXPECT_NO_THROW( trans.dirtrans( gpf, spf ) ); - EXPECT_NO_THROW( spectral.gather(spf,spfg) ); + EXPECT_NO_THROW( spectral.gather( spf, spfg ) ); - if( mpi::comm().rank() == 0 ) { - EXPECT( eckit::types::is_approximately_equal( spg(0), 4., 0.001 )); - } + if ( mpi::comm().rank() == 0 ) { EXPECT( eckit::types::is_approximately_equal( spg( 0 ), 4., 0.001 ) ); } } +CASE( "test_trans_factory" ) { + Log::info() << "test_trans_factory" << std::endl; -CASE( "test_trans_factory" ) -{ - Log::info() << "test_trans_factory" << std::endl; - - trans::TransFactory::list( Log::info() ); - Log::info() << std::endl; + trans::TransFactory::list( Log::info() ); + Log::info() << std::endl; - functionspace::StructuredColumns gp ( Grid("O48") ); - functionspace::Spectral sp ( 47 ); + functionspace::StructuredColumns gp( Grid( "O48" ) ); + functionspace::Spectral sp( 47 ); - trans::Trans trans1 = trans::Trans(gp,sp); - EXPECT( bool(trans1) == true ); + trans::Trans trans1 = trans::Trans( gp, sp ); + EXPECT( bool( trans1 ) == true ); - trans::Trans trans2 = trans::Trans( Grid("O48"), 47 ); - EXPECT( bool(trans2) == true ); + trans::Trans trans2 = trans::Trans( Grid( "O48" ), 47 ); + EXPECT( bool( trans2 ) == true ); } -CASE( "test_trans_using_grid" ) -{ - Log::info() << "test_trans_using_grid" << std::endl; - - trans::Trans trans( Grid("O48"), 47 ); +CASE( "test_trans_using_grid" ) { + Log::info() << "test_trans_using_grid" << std::endl; - functionspace::StructuredColumns gp ( trans.grid() ); - functionspace::Spectral sp ( trans.truncation() ); + trans::Trans trans( Grid( "O48" ), 47 ); - Field spf = sp.createField(option::name("spf")); - Field gpf = gp.createField(option::name("gpf")); + functionspace::StructuredColumns gp( trans.grid() ); + functionspace::Spectral sp( trans.truncation() ); - EXPECT_NO_THROW( trans.dirtrans(gpf,spf) ); - EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); + Field spf = sp.createField( option::name( "spf" ) ); + Field gpf = gp.createField( option::name( "gpf" ) ); - FieldSet gpfields; gpfields.add(gpf); - FieldSet spfields; spfields.add(spf); + EXPECT_NO_THROW( trans.dirtrans( gpf, spf ) ); + EXPECT_NO_THROW( trans.invtrans( spf, gpf ) ); - EXPECT_NO_THROW( trans.dirtrans(gpfields,spfields) ); - EXPECT_NO_THROW( trans.invtrans(spfields,gpfields) ); + FieldSet gpfields; + gpfields.add( gpf ); + FieldSet spfields; + spfields.add( spf ); - gpfields.add(gpf); - EXPECT_THROWS_AS(trans.dirtrans(gpfields,spfields),eckit::SeriousBug); + EXPECT_NO_THROW( trans.dirtrans( gpfields, spfields ) ); + EXPECT_NO_THROW( trans.invtrans( spfields, gpfields ) ); + gpfields.add( gpf ); + EXPECT_THROWS_AS( trans.dirtrans( gpfields, spfields ), eckit::SeriousBug ); } -CASE( "test_trans_using_functionspace_NodeColumns" ) -{ - Log::info() << "test_trans_using_functionspace_NodeColumns" << std::endl; +CASE( "test_trans_using_functionspace_NodeColumns" ) { + Log::info() << "test_trans_using_functionspace_NodeColumns" << std::endl; - functionspace::NodeColumns gp ( MeshGenerator("structured").generate( Grid("O48") ) ); - functionspace::Spectral sp ( 47 ); + functionspace::NodeColumns gp( MeshGenerator( "structured" ).generate( Grid( "O48" ) ) ); + functionspace::Spectral sp( 47 ); - trans::Trans trans( gp, sp ); + trans::Trans trans( gp, sp ); - Field spf = sp.createField(option::name("spf")); - Field gpf = gp.createField(option::name("gpf")); + Field spf = sp.createField( option::name( "spf" ) ); + Field gpf = gp.createField( option::name( "gpf" ) ); - EXPECT_NO_THROW( trans.dirtrans(gpf,spf) ); - EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); + EXPECT_NO_THROW( trans.dirtrans( gpf, spf ) ); + EXPECT_NO_THROW( trans.invtrans( spf, gpf ) ); - FieldSet gpfields; gpfields.add(gpf); - FieldSet spfields; spfields.add(spf); + FieldSet gpfields; + gpfields.add( gpf ); + FieldSet spfields; + spfields.add( spf ); - EXPECT_NO_THROW( trans.dirtrans(gpfields,spfields) ); - EXPECT_NO_THROW( trans.invtrans(spfields,gpfields) ); - - gpfields.add(gpf); - EXPECT_THROWS_AS(trans.dirtrans(gpfields,spfields),eckit::SeriousBug); + EXPECT_NO_THROW( trans.dirtrans( gpfields, spfields ) ); + EXPECT_NO_THROW( trans.invtrans( spfields, gpfields ) ); + gpfields.add( gpf ); + EXPECT_THROWS_AS( trans.dirtrans( gpfields, spfields ), eckit::SeriousBug ); } -CASE( "test_trans_using_functionspace_StructuredColumns" ) -{ - Log::info() << "test_trans_using_functionspace_StructuredColumns" << std::endl; - - functionspace::StructuredColumns gp ( Grid("O48") ); - functionspace::Spectral sp ( 47 ); +CASE( "test_trans_using_functionspace_StructuredColumns" ) { + Log::info() << "test_trans_using_functionspace_StructuredColumns" << std::endl; - trans::Trans trans( gp, sp ); + functionspace::StructuredColumns gp( Grid( "O48" ) ); + functionspace::Spectral sp( 47 ); - Field spf = sp.createField(option::name("spf")); - Field gpf = gp.createField(option::name("gpf")); + trans::Trans trans( gp, sp ); - EXPECT_NO_THROW( trans.dirtrans(gpf,spf) ); - EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); + Field spf = sp.createField( option::name( "spf" ) ); + Field gpf = gp.createField( option::name( "gpf" ) ); - FieldSet gpfields; gpfields.add(gpf); - FieldSet spfields; spfields.add(spf); + EXPECT_NO_THROW( trans.dirtrans( gpf, spf ) ); + EXPECT_NO_THROW( trans.invtrans( spf, gpf ) ); - EXPECT_NO_THROW( trans.dirtrans(gpfields,spfields) ); - EXPECT_NO_THROW( trans.invtrans(spfields,gpfields) ); + FieldSet gpfields; + gpfields.add( gpf ); + FieldSet spfields; + spfields.add( spf ); - gpfields.add(gpf); - EXPECT_THROWS_AS(trans.dirtrans(gpfields,spfields),eckit::SeriousBug); + EXPECT_NO_THROW( trans.dirtrans( gpfields, spfields ) ); + EXPECT_NO_THROW( trans.invtrans( spfields, gpfields ) ); + gpfields.add( gpf ); + EXPECT_THROWS_AS( trans.dirtrans( gpfields, spfields ), eckit::SeriousBug ); } -CASE( "test_trans_MIR_lonlat" ) -{ - Log::info() << "test_trans_MIR_lonlat" << std::endl; - - Grid grid("L48"); - trans::Trans trans( grid, 47 ); - - // global fields - std::vector spf( trans.spectralCoefficients() ); - std::vector gpf( grid.size() ); - - if( mpi::comm().size() == 1 ) { - EXPECT_NO_THROW( trans.invtrans( 1, spf.data(), gpf.data(), option::global() ) ); - - EXPECT_NO_THROW( trans.dirtrans( 1, gpf.data(), spf.data(), option::global() ) ); - - } -} +CASE( "test_trans_MIR_lonlat" ) { + Log::info() << "test_trans_MIR_lonlat" << std::endl; -CASE( "test_trans_VorDivToUV") -{ - int nfld = 1; // TODO: test for nfld>1 - std::vector truncation_array{1};// truncation_array{159,160,1279}; - for( int i=0; i field_U ( nfld*nspec2 ); - std::vector field_V ( nfld*nspec2 ); - - vordiv_to_UV.execute( nspec2, nfld, field_vor.data(), field_div.data(), field_U.data(), field_V.data() ); - - // TODO: do some meaningful checks - Log::info() << "Trans library" << std::endl; - Log::info() << "U: " << std::endl; - for( int j=0; j field_U ( nfld*nspec2 ); - std::vector field_V ( nfld*nspec2 ); - - vordiv_to_UV.execute( nspec2, nfld, field_vor.data(), field_div.data(), field_U.data(), field_V.data() ); - - // TODO: do some meaningful checks - Log::info() << "Local transform" << std::endl; - Log::info() << "U: " << std::endl; - for( int j=0; j1 + std::vector truncation_array{1}; // truncation_array{159,160,1279}; + for ( int i = 0; i < truncation_array.size(); ++i ) { + int truncation = truncation_array[i]; + int nspec2 = ( truncation + 1 ) * ( truncation + 2 ); + + Log::info() << "truncation = " << truncation << std::endl; + + std::vector field_vor( nfld * nspec2, 0. ); + std::vector field_div( nfld * nspec2, 0. ); + + // TODO: initialise field_vor and field_div with something meaningful + field_vor[2 * nfld] = 1.; + Log::info() << "vor: " << std::endl; + for ( int j = 0; j < nfld * nspec2; j++ ) + Log::info() << field_vor[j] << " "; + Log::info() << std::endl; + + // With IFS + if ( trans::VorDivToUVFactory::has( "ifs" ) ) { + trans::VorDivToUV vordiv_to_UV( truncation, option::type( "ifs" ) ); + EXPECT( vordiv_to_UV.truncation() == truncation ); + + std::vector field_U( nfld * nspec2 ); + std::vector field_V( nfld * nspec2 ); + + vordiv_to_UV.execute( nspec2, nfld, field_vor.data(), field_div.data(), field_U.data(), field_V.data() ); + + // TODO: do some meaningful checks + Log::info() << "Trans library" << std::endl; + Log::info() << "U: " << std::endl; + for ( int j = 0; j < nfld * nspec2; j++ ) + Log::info() << field_U[j] << " "; + Log::info() << std::endl; + } + + // With Local + { + trans::VorDivToUV vordiv_to_UV( truncation, option::type( "local" ) ); + EXPECT( vordiv_to_UV.truncation() == truncation ); + + std::vector field_U( nfld * nspec2 ); + std::vector field_V( nfld * nspec2 ); + + vordiv_to_UV.execute( nspec2, nfld, field_vor.data(), field_div.data(), field_U.data(), field_V.data() ); + + // TODO: do some meaningful checks + Log::info() << "Local transform" << std::endl; + Log::info() << "U: " << std::endl; + for ( int j = 0; j < nfld * nspec2; j++ ) + Log::info() << field_U[j] << " "; + Log::info() << std::endl; + } } - - - } } - //----------------------------------------------------------------------------- } // namespace test } // namespace atlas - -int main(int argc, char **argv) { - return atlas::test::run< atlas::test::AtlasTransEnvironment >( argc, argv ); +int main( int argc, char** argv ) { + return atlas::test::run( argc, argv ); } diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index 034ab7d02..1023cdb1c 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -4,14 +4,13 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include -#include "atlas/library/Library.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/Spectral.h" @@ -19,15 +18,16 @@ #include "atlas/grid/Distribution.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" #include "atlas/grid/detail/partitioner/TransPartitioner.h" -#include "atlas/meshgenerator/StructuredMeshGenerator.h" +#include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/meshgenerator/StructuredMeshGenerator.h" +#include "atlas/option.h" #include "atlas/output/Gmsh.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/trans/Trans.h" -#include "atlas/util/Earth.h" #include "atlas/util/CoordinateEnums.h" -#include "atlas/option.h" +#include "atlas/util/Earth.h" #include "tests/AtlasTestEnvironment.h" @@ -41,148 +41,141 @@ namespace test { //----------------------------------------------------------------------------- struct AtlasTransEnvironment : public AtlasTestEnvironment { - AtlasTransEnvironment(int argc, char * argv[]) : AtlasTestEnvironment(argc, argv) { - if( mpi::comm().size() == 1 ) - trans_use_mpi(false); - trans_init(); - } - - ~AtlasTransEnvironment() { - trans_finalize(); - } + AtlasTransEnvironment( int argc, char* argv[] ) : AtlasTestEnvironment( argc, argv ) { + if ( mpi::comm().size() == 1 ) trans_use_mpi( false ); + trans_init(); + } + + ~AtlasTransEnvironment() { trans_finalize(); } }; /// @brief Compute magnitude of flow with rotation-angle beta /// (beta=0 --> zonal, beta=pi/2 --> meridional) -static void rotated_flow_magnitude(grid::StructuredGrid& grid, double var[], const double& beta) -{ - const double radius = util::Earth::radiusInMeters(); - const double USCAL = 20.; - const double pvel = USCAL/radius; - const double deg2rad = M_PI/180.; - - - size_t n(0); - for( size_t jlat=0; jlat zonal, beta=pi/2 --> meridional) -void rotated_flow_magnitude(const functionspace::NodeColumns& fs, Field& field, const double& beta) -{ - const double radius = util::Earth::radiusInMeters(); - const double USCAL = 20.; - const double pvel = USCAL/radius; - const double deg2rad = M_PI/180.; - - array::ArrayView lonlat_deg = array::make_view(fs.nodes().lonlat()); - array::ArrayView var = array::make_view(field); - - size_t nnodes = fs.nodes().size(); - for( size_t jnode=0; jnode lonlat_deg = array::make_view( fs.nodes().lonlat() ); + array::ArrayView var = array::make_view( field ); + + size_t nnodes = fs.nodes().size(); + for ( size_t jnode = 0; jnode < nnodes; ++jnode ) { + double x = lonlat_deg( jnode, LON ) * deg2rad; + double y = lonlat_deg( jnode, LAT ) * deg2rad; + 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; + var( jnode ) = std::sqrt( Ux * Ux + Uy * Uy ); + } } //----------------------------------------------------------------------------- -CASE( "test_invtrans_ifsStyle" ) -{ - std::string grid_uid("O80"); - grid::StructuredGrid g (grid_uid); - long N = g.ny()/2; - trans::TransIFS trans(g,2*N-1); - Log::info() << "Trans initialized" << std::endl; - std::vector rspecg; - int nfld = 1; - - std::vector init_gpg(trans.grid().size()); - std::vector init_gp (trans.trans()->ngptot); - std::vector init_sp (trans.trans()->nspec2); - std::vector nfrom(nfld,1); - if( mpi::comm().rank()==0) { - double beta = M_PI*0.5; - rotated_flow_magnitude(g,init_gpg.data(),beta); - } - trans.distgrid(nfld,nfrom.data(),init_gpg.data(),init_gp.data()); - trans.dirtrans(nfld,init_gp.data(),init_sp.data()); - - std::vector rgp(3*nfld*trans.trans()->ngptot); - double *no_vorticity(nullptr), *no_divergence(nullptr); - int nb_vordiv(0); - int nb_scalar(nfld); - trans.invtrans( nb_scalar, init_sp.data(), nb_vordiv, no_vorticity, no_divergence, rgp.data(), option::scalar_derivatives(true) ); - - std::vector nto(nfld,1); - std::vector rgpg(3*nfld*trans.grid().size()); - - trans.gathgrid( nfld, nto.data(), rgp.data(), rgpg.data() ); - - // Output - { - Mesh mesh = meshgenerator::StructuredMeshGenerator().generate(g); - functionspace::StructuredColumns gp(g); - output::Gmsh gmsh(grid_uid+"-grid.msh"); - Field scalar( "scalar",rgp.data(),array::make_shape(gp.size())); - Field scalar_dNS("scalar_dNS",rgp.data()+nfld*gp.size(),array::make_shape(gp.size())); - Field scalar_dEW("scalar_dEW",rgp.data()+2*nfld*gp.size(),array::make_shape(gp.size())); - gmsh.write(mesh); - gmsh.write(scalar,gp); - gmsh.write(scalar_dEW,gp); - gmsh.write(scalar_dNS,gp); - } +CASE( "test_invtrans_ifsStyle" ) { + std::string grid_uid( "O80" ); + grid::StructuredGrid g( grid_uid ); + long N = g.ny() / 2; + trans::TransIFS trans( g, 2 * N - 1 ); + Log::info() << "Trans initialized" << std::endl; + std::vector rspecg; + int nfld = 1; + + std::vector init_gpg( trans.grid().size() ); + std::vector init_gp( trans.trans()->ngptot ); + std::vector init_sp( trans.trans()->nspec2 ); + std::vector nfrom( nfld, 1 ); + if ( mpi::comm().rank() == 0 ) { + double beta = M_PI * 0.5; + rotated_flow_magnitude( g, init_gpg.data(), beta ); + } + trans.distgrid( nfld, nfrom.data(), init_gpg.data(), init_gp.data() ); + trans.dirtrans( nfld, init_gp.data(), init_sp.data() ); + + std::vector rgp( 3 * nfld * trans.trans()->ngptot ); + double *no_vorticity( nullptr ), *no_divergence( nullptr ); + int nb_vordiv( 0 ); + int nb_scalar( nfld ); + trans.invtrans( nb_scalar, init_sp.data(), nb_vordiv, no_vorticity, no_divergence, rgp.data(), + option::scalar_derivatives( true ) ); + + std::vector nto( nfld, 1 ); + std::vector rgpg( 3 * nfld * trans.grid().size() ); + + trans.gathgrid( nfld, nto.data(), rgp.data(), rgpg.data() ); + + // Output + { + Mesh mesh = meshgenerator::StructuredMeshGenerator().generate( g ); + functionspace::StructuredColumns gp( g ); + output::Gmsh gmsh( grid_uid + "-grid.msh" ); + Field scalar( "scalar", rgp.data(), array::make_shape( gp.size() ) ); + Field scalar_dNS( "scalar_dNS", rgp.data() + nfld * gp.size(), array::make_shape( gp.size() ) ); + Field scalar_dEW( "scalar_dEW", rgp.data() + 2 * nfld * gp.size(), array::make_shape( gp.size() ) ); + gmsh.write( mesh ); + gmsh.write( scalar, gp ); + gmsh.write( scalar_dEW, gp ); + gmsh.write( scalar_dNS, gp ); + } } - -CASE( "test_invtrans_grad" ) -{ - std::string grid_uid("O48"); - grid::StructuredGrid g ( grid_uid ); - Mesh mesh = meshgenerator::StructuredMeshGenerator().generate(g); - long N = g.ny()/2; - trans::Trans trans(g, 2*N-1); - functionspace::NodeColumns gp(mesh); - functionspace::Spectral sp(trans); - - Field scalar_sp = sp.createField(option::name("scalar_sp")); - Field scalar = gp.createField(option::name("scalar")); - Field grad = gp.createField(option::name("grad") | option::variables(2) ); - - // Initial condition - double beta = M_PI*0.5; - rotated_flow_magnitude(gp,scalar,beta); - - // Transform to spectral - trans.dirtrans(scalar,scalar_sp); - - // Inverse transform for gradient - trans.invtrans_grad(scalar_sp,grad); - - gp.haloExchange(grad); - - // Output - { - Mesh mesh = meshgenerator::StructuredMeshGenerator().generate(g); - functionspace::StructuredColumns gp(g); - output::Gmsh gmsh(grid_uid+"-nodes.msh"); - gmsh.write(mesh); - gmsh.write(scalar,gp); - gmsh.write(grad,gp); - } +CASE( "test_invtrans_grad" ) { + std::string grid_uid( "O48" ); + grid::StructuredGrid g( grid_uid ); + Mesh mesh = meshgenerator::StructuredMeshGenerator().generate( g ); + long N = g.ny() / 2; + trans::Trans trans( g, 2 * N - 1 ); + functionspace::NodeColumns gp( mesh ); + functionspace::Spectral sp( trans ); + + Field scalar_sp = sp.createField( option::name( "scalar_sp" ) ); + Field scalar = gp.createField( option::name( "scalar" ) ); + Field grad = gp.createField( option::name( "grad" ) | option::variables( 2 ) ); + + // Initial condition + double beta = M_PI * 0.5; + rotated_flow_magnitude( gp, scalar, beta ); + + // Transform to spectral + trans.dirtrans( scalar, scalar_sp ); + + // Inverse transform for gradient + trans.invtrans_grad( scalar_sp, grad ); + + gp.haloExchange( grad ); + + // Output + { + Mesh mesh = meshgenerator::StructuredMeshGenerator().generate( g ); + functionspace::StructuredColumns gp( g ); + output::Gmsh gmsh( grid_uid + "-nodes.msh" ); + gmsh.write( mesh ); + gmsh.write( scalar, gp ); + gmsh.write( grad, gp ); + } } //----------------------------------------------------------------------------- @@ -190,8 +183,6 @@ CASE( "test_invtrans_grad" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { - return atlas::test::run< atlas::test::AtlasTransEnvironment >( argc, argv ); +int main( int argc, char** argv ) { + return atlas::test::run( argc, argv ); } - diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 98142c043..ce261c94d 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -4,40 +4,40 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ - #include -#include "atlas/library/Library.h" +#include "atlas/array/MakeView.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/Spectral.h" #include "atlas/functionspace/StructuredColumns.h" +#include "atlas/grid.h" #include "atlas/grid/Distribution.h" #include "atlas/grid/Partitioner.h" -#include "atlas/grid.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" #include "atlas/grid/detail/partitioner/TransPartitioner.h" -#include "atlas/meshgenerator/StructuredMeshGenerator.h" +#include "atlas/library/Library.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/output/Gmsh.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Trace.h" #include "atlas/trans/Trans.h" +#include "atlas/trans/local/FourierTransforms.h" #include "atlas/trans/local/LegendrePolynomials.h" #include "atlas/trans/local/LegendreTransforms.h" -#include "atlas/trans/local/FourierTransforms.h" -#include "atlas/array/MakeView.h" -#include "atlas/runtime/Trace.h" #include "transi/trans.h" #include "tests/AtlasTestEnvironment.h" -#include #include +#include using namespace eckit; @@ -51,146 +51,157 @@ namespace test { //----------------------------------------------------------------------------- struct AtlasTransEnvironment : public AtlasTestEnvironment { - AtlasTransEnvironment(int argc, char * argv[]) : AtlasTestEnvironment(argc, argv) { - if( mpi::comm().size() == 1 ) - trans_use_mpi(false); - trans_init(); - } - - ~AtlasTransEnvironment() { - trans_finalize(); - } + AtlasTransEnvironment( int argc, char* argv[] ) : AtlasTestEnvironment( argc, argv ) { + if ( mpi::comm().size() == 1 ) trans_use_mpi( false ); + trans_init(); + } + + ~AtlasTransEnvironment() { trans_finalize(); } }; //----------------------------------------------------------------------------- -void compute_legendre( - const size_t trc, // truncation (in) - const double& lat, // latitude in radians (in) - array::ArrayView& zlfpol)// values of associated Legendre functions, size (trc+1)*trc/2 (out) +void compute_legendre( const size_t trc, // truncation (in) + const double& lat, // latitude in radians (in) + array::ArrayView& zlfpol ) // values of + // associated + // Legendre + // functions, size + // (trc+1)*trc/2 + // (out) { - trans::compute_legendre_polynomials(trc,lat,zlfpol.data()); + trans::compute_legendre_polynomials( trc, lat, zlfpol.data() ); } //----------------------------------------------------------------------------- -void legendre_transform( - const size_t trc, // truncation (in) - const size_t trcFT, // truncation for Fourier transformation (in) - array::ArrayView& rlegReal,// values of associated Legendre functions, size (trc+1)*trc/2 (out) - array::ArrayView& rlegImag,// values of associated Legendre functions, size (trc+1)*trc/2 (out) - const array::ArrayView& zlfpol, // values of associated Legendre functions, size (trc+1)*trc/2 (in) - const double rspecg[]) // spectral data, size (trc+1)*trc (in) +void legendre_transform( const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + array::ArrayView& rlegReal, // values of associated Legendre + // functions, size (trc+1)*trc/2 + // (out) + array::ArrayView& rlegImag, // values of associated Legendre + // functions, size (trc+1)*trc/2 + // (out) + const array::ArrayView& zlfpol, // values of associated Legendre + // functions, size (trc+1)*trc/2 + // (in) + const double rspecg[] ) // spectral data, size (trc+1)*trc (in) { trans::invtrans_legendre( trc, trcFT, trc, zlfpol.data(), 1, rspecg, rlegReal.data(), rlegImag.data() ); } //----------------------------------------------------------------------------- -double fourier_transform( - const size_t trcFT, - array::ArrayView& rlegReal,// values of associated Legendre functions, size (trc+1)*trc/2 (out) - array::ArrayView& rlegImag,// values of associated Legendre functions, size (trc+1)*trc/2 (out) - const double lon) // radians +double fourier_transform( const size_t trcFT, array::ArrayView& rlegReal, // values of associated Legendre + // functions, size (trc+1)*trc/2 + // (out) + array::ArrayView& rlegImag, // values of associated Legendre + // functions, size (trc+1)*trc/2 + // (out) + const double lon ) // radians { - double gp[1]; - trans::invtrans_fourier( trcFT, lon, 1, rlegReal.data(), rlegImag.data(), gp ); - return gp[0]; + double gp[1]; + trans::invtrans_fourier( trcFT, lon, 1, rlegReal.data(), rlegImag.data(), gp ); + return gp[0]; } //----------------------------------------------------------------------------- -// Routine to compute the spectral transform by using a local Fourier transformation +// Routine to compute the spectral transform by using a local Fourier +// transformation // for a single point // // Author: // Andreas Mueller *ECMWF* // -double spectral_transform_point( - const size_t trc, // truncation (in) - const size_t trcFT, // truncation for Fourier transformation (in) - const double lon, // longitude in radians (in) - const double lat, // latitude in radians (in) - const double rspecg[]) // spectral data, size (trc+1)*trc (in) +double spectral_transform_point( const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + const double lon, // longitude in radians (in) + const double lat, // latitude in radians (in) + const double rspecg[] ) // spectral data, size (trc+1)*trc (in) { - int N = (trc+2)*(trc+1)/2; + int N = ( trc + 2 ) * ( trc + 1 ) / 2; ATLAS_TRACE(); - atlas::array::ArrayT zlfpol_(N); - atlas::array::ArrayView zlfpol = make_view(zlfpol_); + atlas::array::ArrayT zlfpol_( N ); + atlas::array::ArrayView zlfpol = make_view( zlfpol_ ); - atlas::array::ArrayT rlegReal_(trcFT+1); - atlas::array::ArrayView rlegReal = make_view(rlegReal_); + atlas::array::ArrayT rlegReal_( trcFT + 1 ); + atlas::array::ArrayView rlegReal = make_view( rlegReal_ ); - atlas::array::ArrayT rlegImag_(trcFT+1); - atlas::array::ArrayView rlegImag = make_view(rlegImag_); + atlas::array::ArrayT rlegImag_( trcFT + 1 ); + atlas::array::ArrayView rlegImag = make_view( rlegImag_ ); // Legendre transform: - compute_legendre(trc, lat, zlfpol); - legendre_transform(trc, trcFT, rlegReal, rlegImag, zlfpol, rspecg); + compute_legendre( trc, lat, zlfpol ); + legendre_transform( trc, trcFT, rlegReal, rlegImag, zlfpol, rspecg ); // Fourier transform: - return fourier_transform(trcFT, rlegReal, rlegImag, lon); + return fourier_transform( trcFT, rlegReal, rlegImag, lon ); } - //----------------------------------------------------------------------------- -// Routine to compute the spectral transform by using a local Fourier transformation -// for a grid (same latitude for all longitudes, allows to compute Legendre functions +// Routine to compute the spectral transform by using a local Fourier +// transformation +// for a grid (same latitude for all longitudes, allows to compute Legendre +// functions // once for all longitudes) // // Author: // Andreas Mueller *ECMWF* // -void spectral_transform_grid( - const size_t trc, // truncation (in) - const size_t trcFT, // truncation for Fourier transformation (in) - const Grid grid, // call with something like Grid("O32") - const double rspecg[], // spectral data, size (trc+1)*trc (in) - double rgp[], // resulting grid point data (out) - const bool pointwise) // use point function for unstructured mesh for testing purposes +void spectral_transform_grid( const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + const Grid grid, // call with something like Grid("O32") + const double rspecg[], // spectral data, size (trc+1)*trc (in) + double rgp[], // resulting grid point data (out) + const bool pointwise ) // use point function for unstructured mesh for + // testing purposes { - std::ostream& out = Log::info(); // just for debugging - int N = (trc+2)*(trc+1)/2; + std::ostream& out = Log::info(); // just for debugging + int N = ( trc + 2 ) * ( trc + 1 ) / 2; ATLAS_TRACE(); - atlas::array::ArrayT zlfpol_(N); - atlas::array::ArrayView zlfpol = make_view(zlfpol_); + atlas::array::ArrayT zlfpol_( N ); + atlas::array::ArrayView zlfpol = make_view( zlfpol_ ); - atlas::array::ArrayT rlegReal_(trcFT+1); - atlas::array::ArrayView rlegReal = make_view(rlegReal_); + atlas::array::ArrayT rlegReal_( trcFT + 1 ); + atlas::array::ArrayView rlegReal = make_view( rlegReal_ ); - atlas::array::ArrayT rlegImag_(trcFT+1); - atlas::array::ArrayView rlegImag = make_view(rlegImag_); + atlas::array::ArrayT rlegImag_( trcFT + 1 ); + atlas::array::ArrayView rlegImag = make_view( rlegImag_ ); int idx = 0; - if( grid::StructuredGrid(grid) ) { - grid::StructuredGrid g(grid); - for( size_t j=0; j0 ) rft *= 2.; // the famous factor 2 that noone really understands - if( imag==0 ) { - rft *= loncos; - } else { + if ( m > 0 ) rft *= 2.; // the famous factor 2 that noone really understands + if ( imag == 0 ) { rft *= loncos; } + else { rft *= -lonsin; } - // Legendre part of the spherical harmonics (following http://mathworld.wolfram.com/SphericalHarmonic.html - // multiplied with -2*sqrt(pi) due to different normalization and different coordinates): + // Legendre part of the spherical harmonics (following + // http://mathworld.wolfram.com/SphericalHarmonic.html + // multiplied with -2*sqrt(pi) due to different normalization and different + // coordinates): // (can also be computed on http://www.wolframalpha.com with: // LegendreP[n, m, x]/Sqrt[1/2*Integrate[LegendreP[n, m, y]^2, {y, -1, 1}]]) // n, m need to be replaced by hand with the correct values - // (otherwise the command will be too long for the free version of wolframalpha) + // (otherwise the command will be too long for the free version of + // wolframalpha) // 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==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==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==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==21 && n==21 ) - return (std::sqrt(1.4465680375575e12)*std::pow(latcos,21))/524288.*rft; - if ( m==22 && n==22 ) - return (15*std::sqrt(2.63012370465e10)*std::pow(latcos,22))/1.048576e6*rft; - if ( m==23 && n==23 ) - return (15*std::sqrt(107492012277)*std::pow(latcos,23))/2.097152e6*rft; - if ( m==24 && n==24 ) - return (105*std::sqrt(35830670759)*std::pow(latcos,24))/8.388608e6*rft; - if ( m==25 && n==25 ) - return (21*std::sqrt(9.136821043545e11)*std::pow(latcos,25))/8.388608e6*rft; - if ( m==26 && n==26 ) - return (21*std::sqrt(3.7250116562145e12)*std::pow(latcos,26))/1.6777216e7*rft; - if ( m==27 && n==27 ) - return (7*std::sqrt(136583760727865.)*std::pow(latcos,27))/3.3554432e7*rft; - if ( m==28 && n==28 ) - return (std::sqrt(2.7248460265209068e16)*std::pow(latcos,28))/6.7108864e7*rft; - if ( m==29 && n==29 ) - return (std::sqrt(110873045217057585.)*std::pow(latcos,29))/1.34217728e8*rft; - if ( m==30 && n==30 ) - return (std::sqrt(450883717216034179.)*std::pow(latcos,30))/2.68435456e8*rft; - if ( m==31 && n==31 ) - return (21*std::sqrt(1.0389025742304935e15)*std::pow(latcos,31))/2.68435456e8*rft; - if ( m==32 && n==32 ) - return (21*std::sqrt(6.752866732498208e16)*std::pow(latcos,32))/2.147483648e9*rft; - if ( m==33 && n==33 ) - return (7*std::sqrt(2467865842240254105.)*std::pow(latcos,33))/4.294967296e9*rft; - if ( m==34 && n==34 ) - return (21*std::sqrt(1112959105324036165.)*std::pow(latcos,34))/8.589934592e9*rft; - if ( m==35 && n==35 ) - return (3*std::sqrt(5.53140675346046e19)*std::pow(latcos,35))/8.589934592e9*rft; - if ( m==36 && n==36 ) - return (std::sqrt(8075853860052271220473.)*std::pow(latcos,36))/3.4359738368e10*rft; - if ( m==37 && n==37 ) - return (5*std::sqrt(3.2739948081292994e20)*std::pow(latcos,37))/3.4359738368e10*rft; - if ( m==38 && n==38 ) - return (35*std::sqrt(2.707815254843781e19)*std::pow(latcos,38))/6.8719476736e10*rft; - if ( m==39 && n==39 ) - return (35*std::sqrt(109701233401363445369.)*std::pow(latcos,39))/1.37438953472e11*rft; - if ( m==40 && n==40 ) - return (63*std::sqrt(548506167006817226845.)*std::pow(latcos,40))/5.49755813888e11*rft; - if ( m==41 && n==41 ) - return (63*std::sqrt(5.551952666044613e20)*std::pow(latcos,41))/5.49755813888e11*rft; - if ( m==42 && n==42 ) - return (15*std::sqrt(3.964094203555854e22)*std::pow(latcos,42))/1.099511627776e12*rft; - if ( m==43 && n==43 ) - return (45*std::sqrt(17823059209786010066579.)*std::pow(latcos,43))/2.199023255552e12*rft; - if ( m==44 && n==44 ) - return (45*std::sqrt(7.210237589413431e22)*std::pow(latcos,44))/4.398046511104e12*rft; - 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? - } else { + 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 == 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 == 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 == 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 == 21 && n == 21 ) + return ( std::sqrt( 1.4465680375575e12 ) * std::pow( latcos, 21 ) ) / 524288. * rft; + if ( m == 22 && n == 22 ) + return ( 15 * std::sqrt( 2.63012370465e10 ) * std::pow( latcos, 22 ) ) / 1.048576e6 * rft; + if ( m == 23 && n == 23 ) + return ( 15 * std::sqrt( 107492012277 ) * std::pow( latcos, 23 ) ) / 2.097152e6 * rft; + if ( m == 24 && n == 24 ) + return ( 105 * std::sqrt( 35830670759 ) * std::pow( latcos, 24 ) ) / 8.388608e6 * rft; + if ( m == 25 && n == 25 ) + return ( 21 * std::sqrt( 9.136821043545e11 ) * std::pow( latcos, 25 ) ) / 8.388608e6 * rft; + if ( m == 26 && n == 26 ) + return ( 21 * std::sqrt( 3.7250116562145e12 ) * std::pow( latcos, 26 ) ) / 1.6777216e7 * rft; + if ( m == 27 && n == 27 ) + return ( 7 * std::sqrt( 136583760727865. ) * std::pow( latcos, 27 ) ) / 3.3554432e7 * rft; + if ( m == 28 && n == 28 ) + return ( std::sqrt( 2.7248460265209068e16 ) * std::pow( latcos, 28 ) ) / 6.7108864e7 * rft; + if ( m == 29 && n == 29 ) + return ( std::sqrt( 110873045217057585. ) * std::pow( latcos, 29 ) ) / 1.34217728e8 * rft; + if ( m == 30 && n == 30 ) + return ( std::sqrt( 450883717216034179. ) * std::pow( latcos, 30 ) ) / 2.68435456e8 * rft; + if ( m == 31 && n == 31 ) + return ( 21 * std::sqrt( 1.0389025742304935e15 ) * std::pow( latcos, 31 ) ) / 2.68435456e8 * rft; + if ( m == 32 && n == 32 ) + return ( 21 * std::sqrt( 6.752866732498208e16 ) * std::pow( latcos, 32 ) ) / 2.147483648e9 * rft; + if ( m == 33 && n == 33 ) + return ( 7 * std::sqrt( 2467865842240254105. ) * std::pow( latcos, 33 ) ) / 4.294967296e9 * rft; + if ( m == 34 && n == 34 ) + return ( 21 * std::sqrt( 1112959105324036165. ) * std::pow( latcos, 34 ) ) / 8.589934592e9 * rft; + if ( m == 35 && n == 35 ) + return ( 3 * std::sqrt( 5.53140675346046e19 ) * std::pow( latcos, 35 ) ) / 8.589934592e9 * rft; + if ( m == 36 && n == 36 ) + return ( std::sqrt( 8075853860052271220473. ) * std::pow( latcos, 36 ) ) / 3.4359738368e10 * rft; + if ( m == 37 && n == 37 ) + return ( 5 * std::sqrt( 3.2739948081292994e20 ) * std::pow( latcos, 37 ) ) / 3.4359738368e10 * rft; + if ( m == 38 && n == 38 ) + return ( 35 * std::sqrt( 2.707815254843781e19 ) * std::pow( latcos, 38 ) ) / 6.8719476736e10 * rft; + if ( m == 39 && n == 39 ) + return ( 35 * std::sqrt( 109701233401363445369. ) * std::pow( latcos, 39 ) ) / 1.37438953472e11 * rft; + if ( m == 40 && n == 40 ) + return ( 63 * std::sqrt( 548506167006817226845. ) * std::pow( latcos, 40 ) ) / 5.49755813888e11 * rft; + if ( m == 41 && n == 41 ) + return ( 63 * std::sqrt( 5.551952666044613e20 ) * std::pow( latcos, 41 ) ) / 5.49755813888e11 * rft; + if ( m == 42 && n == 42 ) + return ( 15 * std::sqrt( 3.964094203555854e22 ) * std::pow( latcos, 42 ) ) / 1.099511627776e12 * rft; + if ( m == 43 && n == 43 ) + return ( 45 * std::sqrt( 17823059209786010066579. ) * std::pow( latcos, 43 ) ) / 2.199023255552e12 * + rft; + if ( m == 44 && n == 44 ) + return ( 45 * std::sqrt( 7.210237589413431e22 ) * std::pow( latcos, 44 ) ) / 4.398046511104e12 * rft; + 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? + } + else { return 0.; } } - // for the remainder the factor 2 from rft is already included in the formulas: + // for the remainder the factor 2 from rft is already included in the + // formulas: // vorticity: - if ( ivar_in==0 ) { - if ( ivar_out==0 ) { // u: - if ( m==0 && n==0 ) - return 0.; - if ( m==0 && n==1 ) { - if ( imag==0 ) { - return std::sqrt(3.)*a/2.*latcos; - } else { + if ( ivar_in == 0 ) { + if ( ivar_out == 0 ) { // u: + if ( m == 0 && n == 0 ) return 0.; + if ( m == 0 && n == 1 ) { + 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; - } else { - return a*std::sqrt(3./2.)*lonsin*latsin; + if ( m == 1 && n == 1 ) { + 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==1 && n==1 ) { - 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 == 1 ) return 0.; + if ( m == 1 && n == 1 ) { + if ( imag == 0 ) { return a * std::sqrt( 3. / 2. ) * lonsin; } + else { + return a * std::sqrt( 3. / 2. ) * loncos; } } - } else { + } + else { return 0.; } } // 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==1 && n==1 ) { - if ( imag==0 ) { - return a*std::sqrt(3./2.)*lonsin; - } else { - return a*std::sqrt(3./2.)*loncos; + 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 == 1 && n == 1 ) { + 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==1 ) { - if ( imag==0 ) { - return -std::sqrt(3.)*a/2.*latcos; - } else { + } + else if ( ivar_out == 1 ) { // v: + if ( m == 0 && n == 0 ) return 0.; + if ( m == 0 && n == 1 ) { + 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; - } else { - return -a*std::sqrt(3./2.)*lonsin*latsin; // sign? + if ( m == 1 && n == 1 ) { + if ( imag == 0 ) { return a * std::sqrt( 3. / 2. ) * loncos * latsin; } + else { + return -a * std::sqrt( 3. / 2. ) * lonsin * latsin; // sign? } } - } else { + } + else { return 0.; } } @@ -430,81 +418,86 @@ double sphericalharmonics_analytic_point( // Andreas Mueller *ECMWF* // void spectral_transform_grid_analytic( - const size_t trc, // truncation (in) - const size_t trcFT, // truncation for Fourier transformation (in) - const double n, // total wave number (implemented so far for n<4 - const double m, // zonal wave number (implemented so far for m<4, m=m ) { - rgp[idx++] = sphericalharmonics_analytic_point(n, m, imag, lon, lat, ivar_in, ivar_out); - } else { + if ( trans::fourier_truncation( trc, g.nx( j ), g.nxmax(), g.ny(), lat, grid::RegularGrid( g ) ) >= + m ) { + rgp[idx++] = sphericalharmonics_analytic_point( n, m, imag, lon, lat, ivar_in, ivar_out ); + } + else { rgp[idx++] = 0.; } } } - } else { + } + else { int idx = 0; - for( PointXY p: grid.xy()) { + for ( PointXY p : grid.xy() ) { double lon = p.x() * util::Constants::degreesToRadians(); double lat = p.y() * util::Constants::degreesToRadians(); // compute spherical harmonics: - rgp[idx++] = sphericalharmonics_analytic_point(n, m, imag, lon, lat, ivar_in, ivar_out); + rgp[idx++] = sphericalharmonics_analytic_point( n, m, imag, lon, lat, ivar_in, ivar_out ); } } } //----------------------------------------------------------------------------- -// Compute root mean square of difference between two arrays divided by maximum absolute value of second array +// Compute root mean square of difference between two arrays divided by maximum +// absolute value of second array // // Author: // Andreas Mueller *ECMWF* // -double compute_rms( - const size_t N, // length of the arrays - double array1[], // first of the two arrays - double array2[]) // second of the two arrays +double compute_rms( const size_t N, // length of the arrays + double array1[], // first of the two arrays + double array2[] ) // second of the two arrays { double rms = 0., rmax = 0.; - for( int idx=0; idx 2.e-15 ) { - out << " !!!!" << std::endl; - for( int jp=0; jp 2.e-15 ) { + out << " !!!!" << std::endl; + for( int jp=0; jp{ - { 50., 20.}, - { 30., -20.}, - { 179., -89.}, - {-101., 70.} - }); - - int trc = 47; // truncation - - double rms = 0.; - for( int m=0; m<=3; m++ ) { // zonal wavenumber - for( int n=m; n<=3; n++ ) { // total wavenumber - for( int imag=0; imag<=1; imag++ ) { // real and imaginary part - rms = spectral_transform_test(trc, n, m, imag, g, false); - EXPECT( rms < tolerance ); - } - } - } +CASE( "test_transgeneral_unstructured" ) { + std::ostream& out = Log::info(); + Log::info() << "test_transgeneral_unstructured" << std::endl; + double tolerance = 2.e-15; + // test spectral transform up to wave number 3 by comparing + // the result with the analytically computed spherical harmonics + Grid g = grid::UnstructuredGrid( new std::vector{{50., 20.}, {30., -20.}, {179., -89.}, {-101., 70.}} ); + + int trc = 47; // truncation + + double rms = 0.; + for ( int m = 0; m <= 3; m++ ) { // zonal wavenumber + for ( int n = m; n <= 3; n++ ) { // total wavenumber + for ( int imag = 0; imag <= 1; imag++ ) { // real and imaginary part + rms = spectral_transform_test( trc, n, m, imag, g, false ); + EXPECT( rms < tolerance ); + } + } + } } //----------------------------------------------------------------------------- -CASE( "test_transgeneral_structured" ) -{ - std::ostream& out = Log::info(); - Log::info() << "test_transgeneral_structured" << std::endl; - double tolerance = 2.e-15; - // test spectral transform up to wave number 3 by comparing - // the result with the analytically computed spherical harmonics - - std::string grid_uid("O10"); - grid::StructuredGrid g (grid_uid); - - int trc = 47; // truncation - - double rms = 0.; - for( int m=0; m<=3; m++ ) { // zonal wavenumber - for( int n=m; n<=3; n++ ) { // total wavenumber - for( int imag=0; imag<=1; imag++ ) { // real and imaginary part - rms = spectral_transform_test(trc, n, m, imag, g, false); - EXPECT( rms < tolerance ); - } - } - } - +CASE( "test_transgeneral_structured" ) { + std::ostream& out = Log::info(); + Log::info() << "test_transgeneral_structured" << std::endl; + double tolerance = 2.e-15; + // test spectral transform up to wave number 3 by comparing + // the result with the analytically computed spherical harmonics + + std::string grid_uid( "O10" ); + grid::StructuredGrid g( grid_uid ); + + int trc = 47; // truncation + + double rms = 0.; + for ( int m = 0; m <= 3; m++ ) { // zonal wavenumber + for ( int n = m; n <= 3; n++ ) { // total wavenumber + for ( int imag = 0; imag <= 1; imag++ ) { // real and imaginary part + rms = spectral_transform_test( trc, n, m, imag, g, false ); + EXPECT( rms < tolerance ); + } + } + } } //----------------------------------------------------------------------------- -CASE( "test_transgeneral_with_translib" ) -{ - Log::info() << "test_transgeneral_with_translib" << std::endl; - // test transgeneral by comparing its result with the trans library - // this test is based on the test_nomesh case in test_trans.cc - - std::ostream& out = Log::info(); - double tolerance = 1.e-13; - Grid g( "F24" ); - grid::StructuredGrid gs(g); - int trc = 47; - trans::Trans trans(g,trc) ; +CASE( "test_transgeneral_with_translib" ) { + Log::info() << "test_transgeneral_with_translib" << std::endl; + // test transgeneral by comparing its result with the trans library + // this test is based on the test_nomesh case in test_trans.cc - functionspace::Spectral spectral (trans); - functionspace::StructuredColumns gridpoints (g); + std::ostream& out = Log::info(); + double tolerance = 1.e-13; + Grid g( "F24" ); + grid::StructuredGrid gs( g ); + int trc = 47; + trans::Trans trans( g, trc ); - Field spf = spectral. createField(option::name("spf")); - Field gpf = gridpoints.createField(option::name("gpf")); + functionspace::Spectral spectral( trans ); + functionspace::StructuredColumns gridpoints( g ); - int N = (trc+2)*(trc+1)/2; - std::vector rspecg (2*N); - std::vector rgp (g.size()); - std::vector rgp_analytic (g.size()); + Field spf = spectral.createField( option::name( "spf" ) ); + Field gpf = gridpoints.createField( option::name( "gpf" ) ); - int k = 0; - for( int m=0; m<=trc; m++ ) { // zonal wavenumber - for( int n=m; n<=trc; n++ ) { // total wavenumber - for( int imag=0; imag<=1; imag++ ) { // real and imaginary part + int N = ( trc + 2 ) * ( trc + 1 ) / 2; + std::vector rspecg( 2 * N ); + std::vector rgp( g.size() ); + std::vector rgp_analytic( g.size() ); - if( sphericalharmonics_analytic_point(n, m, true, 0., 0., 2, 2) == 0. ) { + int k = 0; + for ( int m = 0; m <= trc; m++ ) { // zonal wavenumber + for ( int n = m; n <= trc; n++ ) { // total wavenumber + for ( int imag = 0; imag <= 1; imag++ ) { // real and imaginary part - array::ArrayView sp = array::make_view(spf); - sp.assign(0.); - sp(k) = 1.; + if ( sphericalharmonics_analytic_point( n, m, true, 0., 0., 2, 2 ) == 0. ) { + array::ArrayView sp = array::make_view( spf ); + sp.assign( 0. ); + sp( k ) = 1.; - EXPECT_NO_THROW( trans.invtrans(spf,gpf) ); + EXPECT_NO_THROW( trans.invtrans( spf, gpf ) ); - spectral_transform_grid_analytic(trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data(), 2, 2); + spectral_transform_grid_analytic( trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data(), 2, + 2 ); - // compute spectral transform with the general transform: - spectral_transform_grid(trc, trc, g, sp.data(), rgp.data(), false); + // compute spectral transform with the general transform: + spectral_transform_grid( trc, trc, g, sp.data(), rgp.data(), false ); - array::ArrayView gp = array::make_view(gpf); - double rms_trans = compute_rms(g.size(), gp.data(), rgp.data()); - double rms_gen = compute_rms(g.size(), rgp.data(), rgp_analytic.data()); + array::ArrayView gp = array::make_view( gpf ); + double rms_trans = compute_rms( g.size(), gp.data(), rgp.data() ); + double rms_gen = compute_rms( g.size(), rgp.data(), rgp_analytic.data() ); - if( rms_gen >= tolerance ) { - ATLAS_DEBUG_VAR(rms_gen); - ATLAS_DEBUG_VAR(tolerance); - } - EXPECT( rms_gen < tolerance ); - EXPECT( rms_trans < tolerance ); - } - k++; - } - } - } + if ( rms_gen >= tolerance ) { + ATLAS_DEBUG_VAR( rms_gen ); + ATLAS_DEBUG_VAR( tolerance ); + } + EXPECT( rms_gen < tolerance ); + EXPECT( rms_trans < tolerance ); + } + k++; + } + } + } } //----------------------------------------------------------------------------- -CASE( "test_trans_vordiv_with_translib" ) -{ - Log::info() << "test_trans_vordiv_with_translib" << std::endl; - // test transgeneral by comparing its result with the trans library - // this test is based on the test_nomesh case in test_trans.cc - - std::ostream& out = Log::info(); - double tolerance = 1.e-13; +CASE( "test_trans_vordiv_with_translib" ) { + Log::info() << "test_trans_vordiv_with_translib" << std::endl; + // test transgeneral by comparing its result with the trans library + // this test is based on the test_nomesh case in test_trans.cc - // resolution: (Reduce this number if the test takes too long!) - int res = 12; - - Grid g( "O" + std::to_string(res) ); - grid::StructuredGrid gs(g); - int trc = res*2-1; - trans::Trans trans (g, trc) ; - trans::Trans transLocal(g, trc, util::Config("type","local")); - - functionspace::Spectral spectral (trans); - functionspace::StructuredColumns gridpoints (g); - - int nb_scalar = 2, nb_vordiv = 2; - int N = (trc+2)*(trc+1)/2, nb_all = nb_scalar+2*nb_vordiv; - std::vector sp (2*N*nb_scalar); - std::vector vor (2*N*nb_vordiv); - std::vector div (2*N*nb_vordiv); - std::vector rspecg (2*N); - std::vector gp (nb_all*g.size()); - std::vector rgp (nb_all*g.size()); - std::vector rgp_analytic (g.size()); - - int icase = 0; - for( int ivar_in=0; ivar_in<3; ivar_in++ ) { // vorticity, divergence, scalar - for( int ivar_out=0; ivar_out<3; ivar_out++ ) { // u, v, scalar - int nb_fld = 1; - if( ivar_out==2) { - tolerance = 1.e-13; - nb_fld = nb_scalar; - } else { - tolerance = 2.e-6; - nb_fld = nb_vordiv; - } - for( int jfld=0; jfld=tolerance || rms_trans>=tolerance || rms_diff>=tolerance ) { - Log::info() << "Case " << icase << " ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; - ATLAS_DEBUG_VAR(rms_gen); - ATLAS_DEBUG_VAR(rms_trans); - ATLAS_DEBUG_VAR(rms_diff); - ATLAS_DEBUG_VAR(tolerance); - } - EXPECT( rms_trans < tolerance ); - EXPECT( rms_gen < tolerance ); - icase++; - } - k++; - } - } - } - } - } - } - Log::info() << "Vordiv+scalar comparison with trans: all " << icase << " cases successfully passed!" << std::endl; + std::ostream& out = Log::info(); + double tolerance = 1.e-13; + + // resolution: (Reduce this number if the test takes too long!) + int res = 12; + + Grid g( "O" + std::to_string( res ) ); + grid::StructuredGrid gs( g ); + int trc = res * 2 - 1; + trans::Trans trans( g, trc ); + trans::Trans transLocal( g, trc, util::Config( "type", "local" ) ); + + functionspace::Spectral spectral( trans ); + functionspace::StructuredColumns gridpoints( g ); + + int nb_scalar = 2, nb_vordiv = 2; + int N = ( trc + 2 ) * ( trc + 1 ) / 2, nb_all = nb_scalar + 2 * nb_vordiv; + std::vector sp( 2 * N * nb_scalar ); + std::vector vor( 2 * N * nb_vordiv ); + std::vector div( 2 * N * nb_vordiv ); + std::vector rspecg( 2 * N ); + std::vector gp( nb_all * g.size() ); + std::vector rgp( nb_all * g.size() ); + std::vector rgp_analytic( g.size() ); + + int icase = 0; + for ( int ivar_in = 0; ivar_in < 3; ivar_in++ ) { // vorticity, divergence, scalar + for ( int ivar_out = 0; ivar_out < 3; ivar_out++ ) { // u, v, scalar + int nb_fld = 1; + if ( ivar_out == 2 ) { + tolerance = 1.e-13; + nb_fld = nb_scalar; + } + else { + tolerance = 2.e-6; + nb_fld = nb_vordiv; + } + for ( int jfld = 0; jfld < nb_fld; jfld++ ) { // multiple fields + int k = 0; + for ( int m = 0; m <= trc; m++ ) { // zonal wavenumber + for ( int n = m; n <= trc; n++ ) { // total wavenumber + for ( int imag = 0; imag <= 1; imag++ ) { // real and imaginary part + + if ( sphericalharmonics_analytic_point( n, m, true, 0., 0., ivar_in, ivar_in ) == 0. ) { + for ( int j = 0; j < 2 * N * nb_scalar; j++ ) { + sp[j] = 0.; + } + for ( int j = 0; j < 2 * N * nb_vordiv; j++ ) { + 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.; + + for ( int j = 0; j < nb_all * g.size(); j++ ) { + gp[j] = 0.; + rgp[j] = 0.; + } + for ( int j = 0; j < g.size(); j++ ) { + rgp_analytic[j] = 0.; + } + + spectral_transform_grid_analytic( trc, trc, n, m, imag, g, rspecg.data(), + rgp_analytic.data(), ivar_in, ivar_out ); + + EXPECT_NO_THROW( trans.invtrans( nb_scalar, sp.data(), nb_vordiv, vor.data(), + div.data(), gp.data() ) ); + + // compute spectral transform with the general transform: + // EXPECT_NO_THROW( spectral_transform_grid(trc, trc, g, sp, + // rgp, false) ); + // EXPECT_NO_THROW( transLocal.invtrans( nb_scalar, sp, rgp) ); + EXPECT_NO_THROW( transLocal.invtrans( nb_scalar, sp.data(), nb_vordiv, vor.data(), + div.data(), rgp.data() ) ); + + int pos = ( ivar_out * nb_vordiv + jfld ); + // Log::info() << "Case " << icase << " Analytic solution: + // ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << + // m << " n=" << n << " imag=" << imag << " k=" << k << + // std::endl; + // for( int j=0; j= tolerance || rms_trans >= tolerance || rms_diff >= tolerance ) { + Log::info() + << "Case " << icase << " ivar_in=" << ivar_in << " ivar_out=" << ivar_out + << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; + ATLAS_DEBUG_VAR( rms_gen ); + ATLAS_DEBUG_VAR( rms_trans ); + ATLAS_DEBUG_VAR( rms_diff ); + ATLAS_DEBUG_VAR( tolerance ); + } + EXPECT( rms_trans < tolerance ); + EXPECT( rms_gen < tolerance ); + icase++; + } + k++; + } + } + } + } + } + } + Log::info() << "Vordiv+scalar comparison with trans: all " << icase << " cases successfully passed!" << std::endl; } //----------------------------------------------------------------------------- CASE( "test_trans_invtrans" ) { + trans::Trans trans( Grid( "O64" ), 63, util::Config( "type", "local" ) ); - trans::Trans trans( Grid("O64"), 63, util::Config("type","local") ); - - std::vector rspec(trans.spectralCoefficients()); - std::vector rgp(trans.grid().size()); - - // TODO: rspec needs proper initial data + std::vector rspec( trans.spectralCoefficients() ); + std::vector rgp( trans.grid().size() ); - trans.invtrans(1,rspec.data(),rgp.data()); + // TODO: rspec needs proper initial data + trans.invtrans( 1, rspec.data(), rgp.data() ); } #endif -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- #if 0 CASE( "test_trans_fourier_truncation" ) @@ -890,7 +887,6 @@ CASE( "test_trans_fourier_truncation" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { - return atlas::test::run< atlas::test::AtlasTransEnvironment >( argc, argv ); +int main( int argc, char** argv ) { + return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_earth.cc b/src/tests/util/test_earth.cc index 48099fb7e..f7b410037 100644 --- a/src/tests/util/test_earth.cc +++ b/src/tests/util/test_earth.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -25,171 +26,134 @@ const double R = Earth::radiusInMeters(); // ----------------------------------------------------------------------------- // test_earth_poles -CASE( "test_earth_north_pole" ) -{ - const PointLonLat p1(0., 90.); - const PointXYZ p2 = Earth::convertGeodeticToGeocentric(p1); +CASE( "test_earth_north_pole" ) { + const PointLonLat p1( 0., 90. ); + const PointXYZ p2 = Earth::convertGeodeticToGeocentric( p1 ); - EXPECT(p2.x() == 0); - EXPECT(p2.y() == 0); - EXPECT(p2.z() == R); + EXPECT( p2.x() == 0 ); + EXPECT( p2.y() == 0 ); + EXPECT( p2.z() == R ); } -CASE( "test_earth_south_pole" ) -{ - const PointLonLat p1(0., -90.); - const PointXYZ p2 = Earth::convertGeodeticToGeocentric(p1); +CASE( "test_earth_south_pole" ) { + const PointLonLat p1( 0., -90. ); + const PointXYZ p2 = Earth::convertGeodeticToGeocentric( p1 ); - EXPECT(p2.x() == 0); - EXPECT(p2.y() == 0); - EXPECT(p2.z() == -R); + EXPECT( p2.x() == 0 ); + EXPECT( p2.y() == 0 ); + EXPECT( p2.z() == -R ); } // ----------------------------------------------------------------------------- // test_earth_quadrants -CASE( "test_earth_lon_0" ) -{ - const PointLonLat p1[2] = {{0., 0.}, {-360., 0.}}; - const PointXYZ p2[] = { - Earth::convertGeodeticToGeocentric(p1[0]), - Earth::convertGeodeticToGeocentric(p1[1]) - }; +CASE( "test_earth_lon_0" ) { + const PointLonLat p1[2] = {{0., 0.}, {-360., 0.}}; + const PointXYZ p2[] = {Earth::convertGeodeticToGeocentric( p1[0] ), Earth::convertGeodeticToGeocentric( p1[1] )}; - EXPECT(p2[0].x() == R); - EXPECT(p2[0].y() == 0); - EXPECT(p2[0].z() == 0); + EXPECT( p2[0].x() == R ); + EXPECT( p2[0].y() == 0 ); + EXPECT( p2[0].z() == 0 ); - EXPECT(PointXYZ::equal(p2[0], p2[1])); + EXPECT( PointXYZ::equal( p2[0], p2[1] ) ); } -CASE( "test_earth_lon_90" ) -{ - const PointLonLat p1[2] = {{90., 0.}, {-270., 0.}}; - const PointXYZ p2[] = { - Earth::convertGeodeticToGeocentric(p1[0]), - Earth::convertGeodeticToGeocentric(p1[1]) - }; +CASE( "test_earth_lon_90" ) { + const PointLonLat p1[2] = {{90., 0.}, {-270., 0.}}; + const PointXYZ p2[] = {Earth::convertGeodeticToGeocentric( p1[0] ), Earth::convertGeodeticToGeocentric( p1[1] )}; - EXPECT(p2[0].x() == 0); - EXPECT(p2[0].y() == R); - EXPECT(p2[0].z() == 0); + EXPECT( p2[0].x() == 0 ); + EXPECT( p2[0].y() == R ); + EXPECT( p2[0].z() == 0 ); - EXPECT(PointXYZ::equal(p2[0], p2[1])); + EXPECT( PointXYZ::equal( p2[0], p2[1] ) ); } -CASE( "test_earth_lon_180" ) -{ - const PointLonLat p1[2] = {{180., 0.}, {-180., 0.}}; - const PointXYZ p2[] = { - Earth::convertGeodeticToGeocentric(p1[0]), - Earth::convertGeodeticToGeocentric(p1[1]) - }; +CASE( "test_earth_lon_180" ) { + const PointLonLat p1[2] = {{180., 0.}, {-180., 0.}}; + const PointXYZ p2[] = {Earth::convertGeodeticToGeocentric( p1[0] ), Earth::convertGeodeticToGeocentric( p1[1] )}; - EXPECT(p2[0].x() == -R); - EXPECT(p2[0].y() == 0); - EXPECT(p2[0].z() == 0); + EXPECT( p2[0].x() == -R ); + EXPECT( p2[0].y() == 0 ); + EXPECT( p2[0].z() == 0 ); - EXPECT(PointXYZ::equal(p2[0], p2[1])); + EXPECT( PointXYZ::equal( p2[0], p2[1] ) ); } -CASE( "test_earth_lon_270" ) -{ - const PointLonLat p1[2] = {{270., 0.}, {-90., 0.}}; - const PointXYZ p2[] = { - Earth::convertGeodeticToGeocentric(p1[0]), - Earth::convertGeodeticToGeocentric(p1[1]) - }; +CASE( "test_earth_lon_270" ) { + const PointLonLat p1[2] = {{270., 0.}, {-90., 0.}}; + const PointXYZ p2[] = {Earth::convertGeodeticToGeocentric( p1[0] ), Earth::convertGeodeticToGeocentric( p1[1] )}; - EXPECT(p2[0].x() == 0); - EXPECT(p2[0].y() == -R); - EXPECT(p2[0].z() == 0); + EXPECT( p2[0].x() == 0 ); + EXPECT( p2[0].y() == -R ); + EXPECT( p2[0].z() == 0 ); - EXPECT(PointXYZ::equal(p2[0], p2[1])); + EXPECT( PointXYZ::equal( p2[0], p2[1] ) ); } - // ----------------------------------------------------------------------------- // test_earth_octants -const double L = R * std::sqrt(2) / 2.; +const double L = R * std::sqrt( 2 ) / 2.; -CASE( "test_earth_lon_45" ) -{ - const PointLonLat p1[2] = {{45., 0.}, {-315., 0.}}; - const PointXYZ p2[] = { - Earth::convertGeodeticToGeocentric(p1[0]), - Earth::convertGeodeticToGeocentric(p1[1]) - }; +CASE( "test_earth_lon_45" ) { + const PointLonLat p1[2] = {{45., 0.}, {-315., 0.}}; + const PointXYZ p2[] = {Earth::convertGeodeticToGeocentric( p1[0] ), Earth::convertGeodeticToGeocentric( p1[1] )}; - EXPECT( eckit::types::is_approximately_equal( p2[0].x(), L) ); - EXPECT( eckit::types::is_approximately_equal( p2[0].y(), L) ); - EXPECT(p2[0].z() == 0); + EXPECT( eckit::types::is_approximately_equal( p2[0].x(), L ) ); + EXPECT( eckit::types::is_approximately_equal( p2[0].y(), L ) ); + EXPECT( p2[0].z() == 0 ); - EXPECT(PointXYZ::equal(p2[0], p2[1])); + EXPECT( PointXYZ::equal( p2[0], p2[1] ) ); } -CASE( "test_earth_lon_135" ) -{ - const PointLonLat p1[2] = {{135., 0.}, {-225., 0.}}; - const PointXYZ p2[] = { - Earth::convertGeodeticToGeocentric(p1[0]), - Earth::convertGeodeticToGeocentric(p1[1]) - }; +CASE( "test_earth_lon_135" ) { + const PointLonLat p1[2] = {{135., 0.}, {-225., 0.}}; + const PointXYZ p2[] = {Earth::convertGeodeticToGeocentric( p1[0] ), Earth::convertGeodeticToGeocentric( p1[1] )}; - EXPECT( eckit::types::is_approximately_equal( p2[0].x(), -L) ); - EXPECT( eckit::types::is_approximately_equal( p2[0].y(), L) ); - EXPECT(p2[0].z() == 0); + EXPECT( eckit::types::is_approximately_equal( p2[0].x(), -L ) ); + EXPECT( eckit::types::is_approximately_equal( p2[0].y(), L ) ); + EXPECT( p2[0].z() == 0 ); - EXPECT(PointXYZ::equal(p2[0], p2[1])); + EXPECT( PointXYZ::equal( p2[0], p2[1] ) ); } -CASE( "test_earth_lon_225" ) -{ - const PointLonLat p1[2] = {{225., 0.}, {-135., 0.}}; - const PointXYZ p2[] = { - Earth::convertGeodeticToGeocentric(p1[0]), - Earth::convertGeodeticToGeocentric(p1[1]) - }; +CASE( "test_earth_lon_225" ) { + const PointLonLat p1[2] = {{225., 0.}, {-135., 0.}}; + const PointXYZ p2[] = {Earth::convertGeodeticToGeocentric( p1[0] ), Earth::convertGeodeticToGeocentric( p1[1] )}; - EXPECT( eckit::types::is_approximately_equal( p2[0].x(), -L) ); - EXPECT( eckit::types::is_approximately_equal( p2[0].y(), -L) ); - EXPECT(p2[0].z() == 0); + EXPECT( eckit::types::is_approximately_equal( p2[0].x(), -L ) ); + EXPECT( eckit::types::is_approximately_equal( p2[0].y(), -L ) ); + EXPECT( p2[0].z() == 0 ); - EXPECT(PointXYZ::equal(p2[0], p2[1])); + EXPECT( PointXYZ::equal( p2[0], p2[1] ) ); } -CASE( "test_earth_lon_315" ) -{ - const PointLonLat p1[2] = {{315., 0.}, {-45., 0.}}; - const PointXYZ p2[] = { - Earth::convertGeodeticToGeocentric(p1[0]), - Earth::convertGeodeticToGeocentric(p1[1]) - }; +CASE( "test_earth_lon_315" ) { + const PointLonLat p1[2] = {{315., 0.}, {-45., 0.}}; + const PointXYZ p2[] = {Earth::convertGeodeticToGeocentric( p1[0] ), Earth::convertGeodeticToGeocentric( p1[1] )}; - EXPECT( eckit::types::is_approximately_equal( p2[0].x(), L) ); - EXPECT( eckit::types::is_approximately_equal( p2[0].y(), -L) ); - EXPECT(p2[0].z() == 0); + EXPECT( eckit::types::is_approximately_equal( p2[0].x(), L ) ); + EXPECT( eckit::types::is_approximately_equal( p2[0].y(), -L ) ); + EXPECT( p2[0].z() == 0 ); - EXPECT(PointXYZ::equal(p2[0], p2[1])); + EXPECT( PointXYZ::equal( p2[0], p2[1] ) ); } -CASE( "test_earth_great_circle_latitude_given_longitude" ) -{ +CASE( "test_earth_great_circle_latitude_given_longitude" ) { // latitude at Valparaíso-Shanghai mid-point - const PointLonLat P1(-71.6, -33.); - const PointLonLat P2(121.8, 31.4); + const PointLonLat P1( -71.6, -33. ); + const PointLonLat P2( 121.8, 31.4 ); - PointLonLat midpoint(-159.18, std::numeric_limits::quiet_NaN()); - Earth::greatCircleLatitudeGivenLongitude(P1, P2, midpoint); + PointLonLat midpoint( -159.18, std::numeric_limits::quiet_NaN() ); + Earth::greatCircleLatitudeGivenLongitude( P1, P2, midpoint ); EXPECT( eckit::types::is_approximately_equal( midpoint.lat(), -6.81, 0.01 ) ); } - } // namespace test } // namespace atlas -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_flags.cc b/src/tests/util/test_flags.cc index 5b3b7763a..680e00fce 100644 --- a/src/tests/util/test_flags.cc +++ b/src/tests/util/test_flags.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -20,24 +21,23 @@ namespace test { //----------------------------------------------------------------------------- -CASE( "test_Flags" ) -{ - int b1 = (1<<0); - int b2 = (1<<1); - int b3 = (1<<2); - int b4 = (1<<3); - - int bits = b1 | b2; - std::cout << Bitflags::bitstr(bits) << std::endl; - EXPECT( bits == 3); - - EXPECT( Bitflags::check(bits, b1 )); - EXPECT( Bitflags::check(bits, b2 )); - EXPECT(!Bitflags::check(bits, b3 )); - EXPECT( Bitflags::check_all(bits, b1|b2 )); - EXPECT(!Bitflags::check_all(bits, b1|b3 )); - EXPECT( Bitflags::check_any(bits, b1|b3 )); - EXPECT(!Bitflags::check_any(bits, b3|b4 )); +CASE( "test_Flags" ) { + int b1 = ( 1 << 0 ); + int b2 = ( 1 << 1 ); + int b3 = ( 1 << 2 ); + int b4 = ( 1 << 3 ); + + int bits = b1 | b2; + std::cout << Bitflags::bitstr( bits ) << std::endl; + EXPECT( bits == 3 ); + + EXPECT( Bitflags::check( bits, b1 ) ); + EXPECT( Bitflags::check( bits, b2 ) ); + EXPECT( !Bitflags::check( bits, b3 ) ); + EXPECT( Bitflags::check_all( bits, b1 | b2 ) ); + EXPECT( !Bitflags::check_all( bits, b1 | b3 ) ); + EXPECT( Bitflags::check_any( bits, b1 | b3 ) ); + EXPECT( !Bitflags::check_any( bits, b3 | b4 ) ); } //----------------------------------------------------------------------------- @@ -45,7 +45,6 @@ CASE( "test_Flags" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_footprint.cc b/src/tests/util/test_footprint.cc index b1beb1e57..56bbaaab8 100644 --- a/src/tests/util/test_footprint.cc +++ b/src/tests/util/test_footprint.cc @@ -4,21 +4,22 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/library/Library.h" -#include "atlas/array/ArrayView.h" #include "atlas/array/Array.h" -#include "atlas/util/Metadata.h" +#include "atlas/array/ArrayView.h" #include "atlas/field/Field.h" -#include "atlas/runtime/Log.h" +#include "atlas/grid/Grid.h" +#include "atlas/library/Library.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "atlas/mesh/HybridElements.h" #include "atlas/meshgenerator/MeshGenerator.h" -#include "atlas/grid/Grid.h" +#include "atlas/runtime/Log.h" +#include "atlas/util/Metadata.h" #include "eckit/log/Bytes.h" #include "tests/AtlasTestEnvironment.h" @@ -31,36 +32,38 @@ namespace test { //----------------------------------------------------------------------------- -CASE( "test_broadcast_to_self" ) -{ - array::ArrayT array(10,2); - Log::info() << "array.footprint = " << eckit::Bytes(array.footprint()) << std::endl; - - Field field ("field",array::make_datatype(),array::make_shape(10,2)); - Log::info() << "field.footprint = " << eckit::Bytes(field.footprint()) << std::endl; - - Grid grid("O640"); - MeshGenerator meshgen( "structured" ); - Mesh mesh = meshgen.generate(grid); - - Log::info() << "Footprint for mesh generated from grid " << grid.name() << std::endl; - Log::info() << "mesh.footprint = " << eckit::Bytes(mesh.footprint()) << std::endl; - Log::info() << " .nodes.footprint = " << eckit::Bytes(mesh.nodes().footprint()) << std::endl; - for( size_t f=0; f array( 10, 2 ); + Log::info() << "array.footprint = " << eckit::Bytes( array.footprint() ) << std::endl; + + Field field( "field", array::make_datatype(), array::make_shape( 10, 2 ) ); + Log::info() << "field.footprint = " << eckit::Bytes( field.footprint() ) << std::endl; + + Grid grid( "O640" ); + MeshGenerator meshgen( "structured" ); + Mesh mesh = meshgen.generate( grid ); + + Log::info() << "Footprint for mesh generated from grid " << grid.name() << std::endl; + Log::info() << "mesh.footprint = " << eckit::Bytes( mesh.footprint() ) << std::endl; + Log::info() << " .nodes.footprint = " << eckit::Bytes( mesh.nodes().footprint() ) << std::endl; + for ( size_t f = 0; f < mesh.nodes().nb_fields(); ++f ) { + Log::info() << " ." + mesh.nodes().field( f ).name() + ".footprint = " + << eckit::Bytes( mesh.nodes().field( f ).footprint() ) << std::endl; + } + + Log::info() << " .cells.footprint = " << eckit::Bytes( mesh.cells().footprint() ) << std::endl; + + for ( size_t f = 0; f < mesh.cells().nb_fields(); ++f ) { + Log::info() << " ." + mesh.cells().field( f ).name() + ".footprint = " + << eckit::Bytes( mesh.cells().field( f ).footprint() ) << std::endl; + } + + Log::info() << " .node_connectivity.footprint = " + << eckit::Bytes( mesh.cells().node_connectivity().footprint() ) << std::endl; + Log::info() << " .edge_connectivity.footprint = " + << eckit::Bytes( mesh.cells().edge_connectivity().footprint() ) << std::endl; + Log::info() << " .cell_connectivity.footprint = " + << eckit::Bytes( mesh.cells().cell_connectivity().footprint() ) << std::endl; } //----------------------------------------------------------------------------- @@ -68,7 +71,6 @@ CASE( "test_broadcast_to_self" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index 34193414d..23c581d3e 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -4,15 +4,16 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/parallel/mpi/mpi.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" #include "atlas/array/MakeView.h" +#include "atlas/parallel/mpi/mpi.h" #include "tests/AtlasTestEnvironment.h" #ifdef ATLAS_HAVE_FORTRAN @@ -28,166 +29,163 @@ namespace test { //----------------------------------------------------------------------------- -template< typename Iterator > -std::string pos(Iterator& it) -{ - std::stringstream ss; - for(size_t i=0; i < it.pos().size(); ++i) ss << it.pos()[i] << " "; - return ss.str(); +template +std::string pos( Iterator& it ) { + std::stringstream ss; + for ( size_t i = 0; i < it.pos().size(); ++i ) + ss << it.pos()[i] << " "; + return ss.str(); } -//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- -/* + /* CASE( "test_array" ) { - array::ArrayT _array (3,1,4); - array::ArrayView array(_array); - EXPECT( array.shape(0) == 3 ); - EXPECT( array.shape(1) == 1 ); - EXPECT( array.shape(2) == 4 ); - EXPECT( array.size() == 12 ); - EXPECT( array.stride(0) == 4 ); - EXPECT( array.stride(1) == 4 ); - EXPECT( array.stride(2) == 1 ); - for( size_t j=0; j _array (3,1,4); +array::ArrayView array(_array); +EXPECT( array.shape(0) == 3 ); +EXPECT( array.shape(1) == 1 ); +EXPECT( array.shape(2) == 4 ); +EXPECT( array.size() == 12 ); +EXPECT( array.stride(0) == 4 ); +EXPECT( array.stride(1) == 4 ); +EXPECT( array.stride(2) == 1 ); +for( size_t j=0; j array(5,4,2); - size_t strides[2] = {8,1}; - size_t extents[2] = {5,2}; - array::ArrayView aview(array.data(),2,extents,strides); - array::ArrayView const const_aview(array); - - std::cout << "aview.size() = " << aview.size() << std::endl; - std::cout << "const_.size() = " << const_aview.size() << std::endl; - - array::ArrayView::iterator it; - array::ArrayView::const_iterator const_it; - - int i(0); - for(it = aview.begin(); it!=aview.end(); ++it, ++i) - { - std::cout << "set at pos " << test::pos(it) << " : " << i << std::endl; - *it = i; - } - - for( const_it = const_aview.begin(); const_it!=const_aview.end(); ++const_it) - { - std::cout << "read at pos " << test::pos(const_it) << " : " << *const_it << std::endl; - } -} -*/ - -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE -CASE( "test_indexview_1d" ) -{ - //array::ArrayT array( 10 ); - - Array *array = Array::create(10); - array::ArrayView aview = make_host_view(*array); - - aview(0) = 1 IN_FORTRAN; - EXPECT( aview(0) == 1 IN_FORTRAN ); - - - /* - array::ArrayView aview(array); - IndexView iview(array); - const IndexView const_iview(array); - - aview(0) = 1 IN_FORTRAN; - EXPECT( aview(0) == 1 IN_FORTRAN ); - EXPECT( const_iview(0) == 0 ); - EXPECT( int(iview(0)) == 0 ); +array::ArrayT array(5,4,2); +size_t strides[2] = {8,1}; +size_t extents[2] = {5,2}; +array::ArrayView aview(array.data(),2,extents,strides); +array::ArrayView const const_aview(array); - iview(2) = 2; - EXPECT( aview(2) == 3 IN_FORTRAN ); - EXPECT( const_iview(2) == 2 ); - EXPECT( int(iview(2)) == 2 ); +std::cout << "aview.size() = " << aview.size() << std::endl; +std::cout << "const_.size() = " << const_aview.size() << std::endl; - iview(3) = iview(2); - EXPECT( aview(3) == 3 IN_FORTRAN ); - EXPECT( const_iview(3) == 2 ); - EXPECT( int(iview(3)) == 2 ); +array::ArrayView::iterator it; +array::ArrayView::const_iterator const_it; - iview(3) = iview(2) + 1; - EXPECT( aview(3) == 4 IN_FORTRAN ); - EXPECT( const_iview(3) == 3 ); - EXPECT( int(iview(3)) == 3 ); - - iview(4) = iview(3); - ++iview(4); - EXPECT( aview(4) == 5 IN_FORTRAN ); - EXPECT( const_iview(4) == 4 ); - EXPECT( int(iview(4)) == 4 ); +int i(0); +for(it = aview.begin(); it!=aview.end(); ++it, ++i) +{ +std::cout << "set at pos " << test::pos(it) << " : " << i << std::endl; +*it = i; +} - int val = iview(4); - EXPECT( val == 4 ); +for( const_it = const_aview.begin(); const_it!=const_aview.end(); ++const_it) +{ +std::cout << "read at pos " << test::pos(const_it) << " : " << *const_it << +std::endl; +} +} +*/ - val = iview(4)+1; - EXPECT( val == 5 ); +#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +CASE( "test_indexview_1d" ) { + // array::ArrayT array( 10 ); + + Array* array = Array::create( 10 ); + array::ArrayView aview = make_host_view( *array ); + + aview( 0 ) = 1 IN_FORTRAN; + EXPECT( aview( 0 ) == 1 IN_FORTRAN ); + + /* +array::ArrayView aview(array); +IndexView iview(array); +const IndexView const_iview(array); + +aview(0) = 1 IN_FORTRAN; +EXPECT( aview(0) == 1 IN_FORTRAN ); +EXPECT( const_iview(0) == 0 ); +EXPECT( int(iview(0)) == 0 ); + +iview(2) = 2; +EXPECT( aview(2) == 3 IN_FORTRAN ); +EXPECT( const_iview(2) == 2 ); +EXPECT( int(iview(2)) == 2 ); + +iview(3) = iview(2); +EXPECT( aview(3) == 3 IN_FORTRAN ); +EXPECT( const_iview(3) == 2 ); +EXPECT( int(iview(3)) == 2 ); + +iview(3) = iview(2) + 1; +EXPECT( aview(3) == 4 IN_FORTRAN ); +EXPECT( const_iview(3) == 3 ); +EXPECT( int(iview(3)) == 3 ); + +iview(4) = iview(3); +++iview(4); +EXPECT( aview(4) == 5 IN_FORTRAN ); +EXPECT( const_iview(4) == 4 ); +EXPECT( int(iview(4)) == 4 ); + +int val = iview(4); +EXPECT( val == 4 ); + +val = iview(4)+1; +EXPECT( val == 5 ); */ } #else -CASE( "test_indexview_1d" ) -{ - Array *array = Array::create(10); - - array::ArrayView aview = array::make_view(*array); - IndexView iview = make_indexview(*array); - const IndexView const_iview = make_indexview(*array); - - aview(0) = 1 IN_FORTRAN; - EXPECT( aview(0) == 1 IN_FORTRAN ); - EXPECT( const_iview(0) == 0 ); - EXPECT( int(iview(0)) == 0 ); - - iview(2) = 2; - EXPECT( aview(2) == 3 IN_FORTRAN ); - EXPECT( const_iview(2) == 2 ); - EXPECT( int(iview(2)) == 2 ); - - iview(3) = iview(2); - EXPECT( aview(3) == 3 IN_FORTRAN ); - EXPECT( const_iview(3) == 2 ); - EXPECT( int(iview(3)) == 2 ); - - iview(3) = iview(2) + 1; - EXPECT( aview(3) == 4 IN_FORTRAN ); - EXPECT( const_iview(3) == 3 ); - EXPECT( int(iview(3)) == 3 ); - - iview(4) = iview(3); - ++iview(4); - EXPECT( aview(4) == 5 IN_FORTRAN ); - EXPECT( const_iview(4) == 4 ); - EXPECT( int(iview(4)) == 4 ); - - int val = iview(4); - EXPECT( val == 4 ); - - val = iview(4)+1; - EXPECT( val == 5 ); - +CASE( "test_indexview_1d" ) { + Array* array = Array::create( 10 ); + + array::ArrayView aview = array::make_view( *array ); + IndexView iview = make_indexview( *array ); + const IndexView const_iview = make_indexview( *array ); + + aview( 0 ) = 1 IN_FORTRAN; + EXPECT( aview( 0 ) == 1 IN_FORTRAN ); + EXPECT( const_iview( 0 ) == 0 ); + EXPECT( int( iview( 0 ) ) == 0 ); + + iview( 2 ) = 2; + EXPECT( aview( 2 ) == 3 IN_FORTRAN ); + EXPECT( const_iview( 2 ) == 2 ); + EXPECT( int( iview( 2 ) ) == 2 ); + + iview( 3 ) = iview( 2 ); + EXPECT( aview( 3 ) == 3 IN_FORTRAN ); + EXPECT( const_iview( 3 ) == 2 ); + EXPECT( int( iview( 3 ) ) == 2 ); + + iview( 3 ) = iview( 2 ) + 1; + EXPECT( aview( 3 ) == 4 IN_FORTRAN ); + EXPECT( const_iview( 3 ) == 3 ); + EXPECT( int( iview( 3 ) ) == 3 ); + + iview( 4 ) = iview( 3 ); + ++iview( 4 ); + EXPECT( aview( 4 ) == 5 IN_FORTRAN ); + EXPECT( const_iview( 4 ) == 4 ); + EXPECT( int( iview( 4 ) ) == 4 ); + + int val = iview( 4 ); + EXPECT( val == 4 ); + + val = iview( 4 ) + 1; + EXPECT( val == 5 ); } #endif @@ -285,7 +283,6 @@ CASE( "test_indexview_3d" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_metadata.cc b/src/tests/util/test_metadata.cc index c206dc318..bd97c3a7c 100644 --- a/src/tests/util/test_metadata.cc +++ b/src/tests/util/test_metadata.cc @@ -4,14 +4,15 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ -#include "atlas/library/Library.h" #include "atlas/array/ArrayView.h" -#include "atlas/util/Metadata.h" +#include "atlas/library/Library.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/util/Metadata.h" #include "tests/AtlasTestEnvironment.h" @@ -23,45 +24,33 @@ namespace test { //----------------------------------------------------------------------------- -CASE( "test_broadcast_to_self" ) -{ - Metadata metadata; - if( mpi::comm().rank() == 0 ) - { - metadata.set("paramID",128); - } - - // broadcast - metadata.broadcast(); +CASE( "test_broadcast_to_self" ) { + Metadata metadata; + if ( mpi::comm().rank() == 0 ) { metadata.set( "paramID", 128 ); } - EXPECT( metadata.has("paramID") ); - if( metadata.has("paramID") ) - EXPECT( metadata.get("paramID") == 128 ); + // broadcast + metadata.broadcast(); + EXPECT( metadata.has( "paramID" ) ); + if ( metadata.has( "paramID" ) ) EXPECT( metadata.get( "paramID" ) == 128 ); } // ----------------------------------------------------------------------------- -CASE( "test_broadcast_to_other" ) -{ - size_t root = 0; - Metadata global; - if( mpi::comm().rank() == root ) - { - global.set("paramID",128); - } +CASE( "test_broadcast_to_other" ) { + size_t root = 0; + Metadata global; + if ( mpi::comm().rank() == root ) { global.set( "paramID", 128 ); } - Metadata local; + Metadata local; - // broadcast - global.broadcast(local); + // broadcast + global.broadcast( local ); - EXPECT( local.has("paramID") ); - if( local.has("paramID") ) - EXPECT( local.get("paramID") == 128 ); + EXPECT( local.has( "paramID" ) ); + 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" ) ); } //----------------------------------------------------------------------------- @@ -69,7 +58,6 @@ CASE( "test_broadcast_to_other" ) } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_polygon.cc b/src/tests/util/test_polygon.cc index 826aece40..481235111 100644 --- a/src/tests/util/test_polygon.cc +++ b/src/tests/util/test_polygon.cc @@ -4,131 +4,64 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ #include #include #include -#include "atlas/util/SphericalPolygon.h" #include "atlas/util/Point.h" +#include "atlas/util/SphericalPolygon.h" #include "tests/AtlasTestEnvironment.h" namespace atlas { namespace test { -CASE( "test_polygon_something" ) -{ +CASE( "test_polygon_something" ) { using util::SphericalPolygon; using p = PointLonLat; typedef std::pair point_inside_t; - SphericalPolygon poly( - std::vector { - p(122.143, 35.9951), - p(120, 30.4576), - p(118.125, 24.9199), - p(116.471, 19.3822), - p(121.765, 19.3822), - p(120, 13.8445), - p(118.421, 8.3067), - p(117, 2.7689), - p(112.5, 2.7689), - p(112.5, -2.7689), - p(117, -2.7689), - p(113.684, -8.3067), - p(118.421, -8.3067), - p(115, -13.8445), - p(120, -13.8445), - p(116.471, -19.3822), - p(112.5, -24.9199), - p(118.125, -24.9199), - p(114, -30.4576), - p(120, -30.4576), - p(115.714, -35.9951), - p(122.143, -35.9951), - p(128.571, -35.9951), - p(135, -35.9951), - p(141.429, -35.9951), - p(147.857, -35.9951), - p(154.286, -35.9951), - p(160.714, -35.9951), - p(167.143, -35.9951), - p(173.571, -35.9951), - p(180, -35.9951), - p(186.429, -35.9951), - p(192.857, -35.9951), - p(199.286, -35.9951), - p(205.714, -35.9951), - p(212.143, -35.9951), - p(218.571, -35.9951), - p(225, -35.9951), - p(231.429, -35.9951), - p(237.857, -35.9951), - p(240, -30.4576), - p(234, -30.4576), - p(236.25, -24.9199), - p(238.235, -19.3822), - p(232.941, -19.3822), - p(235, -13.8445), - p(236.842, -8.3067), - p(238.5, -2.7689), - p(234, -2.7689), - p(234, 2.7689), - p(238.5, 2.7689), - p(241.579, 8.3067), - p(236.842, 8.3067), - p(240, 13.8445), - p(235, 13.8445), - p(238.235, 19.3822), - p(241.875, 24.9199), - p(236.25, 24.9199), - p(240, 30.4576), - p(244.286, 35.9951), - p(237.857, 35.9951), - p(231.429, 35.9951), - p(225, 35.9951), - p(218.571, 35.9951), - p(212.143, 35.9951), - p(205.714, 35.9951), - p(199.286, 35.9951), - p(192.857, 35.9951), - p(186.429, 35.9951), - p(180, 35.9951), - p(173.571, 35.9951), - p(167.143, 35.9951), - p(160.714, 35.9951), - p(154.286, 35.9951), - p(147.857, 35.9951), - p(141.429, 35.9951), - p(135, 35.9951), - p(128.571, 35.9951), - p(122.143, 35.9951) - } ); + SphericalPolygon poly( std::vector{ + p( 122.143, 35.9951 ), p( 120, 30.4576 ), p( 118.125, 24.9199 ), p( 116.471, 19.3822 ), + p( 121.765, 19.3822 ), p( 120, 13.8445 ), p( 118.421, 8.3067 ), p( 117, 2.7689 ), + p( 112.5, 2.7689 ), p( 112.5, -2.7689 ), p( 117, -2.7689 ), p( 113.684, -8.3067 ), + p( 118.421, -8.3067 ), p( 115, -13.8445 ), p( 120, -13.8445 ), p( 116.471, -19.3822 ), + p( 112.5, -24.9199 ), p( 118.125, -24.9199 ), p( 114, -30.4576 ), p( 120, -30.4576 ), + p( 115.714, -35.9951 ), p( 122.143, -35.9951 ), p( 128.571, -35.9951 ), p( 135, -35.9951 ), + p( 141.429, -35.9951 ), p( 147.857, -35.9951 ), p( 154.286, -35.9951 ), p( 160.714, -35.9951 ), + p( 167.143, -35.9951 ), p( 173.571, -35.9951 ), p( 180, -35.9951 ), p( 186.429, -35.9951 ), + p( 192.857, -35.9951 ), p( 199.286, -35.9951 ), p( 205.714, -35.9951 ), p( 212.143, -35.9951 ), + p( 218.571, -35.9951 ), p( 225, -35.9951 ), p( 231.429, -35.9951 ), p( 237.857, -35.9951 ), + p( 240, -30.4576 ), p( 234, -30.4576 ), p( 236.25, -24.9199 ), p( 238.235, -19.3822 ), + p( 232.941, -19.3822 ), p( 235, -13.8445 ), p( 236.842, -8.3067 ), p( 238.5, -2.7689 ), + p( 234, -2.7689 ), p( 234, 2.7689 ), p( 238.5, 2.7689 ), p( 241.579, 8.3067 ), + p( 236.842, 8.3067 ), p( 240, 13.8445 ), p( 235, 13.8445 ), p( 238.235, 19.3822 ), + p( 241.875, 24.9199 ), p( 236.25, 24.9199 ), p( 240, 30.4576 ), p( 244.286, 35.9951 ), + p( 237.857, 35.9951 ), p( 231.429, 35.9951 ), p( 225, 35.9951 ), p( 218.571, 35.9951 ), + p( 212.143, 35.9951 ), p( 205.714, 35.9951 ), p( 199.286, 35.9951 ), p( 192.857, 35.9951 ), + p( 186.429, 35.9951 ), p( 180, 35.9951 ), p( 173.571, 35.9951 ), p( 167.143, 35.9951 ), + p( 160.714, 35.9951 ), p( 154.286, 35.9951 ), p( 147.857, 35.9951 ), p( 141.429, 35.9951 ), + p( 135, 35.9951 ), p( 128.571, 35.9951 ), p( 122.143, 35.9951 )} ); - // test some partitioning points that (approximately) exist in lon-lat polygon, but not in a spherical polygon - for (auto P : std::vector { - point_inside_t(p(118.8, 26.9135), true), - point_inside_t(p(118.8, 19.3822), false), - point_inside_t(p(118.8, 9.6359), true), - point_inside_t(p(118.8, -13.8445), true), - point_inside_t(p(118.8, -15.7275), false), - point_inside_t(p(118.8, -30.4576), true), - point_inside_t(p(118.8, -32.0080), false), - point_inside_t(p(118.8, -35.9951), true) - }) { + // test some partitioning points that (approximately) exist in lon-lat + // polygon, but not in a spherical polygon + for ( auto P : std::vector{ + point_inside_t( p( 118.8, 26.9135 ), true ), point_inside_t( p( 118.8, 19.3822 ), false ), + point_inside_t( p( 118.8, 9.6359 ), true ), point_inside_t( p( 118.8, -13.8445 ), true ), + point_inside_t( p( 118.8, -15.7275 ), false ), point_inside_t( p( 118.8, -30.4576 ), true ), + point_inside_t( p( 118.8, -32.0080 ), false ), point_inside_t( p( 118.8, -35.9951 ), true )} ) { // 'contains' uses spherical geometry - EXPECT( poly.contains(P.first) == P.second ); + EXPECT( poly.contains( P.first ) == P.second ); } } +} // namespace test +} // namespace atlas -} // namespace test -} // namespace atlas - - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } diff --git a/src/tests/util/test_vector.cc b/src/tests/util/test_vector.cc index b8045506f..a80c9da63 100644 --- a/src/tests/util/test_vector.cc +++ b/src/tests/util/test_vector.cc @@ -4,7 +4,8 @@ * 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 + * granted to it by virtue of its status as an intergovernmental organisation + * nor * does it submit to any jurisdiction. */ @@ -18,33 +19,32 @@ namespace test { //----------------------------------------------------------------------------- -CASE("test_vector") { - Vector vec(3); +CASE( "test_vector" ) { + Vector vec( 3 ); - VectorView vec_view = make_host_vector_view(vec); + VectorView vec_view = make_host_vector_view( vec ); vec_view[0] = 3; vec_view[1] = -3; vec_view[2] = 1; - EXPECT( vec_view.size() == 3); - EXPECT( vec_view[0] == 3); - EXPECT( vec_view[1] == -3); - EXPECT( vec_view[2] == 1); + EXPECT( vec_view.size() == 3 ); + EXPECT( vec_view[0] == 3 ); + EXPECT( vec_view[1] == -3 ); + EXPECT( vec_view[2] == 1 ); - vec.resize(5); + vec.resize( 5 ); - //TODO invalidate preview views - VectorView vec_viewb = make_host_vector_view(vec); - vec_viewb[3] = 5; - vec_viewb[4] = 6; - - EXPECT( vec_viewb[0] == 3); - EXPECT( vec_viewb[1] == -3); - EXPECT( vec_viewb[2] == 1); - EXPECT( vec_viewb[3] == 5); - EXPECT( vec_viewb[4] == 6); + // TODO invalidate preview views + VectorView vec_viewb = make_host_vector_view( vec ); + vec_viewb[3] = 5; + vec_viewb[4] = 6; + EXPECT( vec_viewb[0] == 3 ); + EXPECT( vec_viewb[1] == -3 ); + EXPECT( vec_viewb[2] == 1 ); + EXPECT( vec_viewb[3] == 5 ); + EXPECT( vec_viewb[4] == 6 ); } //----------------------------------------------------------------------------- @@ -52,7 +52,6 @@ CASE("test_vector") { } // namespace test } // namespace atlas - -int main(int argc, char **argv) { +int main( int argc, char** argv ) { return atlas::test::run( argc, argv ); } From fe1467e6f7a9fa3b0e2f95ab1a7eeea1f8347aee Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 10:31:00 +0000 Subject: [PATCH 341/355] Fix application of clang-format to fortran include --- src/sandbox/fortran_modinc/mod1.h | 6 +++--- src/sandbox/fortran_modinc/mod2.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sandbox/fortran_modinc/mod1.h b/src/sandbox/fortran_modinc/mod1.h index 3f7fd35af..d6e3d6e3a 100644 --- a/src/sandbox/fortran_modinc/mod1.h +++ b/src/sandbox/fortran_modinc/mod1.h @@ -1,4 +1,4 @@ -!(C)Copyright 2013 - 2015 ECMWF. +! (C) Copyright 2013 ECMWF. - type, - extends( fckit_object ), public ::T1 end type +type, extends( fckit_object ), public :: T1 +end type diff --git a/src/sandbox/fortran_modinc/mod2.h b/src/sandbox/fortran_modinc/mod2.h index b0d9c4c30..be0fca4a2 100644 --- a/src/sandbox/fortran_modinc/mod2.h +++ b/src/sandbox/fortran_modinc/mod2.h @@ -1,4 +1,4 @@ -!(C)Copyright 2013 - 2015 ECMWF. +! (C) Copyright 2013 ECMWF. - type, - extends( fckit_object ), public ::T2 end type +type, extends( fckit_object ), public :: T2 +end type From b2433391450ce349aef3d161c34a2f6d67baa401 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 14:24:10 +0000 Subject: [PATCH 342/355] Turn on the barrier_timeout again for atlas c++ tests --- src/tests/AtlasTestEnvironment.h | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 7934cd7af..5feb6ad5f 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -30,12 +30,6 @@ #include "atlas/runtime/trace/StopWatch.h" #include "atlas/util/Config.h" -#ifdef ATLAS_TEST_MPI -#ifdef ECKIT_HAVE_MPI -#include -#endif -#endif - namespace atlas { namespace test { @@ -114,21 +108,15 @@ static double ATLAS_MPI_BARRIER_TIMEOUT() { } static int barrier_timeout( double seconds ) { -#ifdef ATLAS_TEST_MPI - if ( eckit::mpi::comm().size() > 1 ) { - MPI_Request req; - MPI_Ibarrier( MPI_COMM_WORLD, &req ); - - int barrier_succesful = 0; - runtime::trace::StopWatch watch; +// iBarrier only available since eckit 0.19.5 +#if _ECKIT_VERSION >= 1905 + auto req = eckit::mpi::comm().iBarrier(); + runtime::trace::StopWatch watch; + while ( not req.test() ) { watch.start(); - while ( not barrier_succesful ) { - watch.stop(); - if ( watch.elapsed() > seconds ) { return 1; } - watch.start(); - std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - MPI_Test( &req, &barrier_succesful, MPI_STATUS_IGNORE ); - } + std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); + watch.stop(); + if ( watch.elapsed() > seconds ) { return 1; } } #endif return 0; From 6dfe9bb0afc487bdd153e4b7467b3f0a7b1de4ed Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 15:26:16 +0000 Subject: [PATCH 343/355] Fix comment wrap --- src/apps/atlas-benchmark.cc | 3 +-- src/apps/atlas-gaussian-latitudes.cc | 3 +-- src/apps/atlas-gmsh-extract.cc | 3 +-- src/apps/atlas-grids.cc | 3 +-- src/apps/atlas-loadbalance.cc | 3 +-- src/apps/atlas-meshgen.cc | 3 +-- src/apps/atlas.cc | 3 +-- src/atlas/array.h | 3 +-- src/atlas/array/Array.h | 3 +-- src/atlas/array/ArrayIdx.h | 3 +-- src/atlas/array/ArrayLayout.h | 3 +-- src/atlas/array/ArrayShape.h | 3 +-- src/atlas/array/ArraySpec.cc | 3 +-- src/atlas/array/ArraySpec.h | 3 +-- src/atlas/array/ArrayStrides.h | 3 +-- src/atlas/array/ArrayUtil.cc | 3 +-- src/atlas/array/ArrayUtil.h | 3 +-- src/atlas/array/ArrayView.h | 3 +-- src/atlas/array/ArrayViewDefs.h | 3 +-- src/atlas/array/ArrayViewUtil.h | 3 +-- src/atlas/array/DataType.h | 3 +-- src/atlas/array/IndexView.h | 3 +-- src/atlas/array/LocalView.cc | 3 +-- src/atlas/array/LocalView.h | 3 +-- src/atlas/array/Range.h | 3 +-- src/atlas/array/Table.cc | 3 +-- src/atlas/array/Table.h | 3 +-- src/atlas/array/TableView.cc | 3 +-- src/atlas/array/TableView.h | 3 +-- src/atlas/array/gridtools/GPUClonable.h | 3 +-- src/atlas/array/gridtools/GridToolsArray.cc | 3 +-- src/atlas/array/gridtools/GridToolsArrayHelpers.h | 3 +-- src/atlas/array/gridtools/GridToolsArrayView.cc | 3 +-- src/atlas/array/gridtools/GridToolsArrayView.h | 3 +-- src/atlas/array/gridtools/GridToolsDataStore.h | 3 +-- src/atlas/array/gridtools/GridToolsIndexView.cc | 3 +-- src/atlas/array/gridtools/GridToolsIndexView.h | 3 +-- src/atlas/array/gridtools/GridToolsMakeView.h | 3 +-- src/atlas/array/helpers/ArrayAssigner.h | 3 +-- src/atlas/array/helpers/ArrayInitializer.h | 3 +-- src/atlas/array/helpers/ArraySlicer.h | 3 +-- src/atlas/array/helpers/ArrayWriter.h | 3 +-- src/atlas/array/native/NativeArrayView.cc | 3 +-- src/atlas/array/native/NativeArrayView.h | 3 +-- src/atlas/array/native/NativeDataStore.h | 3 +-- src/atlas/array/native/NativeIndexView.cc | 3 +-- src/atlas/array/native/NativeIndexView.h | 3 +-- src/atlas/array_fwd.h | 3 +-- src/atlas/domain.h | 3 +-- src/atlas/domain/Domain.cc | 3 +-- src/atlas/domain/Domain.h | 3 +-- src/atlas/field.h | 3 +-- src/atlas/field/Field.cc | 3 +-- src/atlas/field/Field.h | 3 +-- src/atlas/field/FieldCreator.cc | 3 +-- src/atlas/field/FieldCreator.h | 3 +-- src/atlas/field/FieldCreatorArraySpec.cc | 3 +-- src/atlas/field/FieldCreatorArraySpec.h | 3 +-- src/atlas/field/FieldCreatorIFS.cc | 3 +-- src/atlas/field/FieldCreatorIFS.h | 3 +-- src/atlas/field/FieldSet.cc | 3 +-- src/atlas/field/FieldSet.h | 3 +-- src/atlas/field/State.cc | 3 +-- src/atlas/field/State.h | 3 +-- src/atlas/field/detail/FieldImpl.cc | 3 +-- src/atlas/field/detail/FieldImpl.h | 3 +-- src/atlas/functionspace.h | 3 +-- src/atlas/functionspace/EdgeColumns.cc | 3 +-- src/atlas/functionspace/EdgeColumns.h | 3 +-- src/atlas/functionspace/FunctionSpace.cc | 3 +-- src/atlas/functionspace/FunctionSpace.h | 3 +-- src/atlas/functionspace/NodeColumns.cc | 3 +-- src/atlas/functionspace/NodeColumns.h | 3 +-- src/atlas/functionspace/NodeColumnsInterface.cc | 3 +-- src/atlas/functionspace/NodeColumnsInterface.h | 3 +-- src/atlas/functionspace/PointCloud.cc | 3 +-- src/atlas/functionspace/PointCloud.h | 3 +-- src/atlas/functionspace/Spectral.cc | 3 +-- src/atlas/functionspace/Spectral.h | 3 +-- src/atlas/functionspace/StructuredColumns.cc | 3 +-- src/atlas/functionspace/StructuredColumns.h | 3 +-- src/atlas/grid.h | 3 +-- src/atlas/grid/Distribution.cc | 3 +-- src/atlas/grid/Distribution.h | 3 +-- src/atlas/grid/Grid.cc | 3 +-- src/atlas/grid/Grid.h | 3 +-- src/atlas/grid/Iterator.h | 3 +-- src/atlas/grid/Partitioner.cc | 3 +-- src/atlas/grid/Partitioner.h | 3 +-- src/atlas/grid/detail/grid/Grid.cc | 3 +-- src/atlas/grid/detail/grid/Grid.h | 3 +-- src/atlas/grid/detail/grid/GridBuilder.cc | 3 +-- src/atlas/grid/detail/grid/GridBuilder.h | 3 +-- src/atlas/grid/detail/grid/Structured.cc | 3 +-- src/atlas/grid/detail/grid/Structured.h | 3 +-- src/atlas/grid/detail/grid/Unstructured.cc | 3 +-- src/atlas/grid/detail/grid/Unstructured.h | 3 +-- src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc | 3 +-- src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h | 3 +-- src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h | 3 +-- .../detail/partitioner/MatchingMeshPartitionerBruteForce.cc | 3 +-- .../detail/partitioner/MatchingMeshPartitionerBruteForce.h | 3 +-- .../detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc | 3 +-- .../detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h | 3 +-- .../partitioner/MatchingMeshPartitionerSphericalPolygon.cc | 3 +-- .../partitioner/MatchingMeshPartitionerSphericalPolygon.h | 3 +-- src/atlas/grid/detail/partitioner/Partitioner.cc | 3 +-- src/atlas/grid/detail/partitioner/Partitioner.h | 3 +-- src/atlas/grid/detail/partitioner/TransPartitioner.h | 3 +-- src/atlas/grid/detail/pl/classic_gaussian/N.cc | 3 +-- src/atlas/grid/detail/pl/classic_gaussian/N.h | 3 +-- src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc | 3 +-- src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h | 3 +-- src/atlas/grid/detail/spacing/gaussian/Latitudes.cc | 3 +-- src/atlas/grid/detail/spacing/gaussian/Latitudes.h | 3 +-- src/atlas/grid/detail/spacing/gaussian/N.cc | 3 +-- src/atlas/grid/detail/spacing/gaussian/N.h | 3 +-- src/atlas/interpolation.h | 3 +-- src/atlas/interpolation/Interpolation.cc | 3 +-- src/atlas/interpolation/Interpolation.h | 3 +-- src/atlas/interpolation/Vector2D.h | 3 +-- src/atlas/interpolation/Vector3D.h | 3 +-- src/atlas/interpolation/element/Quad3D.cc | 3 +-- src/atlas/interpolation/element/Quad3D.h | 3 +-- src/atlas/interpolation/element/Triag3D.cc | 3 +-- src/atlas/interpolation/element/Triag3D.h | 3 +-- src/atlas/interpolation/method/FiniteElement.cc | 3 +-- src/atlas/interpolation/method/FiniteElement.h | 3 +-- src/atlas/interpolation/method/Intersect.cc | 3 +-- src/atlas/interpolation/method/Intersect.h | 3 +-- src/atlas/interpolation/method/KNearestNeighbours.cc | 3 +-- src/atlas/interpolation/method/KNearestNeighbours.h | 3 +-- src/atlas/interpolation/method/KNearestNeighboursBase.cc | 3 +-- src/atlas/interpolation/method/KNearestNeighboursBase.h | 3 +-- src/atlas/interpolation/method/Method.cc | 3 +-- src/atlas/interpolation/method/Method.h | 3 +-- src/atlas/interpolation/method/NearestNeighbour.cc | 3 +-- src/atlas/interpolation/method/NearestNeighbour.h | 3 +-- src/atlas/interpolation/method/PointIndex3.cc | 3 +-- src/atlas/interpolation/method/PointIndex3.h | 3 +-- src/atlas/interpolation/method/PointSet.cc | 3 +-- src/atlas/interpolation/method/PointSet.h | 3 +-- src/atlas/interpolation/method/Ray.cc | 3 +-- src/atlas/interpolation/method/Ray.h | 3 +-- src/atlas/library/Library.cc | 3 +-- src/atlas/library/Library.h | 3 +-- src/atlas/mesh.h | 3 +-- src/atlas/mesh/Connectivity.cc | 3 +-- src/atlas/mesh/Connectivity.h | 3 +-- src/atlas/mesh/ElementType.cc | 3 +-- src/atlas/mesh/ElementType.h | 3 +-- src/atlas/mesh/Elements.cc | 3 +-- src/atlas/mesh/Elements.h | 3 +-- src/atlas/mesh/Halo.cc | 3 +-- src/atlas/mesh/Halo.h | 3 +-- src/atlas/mesh/HybridElements.cc | 3 +-- src/atlas/mesh/HybridElements.h | 3 +-- src/atlas/mesh/IsGhostNode.h | 3 +-- src/atlas/mesh/Mesh.cc | 3 +-- src/atlas/mesh/Mesh.h | 3 +-- src/atlas/mesh/Nodes.cc | 3 +-- src/atlas/mesh/Nodes.h | 3 +-- src/atlas/mesh/PartitionPolygon.cc | 3 +-- src/atlas/mesh/PartitionPolygon.h | 3 +-- src/atlas/mesh/actions/BuildCellCentres.cc | 3 +-- src/atlas/mesh/actions/BuildCellCentres.h | 3 +-- src/atlas/mesh/actions/BuildConvexHull3D.cc | 3 +-- src/atlas/mesh/actions/BuildConvexHull3D.h | 3 +-- src/atlas/mesh/actions/BuildDualMesh.cc | 3 +-- src/atlas/mesh/actions/BuildDualMesh.h | 3 +-- src/atlas/mesh/actions/BuildEdges.cc | 3 +-- src/atlas/mesh/actions/BuildEdges.h | 3 +-- src/atlas/mesh/actions/BuildHalo.cc | 3 +-- src/atlas/mesh/actions/BuildHalo.h | 3 +-- src/atlas/mesh/actions/BuildParallelFields.cc | 3 +-- src/atlas/mesh/actions/BuildParallelFields.h | 3 +-- src/atlas/mesh/actions/BuildPeriodicBoundaries.cc | 3 +-- src/atlas/mesh/actions/BuildPeriodicBoundaries.h | 3 +-- src/atlas/mesh/actions/BuildStatistics.cc | 3 +-- src/atlas/mesh/actions/BuildStatistics.h | 3 +-- src/atlas/mesh/actions/BuildTorusXYZField.cc | 3 +-- src/atlas/mesh/actions/BuildTorusXYZField.h | 3 +-- src/atlas/mesh/actions/BuildXYZField.cc | 3 +-- src/atlas/mesh/actions/BuildXYZField.h | 3 +-- src/atlas/mesh/actions/ExtendNodesGlobal.cc | 3 +-- src/atlas/mesh/actions/ExtendNodesGlobal.h | 3 +-- src/atlas/mesh/actions/WriteLoadBalanceReport.cc | 3 +-- src/atlas/mesh/actions/WriteLoadBalanceReport.h | 3 +-- src/atlas/mesh/detail/AccumulateFacets.cc | 3 +-- src/atlas/mesh/detail/AccumulateFacets.h | 3 +-- src/atlas/mesh/detail/MeshImpl.cc | 3 +-- src/atlas/mesh/detail/MeshImpl.h | 3 +-- src/atlas/mesh/detail/MeshIntf.cc | 3 +-- src/atlas/mesh/detail/MeshIntf.h | 3 +-- src/atlas/mesh/detail/PartitionGraph.cc | 3 +-- src/atlas/mesh/detail/PartitionGraph.h | 3 +-- src/atlas/mesh/detail/PeriodicTransform.h | 3 +-- src/atlas/meshgenerator.h | 3 +-- src/atlas/meshgenerator/DelaunayMeshGenerator.cc | 3 +-- src/atlas/meshgenerator/DelaunayMeshGenerator.h | 3 +-- src/atlas/meshgenerator/MeshGenerator.cc | 3 +-- src/atlas/meshgenerator/MeshGenerator.h | 3 +-- src/atlas/meshgenerator/StructuredMeshGenerator.cc | 3 +-- src/atlas/meshgenerator/StructuredMeshGenerator.h | 3 +-- src/atlas/numerics/Method.cc | 3 +-- src/atlas/numerics/Method.h | 3 +-- src/atlas/numerics/Nabla.cc | 3 +-- src/atlas/numerics/Nabla.h | 3 +-- src/atlas/numerics/fvm/Method.cc | 3 +-- src/atlas/numerics/fvm/Method.h | 3 +-- src/atlas/numerics/fvm/Nabla.cc | 3 +-- src/atlas/numerics/fvm/Nabla.h | 3 +-- src/atlas/option.h | 3 +-- src/atlas/option/Options.cc | 3 +-- src/atlas/option/Options.h | 3 +-- src/atlas/option/TransOptions.cc | 3 +-- src/atlas/option/TransOptions.h | 3 +-- src/atlas/output/Gmsh.cc | 3 +-- src/atlas/output/Gmsh.h | 3 +-- src/atlas/output/Output.cc | 3 +-- src/atlas/output/Output.h | 3 +-- src/atlas/output/detail/GmshIO.cc | 3 +-- src/atlas/output/detail/GmshIO.h | 3 +-- src/atlas/output/detail/PointCloudIO.cc | 3 +-- src/atlas/output/detail/PointCloudIO.h | 3 +-- src/atlas/parallel/Checksum.cc | 3 +-- src/atlas/parallel/Checksum.h | 3 +-- src/atlas/parallel/GatherScatter.cc | 3 +-- src/atlas/parallel/GatherScatter.h | 3 +-- src/atlas/parallel/HaloExchange.cc | 3 +-- src/atlas/parallel/HaloExchange.h | 3 +-- src/atlas/parallel/HaloExchangeCUDA.h | 3 +-- src/atlas/parallel/HaloExchangeImpl.h | 3 +-- src/atlas/parallel/mpi/Buffer.h | 3 +-- src/atlas/parallel/mpi/Statistics.h | 3 +-- src/atlas/parallel/mpi/mpi.cc | 3 +-- src/atlas/parallel/mpi/mpi.h | 3 +-- src/atlas/parallel/omp/omp.cc | 3 +-- src/atlas/parallel/omp/omp.h | 3 +-- src/atlas/projection.h | 3 +-- src/atlas/runtime/AtlasTool.h | 3 +-- src/atlas/runtime/Log.cc | 3 +-- src/atlas/runtime/Trace.h | 3 +-- src/atlas/runtime/trace/Barriers.cc | 3 +-- src/atlas/runtime/trace/Barriers.h | 3 +-- src/atlas/runtime/trace/Logging.cc | 3 +-- src/atlas/runtime/trace/Logging.h | 3 +-- src/atlas/runtime/trace/Nesting.cc | 3 +-- src/atlas/runtime/trace/Nesting.h | 3 +-- src/atlas/runtime/trace/StopWatch.h | 3 +-- src/atlas/runtime/trace/Timings.cc | 3 +-- src/atlas/runtime/trace/Timings.h | 3 +-- src/atlas/runtime/trace/TraceT.h | 3 +-- src/atlas/trans/Trans.cc | 3 +-- src/atlas/trans/Trans.h | 3 +-- src/atlas/trans/VorDivToUV.cc | 3 +-- src/atlas/trans/VorDivToUV.h | 3 +-- src/atlas/trans/ifs/TransIFS.cc | 3 +-- src/atlas/trans/ifs/TransIFS.h | 3 +-- src/atlas/trans/ifs/TransIFSNodeColumns.cc | 3 +-- src/atlas/trans/ifs/TransIFSNodeColumns.h | 3 +-- src/atlas/trans/ifs/TransIFSStructuredColumns.cc | 3 +-- src/atlas/trans/ifs/TransIFSStructuredColumns.h | 3 +-- src/atlas/trans/ifs/VorDivToUVIFS.cc | 3 +-- src/atlas/trans/ifs/VorDivToUVIFS.h | 3 +-- src/atlas/trans/local/FourierTransforms.cc | 3 +-- src/atlas/trans/local/FourierTransforms.h | 3 +-- src/atlas/trans/local/LegendrePolynomials.cc | 3 +-- src/atlas/trans/local/LegendrePolynomials.h | 3 +-- src/atlas/trans/local/LegendreTransforms.cc | 3 +-- src/atlas/trans/local/LegendreTransforms.h | 3 +-- src/atlas/trans/local/TransLocal.cc | 3 +-- src/atlas/trans/local/TransLocal.h | 3 +-- src/atlas/trans/local/VorDivToUVLocal.cc | 3 +-- src/atlas/trans/local/VorDivToUVLocal.h | 3 +-- src/atlas/util/Bitflags.h | 3 +-- src/atlas/util/Config.cc | 3 +-- src/atlas/util/Config.h | 3 +-- src/atlas/util/Constants.h | 3 +-- src/atlas/util/CoordinateEnums.h | 3 +-- src/atlas/util/Earth.cc | 3 +-- src/atlas/util/Earth.h | 3 +-- src/atlas/util/GaussianLatitudes.cc | 3 +-- src/atlas/util/GaussianLatitudes.h | 3 +-- src/atlas/util/LonLatMicroDeg.h | 3 +-- src/atlas/util/LonLatPolygon.cc | 3 +-- src/atlas/util/LonLatPolygon.h | 3 +-- src/atlas/util/Metadata.cc | 3 +-- src/atlas/util/Metadata.h | 3 +-- src/atlas/util/MicroDeg.h | 3 +-- src/atlas/util/Polygon.cc | 3 +-- src/atlas/util/Polygon.h | 3 +-- src/atlas/util/Rotation.cc | 3 +-- src/atlas/util/Rotation.h | 3 +-- src/atlas/util/SphericalPolygon.cc | 3 +-- src/atlas/util/SphericalPolygon.h | 3 +-- src/atlas/util/Unique.h | 3 +-- src/atlas/util/detail/Cache.h | 3 +-- src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc | 3 +-- src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc | 3 +-- src/sandbox/grid_distribution/atlas-grid-distribution.cc | 3 +-- src/sandbox/interpolation/PartitionedMesh.cc | 3 +-- src/sandbox/interpolation/PartitionedMesh.h | 3 +-- src/sandbox/interpolation/atlas-parallel-interpolation.cc | 3 +-- src/tests/AtlasTestEnvironment.h | 3 +-- src/tests/TestMeshes.h | 3 +-- src/tests/array/test_array.cc | 3 +-- src/tests/array/test_array_slicer.cc | 3 +-- src/tests/array/test_array_view_util.cc | 3 +-- src/tests/array/test_svector.cc | 3 +-- src/tests/array/test_table.cc | 3 +-- src/tests/functionspace/test_functionspace.cc | 3 +-- src/tests/functionspace/test_pointcloud.cc | 3 +-- src/tests/functionspace/test_structuredcolumns.cc | 3 +-- src/tests/grid/test_domain.cc | 3 +-- src/tests/grid/test_field.cc | 3 +-- src/tests/grid/test_grid_ptr.cc | 3 +-- src/tests/grid/test_grids.cc | 3 +-- src/tests/grid/test_rotation.cc | 3 +-- src/tests/grid/test_state.cc | 3 +-- src/tests/interpolation/test_Quad3D.cc | 3 +-- src/tests/interpolation/test_interpolation_finite_element.cc | 3 +-- src/tests/io/test_gmsh.cc | 3 +-- src/tests/io/test_pointcloud_io.cc | 3 +-- src/tests/mesh/test_accumulate_facets.cc | 3 +-- src/tests/mesh/test_cgal_mesh_gen_from_points.cc | 3 +-- src/tests/mesh/test_connectivity.cc | 3 +-- src/tests/mesh/test_distmesh.cc | 3 +-- src/tests/mesh/test_elements.cc | 3 +-- src/tests/mesh/test_halo.cc | 3 +-- src/tests/mesh/test_ll.cc | 3 +-- src/tests/mesh/test_meshgen3d.cc | 3 +-- src/tests/mesh/test_parfields.cc | 3 +-- src/tests/mesh/test_rgg.cc | 3 +-- src/tests/mesh/test_shapefunctions.cc | 3 +-- src/tests/numerics/test_fvm_nabla.cc | 3 +-- src/tests/parallel/test_gather.cc | 3 +-- src/tests/parallel/test_haloexchange.cc | 3 +-- src/tests/trans/test_trans.cc | 3 +-- src/tests/trans/test_trans_invtrans_grad.cc | 3 +-- src/tests/trans/test_transgeneral.cc | 3 +-- src/tests/util/test_earth.cc | 3 +-- src/tests/util/test_flags.cc | 3 +-- src/tests/util/test_footprint.cc | 3 +-- src/tests/util/test_indexview.cc | 3 +-- src/tests/util/test_metadata.cc | 3 +-- src/tests/util/test_polygon.cc | 3 +-- src/tests/util/test_vector.cc | 3 +-- 348 files changed, 348 insertions(+), 696 deletions(-) diff --git a/src/apps/atlas-benchmark.cc b/src/apps/atlas-benchmark.cc index 26e2c5041..421eb4db0 100644 --- a/src/apps/atlas-benchmark.cc +++ b/src/apps/atlas-benchmark.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /** diff --git a/src/apps/atlas-gaussian-latitudes.cc b/src/apps/atlas-gaussian-latitudes.cc index 99bedf130..51337cbce 100644 --- a/src/apps/atlas-gaussian-latitudes.cc +++ b/src/apps/atlas-gaussian-latitudes.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/apps/atlas-gmsh-extract.cc b/src/apps/atlas-gmsh-extract.cc index f08ea25c3..a4e48d2c7 100644 --- a/src/apps/atlas-gmsh-extract.cc +++ b/src/apps/atlas-gmsh-extract.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/apps/atlas-grids.cc b/src/apps/atlas-grids.cc index c3cf8c5fc..7645a79a7 100644 --- a/src/apps/atlas-grids.cc +++ b/src/apps/atlas-grids.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/apps/atlas-loadbalance.cc b/src/apps/atlas-loadbalance.cc index 300b113dc..17f254ca3 100644 --- a/src/apps/atlas-loadbalance.cc +++ b/src/apps/atlas-loadbalance.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/apps/atlas-meshgen.cc b/src/apps/atlas-meshgen.cc index 536769a6a..955610cc6 100644 --- a/src/apps/atlas-meshgen.cc +++ b/src/apps/atlas-meshgen.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/apps/atlas.cc b/src/apps/atlas.cc index 920956b6e..0ca8a3860 100644 --- a/src/apps/atlas.cc +++ b/src/apps/atlas.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/library/Library.h" diff --git a/src/atlas/array.h b/src/atlas/array.h index b492b9276..cf9c198ef 100644 --- a/src/atlas/array.h +++ b/src/atlas/array.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index e12183f0d..ba7309c97 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/ArrayIdx.h b/src/atlas/array/ArrayIdx.h index ebb59df8c..89269fdf7 100644 --- a/src/atlas/array/ArrayIdx.h +++ b/src/atlas/array/ArrayIdx.h @@ -5,8 +5,7 @@ * 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 size_tergovernmental organisation - * nor - * does it submit to any jurisdiction. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/ArrayLayout.h b/src/atlas/array/ArrayLayout.h index f8bef5b3d..0437831cf 100644 --- a/src/atlas/array/ArrayLayout.h +++ b/src/atlas/array/ArrayLayout.h @@ -5,8 +5,7 @@ * 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 size_tergovernmental organisation - * nor - * does it submit to any jurisdiction. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/ArrayShape.h b/src/atlas/array/ArrayShape.h index bf1dca01e..2c9ecf626 100644 --- a/src/atlas/array/ArrayShape.h +++ b/src/atlas/array/ArrayShape.h @@ -5,8 +5,7 @@ * 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 size_tergovernmental organisation - * nor - * does it submit to any jurisdiction. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/ArraySpec.cc b/src/atlas/array/ArraySpec.cc index 055e9ea6f..4845777b2 100644 --- a/src/atlas/array/ArraySpec.cc +++ b/src/atlas/array/ArraySpec.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/array/ArraySpec.h b/src/atlas/array/ArraySpec.h index 4f13e4fdb..a47236180 100644 --- a/src/atlas/array/ArraySpec.h +++ b/src/atlas/array/ArraySpec.h @@ -5,8 +5,7 @@ * 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 size_tergovernmental organisation - * nor - * does it submit to any jurisdiction. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/ArrayStrides.h b/src/atlas/array/ArrayStrides.h index 4c087c9c8..d7be323da 100644 --- a/src/atlas/array/ArrayStrides.h +++ b/src/atlas/array/ArrayStrides.h @@ -5,8 +5,7 @@ * 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 size_tergovernmental organisation - * nor - * does it submit to any jurisdiction. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/ArrayUtil.cc b/src/atlas/array/ArrayUtil.cc index de53cb3d4..eac20c46f 100644 --- a/src/atlas/array/ArrayUtil.cc +++ b/src/atlas/array/ArrayUtil.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/ArrayUtil.h" diff --git a/src/atlas/array/ArrayUtil.h b/src/atlas/array/ArrayUtil.h index d455cb9ad..b80b76ef5 100644 --- a/src/atlas/array/ArrayUtil.h +++ b/src/atlas/array/ArrayUtil.h @@ -5,8 +5,7 @@ * 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 size_tergovernmental organisation - * nor - * does it submit to any jurisdiction. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/ArrayView.h b/src/atlas/array/ArrayView.h index 535eb5eeb..a5ff11565 100644 --- a/src/atlas/array/ArrayView.h +++ b/src/atlas/array/ArrayView.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file ArrayView.h diff --git a/src/atlas/array/ArrayViewDefs.h b/src/atlas/array/ArrayViewDefs.h index c5e54610a..cde447098 100644 --- a/src/atlas/array/ArrayViewDefs.h +++ b/src/atlas/array/ArrayViewDefs.h @@ -5,8 +5,7 @@ * 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 size_tergovernmental organisation - * nor - * does it submit to any jurisdiction. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/ArrayViewUtil.h b/src/atlas/array/ArrayViewUtil.h index 09aed9501..da98d9f58 100644 --- a/src/atlas/array/ArrayViewUtil.h +++ b/src/atlas/array/ArrayViewUtil.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once #include "atlas/array/ArrayView.h" diff --git a/src/atlas/array/DataType.h b/src/atlas/array/DataType.h index 8e3465472..d765a9aa9 100644 --- a/src/atlas/array/DataType.h +++ b/src/atlas/array/DataType.h @@ -5,8 +5,7 @@ * 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 size_tergovernmental organisation - * nor - * does it submit to any jurisdiction. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/IndexView.h b/src/atlas/array/IndexView.h index 3ccc7f80a..7e095913e 100644 --- a/src/atlas/array/IndexView.h +++ b/src/atlas/array/IndexView.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file IndexView.h diff --git a/src/atlas/array/LocalView.cc b/src/atlas/array/LocalView.cc index 1bc952217..cd0025f1d 100644 --- a/src/atlas/array/LocalView.cc +++ b/src/atlas/array/LocalView.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/LocalView.h" diff --git a/src/atlas/array/LocalView.h b/src/atlas/array/LocalView.h index 0eeba3668..60f0c8214 100644 --- a/src/atlas/array/LocalView.h +++ b/src/atlas/array/LocalView.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file LocalView.h diff --git a/src/atlas/array/Range.h b/src/atlas/array/Range.h index 36fba4cfe..c8eb10535 100644 --- a/src/atlas/array/Range.h +++ b/src/atlas/array/Range.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/Table.cc b/src/atlas/array/Table.cc index c189ddad1..6d76807c5 100644 --- a/src/atlas/array/Table.cc +++ b/src/atlas/array/Table.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/Table.h" diff --git a/src/atlas/array/Table.h b/src/atlas/array/Table.h index 8abf4450c..215eccb05 100644 --- a/src/atlas/array/Table.h +++ b/src/atlas/array/Table.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file Table.h diff --git a/src/atlas/array/TableView.cc b/src/atlas/array/TableView.cc index c7f4f09ad..25c0e57c1 100644 --- a/src/atlas/array/TableView.cc +++ b/src/atlas/array/TableView.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/TableView.h" diff --git a/src/atlas/array/TableView.h b/src/atlas/array/TableView.h index 2e8045f95..87a7bff95 100644 --- a/src/atlas/array/TableView.h +++ b/src/atlas/array/TableView.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file Table.h diff --git a/src/atlas/array/gridtools/GPUClonable.h b/src/atlas/array/gridtools/GPUClonable.h index 6beaa5b61..fdbf21d32 100644 --- a/src/atlas/array/gridtools/GPUClonable.h +++ b/src/atlas/array/gridtools/GPUClonable.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 960fa5d91..1cd4f5c6d 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index 167b28891..462ab4d15 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/gridtools/GridToolsArrayView.cc b/src/atlas/array/gridtools/GridToolsArrayView.cc index fd3c8a16f..8f98835ce 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.cc +++ b/src/atlas/array/gridtools/GridToolsArrayView.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/gridtools/GridToolsArrayView.h" diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index 049903d17..f1eb1f5f8 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/gridtools/GridToolsDataStore.h b/src/atlas/array/gridtools/GridToolsDataStore.h index 29023f56c..8457575a8 100644 --- a/src/atlas/array/gridtools/GridToolsDataStore.h +++ b/src/atlas/array/gridtools/GridToolsDataStore.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/gridtools/GridToolsIndexView.cc b/src/atlas/array/gridtools/GridToolsIndexView.cc index 92fd60b9b..921989ba8 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.cc +++ b/src/atlas/array/gridtools/GridToolsIndexView.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/array/gridtools/GridToolsIndexView.h b/src/atlas/array/gridtools/GridToolsIndexView.h index 8da6980ae..f2fb40834 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.h +++ b/src/atlas/array/gridtools/GridToolsIndexView.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/gridtools/GridToolsMakeView.h b/src/atlas/array/gridtools/GridToolsMakeView.h index cfc44d918..134ce5a42 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.h +++ b/src/atlas/array/gridtools/GridToolsMakeView.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/helpers/ArrayAssigner.h b/src/atlas/array/helpers/ArrayAssigner.h index 393298304..9bbda4552 100644 --- a/src/atlas/array/helpers/ArrayAssigner.h +++ b/src/atlas/array/helpers/ArrayAssigner.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/helpers/ArrayInitializer.h b/src/atlas/array/helpers/ArrayInitializer.h index 697ca6e1f..56791aef6 100644 --- a/src/atlas/array/helpers/ArrayInitializer.h +++ b/src/atlas/array/helpers/ArrayInitializer.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/helpers/ArraySlicer.h b/src/atlas/array/helpers/ArraySlicer.h index d2b1a2cc2..2a34c40dd 100644 --- a/src/atlas/array/helpers/ArraySlicer.h +++ b/src/atlas/array/helpers/ArraySlicer.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/helpers/ArrayWriter.h b/src/atlas/array/helpers/ArrayWriter.h index ff92ba7a8..bd6356ae2 100644 --- a/src/atlas/array/helpers/ArrayWriter.h +++ b/src/atlas/array/helpers/ArrayWriter.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/native/NativeArrayView.cc b/src/atlas/array/native/NativeArrayView.cc index ef006e800..f21c5d923 100644 --- a/src/atlas/array/native/NativeArrayView.cc +++ b/src/atlas/array/native/NativeArrayView.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 41fae7c28..269fe90c6 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file ArrayView.h diff --git a/src/atlas/array/native/NativeDataStore.h b/src/atlas/array/native/NativeDataStore.h index 3e9599b59..f85c76de9 100644 --- a/src/atlas/array/native/NativeDataStore.h +++ b/src/atlas/array/native/NativeDataStore.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/array/native/NativeIndexView.cc b/src/atlas/array/native/NativeIndexView.cc index dc2c642ea..a7d2e1d70 100644 --- a/src/atlas/array/native/NativeIndexView.cc +++ b/src/atlas/array/native/NativeIndexView.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/native/NativeIndexView.h" diff --git a/src/atlas/array/native/NativeIndexView.h b/src/atlas/array/native/NativeIndexView.h index 7bead54d7..e56c32051 100644 --- a/src/atlas/array/native/NativeIndexView.h +++ b/src/atlas/array/native/NativeIndexView.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file IndexView.h diff --git a/src/atlas/array_fwd.h b/src/atlas/array_fwd.h index 01f236e53..30513d004 100644 --- a/src/atlas/array_fwd.h +++ b/src/atlas/array_fwd.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/domain.h b/src/atlas/domain.h index 9f9fa19c4..ecb0a708e 100644 --- a/src/atlas/domain.h +++ b/src/atlas/domain.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/domain/Domain.cc b/src/atlas/domain/Domain.cc index 8d46a37e4..fa90c102a 100644 --- a/src/atlas/domain/Domain.cc +++ b/src/atlas/domain/Domain.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/domain/Domain.h" diff --git a/src/atlas/domain/Domain.h b/src/atlas/domain/Domain.h index f7d785098..90bc7838e 100644 --- a/src/atlas/domain/Domain.h +++ b/src/atlas/domain/Domain.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/field.h b/src/atlas/field.h index d7987f3cd..78c5dfb39 100644 --- a/src/atlas/field.h +++ b/src/atlas/field.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/field/Field.cc b/src/atlas/field/Field.cc index 043b255db..e06069877 100644 --- a/src/atlas/field/Field.cc +++ b/src/atlas/field/Field.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/field/Field.h b/src/atlas/field/Field.h index 78def69ba..420d55f3d 100644 --- a/src/atlas/field/Field.h +++ b/src/atlas/field/Field.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/field/FieldCreator.cc b/src/atlas/field/FieldCreator.cc index 5435fdaa3..b8521db1d 100644 --- a/src/atlas/field/FieldCreator.cc +++ b/src/atlas/field/FieldCreator.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/field/FieldCreator.h" diff --git a/src/atlas/field/FieldCreator.h b/src/atlas/field/FieldCreator.h index 21cf48936..4ef5e4a4c 100644 --- a/src/atlas/field/FieldCreator.h +++ b/src/atlas/field/FieldCreator.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/field/FieldCreatorArraySpec.cc b/src/atlas/field/FieldCreatorArraySpec.cc index 7dbefdebf..a39b786c3 100644 --- a/src/atlas/field/FieldCreatorArraySpec.cc +++ b/src/atlas/field/FieldCreatorArraySpec.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/field/FieldCreatorArraySpec.h" diff --git a/src/atlas/field/FieldCreatorArraySpec.h b/src/atlas/field/FieldCreatorArraySpec.h index 378c2c491..49bb00102 100644 --- a/src/atlas/field/FieldCreatorArraySpec.h +++ b/src/atlas/field/FieldCreatorArraySpec.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/field/FieldCreatorIFS.cc b/src/atlas/field/FieldCreatorIFS.cc index 2894fb7cb..2f13f335b 100644 --- a/src/atlas/field/FieldCreatorIFS.cc +++ b/src/atlas/field/FieldCreatorIFS.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/field/FieldCreatorIFS.h" diff --git a/src/atlas/field/FieldCreatorIFS.h b/src/atlas/field/FieldCreatorIFS.h index b43c474cf..7866e224a 100644 --- a/src/atlas/field/FieldCreatorIFS.h +++ b/src/atlas/field/FieldCreatorIFS.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/field/FieldSet.cc b/src/atlas/field/FieldSet.cc index ca60e9302..8f5c738ee 100644 --- a/src/atlas/field/FieldSet.cc +++ b/src/atlas/field/FieldSet.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/field/FieldSet.h" diff --git a/src/atlas/field/FieldSet.h b/src/atlas/field/FieldSet.h index d48122d04..3b69afb0b 100644 --- a/src/atlas/field/FieldSet.h +++ b/src/atlas/field/FieldSet.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/field/State.cc b/src/atlas/field/State.cc index 3fbd68ff7..9f4ff9dfa 100644 --- a/src/atlas/field/State.cc +++ b/src/atlas/field/State.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/field/State.h" diff --git a/src/atlas/field/State.h b/src/atlas/field/State.h index 98decd278..72b73d384 100644 --- a/src/atlas/field/State.h +++ b/src/atlas/field/State.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index 1959c570d..f3a924409 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/field/detail/FieldImpl.h b/src/atlas/field/detail/FieldImpl.h index 66fe26f36..2222ca9f5 100644 --- a/src/atlas/field/detail/FieldImpl.h +++ b/src/atlas/field/detail/FieldImpl.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/functionspace.h b/src/atlas/functionspace.h index bbe881141..db178dd2b 100644 --- a/src/atlas/functionspace.h +++ b/src/atlas/functionspace.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 58c4b57ab..60fefaa5f 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/functionspace/EdgeColumns.h b/src/atlas/functionspace/EdgeColumns.h index 5883e9cfc..7f22b397d 100644 --- a/src/atlas/functionspace/EdgeColumns.h +++ b/src/atlas/functionspace/EdgeColumns.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/functionspace/FunctionSpace.cc b/src/atlas/functionspace/FunctionSpace.cc index 078c5a1b6..3e5920ef4 100644 --- a/src/atlas/functionspace/FunctionSpace.cc +++ b/src/atlas/functionspace/FunctionSpace.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/functionspace/FunctionSpace.h" diff --git a/src/atlas/functionspace/FunctionSpace.h b/src/atlas/functionspace/FunctionSpace.h index f10a9eb4c..dd60223a4 100644 --- a/src/atlas/functionspace/FunctionSpace.h +++ b/src/atlas/functionspace/FunctionSpace.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index d9b815b9d..23b1711c6 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/functionspace/NodeColumns.h b/src/atlas/functionspace/NodeColumns.h index 806afaecd..e61f96299 100644 --- a/src/atlas/functionspace/NodeColumns.h +++ b/src/atlas/functionspace/NodeColumns.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/functionspace/NodeColumnsInterface.cc b/src/atlas/functionspace/NodeColumnsInterface.cc index ec54e9b45..c139649e8 100644 --- a/src/atlas/functionspace/NodeColumnsInterface.cc +++ b/src/atlas/functionspace/NodeColumnsInterface.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/functionspace/NodeColumnsInterface.h" diff --git a/src/atlas/functionspace/NodeColumnsInterface.h b/src/atlas/functionspace/NodeColumnsInterface.h index a137ef105..254288ed8 100644 --- a/src/atlas/functionspace/NodeColumnsInterface.h +++ b/src/atlas/functionspace/NodeColumnsInterface.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/functionspace/PointCloud.cc b/src/atlas/functionspace/PointCloud.cc index a2c28e2a6..084f42eef 100644 --- a/src/atlas/functionspace/PointCloud.cc +++ b/src/atlas/functionspace/PointCloud.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/functionspace/PointCloud.h" diff --git a/src/atlas/functionspace/PointCloud.h b/src/atlas/functionspace/PointCloud.h index 680a3f799..33db66c13 100644 --- a/src/atlas/functionspace/PointCloud.h +++ b/src/atlas/functionspace/PointCloud.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index b85879674..2793dfba7 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/parallel/mpi/mpi.h" diff --git a/src/atlas/functionspace/Spectral.h b/src/atlas/functionspace/Spectral.h index 99c4c9aa5..ff945ed56 100644 --- a/src/atlas/functionspace/Spectral.h +++ b/src/atlas/functionspace/Spectral.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 65b98dd7d..8b2cdf296 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/functionspace/StructuredColumns.h b/src/atlas/functionspace/StructuredColumns.h index 87cd11a80..1857d85b8 100644 --- a/src/atlas/functionspace/StructuredColumns.h +++ b/src/atlas/functionspace/StructuredColumns.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid.h b/src/atlas/grid.h index c916132cf..fe471368e 100644 --- a/src/atlas/grid.h +++ b/src/atlas/grid.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/Distribution.cc b/src/atlas/grid/Distribution.cc index 8c7be780e..e3f8cc70d 100644 --- a/src/atlas/grid/Distribution.cc +++ b/src/atlas/grid/Distribution.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/Distribution.h" diff --git a/src/atlas/grid/Distribution.h b/src/atlas/grid/Distribution.h index 546034490..7f79a4d12 100644 --- a/src/atlas/grid/Distribution.h +++ b/src/atlas/grid/Distribution.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/Grid.cc b/src/atlas/grid/Grid.cc index ea9b5cfc1..7dbaaa73a 100644 --- a/src/atlas/grid/Grid.cc +++ b/src/atlas/grid/Grid.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/Grid.h" diff --git a/src/atlas/grid/Grid.h b/src/atlas/grid/Grid.h index 494e4c633..adf383d1b 100644 --- a/src/atlas/grid/Grid.h +++ b/src/atlas/grid/Grid.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/Iterator.h b/src/atlas/grid/Iterator.h index 872571f38..f034feced 100644 --- a/src/atlas/grid/Iterator.h +++ b/src/atlas/grid/Iterator.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/Partitioner.cc b/src/atlas/grid/Partitioner.cc index b2aece935..83c3b7f67 100644 --- a/src/atlas/grid/Partitioner.cc +++ b/src/atlas/grid/Partitioner.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/Partitioner.h" diff --git a/src/atlas/grid/Partitioner.h b/src/atlas/grid/Partitioner.h index 4efedf377..cbac7a6cd 100644 --- a/src/atlas/grid/Partitioner.h +++ b/src/atlas/grid/Partitioner.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/detail/grid/Grid.cc b/src/atlas/grid/detail/grid/Grid.cc index 18ff4f15e..1903335b9 100644 --- a/src/atlas/grid/detail/grid/Grid.cc +++ b/src/atlas/grid/detail/grid/Grid.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "Grid.h" diff --git a/src/atlas/grid/detail/grid/Grid.h b/src/atlas/grid/detail/grid/Grid.h index 80a2e8b25..92e1fb505 100644 --- a/src/atlas/grid/detail/grid/Grid.h +++ b/src/atlas/grid/detail/grid/Grid.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/detail/grid/GridBuilder.cc b/src/atlas/grid/detail/grid/GridBuilder.cc index ece5447b4..957084d84 100644 --- a/src/atlas/grid/detail/grid/GridBuilder.cc +++ b/src/atlas/grid/detail/grid/GridBuilder.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "GridBuilder.h" diff --git a/src/atlas/grid/detail/grid/GridBuilder.h b/src/atlas/grid/detail/grid/GridBuilder.h index 48d979042..1a6677bfa 100644 --- a/src/atlas/grid/detail/grid/GridBuilder.h +++ b/src/atlas/grid/detail/grid/GridBuilder.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index bc7084017..b8080eb49 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "Structured.h" diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index e4578c336..3b78ce15d 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index 33dd368b6..d881c4027 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/detail/grid/Unstructured.h" diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index 3e464122f..8599b90c4 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index 8e9fc55d2..7b1f3a297 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h index ccb42bca1..65dfb7c75 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ // Purpose. diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h index 08cc5027d..67dbcab20 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc index 16e1c2456..064084890 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h" diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h index 0e7b3b40a..700ad8b8e 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc index 1207f4b4b..584945639 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h" diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h index 4fa24dcba..7f0370aa2 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc index 6d2a7ba2e..62360877b 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h" diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h index cbfc9edde..acabc70ae 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/detail/partitioner/Partitioner.cc b/src/atlas/grid/detail/partitioner/Partitioner.cc index 682bc603d..187da635c 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.cc +++ b/src/atlas/grid/detail/partitioner/Partitioner.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/detail/partitioner/Partitioner.h" diff --git a/src/atlas/grid/detail/partitioner/Partitioner.h b/src/atlas/grid/detail/partitioner/Partitioner.h index f088c3d06..16231ee31 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.h +++ b/src/atlas/grid/detail/partitioner/Partitioner.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.h b/src/atlas/grid/detail/partitioner/TransPartitioner.h index 7a6e547b8..1cfcb8b17 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.h +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N.cc b/src/atlas/grid/detail/pl/classic_gaussian/N.cc index 70f986504..6bc286c79 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/N.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/detail/pl/classic_gaussian/N.h b/src/atlas/grid/detail/pl/classic_gaussian/N.h index b0fd0d676..f0bdf2c64 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/N.h +++ b/src/atlas/grid/detail/pl/classic_gaussian/N.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc index 271b3d20b..38cd8c7ff 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc +++ b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h index 79b4f82fe..c3b63516b 100644 --- a/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h +++ b/src/atlas/grid/detail/pl/classic_gaussian/PointsPerLatitude.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc index e1b6ae54d..f153b59fe 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.h b/src/atlas/grid/detail/spacing/gaussian/Latitudes.h index ebc070aca..d4f78a371 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.h +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/detail/spacing/gaussian/N.cc b/src/atlas/grid/detail/spacing/gaussian/N.cc index e4e116f94..e2af7f0f5 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N.cc +++ b/src/atlas/grid/detail/spacing/gaussian/N.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/grid/detail/spacing/gaussian/N.h b/src/atlas/grid/detail/spacing/gaussian/N.h index 9c5a4766d..c797153ec 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N.h +++ b/src/atlas/grid/detail/spacing/gaussian/N.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/interpolation.h b/src/atlas/interpolation.h index ce8e25d7b..12f52f2a9 100644 --- a/src/atlas/interpolation.h +++ b/src/atlas/interpolation.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/Interpolation.cc b/src/atlas/interpolation/Interpolation.cc index 819cb818e..432fbc2af 100644 --- a/src/atlas/interpolation/Interpolation.cc +++ b/src/atlas/interpolation/Interpolation.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/interpolation/Interpolation.h" diff --git a/src/atlas/interpolation/Interpolation.h b/src/atlas/interpolation/Interpolation.h index 19eb5119c..f72d303f0 100644 --- a/src/atlas/interpolation/Interpolation.h +++ b/src/atlas/interpolation/Interpolation.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/Vector2D.h b/src/atlas/interpolation/Vector2D.h index b982146d2..06c698bd2 100644 --- a/src/atlas/interpolation/Vector2D.h +++ b/src/atlas/interpolation/Vector2D.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/Vector3D.h b/src/atlas/interpolation/Vector3D.h index bc3c97dae..556826665 100644 --- a/src/atlas/interpolation/Vector3D.h +++ b/src/atlas/interpolation/Vector3D.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/element/Quad3D.cc b/src/atlas/interpolation/element/Quad3D.cc index 01fd43a77..f1703f034 100644 --- a/src/atlas/interpolation/element/Quad3D.cc +++ b/src/atlas/interpolation/element/Quad3D.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/interpolation/element/Quad3D.h b/src/atlas/interpolation/element/Quad3D.h index f71f2b627..55da76fd7 100644 --- a/src/atlas/interpolation/element/Quad3D.h +++ b/src/atlas/interpolation/element/Quad3D.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef atlas_interpolation_element_Quad3D_h diff --git a/src/atlas/interpolation/element/Triag3D.cc b/src/atlas/interpolation/element/Triag3D.cc index f95ca7979..907ff7aad 100644 --- a/src/atlas/interpolation/element/Triag3D.cc +++ b/src/atlas/interpolation/element/Triag3D.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/interpolation/element/Triag3D.h" diff --git a/src/atlas/interpolation/element/Triag3D.h b/src/atlas/interpolation/element/Triag3D.h index 62b07908d..efae85236 100644 --- a/src/atlas/interpolation/element/Triag3D.h +++ b/src/atlas/interpolation/element/Triag3D.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef atlas_interpolation_element_Triag3D_h diff --git a/src/atlas/interpolation/method/FiniteElement.cc b/src/atlas/interpolation/method/FiniteElement.cc index eb6e039a3..45dc1e55e 100644 --- a/src/atlas/interpolation/method/FiniteElement.cc +++ b/src/atlas/interpolation/method/FiniteElement.cc @@ -5,8 +5,7 @@ * 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. and Interpolation + * nor does it submit to any jurisdiction. and Interpolation */ #include diff --git a/src/atlas/interpolation/method/FiniteElement.h b/src/atlas/interpolation/method/FiniteElement.h index 12df8aae0..2bdea35ab 100644 --- a/src/atlas/interpolation/method/FiniteElement.h +++ b/src/atlas/interpolation/method/FiniteElement.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/method/Intersect.cc b/src/atlas/interpolation/method/Intersect.cc index 6ed40cf66..44fe03dfd 100644 --- a/src/atlas/interpolation/method/Intersect.cc +++ b/src/atlas/interpolation/method/Intersect.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/interpolation/method/Intersect.h" diff --git a/src/atlas/interpolation/method/Intersect.h b/src/atlas/interpolation/method/Intersect.h index 8d8e42824..c89309957 100644 --- a/src/atlas/interpolation/method/Intersect.h +++ b/src/atlas/interpolation/method/Intersect.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef atlas_interpolation_method_Intersect_h diff --git a/src/atlas/interpolation/method/KNearestNeighbours.cc b/src/atlas/interpolation/method/KNearestNeighbours.cc index 417e571ed..b6cf0e3f0 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.cc +++ b/src/atlas/interpolation/method/KNearestNeighbours.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/interpolation/method/KNearestNeighbours.h" diff --git a/src/atlas/interpolation/method/KNearestNeighbours.h b/src/atlas/interpolation/method/KNearestNeighbours.h index 6b3e39071..9f412512e 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.h +++ b/src/atlas/interpolation/method/KNearestNeighbours.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.cc b/src/atlas/interpolation/method/KNearestNeighboursBase.cc index 3cf19b166..0572bb0a7 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.cc +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.cc @@ -5,8 +5,7 @@ * 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. and Interpolation + * nor does it submit to any jurisdiction. and Interpolation */ #include "atlas/interpolation/method/KNearestNeighboursBase.h" diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.h b/src/atlas/interpolation/method/KNearestNeighboursBase.h index b46f8324c..c7059c50e 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.h +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index 8178434a8..49330f6c7 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/interpolation/method/Method.h" diff --git a/src/atlas/interpolation/method/Method.h b/src/atlas/interpolation/method/Method.h index b4e2a8e26..5afed2b01 100644 --- a/src/atlas/interpolation/method/Method.h +++ b/src/atlas/interpolation/method/Method.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/method/NearestNeighbour.cc b/src/atlas/interpolation/method/NearestNeighbour.cc index ccbfc64d8..de59e2a33 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.cc +++ b/src/atlas/interpolation/method/NearestNeighbour.cc @@ -5,8 +5,7 @@ * 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. and Interpolation + * nor does it submit to any jurisdiction. and Interpolation */ #include "atlas/interpolation/method/NearestNeighbour.h" diff --git a/src/atlas/interpolation/method/NearestNeighbour.h b/src/atlas/interpolation/method/NearestNeighbour.h index 38de47c20..9b311c499 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.h +++ b/src/atlas/interpolation/method/NearestNeighbour.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/method/PointIndex3.cc b/src/atlas/interpolation/method/PointIndex3.cc index 93acff3af..fab43cd4c 100644 --- a/src/atlas/interpolation/method/PointIndex3.cc +++ b/src/atlas/interpolation/method/PointIndex3.cc @@ -6,8 +6,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/interpolation/method/PointIndex3.h" diff --git a/src/atlas/interpolation/method/PointIndex3.h b/src/atlas/interpolation/method/PointIndex3.h index c3eb1cb11..096e87c03 100644 --- a/src/atlas/interpolation/method/PointIndex3.h +++ b/src/atlas/interpolation/method/PointIndex3.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/method/PointSet.cc b/src/atlas/interpolation/method/PointSet.cc index fa0533d66..9a767ddba 100644 --- a/src/atlas/interpolation/method/PointSet.cc +++ b/src/atlas/interpolation/method/PointSet.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/interpolation/method/PointSet.h" diff --git a/src/atlas/interpolation/method/PointSet.h b/src/atlas/interpolation/method/PointSet.h index aa2814053..a12a1992b 100644 --- a/src/atlas/interpolation/method/PointSet.h +++ b/src/atlas/interpolation/method/PointSet.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/interpolation/method/Ray.cc b/src/atlas/interpolation/method/Ray.cc index 14dcf3e5e..6450dd7e2 100644 --- a/src/atlas/interpolation/method/Ray.cc +++ b/src/atlas/interpolation/method/Ray.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/interpolation/method/Ray.h b/src/atlas/interpolation/method/Ray.h index 8ed774cd8..7fb59c2c5 100644 --- a/src/atlas/interpolation/method/Ray.h +++ b/src/atlas/interpolation/method/Ray.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 4467f69ef..721fe2f25 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/library/config.h" diff --git a/src/atlas/library/Library.h b/src/atlas/library/Library.h index 53998860c..d95369df6 100644 --- a/src/atlas/library/Library.h +++ b/src/atlas/library/Library.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh.h b/src/atlas/mesh.h index 1c706f083..e413f91c7 100644 --- a/src/atlas/mesh.h +++ b/src/atlas/mesh.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index 70bed2881..e28b6afb9 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/Connectivity.h" diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 736a33e6c..0e3a8fe49 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file Connectivity.h diff --git a/src/atlas/mesh/ElementType.cc b/src/atlas/mesh/ElementType.cc index 22292ac85..d4ea081e7 100644 --- a/src/atlas/mesh/ElementType.cc +++ b/src/atlas/mesh/ElementType.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/ElementType.h" diff --git a/src/atlas/mesh/ElementType.h b/src/atlas/mesh/ElementType.h index fec95f10a..c4bc151bb 100644 --- a/src/atlas/mesh/ElementType.h +++ b/src/atlas/mesh/ElementType.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/mesh/Elements.cc b/src/atlas/mesh/Elements.cc index 1b45018f7..27e1da0fd 100644 --- a/src/atlas/mesh/Elements.cc +++ b/src/atlas/mesh/Elements.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/Elements.h" diff --git a/src/atlas/mesh/Elements.h b/src/atlas/mesh/Elements.h index aa4d53309..8c7fd9328 100644 --- a/src/atlas/mesh/Elements.h +++ b/src/atlas/mesh/Elements.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file Elements.h diff --git a/src/atlas/mesh/Halo.cc b/src/atlas/mesh/Halo.cc index a2a9d86aa..20a81a8f4 100644 --- a/src/atlas/mesh/Halo.cc +++ b/src/atlas/mesh/Halo.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/Halo.h" diff --git a/src/atlas/mesh/Halo.h b/src/atlas/mesh/Halo.h index 0bba40af4..af523a7da 100644 --- a/src/atlas/mesh/Halo.h +++ b/src/atlas/mesh/Halo.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/HybridElements.cc b/src/atlas/mesh/HybridElements.cc index 34fbefd4f..8b657d101 100644 --- a/src/atlas/mesh/HybridElements.cc +++ b/src/atlas/mesh/HybridElements.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/HybridElements.h" diff --git a/src/atlas/mesh/HybridElements.h b/src/atlas/mesh/HybridElements.h index 7b4f91af0..e95fb55da 100644 --- a/src/atlas/mesh/HybridElements.h +++ b/src/atlas/mesh/HybridElements.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @file HybridElements.h diff --git a/src/atlas/mesh/IsGhostNode.h b/src/atlas/mesh/IsGhostNode.h index 2520e0003..874564709 100644 --- a/src/atlas/mesh/IsGhostNode.h +++ b/src/atlas/mesh/IsGhostNode.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/Mesh.cc b/src/atlas/mesh/Mesh.cc index ba7394c1b..46b154770 100644 --- a/src/atlas/mesh/Mesh.cc +++ b/src/atlas/mesh/Mesh.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/Mesh.h" diff --git a/src/atlas/mesh/Mesh.h b/src/atlas/mesh/Mesh.h index d47038073..9893f8fc0 100644 --- a/src/atlas/mesh/Mesh.h +++ b/src/atlas/mesh/Mesh.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/Nodes.cc b/src/atlas/mesh/Nodes.cc index de4d67dea..2e167868e 100644 --- a/src/atlas/mesh/Nodes.cc +++ b/src/atlas/mesh/Nodes.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/Nodes.h" diff --git a/src/atlas/mesh/Nodes.h b/src/atlas/mesh/Nodes.h index 4bfe2daa9..eee942230 100644 --- a/src/atlas/mesh/Nodes.h +++ b/src/atlas/mesh/Nodes.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/mesh/PartitionPolygon.cc b/src/atlas/mesh/PartitionPolygon.cc index c1ad79973..e08d9b7d5 100644 --- a/src/atlas/mesh/PartitionPolygon.cc +++ b/src/atlas/mesh/PartitionPolygon.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/PartitionPolygon.h" diff --git a/src/atlas/mesh/PartitionPolygon.h b/src/atlas/mesh/PartitionPolygon.h index 0fd15d58e..e77f07449 100644 --- a/src/atlas/mesh/PartitionPolygon.h +++ b/src/atlas/mesh/PartitionPolygon.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Pedro Maciel diff --git a/src/atlas/mesh/actions/BuildCellCentres.cc b/src/atlas/mesh/actions/BuildCellCentres.cc index 10c64eaf1..a8de1e5db 100644 --- a/src/atlas/mesh/actions/BuildCellCentres.cc +++ b/src/atlas/mesh/actions/BuildCellCentres.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/actions/BuildCellCentres.h" diff --git a/src/atlas/mesh/actions/BuildCellCentres.h b/src/atlas/mesh/actions/BuildCellCentres.h index 66ec52964..0df60152b 100644 --- a/src/atlas/mesh/actions/BuildCellCentres.h +++ b/src/atlas/mesh/actions/BuildCellCentres.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.cc b/src/atlas/mesh/actions/BuildConvexHull3D.cc index 433785037..c90745504 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.cc +++ b/src/atlas/mesh/actions/BuildConvexHull3D.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.h b/src/atlas/mesh/actions/BuildConvexHull3D.h index cbeb456f0..a66543ec2 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.h +++ b/src/atlas/mesh/actions/BuildConvexHull3D.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef atlas_actions_BuildConvexHull3D_h diff --git a/src/atlas/mesh/actions/BuildDualMesh.cc b/src/atlas/mesh/actions/BuildDualMesh.cc index c5b111c19..52ed5edb3 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.cc +++ b/src/atlas/mesh/actions/BuildDualMesh.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/mesh/actions/BuildDualMesh.h b/src/atlas/mesh/actions/BuildDualMesh.h index 1e5fbbdca..55ba62098 100644 --- a/src/atlas/mesh/actions/BuildDualMesh.h +++ b/src/atlas/mesh/actions/BuildDualMesh.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/actions/BuildEdges.cc b/src/atlas/mesh/actions/BuildEdges.cc index f299551bf..e4ea06ddc 100644 --- a/src/atlas/mesh/actions/BuildEdges.cc +++ b/src/atlas/mesh/actions/BuildEdges.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/actions/BuildEdges.h" diff --git a/src/atlas/mesh/actions/BuildEdges.h b/src/atlas/mesh/actions/BuildEdges.h index 22433363a..d2dcab7a1 100644 --- a/src/atlas/mesh/actions/BuildEdges.h +++ b/src/atlas/mesh/actions/BuildEdges.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/actions/BuildHalo.cc b/src/atlas/mesh/actions/BuildHalo.cc index 3f0fba3d9..776901bad 100644 --- a/src/atlas/mesh/actions/BuildHalo.cc +++ b/src/atlas/mesh/actions/BuildHalo.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/mesh/actions/BuildHalo.h b/src/atlas/mesh/actions/BuildHalo.h index 92fd1afe7..df3608bc3 100644 --- a/src/atlas/mesh/actions/BuildHalo.h +++ b/src/atlas/mesh/actions/BuildHalo.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef BuildHalo_h diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 677c1c414..12d06108d 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/actions/BuildParallelFields.h" diff --git a/src/atlas/mesh/actions/BuildParallelFields.h b/src/atlas/mesh/actions/BuildParallelFields.h index b9b440f6a..1b7774a7a 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.h +++ b/src/atlas/mesh/actions/BuildParallelFields.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc b/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc index 1c6bb4e6b..90ac6811a 100644 --- a/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc +++ b/src/atlas/mesh/actions/BuildPeriodicBoundaries.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/mesh/actions/BuildPeriodicBoundaries.h b/src/atlas/mesh/actions/BuildPeriodicBoundaries.h index 5fd69dd61..baaaa3459 100644 --- a/src/atlas/mesh/actions/BuildPeriodicBoundaries.h +++ b/src/atlas/mesh/actions/BuildPeriodicBoundaries.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef BuildPeriodicBoundaries_h diff --git a/src/atlas/mesh/actions/BuildStatistics.cc b/src/atlas/mesh/actions/BuildStatistics.cc index 2a2cfa0e1..ca72ec7c4 100644 --- a/src/atlas/mesh/actions/BuildStatistics.cc +++ b/src/atlas/mesh/actions/BuildStatistics.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/mesh/actions/BuildStatistics.h b/src/atlas/mesh/actions/BuildStatistics.h index 1899e5969..1f450d49b 100644 --- a/src/atlas/mesh/actions/BuildStatistics.h +++ b/src/atlas/mesh/actions/BuildStatistics.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef BuildStatistics_h diff --git a/src/atlas/mesh/actions/BuildTorusXYZField.cc b/src/atlas/mesh/actions/BuildTorusXYZField.cc index 7db5891b9..3c2a042a7 100644 --- a/src/atlas/mesh/actions/BuildTorusXYZField.cc +++ b/src/atlas/mesh/actions/BuildTorusXYZField.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/mesh/actions/BuildTorusXYZField.h b/src/atlas/mesh/actions/BuildTorusXYZField.h index c18ca8184..5fed6ee96 100644 --- a/src/atlas/mesh/actions/BuildTorusXYZField.h +++ b/src/atlas/mesh/actions/BuildTorusXYZField.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef atlas_actions_BuildTorusXYZField_h diff --git a/src/atlas/mesh/actions/BuildXYZField.cc b/src/atlas/mesh/actions/BuildXYZField.cc index 05a3a15f3..725f852d6 100644 --- a/src/atlas/mesh/actions/BuildXYZField.cc +++ b/src/atlas/mesh/actions/BuildXYZField.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/actions/BuildXYZField.h" diff --git a/src/atlas/mesh/actions/BuildXYZField.h b/src/atlas/mesh/actions/BuildXYZField.h index 2a5999872..35db5411e 100644 --- a/src/atlas/mesh/actions/BuildXYZField.h +++ b/src/atlas/mesh/actions/BuildXYZField.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.cc b/src/atlas/mesh/actions/ExtendNodesGlobal.cc index 1a24c05b8..95be58893 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.cc +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/actions/ExtendNodesGlobal.h" diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.h b/src/atlas/mesh/actions/ExtendNodesGlobal.h index 3a912f95d..63452b358 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.h +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc index 05e1e5f18..a20d51d12 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.h b/src/atlas/mesh/actions/WriteLoadBalanceReport.h index eaea20a07..80cfa5ab2 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.h +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef atlas_WriteLoadBalanceReport_h diff --git a/src/atlas/mesh/detail/AccumulateFacets.cc b/src/atlas/mesh/detail/AccumulateFacets.cc index 6519fe1f2..ca6b2bbdc 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.cc +++ b/src/atlas/mesh/detail/AccumulateFacets.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/detail/AccumulateFacets.h" diff --git a/src/atlas/mesh/detail/AccumulateFacets.h b/src/atlas/mesh/detail/AccumulateFacets.h index 3e94591c6..02910b602 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.h +++ b/src/atlas/mesh/detail/AccumulateFacets.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/detail/MeshImpl.cc b/src/atlas/mesh/detail/MeshImpl.cc index 775a25f67..3b15d1090 100644 --- a/src/atlas/mesh/detail/MeshImpl.cc +++ b/src/atlas/mesh/detail/MeshImpl.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/detail/MeshImpl.h" diff --git a/src/atlas/mesh/detail/MeshImpl.h b/src/atlas/mesh/detail/MeshImpl.h index 11ffa0084..b395a145c 100644 --- a/src/atlas/mesh/detail/MeshImpl.h +++ b/src/atlas/mesh/detail/MeshImpl.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/detail/MeshIntf.cc b/src/atlas/mesh/detail/MeshIntf.cc index 268f11de5..abc47fac8 100644 --- a/src/atlas/mesh/detail/MeshIntf.cc +++ b/src/atlas/mesh/detail/MeshIntf.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/detail/MeshIntf.h" diff --git a/src/atlas/mesh/detail/MeshIntf.h b/src/atlas/mesh/detail/MeshIntf.h index 71b6cd0ff..25dd87d66 100644 --- a/src/atlas/mesh/detail/MeshIntf.h +++ b/src/atlas/mesh/detail/MeshIntf.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/detail/PartitionGraph.cc b/src/atlas/mesh/detail/PartitionGraph.cc index 182413fa9..8a098e943 100644 --- a/src/atlas/mesh/detail/PartitionGraph.cc +++ b/src/atlas/mesh/detail/PartitionGraph.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/mesh/detail/PartitionGraph.h b/src/atlas/mesh/detail/PartitionGraph.h index 99dcf3257..61d4122c8 100644 --- a/src/atlas/mesh/detail/PartitionGraph.h +++ b/src/atlas/mesh/detail/PartitionGraph.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/mesh/detail/PeriodicTransform.h b/src/atlas/mesh/detail/PeriodicTransform.h index cb5b74012..7b84d35a4 100644 --- a/src/atlas/mesh/detail/PeriodicTransform.h +++ b/src/atlas/mesh/detail/PeriodicTransform.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/meshgenerator.h b/src/atlas/meshgenerator.h index ab9aeb76c..d1eed4bf2 100644 --- a/src/atlas/meshgenerator.h +++ b/src/atlas/meshgenerator.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/meshgenerator/DelaunayMeshGenerator.cc b/src/atlas/meshgenerator/DelaunayMeshGenerator.cc index 3209c62ee..055d2072d 100644 --- a/src/atlas/meshgenerator/DelaunayMeshGenerator.cc +++ b/src/atlas/meshgenerator/DelaunayMeshGenerator.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/meshgenerator/DelaunayMeshGenerator.h" diff --git a/src/atlas/meshgenerator/DelaunayMeshGenerator.h b/src/atlas/meshgenerator/DelaunayMeshGenerator.h index 420355f22..55fc6c265 100644 --- a/src/atlas/meshgenerator/DelaunayMeshGenerator.h +++ b/src/atlas/meshgenerator/DelaunayMeshGenerator.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/meshgenerator/MeshGenerator.cc b/src/atlas/meshgenerator/MeshGenerator.cc index 7ac6a445c..5be773322 100644 --- a/src/atlas/meshgenerator/MeshGenerator.cc +++ b/src/atlas/meshgenerator/MeshGenerator.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/meshgenerator/MeshGenerator.h b/src/atlas/meshgenerator/MeshGenerator.h index 3c0f26dbe..25cefb207 100644 --- a/src/atlas/meshgenerator/MeshGenerator.h +++ b/src/atlas/meshgenerator/MeshGenerator.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index f052bc8f8..f5e01ebff 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.h b/src/atlas/meshgenerator/StructuredMeshGenerator.h index 1fb3479f0..928eabf05 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.h +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/numerics/Method.cc b/src/atlas/numerics/Method.cc index 2dc5d46f5..0588c54df 100644 --- a/src/atlas/numerics/Method.cc +++ b/src/atlas/numerics/Method.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/numerics/Method.h" diff --git a/src/atlas/numerics/Method.h b/src/atlas/numerics/Method.h index 210b7158f..c131e4ece 100644 --- a/src/atlas/numerics/Method.h +++ b/src/atlas/numerics/Method.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/numerics/Nabla.cc b/src/atlas/numerics/Nabla.cc index d896ccf30..6c949e391 100644 --- a/src/atlas/numerics/Nabla.cc +++ b/src/atlas/numerics/Nabla.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/numerics/Nabla.h" diff --git a/src/atlas/numerics/Nabla.h b/src/atlas/numerics/Nabla.h index 05971d53b..9674e906d 100644 --- a/src/atlas/numerics/Nabla.h +++ b/src/atlas/numerics/Nabla.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/numerics/fvm/Method.cc b/src/atlas/numerics/fvm/Method.cc index f6f2f2d54..d34b97a3a 100644 --- a/src/atlas/numerics/fvm/Method.cc +++ b/src/atlas/numerics/fvm/Method.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/numerics/fvm/Method.h" diff --git a/src/atlas/numerics/fvm/Method.h b/src/atlas/numerics/fvm/Method.h index 67873321a..62e25103a 100644 --- a/src/atlas/numerics/fvm/Method.h +++ b/src/atlas/numerics/fvm/Method.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/numerics/fvm/Nabla.cc b/src/atlas/numerics/fvm/Nabla.cc index ef8d78a92..7c28ff422 100644 --- a/src/atlas/numerics/fvm/Nabla.cc +++ b/src/atlas/numerics/fvm/Nabla.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/numerics/fvm/Nabla.h" diff --git a/src/atlas/numerics/fvm/Nabla.h b/src/atlas/numerics/fvm/Nabla.h index 3cea90661..1ad371145 100644 --- a/src/atlas/numerics/fvm/Nabla.h +++ b/src/atlas/numerics/fvm/Nabla.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/option.h b/src/atlas/option.h index d17ae05ca..9ae239deb 100644 --- a/src/atlas/option.h +++ b/src/atlas/option.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/option/Options.cc b/src/atlas/option/Options.cc index 0183c32ea..20f50239c 100644 --- a/src/atlas/option/Options.cc +++ b/src/atlas/option/Options.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/option/Options.h" diff --git a/src/atlas/option/Options.h b/src/atlas/option/Options.h index d9537eb00..10239c357 100644 --- a/src/atlas/option/Options.h +++ b/src/atlas/option/Options.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/option/TransOptions.cc b/src/atlas/option/TransOptions.cc index 3fec20074..0f00dcd0f 100644 --- a/src/atlas/option/TransOptions.cc +++ b/src/atlas/option/TransOptions.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/option/TransOptions.h" diff --git a/src/atlas/option/TransOptions.h b/src/atlas/option/TransOptions.h index 0aa990cd6..3e548eb2c 100644 --- a/src/atlas/option/TransOptions.h +++ b/src/atlas/option/TransOptions.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/output/Gmsh.cc b/src/atlas/output/Gmsh.cc index bdc6d97c5..b99d23d31 100644 --- a/src/atlas/output/Gmsh.cc +++ b/src/atlas/output/Gmsh.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/output/Gmsh.h b/src/atlas/output/Gmsh.h index 899dc3e11..989460551 100644 --- a/src/atlas/output/Gmsh.h +++ b/src/atlas/output/Gmsh.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/output/Output.cc b/src/atlas/output/Output.cc index 823d25e38..dcd0dea23 100644 --- a/src/atlas/output/Output.cc +++ b/src/atlas/output/Output.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/output/Output.h b/src/atlas/output/Output.h index 85919a6a3..1ec2ebdc3 100644 --- a/src/atlas/output/Output.h +++ b/src/atlas/output/Output.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index 967d8a412..77ab3e2f8 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/output/detail/GmshIO.h" diff --git a/src/atlas/output/detail/GmshIO.h b/src/atlas/output/detail/GmshIO.h index 6e414bd01..5396ae2b8 100644 --- a/src/atlas/output/detail/GmshIO.h +++ b/src/atlas/output/detail/GmshIO.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/output/detail/PointCloudIO.cc b/src/atlas/output/detail/PointCloudIO.cc index 9603f910e..8aeb4bf9b 100644 --- a/src/atlas/output/detail/PointCloudIO.cc +++ b/src/atlas/output/detail/PointCloudIO.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/output/detail/PointCloudIO.h" diff --git a/src/atlas/output/detail/PointCloudIO.h b/src/atlas/output/detail/PointCloudIO.h index 20d8d54d0..3c3e4e309 100644 --- a/src/atlas/output/detail/PointCloudIO.h +++ b/src/atlas/output/detail/PointCloudIO.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/parallel/Checksum.cc b/src/atlas/parallel/Checksum.cc index b005a4880..bb0db51d0 100644 --- a/src/atlas/parallel/Checksum.cc +++ b/src/atlas/parallel/Checksum.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/parallel/Checksum.h" diff --git a/src/atlas/parallel/Checksum.h b/src/atlas/parallel/Checksum.h index 637ba537d..1446236a5 100644 --- a/src/atlas/parallel/Checksum.h +++ b/src/atlas/parallel/Checksum.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef Checksum_h diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index 0a8fa7205..2c5649da2 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/parallel/GatherScatter.h" diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index b9528a2e6..006b1d652 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef Gather_h diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index c220cb744..039506da3 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index dacffa929..6eb87f8dd 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index 6c12fafc9..b606bb8ac 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -7,8 +7,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/ArrayView.h" #include "atlas/array/ArrayViewDefs.h" diff --git a/src/atlas/parallel/HaloExchangeImpl.h b/src/atlas/parallel/HaloExchangeImpl.h index 3fec5c3a2..94c2b7d45 100644 --- a/src/atlas/parallel/HaloExchangeImpl.h +++ b/src/atlas/parallel/HaloExchangeImpl.h @@ -7,8 +7,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/ArrayView.h" #include "atlas/array/SVector.h" diff --git a/src/atlas/parallel/mpi/Buffer.h b/src/atlas/parallel/mpi/Buffer.h index d5ba9ce8d..2e12f4bad 100644 --- a/src/atlas/parallel/mpi/Buffer.h +++ b/src/atlas/parallel/mpi/Buffer.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index aefc2e30f..349230ff9 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/parallel/mpi/mpi.cc b/src/atlas/parallel/mpi/mpi.cc index 78d44b180..f6fd37f1d 100644 --- a/src/atlas/parallel/mpi/mpi.cc +++ b/src/atlas/parallel/mpi/mpi.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/parallel/mpi/mpi.h" diff --git a/src/atlas/parallel/mpi/mpi.h b/src/atlas/parallel/mpi/mpi.h index abc10c4ea..e1d5cd174 100644 --- a/src/atlas/parallel/mpi/mpi.h +++ b/src/atlas/parallel/mpi/mpi.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/parallel/omp/omp.cc b/src/atlas/parallel/omp/omp.cc index 7e946f052..01f3ecc1d 100644 --- a/src/atlas/parallel/omp/omp.cc +++ b/src/atlas/parallel/omp/omp.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/parallel/omp/omp.h" diff --git a/src/atlas/parallel/omp/omp.h b/src/atlas/parallel/omp/omp.h index 1785aea70..f4843d6c6 100644 --- a/src/atlas/parallel/omp/omp.h +++ b/src/atlas/parallel/omp/omp.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/projection.h b/src/atlas/projection.h index 018b92ece..a9ff7db30 100644 --- a/src/atlas/projection.h +++ b/src/atlas/projection.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/runtime/AtlasTool.h b/src/atlas/runtime/AtlasTool.h index be7d5bdd1..97398956c 100644 --- a/src/atlas/runtime/AtlasTool.h +++ b/src/atlas/runtime/AtlasTool.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/runtime/Log.cc b/src/atlas/runtime/Log.cc index ed39f363a..8fdf27c58 100644 --- a/src/atlas/runtime/Log.cc +++ b/src/atlas/runtime/Log.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/runtime/Log.h" diff --git a/src/atlas/runtime/Trace.h b/src/atlas/runtime/Trace.h index ce3773038..cc86528b0 100644 --- a/src/atlas/runtime/Trace.h +++ b/src/atlas/runtime/Trace.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/runtime/trace/Barriers.cc b/src/atlas/runtime/trace/Barriers.cc index fafe90a9b..8f791f1b0 100644 --- a/src/atlas/runtime/trace/Barriers.cc +++ b/src/atlas/runtime/trace/Barriers.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "Barriers.h" diff --git a/src/atlas/runtime/trace/Barriers.h b/src/atlas/runtime/trace/Barriers.h index 475a4f63c..6863c6418 100644 --- a/src/atlas/runtime/trace/Barriers.h +++ b/src/atlas/runtime/trace/Barriers.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/runtime/trace/Logging.cc b/src/atlas/runtime/trace/Logging.cc index 22c96aa71..2991b8bca 100644 --- a/src/atlas/runtime/trace/Logging.cc +++ b/src/atlas/runtime/trace/Logging.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "Logging.h" diff --git a/src/atlas/runtime/trace/Logging.h b/src/atlas/runtime/trace/Logging.h index ab0bd07a7..632239ae3 100644 --- a/src/atlas/runtime/trace/Logging.h +++ b/src/atlas/runtime/trace/Logging.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/runtime/trace/Nesting.cc b/src/atlas/runtime/trace/Nesting.cc index 67c8b2077..b34f98513 100644 --- a/src/atlas/runtime/trace/Nesting.cc +++ b/src/atlas/runtime/trace/Nesting.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "Nesting.h" diff --git a/src/atlas/runtime/trace/Nesting.h b/src/atlas/runtime/trace/Nesting.h index 86ef5fafe..7070662dd 100644 --- a/src/atlas/runtime/trace/Nesting.h +++ b/src/atlas/runtime/trace/Nesting.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/runtime/trace/StopWatch.h b/src/atlas/runtime/trace/StopWatch.h index 67bcf0924..048c39b76 100644 --- a/src/atlas/runtime/trace/StopWatch.h +++ b/src/atlas/runtime/trace/StopWatch.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/runtime/trace/Timings.cc b/src/atlas/runtime/trace/Timings.cc index cdbd8a9ed..5f77cc095 100644 --- a/src/atlas/runtime/trace/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/atlas/runtime/trace/Timings.h b/src/atlas/runtime/trace/Timings.h index f2a8da3d6..2297c5472 100644 --- a/src/atlas/runtime/trace/Timings.h +++ b/src/atlas/runtime/trace/Timings.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/runtime/trace/TraceT.h b/src/atlas/runtime/trace/TraceT.h index 2fe0c9a80..f05edfb85 100644 --- a/src/atlas/runtime/trace/TraceT.h +++ b/src/atlas/runtime/trace/TraceT.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index dd24ca687..14992ecc4 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "eckit/exception/Exceptions.h" diff --git a/src/atlas/trans/Trans.h b/src/atlas/trans/Trans.h index 50753d950..225506a7d 100644 --- a/src/atlas/trans/Trans.h +++ b/src/atlas/trans/Trans.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/VorDivToUV.cc b/src/atlas/trans/VorDivToUV.cc index 8875afc03..b51d7a405 100644 --- a/src/atlas/trans/VorDivToUV.cc +++ b/src/atlas/trans/VorDivToUV.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "eckit/exception/Exceptions.h" diff --git a/src/atlas/trans/VorDivToUV.h b/src/atlas/trans/VorDivToUV.h index 88a1c198a..9bfddbb0b 100644 --- a/src/atlas/trans/VorDivToUV.h +++ b/src/atlas/trans/VorDivToUV.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index aae98839e..f67013b5b 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/trans/ifs/TransIFS.h" diff --git a/src/atlas/trans/ifs/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h index aeb9f37e6..da91a425a 100644 --- a/src/atlas/trans/ifs/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/ifs/TransIFSNodeColumns.cc b/src/atlas/trans/ifs/TransIFSNodeColumns.cc index 447270ff6..fd7835f5d 100644 --- a/src/atlas/trans/ifs/TransIFSNodeColumns.cc +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/trans/ifs/TransIFSNodeColumns.h" diff --git a/src/atlas/trans/ifs/TransIFSNodeColumns.h b/src/atlas/trans/ifs/TransIFSNodeColumns.h index e0f69f1ee..3938f92e0 100644 --- a/src/atlas/trans/ifs/TransIFSNodeColumns.h +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc index adde45c53..e29f4bcb1 100644 --- a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/trans/ifs/TransIFSStructuredColumns.h" diff --git a/src/atlas/trans/ifs/TransIFSStructuredColumns.h b/src/atlas/trans/ifs/TransIFSStructuredColumns.h index a43cdce52..cb198a831 100644 --- a/src/atlas/trans/ifs/TransIFSStructuredColumns.h +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/ifs/VorDivToUVIFS.cc b/src/atlas/trans/ifs/VorDivToUVIFS.cc index c8c7f5164..24d084b80 100644 --- a/src/atlas/trans/ifs/VorDivToUVIFS.cc +++ b/src/atlas/trans/ifs/VorDivToUVIFS.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/trans/ifs/VorDivToUVIFS.h" diff --git a/src/atlas/trans/ifs/VorDivToUVIFS.h b/src/atlas/trans/ifs/VorDivToUVIFS.h index 7c50df964..613a9a2fa 100644 --- a/src/atlas/trans/ifs/VorDivToUVIFS.h +++ b/src/atlas/trans/ifs/VorDivToUVIFS.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc index 015f51a1e..8611a8cff 100644 --- a/src/atlas/trans/local/FourierTransforms.cc +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/trans/local/FourierTransforms.h" diff --git a/src/atlas/trans/local/FourierTransforms.h b/src/atlas/trans/local/FourierTransforms.h index 44f5a186e..a3e4451df 100644 --- a/src/atlas/trans/local/FourierTransforms.h +++ b/src/atlas/trans/local/FourierTransforms.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index cae466ea5..ae1866706 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/trans/local/LegendrePolynomials.h" diff --git a/src/atlas/trans/local/LegendrePolynomials.h b/src/atlas/trans/local/LegendrePolynomials.h index ee81838ee..5407b48cb 100644 --- a/src/atlas/trans/local/LegendrePolynomials.h +++ b/src/atlas/trans/local/LegendrePolynomials.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/local/LegendreTransforms.cc b/src/atlas/trans/local/LegendreTransforms.cc index 06140f274..9db0af26e 100644 --- a/src/atlas/trans/local/LegendreTransforms.cc +++ b/src/atlas/trans/local/LegendreTransforms.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/trans/local/LegendreTransforms.h" diff --git a/src/atlas/trans/local/LegendreTransforms.h b/src/atlas/trans/local/LegendreTransforms.h index e76cbaab2..85a94dd13 100644 --- a/src/atlas/trans/local/LegendreTransforms.h +++ b/src/atlas/trans/local/LegendreTransforms.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index 0f534831e..d4b7f3cb7 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/trans/local/TransLocal.h" diff --git a/src/atlas/trans/local/TransLocal.h b/src/atlas/trans/local/TransLocal.h index 41a3d51a8..4ecedf6e5 100644 --- a/src/atlas/trans/local/TransLocal.h +++ b/src/atlas/trans/local/TransLocal.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index 4d60dfd2e..3cba7e2d0 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/trans/local/VorDivToUVLocal.h" diff --git a/src/atlas/trans/local/VorDivToUVLocal.h b/src/atlas/trans/local/VorDivToUVLocal.h index d827d28a1..ee3903de1 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.h +++ b/src/atlas/trans/local/VorDivToUVLocal.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/Bitflags.h b/src/atlas/util/Bitflags.h index d48e0f36c..4812fee6c 100644 --- a/src/atlas/util/Bitflags.h +++ b/src/atlas/util/Bitflags.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/Config.cc b/src/atlas/util/Config.cc index 67424cc39..156a2233f 100644 --- a/src/atlas/util/Config.cc +++ b/src/atlas/util/Config.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/util/Config.h" diff --git a/src/atlas/util/Config.h b/src/atlas/util/Config.h index 0cb3466d6..ad4120496 100644 --- a/src/atlas/util/Config.h +++ b/src/atlas/util/Config.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #ifndef atlas_Config_h diff --git a/src/atlas/util/Constants.h b/src/atlas/util/Constants.h index 92ed3fe03..b3edb055c 100644 --- a/src/atlas/util/Constants.h +++ b/src/atlas/util/Constants.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/CoordinateEnums.h b/src/atlas/util/CoordinateEnums.h index 9cff0d23e..b182a2082 100644 --- a/src/atlas/util/CoordinateEnums.h +++ b/src/atlas/util/CoordinateEnums.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index 998241f93..0c3256986 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/util/Earth.h" diff --git a/src/atlas/util/Earth.h b/src/atlas/util/Earth.h index f934395dc..60452d965 100644 --- a/src/atlas/util/Earth.h +++ b/src/atlas/util/Earth.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/GaussianLatitudes.cc b/src/atlas/util/GaussianLatitudes.cc index a1ae367f0..3c63f9faa 100644 --- a/src/atlas/util/GaussianLatitudes.cc +++ b/src/atlas/util/GaussianLatitudes.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/util/GaussianLatitudes.h b/src/atlas/util/GaussianLatitudes.h index 04c2ffd67..ef5607f10 100644 --- a/src/atlas/util/GaussianLatitudes.h +++ b/src/atlas/util/GaussianLatitudes.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Willem Deconinck diff --git a/src/atlas/util/LonLatMicroDeg.h b/src/atlas/util/LonLatMicroDeg.h index 8889791cf..a9d689349 100644 --- a/src/atlas/util/LonLatMicroDeg.h +++ b/src/atlas/util/LonLatMicroDeg.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/LonLatPolygon.cc b/src/atlas/util/LonLatPolygon.cc index 9c4a00479..2dc5e4c31 100644 --- a/src/atlas/util/LonLatPolygon.cc +++ b/src/atlas/util/LonLatPolygon.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/util/LonLatPolygon.h" diff --git a/src/atlas/util/LonLatPolygon.h b/src/atlas/util/LonLatPolygon.h index 265347eda..0478c5c9f 100644 --- a/src/atlas/util/LonLatPolygon.h +++ b/src/atlas/util/LonLatPolygon.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index a8b2daabb..356b3ddf3 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/util/Metadata.h" diff --git a/src/atlas/util/Metadata.h b/src/atlas/util/Metadata.h index 49993b90f..a7257833c 100644 --- a/src/atlas/util/Metadata.h +++ b/src/atlas/util/Metadata.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/MicroDeg.h b/src/atlas/util/MicroDeg.h index e8c51cc24..f5cb1c91c 100644 --- a/src/atlas/util/MicroDeg.h +++ b/src/atlas/util/MicroDeg.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/Polygon.cc b/src/atlas/util/Polygon.cc index 137844ae6..228b129dd 100644 --- a/src/atlas/util/Polygon.cc +++ b/src/atlas/util/Polygon.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/util/Polygon.h" diff --git a/src/atlas/util/Polygon.h b/src/atlas/util/Polygon.h index 21eef811c..1675e7117 100644 --- a/src/atlas/util/Polygon.h +++ b/src/atlas/util/Polygon.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ /// @author Pedro Maciel diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index 164a458cb..3c5fb2e03 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/util/Rotation.h" diff --git a/src/atlas/util/Rotation.h b/src/atlas/util/Rotation.h index b1b1731f4..7fe90d727 100644 --- a/src/atlas/util/Rotation.h +++ b/src/atlas/util/Rotation.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/SphericalPolygon.cc b/src/atlas/util/SphericalPolygon.cc index 94cd08330..e50c5beab 100644 --- a/src/atlas/util/SphericalPolygon.cc +++ b/src/atlas/util/SphericalPolygon.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/util/SphericalPolygon.h" diff --git a/src/atlas/util/SphericalPolygon.h b/src/atlas/util/SphericalPolygon.h index 3d1b43bb2..a839d87bc 100644 --- a/src/atlas/util/SphericalPolygon.h +++ b/src/atlas/util/SphericalPolygon.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/Unique.h b/src/atlas/util/Unique.h index ee2cbbacb..4c57d1136 100644 --- a/src/atlas/util/Unique.h +++ b/src/atlas/util/Unique.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/atlas/util/detail/Cache.h b/src/atlas/util/detail/Cache.h index 63ae07dea..039d5304c 100644 --- a/src/atlas/util/detail/Cache.h +++ b/src/atlas/util/detail/Cache.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc index 120b4cca8..84c2ae00b 100644 --- a/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc +++ b/src/sandbox/benchmark_build_halo/atlas-benchmark-build-halo.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc index e6ba097a3..c7a996c31 100644 --- a/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc +++ b/src/sandbox/benchmark_sorting/atlas-benchmark-sorting.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/sandbox/grid_distribution/atlas-grid-distribution.cc b/src/sandbox/grid_distribution/atlas-grid-distribution.cc index a354470df..20d629698 100644 --- a/src/sandbox/grid_distribution/atlas-grid-distribution.cc +++ b/src/sandbox/grid_distribution/atlas-grid-distribution.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/sandbox/interpolation/PartitionedMesh.cc b/src/sandbox/interpolation/PartitionedMesh.cc index e047a7468..32a6518d1 100644 --- a/src/sandbox/interpolation/PartitionedMesh.cc +++ b/src/sandbox/interpolation/PartitionedMesh.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "PartitionedMesh.h" diff --git a/src/sandbox/interpolation/PartitionedMesh.h b/src/sandbox/interpolation/PartitionedMesh.h index 4a88740bf..23e0e04af 100644 --- a/src/sandbox/interpolation/PartitionedMesh.h +++ b/src/sandbox/interpolation/PartitionedMesh.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/sandbox/interpolation/atlas-parallel-interpolation.cc b/src/sandbox/interpolation/atlas-parallel-interpolation.cc index 848bb059f..67a5d3dfe 100644 --- a/src/sandbox/interpolation/atlas-parallel-interpolation.cc +++ b/src/sandbox/interpolation/atlas-parallel-interpolation.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/AtlasTestEnvironment.h b/src/tests/AtlasTestEnvironment.h index 5feb6ad5f..0b0b66abf 100644 --- a/src/tests/AtlasTestEnvironment.h +++ b/src/tests/AtlasTestEnvironment.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #pragma once diff --git a/src/tests/TestMeshes.h b/src/tests/TestMeshes.h index 466d27c23..bfc6e518a 100644 --- a/src/tests/TestMeshes.h +++ b/src/tests/TestMeshes.h @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid.h" diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index a0e46335f..16b78b030 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array.h" diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index bc5f11791..a637cea46 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array.h" diff --git a/src/tests/array/test_array_view_util.cc b/src/tests/array/test_array_view_util.cc index 1a02e9958..61f77fd3a 100644 --- a/src/tests/array/test_array_view_util.cc +++ b/src/tests/array/test_array_view_util.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/Array.h" diff --git a/src/tests/array/test_svector.cc b/src/tests/array/test_svector.cc index f255f5308..7458fd6f9 100644 --- a/src/tests/array/test_svector.cc +++ b/src/tests/array/test_svector.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/SVector.h" diff --git a/src/tests/array/test_table.cc b/src/tests/array/test_table.cc index 0a669834d..34f98386a 100644 --- a/src/tests/array/test_table.cc +++ b/src/tests/array/test_table.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/Table.h" diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index 97fc36393..a1e18754e 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/ArrayView.h" diff --git a/src/tests/functionspace/test_pointcloud.cc b/src/tests/functionspace/test_pointcloud.cc index 6424c127b..faec2cad1 100644 --- a/src/tests/functionspace/test_pointcloud.cc +++ b/src/tests/functionspace/test_pointcloud.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/functionspace/PointCloud.h" diff --git a/src/tests/functionspace/test_structuredcolumns.cc b/src/tests/functionspace/test_structuredcolumns.cc index 19d6945bd..35c360d5f 100644 --- a/src/tests/functionspace/test_structuredcolumns.cc +++ b/src/tests/functionspace/test_structuredcolumns.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/ArrayView.h" diff --git a/src/tests/grid/test_domain.cc b/src/tests/grid/test_domain.cc index a2e564712..65149561a 100644 --- a/src/tests/grid/test_domain.cc +++ b/src/tests/grid/test_domain.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/grid/test_field.cc b/src/tests/grid/test_field.cc index ce482ead3..ce7de4ca8 100644 --- a/src/tests/grid/test_field.cc +++ b/src/tests/grid/test_field.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/runtime/Log.h" diff --git a/src/tests/grid/test_grid_ptr.cc b/src/tests/grid/test_grid_ptr.cc index 52f7c2136..7b9b1435b 100644 --- a/src/tests/grid/test_grid_ptr.cc +++ b/src/tests/grid/test_grid_ptr.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/grid/test_grids.cc b/src/tests/grid/test_grids.cc index 533b93ed6..013a8359b 100644 --- a/src/tests/grid/test_grids.cc +++ b/src/tests/grid/test_grids.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/grid/test_rotation.cc b/src/tests/grid/test_rotation.cc index f25b3a4d6..047dc895c 100644 --- a/src/tests/grid/test_rotation.cc +++ b/src/tests/grid/test_rotation.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/grid/test_state.cc b/src/tests/grid/test_state.cc index 97f5c8b17..c79498edb 100644 --- a/src/tests/grid/test_state.cc +++ b/src/tests/grid/test_state.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/interpolation/test_Quad3D.cc b/src/tests/interpolation/test_Quad3D.cc index 77e0be07f..0b80e8f63 100644 --- a/src/tests/interpolation/test_Quad3D.cc +++ b/src/tests/interpolation/test_Quad3D.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/interpolation/element/Quad3D.h" diff --git a/src/tests/interpolation/test_interpolation_finite_element.cc b/src/tests/interpolation/test_interpolation_finite_element.cc index 095b28c1c..36af5c28e 100644 --- a/src/tests/interpolation/test_interpolation_finite_element.cc +++ b/src/tests/interpolation/test_interpolation_finite_element.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/io/test_gmsh.cc b/src/tests/io/test_gmsh.cc index c43dc083d..121be1de1 100644 --- a/src/tests/io/test_gmsh.cc +++ b/src/tests/io/test_gmsh.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/Mesh.h" diff --git a/src/tests/io/test_pointcloud_io.cc b/src/tests/io/test_pointcloud_io.cc index a5a2b426c..2a704f38c 100644 --- a/src/tests/io/test_pointcloud_io.cc +++ b/src/tests/io/test_pointcloud_io.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/mesh/test_accumulate_facets.cc b/src/tests/mesh/test_accumulate_facets.cc index 4a3d59a76..10052f951 100644 --- a/src/tests/mesh/test_accumulate_facets.cc +++ b/src/tests/mesh/test_accumulate_facets.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/library/config.h" diff --git a/src/tests/mesh/test_cgal_mesh_gen_from_points.cc b/src/tests/mesh/test_cgal_mesh_gen_from_points.cc index 84bbfe618..73e5c6e99 100644 --- a/src/tests/mesh/test_cgal_mesh_gen_from_points.cc +++ b/src/tests/mesh/test_cgal_mesh_gen_from_points.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/mesh/test_connectivity.cc b/src/tests/mesh/test_connectivity.cc index 27ee56118..756b6da0b 100644 --- a/src/tests/mesh/test_connectivity.cc +++ b/src/tests/mesh/test_connectivity.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/mesh/Connectivity.h" diff --git a/src/tests/mesh/test_distmesh.cc b/src/tests/mesh/test_distmesh.cc index b9971c073..ec75f7cb3 100644 --- a/src/tests/mesh/test_distmesh.cc +++ b/src/tests/mesh/test_distmesh.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/mesh/test_elements.cc b/src/tests/mesh/test_elements.cc index 164ee0594..f886fc83a 100644 --- a/src/tests/mesh/test_elements.cc +++ b/src/tests/mesh/test_elements.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index c7209a45e..b92618fb8 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/mesh/test_ll.cc b/src/tests/mesh/test_ll.cc index ac88a2da1..18f3e6d23 100644 --- a/src/tests/mesh/test_ll.cc +++ b/src/tests/mesh/test_ll.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid/Grid.h" diff --git a/src/tests/mesh/test_meshgen3d.cc b/src/tests/mesh/test_meshgen3d.cc index 915b44504..3e85d425f 100644 --- a/src/tests/mesh/test_meshgen3d.cc +++ b/src/tests/mesh/test_meshgen3d.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/grid.h" diff --git a/src/tests/mesh/test_parfields.cc b/src/tests/mesh/test_parfields.cc index 5298a0252..fb208d351 100644 --- a/src/tests/mesh/test_parfields.cc +++ b/src/tests/mesh/test_parfields.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/mesh/test_rgg.cc b/src/tests/mesh/test_rgg.cc index 9f374c7ca..0c646daa4 100644 --- a/src/tests/mesh/test_rgg.cc +++ b/src/tests/mesh/test_rgg.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/mesh/test_shapefunctions.cc b/src/tests/mesh/test_shapefunctions.cc index 1343285b9..da2b48061 100644 --- a/src/tests/mesh/test_shapefunctions.cc +++ b/src/tests/mesh/test_shapefunctions.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/numerics/test_fvm_nabla.cc b/src/tests/numerics/test_fvm_nabla.cc index a5e5e0182..14d3a211c 100644 --- a/src/tests/numerics/test_fvm_nabla.cc +++ b/src/tests/numerics/test_fvm_nabla.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/parallel/test_gather.cc b/src/tests/parallel/test_gather.cc index db7d1f6f2..061992d39 100644 --- a/src/tests/parallel/test_gather.cc +++ b/src/tests/parallel/test_gather.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/parallel/test_haloexchange.cc b/src/tests/parallel/test_haloexchange.cc index 40b651bdc..b92d3bf9e 100644 --- a/src/tests/parallel/test_haloexchange.cc +++ b/src/tests/parallel/test_haloexchange.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 6d9e6b685..34f0d2a5e 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index 1023cdb1c..877727a51 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index ce261c94d..10c50dc18 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/util/test_earth.cc b/src/tests/util/test_earth.cc index f7b410037..9faf6dce6 100644 --- a/src/tests/util/test_earth.cc +++ b/src/tests/util/test_earth.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/util/test_flags.cc b/src/tests/util/test_flags.cc index 680e00fce..ece38c615 100644 --- a/src/tests/util/test_flags.cc +++ b/src/tests/util/test_flags.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/util/test_footprint.cc b/src/tests/util/test_footprint.cc index 56bbaaab8..d9257840b 100644 --- a/src/tests/util/test_footprint.cc +++ b/src/tests/util/test_footprint.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/Array.h" diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index 23c581d3e..54721dedc 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array.h" diff --git a/src/tests/util/test_metadata.cc b/src/tests/util/test_metadata.cc index bd97c3a7c..4730eac5c 100644 --- a/src/tests/util/test_metadata.cc +++ b/src/tests/util/test_metadata.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/ArrayView.h" diff --git a/src/tests/util/test_polygon.cc b/src/tests/util/test_polygon.cc index 481235111..090e14ac8 100644 --- a/src/tests/util/test_polygon.cc +++ b/src/tests/util/test_polygon.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include diff --git a/src/tests/util/test_vector.cc b/src/tests/util/test_vector.cc index a80c9da63..8156eb4a1 100644 --- a/src/tests/util/test_vector.cc +++ b/src/tests/util/test_vector.cc @@ -5,8 +5,7 @@ * 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. + * nor does it submit to any jurisdiction. */ #include "atlas/array/Vector.h" From 93f2042d9e84b4187bfd8923ea12b707442d4e0c Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Thu, 15 Feb 2018 16:35:16 +0000 Subject: [PATCH 344/355] some cleanup in the local transform --- src/atlas/trans/local/FourierTransforms.cc | 47 +++++++++--------- src/atlas/trans/local/FourierTransforms.h | 8 +-- src/atlas/trans/local/LegendrePolynomials.cc | 52 +++++++++++--------- src/atlas/trans/local/LegendrePolynomials.h | 9 ++-- src/atlas/trans/local/LegendreTransforms.cc | 16 +++--- src/atlas/trans/local/LegendreTransforms.h | 16 +++--- src/atlas/trans/local/VorDivToUVLocal.cc | 30 +++++------ src/tests/trans/test_transgeneral.cc | 41 ++++++++------- 8 files changed, 106 insertions(+), 113 deletions(-) diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc index 8611a8cff..2baf32859 100644 --- a/src/atlas/trans/local/FourierTransforms.cc +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -5,7 +5,8 @@ * 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. + * nor + * does it submit to any jurisdiction. */ #include "atlas/trans/local/FourierTransforms.h" @@ -21,50 +22,52 @@ namespace trans { void invtrans_fourier( const size_t trcFT, const double lon, // longitude in radians (in) const int nb_fields, // Number of fields - const double rlegReal[], // values of associated Legendre - // functions, size (trc+1)*trc/2 - // (in) - const double rlegImag[], // values of associated Legendre - // functions, size (trc+1)*trc/2 - // (in) + const double rlegReal[], // associated Legendre functions, size (trc+1)*trc/2 (in) + const double rlegImag[], // associated Legendre functions, size (trc+1)*trc/2 (in) double rgp[] ) // gridpoint { for ( int jfld = 0; jfld < nb_fields; ++jfld ) { rgp[jfld] = 0.; } // local Fourier transformation: - // (FFT would be slower when computing the Fourier transformation for a single - // point) for ( int jm = 0; jm <= trcFT; ++jm ) { const double cos = std::cos( jm * lon ); const double sin = std::sin( jm * lon ); for ( int jfld = 0; jfld < nb_fields; ++jfld ) { - rgp[jfld] += cos * rlegReal[jm * nb_fields + jfld] - sin * rlegImag[jm * nb_fields + jfld]; + double real = cos * rlegReal[jm * nb_fields + jfld]; + double imag = sin * rlegImag[jm * nb_fields + jfld]; + rgp[jfld] += real - imag; } } } -int fourier_truncation( const int truncation, const int nx, const int nxmax, const int ndgl, const double lat, - const bool fullgrid ) { - int linear_truncation = ndgl - 1; - int trc = truncation; - if ( truncation >= linear_truncation || fullgrid ) { +int fourier_truncation( const int truncation, // truncation + const int nx, // number of longitudes + const int nxmax, // maximum nx + const int ndgl, // number of latitudes + const double lat, // latitude in radian + const bool fullgrid ) { // regular grid + int trc = truncation; + int trclin = ndgl - 1; + int trcquad = ndgl * 2 / 3 - 1; + if ( truncation >= trclin || fullgrid ) { // linear trc = ( nx - 1 ) / 2; } - else if ( truncation >= ndgl * 2 / 3 - 1 ) { + else if ( truncation >= trcquad ) { // quadratic - // trc = (nx-1)/(2+std::pow(std::cos(lat),2)); - trc = ( nx - 1 ) / ( 2 + 3 * ( linear_truncation - truncation ) / ndgl * std::pow( std::cos( lat ), 2 ) ); + double weight = 3 * ( trclin - truncation ) / ndgl; + double sqcos = std::pow( std::cos( lat ), 2 ); + + trc = ( nx - 1 ) / ( 2 + weight * sqcos ); } else { // cubic - trc = ( nx - 1 ) / ( 2 + std::pow( std::cos( lat ), 2 ) ) - 1; + double sqcos = std::pow( std::cos( lat ), 2 ); + + trc = ( nx - 1 ) / ( 2 + sqcos ) - 1; } trc = std::min( truncation, trc ); - // std::cout << "truncation=" << truncation << " trc=" << trc << " - // ndgl*2/3-1=" << ndgl*2/3-1 << " nx=" << nx << " nxmax=" << nxmax << " - // latsin2=" << std::pow(std::cos(lat),2) << std::endl; return trc; } diff --git a/src/atlas/trans/local/FourierTransforms.h b/src/atlas/trans/local/FourierTransforms.h index a3e4451df..8b47a8dd9 100644 --- a/src/atlas/trans/local/FourierTransforms.h +++ b/src/atlas/trans/local/FourierTransforms.h @@ -25,12 +25,8 @@ namespace trans { void invtrans_fourier( const size_t trcFT, const double lon, // longitude in radians (in) const int nb_fields, // Number of fields - const double rlegReal[], // values of associated Legendre - // functions, size (trc+1)*trc/2 - // (in) - const double rlegImag[], // values of associated Legendre - // functions, size (trc+1)*trc/2 - // (in) + const double rlegReal[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) + const double rlegImag[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) double rgp[] ); // gridpoint int fourier_truncation( const int truncation, const int nx, const int nxmax, const int ndgl, const double lat, diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index ae1866706..5a290dab9 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -5,7 +5,8 @@ * 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. + * nor + * does it submit to any jurisdiction. */ #include "atlas/trans/local/LegendrePolynomials.h" @@ -18,15 +19,15 @@ namespace trans { //----------------------------------------------------------------------------- -void compute_legendre_polynomials( const size_t trc, // truncation (in) - const double lat, // latitude in radians (in) - double legpol[] ) // values of associated - // Legendre functions, size - // (trc+1)*trc/2 (out) +void compute_legendre_polynomials( + const size_t trc, // truncation (in) + const double lat, // latitude in radians (in) + double legpol[] ) // values of associated Legendre functions, size (trc+1)*trc/2 (out) { array::ArrayT idxmn_( trc + 1, trc + 1 ); array::ArrayView idxmn = array::make_view( idxmn_ ); - int j = 0; + + int j = 0; for ( int jm = 0; jm <= trc; ++jm ) { for ( int jn = jm; jn <= trc; ++jn ) { idxmn( jm, jn ) = j++; @@ -38,6 +39,7 @@ void compute_legendre_polynomials( const size_t trc, // truncation (in) int iodd; + // Compute coefficients for Taylor series in Belousov (19) and (21) // Belousov, Swarztrauber use zfn(0,0)=std::sqrt(2.) // IFS normalisation chosen to be 0.5*Integral(Pnm**2) = 1 zfn( 0, 0 ) = 2.; @@ -49,8 +51,10 @@ void compute_legendre_polynomials( const size_t trc, // truncation (in) iodd = jn % 2; zfn( jn, jn ) = zfnn; for ( int jgl = 2; jgl <= jn - iodd; jgl += 2 ) { - zfn( jn, jn - jgl ) = - zfn( jn, jn - jgl + 2 ) * ( ( jgl - 1. ) * ( 2. * jn - jgl + 2. ) ) / ( jgl * ( 2. * jn - jgl + 1. ) ); + double zfjn = ( ( jgl - 1. ) * ( 2. * jn - jgl + 2. ) ); // new factor numerator + double zfjd = ( jgl * ( 2. * jn - jgl + 1. ) ); // new factor denominator + + zfn( jn, jn - jgl ) = zfn( jn, jn - jgl + 2 ) * zfjn / zfjd; } } @@ -80,12 +84,13 @@ void compute_legendre_polynomials( const size_t trc, // truncation (in) for ( int jn = 2; jn <= trc; jn += 2 ) { double zdlk = 0.5 * zfn( jn, 0 ); double zdlldn = 0.0; + double zdsq = 1. / std::sqrt( jn * ( jn + 1. ) ); // represented by only even k for ( int jk = 2; jk <= jn; jk += 2 ) { // normalised ordinary Legendre polynomial == \overbar{P_n}^0 zdlk = zdlk + zfn( jn, jk ) * std::cos( jk * zdlx1 ); // normalised associated Legendre polynomial == \overbar{P_n}^1 - zdlldn = zdlldn + 1. / std::sqrt( jn * ( jn + 1. ) ) * zfn( jn, jk ) * jk * std::sin( jk * zdlx1 ); + zdlldn = zdlldn + zdsq * zfn( jn, jk ) * jk * std::sin( jk * zdlx1 ); } legpol[idxmn( 0, jn )] = zdlk; legpol[idxmn( 1, jn )] = zdlldn; @@ -96,12 +101,13 @@ void compute_legendre_polynomials( const size_t trc, // truncation (in) zfn( jn, 0 ) = 0.; double zdlk = 0.; double zdlldn = 0.0; + double zdsq = 1. / std::sqrt( jn * ( jn + 1. ) ); // represented by only even k for ( int jk = 1; jk <= jn; jk += 2 ) { // normalised ordinary Legendre polynomial == \overbar{P_n}^0 zdlk = zdlk + zfn( jn, jk ) * std::cos( jk * zdlx1 ); // normalised associated Legendre polynomial == \overbar{P_n}^1 - zdlldn = zdlldn + 1. / std::sqrt( jn * ( jn + 1. ) ) * zfn( jn, jk ) * jk * std::sin( jk * zdlx1 ); + zdlldn = zdlldn + zdsq * zfn( jn, jk ) * jk * std::sin( jk * zdlx1 ); } legpol[idxmn( 0, jn )] = zdlk; legpol[idxmn( 1, jn )] = zdlldn; @@ -114,8 +120,9 @@ void compute_legendre_polynomials( const size_t trc, // truncation (in) double zdls = zdl1sita * std::numeric_limits::min(); for ( int jn = 2; jn <= trc; ++jn ) { - legpol[idxmn( jn, jn )] = - legpol[idxmn( jn - 1, jn - 1 )] * zdlsita * std::sqrt( ( 2. * jn + 1. ) / ( 2. * jn ) ); + 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; } @@ -125,15 +132,16 @@ void compute_legendre_polynomials( const size_t trc, // truncation (in) for ( int jn = 3; jn <= trc; ++jn ) { for ( int jm = 2; jm < jn; ++jm ) { - legpol[idxmn( jm, jn )] = - std::sqrt( ( ( 2. * jn + 1. ) * ( jn + jm - 1. ) * ( jn + jm - 3. ) ) / - ( ( 2. * jn - 3. ) * ( jn + jm ) * ( jn + jm - 2. ) ) ) * - legpol[idxmn( jm - 2, jn - 2 )] - - std::sqrt( ( ( 2. * jn + 1. ) * ( jn + jm - 1. ) * ( jn - jm + 1. ) ) / - ( ( 2. * jn - 1. ) * ( jn + jm ) * ( jn + jm - 2. ) ) ) * - legpol[idxmn( jm - 2, jn - 1 )] * zdlx + - std::sqrt( ( ( 2. * jn + 1. ) * ( jn - jm ) ) / ( ( 2. * jn - 1. ) * ( jn + jm ) ) ) * - legpol[idxmn( jm, jn - 1 )] * zdlx; + double cn = ( ( 2. * jn + 1. ) * ( jn + jm - 1. ) * ( jn + jm - 3. ) ); // numerator of c in Belousov + double cd = ( ( 2. * jn - 3. ) * ( jn + jm ) * ( jn + jm - 2. ) ); // denominator of c in Belousov + double dn = ( ( 2. * jn + 1. ) * ( jn + jm - 1. ) * ( jn - jm + 1. ) ); // numerator of d in Belousov + double dd = ( ( 2. * jn - 1. ) * ( jn + jm ) * ( jn + jm - 2. ) ); // denominator of d in Belousov + double en = ( ( 2. * jn + 1. ) * ( jn - jm ) ); // numerator of e in Belousov + double ed = ( ( 2. * jn - 1. ) * ( jn + jm ) ); // denominator of e in Belousov + + legpol[idxmn( jm, jn )] = std::sqrt( cn / cd ) * legpol[idxmn( jm - 2, jn - 2 )] - + std::sqrt( dn / dd ) * legpol[idxmn( jm - 2, jn - 1 )] * zdlx + + std::sqrt( en / ed ) * legpol[idxmn( jm, jn - 1 )] * zdlx; } } } diff --git a/src/atlas/trans/local/LegendrePolynomials.h b/src/atlas/trans/local/LegendrePolynomials.h index 5407b48cb..56a3e7443 100644 --- a/src/atlas/trans/local/LegendrePolynomials.h +++ b/src/atlas/trans/local/LegendrePolynomials.h @@ -32,11 +32,10 @@ namespace trans { // Ported to C++ by: // Andreas Mueller *ECMWF* // -void compute_legendre_polynomials( const size_t trc, // truncation (in) - const double lat, // latitude in radians (in) - double legpol[] ); // values of associated - // Legendre functions, size - // (trc+1)*trc/2 (out) +void compute_legendre_polynomials( + const size_t trc, // truncation (in) + const double lat, // latitude in radians (in) + double legpol[] ); // values of associated Legendre functions, size (trc+1)*trc/2 (out) // -------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/trans/local/LegendreTransforms.cc b/src/atlas/trans/local/LegendreTransforms.cc index 9db0af26e..4ddb4f0bb 100644 --- a/src/atlas/trans/local/LegendreTransforms.cc +++ b/src/atlas/trans/local/LegendreTransforms.cc @@ -16,18 +16,14 @@ namespace trans { //----------------------------------------------------------------------------- -void invtrans_legendre( const size_t trc, // truncation (in) - const size_t trcFT, // truncation for Fourier transformation (in) - const size_t trcLP, // truncation of Legendre polynomials data legpol. Needs - // to be >= trc (in) - const double legpol[], // values of associated Legendre functions, size - // (trc+1)*trc/2 (in) +void invtrans_legendre( const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + const size_t trcLP, // truncation of Legendre polynomials data legpol. Needs to be >= trc (in) + const double legpol[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) const int nb_fields, // number of fields const double spec[], // spectral data, size (trc+1)*trc (in) - double leg_real[], // values of associated Legendre functions, size - // (trc+1)*trc/2 (out) - double leg_imag[] ) // values of associated Legendre functions, size - // (trc+1)*trc/2 (out) + double leg_real[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + double leg_imag[] ) // values of associated Legendre functions, size (trc+1)*trc/2 (out) { // Legendre transformation: int k = 0, klp = 0; diff --git a/src/atlas/trans/local/LegendreTransforms.h b/src/atlas/trans/local/LegendreTransforms.h index 85a94dd13..c3152e1f5 100644 --- a/src/atlas/trans/local/LegendreTransforms.h +++ b/src/atlas/trans/local/LegendreTransforms.h @@ -21,18 +21,14 @@ namespace trans { // Author: // Andreas Mueller *ECMWF* // -void invtrans_legendre( const size_t trc, // truncation (in) - const size_t trcFT, // truncation for Fourier transformation (in) - const size_t trcLP, // truncation of Legendre polynomials data legpol. Needs - // to be >= trc (in) - const double legpol[], // values of associated Legendre functions, size - // (trc+1)*trc/2 (in) +void invtrans_legendre( const size_t trc, // truncation (in) + const size_t trcFT, // truncation for Fourier transformation (in) + const size_t trcLP, // truncation of Legendre polynomials data legpol. Needs to be >= trc (in) + const double legpol[], // values of associated Legendre functions, size (trc+1)*trc/2 (in) const int nb_fields, // number of fields const double spec[], // spectral data, size (trc+1)*trc (in) - double leg_real[], // values of associated Legendre functions, size - // (trc+1)*trc/2 (out) - double leg_imag[] ); // values of associated Legendre functions, size - // (trc+1)*trc/2 (out) + double leg_real[], // values of associated Legendre functions, size (trc+1)*trc/2 (out) + double leg_imag[] ); // values of associated Legendre functions, size (trc+1)*trc/2 (out) // -------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index 3cba7e2d0..82161e83d 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -75,9 +75,10 @@ void vd2uv( const int truncation, repsnm[0] = 0.; // rlapin: constant factor from eq.(2.2) and (2.3) in [Temperton 1991] + double ra = util::Earth::radiusInMeters(); std::vector rlapin( truncation + 3 ); for ( int jn = 1; jn <= truncation + 2; ++jn ) { - rlapin[jn] = -util::Earth::radiusInMeters() * util::Earth::radiusInMeters() / ( jn * ( jn + 1. ) ); + rlapin[jn] = -ra * ra / ( jn * ( jn + 1. ) ); } rlapin[0] = 0.; @@ -115,10 +116,10 @@ void vd2uv( const int truncation, for ( int jfld = 0; jfld < nb_vordiv_fields; ++jfld ) { int ir = 2 * jfld * nlei1 - 1; for ( int ji = 2; ji < truncation + 4 - km; ++ji ) { - ru[ir + ji] = +zn[ji + 1] * zepsnm[ji] * zlapin[ji + 1] * rvor[ir + ji + 1] - - zn[ji - 2] * zepsnm[ji - 1] * zlapin[ji - 1] * rvor[ir + ji - 1]; - rv[ir + ji] = -zn[ji + 1] * zepsnm[ji] * zlapin[ji + 1] * rdiv[ir + ji + 1] + - zn[ji - 2] * zepsnm[ji - 1] * zlapin[ji - 1] * rdiv[ir + ji - 1]; + double psiM1 = zn[ji + 1] * zepsnm[ji] * zlapin[ji + 1]; + double psiP1 = zn[ji - 2] * zepsnm[ji - 1] * zlapin[ji - 1]; + ru[ir + ji] = +psiM1 * rvor[ir + ji + 1] - psiP1 * rvor[ir + ji - 1]; + rv[ir + ji] = -psiM1 * rdiv[ir + ji + 1] + psiP1 * rdiv[ir + ji - 1]; } } } @@ -126,18 +127,13 @@ void vd2uv( const int truncation, for ( int jfld = 0; jfld < nb_vordiv_fields; ++jfld ) { int ir = 2 * jfld * nlei1 - 1, ii = ir + nlei1; for ( int ji = 2; ji < truncation + 4 - km; ++ji ) { - ru[ir + ji] = -km * zlapin[ji] * rdiv[ii + ji] + - zn[ji + 1] * zepsnm[ji] * zlapin[ji + 1] * rvor[ir + ji + 1] - - zn[ji - 2] * zepsnm[ji - 1] * zlapin[ji - 1] * rvor[ir + ji - 1]; - ru[ii + ji] = +km * zlapin[ji] * rdiv[ir + ji] + - zn[ji + 1] * zepsnm[ji] * zlapin[ji + 1] * rvor[ii + ji + 1] - - zn[ji - 2] * zepsnm[ji - 1] * zlapin[ji - 1] * rvor[ii + ji - 1]; - rv[ir + ji] = -km * zlapin[ji] * rvor[ii + ji] - - zn[ji + 1] * zepsnm[ji] * zlapin[ji + 1] * rdiv[ir + ji + 1] + - zn[ji - 2] * zepsnm[ji - 1] * zlapin[ji - 1] * rdiv[ir + ji - 1]; - rv[ii + ji] = +km * zlapin[ji] * rvor[ir + ji] - - zn[ji + 1] * zepsnm[ji] * zlapin[ji + 1] * rdiv[ii + ji + 1] + - zn[ji - 2] * zepsnm[ji - 1] * zlapin[ji - 1] * rdiv[ii + ji - 1]; + double chiIm = km * zlapin[ji]; + double psiM1 = zn[ji + 1] * zepsnm[ji] * zlapin[ji + 1]; + double psiP1 = zn[ji - 2] * zepsnm[ji - 1] * zlapin[ji - 1]; + ru[ir + ji] = -chiIm * rdiv[ii + ji] + psiM1 * rvor[ir + ji + 1] - psiP1 * rvor[ir + ji - 1]; + ru[ii + ji] = +chiIm * rdiv[ir + ji] + psiM1 * rvor[ii + ji + 1] - psiP1 * rvor[ii + ji - 1]; + rv[ir + ji] = -chiIm * rvor[ii + ji] - psiM1 * rdiv[ir + ji + 1] + psiP1 * rdiv[ir + ji - 1]; + rv[ii + ji] = +chiIm * rvor[ir + ji] - psiM1 * rdiv[ii + ji + 1] + psiP1 * rdiv[ii + ji - 1]; } } } diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 10c50dc18..e90b13358 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -858,27 +858,26 @@ CASE( "test_trans_invtrans" ) { //----------------------------------------------------------------------------- #if 0 -CASE( "test_trans_fourier_truncation" ) -{ - Log::info() << "test_trans_fourier_truncation" << std::endl; - // test transgeneral by comparing its result with the trans library - // this test is based on the test_nomesh case in test_trans.cc - - Grid g( "F640" ); - grid::StructuredGrid gs(g); - int ndgl = gs.ny(); - //int trc = 2*ndgl; // extreme high truncation (below linear) - int trc = ndgl-1; // linear - //int trc = 5./6.*ndgl-1; // between linear and quadratic - //int trc = 2./3.*ndgl-1; // quadratic - //int trc = ndgl/2. -1; // cubic - trans::Trans trans(g, trc) ; - for( int j=0; j Date: Thu, 15 Feb 2018 17:13:32 +0000 Subject: [PATCH 345/355] more cleanup --- src/atlas/trans/local/LegendrePolynomials.cc | 8 ++++---- src/atlas/trans/local/VorDivToUVLocal.cc | 12 ++++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index 5a290dab9..bc32b82f0 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -132,10 +132,10 @@ void compute_legendre_polynomials( for ( int jn = 3; jn <= trc; ++jn ) { for ( int jm = 2; jm < jn; ++jm ) { - double cn = ( ( 2. * jn + 1. ) * ( jn + jm - 1. ) * ( jn + jm - 3. ) ); // numerator of c in Belousov - double cd = ( ( 2. * jn - 3. ) * ( jn + jm ) * ( jn + jm - 2. ) ); // denominator of c in Belousov - double dn = ( ( 2. * jn + 1. ) * ( jn + jm - 1. ) * ( jn - jm + 1. ) ); // numerator of d in Belousov - double dd = ( ( 2. * jn - 1. ) * ( jn + jm ) * ( jn + jm - 2. ) ); // denominator of d in Belousov + double cn = ( ( 2. * jn + 1. ) * ( jn + jm - 3. ) * ( jn + jm - 1. ) ); // numerator of c in Belousov + double cd = ( ( 2. * jn - 3. ) * ( jn + jm - 2. ) * ( jn + jm ) ); // denominator of c in Belousov + double dn = ( ( 2. * jn + 1. ) * ( jn - jm + 1. ) * ( jn + jm - 1. ) ); // numerator of d in Belousov + double dd = ( ( 2. * jn - 1. ) * ( jn + jm - 2. ) * ( jn + jm ) ); // denominator of d in Belousov double en = ( ( 2. * jn + 1. ) * ( jn - jm ) ); // numerator of e in Belousov double ed = ( ( 2. * jn - 1. ) * ( jn + jm ) ); // denominator of e in Belousov diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index 82161e83d..bed717bf0 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -58,10 +58,14 @@ void prfi1b( const int truncation, // ECMWF Research Department documentation of the IFS // Temperton, 1991, MWR 119 p1303 // Ported to C++ by: Andreas Mueller *ECMWF* -void vd2uv( const int truncation, - const int km, // zonal wavenumber - const int nb_vordiv_fields, const double vorticity_spectra[], const double divergence_spectra[], double U[], - double V[], const eckit::Configuration& config ) { +void vd2uv( const int truncation, // truncation + const int km, // zonal wavenumber + const int nb_vordiv_fields, // number of vorticity and divergence fields + const double vorticity_spectra[], // spectral data of vorticity + const double divergence_spectra[], // spectral data of divergence + double U[], // spectral data of U + double V[], // spectral data of V + const eckit::Configuration& config ) { int nlei1 = truncation + 4 + ( truncation + 4 + 1 ) % 2; // repsnm: epsilon from eq.(2.12) and (2.13) in [Temperton 1991] From 025bd7de66f69dfee694d3c263df710b60f8aba7 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 15:41:38 +0000 Subject: [PATCH 346/355] Change #ifdef ATLAS_HAVE_OMP to #if ATLAS_HAVE_OMP --- src/atlas/library/Library.cc | 2 +- src/atlas/library/defines.h.in | 6 ++--- src/atlas/parallel/omp/omp.cc | 22 +++++++++---------- src/atlas/parallel/omp/omp.h | 2 +- src/atlas_f/atlas_f.h.in | 6 ++--- .../example_fortran/example_fortran.F90 | 5 +---- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 721fe2f25..481369d3c 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -229,7 +229,7 @@ void Library::Information::print( std::ostream& out ) const { #ifdef ECKIT_HAVE_MPI feature_MPI = true; #endif -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP feature_OpenMP = true; #endif #ifdef ATLAS_HAVE_TRANS diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index 0bf921b37..dd52fd4ea 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -5,9 +5,7 @@ #define CGAL_FOUND #endif -#if @ATLAS_HAVE_OMP@ -#define ATLAS_HAVE_OMP -#endif +#define ATLAS_HAVE_OMP @ATLAS_HAVE_OMP@ #if @ATLAS_HAVE_TESSELATION@ #define ATLAS_HAVE_TESSELATION @@ -52,4 +50,4 @@ #define ATLAS_INDEXVIEW_BOUNDS_CHECKING #endif -#endif \ No newline at end of file +#endif diff --git a/src/atlas/parallel/omp/omp.cc b/src/atlas/parallel/omp/omp.cc index 01f3ecc1d..fa409d3de 100644 --- a/src/atlas/parallel/omp/omp.cc +++ b/src/atlas/parallel/omp/omp.cc @@ -25,7 +25,7 @@ extern "C" void omp_set_nested( int nested ); extern "C" int omp_get_nested( void ); #endif -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP extern "C" { #pragma weak omp_set_num_threads #pragma weak omp_get_num_threads @@ -41,67 +41,67 @@ extern "C" { #endif void atlas_omp_set_num_threads( int num_threads ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_set_num_threads ) omp_set_num_threads( num_threads ); #endif } int atlas_omp_get_num_threads( void ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_get_num_threads ) return omp_get_num_threads(); #endif return 1; } int atlas_omp_get_max_threads( void ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_get_max_threads ) return omp_get_max_threads(); #endif return 1; } int atlas_omp_get_thread_num( void ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_get_thread_num ) return omp_get_thread_num(); #endif return 0; } int atlas_omp_get_num_procs( void ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_get_num_procs ) return omp_get_num_procs(); #endif return 1; } int atlas_omp_in_parallel( void ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_in_parallel ) return omp_in_parallel(); #endif return 0; } void atlas_omp_set_dynamic( int dynamic_threads ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_set_dynamic ) omp_set_dynamic( dynamic_threads ); #endif } int atlas_omp_get_dynamic( void ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_get_dynamic ) return omp_get_dynamic(); #endif return 0; } void atlas_omp_set_nested( int nested ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_set_nested ) omp_set_nested( nested ); #endif } int atlas_omp_get_nested( void ) { -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP if ( omp_get_nested ) return omp_get_nested(); #endif return 0; diff --git a/src/atlas/parallel/omp/omp.h b/src/atlas/parallel/omp/omp.h index f4843d6c6..98858f65e 100644 --- a/src/atlas/parallel/omp/omp.h +++ b/src/atlas/parallel/omp/omp.h @@ -23,7 +23,7 @@ int atlas_omp_get_dynamic( void ); void atlas_omp_set_nested( int nested ); int atlas_omp_get_nested( void ); -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP #define __ATLAS_OMP_STR( x ) #x #define __ATLAS_OMP_STRINGIFY( x ) __ATLAS_OMP_STR( x ) #define atlas_omp_pragma( x ) _Pragma( __ATLAS_OMP_STRINGIFY( x ) ) diff --git a/src/atlas_f/atlas_f.h.in b/src/atlas_f/atlas_f.h.in index 2c26875ba..4d9f369cd 100644 --- a/src/atlas_f/atlas_f.h.in +++ b/src/atlas_f/atlas_f.h.in @@ -3,9 +3,7 @@ #include "fckit/fckit.h" -#if @ATLAS_HAVE_OMP@ -#define ATLAS_HAVE_OMP -#endif +#define ATLAS_HAVE_OMP @ATLAS_HAVE_OMP@ #if @ATLAS_HAVE_TRANS@ #define ATLAS_HAVE_TRANS @@ -17,4 +15,4 @@ #define ATLAS_BITS_GLOBAL @ATLAS_BITS_GLOBAL@ -#endif \ No newline at end of file +#endif diff --git a/src/sandbox/example_fortran/example_fortran.F90 b/src/sandbox/example_fortran/example_fortran.F90 index b689670d2..5f1ef9923 100644 --- a/src/sandbox/example_fortran/example_fortran.F90 +++ b/src/sandbox/example_fortran/example_fortran.F90 @@ -3,9 +3,6 @@ program example_fortran use atlas_module -#ifdef ATLAS_HAVE_OMP -use omp_lib -#endif implicit none integer j @@ -23,7 +20,7 @@ program example_fortran call atlas_log%set_fortran_unit(6) -#ifdef ATLAS_HAVE_OMP +#if ATLAS_HAVE_OMP call atlas_log%info("OpenMP enabled") #endif From c8a3d4fdace238b97f11dc9ea7651d3a40e35ebd Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 15:46:12 +0000 Subject: [PATCH 347/355] Change #ifdef ATLAS_HAVE_ACC to #if ATLAS_HAVE_ACC --- src/atlas/array/gridtools/GridToolsArray.cc | 4 ++-- src/atlas/library/defines.h.in | 4 +--- src/tests/array/test_array.cc | 14 ++++++-------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/atlas/array/gridtools/GridToolsArray.cc b/src/atlas/array/gridtools/GridToolsArray.cc index 1cd4f5c6d..886a3cd60 100644 --- a/src/atlas/array/gridtools/GridToolsArray.cc +++ b/src/atlas/array/gridtools/GridToolsArray.cc @@ -22,7 +22,7 @@ #include "atlas/array/gridtools/GridToolsTraits.h" #include "atlas/array/helpers/ArrayInitializer.h" #include "atlas/array_fwd.h" -#ifdef ATLAS_HAVE_ACC +#if ATLAS_HAVE_ACC #include "atlas_acc_support/atlas_acc_map_data.h" #endif #include "eckit/exception/Exceptions.h" @@ -332,7 +332,7 @@ size_t ArrayT::footprint() const { template bool ArrayT::accMap() const { if ( not acc_map_ ) { -#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA && defined( ATLAS_HAVE_ACC ) +#if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA && ATLAS_HAVE_ACC atlas_acc_map_data( (void*)host_data(), (void*)device_data(), spec_.allocatedSize() * sizeof( Value ) ); acc_map_ = true; diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index dd52fd4ea..0951599e0 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -29,9 +29,7 @@ #define ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA @ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA@ #endif -#if @ATLAS_HAVE_ACC@ -#define ATLAS_HAVE_ACC -#endif +#define ATLAS_HAVE_ACC @ATLAS_HAVE_ACC@ #ifdef __CUDACC__ #define ATLAS_HOST_DEVICE __host__ __device__ diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index 16b78b030..a9edfb4db 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -567,17 +567,15 @@ CASE( "test_wrap" ) { EXPECT( view( 2 ) == 19 ); } -#ifdef ATLAS_HAVE_ACC CASE( "test_acc_map" ) { Array* ds = Array::create( 2, 3, 4 ); -#ifdef ATLAS_HAVE_ACC - EXPECT( ds->accMap() == true ); - EXPECT( ds->accMap() == true ); -#else - EXPECT( ds->accMap() == false ); -#endif + if( ATLAS_HAVE_ACC ) { + EXPECT( ds->accMap() == true ); + EXPECT( ds->accMap() == true ); + } else { + EXPECT( ds->accMap() == false ); + } } -#endif //----------------------------------------------------------------------------- From cc4d9afdd4c92fcc0b436533a0a6d9cd2764fc1e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 15:53:08 +0000 Subject: [PATCH 348/355] Change #ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING to #if ATLAS_ARRAYVIEW_BOUNDS_CHECKING --- src/atlas/array/LocalView.h | 2 +- src/atlas/array/native/NativeArrayView.h | 2 +- src/atlas/array/native/NativeIndexView.h | 2 +- src/atlas/library/defines.h.in | 6 ++---- src/tests/util/test_indexview.cc | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/atlas/array/LocalView.h b/src/atlas/array/LocalView.h index 60f0c8214..fd279c8fd 100644 --- a/src/atlas/array/LocalView.h +++ b/src/atlas/array/LocalView.h @@ -171,7 +171,7 @@ class LocalView { return index_part<0>( idx... ); } -#ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING +#if ATLAS_ARRAYVIEW_BOUNDS_CHECKING template void check_bounds( Ints... idx ) const { static_assert( sizeof...( idx ) == Rank, "Expected number of indices is different from rank of array" ); diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 269fe90c6..3bcefb9ba 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -188,7 +188,7 @@ class ArrayView { return index_part<0>( idx... ); } -#ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING +#if ATLAS_ARRAYVIEW_BOUNDS_CHECKING template void check_bounds( Ints... idx ) const { static_assert( sizeof...( idx ) == Rank, "Expected number of indices is different from rank of array" ); diff --git a/src/atlas/array/native/NativeIndexView.h b/src/atlas/array/native/NativeIndexView.h index e56c32051..ae071b413 100644 --- a/src/atlas/array/native/NativeIndexView.h +++ b/src/atlas/array/native/NativeIndexView.h @@ -152,7 +152,7 @@ class IndexView { return index_part<0>( idx... ); } -#ifdef ATLAS_ARRAYVIEW_BOUNDS_CHECKING +#if ATLAS_INDEXVIEW_BOUNDS_CHECKING template void check_bounds( Ints... idx ) const { static_assert( sizeof...( idx ) == Rank, "Expected number of indices is different from rank of array" ); diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index 0951599e0..fffbf0024 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -43,9 +43,7 @@ #define ATLAS_BITS_GLOBAL @ATLAS_BITS_GLOBAL@ -#if @ATLAS_HAVE_BOUNDSCHECKING@ -#define ATLAS_ARRAYVIEW_BOUNDS_CHECKING -#define ATLAS_INDEXVIEW_BOUNDS_CHECKING -#endif +#define ATLAS_ARRAYVIEW_BOUNDS_CHECKING @ATLAS_HAVE_BOUNDSCHECKING@ +#define ATLAS_INDEXVIEW_BOUNDS_CHECKING @ATLAS_HAVE_BOUNDSCHECKING@ #endif diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index 54721dedc..62fd5fca4 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -62,7 +62,7 @@ EXPECT( array(1,0,1) == 5 ); EXPECT( array(1,0,2) == 6 ); EXPECT( array(1,0,3) == 7 ); -#ifdef ATLAS_INDEXVIEW_BOUNDS_CHECKING +#if ATLAS_INDEXVIEW_BOUNDS_CHECKING EXPECT_THROWS_AS( array(0,1,0) , eckit::OutOfRange ); // j index out of range EXPECT_THROWS_AS( array(1,2,0,3), eckit::OutOfRange ); // rank out of range #endif From 8027c18696586889def6830b437e2619223edc76 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 16:03:35 +0000 Subject: [PATCH 349/355] Change #ifdef ATLAS_HAVE_FORTRAN to #if ATLAS_HAVE_FORTRAN --- CMakeLists.txt | 2 +- src/atlas/array/Table.cc | 3 ++- src/atlas/array/TableView.h | 6 +++--- src/atlas/array/gridtools/GridToolsIndexView.h | 2 +- src/atlas/array/native/NativeIndexView.h | 4 ++-- src/atlas/functionspace/EdgeColumns.cc | 2 +- src/atlas/functionspace/NodeColumns.cc | 2 +- src/atlas/library/Library.cc | 4 ++-- src/atlas/library/defines.h.in | 8 ++------ src/atlas/mesh/Connectivity.cc | 3 ++- src/atlas/mesh/Connectivity.h | 4 ++-- src/atlas/mesh/HybridElements.cc | 2 +- src/atlas/runtime/Log.h | 4 ++-- src/tests/array/test_table.cc | 3 ++- src/tests/mesh/CMakeLists.txt | 2 +- src/tests/mesh/test_connectivity.cc | 3 ++- src/tests/util/test_indexview.cc | 3 ++- 17 files changed, 29 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d7126c4fe..b4007827d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,7 +113,7 @@ ecbuild_add_option( FEATURE TESSELATION DESCRIPTION "Support for unstructured mesh generation" REQUIRED_PACKAGES "CGAL QUIET" "Boost 1.45.0" ) -if( HAVE_TESSELATION ) +if( ATLAS_HAVE_TESSELATION ) list( APPEND CGAL_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ) if ( TARGET CGAL::CGAL ) list( APPEND CGAL_LIBRARIES CGAL::CGAL ${CGAL_3RD_PARTY_LIBRARIES} ${GMP_LIBRARIES} ${MPFR_LIBRARIES} ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY} ) diff --git a/src/atlas/array/Table.cc b/src/atlas/array/Table.cc index 6d76807c5..07f806008 100644 --- a/src/atlas/array/Table.cc +++ b/src/atlas/array/Table.cc @@ -13,8 +13,9 @@ #include "atlas/array.h" #include "atlas/array/DataType.h" #include "atlas/runtime/ErrorHandling.h" +#include "atlas/library/defines.h" -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 #define TO_FORTRAN +1 #else diff --git a/src/atlas/array/TableView.h b/src/atlas/array/TableView.h index 87a7bff95..4ad5b08cb 100644 --- a/src/atlas/array/TableView.h +++ b/src/atlas/array/TableView.h @@ -30,7 +30,7 @@ namespace array { // -------------------------------------------------------------------------- -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define INDEX_REF Index #define FROM_FORTRAN -1 #define TO_FORTRAN +1 @@ -99,7 +99,7 @@ class TableIndex { template class TableRow { -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN typedef detail::TableIndex Index; #else typedef idx_t Index; @@ -139,7 +139,7 @@ class TableRow { template class TableView : public eckit::Owned { -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN using Index = typename std::conditional::type; #else using Index = idx_t; diff --git a/src/atlas/array/gridtools/GridToolsIndexView.h b/src/atlas/array/gridtools/GridToolsIndexView.h index f2fb40834..5c198355a 100644 --- a/src/atlas/array/gridtools/GridToolsIndexView.h +++ b/src/atlas/array/gridtools/GridToolsIndexView.h @@ -83,7 +83,7 @@ template class IndexView { public: // -- Type definitions -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN typedef detail::FortranIndex Index; #define INDEX_REF Index #define FROM_FORTRAN -1 diff --git a/src/atlas/array/native/NativeIndexView.h b/src/atlas/array/native/NativeIndexView.h index ae071b413..8896e80fe 100644 --- a/src/atlas/array/native/NativeIndexView.h +++ b/src/atlas/array/native/NativeIndexView.h @@ -95,7 +95,7 @@ class FortranIndex { } // namespace detail -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define INDEX_REF Index #define FROM_FORTRAN -1 #define TO_FORTRAN +1 @@ -112,7 +112,7 @@ class IndexView { public: using value_type = typename remove_const::type; -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN typedef detail::FortranIndex Index; #else typedef Value& Index; diff --git a/src/atlas/functionspace/EdgeColumns.cc b/src/atlas/functionspace/EdgeColumns.cc index 60fefaa5f..8c35306e9 100644 --- a/src/atlas/functionspace/EdgeColumns.cc +++ b/src/atlas/functionspace/EdgeColumns.cc @@ -32,7 +32,7 @@ #include "atlas/runtime/Trace.h" #include "atlas/util/detail/Cache.h" -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define REMOTE_IDX_BASE 1 #else #define REMOTE_IDX_BASE 0 diff --git a/src/atlas/functionspace/NodeColumns.cc b/src/atlas/functionspace/NodeColumns.cc index 23b1711c6..8ffff7276 100644 --- a/src/atlas/functionspace/NodeColumns.cc +++ b/src/atlas/functionspace/NodeColumns.cc @@ -37,7 +37,7 @@ #undef atlas_omp_critical_ordered #define atlas_omp_critical_ordered atlas_omp_critical -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define REMOTE_IDX_BASE 1 #else #define REMOTE_IDX_BASE 0 diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 481369d3c..c8a3ed583 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -223,7 +223,7 @@ void Library::Information::print( std::ostream& out ) const { bool feature_Tesselation( false ); bool feature_BoundsChecking( false ); bool feature_MPI( false ); -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN feature_fortran = true; #endif #ifdef ECKIT_HAVE_MPI @@ -235,7 +235,7 @@ void Library::Information::print( std::ostream& out ) const { #ifdef ATLAS_HAVE_TRANS feature_Trans = true; #endif -#ifdef ATLAS_HAVE_TESSELATION +#if ATLAS_HAVE_TESSELATION feature_Tesselation = true; #endif #ifdef ATLAS_HAVE_BOUNDSCHECKING diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index fffbf0024..a93751fe5 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -7,13 +7,9 @@ #define ATLAS_HAVE_OMP @ATLAS_HAVE_OMP@ -#if @ATLAS_HAVE_TESSELATION@ -#define ATLAS_HAVE_TESSELATION -#endif +#define ATLAS_HAVE_TESSELATION @ATLAS_HAVE_TESSELATION@ -#if @ATLAS_HAVE_FORTRAN@ -#define ATLAS_HAVE_FORTRAN -#endif +#define ATLAS_HAVE_FORTRAN @ATLAS_HAVE_FORTRAN@ #if @ATLAS_HAVE_TRANS@ #define ATLAS_HAVE_TRANS diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index e28b6afb9..c50687cbf 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -15,8 +15,9 @@ #include "atlas/array/MakeView.h" #include "atlas/array/Vector.h" #include "atlas/runtime/ErrorHandling.h" +#include "atlas/library/defines.h" -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 #define TO_FORTRAN +1 #else diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 0e3a8fe49..2c47ba6c2 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -54,7 +54,7 @@ class MultiBlockConnectivityImpl; // -------------------------------------------------------------------------- -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define INDEX_REF Index #define FROM_FORTRAN -1 #define TO_FORTRAN +1 @@ -133,7 +133,7 @@ class ConnectivityIndex { } // namespace detail class ConnectivityRow { -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN typedef detail::ConnectivityIndex Index; #else typedef idx_t Index; diff --git a/src/atlas/mesh/HybridElements.cc b/src/atlas/mesh/HybridElements.cc index 8b657d101..26432a4b4 100644 --- a/src/atlas/mesh/HybridElements.cc +++ b/src/atlas/mesh/HybridElements.cc @@ -21,7 +21,7 @@ #include "eckit/log/Bytes.h" #include "eckit/memory/SharedPtr.h" -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 #define TO_FORTRAN +1 #else diff --git a/src/atlas/runtime/Log.h b/src/atlas/runtime/Log.h index 9fc10bc10..82271b290 100644 --- a/src/atlas/runtime/Log.h +++ b/src/atlas/runtime/Log.h @@ -4,7 +4,7 @@ #include "atlas/library/Library.h" -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #include "fckit/Log.h" namespace atlas { namespace detail { @@ -30,7 +30,7 @@ class Log : public detail::LogBase { static Channel& trace() { return atlas::Library::instance().traceChannel(); } static Channel& debug() { return atlas::Library::instance().debugChannel(); } -#ifndef ATLAS_HAVE_FORTRAN +#if ! ATLAS_HAVE_FORTRAN // Stubs for what fckit::Log provides enum Style { diff --git a/src/tests/array/test_table.cc b/src/tests/array/test_table.cc index 34f98386a..4f5b81f16 100644 --- a/src/tests/array/test_table.cc +++ b/src/tests/array/test_table.cc @@ -10,6 +10,7 @@ #include "atlas/array/Table.h" #include "atlas/runtime/Log.h" +#include "atlas/library/defines.h" #include "tests/AtlasTestEnvironment.h" using namespace atlas::array; @@ -19,7 +20,7 @@ namespace test { //----------------------------------------------------------------------------- -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define IN_FORTRAN -1 #else #define IN_FORTRAN diff --git a/src/tests/mesh/CMakeLists.txt b/src/tests/mesh/CMakeLists.txt index 1cc52172c..06d17807d 100644 --- a/src/tests/mesh/CMakeLists.txt +++ b/src/tests/mesh/CMakeLists.txt @@ -60,7 +60,7 @@ ecbuild_add_test( TARGET atlas_test_distmesh ecbuild_add_test( TARGET atlas_test_cgal_mesh_gen_from_points SOURCES test_cgal_mesh_gen_from_points.cc - CONDITION HAVE_TESSELATION + CONDITION ATLAS_HAVE_TESSELATION LIBS atlas ) diff --git a/src/tests/mesh/test_connectivity.cc b/src/tests/mesh/test_connectivity.cc index 756b6da0b..3cb6b5661 100644 --- a/src/tests/mesh/test_connectivity.cc +++ b/src/tests/mesh/test_connectivity.cc @@ -11,6 +11,7 @@ #include "atlas/mesh/Connectivity.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" +#include "atlas/library/defines.h" #include "tests/AtlasTestEnvironment.h" using namespace atlas::mesh; @@ -20,7 +21,7 @@ namespace test { //----------------------------------------------------------------------------- -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 #define INDEX_REF Index #define FROM_FORTRAN -1 diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index 62fd5fca4..b7d7fc3f2 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -13,9 +13,10 @@ #include "atlas/array/IndexView.h" #include "atlas/array/MakeView.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/library/defines.h" #include "tests/AtlasTestEnvironment.h" -#ifdef ATLAS_HAVE_FORTRAN +#if ATLAS_HAVE_FORTRAN #define IN_FORTRAN #else #define IN_FORTRAN -1 From 2ffd6a5af56efcbfaf20c8b08ff19f056358abe0 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 16:05:37 +0000 Subject: [PATCH 350/355] Change #ifdef ATLAS_HAVE_EIGEN to #if ATLAS_HAVE_EIGEN --- src/atlas/interpolation/Vector2D.h | 4 ++-- src/atlas/interpolation/Vector3D.h | 4 ++-- src/atlas/library/defines.h.in | 4 +--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/atlas/interpolation/Vector2D.h b/src/atlas/interpolation/Vector2D.h index 06c698bd2..5d20215a5 100644 --- a/src/atlas/interpolation/Vector2D.h +++ b/src/atlas/interpolation/Vector2D.h @@ -15,7 +15,7 @@ #include "atlas/library/config.h" -#ifdef ATLAS_HAVE_EIGEN +#if ATLAS_HAVE_EIGEN #define EIGEN_NO_AUTOMATIC_RESIZING //#define EIGEN_DONT_ALIGN @@ -31,7 +31,7 @@ namespace interpolation { //---------------------------------------------------------------------------------------------------------------------- -#ifdef ATLAS_HAVE_EIGEN +#if ATLAS_HAVE_EIGEN typedef Eigen::Vector2d Vector2D; diff --git a/src/atlas/interpolation/Vector3D.h b/src/atlas/interpolation/Vector3D.h index 556826665..2dc1594ee 100644 --- a/src/atlas/interpolation/Vector3D.h +++ b/src/atlas/interpolation/Vector3D.h @@ -15,7 +15,7 @@ #include "atlas/library/config.h" -#ifdef ATLAS_HAVE_EIGEN +#if ATLAS_HAVE_EIGEN #define EIGEN_NO_AUTOMATIC_RESIZING //#define EIGEN_DONT_ALIGN @@ -31,7 +31,7 @@ namespace interpolation { //---------------------------------------------------------------------------------------------------------------------- -#ifdef ATLAS_HAVE_EIGEN +#if ATLAS_HAVE_EIGEN typedef Eigen::Vector3d Vector3D; diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index a93751fe5..9705f2588 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -15,9 +15,7 @@ #define ATLAS_HAVE_TRANS #endif -#if @ATLAS_HAVE_EIGEN@ -#define ATLAS_HAVE_EIGEN -#endif +#define ATLAS_HAVE_EIGEN @ATLAS_HAVE_EIGEN@ #if @ATLAS_HAVE_GRIDTOOLS_STORAGE@ #define ATLAS_HAVE_GRIDTOOLS_STORAGE From 49fb061fe8bf73ffb373846084edc40b411c43a8 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 17:25:12 +0000 Subject: [PATCH 351/355] Change more ifdefs and cleanup include order --- src/atlas/array/Array.h | 4 +- src/atlas/array/ArraySpec.cc | 4 +- src/atlas/array/ArrayUtil.cc | 4 +- src/atlas/array/ArrayUtil.h | 1 + src/atlas/array/ArrayView.h | 2 +- src/atlas/array/ArrayViewDefs.h | 1 + src/atlas/array/ArrayViewUtil.h | 1 + src/atlas/array/DataType.h | 1 + src/atlas/array/IndexView.h | 2 +- src/atlas/array/LocalView.cc | 5 ++- src/atlas/array/LocalView.h | 1 + src/atlas/array/SVector.h | 4 +- src/atlas/array/Table.h | 3 +- src/atlas/array/TableView.h | 1 + src/atlas/array/Vector.h | 4 +- .../array/gridtools/GridToolsArrayHelpers.h | 4 +- .../array/gridtools/GridToolsArrayView.h | 1 + .../array/gridtools/GridToolsMakeView.cc | 2 +- src/atlas/array/gridtools/GridToolsTraits.h | 5 ++- src/atlas/array/helpers/ArrayInitializer.h | 4 +- src/atlas/array/native/NativeArray.cc | 2 +- src/atlas/array/native/NativeArrayView.cc | 4 +- src/atlas/array/native/NativeArrayView.h | 1 + src/atlas/array/native/NativeIndexView.cc | 3 +- src/atlas/array/native/NativeIndexView.h | 1 + src/atlas/array/native/NativeMakeView.cc | 2 - src/atlas/array_fwd.h | 1 + src/atlas/domain/Domain.cc | 1 - src/atlas/domain/Domain.h | 4 +- src/atlas/domain/detail/Domain.cc | 3 +- src/atlas/domain/detail/Domain.h | 5 ++- src/atlas/domain/detail/RectangularDomain.cc | 3 +- src/atlas/domain/detail/RectangularDomain.h | 1 + src/atlas/domain/detail/ZonalBandDomain.h | 1 + src/atlas/field/FieldCreator.cc | 11 ++++-- src/atlas/field/FieldCreator.h | 4 +- src/atlas/field/FieldCreatorArraySpec.cc | 7 +++- src/atlas/field/FieldCreatorArraySpec.h | 5 +-- src/atlas/field/FieldCreatorIFS.cc | 7 +++- src/atlas/field/FieldCreatorIFS.h | 5 +-- src/atlas/field/FieldSet.h | 3 +- src/atlas/field/State.cc | 7 +++- src/atlas/field/State.h | 5 +-- src/atlas/field/detail/FieldImpl.cc | 7 ++-- src/atlas/field/detail/FieldImpl.h | 4 +- src/atlas/functionspace/EdgeColumns.h | 3 +- src/atlas/functionspace/FunctionSpace.cc | 7 +++- src/atlas/functionspace/FunctionSpace.h | 6 ++- src/atlas/functionspace/NodeColumns.h | 3 +- src/atlas/functionspace/Spectral.cc | 19 ++++----- src/atlas/functionspace/StructuredColumns.cc | 5 +-- src/atlas/functionspace/StructuredColumns.h | 1 + src/atlas/grid/Distribution.cc | 3 +- src/atlas/grid/Distribution.h | 4 +- src/atlas/grid/Grid.cc | 1 + src/atlas/grid/Grid.h | 4 +- src/atlas/grid/Partitioner.h | 3 +- src/atlas/grid/Spacing.cc | 10 +++++ src/atlas/grid/Spacing.h | 13 ++++++- src/atlas/grid/detail/grid/Grid.h | 6 ++- src/atlas/grid/detail/grid/Structured.cc | 4 +- src/atlas/grid/detail/grid/Structured.h | 4 +- src/atlas/grid/detail/grid/Unstructured.cc | 4 +- src/atlas/grid/detail/grid/Unstructured.h | 4 +- .../partitioner/CheckerboardPartitioner.cc | 2 + .../partitioner/CheckerboardPartitioner.h | 1 + .../partitioner/EqualRegionsPartitioner.cc | 2 + .../partitioner/EqualRegionsPartitioner.h | 1 + .../partitioner/MatchingMeshPartitioner.h | 4 +- .../MatchingMeshPartitionerBruteForce.cc | 8 ++-- .../MatchingMeshPartitionerLonLatPolygon.cc | 6 ++- ...MatchingMeshPartitionerSphericalPolygon.cc | 4 +- .../grid/detail/partitioner/Partitioner.cc | 16 +++++--- .../grid/detail/partitioner/Partitioner.h | 3 +- .../detail/partitioner/TransPartitioner.cc | 3 +- .../grid/detail/spacing/CustomSpacing.cc | 12 ++++++ src/atlas/grid/detail/spacing/CustomSpacing.h | 11 ++++++ src/atlas/grid/detail/spacing/FocusSpacing.cc | 14 ++++++- src/atlas/grid/detail/spacing/FocusSpacing.h | 15 +++++-- .../grid/detail/spacing/GaussianSpacing.cc | 15 ++++++- .../grid/detail/spacing/GaussianSpacing.h | 15 +++++-- .../grid/detail/spacing/LinearSpacing.cc | 12 ++++++ src/atlas/grid/detail/spacing/LinearSpacing.h | 11 ++++++ src/atlas/grid/detail/spacing/Spacing.cc | 12 +++++- src/atlas/grid/detail/spacing/Spacing.h | 14 ++++++- .../grid/detail/spacing/gaussian/Latitudes.cc | 3 +- .../grid/detail/spacing/gaussian/Latitudes.h | 5 +-- src/atlas/grid/detail/spacing/gaussian/N.h | 5 +-- src/atlas/interpolation/Interpolation.cc | 4 +- src/atlas/interpolation/Interpolation.h | 3 +- src/atlas/interpolation/element/Quad3D.h | 4 +- src/atlas/interpolation/element/Triag3D.cc | 3 +- src/atlas/interpolation/element/Triag3D.h | 5 +-- .../interpolation/method/FiniteElement.h | 6 ++- src/atlas/interpolation/method/Intersect.h | 5 +-- .../method/KNearestNeighbours.cc | 5 ++- .../method/KNearestNeighboursBase.cc | 4 +- .../method/KNearestNeighboursBase.h | 3 +- src/atlas/interpolation/method/Method.cc | 10 +++-- src/atlas/interpolation/method/Method.h | 1 + .../interpolation/method/NearestNeighbour.cc | 4 +- src/atlas/interpolation/method/PointIndex3.cc | 4 +- src/atlas/interpolation/method/PointIndex3.h | 7 ++-- src/atlas/interpolation/method/PointSet.cc | 4 +- src/atlas/library/Library.cc | 39 ++++++------------- src/atlas/library/Library.h | 1 + src/atlas/library/config.h | 4 +- src/atlas/library/defines.h.in | 31 +++++---------- src/atlas/mesh/Connectivity.cc | 3 +- src/atlas/mesh/Connectivity.h | 4 +- src/atlas/mesh/Elements.h | 3 +- src/atlas/mesh/Halo.cc | 3 +- src/atlas/mesh/HybridElements.cc | 8 ++-- src/atlas/mesh/HybridElements.h | 5 ++- src/atlas/mesh/Mesh.h | 3 +- src/atlas/mesh/Nodes.h | 8 ++-- src/atlas/mesh/PartitionPolygon.cc | 9 ----- src/atlas/mesh/PartitionPolygon.h | 4 +- src/atlas/mesh/actions/BuildCellCentres.cc | 6 ++- src/atlas/mesh/actions/BuildConvexHull3D.h | 5 +-- src/atlas/mesh/actions/BuildHalo.h | 6 +-- src/atlas/mesh/actions/BuildParallelFields.cc | 7 +++- src/atlas/mesh/actions/BuildParallelFields.h | 5 +-- .../mesh/actions/BuildPeriodicBoundaries.h | 5 +-- src/atlas/mesh/actions/BuildStatistics.cc | 4 +- src/atlas/mesh/actions/BuildStatistics.h | 5 +-- src/atlas/mesh/actions/BuildTorusXYZField.h | 5 +-- src/atlas/mesh/actions/ExtendNodesGlobal.cc | 4 +- .../mesh/actions/WriteLoadBalanceReport.cc | 2 +- .../mesh/actions/WriteLoadBalanceReport.h | 5 +-- src/atlas/mesh/detail/AccumulateFacets.cc | 3 +- src/atlas/mesh/detail/AccumulateFacets.h | 1 + src/atlas/mesh/detail/MeshImpl.cc | 2 +- .../meshgenerator/DelaunayMeshGenerator.cc | 3 +- .../meshgenerator/RegularMeshGenerator.cc | 6 ++- src/atlas/numerics/Method.cc | 3 +- src/atlas/numerics/Method.h | 1 + src/atlas/numerics/Nabla.cc | 10 +++-- src/atlas/numerics/fvm/Method.cc | 6 ++- src/atlas/numerics/fvm/Method.h | 1 + src/atlas/numerics/fvm/Nabla.cc | 5 ++- src/atlas/numerics/fvm/Nabla.h | 1 + src/atlas/output/Gmsh.cc | 3 +- src/atlas/output/Output.cc | 7 ++-- src/atlas/output/Output.h | 4 +- src/atlas/output/detail/GmshIO.cc | 20 +++++----- src/atlas/output/detail/GmshIO.h | 1 + src/atlas/output/detail/PointCloudIO.cc | 8 ++-- src/atlas/output/detail/PointCloudIO.h | 1 + src/atlas/parallel/Checksum.cc | 3 +- src/atlas/parallel/Checksum.h | 13 +++---- src/atlas/parallel/GatherScatter.cc | 3 +- src/atlas/parallel/GatherScatter.h | 7 +--- src/atlas/parallel/HaloExchange.cc | 3 +- src/atlas/parallel/HaloExchange.h | 5 +-- src/atlas/parallel/HaloExchangeCUDA.h | 5 ++- src/atlas/parallel/HaloExchangeImpl.h | 5 ++- src/atlas/parallel/mpi/Statistics.h | 1 + src/atlas/parallel/mpi/mpi.h | 3 +- src/atlas/projection/Projection.cc | 10 +++++ src/atlas/projection/Projection.h | 11 ++++++ .../projection/detail/LambertProjection.cc | 13 ++++++- .../projection/detail/LambertProjection.h | 10 +++++ .../projection/detail/LonLatProjection.cc | 10 +++++ .../projection/detail/LonLatProjection.h | 10 +++++ .../projection/detail/MercatorProjection.cc | 13 ++++++- .../projection/detail/MercatorProjection.h | 10 +++++ src/atlas/projection/detail/ProjectionImpl.cc | 10 +++++ src/atlas/projection/detail/ProjectionImpl.h | 18 +++++++-- .../projection/detail/SchmidtProjection.cc | 13 ++++++- .../projection/detail/SchmidtProjection.h | 10 +++++ src/atlas/runtime/AtlasTool.cc | 14 ++++++- src/atlas/runtime/ErrorHandling.cc | 7 ++-- src/atlas/runtime/Log.cc | 3 +- src/atlas/runtime/Log.h | 1 - src/atlas/runtime/trace/Barriers.cc | 2 + src/atlas/runtime/trace/Barriers.h | 1 + src/atlas/runtime/trace/CallStack.cc | 3 +- src/atlas/runtime/trace/Logging.cc | 4 +- src/atlas/runtime/trace/Nesting.h | 3 +- src/atlas/runtime/trace/Timings.cc | 9 +++-- src/atlas/runtime/trace/TraceT.h | 1 + src/atlas/trans/Trans.cc | 6 ++- src/atlas/trans/VorDivToUV.cc | 6 ++- src/atlas/trans/ifs/TransIFS.cc | 4 +- src/atlas/trans/ifs/TransIFS.h | 6 ++- src/atlas/trans/ifs/TransIFSNodeColumns.cc | 1 - .../trans/ifs/TransIFSStructuredColumns.cc | 1 - src/atlas/trans/ifs/VorDivToUVIFS.cc | 1 - src/atlas/trans/ifs/VorDivToUVIFS.h | 3 +- src/atlas/trans/local/FourierTransforms.cc | 3 +- src/atlas/trans/local/LegendrePolynomials.cc | 3 +- src/atlas/trans/local/LegendreTransforms.cc | 3 +- src/atlas/trans/local/TransLocal.cc | 1 - src/atlas/trans/local/TransLocal.h | 1 + src/atlas/trans/local/VorDivToUVLocal.cc | 1 - src/atlas/util/Checksum.cc | 3 +- src/atlas/util/Config.cc | 10 +++-- src/atlas/util/Config.h | 10 ++--- src/atlas/util/Earth.cc | 8 ++-- src/atlas/util/GaussianLatitudes.h | 1 + src/atlas/util/LonLatPolygon.cc | 3 +- src/atlas/util/LonLatPolygon.h | 1 + src/atlas/util/Metadata.cc | 3 +- src/atlas/util/Metadata.h | 3 +- src/atlas/util/Point.h | 4 +- src/atlas/util/Polygon.cc | 9 +++-- src/atlas/util/Polygon.h | 1 + src/atlas/util/Rotation.cc | 7 ++-- src/atlas/util/Rotation.h | 1 + src/atlas/util/SphericalPolygon.cc | 7 ++-- src/atlas/util/SphericalPolygon.h | 1 + src/atlas/util/detail/Cache.h | 4 +- src/atlas/util/detail/Debug.h | 3 +- src/atlas_acc_support/atlas_acc_map_data.h | 10 +++++ src/atlas_f/atlas_f.h.in | 13 ++----- src/atlas_f/trans/atlas_Trans_module.F90 | 38 +++++++++--------- src/tests/array/test_array.cc | 19 ++++----- src/tests/array/test_array_slicer.cc | 4 +- src/tests/array/test_array_view_util.cc | 1 + src/tests/array/test_svector.cc | 1 + src/tests/functionspace/test_functionspace.cc | 8 ++-- src/tests/functionspace/test_pointcloud.cc | 1 - .../functionspace/test_structuredcolumns.cc | 5 ++- src/tests/grid/test_domain.cc | 1 + src/tests/grid/test_field.cc | 2 +- src/tests/grid/test_grid_ptr.cc | 1 - src/tests/grid/test_grids.cc | 7 ++-- src/tests/grid/test_rotation.cc | 4 +- src/tests/grid/test_state.cc | 3 +- src/tests/interpolation/test_Quad3D.cc | 3 +- .../test_interpolation_finite_element.cc | 2 +- src/tests/io/test_gmsh.cc | 2 +- src/tests/io/test_pointcloud_io.cc | 5 +-- src/tests/mesh/test_accumulate_facets.cc | 2 - src/tests/mesh/test_connectivity.cc | 1 + src/tests/mesh/test_distmesh.cc | 5 ++- src/tests/mesh/test_elements.cc | 4 +- src/tests/mesh/test_halo.cc | 5 ++- src/tests/mesh/test_rgg.cc | 3 +- src/tests/trans/test_trans.cc | 7 ++-- src/tests/trans/test_trans_invtrans_grad.cc | 2 +- src/tests/trans/test_transgeneral.cc | 30 ++++++++------ src/tests/util/test_earth.cc | 1 + src/tests/util/test_flags.cc | 1 + src/tests/util/test_footprint.cc | 3 +- src/tests/util/test_indexview.cc | 3 +- src/tests/util/test_polygon.cc | 1 + 248 files changed, 865 insertions(+), 477 deletions(-) diff --git a/src/atlas/array/Array.h b/src/atlas/array/Array.h index ba7309c97..c56f8e37f 100644 --- a/src/atlas/array/Array.h +++ b/src/atlas/array/Array.h @@ -11,11 +11,13 @@ #pragma once #include + +#include "eckit/memory/Owned.h" + #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" #include "atlas/array_fwd.h" #include "atlas/library/config.h" -#include "eckit/memory/Owned.h" namespace atlas { namespace array { diff --git a/src/atlas/array/ArraySpec.cc b/src/atlas/array/ArraySpec.cc index 4845777b2..8d4c2174b 100644 --- a/src/atlas/array/ArraySpec.cc +++ b/src/atlas/array/ArraySpec.cc @@ -9,9 +9,11 @@ */ #include -#include "atlas/array/ArrayUtil.h" + #include "eckit/exception/Exceptions.h" +#include "atlas/array/ArrayUtil.h" + namespace atlas { namespace array { diff --git a/src/atlas/array/ArrayUtil.cc b/src/atlas/array/ArrayUtil.cc index eac20c46f..0fedb760d 100644 --- a/src/atlas/array/ArrayUtil.cc +++ b/src/atlas/array/ArrayUtil.cc @@ -8,10 +8,12 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/array/ArrayUtil.h" #include + #include "eckit/exception/Exceptions.h" +#include "atlas/array/ArrayUtil.h" + namespace atlas { namespace array { diff --git a/src/atlas/array/ArrayUtil.h b/src/atlas/array/ArrayUtil.h index b80b76ef5..85ae42beb 100644 --- a/src/atlas/array/ArrayUtil.h +++ b/src/atlas/array/ArrayUtil.h @@ -11,6 +11,7 @@ #pragma once #include + #include "atlas/array/ArrayIdx.h" #include "atlas/array/ArrayLayout.h" #include "atlas/array/ArrayShape.h" diff --git a/src/atlas/array/ArrayView.h b/src/atlas/array/ArrayView.h index a5ff11565..a09df34aa 100644 --- a/src/atlas/array/ArrayView.h +++ b/src/atlas/array/ArrayView.h @@ -51,7 +51,7 @@ #include "atlas/library/config.h" -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE #include "atlas/array/gridtools/GridToolsArrayView.h" #else #include "atlas/array/native/NativeArrayView.h" diff --git a/src/atlas/array/ArrayViewDefs.h b/src/atlas/array/ArrayViewDefs.h index cde447098..bf0fcfdaa 100644 --- a/src/atlas/array/ArrayViewDefs.h +++ b/src/atlas/array/ArrayViewDefs.h @@ -9,6 +9,7 @@ */ #pragma once + #include namespace atlas { diff --git a/src/atlas/array/ArrayViewUtil.h b/src/atlas/array/ArrayViewUtil.h index da98d9f58..b8b27d5db 100644 --- a/src/atlas/array/ArrayViewUtil.h +++ b/src/atlas/array/ArrayViewUtil.h @@ -8,6 +8,7 @@ * nor does it submit to any jurisdiction. */ #pragma once + #include "atlas/array/ArrayView.h" namespace atlas { diff --git a/src/atlas/array/DataType.h b/src/atlas/array/DataType.h index d765a9aa9..40f9cfeb2 100644 --- a/src/atlas/array/DataType.h +++ b/src/atlas/array/DataType.h @@ -12,6 +12,7 @@ #include #include + #include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/array/IndexView.h b/src/atlas/array/IndexView.h index 7e095913e..71daae95e 100644 --- a/src/atlas/array/IndexView.h +++ b/src/atlas/array/IndexView.h @@ -38,7 +38,7 @@ #pragma once #include "atlas/library/config.h" -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE #include "atlas/array/gridtools/GridToolsIndexView.h" #else #include "atlas/array/native/NativeIndexView.h" diff --git a/src/atlas/array/LocalView.cc b/src/atlas/array/LocalView.cc index cd0025f1d..b7cd0d806 100644 --- a/src/atlas/array/LocalView.cc +++ b/src/atlas/array/LocalView.cc @@ -9,10 +9,13 @@ */ #include "atlas/array/LocalView.h" + #include -#include "atlas/array/helpers/ArrayAssigner.h" + #include "eckit/exception/Exceptions.h" +#include "atlas/array/helpers/ArrayAssigner.h" + //------------------------------------------------------------------------------------------------------ namespace atlas { diff --git a/src/atlas/array/LocalView.h b/src/atlas/array/LocalView.h index fd279c8fd..12144f654 100644 --- a/src/atlas/array/LocalView.h +++ b/src/atlas/array/LocalView.h @@ -44,6 +44,7 @@ #include #include + #include "atlas/array/ArrayUtil.h" #include "atlas/array/ArrayViewDefs.h" #include "atlas/array/helpers/ArraySlicer.h" diff --git a/src/atlas/array/SVector.h b/src/atlas/array/SVector.h index 01e71d6b3..806d373d9 100644 --- a/src/atlas/array/SVector.h +++ b/src/atlas/array/SVector.h @@ -14,14 +14,12 @@ #include #include "atlas/library/config.h" +#include "atlas/runtime/ErrorHandling.h" #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA #include #endif -#include "atlas/library/config.h" -#include "atlas/runtime/ErrorHandling.h" - namespace atlas { namespace array { diff --git a/src/atlas/array/Table.h b/src/atlas/array/Table.h index 215eccb05..f4a257bc9 100644 --- a/src/atlas/array/Table.h +++ b/src/atlas/array/Table.h @@ -19,9 +19,10 @@ #include #include +#include "eckit/memory/Owned.h" + #include "atlas/array.h" #include "atlas/library/config.h" -#include "eckit/memory/Owned.h" namespace atlas { namespace array { diff --git a/src/atlas/array/TableView.h b/src/atlas/array/TableView.h index 4ad5b08cb..8b4a4bb55 100644 --- a/src/atlas/array/TableView.h +++ b/src/atlas/array/TableView.h @@ -22,6 +22,7 @@ #pragma once #include + #include "atlas/array/Table.h" #include "atlas/library/config.h" diff --git a/src/atlas/array/Vector.h b/src/atlas/array/Vector.h index 94953ebad..5c785509f 100644 --- a/src/atlas/array/Vector.h +++ b/src/atlas/array/Vector.h @@ -14,14 +14,12 @@ #include #include "atlas/library/config.h" +#include "atlas/runtime/ErrorHandling.h" #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA #include #endif -#include "atlas/library/config.h" -#include "atlas/runtime/ErrorHandling.h" - namespace atlas { namespace array { diff --git a/src/atlas/array/gridtools/GridToolsArrayHelpers.h b/src/atlas/array/gridtools/GridToolsArrayHelpers.h index 462ab4d15..68ad92d9e 100644 --- a/src/atlas/array/gridtools/GridToolsArrayHelpers.h +++ b/src/atlas/array/gridtools/GridToolsArrayHelpers.h @@ -14,6 +14,9 @@ #include #include #include + +#include "eckit/exception/Exceptions.h" + #include "atlas/array.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" @@ -21,7 +24,6 @@ #include "atlas/array_fwd.h" #include "atlas/library/config.h" #include "atlas/runtime/Log.h" -#include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------ diff --git a/src/atlas/array/gridtools/GridToolsArrayView.h b/src/atlas/array/gridtools/GridToolsArrayView.h index f1eb1f5f8..22508d9de 100644 --- a/src/atlas/array/gridtools/GridToolsArrayView.h +++ b/src/atlas/array/gridtools/GridToolsArrayView.h @@ -13,6 +13,7 @@ #include #include #include + #include "atlas/array/ArrayUtil.h" #include "atlas/array/ArrayViewDefs.h" #include "atlas/array/LocalView.h" diff --git a/src/atlas/array/gridtools/GridToolsMakeView.cc b/src/atlas/array/gridtools/GridToolsMakeView.cc index d63a726bd..c875af7cf 100644 --- a/src/atlas/array/gridtools/GridToolsMakeView.cc +++ b/src/atlas/array/gridtools/GridToolsMakeView.cc @@ -6,7 +6,7 @@ #include "atlas/array/IndexView.h" #include "atlas/library/config.h" -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE #include "atlas/array/gridtools/GridToolsTraits.h" #endif //------------------------------------------------------------------------------ diff --git a/src/atlas/array/gridtools/GridToolsTraits.h b/src/atlas/array/gridtools/GridToolsTraits.h index b7033573d..41322851c 100644 --- a/src/atlas/array/gridtools/GridToolsTraits.h +++ b/src/atlas/array/gridtools/GridToolsTraits.h @@ -1,10 +1,11 @@ #pragma once -#include "atlas/array/ArrayViewDefs.h" -#include "atlas/library/config.h" #include "gridtools/common/generic_metafunctions/all_integrals.hpp" #include "gridtools/storage/storage-facility.hpp" +#include "atlas/array/ArrayViewDefs.h" +#include "atlas/library/config.h" + //------------------------------------------------------------------------------ namespace atlas { diff --git a/src/atlas/array/helpers/ArrayInitializer.h b/src/atlas/array/helpers/ArrayInitializer.h index 56791aef6..ab909d060 100644 --- a/src/atlas/array/helpers/ArrayInitializer.h +++ b/src/atlas/array/helpers/ArrayInitializer.h @@ -11,10 +11,12 @@ #pragma once #include + +#include "eckit/exception/Exceptions.h" + #include "atlas/array.h" #include "atlas/array/DataType.h" #include "atlas/array_fwd.h" -#include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------ diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index 0b7be6b56..cc0526691 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -1,9 +1,9 @@ #include + #include "atlas/array.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/MakeView.h" #include "atlas/array/native/NativeDataStore.h" - #include "atlas/array/helpers/ArrayInitializer.h" #include "atlas/array/helpers/ArrayWriter.h" diff --git a/src/atlas/array/native/NativeArrayView.cc b/src/atlas/array/native/NativeArrayView.cc index f21c5d923..a9ca0b695 100644 --- a/src/atlas/array/native/NativeArrayView.cc +++ b/src/atlas/array/native/NativeArrayView.cc @@ -9,10 +9,12 @@ */ #include + +#include "eckit/exception/Exceptions.h" + #include "atlas/array/ArrayView.h" #include "atlas/array/helpers/ArrayAssigner.h" #include "atlas/array/helpers/ArrayWriter.h" -#include "eckit/exception/Exceptions.h" //------------------------------------------------------------------------------------------------------ diff --git a/src/atlas/array/native/NativeArrayView.h b/src/atlas/array/native/NativeArrayView.h index 3bcefb9ba..a5edb9ba4 100644 --- a/src/atlas/array/native/NativeArrayView.h +++ b/src/atlas/array/native/NativeArrayView.h @@ -53,6 +53,7 @@ #include #include #include + #include "atlas/array/ArrayUtil.h" #include "atlas/array/ArrayViewDefs.h" #include "atlas/array/LocalView.h" diff --git a/src/atlas/array/native/NativeIndexView.cc b/src/atlas/array/native/NativeIndexView.cc index a7d2e1d70..9fc7457da 100644 --- a/src/atlas/array/native/NativeIndexView.cc +++ b/src/atlas/array/native/NativeIndexView.cc @@ -8,9 +8,10 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/array/native/NativeIndexView.h" #include +#include "atlas/array/native/NativeIndexView.h" + //------------------------------------------------------------------------------------------------------ namespace atlas { diff --git a/src/atlas/array/native/NativeIndexView.h b/src/atlas/array/native/NativeIndexView.h index 8896e80fe..c170219b1 100644 --- a/src/atlas/array/native/NativeIndexView.h +++ b/src/atlas/array/native/NativeIndexView.h @@ -39,6 +39,7 @@ #pragma once #include + #include "atlas/array/ArrayUtil.h" #include "atlas/library/config.h" diff --git a/src/atlas/array/native/NativeMakeView.cc b/src/atlas/array/native/NativeMakeView.cc index 80645fab0..2221a2a18 100644 --- a/src/atlas/array/native/NativeMakeView.cc +++ b/src/atlas/array/native/NativeMakeView.cc @@ -1,9 +1,7 @@ #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" -#include "atlas/array_fwd.h" #include "atlas/library/config.h" - #include "atlas/array.h" namespace atlas { diff --git a/src/atlas/array_fwd.h b/src/atlas/array_fwd.h index 30513d004..1d14fee36 100644 --- a/src/atlas/array_fwd.h +++ b/src/atlas/array_fwd.h @@ -11,6 +11,7 @@ /// @author Willem Deconinck #pragma once + #include "atlas/array/ArrayViewDefs.h" namespace atlas { diff --git a/src/atlas/domain/Domain.cc b/src/atlas/domain/Domain.cc index fa90c102a..8f5a62861 100644 --- a/src/atlas/domain/Domain.cc +++ b/src/atlas/domain/Domain.cc @@ -9,7 +9,6 @@ */ #include "atlas/domain/Domain.h" - #include "atlas/domain/detail/Domain.h" #include "atlas/domain/detail/EmptyDomain.h" #include "atlas/domain/detail/GlobalDomain.h" diff --git a/src/atlas/domain/Domain.h b/src/atlas/domain/Domain.h index 90bc7838e..07f3550fe 100644 --- a/src/atlas/domain/Domain.h +++ b/src/atlas/domain/Domain.h @@ -11,11 +11,13 @@ #pragma once #include + +#include "eckit/memory/SharedPtr.h" + #include "atlas/domain/detail/Domain.h" #include "atlas/domain/detail/RectangularDomain.h" #include "atlas/domain/detail/ZonalBandDomain.h" #include "atlas/projection/Projection.h" -#include "eckit/memory/SharedPtr.h" //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/domain/detail/Domain.cc b/src/atlas/domain/detail/Domain.cc index 85b8e6f2f..6a36c9732 100644 --- a/src/atlas/domain/detail/Domain.cc +++ b/src/atlas/domain/detail/Domain.cc @@ -1,6 +1,7 @@ +#include "eckit/exception/Exceptions.h" + #include "atlas/domain/detail/Domain.h" #include "atlas/projection/Projection.h" -#include "eckit/exception/Exceptions.h" namespace atlas { namespace domain { diff --git a/src/atlas/domain/detail/Domain.h b/src/atlas/domain/detail/Domain.h index c579c061a..17b70b4b2 100644 --- a/src/atlas/domain/detail/Domain.h +++ b/src/atlas/domain/detail/Domain.h @@ -12,12 +12,13 @@ domain shapes (circular, frame, and what not...) #pragma once -#include "atlas/util/Config.h" -#include "atlas/util/Point.h" #include "eckit/config/Parametrisation.h" #include "eckit/memory/Builder.h" #include "eckit/memory/Owned.h" +#include "atlas/util/Config.h" +#include "atlas/util/Point.h" + namespace atlas { class Projection; diff --git a/src/atlas/domain/detail/RectangularDomain.cc b/src/atlas/domain/detail/RectangularDomain.cc index 09e6e8eb7..999204c80 100644 --- a/src/atlas/domain/detail/RectangularDomain.cc +++ b/src/atlas/domain/detail/RectangularDomain.cc @@ -1,6 +1,7 @@ -#include "atlas/domain/detail/RectangularDomain.h" #include +#include "atlas/domain/detail/RectangularDomain.h" + namespace atlas { namespace domain { diff --git a/src/atlas/domain/detail/RectangularDomain.h b/src/atlas/domain/detail/RectangularDomain.h index 85e45a857..d7450e9b2 100644 --- a/src/atlas/domain/detail/RectangularDomain.h +++ b/src/atlas/domain/detail/RectangularDomain.h @@ -2,6 +2,7 @@ #include #include + #include "atlas/domain/detail/Domain.h" namespace atlas { diff --git a/src/atlas/domain/detail/ZonalBandDomain.h b/src/atlas/domain/detail/ZonalBandDomain.h index 345134d71..f08635a9e 100644 --- a/src/atlas/domain/detail/ZonalBandDomain.h +++ b/src/atlas/domain/detail/ZonalBandDomain.h @@ -2,6 +2,7 @@ #include #include + #include "atlas/domain/Domain.h" #include "atlas/domain/detail/RectangularDomain.h" diff --git a/src/atlas/field/FieldCreator.cc b/src/atlas/field/FieldCreator.cc index b8521db1d..a263cb754 100644 --- a/src/atlas/field/FieldCreator.cc +++ b/src/atlas/field/FieldCreator.cc @@ -9,18 +9,21 @@ */ #include "atlas/field/FieldCreator.h" + #include #include #include + +#include "eckit/exception/Exceptions.h" +#include "eckit/os/BackTrace.h" +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" + #include "atlas/field/Field.h" #include "atlas/field/FieldCreatorArraySpec.h" #include "atlas/field/FieldCreatorIFS.h" #include "atlas/grid/Grid.h" #include "atlas/runtime/Log.h" -#include "eckit/exception/Exceptions.h" -#include "eckit/os/BackTrace.h" -#include "eckit/thread/AutoLock.h" -#include "eckit/thread/Mutex.h" namespace { static eckit::Mutex* local_mutex = 0; diff --git a/src/atlas/field/FieldCreator.h b/src/atlas/field/FieldCreator.h index 4ef5e4a4c..3de70e62e 100644 --- a/src/atlas/field/FieldCreator.h +++ b/src/atlas/field/FieldCreator.h @@ -15,9 +15,11 @@ #define atlas_field_FieldCreator_h #include -#include "atlas/field/Field.h" + #include "eckit/memory/Owned.h" +#include "atlas/field/Field.h" + namespace eckit { class Parametrisation; } diff --git a/src/atlas/field/FieldCreatorArraySpec.cc b/src/atlas/field/FieldCreatorArraySpec.cc index a39b786c3..044f34201 100644 --- a/src/atlas/field/FieldCreatorArraySpec.cc +++ b/src/atlas/field/FieldCreatorArraySpec.cc @@ -9,13 +9,16 @@ */ #include "atlas/field/FieldCreatorArraySpec.h" + #include #include -#include "atlas/array/DataType.h" -#include "atlas/field/detail/FieldImpl.h" + #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" +#include "atlas/array/DataType.h" +#include "atlas/field/detail/FieldImpl.h" + namespace atlas { namespace field { diff --git a/src/atlas/field/FieldCreatorArraySpec.h b/src/atlas/field/FieldCreatorArraySpec.h index 49bb00102..9b64e89da 100644 --- a/src/atlas/field/FieldCreatorArraySpec.h +++ b/src/atlas/field/FieldCreatorArraySpec.h @@ -11,8 +11,7 @@ /// @author Willem Deconinck /// @date June 2015 -#ifndef atlas_field_ArraySpec_h -#define atlas_field_ArraySpec_h +#pragma once #include "atlas/field/FieldCreator.h" @@ -53,5 +52,3 @@ class FieldCreatorArraySpec : public FieldCreator { } // namespace field } // namespace atlas - -#endif diff --git a/src/atlas/field/FieldCreatorIFS.cc b/src/atlas/field/FieldCreatorIFS.cc index 2f13f335b..5596f6289 100644 --- a/src/atlas/field/FieldCreatorIFS.cc +++ b/src/atlas/field/FieldCreatorIFS.cc @@ -9,14 +9,17 @@ */ #include "atlas/field/FieldCreatorIFS.h" + #include + +#include "eckit/config/Parametrisation.h" +#include "eckit/exception/Exceptions.h" + #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" #include "atlas/field/detail/FieldImpl.h" #include "atlas/grid/Grid.h" #include "atlas/runtime/Log.h" -#include "eckit/config/Parametrisation.h" -#include "eckit/exception/Exceptions.h" namespace atlas { namespace field { diff --git a/src/atlas/field/FieldCreatorIFS.h b/src/atlas/field/FieldCreatorIFS.h index 7866e224a..83ef0d8cb 100644 --- a/src/atlas/field/FieldCreatorIFS.h +++ b/src/atlas/field/FieldCreatorIFS.h @@ -11,8 +11,7 @@ /// @author Willem Deconinck /// @date June 2015 -#ifndef atlas_field_IFS_h -#define atlas_field_IFS_h +#pragma once #include "atlas/field/FieldCreator.h" @@ -58,5 +57,3 @@ class FieldCreatorIFS : public FieldCreator { } // namespace field } // namespace atlas - -#endif diff --git a/src/atlas/field/FieldSet.h b/src/atlas/field/FieldSet.h index 3b69afb0b..40038637a 100644 --- a/src/atlas/field/FieldSet.h +++ b/src/atlas/field/FieldSet.h @@ -17,10 +17,11 @@ #include #include -#include "atlas/field/Field.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" +#include "atlas/field/Field.h" + namespace atlas { class FieldSet; diff --git a/src/atlas/field/State.cc b/src/atlas/field/State.cc index 9f4ff9dfa..68fd1d808 100644 --- a/src/atlas/field/State.cc +++ b/src/atlas/field/State.cc @@ -9,17 +9,20 @@ */ #include "atlas/field/State.h" + #include #include #include #include + +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" + #include "atlas/field/Field.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "eckit/thread/AutoLock.h" -#include "eckit/thread/Mutex.h" namespace atlas { namespace field { diff --git a/src/atlas/field/State.h b/src/atlas/field/State.h index 72b73d384..4c86d1e76 100644 --- a/src/atlas/field/State.h +++ b/src/atlas/field/State.h @@ -11,8 +11,7 @@ /// @author Willem Deconinck /// @date June 2015 -#ifndef atlas_State_H -#define atlas_State_H +#pragma once #include "atlas/field/Field.h" #include "atlas/util/Config.h" @@ -139,5 +138,3 @@ util::Metadata* atlas__State__metadata( State* This ); } // namespace field } // namespace atlas - -#endif diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index f3a924409..ad963dbb5 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -12,6 +12,9 @@ #include #include +#include "eckit/exception/Exceptions.h" +#include "eckit/memory/ScopedPtr.h" + #include "atlas/array/MakeView.h" #include "atlas/field/FieldCreator.h" #include "atlas/field/detail/FieldImpl.h" @@ -20,8 +23,6 @@ #include "atlas/mesh/Mesh.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "eckit/exception/Exceptions.h" -#include "eckit/memory/ScopedPtr.h" namespace atlas { namespace field { @@ -111,7 +112,7 @@ const std::string& FieldImpl::name() const { void FieldImpl::print( std::ostream& os, bool dump ) const { os << "FieldImpl[name=" << name() << ",datatype=" << datatype().str() << ",size=" << size() << ",shape=" << vector_to_str( shape() ) << ",strides=" << vector_to_str( strides() ) -#ifndef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ! ATLAS_HAVE_GRIDTOOLS_STORAGE << ",bytes=" << bytes() #endif << ",metadata=" << metadata(); diff --git a/src/atlas/field/detail/FieldImpl.h b/src/atlas/field/detail/FieldImpl.h index 2222ca9f5..7413365bc 100644 --- a/src/atlas/field/detail/FieldImpl.h +++ b/src/atlas/field/detail/FieldImpl.h @@ -15,12 +15,14 @@ #include #include + +#include "eckit/memory/Owned.h" + #include "atlas/array.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/DataType.h" #include "atlas/functionspace/FunctionSpace.h" #include "atlas/util/Metadata.h" -#include "eckit/memory/Owned.h" namespace eckit { class Parametrisation; diff --git a/src/atlas/functionspace/EdgeColumns.h b/src/atlas/functionspace/EdgeColumns.h index 7f22b397d..65edb55de 100644 --- a/src/atlas/functionspace/EdgeColumns.h +++ b/src/atlas/functionspace/EdgeColumns.h @@ -10,13 +10,14 @@ #pragma once +#include "eckit/memory/SharedPtr.h" + #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" #include "atlas/mesh/Halo.h" #include "atlas/mesh/Mesh.h" #include "atlas/option.h" #include "atlas/util/Config.h" -#include "eckit/memory/SharedPtr.h" // ---------------------------------------------------------------------------- // Forward declarations diff --git a/src/atlas/functionspace/FunctionSpace.cc b/src/atlas/functionspace/FunctionSpace.cc index 3e5920ef4..7fed4d8a1 100644 --- a/src/atlas/functionspace/FunctionSpace.cc +++ b/src/atlas/functionspace/FunctionSpace.cc @@ -9,18 +9,21 @@ */ #include "atlas/functionspace/FunctionSpace.h" + #include #include #include #include + +#include "eckit/exception/Exceptions.h" +#include "eckit/types/Types.h" + #include "atlas/array/DataType.h" #include "atlas/field/Field.h" #include "atlas/field/detail/FieldImpl.h" #include "atlas/library/config.h" #include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/runtime/ErrorHandling.h" -#include "eckit/exception/Exceptions.h" -#include "eckit/types/Types.h" namespace atlas { namespace functionspace { diff --git a/src/atlas/functionspace/FunctionSpace.h b/src/atlas/functionspace/FunctionSpace.h index dd60223a4..753552b3c 100644 --- a/src/atlas/functionspace/FunctionSpace.h +++ b/src/atlas/functionspace/FunctionSpace.h @@ -11,11 +11,13 @@ #pragma once #include + +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" + #include "atlas/field/Field.h" #include "atlas/option.h" #include "atlas/util/Config.h" -#include "eckit/memory/Owned.h" -#include "eckit/memory/SharedPtr.h" namespace atlas { namespace functionspace { diff --git a/src/atlas/functionspace/NodeColumns.h b/src/atlas/functionspace/NodeColumns.h index e61f96299..05bc3b83a 100644 --- a/src/atlas/functionspace/NodeColumns.h +++ b/src/atlas/functionspace/NodeColumns.h @@ -10,13 +10,14 @@ #pragma once +#include "eckit/memory/SharedPtr.h" + #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" #include "atlas/library/config.h" #include "atlas/mesh/Halo.h" #include "atlas/mesh/Mesh.h" #include "atlas/option.h" -#include "eckit/memory/SharedPtr.h" // ---------------------------------------------------------------------------- // Forward declarations diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index 2793dfba7..43f87e6cd 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -8,7 +8,6 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/parallel/mpi/mpi.h" #include "eckit/os/BackTrace.h" #include "eckit/utils/MD5.h" @@ -21,8 +20,10 @@ #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" #include "atlas/trans/Trans.h" +#include "atlas/parallel/mpi/mpi.h" + -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS #include "atlas/trans/ifs/TransIFS.h" namespace { void trans_check( const int code, const char* msg, const eckit::CodeLocation& location ) { @@ -41,7 +42,7 @@ namespace atlas { namespace functionspace { namespace detail { -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS class Spectral::Parallelisation { public: Parallelisation( const std::shared_ptr<::Trans_t> other ) : trans_( other ) {} @@ -121,7 +122,7 @@ Spectral::Spectral( const int truncation, const eckit::Configuration& config ) : Spectral::Spectral( const trans::Trans& trans, const eckit::Configuration& config ) : truncation_( trans.truncation() ), -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS parallelisation_( new Parallelisation( dynamic_cast( *trans.get() ).trans_ ) ), #else parallelisation_( new Parallelisation( truncation_ ) ), @@ -199,7 +200,7 @@ void Spectral::gather( const FieldSet& local_fieldset, FieldSet& global_fieldset throw eckit::BadValue( err.str() ); } -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS Field& glb = global_fieldset[f]; size_t root = 0; glb.metadata().get( "owner", root ); @@ -247,7 +248,7 @@ void Spectral::scatter( const FieldSet& global_fieldset, FieldSet& local_fieldse throw eckit::BadValue( err.str() ); } -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS size_t root = 0; glb.metadata().get( "owner", root ); ASSERT( loc.shape( 0 ) == nb_spectral_coefficients() ); @@ -295,7 +296,7 @@ std::string Spectral::checksum( const Field& field ) const { } void Spectral::norm( const Field& field, double& norm, int rank ) const { -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS ASSERT( std::max( 1, field.levels() ) == 1 ); struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); args.nfld = 1; @@ -310,7 +311,7 @@ void Spectral::norm( const Field& field, double& norm, int rank ) const { #endif } void Spectral::norm( const Field& field, double norm_per_level[], int rank ) const { -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS ASSERT( std::max( 1, field.levels() ) == 1 ); struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); args.nfld = std::max( 1, field.levels() ); @@ -325,7 +326,7 @@ void Spectral::norm( const Field& field, double norm_per_level[], int rank ) con #endif } void Spectral::norm( const Field& field, std::vector& norm_per_level, int rank ) const { -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS norm_per_level.resize( std::max( 1, field.levels() ) ); struct ::SpecNorm_t args = new_specnorm( *parallelisation_ ); args.nfld = norm_per_level.size(); diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index 8b2cdf296..b28fe326f 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -8,11 +8,11 @@ * nor does it submit to any jurisdiction. */ +#include "atlas/functionspace/StructuredColumns.h" + #include #include -#include "atlas/functionspace/StructuredColumns.h" - #include "eckit/utils/MD5.h" #include "atlas/array/MakeView.h" @@ -28,7 +28,6 @@ #include "atlas/runtime/Trace.h" #include "atlas/util/Checksum.h" #include "atlas/util/CoordinateEnums.h" - #include "atlas/mesh/Mesh.h" #define IDX( i, j ) "(" << i << "," << j << ")" diff --git a/src/atlas/functionspace/StructuredColumns.h b/src/atlas/functionspace/StructuredColumns.h index 1857d85b8..1416591b4 100644 --- a/src/atlas/functionspace/StructuredColumns.h +++ b/src/atlas/functionspace/StructuredColumns.h @@ -11,6 +11,7 @@ #pragma once #include + #include "atlas/array/DataType.h" #include "atlas/field/Field.h" #include "atlas/functionspace/FunctionSpace.h" diff --git a/src/atlas/grid/Distribution.cc b/src/atlas/grid/Distribution.cc index e3f8cc70d..a59d54561 100644 --- a/src/atlas/grid/Distribution.cc +++ b/src/atlas/grid/Distribution.cc @@ -8,8 +8,9 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/grid/Distribution.h" #include + +#include "atlas/grid/Distribution.h" #include "atlas/grid/Grid.h" #include "atlas/grid/Partitioner.h" #include "atlas/parallel/mpi/mpi.h" diff --git a/src/atlas/grid/Distribution.h b/src/atlas/grid/Distribution.h index 7f79a4d12..9b82daf58 100644 --- a/src/atlas/grid/Distribution.h +++ b/src/atlas/grid/Distribution.h @@ -11,10 +11,12 @@ #pragma once #include -#include "atlas/library/config.h" + #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" +#include "atlas/library/config.h" + namespace atlas { class Grid; namespace grid { diff --git a/src/atlas/grid/Grid.cc b/src/atlas/grid/Grid.cc index 7dbaaa73a..889d3d11c 100644 --- a/src/atlas/grid/Grid.cc +++ b/src/atlas/grid/Grid.cc @@ -12,6 +12,7 @@ #include #include + #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" diff --git a/src/atlas/grid/Grid.h b/src/atlas/grid/Grid.h index adf383d1b..9ac565825 100644 --- a/src/atlas/grid/Grid.h +++ b/src/atlas/grid/Grid.h @@ -11,13 +11,15 @@ #pragma once #include + +#include "eckit/memory/SharedPtr.h" + #include "atlas/domain/Domain.h" #include "atlas/grid/Iterator.h" #include "atlas/grid/detail/grid/Grid.h" #include "atlas/grid/detail/grid/Structured.h" #include "atlas/grid/detail/grid/Unstructured.h" #include "atlas/projection/Projection.h" -#include "eckit/memory/SharedPtr.h" namespace eckit { class Hash; diff --git a/src/atlas/grid/Partitioner.h b/src/atlas/grid/Partitioner.h index cbac7a6cd..388bbb914 100644 --- a/src/atlas/grid/Partitioner.h +++ b/src/atlas/grid/Partitioner.h @@ -10,10 +10,11 @@ #pragma once +#include "eckit/memory/SharedPtr.h" + #include "atlas/grid/Distribution.h" #include "atlas/grid/Grid.h" #include "atlas/grid/detail/partitioner/Partitioner.h" -#include "eckit/memory/SharedPtr.h" namespace atlas { namespace grid { diff --git a/src/atlas/grid/Spacing.cc b/src/atlas/grid/Spacing.cc index 6c6859ec7..557c7dd9f 100644 --- a/src/atlas/grid/Spacing.cc +++ b/src/atlas/grid/Spacing.cc @@ -1,3 +1,13 @@ +/* + * (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 "atlas/grid/Spacing.h" #include "atlas/grid/detail/spacing/GaussianSpacing.h" #include "atlas/grid/detail/spacing/LinearSpacing.h" diff --git a/src/atlas/grid/Spacing.h b/src/atlas/grid/Spacing.h index 248def6ef..3439a4d08 100644 --- a/src/atlas/grid/Spacing.h +++ b/src/atlas/grid/Spacing.h @@ -1,8 +1,19 @@ +/* + * (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 "eckit/memory/SharedPtr.h" + #include "atlas/grid/detail/spacing/Spacing.h" #include "atlas/util/Config.h" -#include "eckit/memory/SharedPtr.h" //--------------------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/grid/detail/grid/Grid.h b/src/atlas/grid/detail/grid/Grid.h index 92e1fb505..b93ffba73 100644 --- a/src/atlas/grid/detail/grid/Grid.h +++ b/src/atlas/grid/detail/grid/Grid.h @@ -12,12 +12,14 @@ #include #include + +#include "eckit/memory/Builder.h" +#include "eckit/memory/Owned.h" + #include "atlas/domain/Domain.h" #include "atlas/projection/Projection.h" #include "atlas/util/Config.h" #include "atlas/util/Point.h" -#include "eckit/memory/Builder.h" -#include "eckit/memory/Owned.h" namespace eckit { class Hash; diff --git a/src/atlas/grid/detail/grid/Structured.cc b/src/atlas/grid/detail/grid/Structured.cc index b8080eb49..a92dda322 100644 --- a/src/atlas/grid/detail/grid/Structured.cc +++ b/src/atlas/grid/detail/grid/Structured.cc @@ -12,6 +12,9 @@ #include #include + +#include "eckit/types/FloatCompare.h" + #include "atlas/domain/Domain.h" #include "atlas/grid/Grid.h" #include "atlas/grid/detail/grid/GridBuilder.h" @@ -21,7 +24,6 @@ #include "atlas/runtime/Log.h" #include "atlas/util/Earth.h" #include "atlas/util/Point.h" -#include "eckit/types/FloatCompare.h" namespace atlas { namespace grid { diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index 3b78ce15d..174470c68 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -13,11 +13,11 @@ #include #include -#include "atlas/grid/detail/grid/Grid.h" -#include "atlas/util/Config.h" #include "eckit/memory/Builder.h" #include "eckit/utils/Hash.h" +#include "atlas/grid/detail/grid/Grid.h" +#include "atlas/util/Config.h" #include "atlas/grid/Spacing.h" namespace atlas { diff --git a/src/atlas/grid/detail/grid/Unstructured.cc b/src/atlas/grid/detail/grid/Unstructured.cc index d881c4027..bdb5bf208 100644 --- a/src/atlas/grid/detail/grid/Unstructured.cc +++ b/src/atlas/grid/detail/grid/Unstructured.cc @@ -11,13 +11,15 @@ #include "atlas/grid/detail/grid/Unstructured.h" #include + +#include "eckit/memory/Builder.h" + #include "atlas/array/ArrayView.h" #include "atlas/field/Field.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/memory/Builder.h" namespace atlas { namespace grid { diff --git a/src/atlas/grid/detail/grid/Unstructured.h b/src/atlas/grid/detail/grid/Unstructured.h index 8599b90c4..3f5a9fa7a 100644 --- a/src/atlas/grid/detail/grid/Unstructured.h +++ b/src/atlas/grid/detail/grid/Unstructured.h @@ -18,9 +18,11 @@ #include #include #include -#include "atlas/grid/detail/grid/Grid.h" + #include "eckit/utils/Hash.h" +#include "atlas/grid/detail/grid/Grid.h" + namespace atlas { class Mesh; } diff --git a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc index b6b8e4d4f..223c0d4ab 100644 --- a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.cc @@ -1,10 +1,12 @@ #include "atlas/grid/detail/partitioner/CheckerboardPartitioner.h" + #include #include #include #include #include #include + #include "atlas/grid/Grid.h" #include "atlas/runtime/Log.h" #include "atlas/util/MicroDeg.h" diff --git a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.h b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.h index c50ad9dc9..e6f981e14 100644 --- a/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.h +++ b/src/atlas/grid/detail/partitioner/CheckerboardPartitioner.h @@ -1,6 +1,7 @@ #pragma once #include + #include "atlas/grid/detail/partitioner/Partitioner.h" namespace atlas { diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc index 7b1f3a297..c21e8ac73 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.cc @@ -9,12 +9,14 @@ */ #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" + #include #include #include #include #include #include + #include "atlas/grid/Grid.h" #include "atlas/parallel/mpi/Buffer.h" #include "atlas/parallel/mpi/mpi.h" diff --git a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h index 65dfb7c75..ff4c76ef2 100644 --- a/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h +++ b/src/atlas/grid/detail/partitioner/EqualRegionsPartitioner.h @@ -64,6 +64,7 @@ #pragma once #include + #include "atlas/grid/detail/partitioner/Partitioner.h" namespace atlas { diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h b/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h index 67dbcab20..e18e57d45 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitioner.h @@ -11,9 +11,11 @@ #pragma once #include -#include "atlas/grid/detail/partitioner/Partitioner.h" + #include "eckit/exception/Exceptions.h" +#include "atlas/grid/detail/partitioner/Partitioner.h" + namespace atlas { namespace grid { namespace detail { diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc index 064084890..efe07b5c9 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.cc @@ -11,6 +11,11 @@ #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h" #include + +#include "eckit/geometry/Point2.h" +#include "eckit/log/ProgressTimer.h" +#include "eckit/mpi/Comm.h" + #include "atlas/array/ArrayView.h" #include "atlas/field/Field.h" #include "atlas/grid/Grid.h" @@ -19,9 +24,6 @@ #include "atlas/mesh/Nodes.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/geometry/Point2.h" -#include "eckit/log/ProgressTimer.h" -#include "eckit/mpi/Comm.h" namespace atlas { namespace grid { diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc index 584945639..af30c791e 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.cc @@ -11,13 +11,15 @@ #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h" #include + +#include "eckit/config/Resource.h" +#include "eckit/log/ProgressTimer.h" + #include "atlas/grid/Grid.h" #include "atlas/mesh/Nodes.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/util/LonLatPolygon.h" -#include "eckit/config/Resource.h" -#include "eckit/log/ProgressTimer.h" namespace atlas { namespace grid { diff --git a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc index 62360877b..a4e42abaa 100644 --- a/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc +++ b/src/atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.cc @@ -11,12 +11,14 @@ #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h" #include + +#include "eckit/log/ProgressTimer.h" + #include "atlas/grid/Grid.h" #include "atlas/mesh/Nodes.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/util/SphericalPolygon.h" -#include "eckit/log/ProgressTimer.h" namespace atlas { namespace grid { diff --git a/src/atlas/grid/detail/partitioner/Partitioner.cc b/src/atlas/grid/detail/partitioner/Partitioner.cc index 187da635c..c9087f176 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.cc +++ b/src/atlas/grid/detail/partitioner/Partitioner.cc @@ -9,24 +9,28 @@ */ #include "atlas/grid/detail/partitioner/Partitioner.h" + #include #include + +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" + #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitioner.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h" -#include "eckit/thread/AutoLock.h" -#include "eckit/thread/Mutex.h" -#ifdef ATLAS_HAVE_TRANS -#include "atlas/grid/detail/partitioner/TransPartitioner.h" -#endif #include "atlas/grid/Distribution.h" #include "atlas/grid/Partitioner.h" #include "atlas/library/config.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" +#if ATLAS_HAVE_TRANS +#include "atlas/grid/detail/partitioner/TransPartitioner.h" +#endif + namespace { static eckit::Mutex* local_mutex = 0; @@ -68,7 +72,7 @@ void load_builder() { struct force_link { force_link() { load_builder(); -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS load_builder(); #endif } diff --git a/src/atlas/grid/detail/partitioner/Partitioner.h b/src/atlas/grid/detail/partitioner/Partitioner.h index 16231ee31..663dfeb0f 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.h +++ b/src/atlas/grid/detail/partitioner/Partitioner.h @@ -10,10 +10,11 @@ #pragma once +#include "eckit/memory/Owned.h" + #include "atlas/grid/Distribution.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" -#include "eckit/memory/Owned.h" namespace atlas { namespace grid { diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index 41606ae35..13c817e6e 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -8,6 +8,8 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/exception/Exceptions.h" + #include "atlas/grid/detail/partitioner/TransPartitioner.h" #include "atlas/array.h" #include "atlas/grid/Grid.h" @@ -15,7 +17,6 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Trace.h" #include "atlas/trans/ifs/TransIFS.h" -#include "eckit/exception/Exceptions.h" namespace atlas { namespace grid { diff --git a/src/atlas/grid/detail/spacing/CustomSpacing.cc b/src/atlas/grid/detail/spacing/CustomSpacing.cc index 4b8f189f8..7115a36fd 100644 --- a/src/atlas/grid/detail/spacing/CustomSpacing.cc +++ b/src/atlas/grid/detail/spacing/CustomSpacing.cc @@ -1,5 +1,17 @@ +/* + * (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 "atlas/grid/detail/spacing/CustomSpacing.h" + #include + #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" diff --git a/src/atlas/grid/detail/spacing/CustomSpacing.h b/src/atlas/grid/detail/spacing/CustomSpacing.h index 0919d8d5b..6907bc807 100644 --- a/src/atlas/grid/detail/spacing/CustomSpacing.h +++ b/src/atlas/grid/detail/spacing/CustomSpacing.h @@ -1,6 +1,17 @@ +/* + * (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 + #include "atlas/grid/detail/spacing/Spacing.h" namespace atlas { diff --git a/src/atlas/grid/detail/spacing/FocusSpacing.cc b/src/atlas/grid/detail/spacing/FocusSpacing.cc index a2906230d..0873ce17c 100644 --- a/src/atlas/grid/detail/spacing/FocusSpacing.cc +++ b/src/atlas/grid/detail/spacing/FocusSpacing.cc @@ -1,8 +1,20 @@ -#include "atlas/grid/detail/spacing/FocusSpacing.h" +/* + * (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 + #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" +#include "atlas/grid/detail/spacing/FocusSpacing.h" + namespace atlas { namespace grid { namespace spacing { diff --git a/src/atlas/grid/detail/spacing/FocusSpacing.h b/src/atlas/grid/detail/spacing/FocusSpacing.h index 854752f34..9c032f9a4 100644 --- a/src/atlas/grid/detail/spacing/FocusSpacing.h +++ b/src/atlas/grid/detail/spacing/FocusSpacing.h @@ -1,5 +1,14 @@ -#ifndef atlas_FocusSpacing_H -#define atlas_FocusSpacing_H +/* + * (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/detail/spacing/Spacing.h" @@ -27,5 +36,3 @@ class FocusSpacing : public Spacing { } // namespace spacing } // namespace grid } // namespace atlas - -#endif diff --git a/src/atlas/grid/detail/spacing/GaussianSpacing.cc b/src/atlas/grid/detail/spacing/GaussianSpacing.cc index e4ebe7e26..d2c5d408f 100644 --- a/src/atlas/grid/detail/spacing/GaussianSpacing.cc +++ b/src/atlas/grid/detail/spacing/GaussianSpacing.cc @@ -1,8 +1,19 @@ -#include "atlas/grid/detail/spacing/GaussianSpacing.h" -#include "atlas/grid/detail/spacing/gaussian/Latitudes.h" +/* + * (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/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" +#include "atlas/grid/detail/spacing/GaussianSpacing.h" +#include "atlas/grid/detail/spacing/gaussian/Latitudes.h" + namespace atlas { namespace grid { namespace spacing { diff --git a/src/atlas/grid/detail/spacing/GaussianSpacing.h b/src/atlas/grid/detail/spacing/GaussianSpacing.h index 303c87b8c..bf4aff6d6 100644 --- a/src/atlas/grid/detail/spacing/GaussianSpacing.h +++ b/src/atlas/grid/detail/spacing/GaussianSpacing.h @@ -1,5 +1,14 @@ -#ifndef atlas_GaussianSpacing_H -#define atlas_GaussianSpacing_H +/* + * (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/detail/spacing/Spacing.h" @@ -45,5 +54,3 @@ class GaussianSpacing : public Spacing { } // namespace spacing } // namespace grid } // namespace atlas - -#endif diff --git a/src/atlas/grid/detail/spacing/LinearSpacing.cc b/src/atlas/grid/detail/spacing/LinearSpacing.cc index 45fc50b5b..7a45bb5f0 100644 --- a/src/atlas/grid/detail/spacing/LinearSpacing.cc +++ b/src/atlas/grid/detail/spacing/LinearSpacing.cc @@ -1,5 +1,17 @@ +/* + * (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 "atlas/grid/detail/spacing/LinearSpacing.h" + #include + #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" diff --git a/src/atlas/grid/detail/spacing/LinearSpacing.h b/src/atlas/grid/detail/spacing/LinearSpacing.h index d622e7b4d..3014aa74f 100644 --- a/src/atlas/grid/detail/spacing/LinearSpacing.h +++ b/src/atlas/grid/detail/spacing/LinearSpacing.h @@ -1,6 +1,17 @@ +/* + * (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 + #include "atlas/grid/detail/spacing/Spacing.h" namespace atlas { diff --git a/src/atlas/grid/detail/spacing/Spacing.cc b/src/atlas/grid/detail/spacing/Spacing.cc index 28ce69f68..77de0e4af 100644 --- a/src/atlas/grid/detail/spacing/Spacing.cc +++ b/src/atlas/grid/detail/spacing/Spacing.cc @@ -1,8 +1,18 @@ +/* + * (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 "atlas/grid/detail/spacing/Spacing.h" #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" +#include "atlas/grid/detail/spacing/Spacing.h" + namespace atlas { namespace grid { namespace spacing { diff --git a/src/atlas/grid/detail/spacing/Spacing.h b/src/atlas/grid/detail/spacing/Spacing.h index 51187caa4..baef8c07d 100644 --- a/src/atlas/grid/detail/spacing/Spacing.h +++ b/src/atlas/grid/detail/spacing/Spacing.h @@ -1,11 +1,23 @@ +/* + * (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 #include -#include "atlas/util/Config.h" + #include "eckit/memory/Builder.h" #include "eckit/memory/Owned.h" +#include "atlas/util/Config.h" + namespace eckit { class Parametrisation; } diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc index f153b59fe..37233dd62 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.cc @@ -13,6 +13,8 @@ #include +#include "eckit/memory/ScopedPtr.h" + #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "atlas/grid/detail/spacing/gaussian/Latitudes.h" @@ -21,7 +23,6 @@ #include "atlas/runtime/Log.h" #include "atlas/util/Constants.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/memory/ScopedPtr.h" using eckit::ConcreteBuilderT0; using eckit::Factory; diff --git a/src/atlas/grid/detail/spacing/gaussian/Latitudes.h b/src/atlas/grid/detail/spacing/gaussian/Latitudes.h index d4f78a371..41e4b6182 100644 --- a/src/atlas/grid/detail/spacing/gaussian/Latitudes.h +++ b/src/atlas/grid/detail/spacing/gaussian/Latitudes.h @@ -11,8 +11,7 @@ /// @author Willem Deconinck /// @date Jan 2014 -#ifndef atlas_grid_spacing_gaussian_Latitudes_h -#define atlas_grid_spacing_gaussian_Latitudes_h +#pragma once #include @@ -61,5 +60,3 @@ void gaussian_quadrature_npole_spole( const size_t N, double latitudes[], double } // namespace spacing } // namespace grid } // namespace atlas - -#endif diff --git a/src/atlas/grid/detail/spacing/gaussian/N.h b/src/atlas/grid/detail/spacing/gaussian/N.h index c797153ec..2c40cadfe 100644 --- a/src/atlas/grid/detail/spacing/gaussian/N.h +++ b/src/atlas/grid/detail/spacing/gaussian/N.h @@ -11,8 +11,7 @@ /// @author Willem Deconinck /// @date Nov 2014 -#ifndef atlas_grid_spacing_gaussian_N_h -#define atlas_grid_spacing_gaussian_N_h +#pragma once #include "eckit/memory/Builder.h" #include "eckit/memory/Owned.h" @@ -87,5 +86,3 @@ DECLARE_GAUSSIAN_LATITUDES( 8000 ); } // namespace spacing } // namespace grid } // namespace atlas - -#endif diff --git a/src/atlas/interpolation/Interpolation.cc b/src/atlas/interpolation/Interpolation.cc index 432fbc2af..d8674d06b 100644 --- a/src/atlas/interpolation/Interpolation.cc +++ b/src/atlas/interpolation/Interpolation.cc @@ -8,12 +8,12 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/interpolation/Interpolation.h" +#include "eckit/exception/Exceptions.h" +#include "atlas/interpolation/Interpolation.h" #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" -#include "eckit/exception/Exceptions.h" namespace atlas { diff --git a/src/atlas/interpolation/Interpolation.h b/src/atlas/interpolation/Interpolation.h index f72d303f0..0ff0e6aa4 100644 --- a/src/atlas/interpolation/Interpolation.h +++ b/src/atlas/interpolation/Interpolation.h @@ -10,10 +10,11 @@ #pragma once -#include "atlas/interpolation/method/Method.h" #include "eckit/config/Configuration.h" #include "eckit/memory/SharedPtr.h" +#include "atlas/interpolation/method/Method.h" + namespace atlas { class Field; class FieldSet; diff --git a/src/atlas/interpolation/element/Quad3D.h b/src/atlas/interpolation/element/Quad3D.h index 55da76fd7..f17e4a58a 100644 --- a/src/atlas/interpolation/element/Quad3D.h +++ b/src/atlas/interpolation/element/Quad3D.h @@ -8,8 +8,7 @@ * nor does it submit to any jurisdiction. */ -#ifndef atlas_interpolation_element_Quad3D_h -#define atlas_interpolation_element_Quad3D_h +#pragma once #include @@ -66,4 +65,3 @@ class Quad3D { } // namespace interpolation } // namespace atlas -#endif diff --git a/src/atlas/interpolation/element/Triag3D.cc b/src/atlas/interpolation/element/Triag3D.cc index 907ff7aad..afc245004 100644 --- a/src/atlas/interpolation/element/Triag3D.cc +++ b/src/atlas/interpolation/element/Triag3D.cc @@ -8,8 +8,9 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/interpolation/element/Triag3D.h" #include + +#include "atlas/interpolation/element/Triag3D.h" #include "atlas/interpolation/method/Intersect.h" #include "atlas/interpolation/method/Ray.h" diff --git a/src/atlas/interpolation/element/Triag3D.h b/src/atlas/interpolation/element/Triag3D.h index efae85236..1bd758c23 100644 --- a/src/atlas/interpolation/element/Triag3D.h +++ b/src/atlas/interpolation/element/Triag3D.h @@ -8,8 +8,7 @@ * nor does it submit to any jurisdiction. */ -#ifndef atlas_interpolation_element_Triag3D_h -#define atlas_interpolation_element_Triag3D_h +#pragma once #include @@ -67,5 +66,3 @@ class Triag3D { } // namespace element } // namespace interpolation } // namespace atlas - -#endif diff --git a/src/atlas/interpolation/method/FiniteElement.h b/src/atlas/interpolation/method/FiniteElement.h index 2bdea35ab..bbadf0289 100644 --- a/src/atlas/interpolation/method/FiniteElement.h +++ b/src/atlas/interpolation/method/FiniteElement.h @@ -13,11 +13,13 @@ #include "atlas/interpolation/method/Method.h" #include + +#include "eckit/config/Configuration.h" +#include "eckit/memory/NonCopyable.h" + #include "atlas/array/ArrayView.h" #include "atlas/interpolation/method/PointIndex3.h" #include "atlas/mesh/Elements.h" -#include "eckit/config/Configuration.h" -#include "eckit/memory/NonCopyable.h" namespace atlas { namespace interpolation { diff --git a/src/atlas/interpolation/method/Intersect.h b/src/atlas/interpolation/method/Intersect.h index c89309957..dd51c0388 100644 --- a/src/atlas/interpolation/method/Intersect.h +++ b/src/atlas/interpolation/method/Intersect.h @@ -8,8 +8,7 @@ * nor does it submit to any jurisdiction. */ -#ifndef atlas_interpolation_method_Intersect_h -#define atlas_interpolation_method_Intersect_h +#pragma once #include @@ -55,5 +54,3 @@ struct Intersect { } // namespace method } // namespace interpolation } // namespace atlas - -#endif diff --git a/src/atlas/interpolation/method/KNearestNeighbours.cc b/src/atlas/interpolation/method/KNearestNeighbours.cc index b6cf0e3f0..afc405c3d 100644 --- a/src/atlas/interpolation/method/KNearestNeighbours.cc +++ b/src/atlas/interpolation/method/KNearestNeighbours.cc @@ -10,13 +10,14 @@ #include "atlas/interpolation/method/KNearestNeighbours.h" +#include "eckit/log/Plural.h" +#include "eckit/log/Timer.h" + #include "atlas/functionspace/NodeColumns.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "eckit/log/Plural.h" -#include "eckit/log/Timer.h" namespace atlas { namespace interpolation { diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.cc b/src/atlas/interpolation/method/KNearestNeighboursBase.cc index 0572bb0a7..3a25cd091 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.cc +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.cc @@ -8,13 +8,13 @@ * nor does it submit to any jurisdiction. and Interpolation */ -#include "atlas/interpolation/method/KNearestNeighboursBase.h" +#include "eckit/config/Resource.h" +#include "atlas/interpolation/method/KNearestNeighboursBase.h" #include "atlas/library/Library.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Trace.h" -#include "eckit/config/Resource.h" namespace atlas { namespace interpolation { diff --git a/src/atlas/interpolation/method/KNearestNeighboursBase.h b/src/atlas/interpolation/method/KNearestNeighboursBase.h index c7059c50e..aca15cd33 100644 --- a/src/atlas/interpolation/method/KNearestNeighboursBase.h +++ b/src/atlas/interpolation/method/KNearestNeighboursBase.h @@ -10,9 +10,10 @@ #pragma once +#include "eckit/memory/ScopedPtr.h" + #include "atlas/interpolation/method/Method.h" #include "atlas/interpolation/method/PointIndex3.h" -#include "eckit/memory/ScopedPtr.h" namespace atlas { namespace interpolation { diff --git a/src/atlas/interpolation/method/Method.cc b/src/atlas/interpolation/method/Method.cc index 49330f6c7..05365cc52 100644 --- a/src/atlas/interpolation/method/Method.cc +++ b/src/atlas/interpolation/method/Method.cc @@ -11,10 +11,7 @@ #include "atlas/interpolation/method/Method.h" #include -#include "atlas/field/Field.h" -#include "atlas/field/FieldSet.h" -#include "atlas/runtime/Log.h" -#include "atlas/runtime/Trace.h" + #include "eckit/exception/Exceptions.h" #include "eckit/linalg/LinearAlgebra.h" #include "eckit/linalg/Vector.h" @@ -23,6 +20,11 @@ #include "eckit/thread/Mutex.h" #include "eckit/thread/Once.h" +#include "atlas/field/Field.h" +#include "atlas/field/FieldSet.h" +#include "atlas/runtime/Log.h" +#include "atlas/runtime/Trace.h" + // for static linking #include "FiniteElement.h" #include "KNearestNeighbours.h" diff --git a/src/atlas/interpolation/method/Method.h b/src/atlas/interpolation/method/Method.h index 5afed2b01..3cee4e597 100644 --- a/src/atlas/interpolation/method/Method.h +++ b/src/atlas/interpolation/method/Method.h @@ -12,6 +12,7 @@ #include #include + #include "eckit/config/Configuration.h" #include "eckit/linalg/SparseMatrix.h" #include "eckit/memory/Owned.h" diff --git a/src/atlas/interpolation/method/NearestNeighbour.cc b/src/atlas/interpolation/method/NearestNeighbour.cc index de59e2a33..96fea41fb 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.cc +++ b/src/atlas/interpolation/method/NearestNeighbour.cc @@ -8,14 +8,14 @@ * nor does it submit to any jurisdiction. and Interpolation */ -#include "atlas/interpolation/method/NearestNeighbour.h" +#include "eckit/log/Plural.h" +#include "atlas/interpolation/method/NearestNeighbour.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" -#include "eckit/log/Plural.h" namespace atlas { namespace interpolation { diff --git a/src/atlas/interpolation/method/PointIndex3.cc b/src/atlas/interpolation/method/PointIndex3.cc index fab43cd4c..dcc392a63 100644 --- a/src/atlas/interpolation/method/PointIndex3.cc +++ b/src/atlas/interpolation/method/PointIndex3.cc @@ -9,12 +9,12 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/interpolation/method/PointIndex3.h" +#include "eckit/config/Resource.h" +#include "atlas/interpolation/method/PointIndex3.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/mesh/HybridElements.h" -#include "eckit/config/Resource.h" namespace atlas { namespace interpolation { diff --git a/src/atlas/interpolation/method/PointIndex3.h b/src/atlas/interpolation/method/PointIndex3.h index 096e87c03..5c7827757 100644 --- a/src/atlas/interpolation/method/PointIndex3.h +++ b/src/atlas/interpolation/method/PointIndex3.h @@ -10,14 +10,15 @@ #pragma once -#include "atlas/field/Field.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/util/CoordinateEnums.h" #include "eckit/container/KDMapped.h" #include "eckit/container/KDMemory.h" #include "eckit/container/KDTree.h" #include "eckit/geometry/Point3.h" +#include "atlas/field/Field.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/util/CoordinateEnums.h" + namespace atlas { namespace interpolation { namespace method { diff --git a/src/atlas/interpolation/method/PointSet.cc b/src/atlas/interpolation/method/PointSet.cc index 9a767ddba..105be49ae 100644 --- a/src/atlas/interpolation/method/PointSet.cc +++ b/src/atlas/interpolation/method/PointSet.cc @@ -8,14 +8,14 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/interpolation/method/PointSet.h" +#include "eckit/config/Resource.h" +#include "atlas/interpolation/method/PointSet.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" -#include "eckit/config/Resource.h" using namespace eckit; diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index c8a3ed583..7af939313 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -8,11 +8,6 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/library/config.h" - -#ifdef ATLAS_HAVE_TRANS -#include "transi/version.h" -#endif #include "eckit/eckit_config.h" #include "eckit/filesystem/LocalPathName.h" @@ -30,6 +25,11 @@ #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" #include "atlas/util/Config.h" +#include "atlas/library/config.h" + +#if ATLAS_HAVE_TRANS +#include "transi/version.h" +#endif using eckit::LocalPathName; using eckit::Main; @@ -217,32 +217,17 @@ void Library::Information::print( std::ostream& out ) const { #endif << " \n"; - bool feature_fortran( false ); - bool feature_OpenMP( false ); - bool feature_Trans( false ); - bool feature_Tesselation( false ); - bool feature_BoundsChecking( false ); + bool feature_fortran( ATLAS_HAVE_FORTRAN ); + bool feature_OpenMP( ATLAS_HAVE_OMP ); + bool feature_Trans( ATLAS_HAVE_TRANS ); + bool feature_Tesselation( ATLAS_HAVE_TESSELATION ); + bool feature_BoundsChecking( ATLAS_ARRAYVIEW_BOUNDS_CHECKING ); bool feature_MPI( false ); -#if ATLAS_HAVE_FORTRAN - feature_fortran = true; -#endif #ifdef ECKIT_HAVE_MPI feature_MPI = true; -#endif -#if ATLAS_HAVE_OMP - feature_OpenMP = true; -#endif -#ifdef ATLAS_HAVE_TRANS - feature_Trans = true; -#endif -#if ATLAS_HAVE_TESSELATION - feature_Tesselation = true; -#endif -#ifdef ATLAS_HAVE_BOUNDSCHECKING - feature_BoundsChecking = true; #endif std::string array_data_store = "Native"; -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE array_data_store = "Gridtools-host"; #if ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA array_data_store = "GridTools-CUDA"; @@ -265,7 +250,7 @@ void Library::Information::print( std::ostream& out ) const { if ( Library::exists( "eckit" ) ) { out << " " << str( Library::lookup( "eckit" ) ) << '\n'; } if ( Library::exists( "fckit" ) ) { out << " " << str( Library::lookup( "fckit" ) ) << '\n'; } -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS out << " transi version (" << transi_version() << "), " << "git-sha1 " << transi_git_sha1_abbrev( 7 ) << '\n'; out << " trans version (" << trans_version() << "), " diff --git a/src/atlas/library/Library.h b/src/atlas/library/Library.h index d95369df6..0478d4397 100644 --- a/src/atlas/library/Library.h +++ b/src/atlas/library/Library.h @@ -13,6 +13,7 @@ #include #include #include + #include "eckit/system/Library.h" namespace eckit { diff --git a/src/atlas/library/config.h b/src/atlas/library/config.h index 6c2760023..68793efeb 100644 --- a/src/atlas/library/config.h +++ b/src/atlas/library/config.h @@ -1,9 +1,11 @@ #pragma once #include + +#include "eckit/eckit_config.h" + #include "atlas/atlas_ecbuild_config.h" #include "atlas/library/defines.h" -#include "eckit/eckit_config.h" #define ATLAS_HAVE_TRACE 1 diff --git a/src/atlas/library/defines.h.in b/src/atlas/library/defines.h.in index 9705f2588..22ba76c0c 100644 --- a/src/atlas/library/defines.h.in +++ b/src/atlas/library/defines.h.in @@ -5,25 +5,18 @@ #define CGAL_FOUND #endif -#define ATLAS_HAVE_OMP @ATLAS_HAVE_OMP@ - -#define ATLAS_HAVE_TESSELATION @ATLAS_HAVE_TESSELATION@ - -#define ATLAS_HAVE_FORTRAN @ATLAS_HAVE_FORTRAN@ - -#if @ATLAS_HAVE_TRANS@ -#define ATLAS_HAVE_TRANS -#endif - -#define ATLAS_HAVE_EIGEN @ATLAS_HAVE_EIGEN@ - -#if @ATLAS_HAVE_GRIDTOOLS_STORAGE@ -#define ATLAS_HAVE_GRIDTOOLS_STORAGE +#define ATLAS_HAVE_OMP @ATLAS_HAVE_OMP@ +#define ATLAS_HAVE_ACC @ATLAS_HAVE_ACC@ +#define ATLAS_HAVE_TESSELATION @ATLAS_HAVE_TESSELATION@ +#define ATLAS_HAVE_FORTRAN @ATLAS_HAVE_FORTRAN@ +#define ATLAS_HAVE_EIGEN @ATLAS_HAVE_EIGEN@ +#define ATLAS_BITS_GLOBAL @ATLAS_BITS_GLOBAL@ +#define ATLAS_ARRAYVIEW_BOUNDS_CHECKING @ATLAS_HAVE_BOUNDSCHECKING@ +#define ATLAS_INDEXVIEW_BOUNDS_CHECKING @ATLAS_HAVE_BOUNDSCHECKING@ +#define ATLAS_HAVE_GRIDTOOLS_STORAGE @ATLAS_HAVE_GRIDTOOLS_STORAGE@ #define ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST @ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST@ #define ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA @ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA@ -#endif - -#define ATLAS_HAVE_ACC @ATLAS_HAVE_ACC@ +#define ATLAS_HAVE_TRANS @ATLAS_HAVE_TRANS@ #ifdef __CUDACC__ #define ATLAS_HOST_DEVICE __host__ __device__ @@ -35,9 +28,5 @@ #define ATLAS_HOST #endif -#define ATLAS_BITS_GLOBAL @ATLAS_BITS_GLOBAL@ - -#define ATLAS_ARRAYVIEW_BOUNDS_CHECKING @ATLAS_HAVE_BOUNDSCHECKING@ -#define ATLAS_INDEXVIEW_BOUNDS_CHECKING @ATLAS_HAVE_BOUNDSCHECKING@ #endif diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index c50687cbf..5e93e92bc 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -8,8 +8,9 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/mesh/Connectivity.h" #include + +#include "atlas/mesh/Connectivity.h" #include "atlas/array.h" #include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" diff --git a/src/atlas/mesh/Connectivity.h b/src/atlas/mesh/Connectivity.h index 2c47ba6c2..a611c94de 100644 --- a/src/atlas/mesh/Connectivity.h +++ b/src/atlas/mesh/Connectivity.h @@ -25,6 +25,8 @@ #include +#include "eckit/memory/Owned.h" + #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/DataType.h" @@ -34,8 +36,6 @@ #include "atlas/array_fwd.h" #include "atlas/library/config.h" -#include "eckit/memory/Owned.h" - namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/Elements.h b/src/atlas/mesh/Elements.h index 8c7fd9328..12024510f 100644 --- a/src/atlas/mesh/Elements.h +++ b/src/atlas/mesh/Elements.h @@ -16,10 +16,11 @@ #pragma once +#include "eckit/memory/Owned.h" + #include "atlas/array/ArrayView.h" #include "atlas/mesh/Connectivity.h" #include "atlas/mesh/HybridElements.h" -#include "eckit/memory/Owned.h" namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/Halo.cc b/src/atlas/mesh/Halo.cc index 20a81a8f4..498742e72 100644 --- a/src/atlas/mesh/Halo.cc +++ b/src/atlas/mesh/Halo.cc @@ -8,10 +8,11 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/exception/Exceptions.h" + #include "atlas/mesh/Halo.h" #include "atlas/mesh/Mesh.h" #include "atlas/util/Metadata.h" -#include "eckit/exception/Exceptions.h" namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/HybridElements.cc b/src/atlas/mesh/HybridElements.cc index 26432a4b4..2f49ab24a 100644 --- a/src/atlas/mesh/HybridElements.cc +++ b/src/atlas/mesh/HybridElements.cc @@ -8,8 +8,12 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/mesh/HybridElements.h" #include + +#include "eckit/log/Bytes.h" +#include "eckit/memory/SharedPtr.h" + +#include "atlas/mesh/HybridElements.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/library/config.h" @@ -18,8 +22,6 @@ #include "atlas/mesh/Mesh.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "eckit/log/Bytes.h" -#include "eckit/memory/SharedPtr.h" #if ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 diff --git a/src/atlas/mesh/HybridElements.h b/src/atlas/mesh/HybridElements.h index e95fb55da..59369dbea 100644 --- a/src/atlas/mesh/HybridElements.h +++ b/src/atlas/mesh/HybridElements.h @@ -16,11 +16,12 @@ #pragma once +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" + #include "atlas/field/Field.h" #include "atlas/mesh/Connectivity.h" #include "atlas/util/Metadata.h" -#include "eckit/memory/Owned.h" -#include "eckit/memory/SharedPtr.h" #include "atlas/field/detail/FieldImpl.h" // only included for Fortran interface diff --git a/src/atlas/mesh/Mesh.h b/src/atlas/mesh/Mesh.h index 9893f8fc0..20481065d 100644 --- a/src/atlas/mesh/Mesh.h +++ b/src/atlas/mesh/Mesh.h @@ -12,9 +12,10 @@ #include -#include "atlas/mesh/detail/MeshImpl.h" #include "eckit/memory/SharedPtr.h" +#include "atlas/mesh/detail/MeshImpl.h" + //---------------------------------------------------------------------------------------------------------------------- // Forward declarations diff --git a/src/atlas/mesh/Nodes.h b/src/atlas/mesh/Nodes.h index eee942230..4c4713fb9 100644 --- a/src/atlas/mesh/Nodes.h +++ b/src/atlas/mesh/Nodes.h @@ -15,13 +15,15 @@ #include #include + +#include "eckit/exception/Exceptions.h" +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" + #include "atlas/field/Field.h" #include "atlas/mesh/Connectivity.h" #include "atlas/util/Bitflags.h" #include "atlas/util/Metadata.h" -#include "eckit/exception/Exceptions.h" -#include "eckit/memory/Owned.h" -#include "eckit/memory/SharedPtr.h" namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/PartitionPolygon.cc b/src/atlas/mesh/PartitionPolygon.cc index e08d9b7d5..aadf2e8b3 100644 --- a/src/atlas/mesh/PartitionPolygon.cc +++ b/src/atlas/mesh/PartitionPolygon.cc @@ -9,20 +9,11 @@ */ #include "atlas/mesh/PartitionPolygon.h" - #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/mesh.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/util/CoordinateEnums.h" -//#include "eckit/config/Resource.h" -//#include "eckit/mpi/Comm.h" -//#include "eckit/types/FloatCompare.h" -//#include "atlas/grid/Grid.h" -//#include "atlas/mesh/Elements.h" -//#include "atlas/mesh/Mesh.h" -//#include "atlas/mesh/Nodes.h" -//#include "atlas/runtime/Log.h" namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/PartitionPolygon.h b/src/atlas/mesh/PartitionPolygon.h index e77f07449..35e7b4038 100644 --- a/src/atlas/mesh/PartitionPolygon.h +++ b/src/atlas/mesh/PartitionPolygon.h @@ -15,10 +15,12 @@ #pragma once #include + +#include "eckit/memory/Owned.h" + #include "atlas/library/config.h" #include "atlas/util/Config.h" #include "atlas/util/Polygon.h" -#include "eckit/memory/Owned.h" namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/actions/BuildCellCentres.cc b/src/atlas/mesh/actions/BuildCellCentres.cc index a8de1e5db..1cbfdcebf 100644 --- a/src/atlas/mesh/actions/BuildCellCentres.cc +++ b/src/atlas/mesh/actions/BuildCellCentres.cc @@ -8,15 +8,17 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/mesh/actions/BuildCellCentres.h" #include + +#include "eckit/types/FloatCompare.h" + +#include "atlas/mesh/actions/BuildCellCentres.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/types/FloatCompare.h" namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/actions/BuildConvexHull3D.h b/src/atlas/mesh/actions/BuildConvexHull3D.h index a66543ec2..df281bc96 100644 --- a/src/atlas/mesh/actions/BuildConvexHull3D.h +++ b/src/atlas/mesh/actions/BuildConvexHull3D.h @@ -8,8 +8,7 @@ * nor does it submit to any jurisdiction. */ -#ifndef atlas_actions_BuildConvexHull3D_h -#define atlas_actions_BuildConvexHull3D_h +#pragma once namespace atlas { @@ -27,5 +26,3 @@ class BuildConvexHull3D { } // namespace actions } // namespace mesh } // namespace atlas - -#endif diff --git a/src/atlas/mesh/actions/BuildHalo.h b/src/atlas/mesh/actions/BuildHalo.h index df3608bc3..99839b60f 100644 --- a/src/atlas/mesh/actions/BuildHalo.h +++ b/src/atlas/mesh/actions/BuildHalo.h @@ -8,11 +8,11 @@ * nor does it submit to any jurisdiction. */ -#ifndef BuildHalo_h -#define BuildHalo_h +#pragma once #include #include + #include "atlas/library/config.h" namespace atlas { @@ -54,5 +54,3 @@ void atlas__build_halo( Mesh::Implementation* mesh, int nb_elems ); } // namespace actions } // namespace mesh } // namespace atlas - -#endif // BuildHalo_h diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 12d06108d..3019b1d92 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -8,10 +8,14 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/mesh/actions/BuildParallelFields.h" + #include #include #include + +#include "eckit/exception/Exceptions.h" + +#include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" @@ -28,7 +32,6 @@ #include "atlas/runtime/Trace.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Unique.h" -#include "eckit/exception/Exceptions.h" #define EDGE( jedge ) \ "Edge(" << node_gidx( edge_nodes( jedge, 0 ) ) << "[p" << node_part( edge_nodes( jedge, 0 ) ) << "] " \ diff --git a/src/atlas/mesh/actions/BuildParallelFields.h b/src/atlas/mesh/actions/BuildParallelFields.h index 1b7774a7a..a01c9cb1a 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.h +++ b/src/atlas/mesh/actions/BuildParallelFields.h @@ -11,8 +11,7 @@ /// @author Willem Deconinck /// @date June 2014 -#ifndef BuildParallelFields_h -#define BuildParallelFields_h +#pragma once #include "atlas/library/config.h" #include "atlas/mesh/Mesh.h" @@ -72,5 +71,3 @@ void atlas__renumber_nodes_glb_idx( mesh::Nodes* nodes ); } // namespace actions } // namespace mesh } // namespace atlas - -#endif // BuildParallelFields_h diff --git a/src/atlas/mesh/actions/BuildPeriodicBoundaries.h b/src/atlas/mesh/actions/BuildPeriodicBoundaries.h index baaaa3459..ba0eda760 100644 --- a/src/atlas/mesh/actions/BuildPeriodicBoundaries.h +++ b/src/atlas/mesh/actions/BuildPeriodicBoundaries.h @@ -8,8 +8,7 @@ * nor does it submit to any jurisdiction. */ -#ifndef BuildPeriodicBoundaries_h -#define BuildPeriodicBoundaries_h +#pragma once namespace atlas { class Mesh; @@ -36,5 +35,3 @@ void atlas__build_periodic_boundaries( Mesh::Implementation* mesh ); } // namespace actions } // namespace mesh } // namespace atlas - -#endif // BuildPeriodicBoundaries_h diff --git a/src/atlas/mesh/actions/BuildStatistics.cc b/src/atlas/mesh/actions/BuildStatistics.cc index ca72ec7c4..6c6bfe4b9 100644 --- a/src/atlas/mesh/actions/BuildStatistics.cc +++ b/src/atlas/mesh/actions/BuildStatistics.cc @@ -14,6 +14,9 @@ #include #include #include + +#include "eckit/filesystem/PathName.h" + #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" @@ -29,7 +32,6 @@ #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" #include "atlas/util/Point.h" -#include "eckit/filesystem/PathName.h" namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/actions/BuildStatistics.h b/src/atlas/mesh/actions/BuildStatistics.h index 1f450d49b..009c94b66 100644 --- a/src/atlas/mesh/actions/BuildStatistics.h +++ b/src/atlas/mesh/actions/BuildStatistics.h @@ -8,8 +8,7 @@ * nor does it submit to any jurisdiction. */ -#ifndef BuildStatistics_h -#define BuildStatistics_h +#pragma once namespace atlas { class Mesh; @@ -29,5 +28,3 @@ void atlas__build_statistics( Mesh::Implementation* mesh ); } // namespace actions } // namespace mesh } // namespace atlas - -#endif // BuildStatistics_h diff --git a/src/atlas/mesh/actions/BuildTorusXYZField.h b/src/atlas/mesh/actions/BuildTorusXYZField.h index 5fed6ee96..93f34e9a8 100644 --- a/src/atlas/mesh/actions/BuildTorusXYZField.h +++ b/src/atlas/mesh/actions/BuildTorusXYZField.h @@ -8,8 +8,7 @@ * nor does it submit to any jurisdiction. */ -#ifndef atlas_actions_BuildTorusXYZField_h -#define atlas_actions_BuildTorusXYZField_h +#pragma once #include @@ -50,5 +49,3 @@ class BuildTorusXYZField { } // namespace actions } // namespace mesh } // namespace atlas - -#endif diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.cc b/src/atlas/mesh/actions/ExtendNodesGlobal.cc index 95be58893..84e67937a 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.cc +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.cc @@ -8,15 +8,15 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/mesh/actions/ExtendNodesGlobal.h" +#include "eckit/exception/Exceptions.h" +#include "atlas/mesh/actions/ExtendNodesGlobal.h" #include "atlas/field/Field.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" -#include "eckit/exception/Exceptions.h" namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc index a20d51d12..0f33a0c3f 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc @@ -11,9 +11,9 @@ #include #include -#include "atlas/parallel/mpi/mpi.h" #include "eckit/filesystem/PathName.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/IsGhostNode.h" #include "atlas/mesh/Mesh.h" diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.h b/src/atlas/mesh/actions/WriteLoadBalanceReport.h index 80cfa5ab2..8365e9a47 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.h +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.h @@ -8,8 +8,7 @@ * nor does it submit to any jurisdiction. */ -#ifndef atlas_WriteLoadBalanceReport_h -#define atlas_WriteLoadBalanceReport_h +#pragma once namespace atlas { class Mesh; @@ -31,5 +30,3 @@ void atlas__write_load_balance_report( Mesh::Implementation* mesh, char* filenam } // namespace actions } // namespace mesh } // namespace atlas - -#endif diff --git a/src/atlas/mesh/detail/AccumulateFacets.cc b/src/atlas/mesh/detail/AccumulateFacets.cc index ca6b2bbdc..c1e695cf8 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.cc +++ b/src/atlas/mesh/detail/AccumulateFacets.cc @@ -8,12 +8,13 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/exception/Exceptions.h" + #include "atlas/mesh/detail/AccumulateFacets.h" #include "atlas/mesh/Elements.h" #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Nodes.h" #include "atlas/runtime/Trace.h" -#include "eckit/exception/Exceptions.h" namespace atlas { namespace mesh { diff --git a/src/atlas/mesh/detail/AccumulateFacets.h b/src/atlas/mesh/detail/AccumulateFacets.h index 02910b602..ebbfa2fbd 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.h +++ b/src/atlas/mesh/detail/AccumulateFacets.h @@ -11,6 +11,7 @@ #pragma once #include + #include "atlas/library/config.h" namespace atlas { diff --git a/src/atlas/mesh/detail/MeshImpl.cc b/src/atlas/mesh/detail/MeshImpl.cc index 3b15d1090..68c54dc67 100644 --- a/src/atlas/mesh/detail/MeshImpl.cc +++ b/src/atlas/mesh/detail/MeshImpl.cc @@ -8,12 +8,12 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/mesh/detail/MeshImpl.h" #include #include "eckit/exception/Exceptions.h" #include "eckit/types/FloatCompare.h" +#include "atlas/mesh/detail/MeshImpl.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Elements.h" #include "atlas/mesh/HybridElements.h" diff --git a/src/atlas/meshgenerator/DelaunayMeshGenerator.cc b/src/atlas/meshgenerator/DelaunayMeshGenerator.cc index 055d2072d..4898fc12e 100644 --- a/src/atlas/meshgenerator/DelaunayMeshGenerator.cc +++ b/src/atlas/meshgenerator/DelaunayMeshGenerator.cc @@ -8,6 +8,8 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/utils/Hash.h" + #include "atlas/meshgenerator/DelaunayMeshGenerator.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" @@ -23,7 +25,6 @@ #include "atlas/projection/Projection.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/utils/Hash.h" using atlas::Mesh; diff --git a/src/atlas/meshgenerator/RegularMeshGenerator.cc b/src/atlas/meshgenerator/RegularMeshGenerator.cc index 26b4d80f1..fe86d8f53 100644 --- a/src/atlas/meshgenerator/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/RegularMeshGenerator.cc @@ -1,10 +1,13 @@ -#include "atlas/meshgenerator/RegularMeshGenerator.h" #include #include #include #include #include + +#include "eckit/utils/Hash.h" + +#include "atlas/meshgenerator/RegularMeshGenerator.h" #include "atlas/array/Array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" @@ -21,7 +24,6 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/utils/Hash.h" #define DEBUG_OUTPUT 0 #define DEBUG_OUTPUT_DETAIL 0 diff --git a/src/atlas/numerics/Method.cc b/src/atlas/numerics/Method.cc index 0588c54df..5524988b9 100644 --- a/src/atlas/numerics/Method.cc +++ b/src/atlas/numerics/Method.cc @@ -8,10 +8,11 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/exception/Exceptions.h" + #include "atlas/numerics/Method.h" #include "atlas/library/config.h" #include "atlas/runtime/ErrorHandling.h" -#include "eckit/exception/Exceptions.h" namespace atlas { namespace numerics { diff --git a/src/atlas/numerics/Method.h b/src/atlas/numerics/Method.h index c131e4ece..9a30354aa 100644 --- a/src/atlas/numerics/Method.h +++ b/src/atlas/numerics/Method.h @@ -11,6 +11,7 @@ #pragma once #include + #include "eckit/memory/Owned.h" namespace atlas { diff --git a/src/atlas/numerics/Nabla.cc b/src/atlas/numerics/Nabla.cc index 6c949e391..dce37108f 100644 --- a/src/atlas/numerics/Nabla.cc +++ b/src/atlas/numerics/Nabla.cc @@ -8,9 +8,14 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/numerics/Nabla.h" #include #include + +#include "eckit/exception/Exceptions.h" +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" + +#include "atlas/numerics/Nabla.h" #include "atlas/library/config.h" #include "atlas/numerics/Method.h" #include "atlas/numerics/fvm/Method.h" @@ -18,9 +23,6 @@ #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" #include "atlas/util/Config.h" -#include "eckit/exception/Exceptions.h" -#include "eckit/thread/AutoLock.h" -#include "eckit/thread/Mutex.h" namespace { diff --git a/src/atlas/numerics/fvm/Method.cc b/src/atlas/numerics/fvm/Method.cc index d34b97a3a..1dd1ee8ff 100644 --- a/src/atlas/numerics/fvm/Method.cc +++ b/src/atlas/numerics/fvm/Method.cc @@ -8,8 +8,11 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/numerics/fvm/Method.h" #include + +#include "eckit/exception/Exceptions.h" + +#include "atlas/numerics/fvm/Method.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/functionspace/EdgeColumns.h" @@ -24,7 +27,6 @@ #include "atlas/runtime/ErrorHandling.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" -#include "eckit/exception/Exceptions.h" // ======================================================= diff --git a/src/atlas/numerics/fvm/Method.h b/src/atlas/numerics/fvm/Method.h index 62e25103a..0a7942ed5 100644 --- a/src/atlas/numerics/fvm/Method.h +++ b/src/atlas/numerics/fvm/Method.h @@ -11,6 +11,7 @@ #pragma once #include + #include "atlas/functionspace/EdgeColumns.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/numerics/Method.h" diff --git a/src/atlas/numerics/fvm/Nabla.cc b/src/atlas/numerics/fvm/Nabla.cc index 7c28ff422..2db42a57b 100644 --- a/src/atlas/numerics/fvm/Nabla.cc +++ b/src/atlas/numerics/fvm/Nabla.cc @@ -8,6 +8,9 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/config/Parametrisation.h" +#include "eckit/exception/Exceptions.h" + #include "atlas/numerics/fvm/Nabla.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" @@ -19,8 +22,6 @@ #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/config/Parametrisation.h" -#include "eckit/exception/Exceptions.h" // ======================================================= diff --git a/src/atlas/numerics/fvm/Nabla.h b/src/atlas/numerics/fvm/Nabla.h index 1ad371145..b17f7c553 100644 --- a/src/atlas/numerics/fvm/Nabla.h +++ b/src/atlas/numerics/fvm/Nabla.h @@ -11,6 +11,7 @@ #pragma once #include + #include "atlas/numerics/Nabla.h" namespace atlas { diff --git a/src/atlas/output/Gmsh.cc b/src/atlas/output/Gmsh.cc index b99d23d31..ae003a6be 100644 --- a/src/atlas/output/Gmsh.cc +++ b/src/atlas/output/Gmsh.cc @@ -11,6 +11,8 @@ #include #include +#include "eckit/exception/Exceptions.h" + #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" @@ -21,7 +23,6 @@ #include "atlas/output/detail/GmshIO.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "eckit/exception/Exceptions.h" using atlas::Field; using atlas::FieldSet; diff --git a/src/atlas/output/Output.cc b/src/atlas/output/Output.cc index dcd0dea23..575217b03 100644 --- a/src/atlas/output/Output.cc +++ b/src/atlas/output/Output.cc @@ -11,6 +11,10 @@ #include #include +#include "eckit/exception/Exceptions.h" +#include "eckit/thread/AutoLock.h" +#include "eckit/thread/Mutex.h" + #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" @@ -19,9 +23,6 @@ #include "atlas/output/Output.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "eckit/exception/Exceptions.h" -#include "eckit/thread/AutoLock.h" -#include "eckit/thread/Mutex.h" using atlas::FieldSet; using atlas::FunctionSpace; diff --git a/src/atlas/output/Output.h b/src/atlas/output/Output.h index 1ec2ebdc3..72b04e874 100644 --- a/src/atlas/output/Output.h +++ b/src/atlas/output/Output.h @@ -12,12 +12,14 @@ #include #include -#include "atlas/util/Config.h" + #include "eckit/config/Parametrisation.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" #include "eckit/serialisation/FileStream.h" +#include "atlas/util/Config.h" + namespace eckit { class Parametrisation; class PathName; diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index 77ab3e2f8..fe871c8ec 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -8,12 +8,16 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/output/detail/GmshIO.h" #include #include #include #include #include + +#include "eckit/exception/Exceptions.h" +#include "eckit/filesystem/PathName.h" + +#include "atlas/output/detail/GmshIO.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" @@ -31,13 +35,10 @@ #include "atlas/runtime/Log.h" #include "atlas/util/Constants.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/exception/Exceptions.h" -#include "eckit/filesystem/PathName.h" -#include "eckit/utils/Translator.h" -using namespace eckit; using atlas::functionspace::NodeColumns; using atlas::util::Metadata; +using eckit::PathName; namespace atlas { namespace output { @@ -53,14 +54,13 @@ class GmshFile : public std::ofstream { PathName par_path( file_path ); if ( atlas::mpi::comm().size() == 1 || part == -1 ) { std::ofstream::open( par_path.localPath(), mode ); } else { - Translator to_str; if ( atlas::mpi::comm().rank() == 0 ) { PathName par_path( file_path ); std::ofstream par_file( par_path.localPath(), std::ios_base::out ); for ( size_t p = 0; p < atlas::mpi::comm().size(); ++p ) { PathName loc_path( file_path ); // loc_path = loc_path.baseName(false) + "_p" + to_str(p) + ".msh"; - loc_path = loc_path.baseName( false ) + ".msh.p" + to_str( p ); + loc_path = loc_path.baseName( false ) + ".msh.p" + std::to_string( p ); par_file << "Merge \"" << loc_path << "\";" << std::endl; } par_file.close(); @@ -68,7 +68,7 @@ class GmshFile : public std::ofstream { PathName path( file_path ); // path = path.dirName() + "/" + path.baseName(false) + "_p" + // to_str(part) + ".msh"; - path = path.dirName() + "/" + path.baseName( false ) + ".msh.p" + to_str( part ); + path = path.dirName() + "/" + path.baseName( false ) + ".msh.p" + std::to_string( part ); std::ofstream::open( path.localPath(), mode ); } } @@ -509,7 +509,7 @@ 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 eckit::CantOpenFile( file_path ); std::string line; @@ -711,7 +711,7 @@ void GmshIO::read( const PathName& file_path, Mesh& mesh ) const { break; default: std::cout << "etype " << etype << std::endl; - throw Exception( "ERROR: element type not supported", Here() ); + throw eckit::Exception( "ERROR: element type not supported", Here() ); } } } diff --git a/src/atlas/output/detail/GmshIO.h b/src/atlas/output/detail/GmshIO.h index 5396ae2b8..64613ceb5 100644 --- a/src/atlas/output/detail/GmshIO.h +++ b/src/atlas/output/detail/GmshIO.h @@ -13,6 +13,7 @@ #include #include #include + #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/StructuredColumns.h" #include "atlas/util/Metadata.h" diff --git a/src/atlas/output/detail/PointCloudIO.cc b/src/atlas/output/detail/PointCloudIO.cc index 8aeb4bf9b..39c9ddf89 100644 --- a/src/atlas/output/detail/PointCloudIO.cc +++ b/src/atlas/output/detail/PointCloudIO.cc @@ -8,11 +8,15 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/output/detail/PointCloudIO.h" #include #include #include #include + +#include "eckit/exception/Exceptions.h" +#include "eckit/filesystem/PathName.h" + +#include "atlas/output/detail/PointCloudIO.h" #include "atlas/array/ArrayView.h" #include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" @@ -23,8 +27,6 @@ #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/exception/Exceptions.h" -#include "eckit/filesystem/PathName.h" namespace atlas { namespace output { diff --git a/src/atlas/output/detail/PointCloudIO.h b/src/atlas/output/detail/PointCloudIO.h index 3c3e4e309..bf8af5f52 100644 --- a/src/atlas/output/detail/PointCloudIO.h +++ b/src/atlas/output/detail/PointCloudIO.h @@ -12,6 +12,7 @@ #include #include + #include "atlas/util/Point.h" // forward declarations diff --git a/src/atlas/parallel/Checksum.cc b/src/atlas/parallel/Checksum.cc index bb0db51d0..120503003 100644 --- a/src/atlas/parallel/Checksum.cc +++ b/src/atlas/parallel/Checksum.cc @@ -8,9 +8,10 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/parallel/Checksum.h" #include +#include "atlas/parallel/Checksum.h" + namespace atlas { namespace parallel { diff --git a/src/atlas/parallel/Checksum.h b/src/atlas/parallel/Checksum.h index 1446236a5..db5289a40 100644 --- a/src/atlas/parallel/Checksum.h +++ b/src/atlas/parallel/Checksum.h @@ -8,18 +8,19 @@ * nor does it submit to any jurisdiction. */ -#ifndef Checksum_h -#define Checksum_h +#pragma once #include + +#include "eckit/memory/Owned.h" +#include "eckit/memory/SharedPtr.h" +#include "eckit/utils/Translator.h" + #include "atlas/array/ArrayView.h" #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/util/Checksum.h" -#include "eckit/memory/Owned.h" -#include "eckit/memory/SharedPtr.h" -#include "eckit/utils/Translator.h" namespace atlas { namespace parallel { @@ -169,5 +170,3 @@ void atlas__Checksum__execute_strided_double( Checksum* This, double lfield[], i } // namespace parallel } // namespace atlas - -#endif // Checksum_h diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index 2c5649da2..01e727b09 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -8,11 +8,12 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/parallel/GatherScatter.h" #include #include #include #include + +#include "atlas/parallel/GatherScatter.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/parallel/mpi/Statistics.h" diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index 006b1d652..d3a1f1f40 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -8,16 +8,15 @@ * nor does it submit to any jurisdiction. */ -#ifndef Gather_h -#define Gather_h +#pragma once #include #include -#include "atlas/parallel/mpi/mpi.h" #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/array/ArrayView.h" #include "atlas/library/config.h" #include "atlas/runtime/Log.h" @@ -511,5 +510,3 @@ void atlas__GatherScatter__scatter_double( GatherScatter* This, double gdata[], } // namespace parallel } // namespace atlas - -#endif // Gather_h diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 039506da3..1772b6e73 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -11,10 +11,11 @@ /// @author Willem Deconinck /// @date Nov 2013 -#include "atlas/parallel/HaloExchange.h" #include #include #include + +#include "atlas/parallel/HaloExchange.h" #include "atlas/array/Array.h" #include "atlas/parallel/mpi/Statistics.h" diff --git a/src/atlas/parallel/HaloExchange.h b/src/atlas/parallel/HaloExchange.h index 6eb87f8dd..92b26b6f1 100644 --- a/src/atlas/parallel/HaloExchange.h +++ b/src/atlas/parallel/HaloExchange.h @@ -11,8 +11,7 @@ /// @author Willem Deconinck /// @date Nov 2013 -#ifndef HaloExchange_h -#define HaloExchange_h +#pragma once #include #include @@ -273,5 +272,3 @@ void atlas__HaloExchange__execute_double( HaloExchange* This, double field[], in } // namespace parallel } // namespace atlas - -#endif // HaloExchange_h diff --git a/src/atlas/parallel/HaloExchangeCUDA.h b/src/atlas/parallel/HaloExchangeCUDA.h index b606bb8ac..3d9b45f6b 100644 --- a/src/atlas/parallel/HaloExchangeCUDA.h +++ b/src/atlas/parallel/HaloExchangeCUDA.h @@ -1,5 +1,3 @@ -#pragma once - /* * (C) Copyright 2013 ECMWF. * @@ -9,6 +7,9 @@ * granted to it by virtue of its status as an intergovernmental organisation * nor does it submit to any jurisdiction. */ + +#pragma once + #include "atlas/array/ArrayView.h" #include "atlas/array/ArrayViewDefs.h" #include "atlas/array/SVector.h" diff --git a/src/atlas/parallel/HaloExchangeImpl.h b/src/atlas/parallel/HaloExchangeImpl.h index 94c2b7d45..59c15e908 100644 --- a/src/atlas/parallel/HaloExchangeImpl.h +++ b/src/atlas/parallel/HaloExchangeImpl.h @@ -1,5 +1,3 @@ -#pragma once - /* * (C) Copyright 2013 ECMWF. * @@ -9,6 +7,9 @@ * granted to it by virtue of its status as an intergovernmental organisation * nor does it submit to any jurisdiction. */ + +#pragma once + #include "atlas/array/ArrayView.h" #include "atlas/array/SVector.h" diff --git a/src/atlas/parallel/mpi/Statistics.h b/src/atlas/parallel/mpi/Statistics.h index 349230ff9..8b8d7a422 100644 --- a/src/atlas/parallel/mpi/Statistics.h +++ b/src/atlas/parallel/mpi/Statistics.h @@ -11,6 +11,7 @@ #pragma once #include + #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Trace.h" diff --git a/src/atlas/parallel/mpi/mpi.h b/src/atlas/parallel/mpi/mpi.h index e1d5cd174..03dc7c53c 100644 --- a/src/atlas/parallel/mpi/mpi.h +++ b/src/atlas/parallel/mpi/mpi.h @@ -10,9 +10,10 @@ #pragma once -#include "atlas/parallel/mpi/Statistics.h" #include "eckit/mpi/Comm.h" +#include "atlas/parallel/mpi/Statistics.h" + namespace atlas { namespace mpi { diff --git a/src/atlas/projection/Projection.cc b/src/atlas/projection/Projection.cc index c46090c9f..2366fe3b7 100644 --- a/src/atlas/projection/Projection.cc +++ b/src/atlas/projection/Projection.cc @@ -1,3 +1,13 @@ +/* + * (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 "atlas/projection/Projection.h" namespace atlas { diff --git a/src/atlas/projection/Projection.h b/src/atlas/projection/Projection.h index 931d35810..ed1797a3f 100644 --- a/src/atlas/projection/Projection.h +++ b/src/atlas/projection/Projection.h @@ -1,6 +1,17 @@ +/* + * (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 + #include "eckit/config/Parametrisation.h" #include "eckit/memory/SharedPtr.h" #include "eckit/utils/Hash.h" diff --git a/src/atlas/projection/detail/LambertProjection.cc b/src/atlas/projection/detail/LambertProjection.cc index e32f536c9..e80502ded 100644 --- a/src/atlas/projection/detail/LambertProjection.cc +++ b/src/atlas/projection/detail/LambertProjection.cc @@ -1,5 +1,16 @@ -#include "atlas/projection/detail/LambertProjection.h" +/* + * (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 + +#include "atlas/projection/detail/LambertProjection.h" #include "atlas/util/Constants.h" #include "atlas/util/Earth.h" diff --git a/src/atlas/projection/detail/LambertProjection.h b/src/atlas/projection/detail/LambertProjection.h index 9e80cc569..71975cf6a 100644 --- a/src/atlas/projection/detail/LambertProjection.h +++ b/src/atlas/projection/detail/LambertProjection.h @@ -1,3 +1,13 @@ +/* + * (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/projection/detail/ProjectionImpl.h" diff --git a/src/atlas/projection/detail/LonLatProjection.cc b/src/atlas/projection/detail/LonLatProjection.cc index 7b17d5d33..aa19fe94b 100644 --- a/src/atlas/projection/detail/LonLatProjection.cc +++ b/src/atlas/projection/detail/LonLatProjection.cc @@ -1,3 +1,13 @@ +/* + * (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 "atlas/projection/detail/LonLatProjection.h" namespace atlas { diff --git a/src/atlas/projection/detail/LonLatProjection.h b/src/atlas/projection/detail/LonLatProjection.h index 987db83de..5208c23ef 100644 --- a/src/atlas/projection/detail/LonLatProjection.h +++ b/src/atlas/projection/detail/LonLatProjection.h @@ -1,3 +1,13 @@ +/* + * (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/projection/detail/ProjectionImpl.h" diff --git a/src/atlas/projection/detail/MercatorProjection.cc b/src/atlas/projection/detail/MercatorProjection.cc index 30459d4df..3d2c0416b 100644 --- a/src/atlas/projection/detail/MercatorProjection.cc +++ b/src/atlas/projection/detail/MercatorProjection.cc @@ -1,5 +1,16 @@ -#include "atlas/projection/detail/MercatorProjection.h" +/* + * (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 + +#include "atlas/projection/detail/MercatorProjection.h" #include "atlas/util/Constants.h" #include "atlas/util/Earth.h" diff --git a/src/atlas/projection/detail/MercatorProjection.h b/src/atlas/projection/detail/MercatorProjection.h index b52d17651..de50b37de 100644 --- a/src/atlas/projection/detail/MercatorProjection.h +++ b/src/atlas/projection/detail/MercatorProjection.h @@ -1,3 +1,13 @@ +/* + * (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/projection/detail/ProjectionImpl.h" diff --git a/src/atlas/projection/detail/ProjectionImpl.cc b/src/atlas/projection/detail/ProjectionImpl.cc index e795e0525..40f2b8c35 100644 --- a/src/atlas/projection/detail/ProjectionImpl.cc +++ b/src/atlas/projection/detail/ProjectionImpl.cc @@ -1,3 +1,13 @@ +/* + * (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 "atlas/projection/detail/ProjectionImpl.h" #include "atlas/projection/detail/LonLatProjection.h" #include "atlas/util/Config.h" diff --git a/src/atlas/projection/detail/ProjectionImpl.h b/src/atlas/projection/detail/ProjectionImpl.h index e3229b015..4d11b8114 100644 --- a/src/atlas/projection/detail/ProjectionImpl.h +++ b/src/atlas/projection/detail/ProjectionImpl.h @@ -1,14 +1,26 @@ +/* + * (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 -#include "atlas/util/Config.h" -#include "atlas/util/Point.h" -#include "atlas/util/Rotation.h" + #include "eckit/config/Parametrisation.h" #include "eckit/memory/Builder.h" #include "eckit/memory/Owned.h" #include "eckit/utils/Hash.h" +#include "atlas/util/Config.h" +#include "atlas/util/Point.h" +#include "atlas/util/Rotation.h" + namespace atlas { namespace projection { namespace detail { diff --git a/src/atlas/projection/detail/SchmidtProjection.cc b/src/atlas/projection/detail/SchmidtProjection.cc index 2c943327f..adfca413b 100644 --- a/src/atlas/projection/detail/SchmidtProjection.cc +++ b/src/atlas/projection/detail/SchmidtProjection.cc @@ -1,5 +1,16 @@ -#include "atlas/projection/detail/SchmidtProjection.h" +/* + * (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 + +#include "atlas/projection/detail/SchmidtProjection.h" #include "atlas/util/Constants.h" namespace { diff --git a/src/atlas/projection/detail/SchmidtProjection.h b/src/atlas/projection/detail/SchmidtProjection.h index 8e9003d48..53ffe62a3 100644 --- a/src/atlas/projection/detail/SchmidtProjection.h +++ b/src/atlas/projection/detail/SchmidtProjection.h @@ -1,3 +1,13 @@ +/* + * (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/projection/detail/ProjectionImpl.h" diff --git a/src/atlas/runtime/AtlasTool.cc b/src/atlas/runtime/AtlasTool.cc index b44cf5c0c..62f95a8ba 100644 --- a/src/atlas/runtime/AtlasTool.cc +++ b/src/atlas/runtime/AtlasTool.cc @@ -1,11 +1,21 @@ +/* + * (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 #include "eckit/config/LibEcKit.h" +#include "eckit/log/FileTarget.h" +#include "eckit/log/PrefixTarget.h" #include "atlas/library/config.h" #include "atlas/runtime/AtlasTool.h" -#include "eckit/log/FileTarget.h" -#include "eckit/log/PrefixTarget.h" namespace { diff --git a/src/atlas/runtime/ErrorHandling.cc b/src/atlas/runtime/ErrorHandling.cc index 88e00333c..191014028 100644 --- a/src/atlas/runtime/ErrorHandling.cc +++ b/src/atlas/runtime/ErrorHandling.cc @@ -1,10 +1,11 @@ -#include "atlas/runtime/ErrorHandling.h" -#include "atlas/parallel/mpi/mpi.h" -#include "atlas/runtime/Log.h" #include "eckit/log/CodeLocation.h" #include "eckit/os/BackTrace.h" #include "eckit/utils/Translator.h" +#include "atlas/runtime/ErrorHandling.h" +#include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Log.h" + using namespace atlas; namespace { // anonymous diff --git a/src/atlas/runtime/Log.cc b/src/atlas/runtime/Log.cc index 8fdf27c58..bffdd7324 100644 --- a/src/atlas/runtime/Log.cc +++ b/src/atlas/runtime/Log.cc @@ -8,9 +8,10 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/os/BackTrace.h" + #include "atlas/runtime/Log.h" #include "atlas/parallel/mpi/mpi.h" -#include "eckit/os/BackTrace.h" namespace atlas { diff --git a/src/atlas/runtime/Log.h b/src/atlas/runtime/Log.h index 82271b290..1bb467bcf 100644 --- a/src/atlas/runtime/Log.h +++ b/src/atlas/runtime/Log.h @@ -1,7 +1,6 @@ #pragma once #include "atlas/library/config.h" - #include "atlas/library/Library.h" #if ATLAS_HAVE_FORTRAN diff --git a/src/atlas/runtime/trace/Barriers.cc b/src/atlas/runtime/trace/Barriers.cc index 8f791f1b0..7df95a173 100644 --- a/src/atlas/runtime/trace/Barriers.cc +++ b/src/atlas/runtime/trace/Barriers.cc @@ -9,7 +9,9 @@ */ #include "Barriers.h" + #include + #include "atlas/library/Library.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/trace/StopWatch.h" diff --git a/src/atlas/runtime/trace/Barriers.h b/src/atlas/runtime/trace/Barriers.h index 6863c6418..5024314e3 100644 --- a/src/atlas/runtime/trace/Barriers.h +++ b/src/atlas/runtime/trace/Barriers.h @@ -9,6 +9,7 @@ */ #pragma once + #include //----------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/runtime/trace/CallStack.cc b/src/atlas/runtime/trace/CallStack.cc index 9e18301fb..bb2c043d5 100644 --- a/src/atlas/runtime/trace/CallStack.cc +++ b/src/atlas/runtime/trace/CallStack.cc @@ -1,7 +1,8 @@ +#include "CallStack.h" + #include -#include "CallStack.h" #include "eckit/log/CodeLocation.h" namespace atlas { diff --git a/src/atlas/runtime/trace/Logging.cc b/src/atlas/runtime/trace/Logging.cc index 2991b8bca..3a5963278 100644 --- a/src/atlas/runtime/trace/Logging.cc +++ b/src/atlas/runtime/trace/Logging.cc @@ -11,9 +11,11 @@ #include "Logging.h" #include -#include "atlas/library/Library.h" + #include "eckit/log/Channel.h" +#include "atlas/library/Library.h" + //----------------------------------------------------------------------------------------------------------- namespace atlas { diff --git a/src/atlas/runtime/trace/Nesting.h b/src/atlas/runtime/trace/Nesting.h index 7070662dd..ae8a5effd 100644 --- a/src/atlas/runtime/trace/Nesting.h +++ b/src/atlas/runtime/trace/Nesting.h @@ -10,9 +10,10 @@ #pragma once -#include "atlas/runtime/trace/CallStack.h" #include "eckit/log/CodeLocation.h" +#include "atlas/runtime/trace/CallStack.h" + //----------------------------------------------------------------------------------------------------------- namespace atlas { diff --git a/src/atlas/runtime/trace/Timings.cc b/src/atlas/runtime/trace/Timings.cc index 5f77cc095..d3cb5c599 100644 --- a/src/atlas/runtime/trace/Timings.cc +++ b/src/atlas/runtime/trace/Timings.cc @@ -8,18 +8,21 @@ * nor does it submit to any jurisdiction. */ + +#include "Timings.h" + #include #include #include #include #include -#include "Timings.h" +#include "eckit/config/Configuration.h" +#include "eckit/filesystem/PathName.h" + #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/trace/CallStack.h" #include "atlas/util/Config.h" -#include "eckit/config/Configuration.h" -#include "eckit/filesystem/PathName.h" //----------------------------------------------------------------------------------------------------------- diff --git a/src/atlas/runtime/trace/TraceT.h b/src/atlas/runtime/trace/TraceT.h index f05edfb85..672f14af6 100644 --- a/src/atlas/runtime/trace/TraceT.h +++ b/src/atlas/runtime/trace/TraceT.h @@ -13,6 +13,7 @@ #include #include #include + #include "atlas/runtime/trace/Nesting.h" #include "atlas/runtime/trace/StopWatch.h" #include "atlas/runtime/trace/Timings.h" diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index 14992ecc4..c4559713c 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -17,8 +17,10 @@ #include "atlas/grid/Grid.h" #include "atlas/runtime/Log.h" #include "atlas/trans/Trans.h" +#include "atlas/library/defines.h" -#ifdef ATLAS_HAVE_TRANS +// For factory registration only: +#if ATLAS_HAVE_TRANS #include "atlas/trans/ifs/TransIFSNodeColumns.h" #include "atlas/trans/ifs/TransIFSStructuredColumns.h" #define TRANS_DEFAULT "ifs" @@ -54,7 +56,7 @@ void load_builder_grid() { struct force_link { force_link() { -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS load_builder_functionspace(); load_builder_functionspace(); load_builder_grid(); diff --git a/src/atlas/trans/VorDivToUV.cc b/src/atlas/trans/VorDivToUV.cc index b51d7a405..430f5e162 100644 --- a/src/atlas/trans/VorDivToUV.cc +++ b/src/atlas/trans/VorDivToUV.cc @@ -17,8 +17,10 @@ #include "atlas/grid/Grid.h" #include "atlas/runtime/Log.h" #include "atlas/trans/VorDivToUV.h" +#include "atlas/library/defines.h" -#ifdef ATLAS_HAVE_TRANS +// For factory registration only +#if ATLAS_HAVE_TRANS #include "atlas/trans/ifs/VorDivToUVIFS.h" #define TRANS_DEFAULT "ifs" #else @@ -49,7 +51,7 @@ void load_builder() { struct force_link { force_link() { -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS load_builder(); #endif load_builder(); diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index f67013b5b..ce94496d1 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -8,8 +8,9 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/trans/ifs/TransIFS.h" +#include "eckit/parser/JSON.h" +#include "atlas/trans/ifs/TransIFS.h" #include "atlas/array.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/Spectral.h" @@ -19,7 +20,6 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" -#include "eckit/parser/JSON.h" using Topology = atlas::mesh::Nodes::Topology; using atlas::Field; diff --git a/src/atlas/trans/ifs/TransIFS.h b/src/atlas/trans/ifs/TransIFS.h index da91a425a..8d4835180 100644 --- a/src/atlas/trans/ifs/TransIFS.h +++ b/src/atlas/trans/ifs/TransIFS.h @@ -10,11 +10,13 @@ #pragma once +#include "transi/trans.h" + +#include "eckit/filesystem/PathName.h" + #include "atlas/array/LocalView.h" #include "atlas/grid/Grid.h" #include "atlas/trans/Trans.h" -#include "eckit/filesystem/PathName.h" -#include "transi/trans.h" //----------------------------------------------------------------------------- // Forward declarations diff --git a/src/atlas/trans/ifs/TransIFSNodeColumns.cc b/src/atlas/trans/ifs/TransIFSNodeColumns.cc index fd7835f5d..ffe475bcd 100644 --- a/src/atlas/trans/ifs/TransIFSNodeColumns.cc +++ b/src/atlas/trans/ifs/TransIFSNodeColumns.cc @@ -9,7 +9,6 @@ */ #include "atlas/trans/ifs/TransIFSNodeColumns.h" - #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/Spectral.h" diff --git a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc index e29f4bcb1..6594a42f8 100644 --- a/src/atlas/trans/ifs/TransIFSStructuredColumns.cc +++ b/src/atlas/trans/ifs/TransIFSStructuredColumns.cc @@ -9,7 +9,6 @@ */ #include "atlas/trans/ifs/TransIFSStructuredColumns.h" - #include "atlas/functionspace/Spectral.h" #include "atlas/functionspace/StructuredColumns.h" diff --git a/src/atlas/trans/ifs/VorDivToUVIFS.cc b/src/atlas/trans/ifs/VorDivToUVIFS.cc index 24d084b80..75e052afd 100644 --- a/src/atlas/trans/ifs/VorDivToUVIFS.cc +++ b/src/atlas/trans/ifs/VorDivToUVIFS.cc @@ -9,7 +9,6 @@ */ #include "atlas/trans/ifs/VorDivToUVIFS.h" - #include "atlas/functionspace/Spectral.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" diff --git a/src/atlas/trans/ifs/VorDivToUVIFS.h b/src/atlas/trans/ifs/VorDivToUVIFS.h index 613a9a2fa..d901afb11 100644 --- a/src/atlas/trans/ifs/VorDivToUVIFS.h +++ b/src/atlas/trans/ifs/VorDivToUVIFS.h @@ -10,9 +10,10 @@ #pragma once -#include "atlas/trans/VorDivToUV.h" #include "transi/trans.h" +#include "atlas/trans/VorDivToUV.h" + //----------------------------------------------------------------------------- // Forward declarations diff --git a/src/atlas/trans/local/FourierTransforms.cc b/src/atlas/trans/local/FourierTransforms.cc index 2baf32859..886cc2ee7 100644 --- a/src/atlas/trans/local/FourierTransforms.cc +++ b/src/atlas/trans/local/FourierTransforms.cc @@ -9,11 +9,12 @@ * does it submit to any jurisdiction. */ -#include "atlas/trans/local/FourierTransforms.h" #include #include #include +#include "atlas/trans/local/FourierTransforms.h" + namespace atlas { namespace trans { diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index bc32b82f0..5674924bb 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -9,9 +9,10 @@ * does it submit to any jurisdiction. */ -#include "atlas/trans/local/LegendrePolynomials.h" #include #include + +#include "atlas/trans/local/LegendrePolynomials.h" #include "atlas/array.h" namespace atlas { diff --git a/src/atlas/trans/local/LegendreTransforms.cc b/src/atlas/trans/local/LegendreTransforms.cc index 4ddb4f0bb..b18d28ca8 100644 --- a/src/atlas/trans/local/LegendreTransforms.cc +++ b/src/atlas/trans/local/LegendreTransforms.cc @@ -8,9 +8,10 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/trans/local/LegendreTransforms.h" #include +#include "atlas/trans/local/LegendreTransforms.h" + namespace atlas { namespace trans { diff --git a/src/atlas/trans/local/TransLocal.cc b/src/atlas/trans/local/TransLocal.cc index d4b7f3cb7..8a6828c85 100644 --- a/src/atlas/trans/local/TransLocal.cc +++ b/src/atlas/trans/local/TransLocal.cc @@ -9,7 +9,6 @@ */ #include "atlas/trans/local/TransLocal.h" - #include "atlas/array.h" #include "atlas/option.h" #include "atlas/parallel/mpi/mpi.h" diff --git a/src/atlas/trans/local/TransLocal.h b/src/atlas/trans/local/TransLocal.h index 4ecedf6e5..4295cff71 100644 --- a/src/atlas/trans/local/TransLocal.h +++ b/src/atlas/trans/local/TransLocal.h @@ -11,6 +11,7 @@ #pragma once #include + #include "atlas/grid/Grid.h" #include "atlas/trans/Trans.h" diff --git a/src/atlas/trans/local/VorDivToUVLocal.cc b/src/atlas/trans/local/VorDivToUVLocal.cc index bed717bf0..39d9cfa12 100644 --- a/src/atlas/trans/local/VorDivToUVLocal.cc +++ b/src/atlas/trans/local/VorDivToUVLocal.cc @@ -9,7 +9,6 @@ */ #include "atlas/trans/local/VorDivToUVLocal.h" - #include "atlas/functionspace/Spectral.h" #include "atlas/runtime/Log.h" #include "atlas/util/Earth.h" diff --git a/src/atlas/util/Checksum.cc b/src/atlas/util/Checksum.cc index 52268fe36..955a91ee8 100644 --- a/src/atlas/util/Checksum.cc +++ b/src/atlas/util/Checksum.cc @@ -1,8 +1,9 @@ -#include "atlas/util/Checksum.h" #include #include +#include "atlas/util/Checksum.h" + namespace atlas { namespace util { namespace { // anonymous diff --git a/src/atlas/util/Config.cc b/src/atlas/util/Config.cc index 156a2233f..0f4b6b36f 100644 --- a/src/atlas/util/Config.cc +++ b/src/atlas/util/Config.cc @@ -8,19 +8,21 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/util/Config.h" #include #include #include #include -#include "atlas/grid/Grid.h" -#include "atlas/mesh/Mesh.h" -#include "atlas/runtime/ErrorHandling.h" + #include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" #include "eckit/parser/JSON.h" #include "eckit/parser/YAMLParser.h" +#include "atlas/util/Config.h" +#include "atlas/grid/Grid.h" +#include "atlas/mesh/Mesh.h" +#include "atlas/runtime/ErrorHandling.h" + using std::string; namespace atlas { diff --git a/src/atlas/util/Config.h b/src/atlas/util/Config.h index ad4120496..bf498698d 100644 --- a/src/atlas/util/Config.h +++ b/src/atlas/util/Config.h @@ -8,15 +8,15 @@ * nor does it submit to any jurisdiction. */ -#ifndef atlas_Config_h -#define atlas_Config_h - +#pragma once #include #include -#include "atlas/util/Metadata.h" + #include "eckit/config/Parametrisation.h" #include "eckit/utils/Hash.h" +#include "atlas/util/Metadata.h" + namespace eckit { class PathName; } @@ -151,5 +151,3 @@ class NoConfig : public Config { } // namespace util } // namespace atlas - -#endif // Parametrisation_h diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index 0c3256986..5ebb25738 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -8,16 +8,16 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/util/Earth.h" - #include #include -#include "atlas/util/Constants.h" -#include "atlas/util/Point.h" #include "eckit/exception/Exceptions.h" #include "eckit/types/FloatCompare.h" +#include "atlas/util/Earth.h" +#include "atlas/util/Constants.h" +#include "atlas/util/Point.h" + namespace atlas { namespace util { diff --git a/src/atlas/util/GaussianLatitudes.h b/src/atlas/util/GaussianLatitudes.h index ef5607f10..f14e0bb82 100644 --- a/src/atlas/util/GaussianLatitudes.h +++ b/src/atlas/util/GaussianLatitudes.h @@ -12,6 +12,7 @@ /// @date Jan 2014 #pragma once + #include namespace atlas { diff --git a/src/atlas/util/LonLatPolygon.cc b/src/atlas/util/LonLatPolygon.cc index 2dc5e4c31..8c9103cb9 100644 --- a/src/atlas/util/LonLatPolygon.cc +++ b/src/atlas/util/LonLatPolygon.cc @@ -8,12 +8,13 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/util/LonLatPolygon.h" #include #include #include #include + +#include "atlas/util/LonLatPolygon.h" #include "atlas/util/CoordinateEnums.h" namespace atlas { diff --git a/src/atlas/util/LonLatPolygon.h b/src/atlas/util/LonLatPolygon.h index 0478c5c9f..0076eb59b 100644 --- a/src/atlas/util/LonLatPolygon.h +++ b/src/atlas/util/LonLatPolygon.h @@ -11,6 +11,7 @@ #pragma once #include + #include "atlas/util/Polygon.h" namespace atlas { diff --git a/src/atlas/util/Metadata.cc b/src/atlas/util/Metadata.cc index 356b3ddf3..829621164 100644 --- a/src/atlas/util/Metadata.cc +++ b/src/atlas/util/Metadata.cc @@ -14,12 +14,13 @@ #include #include -#include "atlas/parallel/mpi/mpi.h" #include "eckit/exception/Exceptions.h" #include "eckit/parser/JSON.h" #include "eckit/parser/JSONParser.h" #include "eckit/utils/Hash.h" + +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" using std::string; diff --git a/src/atlas/util/Metadata.h b/src/atlas/util/Metadata.h index a7257833c..3c60a41e8 100644 --- a/src/atlas/util/Metadata.h +++ b/src/atlas/util/Metadata.h @@ -10,11 +10,12 @@ #pragma once -#include #include "eckit/config/LocalConfiguration.h" #include "eckit/config/Parametrisation.h" #include "eckit/utils/Hash.h" +#include + namespace atlas { namespace util { diff --git a/src/atlas/util/Point.h b/src/atlas/util/Point.h index 4cb22c012..c5ba433bb 100644 --- a/src/atlas/util/Point.h +++ b/src/atlas/util/Point.h @@ -18,10 +18,12 @@ #include #include -#include "atlas/util/Earth.h" + #include "eckit/geometry/Point2.h" #include "eckit/geometry/Point3.h" +#include "atlas/util/Earth.h" + namespace atlas { using Point2 = eckit::geometry::Point2; diff --git a/src/atlas/util/Polygon.cc b/src/atlas/util/Polygon.cc index 228b129dd..2a924a332 100644 --- a/src/atlas/util/Polygon.cc +++ b/src/atlas/util/Polygon.cc @@ -8,17 +8,18 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/util/Polygon.h" - #include #include #include #include -#include "atlas/mesh/Nodes.h" -#include "atlas/util/CoordinateEnums.h" + #include "eckit/exception/Exceptions.h" #include "eckit/types/FloatCompare.h" +#include "atlas/util/Polygon.h" +#include "atlas/mesh/Nodes.h" +#include "atlas/util/CoordinateEnums.h" + namespace atlas { namespace util { diff --git a/src/atlas/util/Polygon.h b/src/atlas/util/Polygon.h index 1675e7117..953233b25 100644 --- a/src/atlas/util/Polygon.h +++ b/src/atlas/util/Polygon.h @@ -18,6 +18,7 @@ #include #include #include + #include "atlas/library/config.h" #include "atlas/util/Point.h" diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index 3c5fb2e03..ba4e8d5bb 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -8,14 +8,15 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/util/Rotation.h" - #include #include + +#include "eckit/config/Parametrisation.h" + +#include "atlas/util/Rotation.h" #include "atlas/util/Constants.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" -#include "eckit/config/Parametrisation.h" // Temporary option to activate implementation by RMI during ESCAPE #define OLD_IMPLEMENTATION 0 diff --git a/src/atlas/util/Rotation.h b/src/atlas/util/Rotation.h index 7fe90d727..0a797177f 100644 --- a/src/atlas/util/Rotation.h +++ b/src/atlas/util/Rotation.h @@ -12,6 +12,7 @@ #include #include + #include "atlas/util/Point.h" namespace eckit { diff --git a/src/atlas/util/SphericalPolygon.cc b/src/atlas/util/SphericalPolygon.cc index e50c5beab..79c50103e 100644 --- a/src/atlas/util/SphericalPolygon.cc +++ b/src/atlas/util/SphericalPolygon.cc @@ -8,15 +8,16 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/util/SphericalPolygon.h" - #include #include #include #include -#include "atlas/util/CoordinateEnums.h" + #include "eckit/types/FloatCompare.h" +#include "atlas/util/SphericalPolygon.h" +#include "atlas/util/CoordinateEnums.h" + namespace atlas { namespace util { diff --git a/src/atlas/util/SphericalPolygon.h b/src/atlas/util/SphericalPolygon.h index a839d87bc..5e1f5c46e 100644 --- a/src/atlas/util/SphericalPolygon.h +++ b/src/atlas/util/SphericalPolygon.h @@ -11,6 +11,7 @@ #pragma once #include + #include "atlas/util/Polygon.h" namespace atlas { diff --git a/src/atlas/util/detail/Cache.h b/src/atlas/util/detail/Cache.h index 039d5304c..828343ec4 100644 --- a/src/atlas/util/detail/Cache.h +++ b/src/atlas/util/detail/Cache.h @@ -12,9 +12,11 @@ #include #include #include -#include "atlas/runtime/Log.h" + #include "eckit/memory/SharedPtr.h" +#include "atlas/runtime/Log.h" + namespace atlas { namespace util { diff --git a/src/atlas/util/detail/Debug.h b/src/atlas/util/detail/Debug.h index b6d67017a..39638f967 100644 --- a/src/atlas/util/detail/Debug.h +++ b/src/atlas/util/detail/Debug.h @@ -1,8 +1,9 @@ +#include "eckit/config/Resource.h" + #include "atlas/field.h" #include "atlas/functionspace.h" #include "atlas/mesh.h" #include "atlas/parallel/mpi/mpi.h" -#include "eckit/config/Resource.h" namespace atlas { namespace debug { diff --git a/src/atlas_acc_support/atlas_acc_map_data.h b/src/atlas_acc_support/atlas_acc_map_data.h index 892ebc774..257f1687d 100644 --- a/src/atlas_acc_support/atlas_acc_map_data.h +++ b/src/atlas_acc_support/atlas_acc_map_data.h @@ -1,3 +1,13 @@ +/* + * (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 #ifdef __cplusplus diff --git a/src/atlas_f/atlas_f.h.in b/src/atlas_f/atlas_f.h.in index 4d9f369cd..ac3148cb4 100644 --- a/src/atlas_f/atlas_f.h.in +++ b/src/atlas_f/atlas_f.h.in @@ -3,16 +3,9 @@ #include "fckit/fckit.h" -#define ATLAS_HAVE_OMP @ATLAS_HAVE_OMP@ - -#if @ATLAS_HAVE_TRANS@ -#define ATLAS_HAVE_TRANS -#endif - -#if @ATLAS_HAVE_ACC@ -#define ATLAS_HAVE_ACC -#endif - +#define ATLAS_HAVE_OMP @ATLAS_HAVE_OMP@ +#define ATLAS_HAVE_TRANS @ATLAS_HAVE_TRANS@ +#define ATLAS_HAVE_ACC @ATLAS_HAVE_ACC@ #define ATLAS_BITS_GLOBAL @ATLAS_BITS_GLOBAL@ #endif diff --git a/src/atlas_f/trans/atlas_Trans_module.F90 b/src/atlas_f/trans/atlas_Trans_module.F90 index ff0c0e92e..25ee8ee34 100644 --- a/src/atlas_f/trans/atlas_Trans_module.F90 +++ b/src/atlas_f/trans/atlas_Trans_module.F90 @@ -113,7 +113,7 @@ function atlas_Trans__ctor( grid, nsmax ) result(this) type(atlas_Trans) :: this class(atlas_Grid), intent(in) :: grid integer, intent(in), optional :: nsmax -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS if( present(nsmax) ) then call this%reset_c_ptr( atlas__Trans__new( grid%c_ptr(), nsmax ) ) else @@ -132,7 +132,7 @@ function handle( this ) use atlas_trans_c_binding integer :: handle class(atlas_Trans) :: this -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS handle = atlas__Trans__handle (this%c_ptr()) #else THROW_ERROR @@ -145,7 +145,7 @@ function truncation( this ) use atlas_trans_c_binding integer :: truncation class(atlas_Trans) :: this -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS truncation = atlas__Trans__truncation (this%c_ptr()) #else THROW_ERROR @@ -158,7 +158,7 @@ function nb_spectral_coefficients( this ) use atlas_trans_c_binding integer :: nb_spectral_coefficients class(atlas_Trans) :: this -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS nb_spectral_coefficients = atlas__Trans__nspec2 (this%c_ptr()) #else THROW_ERROR @@ -171,7 +171,7 @@ function nb_spectral_coefficients_global( this ) use atlas_trans_c_binding integer :: nb_spectral_coefficients_global class(atlas_Trans) :: this -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS nb_spectral_coefficients_global = atlas__Trans__nspec2g (this%c_ptr()) #else THROW_ERROR @@ -184,7 +184,7 @@ function nb_gridpoints( this ) use atlas_trans_c_binding integer :: nb_gridpoints class(atlas_Trans) :: this -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS nb_gridpoints = atlas__Trans__ngptot (this%c_ptr()) #else THROW_ERROR @@ -197,7 +197,7 @@ function nb_gridpoints_global( this ) use atlas_trans_c_binding integer :: nb_gridpoints_global class(atlas_Trans) :: this -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS nb_gridpoints_global = atlas__Trans__ngptotg (this%c_ptr()) #else THROW_ERROR @@ -210,7 +210,7 @@ function grid( this ) use atlas_trans_c_binding class(atlas_Trans) :: this type(atlas_Grid) :: grid -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS grid = atlas_Grid( atlas__Trans__grid(this%c_ptr()) ) call grid%return() #else @@ -227,7 +227,7 @@ 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 -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -260,7 +260,7 @@ 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 -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -292,7 +292,7 @@ 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 -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -325,7 +325,7 @@ 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 -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -361,7 +361,7 @@ 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 -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -395,7 +395,7 @@ 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 -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS type(atlas_Config) :: p if( present(config) ) then @@ -430,7 +430,7 @@ 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 -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS type(atlas_Config) :: config config = atlas_Config() call atlas__Trans__invtrans_grad_field( this%c_ptr(), & @@ -454,7 +454,7 @@ subroutine gathspec_r1(this, local, global) class(atlas_Trans), intent(in) :: this real(c_double), intent(in) :: local(:) real(c_double), intent(inout) :: global(:) -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS call atlas__Trans__gathspec(this%c_ptr(), 1, (/1/), local, global ) #else THROW_ERROR @@ -471,7 +471,7 @@ subroutine gathspec_r2(this, local, global) class(atlas_Trans), intent(in) :: this real(c_double), intent(in) :: local(:,:) real(c_double), intent(inout) :: global(:,:) -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS real(c_double), pointer :: local_view(:), global_view(:) integer :: destination(size(local,1)) destination(:) = 1 @@ -494,7 +494,7 @@ subroutine specnorm_r1_scalar(this, spectra, norm, rank) real(c_double), intent(in) :: spectra(:) real(c_double), intent(out) :: norm integer, optional :: rank ! MPI rank -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS integer :: rank_opt real(c_double) :: norms(1) rank_opt = 0 @@ -518,7 +518,7 @@ subroutine specnorm_r2(this, spectra, norm, rank) real(c_double), intent(in) :: spectra(:,:) real(c_double), intent(inout) :: norm(:) integer, optional :: rank ! MPI rank -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS integer :: rank_opt real(c_double), pointer :: spectra_view(:) rank_opt = 0 diff --git a/src/tests/array/test_array.cc b/src/tests/array/test_array.cc index a9edfb4db..a093e56c2 100644 --- a/src/tests/array/test_array.cc +++ b/src/tests/array/test_array.cc @@ -8,10 +8,11 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/memory/SharedPtr.h" + #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "atlas/library/config.h" -#include "eckit/memory/SharedPtr.h" #include "tests/AtlasTestEnvironment.h" #ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE @@ -32,7 +33,7 @@ namespace test { //----------------------------------------------------------------------------- -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE CASE( "test_array" ) { Array* ds = Array::create( 4ul ); auto hv = atlas::array::gridtools::make_gt_host_view( *ds ); @@ -54,7 +55,7 @@ CASE( "test_array_zero_size" ) { delete ds; } -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE CASE( "test_create" ) { Array* ds = Array::create( array::DataType::create(), ArrayShape( {4, 3} ) ); auto hv = atlas::array::gridtools::make_gt_host_view( *ds ); @@ -69,7 +70,7 @@ CASE( "test_create" ) { } #endif -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE CASE( "test_make_view" ) { Array* ds = Array::create( 4ul ); auto hv = atlas::array::gridtools::make_gt_host_view( *ds ); @@ -115,7 +116,7 @@ CASE( "test_localview" ) { delete ds; } -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE CASE( "test_array_shape" ) { ArrayShape as{2, 3}; Array* ds = Array::create( as ); @@ -181,7 +182,7 @@ CASE( "test_spec_layout" ) { delete ds; } -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE CASE( "test_spec_layout_rev" ) { Array* ds = Array::create( make_shape( 4, 5, 6 ), make_layout( 2, 1, 0 ) ); EXPECT( ds->spec().rank() == 3 ); @@ -234,7 +235,7 @@ CASE( "test_copy_ctr" ) { delete ds; } -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE CASE( "test_copy_gt_ctr" ) { Array* ds = Array::create( 3, 2 ); atlas::array::ArrayView hv = make_host_view( *ds ); @@ -400,7 +401,7 @@ CASE( "test_insert" ) { // The original gt data store is deleted and replaced, but the former // atlas::array::ArrayView keeps a pointer to it // wihtout noticing it has been deleted -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE // Following statement seems to contradict previous comment EXPECT( hv.valid() == false ); #endif @@ -526,7 +527,7 @@ CASE( "test_valid" ) { ds->resize( 3, 4, 5 ); // Only implemented using gridtools storage for now -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE EXPECT( hv.valid() == false ); #endif diff --git a/src/tests/array/test_array_slicer.cc b/src/tests/array/test_array_slicer.cc index a637cea46..85e1a4e80 100644 --- a/src/tests/array/test_array_slicer.cc +++ b/src/tests/array/test_array_slicer.cc @@ -8,11 +8,13 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/memory/SharedPtr.h" + #include "atlas/array.h" #include "atlas/array/MakeView.h" #include "atlas/array/helpers/ArraySlicer.h" #include "atlas/library/config.h" -#include "eckit/memory/SharedPtr.h" + #include "tests/AtlasTestEnvironment.h" using namespace atlas::array; diff --git a/src/tests/array/test_array_view_util.cc b/src/tests/array/test_array_view_util.cc index 61f77fd3a..bd1f0c359 100644 --- a/src/tests/array/test_array_view_util.cc +++ b/src/tests/array/test_array_view_util.cc @@ -11,6 +11,7 @@ #include "atlas/array/Array.h" #include "atlas/array/ArrayViewUtil.h" #include "atlas/array_fwd.h" + #include "tests/AtlasTestEnvironment.h" using namespace atlas::array; diff --git a/src/tests/array/test_svector.cc b/src/tests/array/test_svector.cc index 7458fd6f9..cf8fb196b 100644 --- a/src/tests/array/test_svector.cc +++ b/src/tests/array/test_svector.cc @@ -10,6 +10,7 @@ #include "atlas/array/SVector.h" #include "atlas/library/config.h" + #include "tests/AtlasTestEnvironment.h" using namespace atlas::array; diff --git a/src/tests/functionspace/test_functionspace.cc b/src/tests/functionspace/test_functionspace.cc index a1e18754e..96c1c80e6 100644 --- a/src/tests/functionspace/test_functionspace.cc +++ b/src/tests/functionspace/test_functionspace.cc @@ -8,6 +8,9 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/memory/ScopedPtr.h" +#include "eckit/types/Types.h" + #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" @@ -20,8 +23,7 @@ #include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/trans/Trans.h" -#include "eckit/memory/ScopedPtr.h" -#include "eckit/types/Types.h" + #include "tests/AtlasTestEnvironment.h" using namespace eckit; @@ -498,7 +500,7 @@ CASE( "test_SpectralFunctionSpace" ) { EXPECT( columns_scalar.shape( 1 ) == nb_levels ); } -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS CASE( "test_SpectralFunctionSpace_trans_dist" ) { trans::Trans trans( Grid( "F80" ), 159 ); diff --git a/src/tests/functionspace/test_pointcloud.cc b/src/tests/functionspace/test_pointcloud.cc index faec2cad1..636a01257 100644 --- a/src/tests/functionspace/test_pointcloud.cc +++ b/src/tests/functionspace/test_pointcloud.cc @@ -9,7 +9,6 @@ */ #include "atlas/functionspace/PointCloud.h" - #include "atlas/array.h" #include "tests/AtlasTestEnvironment.h" diff --git a/src/tests/functionspace/test_structuredcolumns.cc b/src/tests/functionspace/test_structuredcolumns.cc index 35c360d5f..c0e974af5 100644 --- a/src/tests/functionspace/test_structuredcolumns.cc +++ b/src/tests/functionspace/test_structuredcolumns.cc @@ -8,6 +8,9 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/memory/ScopedPtr.h" +#include "eckit/types/Types.h" + #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" @@ -21,8 +24,6 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/MicroDeg.h" -#include "eckit/memory/ScopedPtr.h" -#include "eckit/types/Types.h" #include "tests/AtlasTestEnvironment.h" diff --git a/src/tests/grid/test_domain.cc b/src/tests/grid/test_domain.cc index 65149561a..d43711274 100644 --- a/src/tests/grid/test_domain.cc +++ b/src/tests/grid/test_domain.cc @@ -16,6 +16,7 @@ #include "atlas/grid/Grid.h" #include "atlas/runtime/Log.h" #include "atlas/util/Config.h" + #include "tests/AtlasTestEnvironment.h" namespace atlas { diff --git a/src/tests/grid/test_field.cc b/src/tests/grid/test_field.cc index ce7de4ca8..0f52d9760 100644 --- a/src/tests/grid/test_field.cc +++ b/src/tests/grid/test_field.cc @@ -8,11 +8,11 @@ * nor does it submit to any jurisdiction. */ -#include "atlas/runtime/Log.h" #include "eckit/memory/SharedPtr.h" #include "eckit/runtime/Tool.h" #include "eckit/value/CompositeParams.h" +#include "atlas/runtime/Log.h" #include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" #include "atlas/field/FieldSet.h" diff --git a/src/tests/grid/test_grid_ptr.cc b/src/tests/grid/test_grid_ptr.cc index 7b9b1435b..224c3a9fd 100644 --- a/src/tests/grid/test_grid_ptr.cc +++ b/src/tests/grid/test_grid_ptr.cc @@ -15,7 +15,6 @@ #include "atlas/grid/Grid.h" #include "atlas/runtime/Log.h" #include "atlas/util/Config.h" - #include "atlas/mesh/Mesh.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" #include "atlas/output/Gmsh.h" diff --git a/src/tests/grid/test_grids.cc b/src/tests/grid/test_grids.cc index 013a8359b..37f63e750 100644 --- a/src/tests/grid/test_grids.cc +++ b/src/tests/grid/test_grids.cc @@ -12,14 +12,15 @@ #include #include +#include "eckit/memory/Builder.h" +#include "eckit/memory/Factory.h" +#include "eckit/types/FloatCompare.h" + #include "atlas/grid.h" #include "atlas/grid/Grid.h" #include "atlas/library/Library.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/util/Config.h" -#include "eckit/memory/Builder.h" -#include "eckit/memory/Factory.h" -#include "eckit/types/FloatCompare.h" #include "tests/AtlasTestEnvironment.h" diff --git a/src/tests/grid/test_rotation.cc b/src/tests/grid/test_rotation.cc index 047dc895c..071d6c797 100644 --- a/src/tests/grid/test_rotation.cc +++ b/src/tests/grid/test_rotation.cc @@ -9,12 +9,14 @@ */ #include + +#include "eckit/types/FloatCompare.h" + #include "atlas/library/Library.h" #include "atlas/runtime/Log.h" #include "atlas/util/Config.h" #include "atlas/util/Constants.h" #include "atlas/util/Rotation.h" -#include "eckit/types/FloatCompare.h" #include "tests/AtlasTestEnvironment.h" diff --git a/src/tests/grid/test_state.cc b/src/tests/grid/test_state.cc index c79498edb..e828014d6 100644 --- a/src/tests/grid/test_state.cc +++ b/src/tests/grid/test_state.cc @@ -11,13 +11,12 @@ #include #include -#include "atlas/library/config.h" - #include "eckit/exception/Exceptions.h" #include "eckit/memory/ScopedPtr.h" #include "eckit/parser/JSON.h" #include "eckit/parser/JSONParser.h" +#include "atlas/library/config.h" #include "atlas/array/ArrayView.h" #include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" diff --git a/src/tests/interpolation/test_Quad3D.cc b/src/tests/interpolation/test_Quad3D.cc index 0b80e8f63..e54766d99 100644 --- a/src/tests/interpolation/test_Quad3D.cc +++ b/src/tests/interpolation/test_Quad3D.cc @@ -8,11 +8,12 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/types/FloatCompare.h" + #include "atlas/interpolation/element/Quad3D.h" #include "atlas/interpolation/method/Ray.h" #include "atlas/util/Point.h" -#include "eckit/types/FloatCompare.h" #include "tests/AtlasTestEnvironment.h" using atlas::PointXYZ; diff --git a/src/tests/interpolation/test_interpolation_finite_element.cc b/src/tests/interpolation/test_interpolation_finite_element.cc index 36af5c28e..dd7718829 100644 --- a/src/tests/interpolation/test_interpolation_finite_element.cc +++ b/src/tests/interpolation/test_interpolation_finite_element.cc @@ -10,9 +10,9 @@ #include -#include "atlas/functionspace/PointCloud.h" #include "eckit/types/FloatCompare.h" +#include "atlas/functionspace/PointCloud.h" #include "atlas/array.h" #include "atlas/functionspace.h" #include "atlas/grid.h" diff --git a/src/tests/io/test_gmsh.cc b/src/tests/io/test_gmsh.cc index 121be1de1..bf96399ff 100644 --- a/src/tests/io/test_gmsh.cc +++ b/src/tests/io/test_gmsh.cc @@ -11,8 +11,8 @@ #include "atlas/mesh/Mesh.h" #include "atlas/output/Gmsh.h" #include "atlas/output/Output.h" -#include "tests/TestMeshes.h" +#include "tests/TestMeshes.h" #include "tests/AtlasTestEnvironment.h" namespace atlas { diff --git a/src/tests/io/test_pointcloud_io.cc b/src/tests/io/test_pointcloud_io.cc index 2a704f38c..990b3d6ed 100644 --- a/src/tests/io/test_pointcloud_io.cc +++ b/src/tests/io/test_pointcloud_io.cc @@ -11,11 +11,11 @@ #include #include -#include "atlas/library/config.h" - #include "eckit/exception/Exceptions.h" #include "eckit/memory/ScopedPtr.h" +#include "eckit/types/FloatCompare.h" +#include "atlas/library/config.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" @@ -27,7 +27,6 @@ #include "atlas/mesh/Nodes.h" #include "atlas/output/detail/PointCloudIO.h" #include "atlas/parallel/mpi/mpi.h" -#include "eckit/types/FloatCompare.h" #include "tests/AtlasTestEnvironment.h" diff --git a/src/tests/mesh/test_accumulate_facets.cc b/src/tests/mesh/test_accumulate_facets.cc index 10052f951..ea80c4bc5 100644 --- a/src/tests/mesh/test_accumulate_facets.cc +++ b/src/tests/mesh/test_accumulate_facets.cc @@ -9,10 +9,8 @@ */ #include "atlas/library/config.h" - #include "atlas/library/Library.h" #include "atlas/mesh/detail/AccumulateFacets.h" - #include "atlas/grid/Grid.h" #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" diff --git a/src/tests/mesh/test_connectivity.cc b/src/tests/mesh/test_connectivity.cc index 3cb6b5661..ce887a8be 100644 --- a/src/tests/mesh/test_connectivity.cc +++ b/src/tests/mesh/test_connectivity.cc @@ -12,6 +12,7 @@ #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" #include "atlas/library/defines.h" + #include "tests/AtlasTestEnvironment.h" using namespace atlas::mesh; diff --git a/src/tests/mesh/test_distmesh.cc b/src/tests/mesh/test_distmesh.cc index ec75f7cb3..92c1e81e6 100644 --- a/src/tests/mesh/test_distmesh.cc +++ b/src/tests/mesh/test_distmesh.cc @@ -11,6 +11,8 @@ #include #include +#include "eckit/types/FloatCompare.h" + #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/grid/Grid.h" @@ -28,9 +30,8 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" -#include "eckit/types/FloatCompare.h" -#include "tests/TestMeshes.h" +#include "tests/TestMeshes.h" #include "tests/AtlasTestEnvironment.h" using namespace atlas; diff --git a/src/tests/mesh/test_elements.cc b/src/tests/mesh/test_elements.cc index f886fc83a..8d6c296e0 100644 --- a/src/tests/mesh/test_elements.cc +++ b/src/tests/mesh/test_elements.cc @@ -12,11 +12,10 @@ #include #include -#include "atlas/library/config.h" - #include "eckit/exception/Exceptions.h" #include "eckit/memory/ScopedPtr.h" +#include "atlas/library/config.h" #include "atlas/field/Field.h" #include "atlas/library/Library.h" #include "atlas/mesh/Connectivity.h" @@ -24,7 +23,6 @@ #include "atlas/mesh/Elements.h" #include "atlas/mesh/Nodes.h" #include "atlas/runtime/Log.h" - #include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" #include "atlas/meshgenerator/StructuredMeshGenerator.h" diff --git a/src/tests/mesh/test_halo.cc b/src/tests/mesh/test_halo.cc index b92618fb8..8a5731158 100644 --- a/src/tests/mesh/test_halo.cc +++ b/src/tests/mesh/test_halo.cc @@ -12,6 +12,8 @@ #include #include +#include "eckit/types/FloatCompare.h" + #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" @@ -29,9 +31,8 @@ #include "atlas/util/CoordinateEnums.h" #include "atlas/util/MicroDeg.h" #include "atlas/util/Unique.h" -#include "eckit/types/FloatCompare.h" -#include "tests/TestMeshes.h" +#include "tests/TestMeshes.h" #include "tests/AtlasTestEnvironment.h" using namespace atlas::output; diff --git a/src/tests/mesh/test_rgg.cc b/src/tests/mesh/test_rgg.cc index 0c646daa4..2ef7cde43 100644 --- a/src/tests/mesh/test_rgg.cc +++ b/src/tests/mesh/test_rgg.cc @@ -12,6 +12,8 @@ #include #include +#include "eckit/types/FloatCompare.h" + #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" @@ -32,7 +34,6 @@ #include "atlas/util/Config.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Metadata.h" -#include "eckit/types/FloatCompare.h" #include "tests/AtlasTestEnvironment.h" diff --git a/src/tests/trans/test_trans.cc b/src/tests/trans/test_trans.cc index 34f0d2a5e..b81037a30 100644 --- a/src/tests/trans/test_trans.cc +++ b/src/tests/trans/test_trans.cc @@ -10,6 +10,9 @@ #include +#include "eckit/filesystem/PathName.h" +#include "eckit/io/DataHandle.h" + #include "atlas/array/MakeView.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/NodeColumns.h" @@ -29,11 +32,9 @@ #include "atlas/trans/Trans.h" #include "atlas/trans/VorDivToUV.h" -#include "eckit/filesystem/PathName.h" -#include "eckit/io/DataHandle.h" #include "tests/AtlasTestEnvironment.h" -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS #include "atlas/trans/ifs/TransIFS.h" #include "atlas/trans/ifs/TransIFSNodeColumns.h" #include "atlas/trans/ifs/TransIFSStructuredColumns.h" diff --git a/src/tests/trans/test_trans_invtrans_grad.cc b/src/tests/trans/test_trans_invtrans_grad.cc index 877727a51..b0bc0f401 100644 --- a/src/tests/trans/test_trans_invtrans_grad.cc +++ b/src/tests/trans/test_trans_invtrans_grad.cc @@ -30,7 +30,7 @@ #include "tests/AtlasTestEnvironment.h" -#ifdef ATLAS_HAVE_TRANS +#if ATLAS_HAVE_TRANS #include "atlas/trans/ifs/TransIFS.h" #endif diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index e90b13358..8cb24556d 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -9,6 +9,7 @@ */ #include +#include #include "atlas/array/MakeView.h" #include "atlas/field/FieldSet.h" @@ -31,12 +32,12 @@ #include "atlas/trans/local/FourierTransforms.h" #include "atlas/trans/local/LegendrePolynomials.h" #include "atlas/trans/local/LegendreTransforms.h" -#include "transi/trans.h" #include "tests/AtlasTestEnvironment.h" -#include -#include +#if ATLAS_HAVE_TRANS +#include "transi/trans.h" +#endif using namespace eckit; @@ -51,11 +52,17 @@ namespace test { struct AtlasTransEnvironment : public AtlasTestEnvironment { AtlasTransEnvironment( int argc, char* argv[] ) : AtlasTestEnvironment( argc, argv ) { - if ( mpi::comm().size() == 1 ) trans_use_mpi( false ); +#if ATLAS_HAVE_TRANS + trans_use_mpi( mpi::comm().size() > 1 ); trans_init(); +#endif } - ~AtlasTransEnvironment() { trans_finalize(); } + ~AtlasTransEnvironment() { +#if ATLAS_HAVE_TRANS + trans_finalize(); +#endif + } }; //----------------------------------------------------------------------------- @@ -655,9 +662,9 @@ CASE( "test_transgeneral_with_translib" ) { Grid g( "F24" ); grid::StructuredGrid gs( g ); int trc = 47; - trans::Trans trans( g, trc ); + trans::Trans transIFS( g, trc, util::Config("type", "ifs") ); - functionspace::Spectral spectral( trans ); + functionspace::Spectral spectral( transIFS ); functionspace::StructuredColumns gridpoints( g ); Field spf = spectral.createField( option::name( "spf" ) ); @@ -678,7 +685,7 @@ CASE( "test_transgeneral_with_translib" ) { sp.assign( 0. ); sp( k ) = 1.; - EXPECT_NO_THROW( trans.invtrans( spf, gpf ) ); + EXPECT_NO_THROW( transIFS.invtrans( spf, gpf ) ); spectral_transform_grid_analytic( trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data(), 2, 2 ); @@ -706,6 +713,7 @@ CASE( "test_transgeneral_with_translib" ) { //----------------------------------------------------------------------------- CASE( "test_trans_vordiv_with_translib" ) { + Log::info() << "test_trans_vordiv_with_translib" << std::endl; // test transgeneral by comparing its result with the trans library // this test is based on the test_nomesh case in test_trans.cc @@ -719,10 +727,10 @@ CASE( "test_trans_vordiv_with_translib" ) { Grid g( "O" + std::to_string( res ) ); grid::StructuredGrid gs( g ); int trc = res * 2 - 1; - trans::Trans trans( g, trc ); + trans::Trans transIFS( g, trc, util::Config("type", "ifs" ) ); trans::Trans transLocal( g, trc, util::Config( "type", "local" ) ); - functionspace::Spectral spectral( trans ); + functionspace::Spectral spectral( transIFS ); functionspace::StructuredColumns gridpoints( g ); int nb_scalar = 2, nb_vordiv = 2; @@ -776,7 +784,7 @@ CASE( "test_trans_vordiv_with_translib" ) { spectral_transform_grid_analytic( trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data(), ivar_in, ivar_out ); - EXPECT_NO_THROW( trans.invtrans( nb_scalar, sp.data(), nb_vordiv, vor.data(), + EXPECT_NO_THROW( transIFS.invtrans( nb_scalar, sp.data(), nb_vordiv, vor.data(), div.data(), gp.data() ) ); // compute spectral transform with the general transform: diff --git a/src/tests/util/test_earth.cc b/src/tests/util/test_earth.cc index 9faf6dce6..094ef64e7 100644 --- a/src/tests/util/test_earth.cc +++ b/src/tests/util/test_earth.cc @@ -10,6 +10,7 @@ #include #include + #include "atlas/util/Earth.h" #include "atlas/util/Point.h" diff --git a/src/tests/util/test_flags.cc b/src/tests/util/test_flags.cc index ece38c615..bbdf009d9 100644 --- a/src/tests/util/test_flags.cc +++ b/src/tests/util/test_flags.cc @@ -11,6 +11,7 @@ #include #include "atlas/util/Bitflags.h" + #include "tests/AtlasTestEnvironment.h" using atlas::util::Bitflags; diff --git a/src/tests/util/test_footprint.cc b/src/tests/util/test_footprint.cc index d9257840b..281474e98 100644 --- a/src/tests/util/test_footprint.cc +++ b/src/tests/util/test_footprint.cc @@ -8,6 +8,8 @@ * nor does it submit to any jurisdiction. */ +#include "eckit/log/Bytes.h" + #include "atlas/array/Array.h" #include "atlas/array/ArrayView.h" #include "atlas/field/Field.h" @@ -19,7 +21,6 @@ #include "atlas/meshgenerator/MeshGenerator.h" #include "atlas/runtime/Log.h" #include "atlas/util/Metadata.h" -#include "eckit/log/Bytes.h" #include "tests/AtlasTestEnvironment.h" diff --git a/src/tests/util/test_indexview.cc b/src/tests/util/test_indexview.cc index b7d7fc3f2..a204e2f00 100644 --- a/src/tests/util/test_indexview.cc +++ b/src/tests/util/test_indexview.cc @@ -14,6 +14,7 @@ #include "atlas/array/MakeView.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/library/defines.h" + #include "tests/AtlasTestEnvironment.h" #if ATLAS_HAVE_FORTRAN @@ -99,7 +100,7 @@ std::endl; } */ -#ifdef ATLAS_HAVE_GRIDTOOLS_STORAGE +#if ATLAS_HAVE_GRIDTOOLS_STORAGE CASE( "test_indexview_1d" ) { // array::ArrayT array( 10 ); diff --git a/src/tests/util/test_polygon.cc b/src/tests/util/test_polygon.cc index 090e14ac8..656e46e27 100644 --- a/src/tests/util/test_polygon.cc +++ b/src/tests/util/test_polygon.cc @@ -11,6 +11,7 @@ #include #include #include + #include "atlas/util/Point.h" #include "atlas/util/SphericalPolygon.h" From 5d1abc58962b7de527a8a906a4fd57de9543557e Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 17:31:28 +0000 Subject: [PATCH 352/355] more cleanup --- src/atlas/array/Table.cc | 2 +- src/atlas/array/native/NativeArray.cc | 2 +- src/atlas/array/native/NativeMakeView.cc | 2 +- src/atlas/field/detail/FieldImpl.cc | 2 +- src/atlas/functionspace/Spectral.cc | 2 +- src/atlas/functionspace/StructuredColumns.cc | 1 - src/atlas/grid/detail/grid/Structured.h | 2 +- src/atlas/grid/detail/partitioner/Partitioner.cc | 4 ++-- src/atlas/grid/detail/partitioner/TransPartitioner.cc | 2 +- src/atlas/interpolation/Interpolation.cc | 2 +- src/atlas/interpolation/element/Quad3D.h | 1 - src/atlas/interpolation/method/NearestNeighbour.cc | 2 +- src/atlas/interpolation/method/PointIndex3.cc | 2 +- src/atlas/interpolation/method/PointSet.cc | 2 +- src/atlas/library/Library.cc | 2 +- src/atlas/mesh/Connectivity.cc | 4 ++-- src/atlas/mesh/HybridElements.cc | 2 +- src/atlas/mesh/actions/BuildCellCentres.cc | 2 +- src/atlas/mesh/actions/BuildParallelFields.cc | 2 +- src/atlas/mesh/actions/ExtendNodesGlobal.cc | 2 +- src/atlas/mesh/actions/WriteLoadBalanceReport.cc | 2 +- src/atlas/mesh/detail/AccumulateFacets.cc | 2 +- src/atlas/mesh/detail/MeshImpl.cc | 2 +- src/atlas/meshgenerator/DelaunayMeshGenerator.cc | 2 +- src/atlas/meshgenerator/RegularMeshGenerator.cc | 2 +- src/atlas/numerics/Method.cc | 2 +- src/atlas/numerics/Nabla.cc | 2 +- src/atlas/numerics/fvm/Method.cc | 2 +- src/atlas/numerics/fvm/Nabla.cc | 2 +- src/atlas/output/detail/GmshIO.cc | 2 +- src/atlas/output/detail/PointCloudIO.cc | 2 +- src/atlas/parallel/GatherScatter.cc | 2 +- src/atlas/parallel/GatherScatter.h | 2 +- src/atlas/parallel/HaloExchange.cc | 2 +- src/atlas/runtime/ErrorHandling.cc | 2 +- src/atlas/runtime/Log.cc | 2 +- src/atlas/runtime/Log.h | 4 ++-- src/atlas/trans/Trans.cc | 2 +- src/atlas/trans/VorDivToUV.cc | 2 +- src/atlas/trans/ifs/TransIFS.cc | 2 +- src/atlas/trans/local/LegendrePolynomials.cc | 2 +- src/atlas/util/Config.cc | 2 +- src/atlas/util/Earth.cc | 2 +- src/atlas/util/LonLatPolygon.cc | 2 +- src/atlas/util/Polygon.cc | 2 +- src/atlas/util/Rotation.cc | 2 +- src/atlas/util/SphericalPolygon.cc | 2 +- 47 files changed, 48 insertions(+), 50 deletions(-) diff --git a/src/atlas/array/Table.cc b/src/atlas/array/Table.cc index 07f806008..34b2e0f81 100644 --- a/src/atlas/array/Table.cc +++ b/src/atlas/array/Table.cc @@ -12,8 +12,8 @@ #include #include "atlas/array.h" #include "atlas/array/DataType.h" -#include "atlas/runtime/ErrorHandling.h" #include "atlas/library/defines.h" +#include "atlas/runtime/ErrorHandling.h" #if ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 diff --git a/src/atlas/array/native/NativeArray.cc b/src/atlas/array/native/NativeArray.cc index cc0526691..3e5f3c346 100644 --- a/src/atlas/array/native/NativeArray.cc +++ b/src/atlas/array/native/NativeArray.cc @@ -3,9 +3,9 @@ #include "atlas/array.h" #include "atlas/array/ArrayUtil.h" #include "atlas/array/MakeView.h" -#include "atlas/array/native/NativeDataStore.h" #include "atlas/array/helpers/ArrayInitializer.h" #include "atlas/array/helpers/ArrayWriter.h" +#include "atlas/array/native/NativeDataStore.h" using namespace atlas::array::helpers; diff --git a/src/atlas/array/native/NativeMakeView.cc b/src/atlas/array/native/NativeMakeView.cc index 2221a2a18..a39e238e4 100644 --- a/src/atlas/array/native/NativeMakeView.cc +++ b/src/atlas/array/native/NativeMakeView.cc @@ -1,8 +1,8 @@ +#include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" #include "atlas/library/config.h" -#include "atlas/array.h" namespace atlas { namespace array { diff --git a/src/atlas/field/detail/FieldImpl.cc b/src/atlas/field/detail/FieldImpl.cc index ad963dbb5..67f7c015f 100644 --- a/src/atlas/field/detail/FieldImpl.cc +++ b/src/atlas/field/detail/FieldImpl.cc @@ -112,7 +112,7 @@ const std::string& FieldImpl::name() const { void FieldImpl::print( std::ostream& os, bool dump ) const { os << "FieldImpl[name=" << name() << ",datatype=" << datatype().str() << ",size=" << size() << ",shape=" << vector_to_str( shape() ) << ",strides=" << vector_to_str( strides() ) -#if ! ATLAS_HAVE_GRIDTOOLS_STORAGE +#if !ATLAS_HAVE_GRIDTOOLS_STORAGE << ",bytes=" << bytes() #endif << ",metadata=" << metadata(); diff --git a/src/atlas/functionspace/Spectral.cc b/src/atlas/functionspace/Spectral.cc index 43f87e6cd..2a833f453 100644 --- a/src/atlas/functionspace/Spectral.cc +++ b/src/atlas/functionspace/Spectral.cc @@ -17,10 +17,10 @@ #include "atlas/functionspace/Spectral.h" #include "atlas/mesh/Mesh.h" #include "atlas/option.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" #include "atlas/trans/Trans.h" -#include "atlas/parallel/mpi/mpi.h" #if ATLAS_HAVE_TRANS diff --git a/src/atlas/functionspace/StructuredColumns.cc b/src/atlas/functionspace/StructuredColumns.cc index b28fe326f..ac199f8a3 100644 --- a/src/atlas/functionspace/StructuredColumns.cc +++ b/src/atlas/functionspace/StructuredColumns.cc @@ -28,7 +28,6 @@ #include "atlas/runtime/Trace.h" #include "atlas/util/Checksum.h" #include "atlas/util/CoordinateEnums.h" -#include "atlas/mesh/Mesh.h" #define IDX( i, j ) "(" << i << "," << j << ")" diff --git a/src/atlas/grid/detail/grid/Structured.h b/src/atlas/grid/detail/grid/Structured.h index 174470c68..c621b96ff 100644 --- a/src/atlas/grid/detail/grid/Structured.h +++ b/src/atlas/grid/detail/grid/Structured.h @@ -16,9 +16,9 @@ #include "eckit/memory/Builder.h" #include "eckit/utils/Hash.h" +#include "atlas/grid/Spacing.h" #include "atlas/grid/detail/grid/Grid.h" #include "atlas/util/Config.h" -#include "atlas/grid/Spacing.h" namespace atlas { namespace grid { diff --git a/src/atlas/grid/detail/partitioner/Partitioner.cc b/src/atlas/grid/detail/partitioner/Partitioner.cc index c9087f176..fad9ee532 100644 --- a/src/atlas/grid/detail/partitioner/Partitioner.cc +++ b/src/atlas/grid/detail/partitioner/Partitioner.cc @@ -16,13 +16,13 @@ #include "eckit/thread/AutoLock.h" #include "eckit/thread/Mutex.h" +#include "atlas/grid/Distribution.h" +#include "atlas/grid/Partitioner.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitioner.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerBruteForce.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerLonLatPolygon.h" #include "atlas/grid/detail/partitioner/MatchingMeshPartitionerSphericalPolygon.h" -#include "atlas/grid/Distribution.h" -#include "atlas/grid/Partitioner.h" #include "atlas/library/config.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" diff --git a/src/atlas/grid/detail/partitioner/TransPartitioner.cc b/src/atlas/grid/detail/partitioner/TransPartitioner.cc index 13c817e6e..059205211 100644 --- a/src/atlas/grid/detail/partitioner/TransPartitioner.cc +++ b/src/atlas/grid/detail/partitioner/TransPartitioner.cc @@ -10,10 +10,10 @@ #include "eckit/exception/Exceptions.h" -#include "atlas/grid/detail/partitioner/TransPartitioner.h" #include "atlas/array.h" #include "atlas/grid/Grid.h" #include "atlas/grid/detail/partitioner/EqualRegionsPartitioner.h" +#include "atlas/grid/detail/partitioner/TransPartitioner.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Trace.h" #include "atlas/trans/ifs/TransIFS.h" diff --git a/src/atlas/interpolation/Interpolation.cc b/src/atlas/interpolation/Interpolation.cc index d8674d06b..579211174 100644 --- a/src/atlas/interpolation/Interpolation.cc +++ b/src/atlas/interpolation/Interpolation.cc @@ -10,10 +10,10 @@ #include "eckit/exception/Exceptions.h" -#include "atlas/interpolation/Interpolation.h" #include "atlas/field/Field.h" #include "atlas/field/FieldSet.h" #include "atlas/functionspace/FunctionSpace.h" +#include "atlas/interpolation/Interpolation.h" namespace atlas { diff --git a/src/atlas/interpolation/element/Quad3D.h b/src/atlas/interpolation/element/Quad3D.h index f17e4a58a..6c5dd1753 100644 --- a/src/atlas/interpolation/element/Quad3D.h +++ b/src/atlas/interpolation/element/Quad3D.h @@ -64,4 +64,3 @@ class Quad3D { } // namespace element } // namespace interpolation } // namespace atlas - diff --git a/src/atlas/interpolation/method/NearestNeighbour.cc b/src/atlas/interpolation/method/NearestNeighbour.cc index 96fea41fb..14f76eefc 100644 --- a/src/atlas/interpolation/method/NearestNeighbour.cc +++ b/src/atlas/interpolation/method/NearestNeighbour.cc @@ -10,8 +10,8 @@ #include "eckit/log/Plural.h" -#include "atlas/interpolation/method/NearestNeighbour.h" #include "atlas/functionspace/NodeColumns.h" +#include "atlas/interpolation/method/NearestNeighbour.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/runtime/Log.h" diff --git a/src/atlas/interpolation/method/PointIndex3.cc b/src/atlas/interpolation/method/PointIndex3.cc index dcc392a63..8fbe18d27 100644 --- a/src/atlas/interpolation/method/PointIndex3.cc +++ b/src/atlas/interpolation/method/PointIndex3.cc @@ -11,9 +11,9 @@ #include "eckit/config/Resource.h" -#include "atlas/interpolation/method/PointIndex3.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" +#include "atlas/interpolation/method/PointIndex3.h" #include "atlas/mesh/HybridElements.h" namespace atlas { diff --git a/src/atlas/interpolation/method/PointSet.cc b/src/atlas/interpolation/method/PointSet.cc index 105be49ae..753172880 100644 --- a/src/atlas/interpolation/method/PointSet.cc +++ b/src/atlas/interpolation/method/PointSet.cc @@ -10,10 +10,10 @@ #include "eckit/config/Resource.h" -#include "atlas/interpolation/method/PointSet.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" +#include "atlas/interpolation/method/PointSet.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" diff --git a/src/atlas/library/Library.cc b/src/atlas/library/Library.cc index 7af939313..084311533 100644 --- a/src/atlas/library/Library.cc +++ b/src/atlas/library/Library.cc @@ -19,13 +19,13 @@ #include "eckit/utils/Translator.h" #include "atlas/library/Library.h" +#include "atlas/library/config.h" #include "atlas/library/git_sha1.h" #include "atlas/library/version.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" #include "atlas/util/Config.h" -#include "atlas/library/config.h" #if ATLAS_HAVE_TRANS #include "transi/version.h" diff --git a/src/atlas/mesh/Connectivity.cc b/src/atlas/mesh/Connectivity.cc index 5e93e92bc..91a6177fb 100644 --- a/src/atlas/mesh/Connectivity.cc +++ b/src/atlas/mesh/Connectivity.cc @@ -10,13 +10,13 @@ #include -#include "atlas/mesh/Connectivity.h" #include "atlas/array.h" #include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" #include "atlas/array/Vector.h" -#include "atlas/runtime/ErrorHandling.h" #include "atlas/library/defines.h" +#include "atlas/mesh/Connectivity.h" +#include "atlas/runtime/ErrorHandling.h" #if ATLAS_HAVE_FORTRAN #define FORTRAN_BASE 1 diff --git a/src/atlas/mesh/HybridElements.cc b/src/atlas/mesh/HybridElements.cc index 2f49ab24a..ad898f6f0 100644 --- a/src/atlas/mesh/HybridElements.cc +++ b/src/atlas/mesh/HybridElements.cc @@ -13,12 +13,12 @@ #include "eckit/log/Bytes.h" #include "eckit/memory/SharedPtr.h" -#include "atlas/mesh/HybridElements.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/library/config.h" #include "atlas/mesh/ElementType.h" #include "atlas/mesh/Elements.h" +#include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" diff --git a/src/atlas/mesh/actions/BuildCellCentres.cc b/src/atlas/mesh/actions/BuildCellCentres.cc index 1cbfdcebf..71ff4dd80 100644 --- a/src/atlas/mesh/actions/BuildCellCentres.cc +++ b/src/atlas/mesh/actions/BuildCellCentres.cc @@ -12,12 +12,12 @@ #include "eckit/types/FloatCompare.h" -#include "atlas/mesh/actions/BuildCellCentres.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/mesh/actions/BuildCellCentres.h" #include "atlas/util/CoordinateEnums.h" namespace atlas { diff --git a/src/atlas/mesh/actions/BuildParallelFields.cc b/src/atlas/mesh/actions/BuildParallelFields.cc index 3019b1d92..cca09905b 100644 --- a/src/atlas/mesh/actions/BuildParallelFields.cc +++ b/src/atlas/mesh/actions/BuildParallelFields.cc @@ -15,7 +15,6 @@ #include "eckit/exception/Exceptions.h" -#include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" @@ -23,6 +22,7 @@ #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/mesh/actions/BuildParallelFields.h" #include "atlas/mesh/detail/PeriodicTransform.h" #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/mpi/Buffer.h" diff --git a/src/atlas/mesh/actions/ExtendNodesGlobal.cc b/src/atlas/mesh/actions/ExtendNodesGlobal.cc index 84e67937a..1311b6b6f 100644 --- a/src/atlas/mesh/actions/ExtendNodesGlobal.cc +++ b/src/atlas/mesh/actions/ExtendNodesGlobal.cc @@ -10,11 +10,11 @@ #include "eckit/exception/Exceptions.h" -#include "atlas/mesh/actions/ExtendNodesGlobal.h" #include "atlas/field/Field.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/mesh/actions/ExtendNodesGlobal.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" diff --git a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc index 0f33a0c3f..d20f477ce 100644 --- a/src/atlas/mesh/actions/WriteLoadBalanceReport.cc +++ b/src/atlas/mesh/actions/WriteLoadBalanceReport.cc @@ -13,12 +13,12 @@ #include "eckit/filesystem/PathName.h" -#include "atlas/parallel/mpi/mpi.h" #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/IsGhostNode.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/mesh/actions/WriteLoadBalanceReport.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" using atlas::mesh::IsGhostNode; diff --git a/src/atlas/mesh/detail/AccumulateFacets.cc b/src/atlas/mesh/detail/AccumulateFacets.cc index c1e695cf8..827a1e3ed 100644 --- a/src/atlas/mesh/detail/AccumulateFacets.cc +++ b/src/atlas/mesh/detail/AccumulateFacets.cc @@ -10,10 +10,10 @@ #include "eckit/exception/Exceptions.h" -#include "atlas/mesh/detail/AccumulateFacets.h" #include "atlas/mesh/Elements.h" #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Nodes.h" +#include "atlas/mesh/detail/AccumulateFacets.h" #include "atlas/runtime/Trace.h" namespace atlas { diff --git a/src/atlas/mesh/detail/MeshImpl.cc b/src/atlas/mesh/detail/MeshImpl.cc index 68c54dc67..30c6696ce 100644 --- a/src/atlas/mesh/detail/MeshImpl.cc +++ b/src/atlas/mesh/detail/MeshImpl.cc @@ -13,12 +13,12 @@ #include "eckit/exception/Exceptions.h" #include "eckit/types/FloatCompare.h" -#include "atlas/mesh/detail/MeshImpl.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Elements.h" #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/mesh/detail/MeshImpl.h" #include "atlas/parallel/mpi/mpi.h" using atlas::Grid; diff --git a/src/atlas/meshgenerator/DelaunayMeshGenerator.cc b/src/atlas/meshgenerator/DelaunayMeshGenerator.cc index 4898fc12e..a466a34f0 100644 --- a/src/atlas/meshgenerator/DelaunayMeshGenerator.cc +++ b/src/atlas/meshgenerator/DelaunayMeshGenerator.cc @@ -10,7 +10,6 @@ #include "eckit/utils/Hash.h" -#include "atlas/meshgenerator/DelaunayMeshGenerator.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" @@ -22,6 +21,7 @@ #include "atlas/mesh/actions/BuildConvexHull3D.h" #include "atlas/mesh/actions/BuildXYZField.h" #include "atlas/mesh/actions/ExtendNodesGlobal.h" +#include "atlas/meshgenerator/DelaunayMeshGenerator.h" #include "atlas/projection/Projection.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" diff --git a/src/atlas/meshgenerator/RegularMeshGenerator.cc b/src/atlas/meshgenerator/RegularMeshGenerator.cc index fe86d8f53..0d66fa9aa 100644 --- a/src/atlas/meshgenerator/RegularMeshGenerator.cc +++ b/src/atlas/meshgenerator/RegularMeshGenerator.cc @@ -7,7 +7,6 @@ #include "eckit/utils/Hash.h" -#include "atlas/meshgenerator/RegularMeshGenerator.h" #include "atlas/array/Array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" @@ -21,6 +20,7 @@ #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/meshgenerator/RegularMeshGenerator.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" diff --git a/src/atlas/numerics/Method.cc b/src/atlas/numerics/Method.cc index 5524988b9..0f4a15f01 100644 --- a/src/atlas/numerics/Method.cc +++ b/src/atlas/numerics/Method.cc @@ -10,8 +10,8 @@ #include "eckit/exception/Exceptions.h" -#include "atlas/numerics/Method.h" #include "atlas/library/config.h" +#include "atlas/numerics/Method.h" #include "atlas/runtime/ErrorHandling.h" namespace atlas { diff --git a/src/atlas/numerics/Nabla.cc b/src/atlas/numerics/Nabla.cc index dce37108f..a27bf3262 100644 --- a/src/atlas/numerics/Nabla.cc +++ b/src/atlas/numerics/Nabla.cc @@ -15,9 +15,9 @@ #include "eckit/thread/AutoLock.h" #include "eckit/thread/Mutex.h" -#include "atlas/numerics/Nabla.h" #include "atlas/library/config.h" #include "atlas/numerics/Method.h" +#include "atlas/numerics/Nabla.h" #include "atlas/numerics/fvm/Method.h" #include "atlas/numerics/fvm/Nabla.h" #include "atlas/runtime/ErrorHandling.h" diff --git a/src/atlas/numerics/fvm/Method.cc b/src/atlas/numerics/fvm/Method.cc index 1dd1ee8ff..999f1255a 100644 --- a/src/atlas/numerics/fvm/Method.cc +++ b/src/atlas/numerics/fvm/Method.cc @@ -12,7 +12,6 @@ #include "eckit/exception/Exceptions.h" -#include "atlas/numerics/fvm/Method.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/functionspace/EdgeColumns.h" @@ -23,6 +22,7 @@ #include "atlas/mesh/actions/BuildDualMesh.h" #include "atlas/mesh/actions/BuildEdges.h" #include "atlas/mesh/actions/BuildParallelFields.h" +#include "atlas/numerics/fvm/Method.h" #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/util/CoordinateEnums.h" diff --git a/src/atlas/numerics/fvm/Nabla.cc b/src/atlas/numerics/fvm/Nabla.cc index 2db42a57b..95f244a90 100644 --- a/src/atlas/numerics/fvm/Nabla.cc +++ b/src/atlas/numerics/fvm/Nabla.cc @@ -11,7 +11,6 @@ #include "eckit/config/Parametrisation.h" #include "eckit/exception/Exceptions.h" -#include "atlas/numerics/fvm/Nabla.h" #include "atlas/array/ArrayView.h" #include "atlas/array/MakeView.h" #include "atlas/field/Field.h" @@ -19,6 +18,7 @@ #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" #include "atlas/numerics/fvm/Method.h" +#include "atlas/numerics/fvm/Nabla.h" #include "atlas/parallel/omp/omp.h" #include "atlas/runtime/Log.h" #include "atlas/util/CoordinateEnums.h" diff --git a/src/atlas/output/detail/GmshIO.cc b/src/atlas/output/detail/GmshIO.cc index fe871c8ec..fa5ffe6a6 100644 --- a/src/atlas/output/detail/GmshIO.cc +++ b/src/atlas/output/detail/GmshIO.cc @@ -17,7 +17,6 @@ #include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" -#include "atlas/output/detail/GmshIO.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" #include "atlas/array/IndexView.h" @@ -30,6 +29,7 @@ #include "atlas/mesh/HybridElements.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/output/detail/GmshIO.h" #include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" diff --git a/src/atlas/output/detail/PointCloudIO.cc b/src/atlas/output/detail/PointCloudIO.cc index 39c9ddf89..d164b57a6 100644 --- a/src/atlas/output/detail/PointCloudIO.cc +++ b/src/atlas/output/detail/PointCloudIO.cc @@ -16,7 +16,6 @@ #include "eckit/exception/Exceptions.h" #include "eckit/filesystem/PathName.h" -#include "atlas/output/detail/PointCloudIO.h" #include "atlas/array/ArrayView.h" #include "atlas/array/DataType.h" #include "atlas/array/MakeView.h" @@ -26,6 +25,7 @@ #include "atlas/functionspace/NodeColumns.h" #include "atlas/mesh/Mesh.h" #include "atlas/mesh/Nodes.h" +#include "atlas/output/detail/PointCloudIO.h" #include "atlas/util/CoordinateEnums.h" namespace atlas { diff --git a/src/atlas/parallel/GatherScatter.cc b/src/atlas/parallel/GatherScatter.cc index 01e727b09..47242218d 100644 --- a/src/atlas/parallel/GatherScatter.cc +++ b/src/atlas/parallel/GatherScatter.cc @@ -13,9 +13,9 @@ #include #include -#include "atlas/parallel/GatherScatter.h" #include "atlas/array.h" #include "atlas/array/ArrayView.h" +#include "atlas/parallel/GatherScatter.h" #include "atlas/parallel/mpi/Statistics.h" #include "atlas/runtime/Log.h" #include "atlas/runtime/Trace.h" diff --git a/src/atlas/parallel/GatherScatter.h b/src/atlas/parallel/GatherScatter.h index d3a1f1f40..8146af252 100644 --- a/src/atlas/parallel/GatherScatter.h +++ b/src/atlas/parallel/GatherScatter.h @@ -16,9 +16,9 @@ #include "eckit/memory/Owned.h" #include "eckit/memory/SharedPtr.h" -#include "atlas/parallel/mpi/mpi.h" #include "atlas/array/ArrayView.h" #include "atlas/library/config.h" +#include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/Log.h" namespace atlas { diff --git a/src/atlas/parallel/HaloExchange.cc b/src/atlas/parallel/HaloExchange.cc index 1772b6e73..aafd9de0e 100644 --- a/src/atlas/parallel/HaloExchange.cc +++ b/src/atlas/parallel/HaloExchange.cc @@ -15,8 +15,8 @@ #include #include -#include "atlas/parallel/HaloExchange.h" #include "atlas/array/Array.h" +#include "atlas/parallel/HaloExchange.h" #include "atlas/parallel/mpi/Statistics.h" namespace atlas { diff --git a/src/atlas/runtime/ErrorHandling.cc b/src/atlas/runtime/ErrorHandling.cc index 191014028..2fe0d5d48 100644 --- a/src/atlas/runtime/ErrorHandling.cc +++ b/src/atlas/runtime/ErrorHandling.cc @@ -2,8 +2,8 @@ #include "eckit/os/BackTrace.h" #include "eckit/utils/Translator.h" -#include "atlas/runtime/ErrorHandling.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" using namespace atlas; diff --git a/src/atlas/runtime/Log.cc b/src/atlas/runtime/Log.cc index bffdd7324..5103c8314 100644 --- a/src/atlas/runtime/Log.cc +++ b/src/atlas/runtime/Log.cc @@ -10,8 +10,8 @@ #include "eckit/os/BackTrace.h" -#include "atlas/runtime/Log.h" #include "atlas/parallel/mpi/mpi.h" +#include "atlas/runtime/Log.h" namespace atlas { diff --git a/src/atlas/runtime/Log.h b/src/atlas/runtime/Log.h index 1bb467bcf..9dbc946bf 100644 --- a/src/atlas/runtime/Log.h +++ b/src/atlas/runtime/Log.h @@ -1,7 +1,7 @@ #pragma once -#include "atlas/library/config.h" #include "atlas/library/Library.h" +#include "atlas/library/config.h" #if ATLAS_HAVE_FORTRAN #include "fckit/Log.h" @@ -29,7 +29,7 @@ class Log : public detail::LogBase { static Channel& trace() { return atlas::Library::instance().traceChannel(); } static Channel& debug() { return atlas::Library::instance().debugChannel(); } -#if ! ATLAS_HAVE_FORTRAN +#if !ATLAS_HAVE_FORTRAN // Stubs for what fckit::Log provides enum Style { diff --git a/src/atlas/trans/Trans.cc b/src/atlas/trans/Trans.cc index c4559713c..c10408891 100644 --- a/src/atlas/trans/Trans.cc +++ b/src/atlas/trans/Trans.cc @@ -15,9 +15,9 @@ #include "atlas/functionspace.h" #include "atlas/grid/Grid.h" +#include "atlas/library/defines.h" #include "atlas/runtime/Log.h" #include "atlas/trans/Trans.h" -#include "atlas/library/defines.h" // For factory registration only: #if ATLAS_HAVE_TRANS diff --git a/src/atlas/trans/VorDivToUV.cc b/src/atlas/trans/VorDivToUV.cc index 430f5e162..f71e2a6c2 100644 --- a/src/atlas/trans/VorDivToUV.cc +++ b/src/atlas/trans/VorDivToUV.cc @@ -15,9 +15,9 @@ #include "atlas/functionspace.h" #include "atlas/grid/Grid.h" +#include "atlas/library/defines.h" #include "atlas/runtime/Log.h" #include "atlas/trans/VorDivToUV.h" -#include "atlas/library/defines.h" // For factory registration only #if ATLAS_HAVE_TRANS diff --git a/src/atlas/trans/ifs/TransIFS.cc b/src/atlas/trans/ifs/TransIFS.cc index ce94496d1..0d80fcdf6 100644 --- a/src/atlas/trans/ifs/TransIFS.cc +++ b/src/atlas/trans/ifs/TransIFS.cc @@ -10,7 +10,6 @@ #include "eckit/parser/JSON.h" -#include "atlas/trans/ifs/TransIFS.h" #include "atlas/array.h" #include "atlas/functionspace/NodeColumns.h" #include "atlas/functionspace/Spectral.h" @@ -20,6 +19,7 @@ #include "atlas/parallel/mpi/mpi.h" #include "atlas/runtime/ErrorHandling.h" #include "atlas/runtime/Log.h" +#include "atlas/trans/ifs/TransIFS.h" using Topology = atlas::mesh::Nodes::Topology; using atlas::Field; diff --git a/src/atlas/trans/local/LegendrePolynomials.cc b/src/atlas/trans/local/LegendrePolynomials.cc index 5674924bb..639f76a82 100644 --- a/src/atlas/trans/local/LegendrePolynomials.cc +++ b/src/atlas/trans/local/LegendrePolynomials.cc @@ -12,8 +12,8 @@ #include #include -#include "atlas/trans/local/LegendrePolynomials.h" #include "atlas/array.h" +#include "atlas/trans/local/LegendrePolynomials.h" namespace atlas { namespace trans { diff --git a/src/atlas/util/Config.cc b/src/atlas/util/Config.cc index 0f4b6b36f..a0802dac7 100644 --- a/src/atlas/util/Config.cc +++ b/src/atlas/util/Config.cc @@ -18,10 +18,10 @@ #include "eckit/parser/JSON.h" #include "eckit/parser/YAMLParser.h" -#include "atlas/util/Config.h" #include "atlas/grid/Grid.h" #include "atlas/mesh/Mesh.h" #include "atlas/runtime/ErrorHandling.h" +#include "atlas/util/Config.h" using std::string; diff --git a/src/atlas/util/Earth.cc b/src/atlas/util/Earth.cc index 5ebb25738..c1712f4c6 100644 --- a/src/atlas/util/Earth.cc +++ b/src/atlas/util/Earth.cc @@ -14,8 +14,8 @@ #include "eckit/exception/Exceptions.h" #include "eckit/types/FloatCompare.h" -#include "atlas/util/Earth.h" #include "atlas/util/Constants.h" +#include "atlas/util/Earth.h" #include "atlas/util/Point.h" namespace atlas { diff --git a/src/atlas/util/LonLatPolygon.cc b/src/atlas/util/LonLatPolygon.cc index 8c9103cb9..b1bab0bc1 100644 --- a/src/atlas/util/LonLatPolygon.cc +++ b/src/atlas/util/LonLatPolygon.cc @@ -14,8 +14,8 @@ #include #include -#include "atlas/util/LonLatPolygon.h" #include "atlas/util/CoordinateEnums.h" +#include "atlas/util/LonLatPolygon.h" namespace atlas { namespace util { diff --git a/src/atlas/util/Polygon.cc b/src/atlas/util/Polygon.cc index 2a924a332..7c365768d 100644 --- a/src/atlas/util/Polygon.cc +++ b/src/atlas/util/Polygon.cc @@ -16,9 +16,9 @@ #include "eckit/exception/Exceptions.h" #include "eckit/types/FloatCompare.h" -#include "atlas/util/Polygon.h" #include "atlas/mesh/Nodes.h" #include "atlas/util/CoordinateEnums.h" +#include "atlas/util/Polygon.h" namespace atlas { namespace util { diff --git a/src/atlas/util/Rotation.cc b/src/atlas/util/Rotation.cc index ba4e8d5bb..bde44090c 100644 --- a/src/atlas/util/Rotation.cc +++ b/src/atlas/util/Rotation.cc @@ -13,10 +13,10 @@ #include "eckit/config/Parametrisation.h" -#include "atlas/util/Rotation.h" #include "atlas/util/Constants.h" #include "atlas/util/CoordinateEnums.h" #include "atlas/util/Earth.h" +#include "atlas/util/Rotation.h" // Temporary option to activate implementation by RMI during ESCAPE #define OLD_IMPLEMENTATION 0 diff --git a/src/atlas/util/SphericalPolygon.cc b/src/atlas/util/SphericalPolygon.cc index 79c50103e..678e0e56c 100644 --- a/src/atlas/util/SphericalPolygon.cc +++ b/src/atlas/util/SphericalPolygon.cc @@ -15,8 +15,8 @@ #include "eckit/types/FloatCompare.h" -#include "atlas/util/SphericalPolygon.h" #include "atlas/util/CoordinateEnums.h" +#include "atlas/util/SphericalPolygon.h" namespace atlas { namespace util { From 726865cda45cb46cd69b56bd958ee582cb97f2c4 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Thu, 15 Feb 2018 17:35:47 +0000 Subject: [PATCH 353/355] Fix compilation without gridtools-storage --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4007827d..f9d1289cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,8 +140,14 @@ if( ATLAS_HAVE_GRIDTOOLS_STORAGE ) set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA 1 ) endif() +else() + + set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_HOST 0 ) + set( ATLAS_GRIDTOOLS_STORAGE_BACKEND_CUDA 0 ) + endif() + ### OpenACC set( ATLAS_ACC_CAPABLE FALSE ) From cc4c8c984629e919e8e568a1dd6d72ab6f392ddb Mon Sep 17 00:00:00 2001 From: Andreas Mueller Date: Thu, 15 Feb 2018 18:42:50 +0000 Subject: [PATCH 354/355] enabled test_transgeneral to run when trans library is not available --- src/tests/trans/CMakeLists.txt | 1 - src/tests/trans/test_transgeneral.cc | 106 ++++++++++----------------- 2 files changed, 39 insertions(+), 68 deletions(-) diff --git a/src/tests/trans/CMakeLists.txt b/src/tests/trans/CMakeLists.txt index 2aecc8ce4..98139106c 100644 --- a/src/tests/trans/CMakeLists.txt +++ b/src/tests/trans/CMakeLists.txt @@ -47,7 +47,6 @@ ecbuild_add_test( TARGET atlas_test_trans_invtrans_grad ecbuild_add_test( TARGET atlas_test_transgeneral SOURCES test_transgeneral.cc - CONDITION ATLAS_HAVE_TRANS LIBS atlas ENVIRONMENT ATLAS_TRACE_REPORT=1 ) diff --git a/src/tests/trans/test_transgeneral.cc b/src/tests/trans/test_transgeneral.cc index 8cb24556d..1f4ee4208 100644 --- a/src/tests/trans/test_transgeneral.cc +++ b/src/tests/trans/test_transgeneral.cc @@ -540,17 +540,6 @@ double spectral_transform_test( double trc, // truncation double rms = compute_rms( g.size(), rgp, rgp_analytic ); - /*out << "m=" << m << " n=" << n << " imag:" << imag << " structured:" << - grid::StructuredGrid(g) << " error:" << rms; - if( rms > 2.e-15 ) { - out << " !!!!" << std::endl; - for( int jp=0; jp( option::name( "spf" ) ); Field gpf = gridpoints.createField( option::name( "gpf" ) ); @@ -684,25 +673,25 @@ CASE( "test_transgeneral_with_translib" ) { array::ArrayView sp = array::make_view( spf ); sp.assign( 0. ); sp( k ) = 1.; - - EXPECT_NO_THROW( transIFS.invtrans( spf, gpf ) ); - - spectral_transform_grid_analytic( trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data(), 2, - 2 ); + spectral_transform_grid_analytic( trc, trc, n, m, imag, g, // + rspecg.data(), rgp_analytic.data(), 2, 2 ); // compute spectral transform with the general transform: spectral_transform_grid( trc, trc, g, sp.data(), rgp.data(), false ); - array::ArrayView gp = array::make_view( gpf ); - double rms_trans = compute_rms( g.size(), gp.data(), rgp.data() ); - double rms_gen = compute_rms( g.size(), rgp.data(), rgp_analytic.data() ); + + double rms_gen = compute_rms( g.size(), rgp.data(), rgp_analytic.data() ); if ( rms_gen >= tolerance ) { ATLAS_DEBUG_VAR( rms_gen ); ATLAS_DEBUG_VAR( tolerance ); } EXPECT( rms_gen < tolerance ); +#if ATLAS_HAVE_TRANS + EXPECT_NO_THROW( transIFS.invtrans( spf, gpf ) ); + double rms_trans = compute_rms( g.size(), gp.data(), rgp.data() ); EXPECT( rms_trans < tolerance ); +#endif } k++; } @@ -713,7 +702,6 @@ CASE( "test_transgeneral_with_translib" ) { //----------------------------------------------------------------------------- CASE( "test_trans_vordiv_with_translib" ) { - Log::info() << "test_trans_vordiv_with_translib" << std::endl; // test transgeneral by comparing its result with the trans library // this test is based on the test_nomesh case in test_trans.cc @@ -721,16 +709,18 @@ CASE( "test_trans_vordiv_with_translib" ) { std::ostream& out = Log::info(); double tolerance = 1.e-13; - // resolution: (Reduce this number if the test takes too long!) - int res = 12; + // Grid: (Adjust the following line if the test takes too long!) + Grid g( "O12" ); - Grid g( "O" + std::to_string( res ) ); grid::StructuredGrid gs( g ); - int trc = res * 2 - 1; - trans::Trans transIFS( g, trc, util::Config("type", "ifs" ) ); + int ndgl = gs.ny(); + int trc = ndgl - 1; // linear +#if ATLAS_HAVE_TRANS + trans::Trans transIFS( g, trc, util::Config( "type", "ifs" ) ); +#endif trans::Trans transLocal( g, trc, util::Config( "type", "local" ) ); - functionspace::Spectral spectral( transIFS ); + functionspace::Spectral spectral( trc ); functionspace::StructuredColumns gridpoints( g ); int nb_scalar = 2, nb_vordiv = 2; @@ -784,49 +774,33 @@ CASE( "test_trans_vordiv_with_translib" ) { spectral_transform_grid_analytic( trc, trc, n, m, imag, g, rspecg.data(), rgp_analytic.data(), ivar_in, ivar_out ); - EXPECT_NO_THROW( transIFS.invtrans( nb_scalar, sp.data(), nb_vordiv, vor.data(), - div.data(), gp.data() ) ); - - // compute spectral transform with the general transform: - // EXPECT_NO_THROW( spectral_transform_grid(trc, trc, g, sp, - // rgp, false) ); - // EXPECT_NO_THROW( transLocal.invtrans( nb_scalar, sp, rgp) ); EXPECT_NO_THROW( transLocal.invtrans( nb_scalar, sp.data(), nb_vordiv, vor.data(), div.data(), rgp.data() ) ); int pos = ( ivar_out * nb_vordiv + jfld ); - // Log::info() << "Case " << icase << " Analytic solution: - // ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << - // m << " n=" << n << " imag=" << imag << " k=" << k << - // std::endl; - // for( int j=0; j= tolerance ) { + Log::info() + << "Case " << icase << " ivar_in=" << ivar_in << " ivar_out=" << ivar_out + << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; + ATLAS_DEBUG_VAR( rms_gen ); + ATLAS_DEBUG_VAR( tolerance ); + } + EXPECT( rms_gen < tolerance ); + icase++; + +#if ATLAS_HAVE_TRANS + EXPECT_NO_THROW( transIFS.invtrans( nb_scalar, sp.data(), nb_vordiv, vor.data(), + div.data(), gp.data() ) ); + double rms_trans = + compute_rms( g.size(), gp.data() + pos * g.size(), rgp_analytic.data() ); double rms_diff = compute_rms( g.size(), rgp.data() + pos * g.size(), gp.data() + pos * g.size() ); - - if ( rms_gen >= tolerance || rms_trans >= tolerance || rms_diff >= tolerance ) { + EXPECT( rms_trans < tolerance ); + if ( rms_trans >= tolerance || rms_diff >= tolerance ) { Log::info() << "Case " << icase << " ivar_in=" << ivar_in << " ivar_out=" << ivar_out << " m=" << m << " n=" << n << " imag=" << imag << " k=" << k << std::endl; @@ -835,9 +809,7 @@ CASE( "test_trans_vordiv_with_translib" ) { ATLAS_DEBUG_VAR( rms_diff ); ATLAS_DEBUG_VAR( tolerance ); } - EXPECT( rms_trans < tolerance ); - EXPECT( rms_gen < tolerance ); - icase++; +#endif } k++; } From 120b4f460ba8c035426c472a527bb2366bf889c1 Mon Sep 17 00:00:00 2001 From: Willem Deconinck Date: Fri, 16 Feb 2018 12:56:44 +0000 Subject: [PATCH 355/355] Remove warning --- src/atlas/meshgenerator/StructuredMeshGenerator.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atlas/meshgenerator/StructuredMeshGenerator.cc b/src/atlas/meshgenerator/StructuredMeshGenerator.cc index f5e01ebff..342cf608c 100644 --- a/src/atlas/meshgenerator/StructuredMeshGenerator.cc +++ b/src/atlas/meshgenerator/StructuredMeshGenerator.cc @@ -820,7 +820,7 @@ void StructuredMeshGenerator::generate_mesh( const grid::StructuredGrid& rg, con } else if ( include_periodic_ghost_points ) // add periodic point { -#warning TODO: use second approach +//#warning TODO: use commented approach part( jnode ) = mypart; // part(jnode) = parts.at( offset_glb.at(jlat) ); ghost( jnode ) = 1; @@ -915,7 +915,7 @@ void StructuredMeshGenerator::generate_mesh( const grid::StructuredGrid& rg, con lonlat( inode, LAT ) = crd[LAT]; glb_idx( inode ) = periodic_glb.at( jlat ) + 1; -#warning TODO: use second approach +//#warning TODO: use commented approach // part(inode) = parts.at( offset_glb.at(jlat) ); part( inode ) = mypart; // The actual part will be fixed later ghost( inode ) = 1;