LUscalarMatrixTemplates.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) 2019-2024 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 "LUscalarMatrix.H"
30 #include "SubList.H"
31 
32 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
33 
34 template<class Type>
36 (
37  List<Type>& x,
38  const UList<Type>& source
39 ) const
40 {
41  // If x and source are different initialize x = source
42  if (&x != &source)
43  {
44  x = source;
45  }
46 
47  const auto tag = UPstream::msgType();
48 
49  if (UPstream::parRun())
50  {
51  List<Type> allx; // scratch space (on master)
52 
53  const label startOfRequests = UPstream::nRequests();
54 
55  // Like globalIndex::gather()
56  if (UPstream::master(comm_))
57  {
58  allx.resize(m());
59 
60  SubList<Type>(allx, x.size()) = x;
61 
62  for (const int proci : UPstream::subProcs(comm_))
63  {
64  SubList<Type> procSlot
65  (
66  allx,
67  procOffsets_[proci+1]-procOffsets_[proci],
68  procOffsets_[proci]
69  );
70 
71  if (procSlot.empty())
72  {
73  // Nothing to do
74  }
76  {
78  (
80  proci,
81  procSlot.data_bytes(),
82  procSlot.size_bytes(),
83  tag,
84  comm_
85  );
86  }
87  else
88  {
89  IPstream::recv(procSlot, proci, tag, comm_);
90  }
91  }
92  }
93  else
94  {
95  if (x.empty())
96  {
97  // Nothing to do
98  }
100  {
102  (
105  x.cdata_bytes(),
106  x.size_bytes(),
107  tag,
108  comm_
109  );
110  }
111  else
112  {
113  OPstream::send(x, UPstream::masterNo(), tag, comm_);
114  }
115  }
116 
117  UPstream::waitRequests(startOfRequests);
118 
119  // LUBacksubstitute and then like globalIndex::scatter()
120  if (UPstream::master(comm_))
121  {
122  LUBacksubstitute(*this, pivotIndices_, allx);
123 
124  x = SubList<Type>(allx, x.size());
125 
126  for (const int proci : UPstream::subProcs(comm_))
127  {
128  SubList<Type> procSlot
129  (
130  allx,
131  procOffsets_[proci+1]-procOffsets_[proci],
132  procOffsets_[proci]
133  );
134 
135  if (procSlot.empty())
136  {
137  // Nothing to do
138  }
140  {
142  (
144  proci,
145  procSlot.cdata_bytes(),
146  procSlot.size_bytes(),
147  tag,
148  comm_
149  );
150  }
151  else
152  {
153  OPstream::send(procSlot, proci, tag, comm_);
154  }
155  }
156  }
157  else
158  {
159  if (x.empty())
160  {
161  // Nothing to do
162  }
164  {
166  (
169  x.data_bytes(),
170  x.size_bytes(),
171  tag,
172  comm_
173  );
174  }
175  else
176  {
177  IPstream::recv(x, UPstream::masterNo(), tag, comm_);
178  }
179  }
180 
181  UPstream::waitRequests(startOfRequests);
182  }
183  else
184  {
185  LUBacksubstitute(*this, pivotIndices_, x);
186  }
187 }
188 
189 
190 template<class Type>
192 (
193  const UList<Type>& source
194 ) const
195 {
196  auto tx = tmp<Field<Type>>::New(m());
197 
198  solve(tx.ref(), source);
199 
200  return tx;
201 }
202 
203 
204 // ************************************************************************* //
void solve(List< Type > &x, const UList< Type > &source) const
Solve the linear system with the given source.
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:153
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests)
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Definition: UList.H:675
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1061
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.
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1252
char * data_bytes() noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:279
static void waitRequests()
Wait for all requests to finish.
Definition: UPstream.H:1561
const char * cdata_bytes() const noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:272
static void recv(Type &value, const int fromProcNo, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, IOstreamOption::streamFormat fmt=IOstreamOption::BINARY)
Receive and deserialize a value. Uses operator>> for de-serialization.
Definition: IPstream.H:81
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition: UPstream.H:1071
SolverPerformance< Type > solve(faMatrix< Type > &, const dictionary &solverControls)
Solve returning the solution statistics given convergence tolerance.
label m() const noexcept
The number of rows.
Definition: Matrix.H:252
A template class to specify that a data type can be considered as being contiguous in memory...
Definition: contiguous.H:70
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1094
static bool write(const UPstream::commsTypes commsType, const int toProcNo, const char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, UPstream::Request *req=nullptr, const UPstream::sendModes sendMode=UPstream::sendModes::normal)
Write buffer contents to given processor.
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:1197
A class for managing temporary objects.
Definition: HashPtrTable.H:50
bool send()
Send buffer contents now and not in destructor [advanced usage]. Returns true on success.
Definition: OPstreams.C:84
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition: UListI.H:286
void LUBacksubstitute(const scalarSquareMatrix &luMmatrix, const labelList &pivotIndices, List< Type > &source)
LU back-substitution with given source, returning the solution in the source.
static std::streamsize read(const UPstream::commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, UPstream::Request *req=nullptr)
Read buffer contents from given processor.
Definition: UIPstreamRead.C:35