Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / foam / matrices / lduMatrix / solvers / GAMG / interfaces / ggiGAMGInterface / ggiGAMGInterfaceTemplates.C
blob789f88d57cc2cbfa982faeab06f03995647d375c
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "ggiGAMGInterface.H"
28 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
30 namespace Foam
33 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
35 template<class Type>
36 tmp<Field<Type> > ggiGAMGInterface::fastReduce(const UList<Type>& ff) const
38     // Algorithm
39     // Local processor contains faceCells part of the zone and requires
40     // zoneAddressing part.
41     // For fast communications, each processor will send the faceCells and
42     // zoneAddressing to the master.  Master will assemble global zone
43     // and send off messages to all processors containing only
44     // the required data
45     // HJ, 24/Jun/2011
47     if (ff.size() != this->size())
48     {
49         FatalErrorIn
50         (
51             "tmp<Field<Type> > ggiGAMGInterface::fastReduce"
52             "("
53             "    const UList<Type>& ff"
54             ") const"
55         )   << "Wrong field size.  ff: " << ff.size()
56             << " interface: " << this->size()
57             << abort(FatalError);
58     }
60     if (localParallel() || !Pstream::parRun())
61     {
62         // Field remains identical: no parallel communications required
63         tmp<Field<Type> > tresult(new Field<Type>(ff));
65         return tresult;
66     }
68     // Execute reduce if not already done
69     if (!initReduce_)
70     {
71         initFastReduce();
72     }
74     if (Pstream::master())
75     {
76         // Master collects information and distributes data.
77         Field<Type> expandField(zoneSize(), pTraits<Type>::zero);
79         // Insert master processor
80         const labelList& za = zoneAddressing();
82         forAll (za, i)
83         {
84             expandField[za[i]] = ff[i];
85         }
87         // Master receives and inserts data from all processors for which
88         // receiveAddr contains entries
89         for (label procI = 1; procI < Pstream::nProcs(); procI++)
90         {
91             const labelList& curRAddr = receiveAddr_[procI];
93             if (!curRAddr.empty())
94             {
95                 Field<Type> receiveBuf(curRAddr.size());
97                 // Opt: reconsider mode of communication
98                 IPstream::read
99                 (
100                     Pstream::blocking,
101                     procI,
102                     reinterpret_cast<char*>(receiveBuf.begin()),
103                     receiveBuf.byteSize()
104                 );
106                 // Insert received information
107                 forAll (curRAddr, i)
108                 {
109                     expandField[curRAddr[i]] = receiveBuf[i];
110                 }
111             }
112         }
114         // Expanded field complete, send required data to other processors
115         for (label procI = 1; procI < Pstream::nProcs(); procI++)
116         {
117             const labelList& curSAddr = sendAddr_[procI];
119             if (!curSAddr.empty())
120             {
121                 Field<Type> sendBuf(curSAddr.size());
123                 forAll (curSAddr, i)
124                 {
125                     sendBuf[i] = expandField[curSAddr[i]];
126                 }
128                 // Opt: reconsider mode of communication
129                 OPstream::write
130                 (
131                     Pstream::blocking,
132                     procI,
133                     reinterpret_cast<const char*>(sendBuf.begin()),
134                     sendBuf.byteSize()
135                 );
136             }
137         }
139         // Note: different from ggi patch: field reduction happens within
140         // fastReduce.  HJ, 26/Jun/2011
141         const labelList& sza = shadowInterface().zoneAddressing();
143         tmp<Field<Type> > tredField
144         (
145             new Field<Type>(sza.size(), pTraits<Type>::zero)
146         );
147         Field<Type>& redField = tredField();
149         // Select elements from shadow zone addressing
150         forAll (sza, i)
151         {
152             redField[i] = expandField[sza[i]];
153         }
155         return tredField;
156     }
157     else
158     {
159         // Send local data to master and receive remote data
160         // If patch is empty, communication is avoided
161         // HJ, 4/Jun/2011
162         if (size())
163         {
164             // Opt: reconsider mode of communication
165             OPstream::write
166             (
167                 Pstream::blocking,
168                 Pstream::masterNo(),
169                 reinterpret_cast<const char*>(ff.begin()),
170                 ff.byteSize()
171             );
172         }
174         // Prepare to receive remote data
175         const labelList& sza = shadowInterface().zoneAddressing();
177         tmp<Field<Type> > treceiveBuf
178         (
179             new Field<Type>(sza.size(), pTraits<Type>::zero)
180         );
181         Field<Type>& receiveBuf = treceiveBuf();
183         if (!sza.empty())
184         {
185             // Opt: reconsider mode of communication
186             IPstream::read
187             (
188                 Pstream::blocking,
189                 Pstream::masterNo(),
190                 reinterpret_cast<char*>(receiveBuf.begin()),
191                 receiveBuf.byteSize()
192             );
194             // Note: different from ggi patch: field reduction happens within
195             // fastReduce.  HJ, 26/Jun/2011
196         }
198         return treceiveBuf;
199     }
203 template<class Type>
204 tmp<Field<Type> > ggiGAMGInterface::expand(const UList<Type>& pd) const
206     // Expand interface data to complete zone
207     tmp<Field<Type> > ted
208     (
209         new Field<Type>(zoneSize(), pTraits<Type>::zero)
210     );
211     Field<Type>& ed = ted();
213     const labelList& za = zoneAddressing();
215     forAll (za, i)
216     {
217         ed[za[i]] = pd[i];
218     }
220     // Reduce zone data if the patch is distributed
221     if (!localParallel())
222     {
223         reduce(ed, sumOp<Field<Type> >());
224     }
226     return ted;
230 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
232 } // End namespace Foam
234 // ************************************************************************* //