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 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 that either wraps as a tmp reference
31  or creates the necessary tmp and copies the values on construction
32  and destruction.
33  This provides automatic conversion between (scalar) types for use
34  with linear solvers able to run mixed precision.
35 
36 \*---------------------------------------------------------------------------*/
37 
38 #ifndef PrecisionAdaptor_H
39 #define PrecisionAdaptor_H
40 
41 #include "tmpNrc.H"
42 #include "Field.H"
43 
44 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
45 
46 namespace Foam
47 {
48 
49 //- A const Field wrapper with possible data conversion
50 template<class Type, class InputType, template<class> class Container = Field>
52 :
53  public tmpNrc<Container<Type>>
54 {
55  // Private Member Functions
56 
57  //- Copy in field
58  void copyInput(const Container<InputType>& input)
59  {
60  this->clear();
61 
62  Container<Type>* p = new Container<Type>(input.size());
63  this->reset(p);
64  std::copy(input.cbegin(), input.cend(), p->begin());
65  }
66 
67  //- Construct from tmp Field, copy/move as required
68  void moveInput(tmp<Container<InputType>>& input)
69  {
70  if (std::is_same<Type, InputType>::value)
71  {
72  auto& tinput = reinterpret_cast<tmp<Container<Type>>&>(input);
73 
74  if (tinput.isTmp())
75  {
76  // Reset to tmp
77  this->reset(tinput.ptr());
78  }
79  else
80  {
81  this->cref(tinput.cref());
82  }
83  }
84  else
85  {
86  this->copyInput(input());
87  }
88  input.clear();
89  }
90 
91 
92 public:
93 
94  //- The adapted field type
95  typedef Container<Type> FieldType;
96 
97 
98  // Constructors
99 
100  //- Construct from Container<InputType>, copying on input as required
101  ConstPrecisionAdaptor(const Container<InputType>& input)
102  :
103  tmpNrc<Container<Type>>()
104  {
105  if (std::is_same<Type, InputType>::value)
106  {
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  tmpNrc<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  tmpNrc<Container<Type>>()
129  {
130  this->moveInput(const_cast<tmp<Container<InputType>>&>(input));
131  }
132 
133 
134  // Member Functions
135 
136  //- Return the field
137  static const Container<Type>& get
138  (
139  const Container<InputType>& input,
140  Container<Type>& dst
141  )
142  {
143  if (std::is_same<Type, InputType>::value)
144  {
145  return reinterpret_cast<const FieldType&>(input);
146  }
147  else
148  {
149  dst.resize(input.size());
150  std::copy(input.cbegin(), input.cend(), dst.begin());
151  return dst;
152  }
153  }
154 };
155 
156 
157 //- A Field wrapper with possible data conversion
158 template<class Type, class InputType, template<class> class Container = Field>
159 class PrecisionAdaptor
160 :
161  public tmpNrc<Container<Type>>
162 {
163  // Private Data
164 
165  //- Reference to underlying field
166  Container<InputType>& ref_;
167 
168 
169  // Private Member Functions
170 
171  //- Copy in field
172  void copyInput(const Container<InputType>& input, const bool copy)
173  {
174  Container<Type>* p = new Container<Type>(input.size());
175  this->reset(p);
176  if (copy)
177  {
178  std::copy(input.cbegin(), input.cend(), p->begin());
179  }
180  }
181 
182 
183 public:
184 
185  //- The adapted field type
186  typedef Container<Type> FieldType;
187 
188 
189  // Constructors
190 
191  //- Construct from Container<InputType>, copying on input if required
192  PrecisionAdaptor(Container<InputType>& input, const bool copy = true)
193  :
194  tmpNrc<Container<Type>>(),
195  ref_(input)
196  {
197  if (std::is_same<Type, InputType>::value)
198  {
199  this->cref(reinterpret_cast<const FieldType&>(input));
200  }
201  else
202  {
203  this->copyInput(input, copy);
204  }
205  }
206 
207 
208  //- Destructor, copying on destroy
210  {
211  if (this->isTmp())
212  {
213  const FieldType& store = this->cref();
214  ref_.resize(store.size());
215  std::copy(store.cbegin(), store.cend(), ref_.begin());
216  }
217  }
218 
219 
220  // Member Functions
221 
222  //- Allow modification without const-ref check
223  FieldType& ref()
224  {
225  return this->constCast();
226  }
227 };
228 
229 
230 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
231 
232 } // End namespace Foam
233 
234 
235 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
236 
237 #endif
238 
239 // ************************************************************************* //
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:59
tmpNrc.H
Foam::tmpNrc< Container< Type > >::cref
const Container< Type > & cref() const
Definition: tmpNrcI.H:205
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::tmpNrc
A class for managing temporary objects without reference counting.
Definition: tmpNrc.H:56
Foam::tmpNrc< Container< Type > >::constCast
Container< Type > & constCast() const
Non-const dereference, even if the object is const.
Definition: tmpNrcI.H:246
Field.H
Foam::PrecisionAdaptor::~PrecisionAdaptor
~PrecisionAdaptor()
Destructor, copying on destroy.
Definition: PrecisionAdaptor.H:208
Foam::tmpNrc< Container< Type > >::clear
void clear() const noexcept
Definition: tmpNrcI.H:282
Foam::tmpNrc< Container< Type > >::reset
void reset() noexcept
Release ownership of managed temporary object.
Definition: tmpNrcI.H:293
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::PrecisionAdaptor
A Field wrapper with possible data conversion.
Definition: PrecisionAdaptor.H:158
Foam::PrecisionAdaptor::ref
FieldType & ref()
Allow modification without const-ref check.
Definition: PrecisionAdaptor.H:222
Foam::PrecisionAdaptor::FieldType
Container< Type > FieldType
The adapted field type.
Definition: PrecisionAdaptor.H:185
Foam::ConstPrecisionAdaptor::ConstPrecisionAdaptor
ConstPrecisionAdaptor(const Container< InputType > &input)
Construct from Container<InputType>, copying on input as required.
Definition: PrecisionAdaptor.H:100
Foam::ConstPrecisionAdaptor
A const Field wrapper with possible data conversion.
Definition: PrecisionAdaptor.H:50
Foam::ConstPrecisionAdaptor::FieldType
Container< Type > FieldType
The adapted field type.
Definition: PrecisionAdaptor.H:94
Foam::PrecisionAdaptor::PrecisionAdaptor
PrecisionAdaptor(Container< InputType > &input, const bool copy=true)
Construct from Container<InputType>, copying on input if required.
Definition: PrecisionAdaptor.H:191
Foam::tmpNrc< Container< Type > >::isTmp
bool isTmp() const noexcept
True if this is a managed pointer (not a const reference)
Definition: tmpNrcI.H:156
Foam::ConstPrecisionAdaptor::ConstPrecisionAdaptor
ConstPrecisionAdaptor(const tmp< Container< InputType >> &input)
Construct from tmp Container, copy/move as required.
Definition: PrecisionAdaptor.H:125
Foam::tmpNrc< Container< Type > >::get
Container< Type > * get() noexcept
Return pointer without nullptr checking.
Definition: tmpNrcI.H:191