PrecisionAdaptor.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2019-2020 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Class
27  Foam::PrecisionAdaptor
28 
29 Description
30  Conversion adaptor for Field/List that either wrap the input as a
31  reference, or creates a temporary pointer and copies the values
32  on construction/destruction.
33 
34  This provides, for example, automatic conversion between types
35  for linear solvers able to run mixed precision.
36 
37 \*---------------------------------------------------------------------------*/
38 
39 #ifndef PrecisionAdaptor_H
40 #define PrecisionAdaptor_H
41 
42 #include "refPtr.H"
43 #include "Field.H"
44 
45 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
46 
47 namespace Foam
48 {
49 
50 //- A const Field/List wrapper with possible data conversion
51 template<class Type, class InputType, template<class> class Container = Field>
53 :
54  public refPtr<Container<Type>>
55 {
56  // Private Member Functions
57 
58  //- Copy in field
59  void copyInput(const Container<InputType>& input)
60  {
61  this->reset(new Container<Type>(input.size()));
62  std::copy(input.cbegin(), input.cend(), this->ref().begin());
63  }
64 
65  //- Construct from tmp Field, copy/move as required
66  void moveInput(tmp<Container<InputType>>& input)
67  {
68  if (std::is_same<Type, InputType>::value)
69  {
70  auto& tinput = reinterpret_cast<tmp<Container<Type>>&>(input);
71 
72  if (tinput.is_pointer())
73  {
74  // Acquire control of the managed pointer
75  this->reset(tinput.ptr());
76  }
77  else
78  {
79  // Use const reference
80  this->cref(tinput.cref());
81  }
82  }
83  else
84  {
85  this->copyInput(input.cref());
86  }
87  input.clear();
88  }
89 
90 
91 public:
92 
93  //- The adapted field type
94  typedef Container<Type> FieldType;
95 
96 
97  // Constructors
98 
99  //- Construct from Container<InputType>, copying on input as required
100  ConstPrecisionAdaptor(const Container<InputType>& input)
101  :
102  refPtr<Container<Type>>()
103  {
104  if (std::is_same<Type, InputType>::value)
105  {
106  // Use const reference directly
107  this->cref(reinterpret_cast<const FieldType&>(input));
108  }
109  else
110  {
111  this->copyInput(input);
112  }
113  }
114 
115 
116  //- Construct from tmp Container, copy/move as required
117  ConstPrecisionAdaptor(tmp<Container<InputType>>&& input)
118  :
119  refPtr<Container<Type>>()
120  {
121  this->moveInput(input);
122  }
123 
124 
125  //- Construct from tmp Container, copy/move as required
126  ConstPrecisionAdaptor(const tmp<Container<InputType>>& input)
127  :
128  refPtr<Container<Type>>()
129  {
130  this->moveInput(const_cast<tmp<Container<InputType>>&>(input));
131  }
132 
133 
134  // Member Functions
135 
136  // May need in the future: using refPtr<Container<Type>>::get;
137 
138  //- Return the field
139  static const Container<Type>& get
140  (
141  const Container<InputType>& input,
142  Container<Type>& dst
143  )
144  {
145  if (std::is_same<Type, InputType>::value)
146  {
147  return reinterpret_cast<const FieldType&>(input);
148  }
149  else
150  {
151  dst.resize(input.size());
152  std::copy(input.cbegin(), input.cend(), dst.begin());
153  return dst;
154  }
155  }
156 };
157 
158 
159 //- A non-const Field/List wrapper with possible data conversion
160 template<class Type, class InputType, template<class> class Container = Field>
161 class PrecisionAdaptor
162 :
163  public refPtr<Container<Type>>
164 {
165  // Private Data
166 
167  //- Reference to underlying (input) data
168  Container<InputType>& ref_;
169 
170 
171  // Private Member Functions
172 
173  //- Copy in field
174  void copyInput(const Container<InputType>& input, const bool copy)
175  {
176  this->reset(new Container<Type>(input.size()));
177  if (copy)
178  {
179  std::copy(input.cbegin(), input.cend(), this->ref().begin());
180  }
181  }
182 
183 
184 public:
185 
186  //- The adapted field type
187  typedef Container<Type> FieldType;
188 
189 
190  // Constructors
191 
192  //- Construct from Container<InputType>, copying on input if required
193  PrecisionAdaptor(Container<InputType>& input, const bool copy = true)
194  :
195  refPtr<Container<Type>>(),
196  ref_(input)
197  {
198  if (std::is_same<Type, InputType>::value)
199  {
200  // Use non-const reference directly
201  this->ref(reinterpret_cast<FieldType&>(ref_));
202  }
203  else
204  {
205  this->copyInput(input, copy);
206  }
207  }
208 
209 
210  //- Destructor, copy back on destroy
212  {
213  if (this->is_pointer())
214  {
215  const FieldType& store = this->cref();
216  ref_.resize(store.size()); // extra safety
217  std::copy(store.cbegin(), store.cend(), ref_.begin());
218  }
219  }
220 };
221 
222 
223 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
224 
225 } // End namespace Foam
226 
227 
228 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
229 
230 #endif
231 
232 // ************************************************************************* //
Foam::refPtr< Container< Type > >::is_pointer
bool is_pointer() const noexcept
True if this is a managed pointer (not a reference)
Definition: refPtr.H:163
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
refPtr.H
Foam::refPtr< Container< Type > >::get
Container< Type > * get() noexcept
Return pointer without nullptr checking.
Definition: refPtr.H:175
Foam::ConstPrecisionAdaptor::ConstPrecisionAdaptor
ConstPrecisionAdaptor(tmp< Container< InputType >> &&input)
Construct from tmp Container, copy/move as required.
Definition: PrecisionAdaptor.H:116
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::refPtr< Container< Type > >::cref
const Container< Type > & cref() const
Definition: refPtrI.H:187
Field.H
Foam::PrecisionAdaptor::~PrecisionAdaptor
~PrecisionAdaptor()
Destructor, copy back on destroy.
Definition: PrecisionAdaptor.H:210
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::PrecisionAdaptor
A non-const Field/List wrapper with possible data conversion.
Definition: PrecisionAdaptor.H:160
Foam::refPtr< Container< Type > >::reset
void reset(Container< Type > *p=nullptr) noexcept
Delete managed temporary object and set to new given pointer.
Definition: refPtrI.H:269
Foam::PrecisionAdaptor::FieldType
Container< Type > FieldType
The adapted field type.
Definition: PrecisionAdaptor.H:186
Foam::ConstPrecisionAdaptor::ConstPrecisionAdaptor
ConstPrecisionAdaptor(const Container< InputType > &input)
Construct from Container<InputType>, copying on input as required.
Definition: PrecisionAdaptor.H:99
Foam::ConstPrecisionAdaptor
A const Field/List wrapper with possible data conversion.
Definition: PrecisionAdaptor.H:51
Foam::input
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:55
Foam::ConstPrecisionAdaptor::FieldType
Container< Type > FieldType
The adapted field type.
Definition: PrecisionAdaptor.H:93
Foam::PrecisionAdaptor::PrecisionAdaptor
PrecisionAdaptor(Container< InputType > &input, const bool copy=true)
Construct from Container<InputType>, copying on input if required.
Definition: PrecisionAdaptor.H:192
Foam::refPtr< Container< Type > >::ref
Container< Type > & ref() const
Definition: refPtrI.H:204
Foam::ConstPrecisionAdaptor::ConstPrecisionAdaptor
ConstPrecisionAdaptor(const tmp< Container< InputType >> &input)
Construct from tmp Container, copy/move as required.
Definition: PrecisionAdaptor.H:125
Foam::refPtr
A class for managing references or pointers (no reference counting)
Definition: PtrList.H:60