40 lduMatrix::preconditioner::
41 addasymMatrixConstructorToTable<distributedDILUPreconditioner>
63 const auto& lduAddr = matrix.
lduAddr();
73 for (
const label interfacei : selectedInterfaces)
75 interfaces[interfacei].initInterfaceMatrixUpdate
82 coupleCoeffs[interfacei],
91 for (
const label interfacei : selectedInterfaces)
93 interfaces[interfacei].updateInterfaceMatrix
100 coupleCoeffs[interfacei],
117 const auto& interfaces = solver_.interfaces();
119 if (selectedInterfaces.size())
122 FieldField<Field, scalar> one(interfaces.size());
123 FieldField<Field, solveScalar> old(interfaces.size());
124 for (
const label inti : selectedInterfaces)
126 const auto& intf = interfaces[inti].interface();
127 const auto& fc = intf.faceCells();
131 updateMatrixInterfaces
141 if (!colourBufs_.set(colouri))
146 new FieldField<Field, solveScalar>
152 auto& colourBuf = colourBufs_[colouri];
153 colourBuf.setSize(interfaces.size());
154 for (
const label inti : selectedInterfaces)
156 const auto& intf = interfaces[inti].interface();
157 const auto& fc = intf.faceCells();
158 if (!colourBuf.set(inti))
160 colourBuf.set(inti,
new Field<solveScalar>(fc.size()));
162 auto& cb = colourBuf[inti];
164 auto& oldValues = old[inti];
168 const label cell = fc[face];
170 cb[face] =
psi[cell]-oldValues[face];
172 std::swap(
psi[cell], oldValues[face]);
182 DynamicList<UPstream::Request>& requests
185 const auto& interfaces = solver_.interfaces();
186 const auto& interfaceBouCoeffs = solver_.interfaceBouCoeffs();
189 for (
const label inti : selectedInterfaces)
191 const auto& intf = interfaces[inti].interface();
192 const auto* ppp = isA<processorLduInterface>(intf);
194 auto& recvBuf = recvBufs_[inti];
199 requests.emplace_back(),
213 DynamicList<UPstream::Request>& requests
216 const auto& interfaces = solver_.interfaces();
219 for (
const label inti : selectedInterfaces)
221 const auto& intf = interfaces[inti].interface();
222 const auto* ppp = isA<processorLduInterface>(intf);
223 const auto& faceCells = intf.faceCells();
225 auto& sendBuf = sendBufs_[inti];
227 sendBuf.resize_nocopy(faceCells.size());
230 sendBuf[face] = psiInternal[faceCells[face]];
235 requests.emplace_back(),
247 DynamicList<UPstream::Request>& requests,
273 const auto& interfaces = solver_.interfaces();
274 const auto& interfaceBouCoeffs = solver_.interfaceBouCoeffs();
275 const auto& interfaceIntCoeffs = solver_.interfaceIntCoeffs();
277 const auto& intf = interfaces[inti].interface();
279 const auto&
faceCells = intf.faceCells();
280 const auto& bc = interfaceBouCoeffs[inti];
281 const auto& ic = interfaceIntCoeffs[inti];
300 const auto& matrix = solver_.matrix();
301 const auto& lduAddr = matrix.lduAddr();
303 const label*
const __restrict__ uPtr = lduAddr.upperAddr().begin();
304 const label*
const __restrict__ lPtr = lduAddr.lowerAddr().begin();
305 const scalar*
const __restrict__ upperPtr = matrix.upper().begin();
306 const scalar*
const __restrict__ lowerPtr = matrix.lower().begin();
308 const label nFaces = matrix.upper().size();
311 const auto& cellColour = *cellColourPtr_;
312 for (label face=0; face<nFaces; face++)
314 const label cell = lPtr[face];
315 if (cellColour[cell] == colouri)
317 rD[uPtr[face]] -= upperPtr[face]*lowerPtr[face]/rD[cell];
323 for (label face=0; face<nFaces; face++)
335 const Field<solveScalar>& recvBuf
338 const auto& interfaces = solver_.interfaces();
339 const auto& interfaceBouCoeffs = solver_.interfaceBouCoeffs();
341 const auto& intf = interfaces[inti].interface();
342 const auto& faceCells = intf.faceCells();
343 const auto& bc = interfaceBouCoeffs[inti];
344 const solveScalar* __restrict__ rDPtr = rD_.begin();
345 solveScalar* __restrict__ wAPtr = wA.begin();
362 const auto& matrix = solver_.matrix();
363 const auto& lduAddr = matrix.lduAddr();
365 solveScalar* __restrict__ wAPtr = wA.begin();
366 const solveScalar* __restrict__ rDPtr = rD_.begin();
368 const label*
const __restrict__ uPtr = lduAddr.upperAddr().begin();
369 const label*
const __restrict__ lPtr = lduAddr.lowerAddr().begin();
370 const label*
const __restrict__ losortPtr = lduAddr.losortAddr().begin();
371 const scalar*
const __restrict__ lowerPtr = matrix.lower().begin();
373 const label nFaces = matrix.upper().size();
376 const auto& cellColour = *cellColourPtr_;
377 for (label face=0; face<nFaces; face++)
379 const label sface = losortPtr[face];
380 const label cell = lPtr[sface];
381 if (cellColour[cell] == colouri)
383 wAPtr[uPtr[sface]] -=
384 rDPtr[uPtr[sface]]*lowerPtr[sface]*wAPtr[cell];
390 for (label face=0; face<nFaces; face++)
392 const label sface = losortPtr[face];
393 wAPtr[uPtr[sface]] -=
394 rDPtr[uPtr[sface]]*lowerPtr[sface]*wAPtr[lPtr[sface]];
406 const auto& matrix = solver_.matrix();
407 const auto& lduAddr = matrix.lduAddr();
409 solveScalar* __restrict__ wAPtr = wA.begin();
410 const solveScalar* __restrict__ rDPtr = rD_.begin();
412 const label*
const __restrict__ uPtr = lduAddr.upperAddr().begin();
413 const label*
const __restrict__ lPtr = lduAddr.lowerAddr().begin();
414 const scalar*
const __restrict__ upperPtr = matrix.upper().begin();
416 const label nFacesM1 = matrix.upper().size() - 1;
420 const auto& cellColour = *cellColourPtr_;
421 for (label face=nFacesM1; face>=0; face--)
423 const label cell = uPtr[face];
424 if (cellColour[cell] == colouri)
428 rDPtr[lPtr[face]]*upperPtr[face]*wAPtr[cell];
434 for (label face=nFacesM1; face>=0; face--)
448 const auto& matrix = solver_.matrix();
451 wait(lowerRecvRequests_);
454 receive(lowerNbrs_, lowerRecvRequests_);
458 rD.resize_nocopy(
diag.size());
459 std::copy(
diag.begin(),
diag.end(), rD.begin());
465 wait(lowerRecvRequests_);
467 for (
const label inti : lowerNbrs_)
469 addInterfaceDiag(rD, inti, recvBufs_[inti]);
483 for (label colouri = 0; colouri < nColours_; colouri++)
487 for (
const label inti : lowerGlobalRecv_[colouri])
489 addInterfaceDiag(rD, inti, colourBufs_[colouri][inti]);
493 forwardInternalDiag(rD, colouri);
498 sendGlobal(higherGlobalSend_[colouri], rD, higherColour_[colouri]);
503 wait(higherSendRequests_);
506 send(higherNbrs_, rD, higherSendRequests_);
509 const label nCells = rD.size();
511 for (label cell=0; cell<nCells; cell++)
513 rD[cell] = 1.0/rD[cell];
522 const lduMatrix::solver& sol,
523 const dictionary&
dict 526 lduMatrix::preconditioner(sol),
527 coupled_(
dict.getOrDefault<bool>(
"coupled", true, keyType::LITERAL)),
528 rD_(sol.matrix().
diag().size())
530 const lduMesh&
mesh = sol.matrix().mesh();
531 const auto& interfaces = sol.interfaces();
532 const auto& interfaceBouCoeffs = sol.interfaceBouCoeffs();
539 forAll(interfaceBouCoeffs, inti)
541 if (interfaces.set(inti))
543 const auto& bc = interfaceBouCoeffs[inti];
558 const label nProcColours =
563 Info<< typeName <<
" : calculated processor colours:" 564 << nProcColours <<
endl;
573 bool haveGlobalCoupled =
false;
574 bool haveDistributedAMI =
false;
577 if (interfaces.set(inti))
579 const auto& intf = interfaces[inti].interface();
580 const auto* ppp = isA<processorLduInterface>(intf);
583 const label nbrColour = procColours[ppp->neighbProcNo()];
585 if (nbrColour < myColour)
589 else if (nbrColour > myColour)
596 <<
"weird processorLduInterface" 597 <<
" from " << ppp->myProcNo()
598 <<
" to " << ppp->neighbProcNo()
604 haveGlobalCoupled =
true;
606 const auto* AMIpp = isA<cyclicAMILduInterface>(intf);
619 Info<< typeName <<
" : interface " << inti
620 <<
" of type " << intf.type()
621 <<
" is distributed:" << haveDistributedAMI <<
endl;
675 if (interfaces.set(inti))
677 const auto& intf = interfaces[inti].interface();
680 const auto* AMIpp = isA<cyclicAMILduInterface>(intf);
683 nbrInti = AMIpp->neighbPatchID();
685 const auto* cycpp = isA<cyclicLduInterface>(intf);
688 nbrInti = cycpp->neighbPatchID();
693 const label colouri = patchToColour[inti];
694 const label nbrColouri = patchToColour[nbrInti];
698 (haveDistributedAMI && (inti < nbrInti))
699 || (!haveDistributedAMI && (colouri < nbrColouri))
729 if (lowerRecv.size())
734 <<
"Lower global interfaces for colour:" << colouri
735 <<
" receiving from:" <<
flatOutput(lowerRecv)
737 <<
" with colour:" << lowerCol <<
endl;
743 if (higherRecv.size())
748 <<
"Higher global interfaces for colour:" << colouri
749 <<
" receiving from:" <<
flatOutput(higherRecv)
751 <<
" with colour:" << higherCol <<
endl;
768 wait(lowerSendRequests_);
769 wait(lowerRecvRequests_);
770 wait(higherSendRequests_);
771 wait(higherRecvRequests_);
790 solveScalar* __restrict__ wAPtr = wA.
begin();
791 const solveScalar* __restrict__ rAPtr = rA.
begin();
792 const solveScalar* __restrict__ rDPtr = rD_.begin();
794 const label nCells = wA.
size();
801 wait(lowerRecvRequests_);
804 receive(lowerNbrs_, lowerRecvRequests_);
815 wait(lowerRecvRequests_);
817 for (
const label inti : lowerNbrs_)
819 addInterface(wA, inti, recvBufs_[inti]);
822 for (label colouri = 0; colouri < nColours_; colouri++)
827 for (
const label inti : lowerGlobalRecv_[colouri])
829 addInterface(wA, inti, colourBufs_[colouri][inti]);
833 forwardInternal(wA, colouri);
841 higherGlobalSend_[colouri],
843 higherColour_[colouri]
850 wait(higherSendRequests_);
853 send(higherNbrs_, wA, higherSendRequests_);
860 wait(higherRecvRequests_);
863 receive(higherNbrs_, higherRecvRequests_);
867 wait(higherRecvRequests_);
869 for (
const label inti : higherNbrs_)
871 addInterface(wA, inti, recvBufs_[inti]);
874 for (label colouri = nColours_-1; colouri >= 0; colouri--)
879 for (
const label inti : higherGlobalRecv_[colouri])
881 addInterface(wA, inti, colourBufs_[colouri][inti]);
885 backwardInternal(wA, colouri);
893 lowerGlobalSend_[colouri],
895 lowerColour_[colouri]
902 wait(lowerSendRequests_);
905 send(lowerNbrs_, wA, lowerSendRequests_);
918 wait(lowerSendRequests_);
919 wait(lowerRecvRequests_);
920 wait(higherSendRequests_);
921 wait(higherRecvRequests_);
virtual void addInterfaceDiag(solveScalarField &rD, const label inti, const Field< solveScalar > &recvBuf) const
Update diagonal for interface.
FieldField< Field, solveScalar > sendBufs_
Buffers for sending and receiving data.
void size(const label n)
Older name for setAddressableSize.
static label cellColour(const lduMesh &mesh, labelList &cellColour, labelList &patchToColour)
Calculate (locally) per cell colour according to walking from global patches. Returns number of colou...
virtual void precondition(solveScalarField &wA, const solveScalarField &rA, const direction cmpt=0) const
Return wA the preconditioned form of residual rA.
Ostream & indent(Ostream &os)
Indent stream.
void send(const labelList &selectedInterfaces, const solveScalarField &psiInternal, DynamicList< UPstream::Request > &requests) const
Start sending sendBufs_.
static int incrMsgType(int val=1) noexcept
Increment the message tag for standard messages.
A face is a list of labels corresponding to mesh vertices.
Field< solveScalar > solveScalarField
distributedDILUPreconditioner(const lduMatrix::solver &, const dictionary &solverControlsUnused)
Construct from matrix components and preconditioner solver controls.
void append(const T &val)
Append an element at the end of the list.
const solver & solver_
Reference to the base-solver this preconditioner is used with.
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests)
autoPtr< labelList > cellColourPtr_
Local (cell) colouring from global interfaces.
const lduMatrix & matrix() const noexcept
virtual void forwardInternalDiag(solveScalarField &rD, const label colouri) const
Update diagonal for all faces of a certain colour.
solveScalarField rD_
The reciprocal preconditioned diagonal.
List< DynamicList< label > > lowerGlobalSend_
Interfaces to non-processor lower coupled interfaces.
virtual void setFinished(const solverPerformance &perf) const
Signal end of solver.
static const lduMesh * meshPtr_
Processor interface buffers and colouring.
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual ~distributedDILUPreconditioner()
Destructor.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
static int myProcNo(label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
List< DynamicList< label > > higherGlobalSend_
Interfaces to non-processor higher coupled interfaces.
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
static int & msgType() noexcept
Message tag of standard messages.
static std::streamsize read(const UPstream::commsTypes commsType, const int fromProcNo, Type *buffer, std::streamsize count, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm, UPstream::Request *req=nullptr)
Receive buffer contents (contiguous types) from given processor.
Smooth ATC in cells next to a set of patches supplied by type.
FieldField< Field, solveScalar > recvBufs_
static void waitRequests()
Wait for all requests to finish.
A field of fields is a PtrList of fields with reference counting.
#define forAll(list, i)
Loop across all elements in list.
List< label > higherColour_
Corresponding destination colour (for higherGlobal)
static autoPtr< labelList > procColoursPtr_
Previous processor colours.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
virtual void forwardInternal(solveScalarField &wA, const label colouri) const
Update preconditioned variable walking forward on internal faces.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual void addInterface(solveScalarField &wA, const label inti, const Field< solveScalar > &recvBuf) const
Update preconditioned variable from interface.
static bool write(const UPstream::commsTypes commsType, const int toProcNo, const Type *buffer, std::streamsize count, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm, UPstream::Request *req=nullptr, const UPstream::sendModes sendMode=UPstream::sendModes::normal)
Write buffer contents (contiguous types only) to given processor.
const lduInterfaceFieldPtrsList & interfaces() const noexcept
void append(const T &val)
Copy append an element to the end of this list.
Version of DILUpreconditioner that uses preconditioning across processor (and coupled) boundaries...
virtual void backwardInternal(solveScalarField &wA, const label colouri) const
Update preconditioned variable walking backward on internal faces.
iterator begin() noexcept
Return an iterator to begin traversing the UList.
virtual void calcReciprocalD(solveScalarField &rD) const
Calculate reciprocal of diagonal.
void receive(const labelList &selectedInterfaces, DynamicList< UPstream::Request > &requests) const
Start receiving in recvBufs_.
const bool coupled_
Precondition across global coupled bc.
void updateMatrixInterfaces(const bool add, const FieldField< Field, scalar > &coupleCoeffs, const labelList &selectedInterfaces, const solveScalarField &psiif, solveScalarField &result, const direction cmpt) const
Variant of lduMatrix::updateMatrixInterfaces on selected interfaces.
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
DynamicList< label > lowerNbrs_
Interfaces to lower coloured processors.
int debug
Static debugging option.
PtrList< FieldField< Field, solveScalar > > colourBufs_
Global interfaces. Per colour the interfaces that (might) influence it.
defineTypeNameAndDebug(combustionModel, 0)
static label colour(const lduMesh &mesh, labelList &procColour)
Calculate processor colouring from processor connectivity. Sets colour per processor such that no nei...
List< DynamicList< label > > lowerGlobalRecv_
Interfaces to non-processor lower coupled interfaces.
static void cancelRequests(UList< UPstream::Request > &requests)
Non-blocking comms: cancel and free outstanding requests. Corresponds to MPI_Cancel() + MPI_Request_f...
static label nProcs(label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
void sendGlobal(const labelList &selectedInterfaces, solveScalarField &psi, const label colouri) const
Send (and store in colourBufs_[colouri]) the effect of.
DynamicList< label > higherNbrs_
Interfaces to higher coloured processors.
label nColours_
Number of colours (in case of multiple disconnected regions.
#define WarningInFunction
Report a warning using Foam::Warning.
const lduAddressing & lduAddr() const
Return the LDU addressing.
A cell is defined as a list of faces with extra functionality.
#define DebugPout
Report an information message using Foam::Pout.
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
void wait(DynamicList< UPstream::Request > &requests, const bool cancel=false) const
Wait for requests or cancel/free requests.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
const volScalarField & psi
List< label > labelList
A List of labels.
List< label > lowerColour_
Corresponding destination colour (for lowerGlobal)
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))
Ostream & incrIndent(Ostream &os)
Increment the indent level.
List< DynamicList< label > > higherGlobalRecv_
Interfaces to non-processor higher coupled interfaces.
void setSize(label n)
Alias for resize()
lduMatrix::preconditioner::addasymMatrixConstructorToTable< distributedDILUPreconditioner > adddistributedDILUPreconditionerAsymMatrixConstructorToTable_
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
static constexpr const zero Zero
Global zero (0)