00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <OpenFOAM/mapPolyMesh.H>
00027 #include <OpenFOAM/PstreamCombineReduceOps.H>
00028
00029
00030
00031
00032 class listEq
00033 {
00034
00035 public:
00036
00037 template<class T>
00038 void operator()(T& x, const T& y) const
00039 {
00040 forAll(y, i)
00041 {
00042 if (y[i].size())
00043 {
00044 x[i] = y[i];
00045 }
00046 }
00047 }
00048 };
00049
00050
00051 template <class Container, class T>
00052 void Foam::fvMeshDistribute::exchange
00053 (
00054 const List<Container >& sendBufs,
00055 List<Container >& recvBufs,
00056 labelListList& sizes
00057 )
00058 {
00059 if (Pstream::parRun())
00060 {
00061 if (!contiguous<T>())
00062 {
00063 FatalErrorIn
00064 (
00065 "Pstream::exchange(..)"
00066 ) << "Continuous data only." << Foam::abort(FatalError);
00067 }
00068
00069 if (sendBufs.size() != Pstream::nProcs())
00070 {
00071 FatalErrorIn
00072 (
00073 "Pstream::exchange(..)"
00074 ) << "Size of list:" << sendBufs.size()
00075 << " does not equal the number of processors:"
00076 << Pstream::nProcs()
00077 << Foam::abort(FatalError);
00078 }
00079
00080 sizes.setSize(Pstream::nProcs());
00081 labelList& nsTransPs = sizes[Pstream::myProcNo()];
00082 nsTransPs.setSize(Pstream::nProcs());
00083
00084 forAll(sendBufs, procI)
00085 {
00086 nsTransPs[procI] = sendBufs[procI].size();
00087 }
00088
00089 Foam::combineReduce(sizes, listEq());
00090
00091
00092
00093
00094
00095 recvBufs.setSize(sendBufs.size());
00096 forAll(sizes, procI)
00097 {
00098 label nRecv = sizes[procI][Pstream::myProcNo()];
00099
00100 if (procI != Pstream::myProcNo() && nRecv > 0)
00101 {
00102 recvBufs[procI].setSize(nRecv);
00103 IPstream::read
00104 (
00105 Pstream::nonBlocking,
00106 procI,
00107 reinterpret_cast<char*>(recvBufs[procI].begin()),
00108 nRecv*sizeof(T)
00109 );
00110 }
00111 }
00112
00113
00114
00115
00116
00117 forAll(sendBufs, procI)
00118 {
00119 if (procI != Pstream::myProcNo() && sendBufs[procI].size() > 0)
00120 {
00121 if
00122 (
00123 !OPstream::write
00124 (
00125 Pstream::nonBlocking,
00126 procI,
00127 reinterpret_cast<const char*>(sendBufs[procI].begin()),
00128 sendBufs[procI].size()*sizeof(T)
00129 )
00130 )
00131 {
00132 FatalErrorIn("Pstream::exchange(..)")
00133 << "Cannot send outgoing message. "
00134 << "to:" << procI << " nBytes:"
00135 << label(sendBufs[procI].size()*sizeof(T))
00136 << Foam::abort(FatalError);
00137 }
00138 }
00139 }
00140
00141
00142
00143
00144
00145 IPstream::waitRequests();
00146 OPstream::waitRequests();
00147 }
00148
00149
00150 recvBufs[Pstream::myProcNo()] = sendBufs[Pstream::myProcNo()];
00151 }
00152
00153
00154 template<class GeoField>
00155 void Foam::fvMeshDistribute::printFieldInfo(const fvMesh& mesh)
00156 {
00157 HashTable<const GeoField*> flds
00158 (
00159 mesh.objectRegistry::lookupClass<GeoField>()
00160 );
00161
00162 for
00163 (
00164 typename HashTable<const GeoField*>::const_iterator iter = flds.begin();
00165 iter != flds.end();
00166 ++iter
00167 )
00168 {
00169 const GeoField& fld = *iter();
00170
00171 Pout<< "Field:" << iter.key() << " internalsize:" << fld.size()
00172
00173 << endl;
00174
00175 forAll(fld.boundaryField(), patchI)
00176 {
00177 Pout<< " " << patchI
00178 << ' ' << fld.boundaryField()[patchI].patch().name()
00179 << ' ' << fld.boundaryField()[patchI].type()
00180 << ' ' << fld.boundaryField()[patchI].size()
00181 << endl;
00182 }
00183 }
00184 }
00185
00186
00187 template<class GeoField>
00188 void Foam::fvMeshDistribute::addPatchFields(const word& patchFieldType)
00189 {
00190 HashTable<const GeoField*> flds
00191 (
00192 mesh_.objectRegistry::lookupClass<GeoField>()
00193 );
00194
00195 for
00196 (
00197 typename HashTable<const GeoField*>::const_iterator iter = flds.begin();
00198 iter != flds.end();
00199 ++iter
00200 )
00201 {
00202 const GeoField& fld = *iter();
00203
00204 typename GeoField::GeometricBoundaryField& bfld =
00205 const_cast<typename GeoField::GeometricBoundaryField&>
00206 (
00207 fld.boundaryField()
00208 );
00209
00210 label sz = bfld.size();
00211 bfld.setSize(sz + 1);
00212 bfld.set
00213 (
00214 sz,
00215 GeoField::PatchFieldType::New
00216 (
00217 patchFieldType,
00218 mesh_.boundary()[sz],
00219 fld.dimensionedInternalField()
00220 )
00221 );
00222 }
00223 }
00224
00225
00226
00227 template<class GeoField>
00228 void Foam::fvMeshDistribute::deleteTrailingPatchFields()
00229 {
00230 HashTable<const GeoField*> flds
00231 (
00232 mesh_.objectRegistry::lookupClass<GeoField>()
00233 );
00234
00235 for
00236 (
00237 typename HashTable<const GeoField*>::const_iterator iter = flds.begin();
00238 iter != flds.end();
00239 ++iter
00240 )
00241 {
00242 const GeoField& fld = *iter();
00243
00244 typename GeoField::GeometricBoundaryField& bfld =
00245 const_cast<typename GeoField::GeometricBoundaryField&>
00246 (
00247 fld.boundaryField()
00248 );
00249
00250
00251 bfld.setSize(bfld.size() - 1);
00252 }
00253 }
00254
00255
00256
00257 template <class T, class Mesh>
00258 void Foam::fvMeshDistribute::saveBoundaryFields
00259 (
00260 PtrList<FieldField<fvsPatchField, T> >& bflds
00261 ) const
00262 {
00263 typedef GeometricField<T, fvsPatchField, Mesh> fldType;
00264
00265 HashTable<const fldType*> flds
00266 (
00267 mesh_.objectRegistry::lookupClass<fldType>()
00268 );
00269
00270 bflds.setSize(flds.size());
00271
00272 label i = 0;
00273
00274 for
00275 (
00276 typename HashTable<const fldType*>::const_iterator iter = flds.begin();
00277 iter != flds.end();
00278 ++iter
00279 )
00280 {
00281 const fldType& fld = *iter();
00282
00283 bflds.set(i, fld.boundaryField().clone().ptr());
00284
00285 i++;
00286 }
00287 }
00288
00289
00290
00291 template <class T, class Mesh>
00292 void Foam::fvMeshDistribute::mapBoundaryFields
00293 (
00294 const mapPolyMesh& map,
00295 const PtrList<FieldField<fvsPatchField, T> >& oldBflds
00296 )
00297 {
00298 const labelList& oldPatchStarts = map.oldPatchStarts();
00299 const labelList& faceMap = map.faceMap();
00300
00301 typedef GeometricField<T, fvsPatchField, Mesh> fldType;
00302
00303 HashTable<const fldType*> flds
00304 (
00305 mesh_.objectRegistry::lookupClass<fldType>()
00306 );
00307
00308 if (flds.size() != oldBflds.size())
00309 {
00310 FatalErrorIn("fvMeshDistribute::mapBoundaryFields(..)") << "problem"
00311 << abort(FatalError);
00312 }
00313
00314 label fieldI = 0;
00315
00316 for
00317 (
00318 typename HashTable<const fldType*>::const_iterator iter = flds.begin();
00319 iter != flds.end();
00320 ++iter
00321 )
00322 {
00323 const fldType& fld = *iter();
00324 typename fldType::GeometricBoundaryField& bfld =
00325 const_cast<typename fldType::GeometricBoundaryField&>
00326 (
00327 fld.boundaryField()
00328 );
00329
00330
00331 const FieldField<fvsPatchField, T>& oldBfld = oldBflds[fieldI++];
00332
00333
00334
00335 forAll(bfld, patchI)
00336 {
00337 fvsPatchField<T>& patchFld = bfld[patchI];
00338 label faceI = patchFld.patch().patch().start();
00339
00340 forAll(patchFld, i)
00341 {
00342 label oldFaceI = faceMap[faceI++];
00343
00344
00345 forAll(oldPatchStarts, oldPatchI)
00346 {
00347 label oldLocalI = oldFaceI - oldPatchStarts[oldPatchI];
00348
00349 if (oldLocalI >= 0 && oldLocalI < oldBfld[oldPatchI].size())
00350 {
00351 patchFld[i] = oldBfld[oldPatchI][oldLocalI];
00352 }
00353 }
00354 }
00355 }
00356 }
00357 }
00358
00359
00360
00361 template<class GeoField, class PatchFieldType>
00362 void Foam::fvMeshDistribute::initPatchFields
00363 (
00364 const typename GeoField::value_type& initVal
00365 )
00366 {
00367 HashTable<const GeoField*> flds
00368 (
00369 mesh_.objectRegistry::lookupClass<GeoField>()
00370 );
00371
00372 for
00373 (
00374 typename HashTable<const GeoField*>::const_iterator iter = flds.begin();
00375 iter != flds.end();
00376 ++iter
00377 )
00378 {
00379 const GeoField& fld = *iter();
00380
00381 typename GeoField::GeometricBoundaryField& bfld =
00382 const_cast<typename GeoField::GeometricBoundaryField&>
00383 (
00384 fld.boundaryField()
00385 );
00386
00387 forAll(bfld, patchI)
00388 {
00389 if (isA<PatchFieldType>(bfld[patchI]))
00390 {
00391 bfld[patchI] == initVal;
00392 }
00393 }
00394 }
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 template<class GeoField>
00417 void Foam::fvMeshDistribute::sendFields
00418 (
00419 const label domain,
00420 const wordList& fieldNames,
00421 const fvMeshSubset& subsetter,
00422 OSstream& toNbr
00423 )
00424 {
00425 toNbr << GeoField::typeName << token::NL << token::BEGIN_BLOCK << token::NL;
00426 forAll(fieldNames, i)
00427 {
00428 if (debug)
00429 {
00430 Pout<< "Subsetting field " << fieldNames[i]
00431 << " for domain:" << domain << endl;
00432 }
00433
00434
00435
00436 const GeoField& fld =
00437 subsetter.baseMesh().objectRegistry::lookupObject<GeoField>(fieldNames[i]);
00438
00439 tmp<GeoField> tsubfld = subsetter.interpolate(fld);
00440
00441 toNbr
00442 << fieldNames[i] << token::NL << token::BEGIN_BLOCK
00443 << tsubfld
00444 << token::NL << token::END_BLOCK << token::NL;
00445 }
00446 toNbr << token::END_BLOCK << token::NL;
00447 }
00448
00449
00450
00451 template<class GeoField>
00452 void Foam::fvMeshDistribute::receiveFields
00453 (
00454 const label domain,
00455 const wordList& fieldNames,
00456 fvMesh& mesh,
00457 PtrList<GeoField>& fields,
00458 const dictionary& fieldDicts
00459 )
00460 {
00461 if (debug)
00462 {
00463 Pout<< "Receiving fields " << fieldNames
00464 << " from domain:" << domain << endl;
00465 }
00466
00467 fields.setSize(fieldNames.size());
00468
00469 forAll(fieldNames, i)
00470 {
00471 if (debug)
00472 {
00473 Pout<< "Constructing field " << fieldNames[i]
00474 << " from domain:" << domain << endl;
00475 }
00476
00477 fields.set
00478 (
00479 i,
00480 new GeoField
00481 (
00482 IOobject
00483 (
00484 fieldNames[i],
00485 mesh.time().timeName(),
00486 mesh,
00487 IOobject::NO_READ,
00488 IOobject::AUTO_WRITE
00489 ),
00490 mesh,
00491 fieldDicts.subDict(fieldNames[i])
00492 )
00493 );
00494 }
00495 }
00496
00497
00498