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;
76template<
class GeoField,
class PatchType,
bool TypeOnly>
79 typename GeoField::Boundary& bfld
82 if constexpr (TypeOnly)
120 for (
direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
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
313 const labelUList& upperAddr = addr.upperAddr();
314 const labelUList& lowerAddr = addr.lowerAddr();
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();
358 auto& bfld = m.psi().constCast().boundaryFieldRef();
360 bfld.setSize(interfaces.size());
367 for (label patchi = 0; patchi < nOldInterfaces; patchi++)
378 label patchi = nOldInterfaces;
379 patchi < interfaces.size();
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);
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];
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(),
755 scale.ref().field() = norm;
761 >(scale.boundaryFieldRef());
766 Pout<<
"oversetFvMeshBase::solveOverset() :"
767 <<
" writing matrix normalisation for field " << m.
psi().
name()
768 <<
" to " << scale.name() <<
endl;
786 const label oldSize = bpsi.size();
805 bpsi.setSize(oldSize);
811 m.
source().transfer(oldSource);
820 const labelList& own = mesh_.faceOwner();
821 const labelList& nei = mesh_.faceNeighbour();
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)
950 os <<
"(processor with my:" << ppp.myProcNo()
951 <<
" nbr:" << ppp.neighbProcNo()
957 os <<
" cell:" << fc[i]
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;
982template<
class GeoField>
986 fld.boundaryFieldRef().template evaluateCoupled<void>();
990template<
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];
1006 Pout<<
"Patch:" << pfld.patch().name() <<
endl;
1010 if (pfld[i] != pfldCorr[i])
1012 Pout<<
" " << i <<
" orig:" << pfld[i]
1013 <<
" corrected:" << pfldCorr[i] <<
endl;
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
const DynamicField< Type > & field() const noexcept
Return const-reference to the primitive field values.
A field of fields is a PtrList of fields with reference counting.
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
tmp< Field< cmptType > > component(const direction) const
Return a component field of the field.
lduInterfaceFieldPtrsList scalarInterfaces() const
Return a list of pointers for each patch field with only those pointing to interfaces being set.
Generic GeometricField class.
this_type & constCast() const noexcept
Return non-const reference to this field.
Internal & ref(const bool updateAccessTime=true)
Same as internalFieldRef().
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Return a reference to the boundary field.
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
@ NO_REGISTER
Do not request registration (bool: false).
@ NO_READ
Nothing to be read.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
const word & name() const noexcept
Return the object name.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
void append(const T &val)
Append an element at the end of the list.
static FOAM_NO_DANGLING_REFERENCE const cellCellStencilObject & New(const fvMesh &mesh, Args &&... args)
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
void setSize(const label n)
Same as resize().
void size(const label n)
Older name for setAddressableSize.
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
void append(T *ptr)
Append an element to the end of the list.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
void set(const bitSet &bitset)
Set specified bits from another bitset.
A processorFvPatchField type bypassing fvPatch.
virtual const scalarList & cellInterpolationWeight() const
Per interpolated cell the interpolation factor. (0 = use.
virtual const labelUList & cellTypes() const
Return the cell type list.
virtual const List< scalarList > & cellInterpolationWeights() const
Weights for cellStencil.
virtual const labelListList & cellStencil() const
Per interpolated cell the neighbour cells (in terms of slots as.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
A special matrix type and solver, designed for finite volume solutions of scalar equations....
const FieldField< Field, Type > & internalCoeffs() const noexcept
fvBoundary scalar field containing pseudo-matrix coeffs for internal cells
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 GeometricField< Type, fvPatchField, volMesh > & psi(const label i=0) const
Return psi.
Field< Type > & source() noexcept
The class contains the addressing required by the lduMatrix: upper, lower and losort.
const labelUList & ownerStartAddr() const
Return owner start addressing.
const labelUList & losortStartAddr() const
Return losort start addressing.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
label size() const noexcept
Return number of equations.
const labelUList & losortAddr() const
Return losort addressing.
const scalarField & diag() const
const scalarField & upper() const
const scalarField & lower() const
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.
static void correctBoundaryConditions(typename GeoField::Boundary &bfld)
Correct boundary conditions of certain type (TypeOnly = true) or explicitly not of the type (TypeOnly...
virtual lduInterfacePtrsList interfaces() const
Return a list of pointers for each patch.
const fvMesh & mesh_
Reference to mesh.
SolverPerformance< Type > solveOverset(fvMatrix< Type > &m, const dictionary &) const
Solve given dictionary with settings.
virtual const lduAddressing & lduAddr() const
Return ldu addressing. If active: is (extended).
static void checkCoupledBC(const GeoField &fld)
Debug: check halo swap is ok.
labelListList stencilFaces_
Corresponding faces (in above lduPtr) to the stencil.
labelListList stencilPatches_
Corresponding patches (in above lduPtr) to the stencil.
void addInterpolation(fvMatrix< Type > &m, const scalarField &normalisation, const bool setHoleCellValue, const Type &holeCellValue) const
Manipulate the matrix to add the interpolation/set hole.
void write(Ostream &, const fvMatrix< Type > &, const lduAddressing &, const lduInterfacePtrsList &) const
Debug: print matrix.
lduInterfacePtrsList allInterfaces_
Interfaces for above mesh. Contains both original and above added processorLduInterfaces.
tmp< scalarField > normalisation(const fvMatrix< Type > &m) const
Determine normalisation for interpolation. This equals the original diagonal except stabilised for ze...
static void correctCoupledBoundaryConditions(GeoField &fld)
Debug: correct coupled bc.
scalar cellAverage(const labelUList &types, const labelUList &nbrTypes, const scalarField &norm, const scalarField &nbrNorm, const label celli, bitSet &isFront) const
Average norm of valid neighbours.
bool active() const
Return true if using extended addressing.
labelList reverseFaceMap_
From old to new face labels.
Boundary condition for use on overset patches. To be run in combination with special dynamicFvMesh ty...
virtual void write(Ostream &os) const
Write.
A traits class, which is primarily used for primitives and vector-space.
An abstract base class for processor coupled interfaces.
virtual int neighbProcNo() const =0
Return neighbour processor number (rank in communicator).
virtual int myProcNo() const =0
Return processor number (rank in communicator).
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
A class for managing temporary objects.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
const volScalarField & psi
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
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))
const cellCellStencilObject & overlap
Namespace for handling debugging switches.
const std::string patch
OpenFOAM patch number as a std::string.
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.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
const dimensionSet dimless
Dimensionless.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
GeometricField< scalar, fvPatchField, volMesh > volScalarField
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
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.
Ostream & endl(Ostream &os)
Add newline and flush stream.
void inplaceReorder(const labelUList &oldToNew, ListType &input, const bool prune=false)
Inplace reorder the elements of a list.
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
errorManipArg< error, int > exit(error &err, const int errNo=1)
UList< label > labelUList
A UList of labels.
List< scalar > scalarList
List of scalar.
UPtrList< const lduInterfaceField > lduInterfaceFieldPtrsList
List of coupled interface fields to be used in coupling.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
#define forAll(list, i)
Loop across all elements in list.