Commit bf9d74ba authored by Mark Olesen's avatar Mark Olesen Committed by Andrew Heather
Browse files

ENH: increase robustness of PrecisionAdaptor

- overload the ref() method to allow modification of the referenced
  (non-const) field directly. Same as constCast(), but less typing
  and less prone to error.

- construct ConstPrecisionAdaptor from tmp for improved efficiency.
parent 255e4735
......@@ -49,28 +49,85 @@ class ConstPrecisionAdaptor
:
public tmp<Field<Type>>
{
// Private Member Functions
//- Copy in field
void copyInput(const Field<InputType>& input)
{
this->clear();
Field<Type>* p = new Field<Type>(input.size());
this->reset(p);
std::copy(input.cbegin(), input.cend(), p->begin());
}
//- Construct from tmp Field, copy/move as required
void moveInput(tmp<Field<InputType>>& input)
{
if (std::is_same<Type, InputType>::value)
{
auto& tinput = reinterpret_cast<tmp<FieldType>&>(input);
if (tinput.isTmp())
{
this->clear();
this->swap(tinput);
}
else
{
this->cref(tinput.cref());
}
}
else
{
this->copyInput(input());
}
input.clear();
}
public:
//- The adapted field type
typedef Field<Type> FieldType;
// Constructors
//- Construct from InputType
//- Construct from Field<InputType>, copying on input as required
ConstPrecisionAdaptor(const Field<InputType>& input)
:
tmp<Field<Type>>()
{
if (std::is_same<Type, InputType>::value)
{
// Set reference - cast for compiler to handle different types
this->cref(reinterpret_cast<const Field<Type>&>(input));
this->cref(reinterpret_cast<const FieldType&>(input));
}
else
{
this->reset(new Field<Type>(input.size()));
std::copy(input.cbegin(), input.cend(), this->ref().begin());
this->copyInput(input);
}
}
//- Construct from tmp Field, copy/move as required
ConstPrecisionAdaptor(tmp<Field<InputType>>&& input)
:
tmp<Field<Type>>()
{
this->moveInput(input);
}
//- Construct from tmp Field, copy/move as required
ConstPrecisionAdaptor(const tmp<Field<InputType>>& input)
:
tmp<Field<Type>>()
{
this->moveInput(const_cast<tmp<Field<InputType>>&>(input));
}
// Member Functions
//- Return the field
......@@ -82,7 +139,7 @@ public:
{
if (std::is_same<Type, InputType>::value)
{
return reinterpret_cast<const Field<Type>&>(input);
return reinterpret_cast<const FieldType&>(input);
}
else
{
......@@ -106,8 +163,25 @@ class PrecisionAdaptor
Field<InputType>& ref_;
// Private Member Functions
//- Copy in field
void copyInput(const Field<InputType>& input)
{
this->clear();
Field<Type>* p = new Field<Type>(input.size());
this->reset(p);
std::copy(input.cbegin(), input.cend(), p->begin());
}
public:
//- The adapted field type
typedef Field<Type> FieldType;
// Constructors
//- Construct from Field<InputType>, copying on input as required
......@@ -118,13 +192,11 @@ public:
{
if (std::is_same<Type, InputType>::value)
{
// Set reference - cast for compiler to handle different types
this->cref(reinterpret_cast<const Field<Type>&>(input));
this->cref(reinterpret_cast<const FieldType&>(input));
}
else
{
this->reset(new Field<Type>(input.size()));
std::copy(input.cbegin(), input.cend(), this->ref().begin());
this->copyInput(input);
}
}
......@@ -134,11 +206,20 @@ public:
{
if (this->isTmp())
{
const Field<Type>& store = this->cref();
const FieldType& store = this->cref();
ref_.resize(store.size());
std::copy(store.cbegin(), store.cend(), ref_.begin());
}
}
// Member Functions
//- Allow modification without const-ref check
FieldType& ref()
{
return this->constCast();
}
};
......
......@@ -41,7 +41,7 @@ Foam::solverPerformance Foam::GAMGSolver::solve
) const
{
PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
solveScalarField& psi = tpsi.constCast();
solveScalarField& psi = tpsi.ref();
ConstPrecisionAdaptor<solveScalar, scalar> tsource(source);
......@@ -581,21 +581,16 @@ void Foam::GAMGSolver::solveCoarsestLevel
{
const label coarsestLevel = matrixLevels_.size() - 1;
label coarseComm = matrixLevels_[coarsestLevel].mesh().comm();
const label coarseComm = matrixLevels_[coarsestLevel].mesh().comm();
if (directSolveCoarsest_)
{
PrecisionAdaptor<scalar, solveScalar> tcorrField
(
coarsestCorrField
);
PrecisionAdaptor<scalar, solveScalar> tcorrField(coarsestCorrField);
coarsestLUMatrixPtr_->solve
(
tcorrField.constCast(),
ConstPrecisionAdaptor<scalar, solveScalar>
(
coarsestSource
)()
tcorrField.ref(),
ConstPrecisionAdaptor<scalar, solveScalar>(coarsestSource)()
);
}
//else if
......
......@@ -73,7 +73,7 @@ Foam::solverPerformance Foam::PBiCG::solve
) const
{
PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
solveScalarField& psi = tpsi.constCast();
solveScalarField& psi = tpsi.ref();
// --- Setup class containing solver performance data
solverPerformance solverPerf
......
......@@ -282,11 +282,9 @@ Foam::solverPerformance Foam::PBiCGStab::solve
) const
{
PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
solveScalarField& psi = tpsi.constCast();
return scalarSolve
(
psi,
tpsi.ref(),
ConstPrecisionAdaptor<solveScalar, scalar>(source)(),
cmpt
);
......
......@@ -220,7 +220,7 @@ Foam::solverPerformance Foam::PCG::solve
PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
return scalarSolve
(
tpsi.constCast(),
tpsi.ref(),
ConstPrecisionAdaptor<solveScalar, scalar>(source)(),
cmpt
);
......
......@@ -86,7 +86,7 @@ Foam::solverPerformance Foam::smoothSolver::solve
) const
{
PrecisionAdaptor<solveScalar, scalar> tpsi(psi_s);
solveScalarField& psi = tpsi.constCast();
solveScalarField& psi = tpsi.ref();
// Setup class containing solver performance data
solverPerformance solverPerf(typeName, fieldName_);
......
......@@ -119,7 +119,6 @@ Foam::tmp<Foam::scalarField> Foam::faMatrix<Foam::scalar>::residual() const
);
ConstPrecisionAdaptor<scalar, solveScalar> tres_s(tres);
addBoundarySource(tres_s.ref());
return tres_s;
......
......@@ -184,7 +184,7 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated
bouCoeffsCmpt,
interfaces,
psiCmpt_ss(),
sourceCmpt_ss.constCast(),
sourceCmpt_ss.ref(),
cmpt
);
......@@ -194,7 +194,7 @@ Foam::SolverPerformance<Type> Foam::fvMatrix<Type>::solveSegregated
bouCoeffsCmpt,
interfaces,
psiCmpt_ss(),
sourceCmpt_ss.constCast(),
sourceCmpt_ss.ref(),
cmpt
);
}
......
......@@ -215,8 +215,10 @@ Foam::tmp<Foam::scalarField> Foam::fvMatrix<Foam::scalar>::residual() const
0
)
);
ConstPrecisionAdaptor<scalar, solveScalar> tres_s(tres);
addBoundarySource(tres_s.constCast());
addBoundarySource(tres_s.ref());
return tres_s;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment