OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
PRegion.h
Go to the documentation of this file.
1// -*- C++ -*-
2/***************************************************************************
3 *
4 * The IPPL Framework
5 *
6 *
7 * Visit http://people.web.psi.ch/adelmann/ for more details
8 *
9 ***************************************************************************/
10
11#ifndef PREGION_H
12#define PREGION_H
13
14/***********************************************************************
15 * PRegion represents a (possibly continuous) numeric interval. It is
16 * similar to Index, with the following differences:
17 * 1. It is templated on the data type; Index always uses integers
18 * 2. A PRegion is defined between two endpoints A and B; the PRegion
19 * includes values X where A <= X < B (i.e., X in [A,B) )
20 * 3. PRegion does not keep track of a base Index, and does not
21 * supply the plugBase operation. It is not designed for use in
22 * Field operations like Index is, it is meant instead for use in
23 * Particle construction and usage.
24 *
25 ***********************************************************************
26 *
27 * PRegion<T>() --> make a PRegion on [0,1)
28 * PRegion<T>(B) --> make a PRegion on [0,B)
29 * PRegion<T>(A,B) --> make a PRegion on [A,B)
30 *
31 ***********************************************************************/
32
33// include files
34#include "Message/Message.h"
35
36#include <iostream>
37
38// forward declarations
39template<class T> class PRegion;
40template <class T>
42template <class T>
44template <class T>
46template <class T>
48template <class T>
50template <class T>
52template <class T>
54template <class T>
56template<class T>
57std::ostream& operator<<(std::ostream&, const PRegion<T>&);
58
59template<class T>
60class PRegion {
61
62public:
63 //
64 // Member functions. Make these inline for efficiency.
65 //
66
67 // Constructors
68 PRegion() : First(0), Last(1) {} // [0,1)
69 PRegion(T B) : First(0), Last(B) {} // [0,B)
70 PRegion(T A, T B) : First(A), Last(B) {} // [A,B)
71
72 // Destructor ... nothing to do
74
75 // General query functions
76 T min() const { return (First < Last ? First : Last); } // smallest elem
77 T max() const { return (First > Last ? First : Last); } // largest elem
78 T length() const { return (max() - min()); } // length of region
79 T first() const { return First; } // first element.
80 T last() const { return Last; } // last element.
81 bool empty() const { return (First == Last);} // is it empty?
82
83 // compute-assign operators
85 First += t;
86 Last += t;
87 return *this;
88 }
90 First -= t;
91 Last -= t;
92 return *this;
93 }
95 First *= t;
96 Last *= t;
97 return *this;
98 }
100 if (t != 0) {
101 First /= t;
102 Last /= t;
103 }
104 return *this;
105 }
106
107 // Intersect with another PRegion. Since we have possibly continuous
108 // variables, we do not consider the stride here, just where the two
109 // intervals overlap (if at all)
111 T A = 0;
112 T B = 0;
113
114 // find min and max of both ranges
115 T Amin = min();
116 T Amax = max();
117 T Bmin = r.min();
118 T Bmax = r.max();
119
120 // make sure these regions overlap
121 // must check special case of single points
122 if (Amin == Amax) {
123 if ((Bmin == Bmax && Amin == Bmin) ||
124 (Bmin != Bmax && Amin >= Bmin && Amin < Bmax))
125 A = B = Amin;
126 }
127 else if (Bmin == Bmax) {
128 if (Bmin >= Amin && Bmin < Amax)
129 A = B = Bmin;
130 }
131 else {
132 if (Amax > Bmin && Bmax > Amin) {
133 A = (Amin > Bmin ? Amin : Bmin);
134 B = (Amax < Bmax ? Amax : Bmax);
135 }
136 }
137
138 // now return the intersecting region
139 return PRegion<T>(A, B);
140 }
141
142 // Test to see if there is any overlap between two PRegions
143 bool touches(const PRegion<T>& r) const {
144 bool retval = false;
145 // find min and max of both ranges
146 T Amin = min();
147 T Amax = max();
148 T Bmin = r.min();
149 T Bmax = r.max();
150
151 // check for overlap ... must check special case of single points
152 if (Amin == Amax) {
153 if ((Bmin == Bmax && Amin == Bmin) ||
154 (Bmin != Bmax && Amin >= Bmin && Amin < Bmax))
155 retval = true;
156 }
157 else if (Bmin == Bmax) {
158 if (Bmin >= Amin && Bmin < Amax)
159 retval = true;
160 }
161 else {
162 if (Amax > Bmin && Bmax > Amin)
163 retval = true;
164 }
165 return retval;
166 }
167
168 // Test to see if the given PRegion is contained within this one
169 bool contains(const PRegion<T>& r) const {
170 return ( min() <= r.min() && max() >= r.max() );
171 }
172
173 // Split one into two.
174 bool split(PRegion<T>& l, PRegion<T>& r) const {
175 T mid = First + (Last - First) / T(2);
176 l = PRegion<T>(First, mid);
177 r = PRegion<T>(mid, Last);
178 return true;
179 }
180
181 // An operator< so we can impose some sort of ordering.
182 bool operator<(const PRegion<T>& r) const {
183 T L1 = length();
184 T L2 = r.length();
185 T Amin = min();
186 T Bmin = r.min();
187 return ( (L1 < L2) || ( (L1 == L2) && ( (Amin < Bmin) ||
188 ( (Amin == Bmin) && (L1 > 0) ) ) ) );
189 }
190
191 // Test for equality.
192 bool operator==(const PRegion<T>& r) const {
193 return ( (Last==r.Last) && (First==r.First) );
194 }
195
196 // put data into a message to send to another node
198 T d[2];
199 d[0] = First;
200 d[1] = Last;
201 m.put(d, d + 2);
202 return m;
203 }
204
205 // get data out from a message
207 T d[2];
208 m.get_iter(d);
209 *this = PRegion<T>(d[0], d[1]);
210 return m;
211 }
212
213private:
214 // The interval endpoints
216};
217
218
219// Additive operations.
220template <class T>
221inline
223 return PRegion<T>(r.first() + t, r.last() + t);
224}
225template <class T>
226inline
228 return PRegion<T>(r.first() + t, r.last() + t);
229}
230template <class T>
231inline
233 return PRegion<T>(r.first() - t, r.last() - t);
234}
235template <class T>
236inline
238 return PRegion<T>(t - r.first(), t - r.last());
239}
240
241// Multipplicative operations.
242template <class T>
243inline
245 return PRegion<T>(-r.first(), -r.last());
246}
247template <class T>
248inline
250 return PRegion<T>(r.first() * t, r.last() * t);
251}
252template <class T>
253inline
255 return PRegion<T>(r.first() * t, r.last() * t);
256}
257template <class T>
258inline
260 if (t != 0)
261 return PRegion<T>(r.first() / t, r.last() / t);
262 else // This is an error!!
263 return r;
264}
265
266// Print out PRegion.
267template <class T>
268inline
269std::ostream& operator<<(std::ostream& out, const PRegion<T>& r) {
270 out << '[' << r.min();
271 out << ',' << r.max();
272 out << ')';
273 return out;
274}
275
276
277#endif // PREGION_H
278
279/***************************************************************************
280 * $RCSfile: PRegion.h,v $ $Author: adelmann $
281 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:32 $
282 * IPPL_VERSION_ID: $Id: PRegion.h,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $
283 ***************************************************************************/
std::ostream & operator<<(std::ostream &, const PRegion< T > &)
Definition: PRegion.h:269
PRegion< T > operator+(const PRegion< T > &, T)
Definition: PRegion.h:222
PRegion< T > operator-(const PRegion< T > &, T)
Definition: PRegion.h:232
PRegion< T > operator/(const PRegion< T > &, T)
Definition: PRegion.h:259
PRegion< T > operator*(const PRegion< T > &, T)
Definition: PRegion.h:249
Message & get_iter(OutputIterator o)
Definition: Message.h:511
Message & put(const T &val)
Definition: Message.h:406
PRegion(T B)
Definition: PRegion.h:69
PRegion< T > & operator*=(T t)
Definition: PRegion.h:94
PRegion< T > & operator+=(T t)
Definition: PRegion.h:84
bool split(PRegion< T > &l, PRegion< T > &r) const
Definition: PRegion.h:174
bool contains(const PRegion< T > &r) const
Definition: PRegion.h:169
Message & putMessage(Message &m)
Definition: PRegion.h:197
PRegion(T A, T B)
Definition: PRegion.h:70
~PRegion()
Definition: PRegion.h:73
PRegion< T > & operator/=(T t)
Definition: PRegion.h:99
PRegion< T > & operator-=(T t)
Definition: PRegion.h:89
PRegion< T > intersect(const PRegion< T > &r) const
Definition: PRegion.h:110
T max() const
Definition: PRegion.h:77
bool operator<(const PRegion< T > &r) const
Definition: PRegion.h:182
T Last
Definition: PRegion.h:215
bool operator==(const PRegion< T > &r) const
Definition: PRegion.h:192
bool touches(const PRegion< T > &r) const
Definition: PRegion.h:143
Message & getMessage(Message &m)
Definition: PRegion.h:206
PRegion()
Definition: PRegion.h:68
T first() const
Definition: PRegion.h:79
bool empty() const
Definition: PRegion.h:81
T min() const
Definition: PRegion.h:76
T last() const
Definition: PRegion.h:80
T First
Definition: PRegion.h:215
T length() const
Definition: PRegion.h:78