44 const bool setHoleCellValue,
49 const label cType = types[celli];
50 const scalar
f = factor[celli];
54 coeffs[facei] *= 1.0-
f;
71 coeffs[facei] *= 1.0-
f;
76 template<
class GeoField,
class PatchType,
bool TypeOnly>
79 typename GeoField::Boundary& bfld
82 if constexpr (TypeOnly)
88 return (
bool(isA<PatchType>(pfld)));
98 return (!
bool(isA<PatchType>(pfld)));
108 const fvMatrix<Type>& m
119 const FieldField<Field, Type>& internalCoeffs = m.internalCoeffs();
122 forAll(internalCoeffs, patchi)
124 const labelUList& fc = mesh_.lduAddr().patchAddr(patchi);
125 const Field<Type>& intCoeffs = internalCoeffs[patchi];
126 const scalarField cmptCoeffs(intCoeffs.component(cmpt));
129 norm[fc[i]] += cmptCoeffs[i];
138 const scalar&
n = norm[celli];
150 Pout<<
"For field " << m.psi().
name() <<
" have zero diagonals for " 158 const labelList& own = mesh_.faceOwner();
159 const labelList& nei = mesh_.faceNeighbour();
169 extrapolatedNorm[celli] = -GREAT;
174 bitSet isFront(mesh_.nFaces());
175 for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
177 label ownType = types[own[facei]];
178 label neiType = types[nei[facei]];
192 label facei = mesh_.nInternalFaces();
193 facei < mesh_.nFaces();
197 const label ownType = types[own[facei]];
198 const label neiType = nbrTypes[facei-mesh_.nInternalFaces()];
215 bitSet newIsFront(mesh_.nFaces());
219 for (
const label facei : isFront)
221 if (extrapolatedNorm[own[facei]] == -GREAT)
224 newNorm[own[facei]] = cellAverage
237 mesh_.isInternalFace(facei)
238 && extrapolatedNorm[nei[facei]] == -GREAT
242 newNorm[nei[facei]] = cellAverage
261 extrapolatedNorm.transfer(newNorm);
262 isFront.transfer(newIsFront);
269 scalar&
n = norm[celli];
279 n = extrapolatedNorm[celli];
292 const bool setHoleCellValue,
293 const Type& holeCellValue
306 Field<Type>& source = m.source();
312 const lduAddressing& addr = lduAddr();
313 const labelUList& upperAddr = addr.upperAddr();
314 const labelUList& lowerAddr = addr.lowerAddr();
317 if (!isA<fvMeshPrimitiveLduAddressing>(addr))
320 <<
"Problem : addressing is not fvMeshPrimitiveLduAddressing" 326 upper.setSize(upperAddr.size(), 0.0);
328 lower.setSize(lowerAddr.size(), 0.0);
333 const label nOldInterfaces = mesh_.fvMesh::interfaces().size();
336 if (interfaces.size() > nOldInterfaces)
339 m.internalCoeffs().setSize(interfaces.size());
340 m.boundaryCoeffs().setSize(interfaces.size());
345 label patchi = nOldInterfaces;
346 patchi < interfaces.size();
350 const labelUList& fc = interfaces[patchi].faceCells();
351 m.internalCoeffs().set(patchi,
new Field<Type>(fc.size(),
Zero));
352 m.boundaryCoeffs().set(patchi,
new Field<Type>(fc.size(),
Zero));
358 auto& bfld = m.psi().constCast().boundaryFieldRef();
360 bfld.setSize(interfaces.size());
367 for (label patchi = 0; patchi < nOldInterfaces; patchi++)
369 if (isA<processorFvPatch>(bfld[patchi].
patch()))
378 label patchi = nOldInterfaces;
379 patchi < interfaces.size();
386 new calculatedProcessorFvPatchField<Type>
389 bfld[addPatchi].
patch(),
410 const label l = lowerAddr[facei];
411 scaleConnection(
upper, types, factor, setHoleCellValue, l, facei);
412 const label u = upperAddr[facei];
413 scaleConnection(
lower, types, factor, setHoleCellValue, u, facei);
430 for (label patchi = 0; patchi < nOldInterfaces; ++patchi)
432 const labelUList& fc = addr.patchAddr(patchi);
433 Field<Type>& bCoeffs = m.boundaryCoeffs()[patchi];
434 Field<Type>& iCoeffs = m.internalCoeffs()[patchi];
437 scaleConnection(bCoeffs, types, factor, setHoleCellValue, fc[i], i);
439 scaleConnection(iCoeffs, types, factor, setHoleCellValue, fc[i], i);
479 const Type wantedValue
485 diag[celli] = normalisation[celli];
486 source[celli] = normalisation[celli]*wantedValue;
494 const scalar
f = factor[celli];
497 const labelList& nbrFaces = stencilFaces_[celli];
498 const labelList& nbrPatches = stencilPatches_[celli];
500 diag[celli] *= (1.0-
f);
501 source[celli] *= (1.0-
f);
505 const label patchi = nbrPatches[nbri];
506 const label facei = nbrFaces[nbri];
510 const label nbrCelli = nbrs[nbri];
512 const scalar
s = normalisation[celli]*
f*w[nbri];
514 scalar& u =
upper[facei];
515 scalar& l =
lower[facei];
516 if (celli < nbrCelli)
544 const scalar
s = normalisation[celli]*
f*w[nbri];
545 m.boundaryCoeffs()[patchi][facei] += pTraits<Type>::one*
s;
546 m.internalCoeffs()[patchi][facei] += pTraits<Type>::one*
s;
705 auto& bpsi = m.
psi().constCast().boundaryFieldRef();
707 bool hasOverset =
false;
721 Pout<<
"oversetFvMeshBase::solveOverset() :" 722 <<
" bypassing matrix adjustment for field " << m.
psi().name()
726 return mesh_.fvMesh::solve(m,
dict);
731 Pout<<
"oversetFvMeshBase::solveOverset() :" 732 <<
" adjusting matrix for interpolation for field " 739 if (
debug && mesh_.time().writeTime())
745 m.
psi().name() +
"_normalisation",
746 mesh_.time().timeName(),
759 oversetFvPatchField<scalar>,
761 >(scale.boundaryFieldRef());
766 Pout<<
"oversetFvMeshBase::solveOverset() :" 767 <<
" writing matrix normalisation for field " << m.
psi().name()
768 <<
" to " << scale.name() <<
endl;
783 Field<Type> oldSource(m.
source());
786 const label oldSize = bpsi.
size();
796 calculatedProcessorFvPatchField<Type>,
802 SolverPerformance<Type>
s(mesh_.fvMesh::solve(m,
dict));
805 bpsi.setSize(oldSize);
811 m.
source().transfer(oldSource);
820 const labelList& own = mesh_.faceOwner();
821 const labelList& nei = mesh_.faceNeighbour();
823 auto&
psi = m.
psi().constCast();
826 for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
828 const label ownType = types[own[facei]];
829 const label neiType = types[nei[facei]];
836 psi[own[facei]] =
psi[nei[facei]];
844 psi[nei[facei]] =
psi[own[facei]];
864 os <<
"** Matrix **" <<
endl;
880 forAll(interfaces, patchi)
882 if (interfaces.
set(patchi))
884 const labelUList& fc = interfaces[patchi].faceCells();
888 cellToPatch[fc[i]].append(patchi);
889 cellToPatchFace[fc[i]].append(i);
897 os <<
"cell:" << celli <<
" diag:" <<
diag[celli]
898 <<
" source:" << source[celli] <<
endl;
900 label startLabel = ownerStartAddr[celli];
901 label endLabel = ownerStartAddr[celli + 1];
903 for (label facei = startLabel; facei < endLabel; facei++)
905 os <<
" face:" << facei
906 <<
" nbr:" << upperAddr[facei] <<
" coeff:" <<
upper[facei]
913 for (label i = startLabel; i < endLabel; i++)
915 label facei = losortAddr[i];
916 os <<
" face:" << facei
917 <<
" nbr:" << lowerAddr[facei] <<
" coeff:" <<
lower[facei]
921 forAll(cellToPatch[celli], i)
923 label patchi = cellToPatch[celli][i];
924 label patchFacei = cellToPatchFace[celli][i];
926 os <<
" patch:" << patchi
927 <<
" patchface:" << patchFacei
939 os <<
"patch:" << patchi
941 <<
" size:" << fc.size() <<
endl;
944 interfaces.
set(patchi)
945 && isA<processorLduInterface>(interfaces[patchi])
948 const processorLduInterface& ppp =
949 refCast<const processorLduInterface>(interfaces[patchi]);
950 os <<
"(processor with my:" << ppp.myProcNo()
951 <<
" nbr:" << ppp.neighbProcNo()
957 os <<
" cell:" << fc[i]
967 m.
psi().boundaryField().scalarInterfaces();
968 forAll(interfaceFields, inti)
970 if (interfaceFields.set(inti))
972 os <<
"interface:" << inti
973 <<
" if type:" << interfaceFields[inti].interface().type()
974 <<
" fld type:" << interfaceFields[inti].type() <<
endl;
978 os <<
"** End of Matrix **" <<
endl;
982 template<
class GeoField>
986 fld.boundaryFieldRef().template evaluateCoupled<void>();
990 template<
class GeoField>
993 Pout<<
"** starting checking of " <<
fld.name() <<
endl;
995 GeoField fldCorr(
fld.name()+
"_correct",
fld);
996 correctCoupledBoundaryConditions(fldCorr);
998 const auto& bfld =
fld.boundaryField();
999 const auto& bfldCorr = fldCorr.boundaryField();
1003 const auto& pfld = bfld[patchi];
1004 const auto& pfldCorr = bfldCorr[patchi];
1010 if (pfld[i] != pfldCorr[i])
1012 Pout<<
" " << i <<
" orig:" << pfld[i]
1013 <<
" corrected:" << pfldCorr[i] <<
endl;
UPtrList< const lduInterfaceField > lduInterfaceFieldPtrsList
List of coupled interface fields to be used in coupling.
List< scalar > scalarList
List of scalar.
virtual const scalarList & cellInterpolationWeight() const
Per interpolated cell the interpolation factor. (0 = use.
const scalarField & diag() const
void size(const label n)
Older name for setAddressableSize.
errorManipArg< error, int > exit(error &err, const int errNo=1)
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const labelUList & losortStartAddr() const
Return losort start addressing.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
static void checkCoupledBC(const GeoField &fld)
Debug: check halo swap is ok.
static FOAM_NO_DANGLING_REFERENCE const Type & New(const Mesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
Ostream & endl(Ostream &os)
Add newline and flush stream.
A traits class, which is primarily used for primitives and vector-space.
void scaleConnection(Field< Type > &coeffs, const labelUList &types, const scalarList &factor, const bool setHoleCellValue, const label celli, const label facei) const
Freeze values at holes.
Generic GeometricField class.
::Foam::direction nComponents(const expressions::valueTypeCode) noexcept
The number of components associated with given valueTypeCode.
tmp< scalarField > normalisation(const fvMatrix< Type > &m) const
Determine normalisation for interpolation. This equals the original diagonal except stabilised for ze...
Ignore writing from objectRegistry::writeObject()
const dimensionSet dimless
Dimensionless.
virtual const fileName & name() const override
Get the name of the output serial stream. (eg, the name of the Fstream file name) ...
List< labelList > labelListList
List of labelList.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
static void correctCoupledBoundaryConditions(GeoField &fld)
Debug: correct coupled bc.
SolverPerformance< Type > solveOverset(fvMatrix< Type > &m, const dictionary &) const
Solve given dictionary with settings.
UList< label > labelUList
A UList of labels.
virtual const labelUList & cellTypes() const
Return the cell type list.
#define forAll(list, i)
Loop across all elements in list.
GeometricField< scalar, fvPatchField, volMesh > volScalarField
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
const GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
label size() const noexcept
Return number of equations.
Generic templated field type.
virtual const labelListList & cellStencil() const
Per interpolated cell the neighbour cells (in terms of slots as.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
void addInterpolation(fvMatrix< Type > &m, const scalarField &normalisation, const bool setHoleCellValue, const Type &holeCellValue) const
Manipulate the matrix to add the interpolation/set hole.
static void correctBoundaryConditions(typename GeoField::Boundary &bfld)
Correct boundary conditions of certain type (TypeOnly = true) or explicitly not of the type (TypeOnly...
const cellCellStencilObject & overlap
virtual const List< scalarList > & cellInterpolationWeights() const
Weights for cellStencil.
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
const scalarField & lower() const
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
A special matrix type and solver, designed for finite volume solutions of scalar equations. Face addressing is used to make all matrix assembly and solution loops vectorise.
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
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;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Field< Type > & source() noexcept
const scalarField & upper() const
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
const Field< Type > & field() const noexcept
Return const-reference to the primitive field values.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
const std::string patch
OpenFOAM patch number as a std::string.
const labelUList & losortAddr() const
Return losort addressing.
Internal & ref(const bool updateAccessTime=true)
Same as internalFieldRef()
const FieldField< Field, Type > & internalCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for internal cells
const volScalarField & psi
The class contains the addressing required by the lduMatrix: upper, lower and losort.
const FieldField< Field, Type > & boundaryCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for boundary cells
void boundaryManipulate(typename GeometricField< Type, fvPatchField, volMesh >::Boundary &values)
Manipulate based on a boundary field.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
List< label > labelList
A List of labels.
A class for managing temporary objects.
void write(Ostream &, const fvMatrix< Type > &, const lduAddressing &, const lduInterfacePtrsList &) const
Debug: print matrix.
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))
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Do not request registration (bool: false)
const labelUList & ownerStartAddr() const
Return owner start addressing.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
Boundary condition for use on overset patches. To be run in combination with special dynamicFvMesh ty...
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
static constexpr const zero Zero
Global zero (0)