GAMGSolverAgglomerateMatrix.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "GAMGSolver.H"
30 #include "GAMGInterfaceField.H"
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 void Foam::GAMGSolver::agglomerateMatrix
37 (
38  const label fineLevelIndex,
39  const lduMesh& coarseMesh,
40  const lduInterfacePtrsList& coarseMeshInterfaces
41 )
42 {
43  // Get fine matrix
44  const lduMatrix& fineMatrix = matrixLevel(fineLevelIndex);
45 
46  if (UPstream::myProcNo(fineMatrix.mesh().comm()) != -1)
47  {
48  const label nCoarseFaces = agglomeration_.nFaces(fineLevelIndex);
49  const label nCoarseCells = agglomeration_.nCells(fineLevelIndex);
50 
51  // Set the coarse level matrix
52  matrixLevels_.set
53  (
54  fineLevelIndex,
55  new lduMatrix(coarseMesh)
56  );
57  lduMatrix& coarseMatrix = matrixLevels_[fineLevelIndex];
58 
59 
60  // Coarse matrix diagonal initialised by restricting the finer mesh
61  // diagonal. Note that we size with the cached coarse nCells and not
62  // the actual coarseMesh size since this might be dummy when processor
63  // agglomerating.
64  scalarField& coarseDiag = coarseMatrix.diag(nCoarseCells);
65 
66  agglomeration_.restrictField
67  (
68  coarseDiag,
69  fineMatrix.diag(),
70  fineLevelIndex,
71  false // no processor agglomeration
72  );
73 
74  // Get reference to fine-level interfaces
75  const lduInterfaceFieldPtrsList& fineInterfaces =
76  interfaceLevel(fineLevelIndex);
77 
78  // Create coarse-level interfaces
79  primitiveInterfaceLevels_.set
80  (
81  fineLevelIndex,
82  new PtrList<lduInterfaceField>(fineInterfaces.size())
83  );
84 
85  PtrList<lduInterfaceField>& coarsePrimInterfaces =
86  primitiveInterfaceLevels_[fineLevelIndex];
87 
88  interfaceLevels_.set
89  (
90  fineLevelIndex,
91  new lduInterfaceFieldPtrsList(fineInterfaces.size())
92  );
93 
94  lduInterfaceFieldPtrsList& coarseInterfaces =
95  interfaceLevels_[fineLevelIndex];
96 
97  // Set coarse-level boundary coefficients
98  interfaceLevelsBouCoeffs_.set
99  (
100  fineLevelIndex,
101  new FieldField<Field, scalar>(fineInterfaces.size())
102  );
103  FieldField<Field, scalar>& coarseInterfaceBouCoeffs =
104  interfaceLevelsBouCoeffs_[fineLevelIndex];
105 
106  // Set coarse-level internal coefficients
107  interfaceLevelsIntCoeffs_.set
108  (
109  fineLevelIndex,
110  new FieldField<Field, scalar>(fineInterfaces.size())
111  );
112  FieldField<Field, scalar>& coarseInterfaceIntCoeffs =
113  interfaceLevelsIntCoeffs_[fineLevelIndex];
114 
115  // Add the coarse level
116  agglomerateInterfaceCoefficients
117  (
118  fineLevelIndex,
119  coarseMeshInterfaces,
120  coarsePrimInterfaces,
121  coarseInterfaces,
122  coarseInterfaceBouCoeffs,
123  coarseInterfaceIntCoeffs
124  );
125 
126 
127  // Get face restriction map for current level
128  const labelList& faceRestrictAddr =
129  agglomeration_.faceRestrictAddressing(fineLevelIndex);
130  const boolList& faceFlipMap =
131  agglomeration_.faceFlipMap(fineLevelIndex);
132 
133  // Check if matrix is asymmetric and if so agglomerate both upper
134  // and lower coefficients ...
135  if (fineMatrix.hasLower())
136  {
137  // Get off-diagonal matrix coefficients
138  const scalarField& fineUpper = fineMatrix.upper();
139  const scalarField& fineLower = fineMatrix.lower();
140 
141  // Coarse matrix upper coefficients. Note passed in size
142  scalarField& coarseUpper = coarseMatrix.upper(nCoarseFaces);
143  scalarField& coarseLower = coarseMatrix.lower(nCoarseFaces);
144 
145  forAll(faceRestrictAddr, fineFacei)
146  {
147  label cFace = faceRestrictAddr[fineFacei];
148 
149  if (cFace >= 0)
150  {
151  // Check the orientation of the fine-face relative to the
152  // coarse face it is being agglomerated into
153  if (!faceFlipMap[fineFacei])
154  {
155  coarseUpper[cFace] += fineUpper[fineFacei];
156  coarseLower[cFace] += fineLower[fineFacei];
157  }
158  else
159  {
160  coarseUpper[cFace] += fineLower[fineFacei];
161  coarseLower[cFace] += fineUpper[fineFacei];
162  }
163  }
164  else
165  {
166  // Add the fine face coefficients into the diagonal.
167  coarseDiag[-1 - cFace] +=
168  fineUpper[fineFacei] + fineLower[fineFacei];
169  }
170  }
171  }
172  else // ... Otherwise it is symmetric so agglomerate just the upper
173  {
174  // Get off-diagonal matrix coefficients
175  const scalarField& fineUpper = fineMatrix.upper();
176 
177  // Coarse matrix upper coefficients
178  scalarField& coarseUpper = coarseMatrix.upper(nCoarseFaces);
179 
180  forAll(faceRestrictAddr, fineFacei)
181  {
182  label cFace = faceRestrictAddr[fineFacei];
183 
184  if (cFace >= 0)
185  {
186  coarseUpper[cFace] += fineUpper[fineFacei];
187  }
188  else
189  {
190  // Add the fine face coefficient into the diagonal.
191  coarseDiag[-1 - cFace] += 2*fineUpper[fineFacei];
192  }
193  }
194  }
195  }
196 }
197 
198 
199 void Foam::GAMGSolver::agglomerateInterfaceCoefficients
200 (
201  const label fineLevelIndex,
202  const lduInterfacePtrsList& coarseMeshInterfaces,
203  PtrList<lduInterfaceField>& coarsePrimInterfaces,
204  lduInterfaceFieldPtrsList& coarseInterfaces,
205  FieldField<Field, scalar>& coarseInterfaceBouCoeffs,
206  FieldField<Field, scalar>& coarseInterfaceIntCoeffs
207 ) const
208 {
209  // Get reference to fine-level interfaces
210  const lduInterfaceFieldPtrsList& fineInterfaces =
211  interfaceLevel(fineLevelIndex);
212 
213  // Get reference to fine-level boundary coefficients
214  const FieldField<Field, scalar>& fineInterfaceBouCoeffs =
215  interfaceBouCoeffsLevel(fineLevelIndex);
216 
217  // Get reference to fine-level internal coefficients
218  const FieldField<Field, scalar>& fineInterfaceIntCoeffs =
219  interfaceIntCoeffsLevel(fineLevelIndex);
220 
221  const labelListList& patchFineToCoarse =
222  agglomeration_.patchFaceRestrictAddressing(fineLevelIndex);
223 
224  const labelList& nPatchFaces =
225  agglomeration_.nPatchFaces(fineLevelIndex);
226 
227 
228  // Add the coarse level
229  forAll(fineInterfaces, inti)
230  {
231  if (fineInterfaces.set(inti))
232  {
233  const GAMGInterface& coarseInterface =
234  refCast<const GAMGInterface>
235  (
236  coarseMeshInterfaces[inti]
237  );
238 
239  coarsePrimInterfaces.set
240  (
241  inti,
243  (
244  coarseInterface,
245  fineInterfaces[inti]
246  ).ptr()
247  );
248  coarseInterfaces.set
249  (
250  inti,
251  &coarsePrimInterfaces[inti]
252  );
253 
254  const labelList& faceRestrictAddressing = patchFineToCoarse[inti];
255 
256  coarseInterfaceBouCoeffs.set
257  (
258  inti,
259  new scalarField(nPatchFaces[inti], Zero)
260  );
261  agglomeration_.restrictField
262  (
263  coarseInterfaceBouCoeffs[inti],
264  fineInterfaceBouCoeffs[inti],
265  faceRestrictAddressing
266  );
267 
268  coarseInterfaceIntCoeffs.set
269  (
270  inti,
271  new scalarField(nPatchFaces[inti], Zero)
272  );
273  agglomeration_.restrictField
274  (
275  coarseInterfaceIntCoeffs[inti],
276  fineInterfaceIntCoeffs[inti],
277  faceRestrictAddressing
278  );
279  }
280  }
281 }
282 
283 
284 void Foam::GAMGSolver::gatherMatrices
285 (
286  const label destLevel,
287  const label comm,
288 
289  // Local matrix
290  const lduMatrix& mat,
291  const FieldField<Field, scalar>& interfaceBouCoeffs,
292  const FieldField<Field, scalar>& interfaceIntCoeffs,
293  const lduInterfaceFieldPtrsList& interfaces,
294 
295  // Remote matrices
296  PtrList<lduMatrix>& otherMats,
297  PtrList<FieldField<Field, scalar>>& otherBouCoeffs,
298  PtrList<FieldField<Field, scalar>>& otherIntCoeffs,
299  PtrList<PtrList<lduInterfaceField>>& otherInterfaces
300 ) const
301 {
302  if (debug & 2)
303  {
304  const auto& procIDs = UPstream::procID(comm);
305 
306  Pout<< "GAMGSolver::gatherMatrices :"
307  << " collecting matrices from procs:" << procIDs
308  << " using comm:" << comm << endl;
309  }
310 
311  const auto& boundaryMap = agglomeration_.boundaryMap(destLevel);
312 
313  // Use PstreamBuffers
314  PstreamBuffers pBufs
315  (
318  comm
319  );
320 
321  // Send to master
322  if (!UPstream::master(comm))
323  {
324  // Mark valid interfaces
325  // -1 : not set
326  // >= 0 : coupled interface (might also be unmerged processor boundary)
327  //
328  // Note: most processor interfaces will disappear. Originally
329  // we did not know which ones were kept but this is now stored
330  // on the boundaryMap (even on the slave processors). So we can
331  // already filter here and avoid sending across typeNames etc.
332 
333  const label proci = UPstream::myProcNo(comm);
334 
335  labelList validInterface(interfaces.size(), -1);
336  forAll(interfaces, intI)
337  {
338  const label allIntI = boundaryMap[proci][intI];
339  if (interfaces.set(intI) && allIntI != -1)
340  {
341  validInterface[intI] = intI;
342  }
343  }
344 
345  UOPstream toMaster(UPstream::masterNo(), pBufs);
346 
347  toMaster<< mat << token::SPACE << validInterface;
348 
349  forAll(validInterface, intI)
350  {
351  if (validInterface[intI] != -1)
352  {
353  const auto& interface = refCast<const GAMGInterfaceField>
354  (
355  interfaces[intI]
356  );
357 
358  toMaster
359  << interfaceBouCoeffs[intI]
360  << interfaceIntCoeffs[intI]
361  << interface.type();
362  interface.write(toMaster);
363  }
364  }
365  }
366 
367  // Wait for finish
368  pBufs.finishedGathers();
369 
370  // Consume
371  if (UPstream::master(comm))
372  {
373  const label nProcs = UPstream::nProcs(comm);
374 
375  const lduMesh& destMesh = agglomeration_.meshLevel(destLevel);
376  lduInterfacePtrsList destInterfaces = destMesh.interfaces();
377 
378  // Master.
379  otherMats.setSize(nProcs-1);
380  otherBouCoeffs.setSize(nProcs-1);
381  otherIntCoeffs.setSize(nProcs-1);
382  otherInterfaces.setSize(nProcs-1);
383 
384  for (const int proci : UPstream::subProcs(comm))
385  {
386  const label otherI = proci-1;
387 
388  UIPstream fromProc(proci, pBufs);
389 
390  otherMats.set(otherI, new lduMatrix(destMesh, fromProc));
391 
392  // Receive number of/valid interfaces
393  // >= 0 : remote interface index
394  // -1 : invalid interface
395  const labelList validInterface(fromProc);
396 
397  otherBouCoeffs.set
398  (
399  otherI,
400  new FieldField<Field, scalar>(validInterface.size())
401  );
402  otherIntCoeffs.set
403  (
404  otherI,
405  new FieldField<Field, scalar>(validInterface.size())
406  );
407  otherInterfaces.set
408  (
409  otherI,
410  new PtrList<lduInterfaceField>(validInterface.size())
411  );
412 
413  forAll(validInterface, intI)
414  {
415  if (validInterface[intI] != -1)
416  {
417  otherBouCoeffs[otherI].set
418  (
419  intI,
420  new scalarField(fromProc)
421  );
422  otherIntCoeffs[otherI].set
423  (
424  intI,
425  new scalarField(fromProc)
426  );
427 
428  const word coupleType(fromProc);
429 
430  const label allIntI = boundaryMap[proci][intI];
431 
432  otherInterfaces[otherI].set
433  (
434  intI,
436  (
437  coupleType,
438  refCast<const GAMGInterface>
439  (
440  destInterfaces[allIntI]
441  ),
442  fromProc
443  ).release()
444  );
445  }
446  }
447  }
448  }
449 }
450 
451 
452 void Foam::GAMGSolver::procAgglomerateMatrix
453 (
454  // Agglomeration information
455  const labelList& procAgglomMap,
456  const List<label>& agglomProcIDs,
457 
458  const label levelI,
459 
460  // Resulting matrix
461  autoPtr<lduMatrix>& allMatrixPtr,
462  FieldField<Field, scalar>& allInterfaceBouCoeffs,
463  FieldField<Field, scalar>& allInterfaceIntCoeffs,
464  PtrList<lduInterfaceField>& allPrimitiveInterfaces,
465  lduInterfaceFieldPtrsList& allInterfaces
466 ) const
467 {
468  const lduMatrix& coarsestMatrix = matrixLevels_[levelI];
469  const lduInterfaceFieldPtrsList& coarsestInterfaces =
470  interfaceLevels_[levelI];
471  const FieldField<Field, scalar>& coarsestBouCoeffs =
472  interfaceLevelsBouCoeffs_[levelI];
473  const FieldField<Field, scalar>& coarsestIntCoeffs =
474  interfaceLevelsIntCoeffs_[levelI];
475 
476  // Communicator containing all processors to combine (=agglomProcIDs).
477  // Result will be on master of communicator.
478  const label agglomComm = agglomeration_.agglomCommunicator(levelI+1);
479 
480 
481  // Gather all matrix coefficients onto agglomProcIDs[0]
482  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
483 
484  PtrList<lduMatrix> otherMats;
485  PtrList<FieldField<Field, scalar>> otherBouCoeffs;
486  PtrList<FieldField<Field, scalar>> otherIntCoeffs;
487  PtrList<PtrList<lduInterfaceField>> otherInterfaces;
488  gatherMatrices
489  (
490  levelI+1, // allMesh level (only on master)
491  agglomComm,
492 
493  coarsestMatrix, // master before gathering
494  coarsestBouCoeffs, // master before gathering
495  coarsestIntCoeffs, // master before gathering
496  coarsestInterfaces, // master before gathering
497 
498  otherMats, // slave info
499  otherBouCoeffs, // slave info
500  otherIntCoeffs, // slave info
501  otherInterfaces // slave info
502  );
503 
504 
505  if (UPstream::master(agglomComm))
506  {
507  // Agglomerate all matrix
508  // ~~~~~~~~~~~~~~~~~~~~~~
509 
510  const lduMesh& allMesh = agglomeration_.meshLevel(levelI+1);
511  const labelList& cellOffsets = agglomeration_.cellOffsets(levelI+1);
512  const labelListList& faceMap = agglomeration_.faceMap(levelI+1);
513  const labelListList& boundaryMap = agglomeration_.boundaryMap(levelI+1);
514  const labelListListList& boundaryFaceMap =
515  agglomeration_.boundaryFaceMap(levelI+1);
516 
517  allMatrixPtr.reset(new lduMatrix(allMesh));
518  lduMatrix& allMatrix = allMatrixPtr();
519 
520  if (coarsestMatrix.hasDiag())
521  {
522  scalarField& allDiag = allMatrix.diag();
523 
524  SubList<scalar>
525  (
526  allDiag,
527  coarsestMatrix.diag().size()
528  ) = coarsestMatrix.diag();
529 
530  forAll(otherMats, i)
531  {
532  SubList<scalar>
533  (
534  allDiag,
535  otherMats[i].diag().size(),
536  cellOffsets[i+1]
537  ) = otherMats[i].diag();
538  }
539  }
540  if (coarsestMatrix.hasLower())
541  {
542  scalarField& allLower = allMatrix.lower();
543  UIndirectList<scalar>
544  (
545  allLower,
546  faceMap[0]
547  ) = coarsestMatrix.lower();
548  forAll(otherMats, i)
549  {
550  UIndirectList<scalar>
551  (
552  allLower,
553  faceMap[i+1]
554  ) = otherMats[i].lower();
555  }
556  }
557  if (coarsestMatrix.hasUpper())
558  {
559  scalarField& allUpper = allMatrix.upper();
560  UIndirectList<scalar>
561  (
562  allUpper,
563  faceMap[0]
564  ) = coarsestMatrix.upper();
565  forAll(otherMats, i)
566  {
567  UIndirectList<scalar>
568  (
569  allUpper,
570  faceMap[i+1]
571  ) = otherMats[i].upper();
572  }
573  }
574 
575 
576  // Agglomerate interface fields and coefficients
577  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
578 
579  lduInterfacePtrsList allMeshInterfaces = allMesh.interfaces();
580 
581  allInterfaceBouCoeffs.setSize(allMeshInterfaces.size());
582  allInterfaceIntCoeffs.setSize(allMeshInterfaces.size());
583  allPrimitiveInterfaces.setSize(allMeshInterfaces.size());
584  allInterfaces.setSize(allMeshInterfaces.size());
585 
586  forAll(allMeshInterfaces, intI)
587  {
588  const lduInterface& patch = allMeshInterfaces[intI];
589  label size = patch.faceCells().size();
590 
591  allInterfaceBouCoeffs.set(intI, new scalarField(size));
592  allInterfaceIntCoeffs.set(intI, new scalarField(size));
593  }
594 
595  UPtrList<lduInterfaceField> otherFlds(0);
596 
597  forAll(boundaryMap, proci)
598  {
599  const FieldField<Field, scalar>& procBouCoeffs
600  (
601  (proci == 0)
602  ? coarsestBouCoeffs
603  : otherBouCoeffs[proci-1]
604  );
605  const FieldField<Field, scalar>& procIntCoeffs
606  (
607  (proci == 0)
608  ? coarsestIntCoeffs
609  : otherIntCoeffs[proci-1]
610  );
611 
612 
613  const labelList& bMap = boundaryMap[proci];
614  forAll(bMap, procIntI)
615  {
616  label allIntI = bMap[procIntI];
617 
618  if (allIntI != -1)
619  {
620  // So this boundary has been preserved. Copy
621  // data across.
622 
623  if (!allInterfaces.set(allIntI))
624  {
625  const GAMGInterface& intf = refCast<const GAMGInterface>
626  (
627  allMeshInterfaces[allIntI]
628  );
629 
630  if (proci == 0)
631  {
632  // Clone my local interfaceField. Since it is from
633  // this processor it will already exist, even if it
634  // is a processor one.
635 
636  const auto& ffld =
637  refCast<const GAMGInterfaceField>
638  (
639  coarsestInterfaces[procIntI]
640  );
641 
642  allPrimitiveInterfaces.set
643  (
644  allIntI,
645  ffld.clone
646  (
647  intf,
648  otherFlds
649  ).release()
650  );
651  }
652  else
653  {
654  // Recreate a remote interfaceField
655  if (otherInterfaces[proci-1].set(procIntI))
656  {
657  const auto& ffld =
658  refCast<const GAMGInterfaceField>
659  (
660  otherInterfaces[proci-1][procIntI]
661  );
662 
663  allPrimitiveInterfaces.set
664  (
665  allIntI,
666  ffld.clone
667  (
668  intf,
669  otherFlds
670  ).release()
671  );
672  }
673  else
674  {
675  // Recreate a default interfaceField with
676  // sensible defaults.
677  // Should not occur since all unmerged
678  // processor interfaces get transferred.
679  allPrimitiveInterfaces.set
680  (
681  allIntI,
683  (
684  intf,
685  false, //doTransform,
686  0 //rank
687  ).ptr()
688  );
689  }
690  }
691  allInterfaces.set
692  (
693  allIntI,
694  allPrimitiveInterfaces.get(allIntI)
695  );
696  }
697 
698 
699  // Map data from processor to complete mesh
700 
701  scalarField& allBou = allInterfaceBouCoeffs[allIntI];
702  scalarField& allInt = allInterfaceIntCoeffs[allIntI];
703 
704  const labelList& map = boundaryFaceMap[proci][procIntI];
705 
706  const scalarField& procBou = procBouCoeffs[procIntI];
707  const scalarField& procInt = procIntCoeffs[procIntI];
708 
709  forAll(map, i)
710  {
711  label allFacei = map[i];
712  if (allFacei < 0)
713  {
715  << "problem." << abort(FatalError);
716  }
717  allBou[allFacei] = procBou[i];
718  allInt[allFacei] = procInt[i];
719  }
720  }
721  else if (procBouCoeffs.set(procIntI))
722  {
723  // Boundary has become internal face
724 
725  const labelList& map = boundaryFaceMap[proci][procIntI];
726  const scalarField& procBou = procBouCoeffs[procIntI];
727  const scalarField& procInt = procIntCoeffs[procIntI];
728 
729  forAll(map, i)
730  {
731  if (map[i] >= 0)
732  {
733  label allFacei = map[i];
734 
735  if (coarsestMatrix.hasUpper())
736  {
737  allMatrix.upper()[allFacei] = -procBou[i];
738  }
739  if (coarsestMatrix.hasLower())
740  {
741  allMatrix.lower()[allFacei] = -procInt[i];
742  }
743  }
744  else
745  {
746  label allFacei = -map[i]-1;
747 
748  if (coarsestMatrix.hasUpper())
749  {
750  allMatrix.upper()[allFacei] = -procInt[i];
751  }
752  if (coarsestMatrix.hasLower())
753  {
754  allMatrix.lower()[allFacei] = -procBou[i];
755  }
756  }
757  }
758  }
759  }
760  }
761 
762 
763  //Pout<< "** Assembled allMatrix:" << allMatrix.info() << endl;
764  //
765  //forAll(allInterfaces, intI)
766  //{
767  // if (allInterfaces.set(intI))
768  // {
769  // Pout<< " patch:" << intI
770  // << " type:" << allInterfaces[intI].type()
771  // << " size:"
772  // << allInterfaces[intI].interface().faceCells().size()
773  // << endl;
774  //
775  // const scalarField& bouCoeffs = allInterfaceBouCoeffs[intI];
776  // const scalarField& intCoeffs = allInterfaceIntCoeffs[intI];
777  // forAll(bouCoeffs, facei)
778  // {
779  // Pout<< " " << facei
780  // << "\tbou:" << bouCoeffs[facei]
781  // << "\tint:" << intCoeffs[facei]
782  // << endl;
783  // }
784  // }
785  //}
786  }
787 }
788 
789 
790 void Foam::GAMGSolver::procAgglomerateMatrix
791 (
792  const labelList& procAgglomMap,
793  const List<label>& agglomProcIDs,
794 
795  const label levelI
796 )
797 {
798  autoPtr<lduMatrix> allMatrixPtr;
799  autoPtr<FieldField<Field, scalar>> allInterfaceBouCoeffs
800  (
801  new FieldField<Field, scalar>(0)
802  );
803  autoPtr<FieldField<Field, scalar>> allInterfaceIntCoeffs
804  (
805  new FieldField<Field, scalar>(0)
806  );
807  autoPtr<PtrList<lduInterfaceField>> allPrimitiveInterfaces
808  (
809  new PtrList<lduInterfaceField>(0)
810  );
811  autoPtr<lduInterfaceFieldPtrsList> allInterfaces
812  (
814  );
815 
816  procAgglomerateMatrix
817  (
818  // Agglomeration information
819  procAgglomMap,
820  agglomProcIDs,
821 
822  levelI,
823 
824  // Resulting matrix
825  allMatrixPtr,
826  allInterfaceBouCoeffs(),
827  allInterfaceIntCoeffs(),
828  allPrimitiveInterfaces(),
829  allInterfaces()
830  );
831 
832  matrixLevels_.set(levelI, allMatrixPtr);
833  interfaceLevelsBouCoeffs_.set(levelI, allInterfaceBouCoeffs);
834  interfaceLevelsIntCoeffs_.set(levelI, allInterfaceIntCoeffs);
835  primitiveInterfaceLevels_.set(levelI, allPrimitiveInterfaces);
836  interfaceLevels_.set(levelI, allInterfaces);
837 }
838 
839 
840 // ************************************************************************* //
UPtrList< const lduInterfaceField > lduInterfaceFieldPtrsList
List of coupled interface fields to be used in coupling.
const labelList & faceRestrictAddressing(const label leveli) const
Return face restrict addressing of given level.
void restrictField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex, const bool procAgglom) const
Restrict (integrate by summation) cell field.
const boolList & faceFlipMap(const label leveli) const
Return face flip map of given level.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
Definition: List.H:489
Type & refCast(U &obj)
A dynamic_cast (for references). Generates a FatalError on failed casts and uses the virtual type() m...
Definition: typeInfo.H:159
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1187
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1229
interfaceProperties interface(alpha1, U, thermo->transportPropertiesDict())
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
Definition: UPstream.H:1065
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition: UPstream.H:1059
Space [isspace].
Definition: token.H:131
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
List< labelListList > labelListListList
List of labelListList.
Definition: labelList.H:41
errorManip< error > abort(error &err)
Definition: errorManip.H:139
int debug
Static debugging option.
label nFaces(const label leveli) const
Return number of coarse faces (before processor agglomeration)
static autoPtr< GAMGInterfaceField > New(const GAMGInterface &GAMGCp, const lduInterfaceField &fineInterface)
Return a pointer to a new interface created on freestore given.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
Definition: stringOps.C:1171
static List< int > & procID(const label communicator)
The list of ranks within a given communicator.
Definition: UPstream.H:1130
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
const std::string patch
OpenFOAM patch number as a std::string.
"nonBlocking" : (MPI_Isend, MPI_Irecv)
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:1185
List< label > labelList
A List of labels.
Definition: List.H:62
void setSize(const label n)
Alias for resize()
Definition: UPtrList.H:840
List< bool > boolList
A List of bools.
Definition: List.H:60
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
label nCells(const label leveli) const
Return number of coarse cells (before processor agglomeration)
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127