atlas
Unstructured.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2013 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation
8  * nor does it submit to any jurisdiction.
9  */
10 
16 
17 #pragma once
18 
19 #include <cstddef>
20 #include <memory>
21 #include <vector>
22 
23 #include "atlas/grid/detail/grid/Grid.h"
24 #include "atlas/runtime/Exception.h"
25 #include "atlas/util/Point.h"
26 
27 namespace atlas {
28 class Mesh;
29 }
30 
31 namespace atlas {
32 namespace grid {
33 namespace detail {
34 namespace grid {
35 
36 class Unstructured : public Grid {
37 private:
38  struct ComputePointXY {
39  void update_value( idx_t n ) {}
40  void compute_value( idx_t n, PointXY& point ) { grid_.xy( n, point.data() ); }
41  const PointXY& get_reference( idx_t n ) const { return grid_.xy( n ); }
42 
43  ComputePointXY( const Unstructured& grid ) : grid_( grid ) {}
44  const Unstructured& grid_;
45  };
46 
47  struct ComputePointLonLat {
48  void update_value( idx_t n ) {
49  if ( n < size_ ) {
50  grid_.lonlat( n, point_.data() );
51  }
52  }
53  void compute_value( idx_t n, PointLonLat& point ) { grid_.lonlat( n, point.data() ); }
54  const PointLonLat& get_reference( idx_t n ) const { return point_; }
55 
56  ComputePointLonLat( const Unstructured& grid ) : grid_( grid ), size_( grid_.size() ) {}
57  const Unstructured& grid_;
58  idx_t size_;
59  PointLonLat point_;
60  };
61 
62  template <typename Base, typename ComputePoint>
63  class UnstructuredIterator : public Base {
64  public:
65  UnstructuredIterator( const Unstructured& grid, bool begin = true ) :
66  grid_( grid ),
67  size_( static_cast<idx_t>( grid_.points_->size() ) ),
68  n_( begin ? 0 : size_ ),
69  point_computer_{grid_} {
70  point_computer_.update_value( n_ );
71  }
72 
73  virtual bool next( typename Base::value_type& point ) {
74  if ( n_ < size_ ) {
75  point_computer_.compute_value( n_, point );
76  ++n_;
77  return true;
78  }
79  else {
80  return false;
81  }
82  }
83 
84  virtual typename Base::reference operator*() const { return point_computer_.get_reference( n_ ); }
85 
86  virtual const Base& operator++() {
87  ++n_;
88  point_computer_.update_value( n_ );
89  return *this;
90  }
91 
92 
93  virtual const Base& operator+=( typename Base::difference_type distance ) {
94  n_ += distance;
95  point_computer_.update_value( n_ );
96  return *this;
97  }
98 
99  virtual bool operator==( const Base& other ) const {
100  return n_ == static_cast<const UnstructuredIterator&>( other ).n_;
101  }
102 
103  virtual bool operator!=( const Base& other ) const {
104  return n_ != static_cast<const UnstructuredIterator&>( other ).n_;
105  }
106 
107  virtual typename Base::difference_type distance( const Base& other ) const {
108  const auto& _other = static_cast<const UnstructuredIterator&>( other );
109  return _other.n_ - n_;
110  }
111 
112  virtual std::unique_ptr<Base> clone() const {
113  auto result = new UnstructuredIterator( grid_, false );
114  result->n_ = n_;
115  result->point_computer_.update_value( n_ );
116  return std::unique_ptr<Base>( result );
117  }
118 
119  protected:
120  const Unstructured& grid_;
121  idx_t size_;
122  idx_t n_;
123  ComputePoint point_computer_;
124  };
125 
126 public:
127  using IteratorXY = UnstructuredIterator<Grid::IteratorXY, ComputePointXY>;
128  using IteratorLonLat = UnstructuredIterator<Grid::IteratorLonLat, ComputePointLonLat>;
129 
130 public: // methods
131  static std::string static_type() { return "unstructured"; }
132  virtual std::string name() const override;
133  virtual std::string type() const override { return static_type(); }
134 
136  Unstructured( const Grid&, Domain );
137 
139  Unstructured( const Config& );
140 
142  Unstructured( std::vector<PointXY>* pts );
143 
145  Unstructured( std::vector<PointXY>&& pts );
146 
148  Unstructured( const std::vector<PointXY>& pts );
149 
151  Unstructured( const Mesh& m );
152 
154  Unstructured( std::initializer_list<PointXY> );
155 
156  virtual ~Unstructured() override;
157 
158  virtual idx_t size() const override;
159 
160  virtual Spec spec() const override;
161 
162  const PointXY& xy( idx_t n ) const { return ( *points_ )[n]; }
163 
164  PointLonLat lonlat( idx_t n ) const { return projection_.lonlat( ( *points_ )[n] ); }
165 
166  void xy( idx_t n, double crd[] ) const {
167  PointXY& p = ( *points_ )[n];
168  crd[0] = p[0];
169  crd[1] = p[1];
170  }
171 
172  void lonlat( idx_t n, double crd[] ) const {
173  xy( n, crd );
174  projection_.xy2lonlat( crd );
175  }
176 
177  virtual std::unique_ptr<Grid::IteratorXY> xy_begin() const override {
178  return std::unique_ptr<Grid::IteratorXY>( new IteratorXY( *this ) );
179  }
180  virtual std::unique_ptr<Grid::IteratorXY> xy_end() const override {
181  return std::unique_ptr<Grid::IteratorXY>( new IteratorXY( *this, false ) );
182  }
183  virtual std::unique_ptr<Grid::IteratorLonLat> lonlat_begin() const override {
184  return std::unique_ptr<Grid::IteratorLonLat>( new IteratorLonLat( *this ) );
185  }
186  virtual std::unique_ptr<Grid::IteratorLonLat> lonlat_end() const override {
187  return std::unique_ptr<Grid::IteratorLonLat>( new IteratorLonLat( *this, false ) );
188  }
189 
190  Config meshgenerator() const override;
191  Config partitioner() const override;
192 
193 private: // methods
194  virtual void print( std::ostream& ) const override;
195 
197  virtual void hash( eckit::Hash& ) const override;
198 
200  virtual RectangularLonLatDomain lonlatBoundingBox() const override;
201 
202 protected:
204  std::unique_ptr<std::vector<PointXY>> points_;
205 
207  mutable std::string shortName_;
208 
210  mutable std::unique_ptr<Grid::Spec> cached_spec_;
211 };
212 
213 extern "C" {
214 const Unstructured* atlas__grid__Unstructured__points( const double lonlat[], int shapef[], int stridesf[] );
215 const Unstructured* atlas__grid__Unstructured__config( util::Config* conf );
216 }
217 
218 
219 } // namespace grid
220 } // namespace detail
221 } // namespace grid
222 } // namespace atlas
std::string hash() const
Definition: Grid.cc:127
Unstructured(const Grid &, Domain)
Constructor converting any Grid with domain to an unstructured grid.
Definition: Unstructured.cc:79
Definition: Unstructured.h:36
This file contains classes and functions working on points.
Point in longitude-latitude coordinate system.
Definition: Point.h:103
virtual idx_t size() const override
Definition: Unstructured.cc:192
std::string shortName_
Cache for the shortName.
Definition: Unstructured.h:207
Definition: Mesh.h:55
std::unique_ptr< Grid::Spec > cached_spec_
Cache for the spec since may be quite heavy to compute.
Definition: Unstructured.h:210
std::unique_ptr< std::vector< PointXY > > points_
Storage of coordinate points.
Definition: Unstructured.h:204
Definition: Domain.h:130
virtual std::string name() const override
Human readable name (may not be unique)
Definition: Unstructured.cc:165
Definition: Grid.h:42
Definition: Domain.h:48
Point in arbitrary XY-coordinate system.
Definition: Point.h:40
Contains all atlas classes and methods.
Definition: atlas-grids.cc:33
long idx_t
Integer type for indices in connectivity tables.
Definition: config.h:42
Configuration class used to construct various atlas components.
Definition: Config.h:27