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)
173  {
174  Container<Type>* p = new Container<Type>(input.size());
175  this->reset(p);
176  std::copy(input.cbegin(), input.cend(), p->begin());
177  }
178 
179 
180 public:
181 
182  //- The adapted field type
183  typedef Container<Type> FieldType;
184 
185 
186  // Constructors
187 
188  //- Construct from Container<InputType>, copying on input as required
189  PrecisionAdaptor(Container<InputType>& input)
190  :
191  tmpNrc<Container<Type>>(),
192  ref_(input)
193  {
194  if (std::is_same<Type, InputType>::value)
195  {
196  this->cref(reinterpret_cast<const FieldType&>(input));
197  }
198  else
199  {
200  this->copyInput(input);
201  }
202  }
203 
204 
205  //- Destructor, copying on destroy
207  {
208  if (this->isTmp())
209  {
210  const FieldType& store = this->cref();
211  ref_.resize(store.size());
212  std::copy(store.cbegin(), store.cend(), ref_.begin());
213  }
214  }
215 
216 
217  // Member Functions
218 
219  //- Allow modification without const-ref check
220  FieldType& ref()
221  {
222  return this->constCast();
223  }
224 };
225 
226 
227 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
228 
229 } // End namespace Foam
230 
231 
232 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
233 
234 #endif
235 
236 // ************************************************************************* //
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:205
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:219
Foam::PrecisionAdaptor::FieldType
Container< Type > FieldType
The adapted field type.
Definition: PrecisionAdaptor.H:182
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)
Construct from Container<InputType>, copying on input as required.
Definition: PrecisionAdaptor.H:188
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