33template<
class Type,
class DType,
class LUType>
51template<
class Type,
class DType,
class LUType>
54 const Field<LUType>& Lower =
const_cast<const LduMatrix&
>(*this).lower();
55 const Field<LUType>& Upper =
const_cast<const LduMatrix&
>(*this).upper();
56 Field<DType>& Diag = diag();
58 const labelUList& l = lduAddr().lowerAddr();
59 const labelUList& u = lduAddr().upperAddr();
61 for (label face=0; face<l.size(); face++)
69template<
class Type,
class DType,
class LUType>
75 const Field<LUType>& Lower =
const_cast<const LduMatrix&
>(*this).lower();
76 const Field<LUType>& Upper =
const_cast<const LduMatrix&
>(*this).upper();
78 const labelUList& l = lduAddr().lowerAddr();
79 const labelUList& u = lduAddr().upperAddr();
81 for (label face = 0; face < l.size(); face++)
83 sumOff[u[face]] += cmptMag(Lower[face]);
89template<
class Type,
class DType,
class LUType>
93 auto tHpsi = tmp<Field<Type>>::New(lduAddr().size(),
Foam::zero{});
95 if (hasLower() || hasUpper())
97 Type* __restrict__ HpsiPtr = tHpsi.ref().begin();
99 const Type* __restrict__ psiPtr =
psi.begin();
101 const label* __restrict__ uPtr = lduAddr().upperAddr().begin();
102 const label* __restrict__ lPtr = lduAddr().lowerAddr().begin();
104 const LUType* __restrict__ lowerPtr =
lower().begin();
105 const LUType* __restrict__ upperPtr =
upper().begin();
107 const label nFaces =
upper().size();
109 for (label face=0; face<nFaces; face++)
111 HpsiPtr[uPtr[face]] -= lowerPtr[face]*psiPtr[lPtr[face]];
112 HpsiPtr[lPtr[face]] -= upperPtr[face]*psiPtr[uPtr[face]];
119template<
class Type,
class DType,
class LUType>
123 tmp<Field<Type>> tHpsi(
H(tpsi()));
129template<
class Type,
class DType,
class LUType>
141 auto& faceHpsi = tfaceHpsi.ref();
152template<
class Type,
class DType,
class LUType>
164template<
class Type,
class DType,
class LUType>
183 upperPtr_.reset(
nullptr);
192 lowerPtr_.reset(
nullptr);
197 source() =
A.source();
200 interfacesUpper_ =
A.interfacesUpper_;
201 interfacesLower_ =
A.interfacesLower_;
205template<
class Type,
class DType,
class LUType>
213 diagPtr_ = std::move(
A.diagPtr_);
214 upperPtr_ = std::move(
A.upperPtr_);
215 lowerPtr_ = std::move(
A.lowerPtr_);
216 sourcePtr_ = std::move(
A.sourcePtr_);
218 interfacesUpper_ = std::move(
A.interfacesUpper_);
219 interfacesLower_ = std::move(
A.interfacesLower_);
223template<
class Type,
class DType,
class LUType>
243 sourcePtr_->negate();
251template<
class Type,
class DType,
class LUType>
261 source() +=
A.source();
264 if (symmetric() &&
A.symmetric())
268 else if (symmetric() &&
A.asymmetric())
282 else if (asymmetric() &&
A.symmetric())
296 else if (asymmetric() &&
A.asymmetric())
313 else if (
A.diagonal())
319 <<
"Unknown matrix type combination"
320 <<
abort(FatalError);
323 interfacesUpper_ +=
A.interfacesUpper_;
324 interfacesLower_ +=
A.interfacesLower_;
328template<
class Type,
class DType,
class LUType>
338 source() -=
A.source();
341 if (symmetric() &&
A.symmetric())
345 else if (symmetric() &&
A.asymmetric())
359 else if (asymmetric() &&
A.symmetric())
373 else if (asymmetric() &&
A.asymmetric())
390 else if (
A.diagonal())
396 <<
"Unknown matrix type combination"
397 <<
abort(FatalError);
400 interfacesUpper_ -=
A.interfacesUpper_;
401 interfacesLower_ -=
A.interfacesLower_;
405template<
class Type,
class DType,
class LUType>
423 if (symmetric() || asymmetric())
425 Field<LUType>&
upper = this->upper();
426 Field<LUType>&
lower = this->lower();
431 for (label face=0; face<
upper.size(); face++)
433 upper[face] *= sf[l[face]];
436 for (label face=0; face<
lower.size(); face++)
438 lower[face] *= sf[u[face]];
443 <<
"Scaling a matrix by scalarField is not currently supported\n"
444 "because scaling interfacesUpper_ and interfacesLower_ "
445 "require special transfers"
446 <<
abort(FatalError);
453template<
class Type,
class DType,
class LUType>
476 interfacesUpper_ *=
s;
477 interfacesLower_ *=
s;
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
LduMatrix is a general matrix class in which the coefficients are stored as three arrays,...
bool hasUpper() const noexcept
const Field< LUType > & upper() const
const lduAddressing & lduAddr() const
Return the LDU addressing.
const Field< Type > & source() const
bool asymmetric() const noexcept
Matrix is asymmetric (ie, full).
tmp< Field< Type > > H(const Field< Type > &) const
bool symmetric() const noexcept
Matrix is symmetric.
const Field< DType > & diag() const
void operator+=(const LduMatrix< Type, DType, LUType > &)
void operator=(const LduMatrix< Type, DType, LUType > &)
Copy assignment.
void operator*=(const scalarField &)
bool diagonal() const noexcept
Matrix has diagonal only.
void sumMagOffDiag(Field< LUType > &sumOff) const
LduMatrix(const lduMesh &mesh)
Construct given an LDU addressed mesh.
bool hasLower() const noexcept
tmp< Field< Type > > faceH(const Field< Type > &) const
void operator-=(const LduMatrix< Type, DType, LUType > &)
const Field< LUType > & lower() const
friend Ostream & operator(Ostream &, const LduMatrix< Type, DType, LUType > &)
void size(const label n)
Older name for setAddressableSize.
A face is a list of labels corresponding to mesh vertices.
A class for managing temporary objects.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
const volScalarField & psi
volScalarField H(IOobject("H", runTime.timeName(), mesh.thisDb(), IOobject::NO_READ, IOobject::AUTO_WRITE), mesh, dimensionedScalar(dimLength, Zero))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
errorManip< error > abort(error &err)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
void cmptMag(FieldField< Field, Type > &cf, const FieldField< Field, Type > &f)
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
UList< label > labelUList
A UList of labels.